From 813d9e8175b30e2b4dfdf9aa67f3088e38115f2f Mon Sep 17 00:00:00 2001 From: James Laskey Date: Mon, 28 Jan 2013 16:29:10 -0400 Subject: [PATCH 0001/1294] 8006676: Integrate Nashorn into new build system Reviewed-by: jlaskey --- jdk/THIRD_PARTY_README | 24 +++++++++++------------ jdk/make/launchers/Makefile | 4 ++++ jdk/makefiles/CompileLaunchers.gmk | 5 +++++ jdk/makefiles/CreateJars.gmk | 8 ++++++++ jdk/test/tools/launcher/VersionCheck.java | 1 + 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/jdk/THIRD_PARTY_README b/jdk/THIRD_PARTY_README index 6dc1b331638..61834ab7a5a 100644 --- a/jdk/THIRD_PARTY_README +++ b/jdk/THIRD_PARTY_README @@ -6,7 +6,7 @@ Framework v4.0, which is included with JRE 8, and JDK 8. --- begin of LICENSE --- -Copyright (c) 2000-2011 France Tlcom +Copyright (c) 2000-2011 France TÈlÈcom All rights reserved. Redistribution and use in source and binary forms, with or without @@ -741,7 +741,7 @@ Linux and Solaris. --- begin of LICENSE --- -Copyright ¬© 2001,2003 Keith Packard +Copyright ¬¨¬© 2001,2003 Keith Packard Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the @@ -1955,16 +1955,16 @@ v1.9, which is included with JRE 7, JDK 7, and OpenJDK 7. Unicode Terms of Use For the general privacy policy governing access to this site, see the Unicode -Privacy Policy. For trademark usage, see the Unicode® Consortium Name and +Privacy Policy. For trademark usage, see the Unicode¬Æ Consortium Name and Trademark Usage Policy. A. Unicode Copyright. - 1. Copyright © 1991-2011 Unicode, Inc. All rights reserved. + 1. Copyright ¬© 1991-2011 Unicode, Inc. All rights reserved. 2. Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative - works conforming to the Unicode® Standard, subject to Terms and + works conforming to the Unicode¬Æ Standard, subject to Terms and Conditions herein. 3. Any person is hereby authorized, without fee, to view, use, reproduce, @@ -2030,14 +2030,14 @@ D. Waiver of Damages. In no event shall Unicode or its licensors be liable for E.Trademarks & Logos. 1. The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, - Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of + Inc. ‚ÄúThe Unicode Consortium‚Äù and ‚ÄúUnicode, Inc.‚Äù are trade names of Unicode, Inc. Use of the information and materials found on this - website indicates your acknowledgement of Unicode, Inc.’s exclusive + website indicates your acknowledgement of Unicode, Inc.‚Äôs exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. - 2. The Unicode Consortium Name and Trademark Usage Policy (“Trademark - Policy”) are incorporated herein by reference and you agree to abide by + 2. The Unicode Consortium Name and Trademark Usage Policy (‚ÄúTrademark + Policy‚Äù) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. @@ -2060,12 +2060,12 @@ Miscellaneous. 2. Modification by Unicode. Unicode shall have the right to modify this Agreement at any time by posting it to this site. The user may not - assign any part of this Agreement without Unicode’s prior written + assign any part of this Agreement without Unicode‚Äôs prior written consent. 3. Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on - Unicode’s net income. + Unicode‚Äôs net income. 4. Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain @@ -2094,7 +2094,7 @@ SOFTWARE. COPYRIGHT AND PERMISSION NOTICE -Copyright © 1991-2011 Unicode, Inc. All rights reserved. Distributed under the +Copyright ¬© 1991-2011 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/jdk/make/launchers/Makefile b/jdk/make/launchers/Makefile index be16512e478..4be80722894 100644 --- a/jdk/make/launchers/Makefile +++ b/jdk/make/launchers/Makefile @@ -77,6 +77,10 @@ $(call make-launcher, jmap, sun.tools.jmap.JMap, \ -J-Dsun.jvm.hotspot.debugger.useWindbgDebugger, ) $(call make-launcher, jps, sun.tools.jps.Jps, , ) $(call make-launcher, jrunscript, com.sun.tools.script.shell.Main, , ) +$(call make-launcher, jjs, jdk.nashorn.tools.Shell, \ + -J-XX:-TieredCompilation \ + -J-Xms2G \ + -J-Xmx2G, ) $(call make-launcher, jsadebugd, sun.jvm.hotspot.jdi.SADebugServer, , ) $(call make-launcher, jstack, sun.tools.jstack.JStack, \ -J-Dsun.jvm.hotspot.debugger.useProcDebugger \ diff --git a/jdk/makefiles/CompileLaunchers.gmk b/jdk/makefiles/CompileLaunchers.gmk index 354fea12044..f1ceeedfd34 100644 --- a/jdk/makefiles/CompileLaunchers.gmk +++ b/jdk/makefiles/CompileLaunchers.gmk @@ -311,6 +311,11 @@ $(eval $(call SetupLauncher,jps,\ $(eval $(call SetupLauncher,jrunscript,\ -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.script.shell.Main"$(COMMA) }')) +$(eval $(call SetupLauncher,jjs,\ + -DJAVA_ARGS='{ "-J-XX:-TieredCompilation"$(COMMA) \ + "-J-Xms2G"$(COMMA) "-J-Xmx2G"$(COMMA) \ + "jdk.nashorn.tools.Shell"$(COMMA) }')) + $(eval $(call SetupLauncher,jsadebugd,\ -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.jvm.hotspot.jdi.SADebugServer"$(COMMA) }' \ -DAPP_CLASSPATH='{ "/lib/tools.jar"$(COMMA) "/lib/sa-jdi.jar"$(COMMA) "/classes" }' \ diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk index 21c3ca98bfb..d67ab5a65f6 100644 --- a/jdk/makefiles/CreateJars.gmk +++ b/jdk/makefiles/CreateJars.gmk @@ -1046,6 +1046,14 @@ endif ########################################################################################## +# Import nashorn.jar from nashorn dist dir. +$(IMAGES_OUTPUTDIR)/lib/ext/nashorn.jar: $(NASHORN_DIST)/nashorn.jar + $(install-file) + +JARS += $(IMAGES_OUTPUTDIR)/lib/ext/nashorn.jar + +########################################################################################## + -include $(CUSTOM_MAKE_DIR)/CreateJars.gmk ########################################################################################## diff --git a/jdk/test/tools/launcher/VersionCheck.java b/jdk/test/tools/launcher/VersionCheck.java index c30ef424011..dd15d04570f 100644 --- a/jdk/test/tools/launcher/VersionCheck.java +++ b/jdk/test/tools/launcher/VersionCheck.java @@ -73,6 +73,7 @@ public class VersionCheck extends TestHelper { "jmap", "jps", "jrunscript", + "jjs", "jsadebugd", "jstack", "jstat", From d56ceaa96bd493fee496887df21e6d76745391bb Mon Sep 17 00:00:00 2001 From: James Laskey Date: Mon, 28 Jan 2013 16:29:34 -0400 Subject: [PATCH 0002/1294] 8006676: Integrate Nashorn into new build system Reviewed-by: jlaskey --- common/autoconf/generated-configure.sh | 16 ++++++++ common/autoconf/source-dirs.m4 | 15 ++++++- common/autoconf/spec.gmk.in | 3 ++ common/bin/compare.sh | 30 +++++++++++++- common/makefiles/Main.gmk | 14 +++++-- common/makefiles/MakeBase.gmk | 3 +- make/nashorn-rules.gmk | 56 ++++++++++++++++++++++++++ make/scripts/hgforest.sh | 2 +- 8 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 make/nashorn-rules.gmk diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index ff6a41fc001..ee55de77f12 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -738,6 +738,7 @@ BUILD_OUTPUT OVERRIDE_SRC_ROOT ADD_SRC_ROOT JDK_TOPDIR +NASHORN_TOPDIR HOTSPOT_TOPDIR JAXWS_TOPDIR JAXP_TOPDIR @@ -15627,6 +15628,7 @@ CORBA_TOPDIR="$SRC_ROOT/corba" JAXP_TOPDIR="$SRC_ROOT/jaxp" JAXWS_TOPDIR="$SRC_ROOT/jaxws" HOTSPOT_TOPDIR="$SRC_ROOT/hotspot" +NASHORN_TOPDIR="$SRC_ROOT/nashorn" JDK_TOPDIR="$SRC_ROOT/jdk" @@ -15637,6 +15639,7 @@ JDK_TOPDIR="$SRC_ROOT/jdk" + ############################################################################### # # Pickup additional source for a component from outside of the source root @@ -15867,6 +15870,19 @@ $as_echo_n "checking if hotspot should be overridden... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes with $HOTSPOT_TOPDIR" >&5 $as_echo "yes with $HOTSPOT_TOPDIR" >&6; } fi +if test "x$with_override_nashorn" != x; then + CURDIR="$PWD" + cd "$with_override_nashorn" + NASHORN_TOPDIR="`pwd`" + cd "$CURDIR" + if ! test -f $NASHORN_TOPDIR/makefiles/BuildNashorn.gmk; then + as_fn_error $? "You have to override nashorn with a full nashorn repo!" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if nashorn should be overridden" >&5 +$as_echo_n "checking if nashorn should be overridden... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes with $NASHORN_TOPDIR" >&5 +$as_echo "yes with $NASHORN_TOPDIR" >&6; } +fi if test "x$with_override_jdk" != x; then CURDIR="$PWD" cd "$with_override_jdk" diff --git a/common/autoconf/source-dirs.m4 b/common/autoconf/source-dirs.m4 index eacd056066b..bb0aba1b826 100644 --- a/common/autoconf/source-dirs.m4 +++ b/common/autoconf/source-dirs.m4 @@ -33,12 +33,14 @@ CORBA_TOPDIR="$SRC_ROOT/corba" JAXP_TOPDIR="$SRC_ROOT/jaxp" JAXWS_TOPDIR="$SRC_ROOT/jaxws" HOTSPOT_TOPDIR="$SRC_ROOT/hotspot" +NASHORN_TOPDIR="$SRC_ROOT/nashorn" JDK_TOPDIR="$SRC_ROOT/jdk" AC_SUBST(LANGTOOLS_TOPDIR) AC_SUBST(CORBA_TOPDIR) AC_SUBST(JAXP_TOPDIR) AC_SUBST(JAXWS_TOPDIR) AC_SUBST(HOTSPOT_TOPDIR) +AC_SUBST(NASHORN_TOPDIR) AC_SUBST(JDK_TOPDIR) ]) @@ -233,7 +235,18 @@ if test "x$with_override_hotspot" != x; then fi AC_MSG_CHECKING([if hotspot should be overridden]) AC_MSG_RESULT([yes with $HOTSPOT_TOPDIR]) -fi +fi +if test "x$with_override_nashorn" != x; then + CURDIR="$PWD" + cd "$with_override_nashorn" + NASHORN_TOPDIR="`pwd`" + cd "$CURDIR" + if ! test -f $NASHORN_TOPDIR/makefiles/BuildNashorn.gmk; then + AC_MSG_ERROR([You have to override nashorn with a full nashorn repo!]) + fi + AC_MSG_CHECKING([if nashorn should be overridden]) + AC_MSG_RESULT([yes with $NASHORN_TOPDIR]) +fi if test "x$with_override_jdk" != x; then CURDIR="$PWD" cd "$with_override_jdk" diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index 5fde9e7cf16..f7c61f9d228 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -141,6 +141,7 @@ CORBA_TOPDIR:=@CORBA_TOPDIR@ JAXP_TOPDIR:=@JAXP_TOPDIR@ JAXWS_TOPDIR:=@JAXWS_TOPDIR@ HOTSPOT_TOPDIR:=@HOTSPOT_TOPDIR@ +NASHORN_TOPDIR:=@NASHORN_TOPDIR@ COPYRIGHT_YEAR:=@COPYRIGHT_YEAR@ # Location where build customization files may be found @@ -230,6 +231,7 @@ JAXP_OUTPUTDIR=$(BUILD_OUTPUT)/jaxp JAXWS_OUTPUTDIR=$(BUILD_OUTPUT)/jaxws HOTSPOT_OUTPUTDIR=$(BUILD_OUTPUT)/hotspot JDK_OUTPUTDIR=$(BUILD_OUTPUT)/jdk +NASHORN_OUTPUTDIR=$(BUILD_OUTPUT)/nashorn IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images JCE_OUTPUTDIR=$(BUILD_OUTPUT)/jce-release @@ -238,6 +240,7 @@ CORBA_DIST=$(CORBA_OUTPUTDIR)/dist JAXP_DIST=$(JAXP_OUTPUTDIR)/dist JAXWS_DIST=$(JAXWS_OUTPUTDIR)/dist HOTSPOT_DIST=@HOTSPOT_DIST@ +NASHORN_DIST=$(NASHORN_OUTPUTDIR)/dist BUILD_HOTSPOT=@BUILD_HOTSPOT@ diff --git a/common/bin/compare.sh b/common/bin/compare.sh index 1e1ceb08ae6..0ba46727acc 100644 --- a/common/bin/compare.sh +++ b/common/bin/compare.sh @@ -350,9 +350,15 @@ compare_zip_file() { OTHER_DIR=$2 WORK_DIR=$3 ZIP_FILE=$4 + # Optionally provide different name for other zipfile + OTHER_ZIP_FILE=$5 THIS_ZIP=$THIS_DIR/$ZIP_FILE - OTHER_ZIP=$OTHER_DIR/$ZIP_FILE + if [ -n "$OTHER_ZIP_FILE" ]; then + OTHER_ZIP=$OTHER_DIR/$OTHER_ZIP_FILE + else + OTHER_ZIP=$OTHER_DIR/$ZIP_FILE + fi THIS_SUFFIX="${THIS_ZIP##*.}" OTHER_SUFFIX="${OTHER_ZIP##*.}" @@ -962,6 +968,9 @@ if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "-?" ] || [ "$1" = "/h" ] || [ "$1 echo "[FILTER] List filenames in the image to compare, works for jars, zips, libs and execs" echo "Example:" echo "bash ./common/bin/compareimages.sh CodePointIM.jar" + echo "" + echo "-2zips Compare two zip files only" + echo "" exit 10 fi @@ -1023,6 +1032,13 @@ while [ -n "$1" ]; do -execs) CMP_EXECS=true ;; + -2zips) + CMP_2_ZIPS=true + THIS_FILE=$2 + OTHER_FILE=$3 + shift + shift + ;; *) CMP_NAMES=false CMP_PERMS=false @@ -1041,6 +1057,18 @@ while [ -n "$1" ]; do shift done +if [ "$CMP_2_ZIPS" = "true" ]; then + THIS_DIR="$(dirname $THIS_FILE)" + THIS_DIR="$(cd "$THIS_DIR" && pwd )" + OTHER_DIR="$(dirname $OTHER_FILE)" + OTHER_DIR="$(cd "$OTHER_DIR" && pwd )" + THIS_FILE_NAME="$(basename $THIS_FILE)" + OTHER_FILE_NAME="$(basename $OTHER_FILE)" + echo Comparing $THIS_DIR/$THIS_FILE_NAME and $OTHER_DIR/$OTHER_FILE_NAME + compare_zip_file $THIS_DIR $OTHER_DIR $COMPARE_ROOT/2zips $THIS_FILE_NAME $OTHER_FILE_NAME + exit +fi + if [ "$CMP_NAMES" = "false" ] && [ "$CMP_TYPES" = "false" ] && [ "$CMP_PERMS" = "false" ] && [ "$CMP_GENERAL" = "false" ] && [ "$CMP_ZIPS" = "false" ] && [ "$CMP_JARS" = "false" ] && [ "$CMP_LIBS" = "false" ] && [ "$CMP_EXECS" = "false" ]; then CMP_NAMES=true CMP_PERMS=true diff --git a/common/makefiles/Main.gmk b/common/makefiles/Main.gmk index c96747f090c..104a8fdccdb 100644 --- a/common/makefiles/Main.gmk +++ b/common/makefiles/Main.gmk @@ -116,13 +116,19 @@ jdk-only: start-make @($(CD) $(JDK_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJdk.gmk $(JDK_TARGET)) @$(call TargetExit) +nashorn: jdk nashorn-only +nashorn-only: start-make + @$(call TargetEnter) + @($(CD) $(NASHORN_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildNashorn.gmk) + @$(call TargetExit) + demos: jdk demos-only demos-only: start-make @$(call TargetEnter) @($(CD) $(JDK_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJdk.gmk demos) @$(call TargetExit) -images: source-tips demos images-only +images: source-tips demos nashorn images-only images-only: start-make @$(call TargetEnter) @($(CD) $(JDK_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJdk.gmk images) @@ -173,7 +179,7 @@ $(OUTPUT_ROOT)/source_tips: FRC # Remove everything, except the output from configure. -clean: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-images clean-overlay-images clean-bootcycle-build clean-docs +clean: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-nashorn clean-images clean-overlay-images clean-bootcycle-build clean-docs @($(CD) $(OUTPUT_ROOT) && $(RM) -r tmp source_tips build.log* build-trace*.log*) @$(ECHO) Cleaned all build artifacts. @@ -203,6 +209,8 @@ clean-hotspot: $(call CleanComponent,hotspot) clean-jdk: $(call CleanComponent,jdk) +clean-nashorn: + $(call CleanComponent,nashorn) clean-images: $(call CleanComponent,images) clean-overlay-images: @@ -216,6 +224,6 @@ clean-docs: .PHONY: langtools corba jaxp jaxws hotspot jdk images overlay-images install .PHONY: langtools-only corba-only jaxp-only jaxws-only hotspot-only jdk-only images-only overlay-images-only install-only .PHONY: all test clean dist-clean bootcycle-images start-make -.PHONY: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-images clean-overlay-images clean-bootcycle-build +.PHONY: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-nashorn clean-images clean-overlay-images clean-bootcycle-build FRC: # Force target diff --git a/common/makefiles/MakeBase.gmk b/common/makefiles/MakeBase.gmk index 708cbada085..4c1ecc8c8b7 100644 --- a/common/makefiles/MakeBase.gmk +++ b/common/makefiles/MakeBase.gmk @@ -51,8 +51,9 @@ decompress_paths=$(SED) -f $(SRC_ROOT)/common/makefiles/support/ListPathsSafely- -e 's|X98|$(OUTPUT_ROOT)|g' -e 's|X97|$(SRC_ROOT)|g' \ -e 's|X00|X|g' | tr '\n' '$2' +# Subst in an extra $ to prevent it from disappearing. define ListPathsSafely_If - $(if $(word $3,$($1)),$(eval $1_LPS$3:=$(call compress_paths,$(wordlist $3,$4,$($1))))) + $(if $(word $3,$($1)),$(eval $1_LPS$3:=$(call compress_paths,$(subst $$,$$$$,$(wordlist $3,$4,$($1)))))) endef define ListPathsSafely_Printf diff --git a/make/nashorn-rules.gmk b/make/nashorn-rules.gmk new file mode 100644 index 00000000000..a205f2ea97e --- /dev/null +++ b/make/nashorn-rules.gmk @@ -0,0 +1,56 @@ +# +# Copyright (c) 2001, 2011, 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. +# + +################################################################ +# NASHORN TARGETS +################################################################ + +NASHORN_BUILD_ARGUMENTS = \ + $(COMMON_BUILD_ARGUMENTS) \ + ALT_OUTPUTDIR=$(NASHORN_OUTPUTDIR) \ + ALT_BOOTDIR=$(BOOTDIR) \ + ALT_JDK_IMPORT_PATH=$(JDK_IMPORT_PATH) + +ifeq ($(BUILD_LANGTOOLS), true) + NASHORN_BUILD_ARGUMENTS += ALT_LANGTOOLS_DIST=$(ABS_LANGTOOLS_DIST) +endif + +nashorn: nashorn-build +nashorn-build: + $(MKDIR) -p $(NASHORN_OUTPUTDIR) + @$(call MakeStart,nashorn,all) + ($(CD) $(NASHORN_TOPDIR)/make && \ + $(MAKE) $(NASHORN_BUILD_ARGUMENTS) all) + @$(call MakeFinish,nashorn,all) + +nashorn-clobber:: + $(MKDIR) -p $(NASHORN_OUTPUTDIR) + @$(call MakeStart,nashorn,clobber) + ($(CD) $(NASHORN_TOPDIR)/make && \ + $(MAKE) $(NASHORN_BUILD_ARGUMENTS) clobber) + @$(call MakeFinish,nashorn,clobber) + +.PHONY: nashorn nashorn-build nashorn-clobber + diff --git a/make/scripts/hgforest.sh b/make/scripts/hgforest.sh index ed937f3711e..f30d3eb7768 100644 --- a/make/scripts/hgforest.sh +++ b/make/scripts/hgforest.sh @@ -40,7 +40,7 @@ pull_default="" repos="" repos_extra="" if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then - subrepos="corba jaxp jaxws langtools jdk hotspot" + subrepos="corba jaxp jaxws langtools jdk hotspot nashorn" if [ -f .hg/hgrc ] ; then pull_default=`hg paths default` if [ "${pull_default}" = "" ] ; then From 383e963093f4b9663f59719f1ed3847a94a8d43c Mon Sep 17 00:00:00 2001 From: James Laskey Date: Wed, 6 Feb 2013 13:37:03 -0400 Subject: [PATCH 0003/1294] 8007666: nashorn missing from hgforest.sh Reviewed-by: jlaskey --- common/bin/hgforest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/bin/hgforest.sh b/common/bin/hgforest.sh index cbda87160ba..e4cb76a45a3 100644 --- a/common/bin/hgforest.sh +++ b/common/bin/hgforest.sh @@ -96,7 +96,7 @@ pull_default="" repos="" repos_extra="" if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then - subrepos="corba jaxp jaxws langtools jdk hotspot" + subrepos="corba jaxp jaxws langtools jdk hotspot nashorn" if [ -f .hg/hgrc ] ; then pull_default=`hg paths default` if [ "${pull_default}" = "" ] ; then From eba603edcf540627aec0d5ac3e6bfef1da8c2d61 Mon Sep 17 00:00:00 2001 From: James Laskey Date: Mon, 18 Feb 2013 19:01:59 -0400 Subject: [PATCH 0004/1294] 8008420: Fix Nashorn forest to build with NEWBUILD=false Reviewed-by: jjh --- Makefile | 7 +++++++ make/nashorn-rules.gmk | 3 +++ 2 files changed, 10 insertions(+) diff --git a/Makefile b/Makefile index f9162f0b641..f7b9d1b35e3 100644 --- a/Makefile +++ b/Makefile @@ -90,6 +90,7 @@ include ./make/corba-rules.gmk include ./make/jaxp-rules.gmk include ./make/jaxws-rules.gmk include ./make/jdk-rules.gmk +include ./make/nashorn-rules.gmk include ./make/install-rules.gmk include ./make/sponsors-rules.gmk include ./make/deploy-rules.gmk @@ -174,6 +175,11 @@ ifeq ($(BUILD_JDK), true) clobber:: jdk-clobber endif +ifeq ($(BUILD_NASHORN), true) + generic_build_repo_series:: $(NASHORN) + clobber:: nashorn-clobber +endif + ifeq ($(BUILD_DEPLOY), true) generic_build_repo_series:: $(DEPLOY) clobber:: deploy-clobber @@ -336,6 +342,7 @@ deploy_fastdebug_only: BUILD_HOTSPOT=false \ BUILD_JDK=false \ BUILD_LANGTOOLS=false \ + BUILD_NASHORN=false \ BUILD_CORBA=false \ BUILD_JAXP=false \ BUILD_JAXWS=false \ diff --git a/make/nashorn-rules.gmk b/make/nashorn-rules.gmk index a205f2ea97e..a86a0475ced 100644 --- a/make/nashorn-rules.gmk +++ b/make/nashorn-rules.gmk @@ -37,6 +37,9 @@ ifeq ($(BUILD_LANGTOOLS), true) NASHORN_BUILD_ARGUMENTS += ALT_LANGTOOLS_DIST=$(ABS_LANGTOOLS_DIST) endif +# Default targets +NASHORN = nashorn-build + nashorn: nashorn-build nashorn-build: $(MKDIR) -p $(NASHORN_OUTPUTDIR) From 6ac18a4c3b1ca84127fdae0bce1da42a3aa988cb Mon Sep 17 00:00:00 2001 From: James Laskey Date: Tue, 19 Feb 2013 10:02:55 -0400 Subject: [PATCH 0005/1294] 8008446: Tweaks to make all NEWBUILD=false round 2 Reviewed-by: jjh --- make/Defs-internal.gmk | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/make/Defs-internal.gmk b/make/Defs-internal.gmk index 6f40f763bc9..15374ff7c51 100644 --- a/make/Defs-internal.gmk +++ b/make/Defs-internal.gmk @@ -100,6 +100,7 @@ ABS_JAXP_TOPDIR:=$(call OptFullPath,"$(JAXP_TOPDIR)") ABS_JAXWS_TOPDIR:=$(call OptFullPath,"$(JAXWS_TOPDIR)") ABS_JDK_TOPDIR:=$(call OptFullPath,"$(JDK_TOPDIR)") ABS_HOTSPOT_TOPDIR:=$(call OptFullPath,"$(HOTSPOT_TOPDIR)") +ABS_NASHORN_TOPDIR:=$(call OptFullPath,"$(NASHORN_TOPDIR)") ABS_INSTALL_TOPDIR:=$(call OptFullPath,"$(INSTALL_TOPDIR)") ABS_SPONSORS_TOPDIR:=$(call OptFullPath,"$(SPONSORS_TOPDIR)") ABS_DEPLOY_TOPDIR:=$(call OptFullPath,"$(DEPLOY_TOPDIR)") @@ -165,6 +166,15 @@ ifeq ($(JDK_SRC_AVAILABLE),true) endif endif +NASHORN_SRC_AVAILABLE := $(call MkExists,$(NASHORN_TOPDIR)/make/Makefile) +ifndef BUILD_NASHORN + ifdef ALT_NASHORN_DIST + BUILD_NASHORN := false + else + BUILD_NASHORN := $(NASHORN_SRC_AVAILABLE) + endif +endif + DEPLOY_SRC_AVAILABLE := $(call MkExists,$(DEPLOY_TOPDIR)/make/Makefile) ifndef BUILD_DEPLOY BUILD_DEPLOY := $(DEPLOY_SRC_AVAILABLE) @@ -308,6 +318,10 @@ ifndef ALT_JAXWS_DIST JAXWS_OUTPUTDIR = $(ABS_OUTPUTDIR)/jaxws ABS_JAXWS_DIST = $(JAXWS_OUTPUTDIR)/dist endif +ifndef ALT_NASHORN_DIST + NASHORN_OUTPUTDIR = $(ABS_OUTPUTDIR)/nashorn + ABS_NASHORN_DIST = $(NASHORN_OUTPUTDIR)/dist +endif # Common make arguments (supplied to all component builds) COMMON_BUILD_ARGUMENTS = \ From 9441d55bcae9f25bbf0e9b4ae0da2987a14e2327 Mon Sep 17 00:00:00 2001 From: James Laskey Date: Thu, 21 Feb 2013 15:25:07 -0400 Subject: [PATCH 0006/1294] 8008447: Tweaks to make all NEWBUILD=false round 3 Reviewed-by: jjh, sundar --- jdk/make/launchers/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jdk/make/launchers/Makefile b/jdk/make/launchers/Makefile index 4be80722894..e88742a992b 100644 --- a/jdk/make/launchers/Makefile +++ b/jdk/make/launchers/Makefile @@ -77,10 +77,12 @@ $(call make-launcher, jmap, sun.tools.jmap.JMap, \ -J-Dsun.jvm.hotspot.debugger.useWindbgDebugger, ) $(call make-launcher, jps, sun.tools.jps.Jps, , ) $(call make-launcher, jrunscript, com.sun.tools.script.shell.Main, , ) +ifeq ("$(NEWBUILD)","true") $(call make-launcher, jjs, jdk.nashorn.tools.Shell, \ -J-XX:-TieredCompilation \ -J-Xms2G \ -J-Xmx2G, ) +endif $(call make-launcher, jsadebugd, sun.jvm.hotspot.jdi.SADebugServer, , ) $(call make-launcher, jstack, sun.tools.jstack.JStack, \ -J-Dsun.jvm.hotspot.debugger.useProcDebugger \ From 9f4d8efb2217275fbdff5004165d3df705926fce Mon Sep 17 00:00:00 2001 From: James Laskey Date: Thu, 21 Feb 2013 15:25:31 -0400 Subject: [PATCH 0007/1294] 8008447: Tweaks to make all NEWBUILD=false round 3 Reviewed-by: jjh, sundar --- make/jdk-rules.gmk | 3 +++ make/sanity-rules.gmk | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/make/jdk-rules.gmk b/make/jdk-rules.gmk index 42ba6adf627..dc6b5556dd0 100644 --- a/make/jdk-rules.gmk +++ b/make/jdk-rules.gmk @@ -62,6 +62,9 @@ endif ifeq ($(BUILD_JAXWS), true) JDK_BUILD_ARGUMENTS += ALT_JAXWS_DIST=$(ABS_JAXWS_DIST) endif +ifeq ($(BUILD_NASHORN), true) + JDK_BUILD_ARGUMENTS += ALT_NASHORN_DIST=$(ABS_NASHORN_DIST) +endif ifeq ($(BUILD_HOTSPOT), true) JDK_BUILD_ARGUMENTS += ALT_HOTSPOT_IMPORT_PATH=$(HOTSPOT_DIR)/import diff --git a/make/sanity-rules.gmk b/make/sanity-rules.gmk index 544dba10ffd..ee3d6f88ab1 100644 --- a/make/sanity-rules.gmk +++ b/make/sanity-rules.gmk @@ -182,6 +182,14 @@ ifeq ($(JDK_SRC_AVAILABLE), true) "" >> $(WARNING_FILE) endif endif +ifeq ($(NASHORN_SRC_AVAILABLE), true) + ifneq ($(BUILD_NASHORN), true) + @$(ECHO) "WARNING: You are not building the NASHORN sources.\n" \ + " The nashorn files will be obtained from \n" \ + " the location set in ALT_JDK_IMPORT_PATH. \n" \ + "" >> $(WARNING_FILE) + endif +endif ifeq ($(DEPLOY_SRC_AVAILABLE), true) ifneq ($(BUILD_DEPLOY), true) @$(ECHO) "WARNING: You are not building the DEPLOY sources.\n" \ @@ -268,6 +276,9 @@ endif ifeq ($(JDK_SRC_AVAILABLE), true) @$(ECHO) " JDK_TOPDIR = $(JDK_TOPDIR)" >> $(MESSAGE_FILE) endif +ifeq ($(NASHORN_SRC_AVAILABLE), true) + @$(ECHO) " NASHORN_TOPDIR = $(NASHORN_TOPDIR)" >> $(MESSAGE_FILE) +endif ifeq ($(DEPLOY_SRC_AVAILABLE), true) @$(ECHO) " DEPLOY_TOPDIR = $(DEPLOY_TOPDIR)" >> $(MESSAGE_FILE) endif @@ -303,6 +314,9 @@ endif ifeq ($(JDK_SRC_AVAILABLE), true) @$(ECHO) " BUILD_JDK = $(BUILD_JDK) " >> $(MESSAGE_FILE) endif +ifeq ($(NASHORN_SRC_AVAILABLE), true) + @$(ECHO) " BUILD_NASHORN = $(BUILD_NASHORN) " >> $(MESSAGE_FILE) +endif ifeq ($(DEPLOY_SRC_AVAILABLE), true) @$(ECHO) " BUILD_DEPLOY = $(BUILD_DEPLOY) " >> $(MESSAGE_FILE) endif From ff7ec1f667147714920c41cc182bcc5299c4983f Mon Sep 17 00:00:00 2001 From: James Laskey Date: Fri, 22 Feb 2013 10:23:11 -0400 Subject: [PATCH 0008/1294] 8008721: Tweaks to make all NEWBUILD=false round 4 Reviewed-by: jjh --- jdk/make/launchers/Makefile | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/jdk/make/launchers/Makefile b/jdk/make/launchers/Makefile index e88742a992b..47645158793 100644 --- a/jdk/make/launchers/Makefile +++ b/jdk/make/launchers/Makefile @@ -77,12 +77,7 @@ $(call make-launcher, jmap, sun.tools.jmap.JMap, \ -J-Dsun.jvm.hotspot.debugger.useWindbgDebugger, ) $(call make-launcher, jps, sun.tools.jps.Jps, , ) $(call make-launcher, jrunscript, com.sun.tools.script.shell.Main, , ) -ifeq ("$(NEWBUILD)","true") -$(call make-launcher, jjs, jdk.nashorn.tools.Shell, \ - -J-XX:-TieredCompilation \ - -J-Xms2G \ - -J-Xmx2G, ) -endif +$(call make-launcher, jjs, jdk.nashorn.tools.Shell, , ) $(call make-launcher, jsadebugd, sun.jvm.hotspot.jdi.SADebugServer, , ) $(call make-launcher, jstack, sun.tools.jstack.JStack, \ -J-Dsun.jvm.hotspot.debugger.useProcDebugger \ From e99848e82df223de70c6dd5fcd67c8058dadb0e5 Mon Sep 17 00:00:00 2001 From: James Laskey Date: Fri, 22 Feb 2013 17:45:37 -0400 Subject: [PATCH 0009/1294] 8008756: THIRD_PARTY_README contains Unicode Reviewed-by: jjh --- jdk/THIRD_PARTY_README | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/jdk/THIRD_PARTY_README b/jdk/THIRD_PARTY_README index 61834ab7a5a..6dc1b331638 100644 --- a/jdk/THIRD_PARTY_README +++ b/jdk/THIRD_PARTY_README @@ -6,7 +6,7 @@ Framework v4.0, which is included with JRE 8, and JDK 8. --- begin of LICENSE --- -Copyright (c) 2000-2011 France TÈlÈcom +Copyright (c) 2000-2011 France Tlcom All rights reserved. Redistribution and use in source and binary forms, with or without @@ -741,7 +741,7 @@ Linux and Solaris. --- begin of LICENSE --- -Copyright ¬¨¬© 2001,2003 Keith Packard +Copyright ¬© 2001,2003 Keith Packard Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the @@ -1955,16 +1955,16 @@ v1.9, which is included with JRE 7, JDK 7, and OpenJDK 7. Unicode Terms of Use For the general privacy policy governing access to this site, see the Unicode -Privacy Policy. For trademark usage, see the Unicode¬Æ Consortium Name and +Privacy Policy. For trademark usage, see the Unicode® Consortium Name and Trademark Usage Policy. A. Unicode Copyright. - 1. Copyright ¬© 1991-2011 Unicode, Inc. All rights reserved. + 1. Copyright © 1991-2011 Unicode, Inc. All rights reserved. 2. Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative - works conforming to the Unicode¬Æ Standard, subject to Terms and + works conforming to the Unicode® Standard, subject to Terms and Conditions herein. 3. Any person is hereby authorized, without fee, to view, use, reproduce, @@ -2030,14 +2030,14 @@ D. Waiver of Damages. In no event shall Unicode or its licensors be liable for E.Trademarks & Logos. 1. The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, - Inc. ‚ÄúThe Unicode Consortium‚Äù and ‚ÄúUnicode, Inc.‚Äù are trade names of + Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this - website indicates your acknowledgement of Unicode, Inc.‚Äôs exclusive + website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. - 2. The Unicode Consortium Name and Trademark Usage Policy (‚ÄúTrademark - Policy‚Äù) are incorporated herein by reference and you agree to abide by + 2. The Unicode Consortium Name and Trademark Usage Policy (“Trademark + Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. @@ -2060,12 +2060,12 @@ Miscellaneous. 2. Modification by Unicode. Unicode shall have the right to modify this Agreement at any time by posting it to this site. The user may not - assign any part of this Agreement without Unicode‚Äôs prior written + assign any part of this Agreement without Unicode’s prior written consent. 3. Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on - Unicode‚Äôs net income. + Unicode’s net income. 4. Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain @@ -2094,7 +2094,7 @@ SOFTWARE. COPYRIGHT AND PERMISSION NOTICE -Copyright ¬© 1991-2011 Unicode, Inc. All rights reserved. Distributed under the +Copyright © 1991-2011 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy From 22e895a8979c6b14f8c87d8458e3d0af7c9bae42 Mon Sep 17 00:00:00 2001 From: James Laskey Date: Fri, 22 Feb 2013 18:03:07 -0400 Subject: [PATCH 0010/1294] 8008757: NEWBUILD=true has separate launcher code for jjs Reviewed-by: jjh --- jdk/makefiles/CompileLaunchers.gmk | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/jdk/makefiles/CompileLaunchers.gmk b/jdk/makefiles/CompileLaunchers.gmk index 8d6f606acfc..501c986082e 100644 --- a/jdk/makefiles/CompileLaunchers.gmk +++ b/jdk/makefiles/CompileLaunchers.gmk @@ -312,9 +312,7 @@ $(eval $(call SetupLauncher,jrunscript,\ -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.script.shell.Main"$(COMMA) }')) $(eval $(call SetupLauncher,jjs,\ - -DJAVA_ARGS='{ "-J-XX:-TieredCompilation"$(COMMA) \ - "-J-Xms2G"$(COMMA) "-J-Xmx2G"$(COMMA) \ - "jdk.nashorn.tools.Shell"$(COMMA) }')) + -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "jdk.nashorn.tools.Shell"$(COMMA) }')) $(eval $(call SetupLauncher,jsadebugd,\ -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.jvm.hotspot.jdi.SADebugServer"$(COMMA) }' \ From 636021664aecb3ed1fd8d6419e624baa379a09d3 Mon Sep 17 00:00:00 2001 From: James Laskey Date: Fri, 22 Feb 2013 22:58:48 -0400 Subject: [PATCH 0011/1294] 8008774: nashorn missing from dependencies after merge with tl Reviewed-by: jjh --- common/makefiles/Main.gmk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/makefiles/Main.gmk b/common/makefiles/Main.gmk index 30a966d9b21..c43f590707c 100644 --- a/common/makefiles/Main.gmk +++ b/common/makefiles/Main.gmk @@ -137,7 +137,7 @@ demos-only: start-make # Note: This double-colon rule is intentional, to support # custom make file integration. -images:: source-tips demos images-only +images:: source-tips demos nashorn images-only images-only: start-make @$(call TargetEnter) @($(CD) $(JDK_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJdk.gmk images) @@ -241,8 +241,8 @@ clean-docs: $(call CleanComponent,docs) $(call CleanComponent,docstemp) -.PHONY: langtools corba jaxp jaxws hotspot jdk images overlay-images install -.PHONY: langtools-only corba-only jaxp-only jaxws-only hotspot-only jdk-only images-only overlay-images-only install-only +.PHONY: langtools corba jaxp jaxws hotspot jdk nashorn images overlay-images install +.PHONY: langtools-only corba-only jaxp-only jaxws-only hotspot-only jdk-only nashorn-only images-only overlay-images-only install-only .PHONY: all test clean dist-clean bootcycle-images start-make .PHONY: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-nashorn clean-images clean-overlay-images clean-bootcycle-build .PHONY: profiles profiles-only profiles-oscheck From b5a3cc405ba9f7e113dcd1ac80135bd4a7cf0cd1 Mon Sep 17 00:00:00 2001 From: James Laskey Date: Fri, 22 Feb 2013 23:36:47 -0400 Subject: [PATCH 0012/1294] 8008775: Remove non-ascii from jdk/THIRD_PARTY_README Reviewed-by: jjh --- jdk/THIRD_PARTY_README | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/jdk/THIRD_PARTY_README b/jdk/THIRD_PARTY_README index 6dc1b331638..458e7537479 100644 --- a/jdk/THIRD_PARTY_README +++ b/jdk/THIRD_PARTY_README @@ -6,7 +6,7 @@ Framework v4.0, which is included with JRE 8, and JDK 8. --- begin of LICENSE --- -Copyright (c) 2000-2011 France Tlcom +Copyright (c) 2000-2011 France Telecom All rights reserved. Redistribution and use in source and binary forms, with or without @@ -741,7 +741,7 @@ Linux and Solaris. --- begin of LICENSE --- -Copyright ¬© 2001,2003 Keith Packard +Copyright ¬¨¬© 2001,2003 Keith Packard Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the @@ -1955,16 +1955,16 @@ v1.9, which is included with JRE 7, JDK 7, and OpenJDK 7. Unicode Terms of Use For the general privacy policy governing access to this site, see the Unicode -Privacy Policy. For trademark usage, see the Unicode® Consortium Name and +Privacy Policy. For trademark usage, see the Unicode¬Æ Consortium Name and Trademark Usage Policy. A. Unicode Copyright. - 1. Copyright © 1991-2011 Unicode, Inc. All rights reserved. + 1. Copyright ¬© 1991-2011 Unicode, Inc. All rights reserved. 2. Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative - works conforming to the Unicode® Standard, subject to Terms and + works conforming to the Unicode¬Æ Standard, subject to Terms and Conditions herein. 3. Any person is hereby authorized, without fee, to view, use, reproduce, @@ -2030,14 +2030,14 @@ D. Waiver of Damages. In no event shall Unicode or its licensors be liable for E.Trademarks & Logos. 1. The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, - Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of + Inc. ‚ÄúThe Unicode Consortium‚Äù and ‚ÄúUnicode, Inc.‚Äù are trade names of Unicode, Inc. Use of the information and materials found on this - website indicates your acknowledgement of Unicode, Inc.’s exclusive + website indicates your acknowledgement of Unicode, Inc.‚Äôs exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. - 2. The Unicode Consortium Name and Trademark Usage Policy (“Trademark - Policy”) are incorporated herein by reference and you agree to abide by + 2. The Unicode Consortium Name and Trademark Usage Policy (‚ÄúTrademark + Policy‚Äù) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. @@ -2060,12 +2060,12 @@ Miscellaneous. 2. Modification by Unicode. Unicode shall have the right to modify this Agreement at any time by posting it to this site. The user may not - assign any part of this Agreement without Unicode’s prior written + assign any part of this Agreement without Unicode‚Äôs prior written consent. 3. Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on - Unicode’s net income. + Unicode‚Äôs net income. 4. Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain @@ -2094,7 +2094,7 @@ SOFTWARE. COPYRIGHT AND PERMISSION NOTICE -Copyright © 1991-2011 Unicode, Inc. All rights reserved. Distributed under the +Copyright ¬© 1991-2011 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy From 8f734f4dcff290797f5ffc99dc13ebc97bd7d813 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Tue, 23 Apr 2013 09:37:31 +0200 Subject: [PATCH 0013/1294] 8011081: Improve jhat Properly escape HTML output Reviewed-by: alanb, mschoene, sundar --- .../hat/internal/server/AllClassesQuery.java | 2 +- .../tools/hat/internal/server/ClassQuery.java | 10 +++++----- .../tools/hat/internal/server/HttpReader.java | 10 +++------- .../internal/server/InstancesCountQuery.java | 4 ++-- .../sun/tools/hat/internal/server/OQLHelp.java | 5 +---- .../sun/tools/hat/internal/server/OQLQuery.java | 15 +++------------ .../tools/hat/internal/server/QueryHandler.java | 17 +++++++++++++++-- .../hat/internal/server/RefsByTypeQuery.java | 6 +++--- 8 files changed, 33 insertions(+), 36 deletions(-) diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/server/AllClassesQuery.java b/jdk/src/share/classes/com/sun/tools/hat/internal/server/AllClassesQuery.java index d44a8fc2ecf..bdf01b8d5c6 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/server/AllClassesQuery.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/AllClassesQuery.java @@ -84,7 +84,7 @@ class AllClassesQuery extends QueryHandler { lastPackage = pkg; printClass(clazz); if (clazz.getId() != -1) { - out.print(" [" + clazz.getIdString() + "]"); + print(" [" + clazz.getIdString() + "]"); } out.println("
"); } diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java b/jdk/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java index 1d5782390ce..f13572a22cc 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java @@ -112,12 +112,12 @@ class ClassQuery extends QueryHandler { out.println("

Instances

"); printAnchorStart(); - out.print("instances/" + encodeForURL(clazz)); + print("instances/" + encodeForURL(clazz)); out.print("\">"); out.println("Exclude subclasses
"); printAnchorStart(); - out.print("allInstances/" + encodeForURL(clazz)); + print("allInstances/" + encodeForURL(clazz)); out.print("\">"); out.println("Include subclasses
"); @@ -126,19 +126,19 @@ class ClassQuery extends QueryHandler { out.println("

New Instances

"); printAnchorStart(); - out.print("newInstances/" + encodeForURL(clazz)); + print("newInstances/" + encodeForURL(clazz)); out.print("\">"); out.println("Exclude subclasses
"); printAnchorStart(); - out.print("allNewInstances/" + encodeForURL(clazz)); + print("allNewInstances/" + encodeForURL(clazz)); out.print("\">"); out.println("Include subclasses
"); } out.println("

References summary by Type

"); printAnchorStart(); - out.print("refsByType/" + encodeForURL(clazz)); + print("refsByType/" + encodeForURL(clazz)); out.print("\">"); out.println("References summary by type"); diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/server/HttpReader.java b/jdk/src/share/classes/com/sun/tools/hat/internal/server/HttpReader.java index f86c8caa8e2..f08c9875c67 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/server/HttpReader.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/HttpReader.java @@ -41,21 +41,17 @@ package com.sun.tools.hat.internal.server; import java.net.Socket; -import java.net.ServerSocket; -import java.net.InetAddress; import java.io.InputStream; import java.io.BufferedInputStream; import java.io.IOException; -import java.io.Writer; import java.io.BufferedWriter; import java.io.PrintWriter; -import java.io.OutputStream; import java.io.OutputStreamWriter; -import java.io.BufferedOutputStream; import com.sun.tools.hat.internal.model.Snapshot; import com.sun.tools.hat.internal.oql.OQLEngine; +import com.sun.tools.hat.internal.util.Misc; public class HttpReader implements Runnable { @@ -87,7 +83,7 @@ public class HttpReader implements Runnable { outputError("Protocol error"); } int data; - StringBuffer queryBuf = new StringBuffer(); + StringBuilder queryBuf = new StringBuilder(); while ((data = in.read()) != -1 && data != ' ') { char ch = (char) data; queryBuf.append(ch); @@ -217,7 +213,7 @@ public class HttpReader implements Runnable { private void outputError(String msg) { out.println(); out.println(""); - out.println(msg); + out.println(Misc.encodeHtml(msg)); out.println(""); } diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/server/InstancesCountQuery.java b/jdk/src/share/classes/com/sun/tools/hat/internal/server/InstancesCountQuery.java index 724b549ca4b..7e87543ef99 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/server/InstancesCountQuery.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/InstancesCountQuery.java @@ -102,7 +102,7 @@ class InstancesCountQuery extends QueryHandler { int count = clazz.getInstancesCount(false); print("" + count); printAnchorStart(); - out.print("instances/" + encodeForURL(classes[i])); + print("instances/" + encodeForURL(classes[i])); out.print("\"> "); if (count == 1) { print("instance"); @@ -121,7 +121,7 @@ class InstancesCountQuery extends QueryHandler { } print("("); printAnchorStart(); - out.print("newInstances/" + encodeForURL(classes[i])); + print("newInstances/" + encodeForURL(classes[i])); out.print("\">"); print("" + newInst + " new"); out.print(") "); diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/server/OQLHelp.java b/jdk/src/share/classes/com/sun/tools/hat/internal/server/OQLHelp.java index 6aaa909109a..730d2b7672d 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/server/OQLHelp.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/OQLHelp.java @@ -54,10 +54,7 @@ class OQLHelp extends QueryHandler { out.print((char)ch); } } catch (Exception exp) { - out.println(exp.getMessage()); - out.println("
");
-            exp.printStackTrace(out);
-            out.println("
"); + printException(exp); } } } diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/server/OQLQuery.java b/jdk/src/share/classes/com/sun/tools/hat/internal/server/OQLQuery.java index 8e5ec5e2894..3e99bbcbb74 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/server/OQLQuery.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/OQLQuery.java @@ -32,10 +32,7 @@ package com.sun.tools.hat.internal.server; -import com.sun.tools.hat.internal.model.*; import com.sun.tools.hat.internal.oql.*; -import com.sun.tools.hat.internal.util.ArraySorter; -import com.sun.tools.hat.internal.util.Comparer; /** * This handles Object Query Language (OQL) queries. @@ -68,7 +65,7 @@ class OQLQuery extends QueryHandler { out.println("

"); out.println(""); out.println("

"); @@ -91,10 +88,7 @@ class OQLQuery extends QueryHandler { try { out.println(engine.toHtml(o)); } catch (Exception e) { - out.println(e.getMessage()); - out.println("
");
-                             e.printStackTrace(out);
-                             out.println("
"); + printException(e); } out.println(""); return false; @@ -102,10 +96,7 @@ class OQLQuery extends QueryHandler { }); out.println(""); } catch (OQLException exp) { - out.println(exp.getMessage()); - out.println("
");
-            exp.printStackTrace(out);
-            out.println("
"); + printException(exp); } } diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/server/QueryHandler.java b/jdk/src/share/classes/com/sun/tools/hat/internal/server/QueryHandler.java index deda0f48058..9a6d93de06a 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/server/QueryHandler.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/QueryHandler.java @@ -36,6 +36,7 @@ import java.io.PrintWriter; import com.sun.tools.hat.internal.model.*; import com.sun.tools.hat.internal.util.Misc; +import java.io.StringWriter; import java.net.URLEncoder; import java.io.UnsupportedEncodingException; @@ -96,7 +97,7 @@ abstract class QueryHandler { } protected void error(String msg) { - out.println(msg); + println(msg); } protected void printAnchorStart() { @@ -160,7 +161,6 @@ abstract class QueryHandler { out.println("null"); return; } - String name = clazz.getName(); printAnchorStart(); out.print("class/"); print(encodeForURL(clazz)); @@ -208,6 +208,15 @@ abstract class QueryHandler { } } + protected void printException(Throwable t) { + println(t.getMessage()); + out.println("
");
+        StringWriter sw = new StringWriter();
+        t.printStackTrace(new PrintWriter(sw));
+        print(sw.toString());
+        out.println("
"); + } + protected void printHex(long addr) { if (snapshot.getIdentifierSize() == 4) { out.print(Misc.toHex((int)addr)); @@ -223,4 +232,8 @@ abstract class QueryHandler { protected void print(String str) { out.print(Misc.encodeHtml(str)); } + + protected void println(String str) { + out.println(Misc.encodeHtml(str)); + } } diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/server/RefsByTypeQuery.java b/jdk/src/share/classes/com/sun/tools/hat/internal/server/RefsByTypeQuery.java index 5e7de9a8866..3337b471590 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/server/RefsByTypeQuery.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/RefsByTypeQuery.java @@ -89,7 +89,7 @@ public class RefsByTypeQuery extends QueryHandler { out.println("

"); printClass(clazz); if (clazz.getId() != -1) { - out.println("[" + clazz.getIdString() + "]"); + println("[" + clazz.getIdString() + "]"); } out.println("

"); @@ -125,9 +125,9 @@ public class RefsByTypeQuery extends QueryHandler { JavaClass clazz = classes[i]; out.println(""); out.print(""); - out.print(clazz.getName()); + print(clazz.getName()); out.println(""); out.println(""); out.println(map.get(clazz)); From 7ca524c5cd9a36f350d8bb8ba5770df69427e706 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Tue, 7 May 2013 13:37:03 -0700 Subject: [PATCH 0014/1294] 8013506: Better Pack200 data handling Reviewed-by: jrose, kizune, mschoene --- jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp b/jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp index 93bf3301546..f7b95b47368 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -340,6 +340,10 @@ uLong jar::get_dostime(int modtime) { struct tm sbuf; (void)memset((void*)&sbuf,0, sizeof(sbuf)); struct tm* s = gmtime_r(&t, &sbuf); + if (s == NULL) { + fprintf(u->errstrm, "Error: gmtime failure, invalid input archive\n"); + exit(2); + } modtime_cache = modtime; dostime_cache = dostime(s->tm_year + 1900, s->tm_mon + 1, s->tm_mday, s->tm_hour, s->tm_min, s->tm_sec); @@ -384,7 +388,7 @@ bool jar::deflate_bytes(bytes& head, bytes& tail) { } deflated.empty(); - zs.next_out = (uchar*) deflated.grow(len + (len/2)); + zs.next_out = (uchar*) deflated.grow(add_size(len, (len/2))); zs.avail_out = (int)deflated.size(); zs.next_in = (uchar*)head.ptr; From e8457abad47c8c47beafcdbb394bbaf88b30753e Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Thu, 9 May 2013 09:52:55 -0700 Subject: [PATCH 0015/1294] 8013510: Augment image writing code Reviewed-by: bae, prr --- .../com/sun/imageio/plugins/jpeg/JPEGImageReader.java | 5 +++++ .../com/sun/imageio/plugins/jpeg/JPEGImageWriter.java | 4 ++-- jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c | 9 +++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java index d69200c1408..0b7a865074a 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java @@ -1165,6 +1165,11 @@ public class JPEGImageReader extends ImageReader { target = imRas; } int [] bandSizes = target.getSampleModel().getSampleSize(); + for (int i = 0; i < bandSizes.length; i++) { + if (bandSizes[i] <= 0 || bandSizes[i] > 8) { + throw new IIOException("Illegal band size: should be 0 < size <= 8"); + } + } /* * If the process is sequential, and we have restart markers, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java index b8564176df8..d9723e7ba20 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java @@ -495,8 +495,8 @@ public class JPEGImageWriter extends ImageWriter { // handle <= 8-bit samples. We now check the band sizes and throw // an exception for images, such as USHORT_GRAY, with > 8 bits // per sample. - if (bandSizes[i] > 8) { - throw new IIOException("Sample size must be <= 8"); + if (bandSizes[i] <= 0 || bandSizes[i] > 8) { + throw new IIOException("Illegal band size: should be 0 < size <= 8"); } // 4450894 part 2: We expand IndexColorModel images to full 24- // or 32-bit in grabPixels() for each scanline. For indexed diff --git a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c index 7411c34bb83..4934c748f61 100644 --- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c +++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c @@ -2674,6 +2674,15 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage bandSize = (*env)->GetIntArrayElements(env, bandSizes, NULL); + for (i = 0; i < numBands; i++) { + if (bandSize[i] <= 0 || bandSize[i] > JPEG_BAND_SIZE) { + (*env)->ReleaseIntArrayElements(env, bandSizes, + bandSize, JNI_ABORT); + JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid Image"); + return JNI_FALSE;; + } + } + for (i = 0; i < numBands; i++) { if (bandSize[i] != JPEG_BAND_SIZE) { if (scale == NULL) { From 7dacefeca149e32a783e18398b5974d6c53bb867 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Tue, 14 May 2013 12:51:59 +0400 Subject: [PATCH 0016/1294] 8014093: Improve parsing of images Reviewed-by: prr, jgodinez --- .../native/sun/awt/image/awt_parseImage.c | 443 ++++++------------ .../native/sun/awt/image/awt_parseImage.h | 11 +- .../native/sun/awt/medialib/awt_ImagingLib.c | 114 +---- 3 files changed, 151 insertions(+), 417 deletions(-) diff --git a/jdk/src/share/native/sun/awt/image/awt_parseImage.c b/jdk/src/share/native/sun/awt/image/awt_parseImage.c index e11a8dbee8c..8d6e9a3ed80 100644 --- a/jdk/src/share/native/sun/awt/image/awt_parseImage.c +++ b/jdk/src/share/native/sun/awt/image/awt_parseImage.c @@ -873,363 +873,204 @@ setHints(JNIEnv *env, BufImageS_t *imageP) { return 1; } -/* - * This routine will fill in a buffer of data for either 1 band or all - * bands (if band == -1). - */ #define MAX_TO_GRAB (10240) -int awt_getPixelByte(JNIEnv *env, int band, RasterS_t *rasterP, - unsigned char *bufferP) { - int w = rasterP->width; - int h = rasterP->height; - int numBands = rasterP->numBands; +typedef union { + void *pv; + unsigned char *pb; + unsigned short *ps; +} PixelData_t; + + +int awt_getPixels(JNIEnv *env, RasterS_t *rasterP, void *bufferP) { + const int w = rasterP->width; + const int h = rasterP->height; + const int numBands = rasterP->numBands; int y; int i; - int maxLines = (h < MAX_TO_GRAB/w ? h : MAX_TO_GRAB/w); + int maxLines; jobject jsm; - int off; + int off = 0; jarray jdata = NULL; jobject jdatabuffer; int *dataP; - int maxBytes = w; + int maxSamples; + PixelData_t p; + + if (bufferP == NULL) { + return -1; + } + + if (rasterP->dataType != BYTE_DATA_TYPE && + rasterP->dataType != SHORT_DATA_TYPE) + { + return -1; + } + + p.pv = bufferP; + + if (!SAFE_TO_MULT(w, numBands)) { + return -1; + } + maxSamples = w * numBands; + + maxLines = maxSamples > MAX_TO_GRAB ? 1 : (MAX_TO_GRAB / maxSamples); + if (maxLines > h) { + maxLines = h; + } + + if (!SAFE_TO_MULT(maxSamples, maxLines)) { + return -1; + } + + maxSamples *= maxLines; jsm = (*env)->GetObjectField(env, rasterP->jraster, g_RasterSampleModelID); jdatabuffer = (*env)->GetObjectField(env, rasterP->jraster, g_RasterDataBufferID); - jdata = (*env)->NewIntArray(env, maxBytes*rasterP->numBands*maxLines); + + jdata = (*env)->NewIntArray(env, maxSamples); if (JNU_IsNull(env, jdata)) { JNU_ThrowOutOfMemoryError(env, "Out of Memory"); return -1; } - /* Here is the generic code */ - if (band >= 0) { - int dOff; - if (band >= numBands) { + for (y = 0; y < h; y += maxLines) { + if (y + maxLines > h) { + maxLines = h - y; + maxSamples = w * numBands * maxLines; + } + + (*env)->CallObjectMethod(env, jsm, g_SMGetPixelsMID, + 0, y, w, + maxLines, jdata, jdatabuffer); + + if ((*env)->ExceptionOccurred(env)) { (*env)->DeleteLocalRef(env, jdata); - JNU_ThrowInternalError(env, "Band out of range."); return -1; } - off = 0; - for (y=0; y < h; ) { - (*env)->CallObjectMethod(env, jsm, g_SMGetPixelsMID, - 0, y, w, - maxLines, jdata, jdatabuffer); - dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, - NULL); - if (dataP == NULL) { - (*env)->DeleteLocalRef(env, jdata); - return -1; - } - dOff = band; - for (i=0; i < maxBytes; i++, dOff += numBands) { - bufferP[off++] = (unsigned char) dataP[dOff]; - } - (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP, - JNI_ABORT); - - if (y+maxLines < h) { - y += maxLines; - } - else { - y++; - maxBytes = w; - } - } - } - else { - off = 0; - maxBytes *= numBands; - for (y=0; y < h; ) { - (*env)->CallObjectMethod(env, jsm, g_SMGetPixelsMID, - 0, y, w, - maxLines, jdata, jdatabuffer); - dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, - NULL); - if (dataP == NULL) { - (*env)->DeleteLocalRef(env, jdata); - return -1; - } - for (i=0; i < maxBytes; i++) { - bufferP[off++] = (unsigned char) dataP[i]; - } - - (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP, - JNI_ABORT); - - if (y+maxLines < h) { - y += maxLines; - } - else { - y++; - maxBytes = w*numBands; - } - } - - } - (*env)->DeleteLocalRef(env, jdata); - - return 0; -} -int awt_setPixelByte(JNIEnv *env, int band, RasterS_t *rasterP, - unsigned char *bufferP) { - int w = rasterP->width; - int h = rasterP->height; - int numBands = rasterP->numBands; - int y; - int i; - int maxLines = (h < MAX_TO_GRAB/w ? h : MAX_TO_GRAB/w); - jobject jsm; - int off; - jarray jdata = NULL; - jobject jdatabuffer; - int *dataP; - int maxBytes = w; - - jsm = (*env)->GetObjectField(env, rasterP->jraster, g_RasterSampleModelID); - jdatabuffer = (*env)->GetObjectField(env, rasterP->jraster, - g_RasterDataBufferID); - /* Here is the generic code */ - jdata = (*env)->NewIntArray(env, maxBytes*rasterP->numBands*maxLines); - if (JNU_IsNull(env, jdata)) { - JNU_ThrowOutOfMemoryError(env, "Out of Memory"); - return -1; - } - if (band >= 0) { - int dOff; - if (band >= numBands) { + dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, + NULL); + if (dataP == NULL) { (*env)->DeleteLocalRef(env, jdata); - JNU_ThrowInternalError(env, "Band out of range."); return -1; } - off = 0; - for (y=0; y < h; y+=maxLines) { - if (y+maxLines > h) { - maxBytes = w*numBands; - maxLines = h - y; - } - dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, - NULL); - if (dataP == NULL) { - (*env)->DeleteLocalRef(env, jdata); - return -1; - } - dOff = band; - for (i=0; i < maxBytes; i++, dOff += numBands) { - dataP[dOff] = bufferP[off++]; - } - (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP, - JNI_ABORT); - - (*env)->CallVoidMethod(env, jsm, g_SMSetPixelsMID, - 0, y, w, - maxLines, jdata, jdatabuffer); - } - } - else { - off = 0; - maxBytes *= numBands; - for (y=0; y < h; y+=maxLines) { - if (y+maxLines > h) { - maxBytes = w*numBands; - maxLines = h - y; + switch (rasterP->dataType) { + case BYTE_DATA_TYPE: + for (i = 0; i < maxSamples; i ++) { + p.pb[off++] = (unsigned char) dataP[i]; } - dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, - NULL); - if (dataP == NULL) { - (*env)->DeleteLocalRef(env, jdata); - return -1; + break; + case SHORT_DATA_TYPE: + for (i = 0; i < maxSamples; i ++) { + p.ps[off++] = (unsigned short) dataP[i]; } - for (i=0; i < maxBytes; i++) { - dataP[i] = bufferP[off++]; - } - - (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP, - JNI_ABORT); - - (*env)->CallVoidMethod(env, jsm, g_SMSetPixelsMID, - 0, y, w, - maxLines, jdata, jdatabuffer); + break; } + (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP, + JNI_ABORT); } - (*env)->DeleteLocalRef(env, jdata); - return 0; + return 1; } -int awt_getPixelShort(JNIEnv *env, int band, RasterS_t *rasterP, - unsigned short *bufferP) { - int w = rasterP->width; - int h = rasterP->height; - int numBands = rasterP->numBands; + +int awt_setPixels(JNIEnv *env, RasterS_t *rasterP, void *bufferP) { + const int w = rasterP->width; + const int h = rasterP->height; + const int numBands = rasterP->numBands; + int y; int i; - int maxLines = (h < MAX_TO_GRAB/w ? h : MAX_TO_GRAB/w); + int maxLines; jobject jsm; - int off; + int off = 0; jarray jdata = NULL; jobject jdatabuffer; int *dataP; - int maxBytes = w*maxLines; + int maxSamples; + PixelData_t p; + + if (bufferP == NULL) { + return -1; + } + + if (rasterP->dataType != BYTE_DATA_TYPE && + rasterP->dataType != SHORT_DATA_TYPE) + { + return -1; + } + + p.pv = bufferP; + + if (!SAFE_TO_MULT(w, numBands)) { + return -1; + } + maxSamples = w * numBands; + + maxLines = maxSamples > MAX_TO_GRAB ? 1 : (MAX_TO_GRAB / maxSamples); + if (maxLines > h) { + maxLines = h; + } + + if (!SAFE_TO_MULT(maxSamples, maxLines)) { + return -1; + } + + maxSamples *= maxLines; jsm = (*env)->GetObjectField(env, rasterP->jraster, g_RasterSampleModelID); jdatabuffer = (*env)->GetObjectField(env, rasterP->jraster, g_RasterDataBufferID); - jdata = (*env)->NewIntArray(env, maxBytes*rasterP->numBands*maxLines); + + jdata = (*env)->NewIntArray(env, maxSamples); if (JNU_IsNull(env, jdata)) { JNU_ThrowOutOfMemoryError(env, "Out of Memory"); return -1; } - /* Here is the generic code */ - if (band >= 0) { - int dOff; - if (band >= numBands) { + + for (y = 0; y < h; y += maxLines) { + if (y + maxLines > h) { + maxLines = h - y; + maxSamples = w * numBands * maxLines; + } + dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, + NULL); + if (dataP == NULL) { (*env)->DeleteLocalRef(env, jdata); - JNU_ThrowInternalError(env, "Band out of range."); return -1; } - off = 0; - for (y=0; y < h; y += maxLines) { - if (y+maxLines > h) { - maxBytes = w*numBands; - maxLines = h - y; - } - (*env)->CallObjectMethod(env, jsm, g_SMGetPixelsMID, - 0, y, w, - maxLines, jdata, jdatabuffer); - dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, - NULL); - if (dataP == NULL) { - (*env)->DeleteLocalRef(env, jdata); - return -1; - } - dOff = band; - for (i=0; i < maxBytes; i++, dOff += numBands) { - bufferP[off++] = (unsigned short) dataP[dOff]; + switch (rasterP->dataType) { + case BYTE_DATA_TYPE: + for (i = 0; i < maxSamples; i ++) { + dataP[i] = p.pb[off++]; } - - (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP, - JNI_ABORT); - } - } - else { - off = 0; - maxBytes *= numBands; - for (y=0; y < h; y+=maxLines) { - if (y+maxLines > h) { - maxBytes = w*numBands; - maxLines = h - y; + break; + case SHORT_DATA_TYPE: + for (i = 0; i < maxSamples; i ++) { + dataP[i] = p.ps[off++]; } - (*env)->CallObjectMethod(env, jsm, g_SMGetPixelsMID, - 0, y, w, - maxLines, jdata, jdatabuffer); - dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, - NULL); - if (dataP == NULL) { - (*env)->DeleteLocalRef(env, jdata); - return -1; - } - for (i=0; i < maxBytes; i++) { - bufferP[off++] = (unsigned short) dataP[i]; - } - - (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP, - JNI_ABORT); + break; } + (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP, + JNI_ABORT); + + (*env)->CallVoidMethod(env, jsm, g_SMSetPixelsMID, + 0, y, w, + maxLines, jdata, jdatabuffer); + + if ((*env)->ExceptionOccurred(env)) { + (*env)->DeleteLocalRef(env, jdata); + return -1; + } } (*env)->DeleteLocalRef(env, jdata); - return 0; -} -int awt_setPixelShort(JNIEnv *env, int band, RasterS_t *rasterP, - unsigned short *bufferP) { - int w = rasterP->width; - int h = rasterP->height; - int numBands = rasterP->numBands; - int y; - int i; - int maxLines = (h < MAX_TO_GRAB/w ? h : MAX_TO_GRAB/w); - jobject jsm; - int off; - jarray jdata = NULL; - jobject jdatabuffer; - int *dataP; - int maxBytes = w; - - jsm = (*env)->GetObjectField(env, rasterP->jraster, g_RasterSampleModelID); - jdatabuffer = (*env)->GetObjectField(env, rasterP->jraster, - g_RasterDataBufferID); - if (band >= numBands) { - JNU_ThrowInternalError(env, "Band out of range."); - return -1; - } - /* Here is the generic code */ - jdata = (*env)->NewIntArray(env, maxBytes*rasterP->numBands*maxLines); - if (JNU_IsNull(env, jdata)) { - JNU_ThrowOutOfMemoryError(env, "Out of Memory"); - return -1; - } - if (band >= 0) { - int dOff; - off = 0; - for (y=0; y < h; y+=maxLines) { - if (y+maxLines > h) { - maxBytes = w*numBands; - maxLines = h - y; - } - dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, - NULL); - if (dataP == NULL) { - (*env)->DeleteLocalRef(env, jdata); - return -1; - } - dOff = band; - for (i=0; i < maxBytes; i++, dOff += numBands) { - dataP[dOff] = bufferP[off++]; - } - - (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP, - JNI_ABORT); - - (*env)->CallVoidMethod(env, jsm, g_SMSetPixelsMID, - 0, y, w, - maxLines, jdata, jdatabuffer); - } - } - else { - off = 0; - maxBytes *= numBands; - for (y=0; y < h; y+=maxLines) { - if (y+maxLines > h) { - maxBytes = w*numBands; - maxLines = h - y; - } - dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, - NULL); - if (dataP == NULL) { - (*env)->DeleteLocalRef(env, jdata); - return -1; - } - for (i=0; i < maxBytes; i++) { - dataP[i] = bufferP[off++]; - } - - (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP, - JNI_ABORT); - - (*env)->CallVoidMethod(env, jsm, g_SMSetPixelsMID, - 0, y, w, - maxLines, jdata, jdatabuffer); - } - - } - - (*env)->DeleteLocalRef(env, jdata); - return 0; + + return 1; } diff --git a/jdk/src/share/native/sun/awt/image/awt_parseImage.h b/jdk/src/share/native/sun/awt/image/awt_parseImage.h index b92bb0c2833..02dfd1a2154 100644 --- a/jdk/src/share/native/sun/awt/image/awt_parseImage.h +++ b/jdk/src/share/native/sun/awt/image/awt_parseImage.h @@ -188,13 +188,8 @@ void awt_freeParsedRaster(RasterS_t *rasterP, int freeRasterP); void awt_freeParsedImage(BufImageS_t *imageP, int freeImageP); -int awt_getPixelByte(JNIEnv *env, int band, RasterS_t *rasterP, - unsigned char *bufferP); -int awt_setPixelByte(JNIEnv *env, int band, RasterS_t *rasterP, - unsigned char *bufferP); -int awt_getPixelShort(JNIEnv *env, int band, RasterS_t *rasterP, - unsigned short *bufferP); -int awt_setPixelShort(JNIEnv *env, int band, RasterS_t *rasterP, - unsigned short *bufferP); +int awt_getPixels(JNIEnv *env, RasterS_t *rasterP, void *bufferP); + +int awt_setPixels(JNIEnv *env, RasterS_t *rasterP, void *bufferP); #endif /* AWT_PARSE_IMAGE_H */ diff --git a/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c b/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c index 25764213888..e3af348adda 100644 --- a/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c +++ b/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c @@ -700,22 +700,7 @@ Java_sun_awt_image_ImagingLib_convolveRaster(JNIEnv *env, jobject this, /* Means that we couldn't write directly into the destination buffer */ if (ddata == NULL) { - unsigned char *bdataP; - unsigned short *sdataP; - - /* Punt for now */ - switch (dstRasterP->dataType) { - case BYTE_DATA_TYPE: - bdataP = (unsigned char *) mlib_ImageGetData(dst); - retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ; - break; - case SHORT_DATA_TYPE: - sdataP = (unsigned short *) mlib_ImageGetData(dst); - retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ; - break; - default: - retStatus = 0; - } + retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst)); } /* Release the pinned memory */ @@ -1119,24 +1104,9 @@ fprintf(stderr,"Flags : %d\n",dst->flags); /* Means that we couldn't write directly into the destination buffer */ if (ddata == NULL) { - unsigned char *bdataP; - unsigned short *sdataP; - /* Need to store it back into the array */ if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) { - /* Punt for now */ - switch (dst->type) { - case MLIB_BYTE: - bdataP = (unsigned char *) mlib_ImageGetData(dst); - retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ; - break; - case MLIB_SHORT: - sdataP = (unsigned short *) mlib_ImageGetData(dst); - retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ; - break; - default: - retStatus = 0; - } + retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst)); } } @@ -1704,21 +1674,7 @@ Java_sun_awt_image_ImagingLib_lookupByteRaster(JNIEnv *env, * the destination buffer */ if (ddata == NULL) { - unsigned char* bdataP; - unsigned short* sdataP; - - switch (dstRasterP->dataType) { - case BYTE_DATA_TYPE: - bdataP = (unsigned char *) mlib_ImageGetData(dst); - retStatus = (awt_setPixelByte(env, -1, dstRasterP, bdataP) >= 0) ; - break; - case SHORT_DATA_TYPE: - sdataP = (unsigned short *) mlib_ImageGetData(dst); - retStatus = (awt_setPixelShort(env, -1, dstRasterP, sdataP) >= 0) ; - break; - default: - retStatus = 0; - } + retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst)); } /* Release the LUT */ @@ -2298,7 +2254,6 @@ allocateRasterArray(JNIEnv *env, RasterS_t *rasterP, mlib_image **mlibImagePP, void **dataPP, int isSrc) { void *dataP; unsigned char *cDataP; - unsigned short *sdataP; int dataType = BYTE_DATA_TYPE; int width; int height; @@ -2484,8 +2439,7 @@ allocateRasterArray(JNIEnv *env, RasterS_t *rasterP, return -1; } if (isSrc) { - cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP); - if (awt_getPixelByte(env, -1, rasterP, cDataP) < 0) { + if (awt_getPixels(env, rasterP, mlib_ImageGetData(*mlibImagePP)) < 0) { (*sMlibSysFns.deleteImageFP)(*mlibImagePP); return -1; } @@ -2499,8 +2453,7 @@ allocateRasterArray(JNIEnv *env, RasterS_t *rasterP, return -1; } if (isSrc) { - sdataP = (unsigned short *) mlib_ImageGetData(*mlibImagePP); - if (awt_getPixelShort(env, -1, rasterP, sdataP) < 0) { + if (awt_getPixels(env, rasterP, mlib_ImageGetData(*mlibImagePP)) < 0) { (*sMlibSysFns.deleteImageFP)(*mlibImagePP); return -1; } @@ -2550,60 +2503,6 @@ freeDataArray(JNIEnv *env, jobject srcJdata, mlib_image *srcmlibImP, } } -static int -storeDstArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP, - mlibHintS_t *hintP, mlib_image *mlibImP, void *ddata) { - RasterS_t *rasterP = &dstP->raster; - - /* Nothing to do since it is the same image type */ - if (srcP->imageType == dstP->imageType - && srcP->imageType != java_awt_image_BufferedImage_TYPE_CUSTOM - && srcP->imageType != java_awt_image_BufferedImage_TYPE_BYTE_INDEXED - && srcP->imageType != java_awt_image_BufferedImage_TYPE_BYTE_BINARY) { - /* REMIND: Should check the ICM LUTS to see if it is the same */ - return 0; - } - - /* These types are compatible with TYPE_INT_RGB */ - if (srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB - && (dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB || - dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE)){ - return 0; - } - - if (hintP->cvtSrcToDefault && - (srcP->cmodel.isAlphaPre == dstP->cmodel.isAlphaPre)) { - if (srcP->cmodel.isAlphaPre) { - if (dstP->imageType == - java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE) - { - return 0; - } - if (!srcP->cmodel.supportsAlpha && - dstP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB){ - return 0; - } - } - else { - /* REMIND: */ - } - } - - if (dstP->cmodel.cmType == DIRECT_CM_TYPE) { - /* Just need to move bits */ - if (mlibImP->type == MLIB_BYTE) { - return awt_setPixelByte(env, -1, &dstP->raster, - (unsigned char *) mlibImP->data); - } - else if (mlibImP->type == MLIB_SHORT) { - return awt_setPixelByte(env, -1, &dstP->raster, - (unsigned char *) mlibImP->data); - } - } - - return 0; -} - #define ERR_BAD_IMAGE_LAYOUT (-2) #define CHECK_DST_ARRAY(start_offset, elements_per_pixel) \ @@ -2716,8 +2615,7 @@ storeImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP, } } else if (mlibImP->type == MLIB_SHORT) { - return awt_setPixelShort(env, -1, rasterP, - (unsigned short *) mlibImP->data); + return awt_setPixels(env, rasterP, mlibImP->data); } } else { From 38c8e922af160aeb9e4a054cd779d63011960bd4 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Mon, 20 May 2013 14:39:17 +0400 Subject: [PATCH 0017/1294] 8013744: Better tabling for AWT Reviewed-by: art, malenkov, skoivu --- jdk/src/share/classes/javax/swing/JTable.java | 18 +++++++++++------- .../share/classes/javax/swing/UIDefaults.java | 12 +++--------- .../javax/swing/text/DefaultFormatter.java | 8 ++++++-- .../javax/swing/text/NumberFormatter.java | 6 +++++- .../classes/sun/swing/SwingLazyValue.java | 3 ++- .../classes/sun/swing/SwingUtilities2.java | 13 +++++++++++++ 6 files changed, 40 insertions(+), 20 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JTable.java b/jdk/src/share/classes/javax/swing/JTable.java index bed8e5ca93e..3bb97ddfd44 100644 --- a/jdk/src/share/classes/javax/swing/JTable.java +++ b/jdk/src/share/classes/javax/swing/JTable.java @@ -52,6 +52,7 @@ import java.text.MessageFormat; import javax.print.attribute.*; import javax.print.PrintService; +import sun.reflect.misc.ReflectUtil; import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2.Section; @@ -5462,14 +5463,15 @@ public class JTable extends JComponent implements TableModelListener, Scrollable // they have the option to replace the value with // null or use escape to restore the original. // For Strings, return "" for backward compatibility. - if ("".equals(s)) { - if (constructor.getDeclaringClass() == String.class) { - value = s; - } - return super.stopCellEditing(); - } - try { + if ("".equals(s)) { + if (constructor.getDeclaringClass() == String.class) { + value = s; + } + return super.stopCellEditing(); + } + + SwingUtilities2.checkAccess(constructor.getModifiers()); value = constructor.newInstance(new Object[]{s}); } catch (Exception e) { @@ -5493,6 +5495,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable if (type == Object.class) { type = String.class; } + ReflectUtil.checkPackageAccess(type); + SwingUtilities2.checkAccess(type.getModifiers()); constructor = type.getConstructor(argTypes); } catch (Exception e) { diff --git a/jdk/src/share/classes/javax/swing/UIDefaults.java b/jdk/src/share/classes/javax/swing/UIDefaults.java index 9f304e742c7..3bd1297dd58 100644 --- a/jdk/src/share/classes/javax/swing/UIDefaults.java +++ b/jdk/src/share/classes/javax/swing/UIDefaults.java @@ -53,6 +53,7 @@ import java.security.PrivilegedAction; import sun.reflect.misc.MethodUtil; import sun.reflect.misc.ReflectUtil; +import sun.swing.SwingUtilities2; import sun.util.CoreResourceBundleControl; /** @@ -1101,7 +1102,7 @@ public class UIDefaults extends Hashtable } ReflectUtil.checkPackageAccess(className); c = Class.forName(className, true, (ClassLoader)cl); - checkAccess(c.getModifiers()); + SwingUtilities2.checkAccess(c.getModifiers()); if (methodName != null) { Class[] types = getClassArray(args); Method m = c.getMethod(methodName, types); @@ -1109,7 +1110,7 @@ public class UIDefaults extends Hashtable } else { Class[] types = getClassArray(args); Constructor constructor = c.getConstructor(types); - checkAccess(constructor.getModifiers()); + SwingUtilities2.checkAccess(constructor.getModifiers()); return constructor.newInstance(args); } } catch(Exception e) { @@ -1124,13 +1125,6 @@ public class UIDefaults extends Hashtable }, acc); } - private void checkAccess(int modifiers) { - if(System.getSecurityManager() != null && - !Modifier.isPublic(modifiers)) { - throw new SecurityException("Resource is not accessible"); - } - } - /* * Coerce the array of class types provided into one which * looks the way the Reflection APIs expect. This is done diff --git a/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java b/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java index b67966ab70a..ac5bc72e76f 100644 --- a/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java +++ b/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java @@ -24,7 +24,8 @@ */ package javax.swing.text; -import sun.reflect.misc.ConstructorUtil; +import sun.reflect.misc.ReflectUtil; +import sun.swing.SwingUtilities2; import java.io.Serializable; import java.lang.reflect.*; @@ -247,7 +248,9 @@ public class DefaultFormatter extends JFormattedTextField.AbstractFormatter Constructor cons; try { - cons = ConstructorUtil.getConstructor(vc, new Class[]{String.class}); + ReflectUtil.checkPackageAccess(vc); + SwingUtilities2.checkAccess(vc.getModifiers()); + cons = vc.getConstructor(new Class[]{String.class}); } catch (NoSuchMethodException nsme) { cons = null; @@ -255,6 +258,7 @@ public class DefaultFormatter extends JFormattedTextField.AbstractFormatter if (cons != null) { try { + SwingUtilities2.checkAccess(cons.getModifiers()); return cons.newInstance(new Object[] { string }); } catch (Throwable ex) { throw new ParseException("Error creating instance", 0); diff --git a/jdk/src/share/classes/javax/swing/text/NumberFormatter.java b/jdk/src/share/classes/javax/swing/text/NumberFormatter.java index 9500dcc03b7..672a92e5b63 100644 --- a/jdk/src/share/classes/javax/swing/text/NumberFormatter.java +++ b/jdk/src/share/classes/javax/swing/text/NumberFormatter.java @@ -27,6 +27,8 @@ package javax.swing.text; import java.lang.reflect.*; import java.text.*; import java.util.*; +import sun.reflect.misc.ReflectUtil; +import sun.swing.SwingUtilities2; /** * NumberFormatter subclasses InternationalFormatter @@ -427,10 +429,12 @@ public class NumberFormatter extends InternationalFormatter { valueClass = value.getClass(); } try { + ReflectUtil.checkPackageAccess(valueClass); + SwingUtilities2.checkAccess(valueClass.getModifiers()); Constructor cons = valueClass.getConstructor( new Class[] { String.class }); - if (cons != null) { + SwingUtilities2.checkAccess(cons.getModifiers()); return cons.newInstance(new Object[]{string}); } } catch (Throwable ex) { } diff --git a/jdk/src/share/classes/sun/swing/SwingLazyValue.java b/jdk/src/share/classes/sun/swing/SwingLazyValue.java index 2d1aa9cf847..a9e6f2c1bc8 100644 --- a/jdk/src/share/classes/sun/swing/SwingLazyValue.java +++ b/jdk/src/share/classes/sun/swing/SwingLazyValue.java @@ -30,6 +30,7 @@ import java.lang.reflect.AccessibleObject; import java.security.AccessController; import java.security.PrivilegedAction; import javax.swing.UIDefaults; +import sun.reflect.misc.ReflectUtil; /** * SwingLazyValue is a copy of ProxyLazyValue that does not snapshot the @@ -63,7 +64,7 @@ public class SwingLazyValue implements UIDefaults.LazyValue { public Object createValue(final UIDefaults table) { try { - Object cl; + ReflectUtil.checkPackageAccess(className); Class c = Class.forName(className, true, null); if (methodName != null) { Class[] types = getClassArray(args); diff --git a/jdk/src/share/classes/sun/swing/SwingUtilities2.java b/jdk/src/share/classes/sun/swing/SwingUtilities2.java index c6134885adf..57f7bb39cdc 100644 --- a/jdk/src/share/classes/sun/swing/SwingUtilities2.java +++ b/jdk/src/share/classes/sun/swing/SwingUtilities2.java @@ -1311,6 +1311,19 @@ public class SwingUtilities2 { } } + /** + * Utility method that throws SecurityException if SecurityManager is set + * and modifiers are not public + * + * @param modifiers a set of modifiers + */ + public static void checkAccess(int modifiers) { + if (System.getSecurityManager() != null + && !Modifier.isPublic(modifiers)) { + throw new SecurityException("Resource is not accessible"); + } + } + /** * Returns true if EventQueue.getCurrentEvent() has the permissions to * access the system clipboard and if it is allowed gesture (if From 9a9e180fdd52a65f07849cdd40c72bacd150b99d Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Mon, 20 May 2013 15:26:42 +0400 Subject: [PATCH 0018/1294] 8014102: Improve image conversion Reviewed-by: mschoene, prr, jgodinez --- .../native/sun/awt/medialib/awt_ImagingLib.c | 94 +++++++++++++------ 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c b/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c index e3af348adda..5b5f2acda71 100644 --- a/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c +++ b/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c @@ -1985,21 +1985,25 @@ expandPacked(JNIEnv *env, BufImageS_t *img, ColorModelS_t *cmP, return 0; } +#define NUM_LINES 10 + static int cvtCustomToDefault(JNIEnv *env, BufImageS_t *imageP, int component, unsigned char *dataP) { - ColorModelS_t *cmP = &imageP->cmodel; - RasterS_t *rasterP = &imageP->raster; + const RasterS_t *rasterP = &imageP->raster; + const int w = rasterP->width; + const int h = rasterP->height; + int y; - jobject jpixels = NULL; + jintArray jpixels = NULL; jint *pixels; unsigned char *dP = dataP; -#define NUM_LINES 10 - int numLines = NUM_LINES; + int numLines = h > NUM_LINES ? NUM_LINES : h; + /* it is safe to calculate the scan length, because width has been verified * on creation of the mlib image */ - int scanLength = rasterP->width * 4; + const int scanLength = w * 4; int nbytes = 0; if (!SAFE_TO_MULT(numLines, scanLength)) { @@ -2008,42 +2012,70 @@ cvtCustomToDefault(JNIEnv *env, BufImageS_t *imageP, int component, nbytes = numLines * scanLength; - for (y=0; y < rasterP->height; y+=numLines) { - /* getData, one scanline at a time */ - if (y+numLines > rasterP->height) { - numLines = rasterP->height - y; + jpixels = (*env)->NewIntArray(env, nbytes); + if (JNU_IsNull(env, jpixels)) { + JNU_ThrowOutOfMemoryError(env, "Out of Memory"); + return -1; + } + + for (y = 0; y < h; y += numLines) { + if (y + numLines > h) { + numLines = h - y; nbytes = numLines * scanLength; } - jpixels = (*env)->CallObjectMethod(env, imageP->jimage, - g_BImgGetRGBMID, 0, y, - rasterP->width, numLines, - jpixels,0, rasterP->width); - if (jpixels == NULL) { - JNU_ThrowInternalError(env, "Can't retrieve pixels."); + + (*env)->CallObjectMethod(env, imageP->jimage, + g_BImgGetRGBMID, 0, y, + w, numLines, + jpixels, 0, w); + if ((*env)->ExceptionOccurred(env)) { + (*env)->DeleteLocalRef(env, jpixels); return -1; } pixels = (*env)->GetPrimitiveArrayCritical(env, jpixels, NULL); + if (pixels == NULL) { + (*env)->DeleteLocalRef(env, jpixels); + return -1; + } + memcpy(dP, pixels, nbytes); dP += nbytes; + (*env)->ReleasePrimitiveArrayCritical(env, jpixels, pixels, JNI_ABORT); } + + /* Need to release the array */ + (*env)->DeleteLocalRef(env, jpixels); + return 0; } static int cvtDefaultToCustom(JNIEnv *env, BufImageS_t *imageP, int component, unsigned char *dataP) { - ColorModelS_t *cmP = &imageP->cmodel; - RasterS_t *rasterP = &imageP->raster; + const RasterS_t *rasterP = &imageP->raster; + const int w = rasterP->width; + const int h = rasterP->height; + int y; + jintArray jpixels = NULL; jint *pixels; unsigned char *dP = dataP; -#define NUM_LINES 10 - int numLines = NUM_LINES; - int nbytes = rasterP->width*4*NUM_LINES; - jintArray jpixels; + int numLines = h > NUM_LINES ? NUM_LINES : h; + + /* it is safe to calculate the scan length, because width has been verified + * on creation of the mlib image + */ + const int scanLength = w * 4; + + int nbytes = 0; + if (!SAFE_TO_MULT(numLines, scanLength)) { + return -1; + } + + nbytes = numLines * scanLength; jpixels = (*env)->NewIntArray(env, nbytes); if (JNU_IsNull(env, jpixels)) { @@ -2051,14 +2083,15 @@ cvtDefaultToCustom(JNIEnv *env, BufImageS_t *imageP, int component, return -1; } - for (y=0; y < rasterP->height; y+=NUM_LINES) { - if (y+numLines > rasterP->height) { - numLines = rasterP->height - y; - nbytes = rasterP->width*4*numLines; + for (y = 0; y < h; y += numLines) { + if (y + numLines > h) { + numLines = h - y; + nbytes = numLines * scanLength; } + pixels = (*env)->GetPrimitiveArrayCritical(env, jpixels, NULL); if (pixels == NULL) { - /* JNI error */ + (*env)->DeleteLocalRef(env, jpixels); return -1; } @@ -2067,12 +2100,11 @@ cvtDefaultToCustom(JNIEnv *env, BufImageS_t *imageP, int component, (*env)->ReleasePrimitiveArrayCritical(env, jpixels, pixels, 0); - /* setData, one scanline at a time */ - /* Fix 4223648, 4184283 */ (*env)->CallVoidMethod(env, imageP->jimage, g_BImgSetRGBMID, 0, y, - rasterP->width, numLines, jpixels, 0, - rasterP->width); + w, numLines, jpixels, + 0, w); if ((*env)->ExceptionOccurred(env)) { + (*env)->DeleteLocalRef(env, jpixels); return -1; } } From 5c6c0246ccc0e07d49ec855a939deb8b1ac42e54 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 20 May 2013 19:49:20 +0400 Subject: [PATCH 0019/1294] 8012071: Better Building of Beans Reviewed-by: art, skoivu --- jdk/src/share/classes/java/beans/Beans.java | 6 ++++++ .../beans/DefaultPersistenceDelegate.java | 3 +++ .../share/classes/java/beans/MetaData.java | 19 +++++++++++-------- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/jdk/src/share/classes/java/beans/Beans.java b/jdk/src/share/classes/java/beans/Beans.java index 2183d224167..a457fa41805 100644 --- a/jdk/src/share/classes/java/beans/Beans.java +++ b/jdk/src/share/classes/java/beans/Beans.java @@ -42,6 +42,8 @@ import java.io.ObjectInputStream; import java.io.ObjectStreamClass; import java.io.StreamCorruptedException; +import java.lang.reflect.Modifier; + import java.net.URL; import java.security.AccessController; @@ -222,6 +224,10 @@ public class Beans { throw ex; } + if (!Modifier.isPublic(cl.getModifiers())) { + throw new ClassNotFoundException("" + cl + " : no public access"); + } + /* * Try to instantiate the class. */ diff --git a/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java b/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java index 3c6c7c2a3d3..6891692c30b 100644 --- a/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java +++ b/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java @@ -221,6 +221,9 @@ public class DefaultPersistenceDelegate extends PersistenceDelegate { // Write out the properties of this instance. private void initBean(Class type, Object oldInstance, Object newInstance, Encoder out) { for (Field field : type.getFields()) { + if (!ReflectUtil.isPackageAccessible(field.getDeclaringClass())) { + continue; + } int mod = field.getModifiers(); if (Modifier.isFinal(mod) || Modifier.isStatic(mod) || Modifier.isTransient(mod)) { continue; diff --git a/jdk/src/share/classes/java/beans/MetaData.java b/jdk/src/share/classes/java/beans/MetaData.java index 61f51d4bb3f..d733b6f1eab 100644 --- a/jdk/src/share/classes/java/beans/MetaData.java +++ b/jdk/src/share/classes/java/beans/MetaData.java @@ -42,6 +42,7 @@ import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.lang.reflect.InvocationTargetException; import java.security.AccessController; @@ -56,7 +57,7 @@ import javax.swing.plaf.ColorUIResource; import sun.swing.PrintColorUIResource; -import java.util.Objects; +import static sun.reflect.misc.ReflectUtil.isPackageAccessible; /* * Like the Intropector, the MetaData class @@ -850,13 +851,15 @@ static final class java_awt_AWTKeyStroke_PersistenceDelegate extends Persistence static class StaticFieldsPersistenceDelegate extends PersistenceDelegate { protected void installFields(Encoder out, Class cls) { - Field fields[] = cls.getFields(); - for(int i = 0; i < fields.length; i++) { - Field field = fields[i]; - // Don't install primitives, their identity will not be preserved - // by wrapping. - if (Object.class.isAssignableFrom(field.getType())) { - out.writeExpression(new Expression(field, "get", new Object[]{null})); + if (Modifier.isPublic(cls.getModifiers()) && isPackageAccessible(cls)) { + Field fields[] = cls.getFields(); + for(int i = 0; i < fields.length; i++) { + Field field = fields[i]; + // Don't install primitives, their identity will not be preserved + // by wrapping. + if (Object.class.isAssignableFrom(field.getType())) { + out.writeExpression(new Expression(field, "get", new Object[]{null})); + } } } } From d86660d21bbc69c1991b3d7ea3ce582e080cfcdb Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 31 May 2013 21:25:42 +0400 Subject: [PATCH 0020/1294] 8012277: Improve AWT DataFlavor Reviewed-by: art, skoivu --- .../java/awt/datatransfer/DataFlavor.java | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java b/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java index acbc0fe659d..3c1691545f4 100644 --- a/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java +++ b/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java @@ -30,6 +30,9 @@ import java.nio.*; import java.util.*; import sun.awt.datatransfer.DataTransferer; +import sun.reflect.misc.ReflectUtil; + +import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION; /** * A {@code DataFlavor} provides meta information about data. {@code DataFlavor} @@ -116,26 +119,36 @@ public class DataFlavor implements Externalizable, Cloneable { ClassLoader fallback) throws ClassNotFoundException { - ClassLoader systemClassLoader = (ClassLoader) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - ClassLoader cl = Thread.currentThread(). - getContextClassLoader(); - return (cl != null) - ? cl - : ClassLoader.getSystemClassLoader(); - } - }); - + ReflectUtil.checkPackageAccess(className); try { - return Class.forName(className, true, systemClassLoader); - } catch (ClassNotFoundException e2) { - if (fallback != null) { - return Class.forName(className, true, fallback); - } else { - throw new ClassNotFoundException(className); + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(GET_CLASSLOADER_PERMISSION); } + ClassLoader loader = ClassLoader.getSystemClassLoader(); + try { + // bootstrap class loader and system class loader if present + return Class.forName(className, true, loader); + } + catch (ClassNotFoundException exception) { + // thread context class loader if and only if present + loader = Thread.currentThread().getContextClassLoader(); + if (loader != null) { + try { + return Class.forName(className, true, loader); + } + catch (ClassNotFoundException e) { + // fallback to user's class loader + } + } + } + } catch (SecurityException exception) { + // ignore secured class loaders + } + if (fallback != null) { + return Class.forName(className, true, fallback); + } else { + throw new ClassNotFoundException(className); } } From 81621f63cad78c5a6ebf95d536a2e887bf253f08 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 8 May 2013 09:21:59 +0800 Subject: [PATCH 0021/1294] 8014341: Better service from Kerberos servers Read incoming data safely and take care of null return value Reviewed-by: valeriep, ahgross --- jdk/src/share/classes/sun/security/krb5/KdcComm.java | 12 ++++++++---- .../sun/security/krb5/internal/NetClient.java | 10 +++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/sun/security/krb5/KdcComm.java b/jdk/src/share/classes/sun/security/krb5/KdcComm.java index 80c0af48e00..c3048aaf64a 100644 --- a/jdk/src/share/classes/sun/security/krb5/KdcComm.java +++ b/jdk/src/share/classes/sun/security/krb5/KdcComm.java @@ -246,11 +246,15 @@ public final class KdcComm { savedException = e; } } - if (ibuf == null && savedException != null) { - if (savedException instanceof IOException) { - throw (IOException) savedException; + if (ibuf == null) { + if (savedException != null) { + if (savedException instanceof IOException) { + throw (IOException) savedException; + } else { + throw (KrbException) savedException; + } } else { - throw (KrbException) savedException; + throw new IOException("Cannot get a KDC reply"); } } return ibuf; diff --git a/jdk/src/share/classes/sun/security/krb5/internal/NetClient.java b/jdk/src/share/classes/sun/security/krb5/internal/NetClient.java index 1f5b15bb7e6..7502cf00e9a 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/NetClient.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/NetClient.java @@ -31,6 +31,8 @@ package sun.security.krb5.internal; +import sun.misc.IOUtils; + import java.io.*; import java.net.*; @@ -100,17 +102,15 @@ class TCPClient extends NetClient { return null; } - byte data[] = new byte[len]; - count = readFully(data, len); - if (count != len) { + try { + return IOUtils.readFully(in, len, true); + } catch (IOException ioe) { if (Krb5.DEBUG) { System.out.println( ">>>DEBUG: TCPClient could not read complete packet (" + len + "/" + count + ")"); } return null; - } else { - return data; } } From c7d65c420780466e944fdf59f3a5140c73c2d8cf Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 13 Jun 2013 10:21:06 +0800 Subject: [PATCH 0022/1294] 8013739: Better LDAP resource management Reviewed-by: ahgross, mchung, xuelei --- .../com/sun/jndi/ldap/VersionHelper12.java | 15 ++++++++---- jdk/src/share/classes/java/lang/System.java | 4 ++++ jdk/src/share/classes/java/lang/Thread.java | 24 +++++++++++++++++-- .../classes/sun/misc/JavaLangAccess.java | 8 +++++++ 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/VersionHelper12.java b/jdk/src/share/classes/com/sun/jndi/ldap/VersionHelper12.java index 9e8854a460c..63e6bd280ba 100644 --- a/jdk/src/share/classes/com/sun/jndi/ldap/VersionHelper12.java +++ b/jdk/src/share/classes/com/sun/jndi/ldap/VersionHelper12.java @@ -25,11 +25,12 @@ package com.sun.jndi.ldap; -import java.net.URL; import java.net.URLClassLoader; import java.net.MalformedURLException; +import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; +import sun.misc.SharedSecrets; final class VersionHelper12 extends VersionHelper { @@ -82,12 +83,16 @@ final class VersionHelper12 extends VersionHelper { } Thread createThread(final Runnable r) { + final AccessControlContext acc = AccessController.getContext(); + // 4290486: doPrivileged is needed to create a thread in + // an environment that restricts "modifyThreadGroup". return AccessController.doPrivileged( - new PrivilegedAction() { - public Thread run() { - return new Thread(r); + new PrivilegedAction() { + public Thread run() { + return SharedSecrets.getJavaLangAccess() + .newThreadWithAcc(r, acc); + } } - } ); } } diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java index 52a5e0de823..445b4e1a959 100644 --- a/jdk/src/share/classes/java/lang/System.java +++ b/jdk/src/share/classes/java/lang/System.java @@ -26,6 +26,7 @@ package java.lang; import java.io.*; import java.lang.reflect.Executable; +import java.security.AccessControlContext; import java.util.Properties; import java.util.PropertyPermission; import java.util.StringTokenizer; @@ -1251,6 +1252,9 @@ public final class System { public String newStringUnsafe(char[] chars) { return new String(chars, true); } + public Thread newThreadWithAcc(Runnable target, AccessControlContext acc) { + return new Thread(target, acc); + } }); } } diff --git a/jdk/src/share/classes/java/lang/Thread.java b/jdk/src/share/classes/java/lang/Thread.java index bb175ff89ad..d97f03d4e24 100644 --- a/jdk/src/share/classes/java/lang/Thread.java +++ b/jdk/src/share/classes/java/lang/Thread.java @@ -340,6 +340,15 @@ class Thread implements Runnable { sleep(millis); } + /** + * Initializes a Thread with the current AccessControlContext. + * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext) + */ + private void init(ThreadGroup g, Runnable target, String name, + long stackSize) { + init(g, target, name, stackSize, null); + } + /** * Initializes a Thread. * @@ -348,9 +357,11 @@ class Thread implements Runnable { * @param name the name of the new Thread * @param stackSize the desired stack size for the new thread, or * zero to indicate that this parameter is to be ignored. + * @param acc the AccessControlContext to inherit, or + * AccessController.getContext() if null */ private void init(ThreadGroup g, Runnable target, String name, - long stackSize) { + long stackSize, AccessControlContext acc) { if (name == null) { throw new NullPointerException("name cannot be null"); } @@ -396,7 +407,8 @@ class Thread implements Runnable { this.contextClassLoader = parent.getContextClassLoader(); else this.contextClassLoader = parent.contextClassLoader; - this.inheritedAccessControlContext = AccessController.getContext(); + this.inheritedAccessControlContext = + acc != null ? acc : AccessController.getContext(); this.target = target; setPriority(priority); if (parent.inheritableThreadLocals != null) @@ -448,6 +460,14 @@ class Thread implements Runnable { init(null, target, "Thread-" + nextThreadNum(), 0); } + /** + * Creates a new Thread that inherits the given AccessControlContext. + * This is not a public constructor. + */ + Thread(Runnable target, AccessControlContext acc) { + init(null, target, "Thread-" + nextThreadNum(), 0, acc); + } + /** * Allocates a new {@code Thread} object. This constructor has the same * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} diff --git a/jdk/src/share/classes/sun/misc/JavaLangAccess.java b/jdk/src/share/classes/sun/misc/JavaLangAccess.java index 888d4ea8c46..45222f3652e 100644 --- a/jdk/src/share/classes/sun/misc/JavaLangAccess.java +++ b/jdk/src/share/classes/sun/misc/JavaLangAccess.java @@ -27,6 +27,8 @@ package sun.misc; import java.lang.annotation.Annotation; import java.lang.reflect.Executable; +import java.security.AccessControlContext; + import sun.reflect.ConstantPool; import sun.reflect.annotation.AnnotationType; import sun.nio.ch.Interruptible; @@ -107,4 +109,10 @@ public interface JavaLangAccess { * @return a newly created string whose content is the character array */ String newStringUnsafe(char[] chars); + + /** + * Returns a new Thread with the given Runnable and an + * inherited AccessControlContext. + */ + Thread newThreadWithAcc(Runnable target, AccessControlContext acc); } From 0be0627640342d268cad10b1aa1e47fc92312162 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 13 Jun 2013 10:31:21 +0800 Subject: [PATCH 0023/1294] 8015731: Subject java.security.auth.subject to improvements Reviewed-by: skoivu, mullan --- jdk/src/share/classes/javax/security/auth/Subject.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/javax/security/auth/Subject.java b/jdk/src/share/classes/javax/security/auth/Subject.java index 1caaad400e2..1128d8c1011 100644 --- a/jdk/src/share/classes/javax/security/auth/Subject.java +++ b/jdk/src/share/classes/javax/security/auth/Subject.java @@ -1297,8 +1297,14 @@ public final class Subject implements java.io.Serializable { { ObjectInputStream.GetField fields = ois.readFields(); subject = (Subject) fields.get("this$0", null); - elements = (LinkedList) fields.get("elements", null); which = fields.get("which", 0); + + LinkedList tmp = (LinkedList) fields.get("elements", null); + if (tmp.getClass() != LinkedList.class) { + elements = new LinkedList(tmp); + } else { + elements = tmp; + } } } From 73c5ae165c4ba53d8d168683c24af3241ccb5233 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Thu, 13 Jun 2013 12:14:37 -0700 Subject: [PATCH 0024/1294] 8014098: Better profile validation Reviewed-by: bae, mschoene, prr --- .../share/native/sun/java2d/cmm/lcms/cmsio0.c | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c index 5bad907e2d7..a18d75c3b5b 100644 --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c @@ -1074,6 +1074,27 @@ cmsHPROFILE CMSEXPORT cmsOpenProfileFromMem(const void* MemPtr, cmsUInt32Number } +static +cmsBool SanityCheck(_cmsICCPROFILE* profile) +{ + cmsIOHANDLER* io = profile->IOhandler; + if (!io) { + return FALSE; + } + + if (!io->Seek || + !(io->Seek==NULLSeek || io->Seek==MemorySeek || io->Seek==FileSeek)) + { + return FALSE; + } + if (!io->Read || + !(io->Read==NULLRead || io->Read==MemoryRead || io->Read==FileRead)) + { + return FALSE; + } + + return TRUE; +} // Dump tag contents. If the profile is being modified, untouched tags are copied from FileOrig static @@ -1087,6 +1108,7 @@ cmsBool SaveTags(_cmsICCPROFILE* Icc, _cmsICCPROFILE* FileOrig) cmsTagTypeSignature TypeBase; cmsTagTypeHandler* TypeHandler; + if (!SanityCheck(FileOrig)) return FALSE; for (i=0; i < Icc -> TagCount; i++) { @@ -1292,8 +1314,8 @@ cmsBool CMSEXPORT cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr, cmsUIn // Should we just calculate the needed space? if (MemPtr == NULL) { - *BytesNeeded = cmsSaveProfileToIOhandler(hProfile, NULL); - return TRUE; + *BytesNeeded = cmsSaveProfileToIOhandler(hProfile, NULL); + return (*BytesNeeded == 0 ? FALSE : TRUE); } // That is a real write operation From a968eabd507357fa7bb923eb8098dd420ebd8685 Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Fri, 14 Jun 2013 15:49:41 +0100 Subject: [PATCH 0025/1294] 8011157: Improve CORBA portablility Fix also reviewed by Alexander Fomin Reviewed-by: alanb, coffeys, skoivu --- common/makefiles/RMICompilation.gmk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/makefiles/RMICompilation.gmk b/common/makefiles/RMICompilation.gmk index 4727412e958..acbc7054ceb 100644 --- a/common/makefiles/RMICompilation.gmk +++ b/common/makefiles/RMICompilation.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,11 +60,11 @@ define SetupRMICompilation ifneq (,$$($1_RUN_IIOP)) $1_TARGETS += $$($1_TIE_FILES) - $1_ARGS += -iiop + $1_ARGS += -iiop -emitPermissionCheck endif ifneq (,$$($1_RUN_IIOP_STDPKG)) $1_TARGETS += $$($1_TIE_STDPKG_FILES) - $1_ARGS2 := -iiop -standardPackage + $1_ARGS2 := -iiop -emitPermissionCheck -standardPackage endif ifneq (,$$($1_KEEP_GENERATED)) From ae96f935a2cb24cf785ee38817c46fd42519bc69 Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Fri, 14 Jun 2013 15:49:54 +0100 Subject: [PATCH 0026/1294] 8011157: Improve CORBA portablility Fix also reviewed by Alexander Fomin Reviewed-by: alanb, coffeys, skoivu --- jdk/make/com/sun/jmx/Makefile | 2 ++ .../modelmbean/RequiredModelMBean.java | 8 ++++++-- .../management/remote/rmi/RMIConnector.java | 18 +++++++++++++----- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/jdk/make/com/sun/jmx/Makefile b/jdk/make/com/sun/jmx/Makefile index 62435751673..02ef6b07998 100644 --- a/jdk/make/com/sun/jmx/Makefile +++ b/jdk/make/com/sun/jmx/Makefile @@ -130,11 +130,13 @@ $(CLASSDESTDIR)/%_Stub.class: $(CLASSDESTDIR)/%.class $(RMIC) -classpath "$(CLASSDESTDIR)" \ -d $(CLASSDESTDIR) \ -iiop -v1.2 \ + -emitPermissionCheck \ $(subst /,.,$(<:$(CLASSDESTDIR)/%.class=%)) $(RMIC) $(HOTSPOT_INTERPRETER_FLAG) -classpath "$(CLASSDESTDIR)" \ -d $(CLASSDESTDIR) \ -iiop -v1.2 \ -standardPackage \ + -emitPermissionCheck \ $(subst /,.,$(<:$(CLASSDESTDIR)/%.class=%)) @$(java-vm-cleanup) diff --git a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java index 6d28adaf0f7..0afd70f9423 100644 --- a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java +++ b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -298,11 +298,15 @@ public class RequiredModelMBean RequiredModelMBean.class.getName(), "setModelMBeanInfo(ModelMBeanInfo)", "Setting ModelMBeanInfo to " + printModelMBeanInfo(mbi)); + int noOfNotifications = 0; + if (mbi.getNotifications() != null) { + noOfNotifications = mbi.getNotifications().length; + } MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), "setModelMBeanInfo(ModelMBeanInfo)", "ModelMBeanInfo notifications has " + - (mbi.getNotifications()).length + " elements"); + noOfNotifications + " elements"); } modelMBeanInfo = (ModelMBeanInfo)mbi.clone(); diff --git a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java index 53e6754e6ed..4ddfb8fee38 100644 --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,6 +61,7 @@ import java.rmi.server.RemoteRef; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; +import java.security.PrivilegedActionException; import java.security.ProtectionDomain; import java.util.Arrays; import java.util.Collections; @@ -128,7 +129,6 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable Map environment) { if (rmiServer == null && address == null) throw new IllegalArgumentException("rmiServer and jmxServiceURL both null"); - initTransients(); this.rmiServer = rmiServer; @@ -2370,13 +2370,21 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable } } - private static RMIConnection shadowIiopStub(Object stub) + private static RMIConnection shadowIiopStub(Object stub) throws InstantiationException, IllegalAccessException { - Object proxyStub = proxyStubClass.newInstance(); + Object proxyStub = null; + try { + proxyStub = AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + return proxyStubClass.newInstance(); + } + }); + } catch (PrivilegedActionException e) { + throw new InternalError(); + } IIOPHelper.setDelegate(proxyStub, IIOPHelper.getDelegate(stub)); return (RMIConnection) proxyStub; } - private static RMIConnection getConnection(RMIServer server, Object credentials, boolean checkStub) From 3f85c00fb2c68a4762e7b8851eb9c06158fd4146 Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Fri, 14 Jun 2013 16:31:55 +0100 Subject: [PATCH 0027/1294] 8011157: Improve CORBA portablility Fix also reviewed by Alexander Fomin Reviewed-by: alanb, coffeys, skoivu --- .../corba/se/impl/transport/SelectorImpl.java | 4 +- .../sun/rmi/rmic/iiop/StubGenerator.java | 75 ++++++++++++++++++- 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java index 7bd98805ab7..054071b7d8b 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java +++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ import com.sun.corba.se.impl.orbutil.ORBUtility; /** * @author Harold Carr */ -public class SelectorImpl +class SelectorImpl extends Thread implements diff --git a/corba/src/share/classes/sun/rmi/rmic/iiop/StubGenerator.java b/corba/src/share/classes/sun/rmi/rmic/iiop/StubGenerator.java index aa3c6bea2f5..0d41c1edb90 100644 --- a/corba/src/share/classes/sun/rmi/rmic/iiop/StubGenerator.java +++ b/corba/src/share/classes/sun/rmi/rmic/iiop/StubGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,9 @@ package sun.rmi.rmic.iiop; import java.io.File; import java.io.IOException; +import java.io.SerializablePermission; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Vector; import java.util.Hashtable; import java.util.Enumeration; @@ -49,6 +52,7 @@ import com.sun.corba.se.impl.util.Utility; import com.sun.corba.se.impl.util.PackagePrefixChecker; import sun.rmi.rmic.Main; + /** * An IIOP stub/tie generator for rmic. * @@ -78,6 +82,7 @@ public class StubGenerator extends sun.rmi.rmic.iiop.Generator { protected boolean castArray = false; protected Hashtable transactionalObjects = new Hashtable() ; protected boolean POATie = false ; + protected boolean emitPermissionCheck = false; /** * Default constructor for Main to use. @@ -193,6 +198,9 @@ public class StubGenerator extends sun.rmi.rmic.iiop.Generator { } else if (argv[i].equals("-standardPackage")) { standardPackage = true; argv[i] = null; + } else if (argv[i].equals("-emitPermissionCheck")) { + emitPermissionCheck = true; + argv[i] = null; } else if (arg.equals("-xstubbase")) { argv[i] = null; if (++i < argv.length && argv[i] != null && !argv[i].startsWith("-")) { @@ -390,9 +398,22 @@ public class StubGenerator extends sun.rmi.rmic.iiop.Generator { writePackageAndImports(p); +// generate +// import java.security.AccessController; +// import java.security.PrivilegedAction; +// import java.io.SerializablePermission; + if (emitPermissionCheck) { + p.pln("import java.security.AccessController;"); + p.pln("import java.security.PrivilegedAction;"); + p.pln("import java.io.SerializablePermission;"); + p.pln(); + p.pln(); + } + // Declare the stub class; implement all remote interfaces. p.p("public class " + currentClass); + p.p(" extends " + getName(stubBaseClass)); p.p(" implements "); if (remoteInterfaces.length > 0) { @@ -422,6 +443,57 @@ public class StubGenerator extends sun.rmi.rmic.iiop.Generator { writeIds( p, theType, false ); p.pln(); + if (emitPermissionCheck) { + + // produce the following generated code for example + // private static Void checkPermission() { + // SecurityManager sm = System.getSecurityManager(); + // if (sm != null) { + // sm.checkPermission(new SerializablePermission( + // "enableSubclassImplementation")); // testing + // } + // return null; + // } + // + // private _XXXXX_Stub(Void ignore) { + // } + // + // public _XXXXX_Stub() { + // this(checkPermission()); + // } + // + // where XXXXX is the name of the remote interface + + p.pln(); + p.plnI("private static Void checkPermission() {"); + p.plnI("SecurityManager sm = System.getSecurityManager();"); + p.pln("if (sm != null) {"); + p.pI(); + p.plnI("sm.checkPermission(new SerializablePermission("); + p.plnI("\"enableSubclassImplementation\"));"); + p.pO(); + p.pO(); + p.pOln("}"); + p.pln("return null;"); + p.pO(); + p.pOln("}"); + p.pln(); + p.pO(); + + p.pI(); + p.pln("private " + currentClass + "(Void ignore) { }"); + p.pln(); + + p.plnI("public " + currentClass + "() { "); + p.pln("this(checkPermission());"); + p.pOln("}"); + p.pln(); + } + + if (!emitPermissionCheck) { + p.pI(); + } + // Write the _ids() method... p.plnI("public String[] _ids() { "); @@ -815,7 +887,6 @@ public class StubGenerator extends sun.rmi.rmic.iiop.Generator { CompoundType theType) throws IOException { // Wtite the method declaration and opening brace... - String methodName = method.getName(); String methodIDLName = method.getIDLName(); From ccc1dc9103b704a619a638c35d93f689c6798d16 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Thu, 20 Jun 2013 08:51:47 +0200 Subject: [PATCH 0028/1294] 8014085: Better serialization support in JMX classes Reviewed-by: alanb, dfuchs, skoivu --- .../management/MBeanNotificationInfo.java | 22 ++++- .../javax/management/remote/JMXPrincipal.java | 23 ++++- .../management/remote/JMXServiceURL.java | 99 +++++++++++++------ .../management/remote/NotificationResult.java | 53 +++++++--- .../remote/TargetedNotification.java | 34 +++++-- 5 files changed, 176 insertions(+), 55 deletions(-) diff --git a/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java b/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java index b4bbbe80292..dfa4ab1f8ff 100644 --- a/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java @@ -25,6 +25,9 @@ package javax.management; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.util.Arrays; /** @@ -67,7 +70,7 @@ public class MBeanNotificationInfo extends MBeanFeatureInfo implements Cloneable /** * @serial The different types of the notification. */ - private final String[] types; + private String[] types; /** @see MBeanInfo#arrayGettersSafe */ private final transient boolean arrayGettersSafe; @@ -114,9 +117,8 @@ public class MBeanNotificationInfo extends MBeanFeatureInfo implements Cloneable notifType, though it doesn't explicitly allow it either. */ - if (notifTypes == null) - notifTypes = NO_TYPES; - this.types = notifTypes; + this.types = (notifTypes != null && notifTypes.length > 0) ? + notifTypes.clone() : NO_TYPES; this.arrayGettersSafe = MBeanInfo.arrayGettersSafe(this.getClass(), MBeanNotificationInfo.class); @@ -203,4 +205,16 @@ public class MBeanNotificationInfo extends MBeanFeatureInfo implements Cloneable hash ^= types[i].hashCode(); return hash; } + + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + ObjectInputStream.GetField gf = ois.readFields(); + String[] t = (String[])gf.get("types", null); + + if (t == null) { + throw new InvalidObjectException("Trying to deserialize an invalid " + + "instance of " + MBeanNotificationInfo.class + + "[types=null]"); + } + types = t.length == 0 ? t : t.clone(); + } } diff --git a/jdk/src/share/classes/javax/management/remote/JMXPrincipal.java b/jdk/src/share/classes/javax/management/remote/JMXPrincipal.java index 258c537e277..5cb0c3739bc 100644 --- a/jdk/src/share/classes/javax/management/remote/JMXPrincipal.java +++ b/jdk/src/share/classes/javax/management/remote/JMXPrincipal.java @@ -26,6 +26,9 @@ package javax.management.remote; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.io.Serializable; import java.security.Principal; @@ -64,9 +67,7 @@ public class JMXPrincipal implements Principal, Serializable { * null. */ public JMXPrincipal(String name) { - if (name == null) - throw new NullPointerException("illegal null input"); - + validate(name); this.name = name; } @@ -130,4 +131,20 @@ public class JMXPrincipal implements Principal, Serializable { public int hashCode() { return name.hashCode(); } + + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + ObjectInputStream.GetField gf = ois.readFields(); + String principalName = (String)gf.get("name", null); + try { + validate(principalName); + this.name = principalName; + } catch (NullPointerException e) { + throw new InvalidObjectException(e.getMessage()); + } + } + + private static void validate(String name) throws NullPointerException { + if (name == null) + throw new NullPointerException("illegal null input"); + } } diff --git a/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java b/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java index 143966bad68..4b1c376eda1 100644 --- a/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java +++ b/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java @@ -29,6 +29,9 @@ package javax.management.remote; import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.io.Serializable; import java.net.InetAddress; @@ -297,7 +300,7 @@ public class JMXServiceURL implements Serializable { If we're given an explicit host name that is illegal we have to reject it. (Bug 5057532.) */ try { - validateHost(host); + validateHost(host, port); } catch (MalformedURLException e) { if (logger.fineOn()) { logger.fine("JMXServiceURL", @@ -336,36 +339,82 @@ public class JMXServiceURL implements Serializable { validate(); } - private void validate() throws MalformedURLException { + private static final String INVALID_INSTANCE_MSG = + "Trying to deserialize an invalid instance of JMXServiceURL"; + private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException { + ObjectInputStream.GetField gf = inputStream.readFields(); + String h = (String)gf.get("host", null); + int p = (int)gf.get("port", -1); + String proto = (String)gf.get("protocol", null); + String url = (String)gf.get("urlPath", null); + if (proto == null || url == null || h == null) { + StringBuilder sb = new StringBuilder(INVALID_INSTANCE_MSG).append('['); + boolean empty = true; + if (proto == null) { + sb.append("protocol=null"); + empty = false; + } + if (h == null) { + sb.append(empty ? "" : ",").append("host=null"); + empty = false; + } + if (url == null) { + sb.append(empty ? "" : ",").append("urlPath=null"); + } + sb.append(']'); + throw new InvalidObjectException(sb.toString()); + } + + if (h.contains("[") || h.contains("]")) { + throw new InvalidObjectException("Invalid host name: " + h); + } + + try { + validate(proto, h, p, url); + this.protocol = proto; + this.host = h; + this.port = p; + this.urlPath = url; + } catch (MalformedURLException e) { + throw new InvalidObjectException(INVALID_INSTANCE_MSG + ": " + + e.getMessage()); + } + + } + + private void validate(String proto, String h, int p, String url) + throws MalformedURLException { // Check protocol - - final int protoEnd = indexOfFirstNotInSet(protocol, protocolBitSet, 0); - if (protoEnd == 0 || protoEnd < protocol.length() - || !alphaBitSet.get(protocol.charAt(0))) { + final int protoEnd = indexOfFirstNotInSet(proto, protocolBitSet, 0); + if (protoEnd == 0 || protoEnd < proto.length() + || !alphaBitSet.get(proto.charAt(0))) { throw new MalformedURLException("Missing or invalid protocol " + - "name: \"" + protocol + "\""); + "name: \"" + proto + "\""); } // Check host - - validateHost(); + validateHost(h, p); // Check port - - if (port < 0) - throw new MalformedURLException("Bad port: " + port); + if (p < 0) + throw new MalformedURLException("Bad port: " + p); // Check URL path - - if (urlPath.length() > 0) { - if (!urlPath.startsWith("/") && !urlPath.startsWith(";")) - throw new MalformedURLException("Bad URL path: " + urlPath); + if (url.length() > 0) { + if (!url.startsWith("/") && !url.startsWith(";")) + throw new MalformedURLException("Bad URL path: " + url); } } - private void validateHost() throws MalformedURLException { - if (host.length() == 0) { + private void validate() throws MalformedURLException { + validate(this.protocol, this.host, this.port, this.urlPath); + } + + private static void validateHost(String h, int port) + throws MalformedURLException { + + if (h.length() == 0) { if (port != 0) { throw new MalformedURLException("Cannot give port number " + "without host name"); @@ -373,12 +422,6 @@ public class JMXServiceURL implements Serializable { return; } - validateHost(host); - } - - private static void validateHost(String h) - throws MalformedURLException { - if (isNumericIPv6Address(h)) { /* We assume J2SE >= 1.4 here. Otherwise you can't use the address anyway. We can't call @@ -663,22 +706,22 @@ public class JMXServiceURL implements Serializable { /** * The value returned by {@link #getProtocol()}. */ - private final String protocol; + private String protocol; /** * The value returned by {@link #getHost()}. */ - private final String host; + private String host; /** * The value returned by {@link #getPort()}. */ - private final int port; + private int port; /** * The value returned by {@link #getURLPath()}. */ - private final String urlPath; + private String urlPath; /** * Cached result of {@link #toString()}. diff --git a/jdk/src/share/classes/javax/management/remote/NotificationResult.java b/jdk/src/share/classes/javax/management/remote/NotificationResult.java index cbc79755099..9e7cfaac31d 100644 --- a/jdk/src/share/classes/javax/management/remote/NotificationResult.java +++ b/jdk/src/share/classes/javax/management/remote/NotificationResult.java @@ -25,6 +25,9 @@ package javax.management.remote; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.io.Serializable; /** @@ -76,17 +79,7 @@ public class NotificationResult implements Serializable { public NotificationResult(long earliestSequenceNumber, long nextSequenceNumber, TargetedNotification[] targetedNotifications) { - if (targetedNotifications == null) { - final String msg = "Notifications null"; - throw new IllegalArgumentException(msg); - } - - if (earliestSequenceNumber < 0 || nextSequenceNumber < 0) - throw new IllegalArgumentException("Bad sequence numbers"); - /* We used to check nextSequenceNumber >= earliestSequenceNumber - here. But in fact the opposite can legitimately be true if - notifications have been lost. */ - + validate(targetedNotifications, earliestSequenceNumber, nextSequenceNumber); this.earliestSequenceNumber = earliestSequenceNumber; this.nextSequenceNumber = nextSequenceNumber; this.targetedNotifications = (targetedNotifications.length == 0 ? targetedNotifications : targetedNotifications.clone()); @@ -138,7 +131,39 @@ public class NotificationResult implements Serializable { getTargetedNotifications().length; } - private final long earliestSequenceNumber; - private final long nextSequenceNumber; - private final TargetedNotification[] targetedNotifications; + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + ObjectInputStream.GetField gf = ois.readFields(); + TargetedNotification[] tNotifs = (TargetedNotification[])gf.get("targetedNotifications", null); + long snStart = gf.get("earliestSequenceNumber", -1L); + long snNext = gf.get("nextSequenceNumber", -1L); + try { + validate(tNotifs, snStart, snNext); + + this.targetedNotifications = tNotifs.length == 0 ? tNotifs : tNotifs.clone(); + this.earliestSequenceNumber = snStart; + this.nextSequenceNumber = snNext; + } catch (IllegalArgumentException e) { + throw new InvalidObjectException(e.getMessage()); + } + } + + private long earliestSequenceNumber; + private long nextSequenceNumber; + private TargetedNotification[] targetedNotifications; + + private static void validate(TargetedNotification[] targetedNotifications, + long earliestSequenceNumber, + long nextSequenceNumber) + throws IllegalArgumentException { + if (targetedNotifications == null) { + final String msg = "Notifications null"; + throw new IllegalArgumentException(msg); + } + + if (earliestSequenceNumber < 0 || nextSequenceNumber < 0) + throw new IllegalArgumentException("Bad sequence numbers"); + /* We used to check nextSequenceNumber >= earliestSequenceNumber + here. But in fact the opposite can legitimately be true if + notifications have been lost. */ + } } diff --git a/jdk/src/share/classes/javax/management/remote/TargetedNotification.java b/jdk/src/share/classes/javax/management/remote/TargetedNotification.java index c4b58dfba90..03aa0ca6235 100644 --- a/jdk/src/share/classes/javax/management/remote/TargetedNotification.java +++ b/jdk/src/share/classes/javax/management/remote/TargetedNotification.java @@ -26,6 +26,9 @@ package javax.management.remote; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.io.Serializable; import javax.management.Notification; @@ -73,12 +76,9 @@ public class TargetedNotification implements Serializable { */ public TargetedNotification(Notification notification, Integer listenerID) { + validate(notification, listenerID); // If we replace integer with int... // this(notification,intValue(listenerID)); - if (notification == null) throw new - IllegalArgumentException("Invalid notification: null"); - if (listenerID == null) throw new - IllegalArgumentException("Invalid listener ID: null"); this.notif = notification; this.id = listenerID; } @@ -115,13 +115,13 @@ public class TargetedNotification implements Serializable { * @serial A notification to transmit to the other side. * @see #getNotification() **/ - private final Notification notif; + private Notification notif; /** * @serial The ID of the listener to which the notification is * targeted. * @see #getListenerID() **/ - private final Integer id; + private Integer id; //private final int id; // Needed if we use int instead of Integer... @@ -130,4 +130,26 @@ public class TargetedNotification implements Serializable { // IllegalArgumentException("Invalid listener ID: null"); // return id.intValue(); // } + + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + ObjectInputStream.GetField gf = ois.readFields(); + Notification notification = (Notification)gf.get("notif", null); + Integer listenerId = (Integer)gf.get("id", null); + try { + validate(notification, listenerId); + this.notif = notification; + this.id = listenerId; + } catch (IllegalArgumentException e) { + throw new InvalidObjectException(e.getMessage()); + } + } + + private static void validate(Notification notif, Integer id) throws IllegalArgumentException { + if (notif == null) { + throw new IllegalArgumentException("Invalid notification: null"); + } + if (id == null) { + throw new IllegalArgumentException("Invalid listener ID: null"); + } + } } From d0a47b3b30d11d264021b383ecfe09ebe62a3ecb Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Mon, 1 Jul 2013 15:17:24 +0400 Subject: [PATCH 0029/1294] 8017287: Better resource disposal Reviewed-by: prr, vadim, skoivu --- jdk/src/share/classes/sun/java2d/Disposer.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/sun/java2d/Disposer.java b/jdk/src/share/classes/sun/java2d/Disposer.java index dcedfe3846e..7be5c3acc92 100644 --- a/jdk/src/share/classes/sun/java2d/Disposer.java +++ b/jdk/src/share/classes/sun/java2d/Disposer.java @@ -155,8 +155,7 @@ public class Disposer implements Runnable { rec = null; clearDeferredRecords(); } catch (Exception e) { - System.out.println("Exception while removing reference: " + e); - e.printStackTrace(); + System.out.println("Exception while removing reference."); } } } @@ -182,7 +181,6 @@ public class Disposer implements Runnable { rec.dispose(); } catch (Exception e) { System.out.println("Exception while disposing deferred rec."); - e.printStackTrace(); } } deferredRecords.clear(); @@ -233,8 +231,7 @@ public class Disposer implements Runnable { } } } catch (Exception e) { - System.out.println("Exception while removing reference: " + e); - e.printStackTrace(); + System.out.println("Exception while removing reference."); } finally { pollingQueue = false; } From 2fc3e6741814a67fe89734348d091dea3f32e529 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Wed, 3 Jul 2013 10:14:02 +0200 Subject: [PATCH 0030/1294] 8012146: Improve tool support Reviewed-by: ksrini, dholmes, alanb, anthony --- jdk/makefiles/CompileLaunchers.gmk | 6 ++---- jdk/makefiles/Images.gmk | 5 +++++ jdk/test/Makefile | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/jdk/makefiles/CompileLaunchers.gmk b/jdk/makefiles/CompileLaunchers.gmk index 90348b6360f..253fe0231c8 100644 --- a/jdk/makefiles/CompileLaunchers.gmk +++ b/jdk/makefiles/CompileLaunchers.gmk @@ -52,8 +52,7 @@ endif ifeq ($(OPENJDK_TARGET_OS), macosx) ORIGIN_ARG:=$(call SET_EXECUTABLE_ORIGIN) else - ORIGIN_ARG:=$(call SET_EXECUTABLE_ORIGIN,$(ORIGIN_ROOT)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/jli) \ - $(call SET_EXECUTABLE_ORIGIN,$(ORIGIN_ROOT)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/jli) + ORIGIN_ARG:=$(call SET_EXECUTABLE_ORIGIN,$(ORIGIN_ROOT)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/jli) endif # @@ -62,8 +61,7 @@ endif # devloper documentation of JAWT and what worked with OpenJDK6. # ifneq ($(findstring $(OPENJDK_TARGET_OS), linux solaris),) - ORIGIN_ARG+=$(call SET_EXECUTABLE_ORIGIN,$(ORIGIN_ROOT)/lib$(OPENJDK_TARGET_CPU_LIBDIR)) \ - $(call SET_EXECUTABLE_ORIGIN,$(ORIGIN_ROOT)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)) + ORIGIN_ARG+=$(call SET_EXECUTABLE_ORIGIN,$(ORIGIN_ROOT)/lib$(OPENJDK_TARGET_CPU_LIBDIR)) endif define SetupLauncher diff --git a/jdk/makefiles/Images.gmk b/jdk/makefiles/Images.gmk index d265f4cd587..492cf544ab5 100644 --- a/jdk/makefiles/Images.gmk +++ b/jdk/makefiles/Images.gmk @@ -218,6 +218,11 @@ ifeq ($(OPENJDK_TARGET_OS), linux) JDK_LIB_FILES += jexec endif +ifneq ($(findstring $(OPENJDK_TARGET_OS), linux solaris),) # If Linux or Solaris + JDK_LIB_FILES += $(LIBRARY_PREFIX)jli$(SHARED_LIBRARY_SUFFIX) \ + $(LIBRARY_PREFIX)jawt$(SHARED_LIBRARY_SUFFIX) +endif + # Find all files to copy from $(JDK_OUTPUTDIR)/lib # Jar files are not expected to be here ALL_JDKOUT_LIB_LIST := $(call not-containing,_the.,$(filter-out %.jar,\ diff --git a/jdk/test/Makefile b/jdk/test/Makefile index de6b4a783ff..aac9ef4227b 100644 --- a/jdk/test/Makefile +++ b/jdk/test/Makefile @@ -521,7 +521,8 @@ jdk_other: $(call TestDirs, \ com/sun/org/apache/xerces \ com/sun/corba \ com/sun/tracing \ - sun/usagetracker) + sun/usagetracker \ + misc) $(call RunAgentvmBatch) # Stable agentvm testruns (minus items from PROBLEM_LIST) From f0b7243841e85efcaeda0e7789f961b8201c4d9b Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Wed, 3 Jul 2013 15:10:11 -0700 Subject: [PATCH 0031/1294] 8011071: Better crypto provider handling Reviewed-by: hawtin, valeriep --- .../com/sun/crypto/provider/DHPrivateKey.java | 18 +------ .../sun/security/ec/ECPrivateKeyImpl.java | 10 +--- .../sun/security/jgss/GSSCredentialImpl.java | 4 +- .../classes/sun/security/pkcs/PKCS8Key.java | 13 +---- .../classes/sun/security/pkcs11/P11Key.java | 48 +------------------ .../sun/security/provider/DSAPrivateKey.java | 7 +-- .../security/rsa/RSAPrivateCrtKeyImpl.java | 27 +---------- .../sun/security/rsa/RSAPrivateKeyImpl.java | 9 +--- 8 files changed, 9 insertions(+), 127 deletions(-) diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DHPrivateKey.java b/jdk/src/share/classes/com/sun/crypto/provider/DHPrivateKey.java index 1653a239960..cb50886f6eb 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DHPrivateKey.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DHPrivateKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -279,22 +279,6 @@ javax.crypto.interfaces.DHPrivateKey, Serializable { return new DHParameterSpec(this.p, this.g); } - public String toString() { - String LINE_SEP = System.getProperty("line.separator"); - - StringBuffer strbuf - = new StringBuffer("SunJCE Diffie-Hellman Private Key:" - + LINE_SEP + "x:" + LINE_SEP - + Debug.toHexString(this.x) - + LINE_SEP + "p:" + LINE_SEP - + Debug.toHexString(this.p) - + LINE_SEP + "g:" + LINE_SEP - + Debug.toHexString(this.g)); - if (this.l != 0) - strbuf.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); - return strbuf.toString(); - } - private void parseKeyBits() throws InvalidKeyException { try { DerInputStream in = new DerInputStream(this.key); diff --git a/jdk/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java b/jdk/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java index 3bc90ce8071..b974c3ca86c 100644 --- a/jdk/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java +++ b/jdk/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, 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 @@ -152,12 +152,4 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey { throw new InvalidKeyException("Invalid EC private key", e); } } - - // return a string representation of this key for debugging - public String toString() { - return "Sun EC private key, " + params.getCurve().getField().getFieldSize() - + " bits\n private value: " - + s + "\n parameters: " + params; - } - } diff --git a/jdk/src/share/classes/sun/security/jgss/GSSCredentialImpl.java b/jdk/src/share/classes/sun/security/jgss/GSSCredentialImpl.java index 584e1784c8a..65f6847fd3e 100644 --- a/jdk/src/share/classes/sun/security/jgss/GSSCredentialImpl.java +++ b/jdk/src/share/classes/sun/security/jgss/GSSCredentialImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -651,7 +651,7 @@ public class GSSCredentialImpl implements ExtendedGSSCredential { buffer.append(element.isAcceptorCredential() ? " Accept" : ""); buffer.append(" ["); - buffer.append(element.toString()); + buffer.append(element.getClass()); buffer.append(']'); } catch (GSSException e) { // skip to next element diff --git a/jdk/src/share/classes/sun/security/pkcs/PKCS8Key.java b/jdk/src/share/classes/sun/security/pkcs/PKCS8Key.java index c53b421da66..59512f11b6e 100644 --- a/jdk/src/share/classes/sun/security/pkcs/PKCS8Key.java +++ b/jdk/src/share/classes/sun/security/pkcs/PKCS8Key.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -304,17 +304,6 @@ public class PKCS8Key implements PrivateKey { return encodedKey.clone(); } - /* - * Returns a printable representation of the key - */ - public String toString () - { - HexDumpEncoder encoder = new HexDumpEncoder (); - - return "algorithm = " + algid.toString () - + ", unparsed keybits = \n" + encoder.encodeBuffer (key); - } - /** * Initialize an PKCS8Key object from an input stream. The data * on that input stream must be encoded using DER, obeying the diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11Key.java b/jdk/src/share/classes/sun/security/pkcs11/P11Key.java index dd0ec5f7ee1..e85d27efbb3 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/P11Key.java +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Key.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -552,27 +552,6 @@ abstract class P11Key implements Key, Length { fetchValues(); return coeff; } - public String toString() { - fetchValues(); - StringBuilder sb = new StringBuilder(super.toString()); - sb.append("\n modulus: "); - sb.append(n); - sb.append("\n public exponent: "); - sb.append(e); - sb.append("\n private exponent: "); - sb.append(d); - sb.append("\n prime p: "); - sb.append(p); - sb.append("\n prime q: "); - sb.append(q); - sb.append("\n prime exponent p: "); - sb.append(pe); - sb.append("\n prime exponent q: "); - sb.append(qe); - sb.append("\n crt coefficient: "); - sb.append(coeff); - return sb.toString(); - } } // RSA non-CRT private key @@ -628,15 +607,6 @@ abstract class P11Key implements Key, Length { fetchValues(); return d; } - public String toString() { - fetchValues(); - StringBuilder sb = new StringBuilder(super.toString()); - sb.append("\n modulus: "); - sb.append(n); - sb.append("\n private exponent: "); - sb.append(d); - return sb.toString(); - } } private static final class P11RSAPublicKey extends P11Key @@ -812,11 +782,6 @@ abstract class P11Key implements Key, Length { fetchValues(); return params; } - public String toString() { - fetchValues(); - return super.toString() + "\n x: " + x + "\n p: " + params.getP() - + "\n q: " + params.getQ() + "\n g: " + params.getG(); - } } private static final class P11DHPrivateKey extends P11Key @@ -876,11 +841,6 @@ abstract class P11Key implements Key, Length { fetchValues(); return params; } - public String toString() { - fetchValues(); - return super.toString() + "\n x: " + x + "\n p: " + params.getP() - + "\n g: " + params.getG(); - } } private static final class P11DHPublicKey extends P11Key @@ -1001,12 +961,6 @@ abstract class P11Key implements Key, Length { fetchValues(); return params; } - public String toString() { - fetchValues(); - return super.toString() - + "\n private value: " + s - + "\n parameters: " + params; - } } private static final class P11ECPublicKey extends P11Key diff --git a/jdk/src/share/classes/sun/security/provider/DSAPrivateKey.java b/jdk/src/share/classes/sun/security/provider/DSAPrivateKey.java index b521e3d2fbd..97e7ef8d7da 100644 --- a/jdk/src/share/classes/sun/security/provider/DSAPrivateKey.java +++ b/jdk/src/share/classes/sun/security/provider/DSAPrivateKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -142,11 +142,6 @@ implements java.security.interfaces.DSAPrivateKey, Serializable { } } - public String toString() { - return "Sun DSA Private Key \nparameters:" + algid + "\nx: " + - Debug.toHexString(x) + "\n"; - } - protected void parseKeyBits() throws InvalidKeyException { try { DerInputStream in = new DerInputStream(key); diff --git a/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java b/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java index b289ef2efaa..7e68c427e52 100644 --- a/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java +++ b/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -225,29 +225,4 @@ public final class RSAPrivateCrtKeyImpl } return b; } - - // return a string representation of this key for debugging - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("Sun RSA private CRT key, "); - sb.append(n.bitLength()); - sb.append(" bits\n modulus: "); - sb.append(n); - sb.append("\n public exponent: "); - sb.append(e); - sb.append("\n private exponent: "); - sb.append(d); - sb.append("\n prime p: "); - sb.append(p); - sb.append("\n prime q: "); - sb.append(q); - sb.append("\n prime exponent p: "); - sb.append(pe); - sb.append("\n prime exponent q: "); - sb.append(qe); - sb.append("\n crt coefficient: "); - sb.append(coeff); - return sb.toString(); - } - } diff --git a/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java b/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java index f9a7c340bf4..1a7df130463 100644 --- a/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java +++ b/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -98,11 +98,4 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey { public BigInteger getPrivateExponent() { return d; } - - // return a string representation of this key for debugging - public String toString() { - return "Sun RSA private key, " + n.bitLength() + " bits\n modulus: " - + n + "\n private exponent: " + d; - } - } From 455cd24c9541114abe0a297a27be30c219fe399c Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Mon, 8 Jul 2013 16:15:39 +0400 Subject: [PATCH 0032/1294] 8008589: Better MBean permission validation Better MBean permission validation Reviewed-by: skoivu, dfuchs, mchung, sjiang --- .../management/MBeanTrustPermission.java | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/jdk/src/share/classes/javax/management/MBeanTrustPermission.java b/jdk/src/share/classes/javax/management/MBeanTrustPermission.java index 040f0ddd653..605201a9f8d 100644 --- a/jdk/src/share/classes/javax/management/MBeanTrustPermission.java +++ b/jdk/src/share/classes/javax/management/MBeanTrustPermission.java @@ -26,6 +26,9 @@ package javax.management; import java.security.BasicPermission; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; /** * This permission represents "trust" in a signer or codebase. @@ -75,15 +78,31 @@ public class MBeanTrustPermission extends BasicPermission { */ public MBeanTrustPermission(String name, String actions) { super(name, actions); - /* Check that actions is a null empty string */ - if (actions != null && actions.length() > 0) - throw new IllegalArgumentException("MBeanTrustPermission " + - "actions must be null: " + - actions); + validate(name,actions); + } - if (!name.equals("register") && !name.equals("*")) - throw new IllegalArgumentException("MBeanTrustPermission: " + - "Unknown target name " + + private static void validate(String name, String actions) { + /* Check that actions is a null empty string */ + if (actions != null && actions.length() > 0) { + throw new IllegalArgumentException("MBeanTrustPermission actions must be null: " + + actions); + } + + if (!name.equals("register") && !name.equals("*")) { + throw new IllegalArgumentException("MBeanTrustPermission: Unknown target name " + "[" + name + "]"); + } + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + + // Reading private fields of base class + in.defaultReadObject(); + try { + validate(super.getName(),super.getActions()); + } catch (IllegalArgumentException e) { + throw new InvalidObjectException(e.getMessage()); + } } } From c11a760a1b1481f5a2442c3d70d563fd25e8f6fc Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Thu, 26 Sep 2013 23:05:29 -0700 Subject: [PATCH 0033/1294] 8025720: Separate temporal interface layer Remove ZoneId and Chronology from TemporalField interface Reviewed-by: sherman --- .../classes/java/time/format/Parsed.java | 2 +- .../classes/java/time/temporal/IsoFields.java | 13 +++++++++-- .../java/time/temporal/JulianFields.java | 7 +++--- .../java/time/temporal/TemporalField.java | 23 +++++++++++-------- .../java/time/temporal/WeekFields.java | 9 ++++---- .../time/format/TCKDateTimeParseResolver.java | 12 ++++------ 6 files changed, 39 insertions(+), 27 deletions(-) diff --git a/jdk/src/share/classes/java/time/format/Parsed.java b/jdk/src/share/classes/java/time/format/Parsed.java index 908c7decaef..a86697a31f3 100644 --- a/jdk/src/share/classes/java/time/format/Parsed.java +++ b/jdk/src/share/classes/java/time/format/Parsed.java @@ -262,7 +262,7 @@ final class Parsed implements TemporalAccessor { while (changedCount < 50) { for (Map.Entry entry : fieldValues.entrySet()) { TemporalField targetField = entry.getKey(); - TemporalAccessor resolvedObject = targetField.resolve(fieldValues, chrono, zone, resolverStyle); + TemporalAccessor resolvedObject = targetField.resolve(fieldValues, this, resolverStyle); if (resolvedObject != null) { if (resolvedObject instanceof ChronoZonedDateTime) { ChronoZonedDateTime czdt = (ChronoZonedDateTime) resolvedObject; diff --git a/jdk/src/share/classes/java/time/temporal/IsoFields.java b/jdk/src/share/classes/java/time/temporal/IsoFields.java index bb19c299875..e8ccff15f60 100644 --- a/jdk/src/share/classes/java/time/temporal/IsoFields.java +++ b/jdk/src/share/classes/java/time/temporal/IsoFields.java @@ -69,6 +69,7 @@ import static java.time.temporal.ChronoUnit.MONTHS; import static java.time.temporal.ChronoUnit.WEEKS; import static java.time.temporal.ChronoUnit.YEARS; +import java.time.DateTimeException; import java.time.Duration; import java.time.LocalDate; import java.time.ZoneId; @@ -343,7 +344,7 @@ public final class IsoFields { } @Override public ChronoLocalDate resolve( - Map fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + Map fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) { Long yearLong = fieldValues.get(YEAR); Long qoyLong = fieldValues.get(QUARTER_OF_YEAR); if (yearLong == null || qoyLong == null) { @@ -351,6 +352,7 @@ public final class IsoFields { } int y = YEAR.checkValidIntValue(yearLong); // always validate long doq = fieldValues.get(DAY_OF_QUARTER); + ensureIso(partialTemporal); LocalDate date; if (resolverStyle == ResolverStyle.LENIENT) { date = LocalDate.of(y, 1, 1).plusMonths(Math.multiplyExact(Math.subtractExact(qoyLong, 1), 3)); @@ -464,7 +466,7 @@ public final class IsoFields { } @Override public ChronoLocalDate resolve( - Map fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + Map fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) { Long wbyLong = fieldValues.get(WEEK_BASED_YEAR); Long dowLong = fieldValues.get(DAY_OF_WEEK); if (wbyLong == null || dowLong == null) { @@ -472,6 +474,7 @@ public final class IsoFields { } int wby = WEEK_BASED_YEAR.range().checkValidIntValue(wbyLong, WEEK_BASED_YEAR); // always validate long wowby = fieldValues.get(WEEK_OF_WEEK_BASED_YEAR); + ensureIso(partialTemporal); LocalDate date = LocalDate.of(wby, 1, 4); if (resolverStyle == ResolverStyle.LENIENT) { long dow = dowLong; // unvalidated @@ -568,6 +571,12 @@ public final class IsoFields { return Chronology.from(temporal).equals(IsoChronology.INSTANCE); } + private static void ensureIso(TemporalAccessor temporal) { + if (isIso(temporal) == false) { + throw new DateTimeException("Resolve requires IsoChronology"); + } + } + private static ValueRange getWeekRange(LocalDate date) { int wby = getWeekBasedYear(date); date = date.withDayOfYear(1).withYear(wby); diff --git a/jdk/src/share/classes/java/time/temporal/JulianFields.java b/jdk/src/share/classes/java/time/temporal/JulianFields.java index 326f20d222f..f950d87201b 100644 --- a/jdk/src/share/classes/java/time/temporal/JulianFields.java +++ b/jdk/src/share/classes/java/time/temporal/JulianFields.java @@ -291,13 +291,14 @@ public final class JulianFields { //----------------------------------------------------------------------- @Override public ChronoLocalDate resolve( - Map fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + Map fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) { long value = fieldValues.remove(this); + Chronology chrono = Chronology.from(partialTemporal); if (resolverStyle == ResolverStyle.LENIENT) { - return chronology.dateEpochDay(Math.subtractExact(value, offset)); + return chrono.dateEpochDay(Math.subtractExact(value, offset)); } range().checkValidValue(value, this); - return chronology.dateEpochDay(value - offset); + return chrono.dateEpochDay(value - offset); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/temporal/TemporalField.java b/jdk/src/share/classes/java/time/temporal/TemporalField.java index e757734510c..51903ede30f 100644 --- a/jdk/src/share/classes/java/time/temporal/TemporalField.java +++ b/jdk/src/share/classes/java/time/temporal/TemporalField.java @@ -62,7 +62,6 @@ package java.time.temporal; import java.time.DateTimeException; -import java.time.ZoneId; import java.time.chrono.Chronology; import java.time.format.ResolverStyle; import java.util.Locale; @@ -338,6 +337,13 @@ public interface TemporalField { * complete {@code LocalDate}. The resolve method will remove all three * fields from the map before returning the {@code LocalDate}. *

+ * A partially complete temporal is used to allow the chronology and zone + * to be queried. In general, only the chronology will be needed. + * Querying items other than the zone or chronology is undefined and + * must not be relied on. + * The behavior of other methods such as {@code get}, {@code getLong}, + * {@code range} and {@code isSupported} is unpredictable and the results undefined. + *

* If resolution should be possible, but the data is invalid, the resolver * style should be used to determine an appropriate level of leniency, which * may require throwing a {@code DateTimeException} or {@code ArithmeticException}. @@ -350,16 +356,14 @@ public interface TemporalField { * instances that can produce a date, such as {@code EPOCH_DAY}. *

* Not all {@code TemporalAccessor} implementations are accepted as return values. - * Implementations must accept {@code ChronoLocalDate}, {@code ChronoLocalDateTime}, - * {@code ChronoZonedDateTime} and {@code LocalTime}. - *

- * The zone is not normally required for resolution, but is provided for completeness. + * Implementations that call this method must accept {@code ChronoLocalDate}, + * {@code ChronoLocalDateTime}, {@code ChronoZonedDateTime} and {@code LocalTime}. *

* The default implementation must return null. * * @param fieldValues the map of fields to values, which can be updated, not null - * @param chronology the effective chronology, not null - * @param zone the effective zone, not null + * @param partialTemporal the partially complete temporal to query for zone and + * chronology; querying for other things is undefined and not recommended, not null * @param resolverStyle the requested type of resolve, not null * @return the resolved temporal object; null if resolving only * changed the map, or no resolve occurred @@ -368,8 +372,9 @@ public interface TemporalField { * by querying a field on the temporal without first checking if it is supported */ default TemporalAccessor resolve( - Map fieldValues, Chronology chronology, - ZoneId zone, ResolverStyle resolverStyle) { + Map fieldValues, + TemporalAccessor partialTemporal, + ResolverStyle resolverStyle) { return null; } diff --git a/jdk/src/share/classes/java/time/temporal/WeekFields.java b/jdk/src/share/classes/java/time/temporal/WeekFields.java index b3eb1383450..0edfa73e217 100644 --- a/jdk/src/share/classes/java/time/temporal/WeekFields.java +++ b/jdk/src/share/classes/java/time/temporal/WeekFields.java @@ -892,7 +892,7 @@ public final class WeekFields implements Serializable { @Override public ChronoLocalDate resolve( - Map fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + Map fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) { final long value = fieldValues.get(this); final int newValue = Math.toIntExact(value); // broad limit makes overflow checking lighter // first convert localized day-of-week to ISO day-of-week @@ -915,19 +915,20 @@ public final class WeekFields implements Serializable { int dow = localizedDayOfWeek(isoDow); // build date + Chronology chrono = Chronology.from(partialTemporal); if (fieldValues.containsKey(YEAR)) { int year = YEAR.checkValidIntValue(fieldValues.get(YEAR)); // validate if (rangeUnit == MONTHS && fieldValues.containsKey(MONTH_OF_YEAR)) { // week-of-month long month = fieldValues.get(MONTH_OF_YEAR); // not validated yet - return resolveWoM(fieldValues, chronology, year, month, newValue, dow, resolverStyle); + return resolveWoM(fieldValues, chrono, year, month, newValue, dow, resolverStyle); } if (rangeUnit == YEARS) { // week-of-year - return resolveWoY(fieldValues, chronology, year, newValue, dow, resolverStyle); + return resolveWoY(fieldValues, chrono, year, newValue, dow, resolverStyle); } } else if ((rangeUnit == WEEK_BASED_YEARS || rangeUnit == FOREVER) && fieldValues.containsKey(weekDef.weekBasedYear) && fieldValues.containsKey(weekDef.weekOfWeekBasedYear)) { // week-of-week-based-year and year-of-week-based-year - return resolveWBY(fieldValues, chronology, dow, resolverStyle); + return resolveWBY(fieldValues, chrono, dow, resolverStyle); } return null; } diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java index 4ef01317b2e..b99d9bb4730 100644 --- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java +++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java @@ -927,8 +927,7 @@ public class TCKDateTimeParseResolver { } @Override public TemporalAccessor resolve( - Map fieldValues, Chronology chronology, - ZoneId zone, ResolverStyle resolverStyle) { + Map fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) { return LocalTime.MIDNIGHT.plusNanos(fieldValues.remove(this)); } }; @@ -979,8 +978,7 @@ public class TCKDateTimeParseResolver { } @Override public TemporalAccessor resolve( - Map fieldValues, Chronology chronology, - ZoneId zone, ResolverStyle resolverStyle) { + Map fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) { fieldValues.remove(this); return LocalDateTime.of(2010, 6, 30, 12, 30); } @@ -1032,8 +1030,7 @@ public class TCKDateTimeParseResolver { } @Override public TemporalAccessor resolve( - Map fieldValues, Chronology chronology, - ZoneId zone, ResolverStyle resolverStyle) { + Map fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) { return ThaiBuddhistChronology.INSTANCE.dateNow(); } }; @@ -1082,8 +1079,7 @@ public class TCKDateTimeParseResolver { } @Override public TemporalAccessor resolve( - Map fieldValues, Chronology chronology, - ZoneId zone, ResolverStyle resolverStyle) { + Map fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) { return ZonedDateTime.of(2010, 6, 30, 12, 30, 0, 0, ZoneId.of("Europe/Paris")); } }; From f2ea6795a76bbbaf4c99158d772c946b1f0b0e1e Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Tue, 9 Jul 2013 21:35:04 +0100 Subject: [PATCH 0034/1294] 8025719: Change Chronology to an interface Split Chronology and add AbstractChronology Reviewed-by: darcy --- .../java/time/chrono/AbstractChronology.java | 783 ++++++++++++++++++ .../java/time/chrono/ChronoLocalDate.java | 2 +- .../java/time/chrono/ChronoLocalDateTime.java | 2 +- .../java/time/chrono/ChronoZonedDateTime.java | 2 +- .../classes/java/time/chrono/Chronology.java | 710 ++-------------- .../java/time/chrono/HijrahChronology.java | 8 +- .../java/time/chrono/IsoChronology.java | 2 +- .../java/time/chrono/JapaneseChronology.java | 2 +- .../java/time/chrono/MinguoChronology.java | 2 +- .../share/classes/java/time/chrono/Ser.java | 4 +- .../time/chrono/ThaiBuddhistChronology.java | 2 +- .../java/time/chrono/CopticChronology.java | 8 +- 12 files changed, 864 insertions(+), 663 deletions(-) create mode 100644 jdk/src/share/classes/java/time/chrono/AbstractChronology.java diff --git a/jdk/src/share/classes/java/time/chrono/AbstractChronology.java b/jdk/src/share/classes/java/time/chrono/AbstractChronology.java new file mode 100644 index 00000000000..89b728e88c9 --- /dev/null +++ b/jdk/src/share/classes/java/time/chrono/AbstractChronology.java @@ -0,0 +1,783 @@ +/* + * Copyright (c) 2012, 2013, 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 file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package java.time.chrono; + +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_WEEK; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; +import static java.time.temporal.ChronoField.EPOCH_DAY; +import static java.time.temporal.ChronoField.ERA; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; +import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.WEEKS; +import static java.time.temporal.TemporalAdjuster.nextOrSame; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.time.DateTimeException; +import java.time.DayOfWeek; +import java.time.format.ResolverStyle; +import java.time.temporal.ChronoField; +import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalField; +import java.time.temporal.ValueRange; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.ServiceLoader; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import sun.util.logging.PlatformLogger; + +/** + * An abstract implementation of a calendar system, used to organize and identify dates. + *

+ * The main date and time API is built on the ISO calendar system. + * The chronology operates behind the scenes to represent the general concept of a calendar system. + *

+ * See {@link Chronology} for more details. + * + * @implSpec + * This class is separated from the {@code Chronology} interface so that the static methods + * are not inherited. While {@code Chronology} can be implemented directly, it is strongly + * recommended to extend this abstract class instead. + *

+ * This class must be implemented with care to ensure other classes operate correctly. + * All implementations that can be instantiated must be final, immutable and thread-safe. + * Subclasses should be Serializable wherever possible. + * + * @since 1.8 + */ +public abstract class AbstractChronology implements Chronology { + + /** + * ChronoLocalDate order constant. + */ + static final Comparator DATE_ORDER = + (Comparator & Serializable) (date1, date2) -> { + return Long.compare(date1.toEpochDay(), date2.toEpochDay()); + }; + /** + * ChronoLocalDateTime order constant. + */ + static final Comparator> DATE_TIME_ORDER = + (Comparator> & Serializable) (dateTime1, dateTime2) -> { + int cmp = Long.compare(dateTime1.toLocalDate().toEpochDay(), dateTime2.toLocalDate().toEpochDay()); + if (cmp == 0) { + cmp = Long.compare(dateTime1.toLocalTime().toNanoOfDay(), dateTime2.toLocalTime().toNanoOfDay()); + } + return cmp; + }; + /** + * ChronoZonedDateTime order constant. + */ + static final Comparator> INSTANT_ORDER = + (Comparator> & Serializable) (dateTime1, dateTime2) -> { + int cmp = Long.compare(dateTime1.toEpochSecond(), dateTime2.toEpochSecond()); + if (cmp == 0) { + cmp = Long.compare(dateTime1.toLocalTime().getNano(), dateTime2.toLocalTime().getNano()); + } + return cmp; + }; + + /** + * Map of available calendars by ID. + */ + private static final ConcurrentHashMap CHRONOS_BY_ID = new ConcurrentHashMap<>(); + /** + * Map of available calendars by calendar type. + */ + private static final ConcurrentHashMap CHRONOS_BY_TYPE = new ConcurrentHashMap<>(); + + /** + * Register a Chronology by its ID and type for lookup by {@link #of(String)}. + * Chronologies must not be registered until they are completely constructed. + * Specifically, not in the constructor of Chronology. + * + * @param chrono the chronology to register; not null + * @return the already registered Chronology if any, may be null + */ + static Chronology registerChrono(Chronology chrono) { + return registerChrono(chrono, chrono.getId()); + } + + /** + * Register a Chronology by ID and type for lookup by {@link #of(String)}. + * Chronos must not be registered until they are completely constructed. + * Specifically, not in the constructor of Chronology. + * + * @param chrono the chronology to register; not null + * @param id the ID to register the chronology; not null + * @return the already registered Chronology if any, may be null + */ + static Chronology registerChrono(Chronology chrono, String id) { + Chronology prev = CHRONOS_BY_ID.putIfAbsent(id, chrono); + if (prev == null) { + String type = chrono.getCalendarType(); + if (type != null) { + CHRONOS_BY_TYPE.putIfAbsent(type, chrono); + } + } + return prev; + } + + /** + * Initialization of the maps from id and type to Chronology. + * The ServiceLoader is used to find and register any implementations + * of {@link java.time.chrono.AbstractChronology} found in the bootclass loader. + * The built-in chronologies are registered explicitly. + * Calendars configured via the Thread's context classloader are local + * to that thread and are ignored. + *

+ * The initialization is done only once using the registration + * of the IsoChronology as the test and the final step. + * Multiple threads may perform the initialization concurrently. + * Only the first registration of each Chronology is retained by the + * ConcurrentHashMap. + * @return true if the cache was initialized + */ + private static boolean initCache() { + if (CHRONOS_BY_ID.get("ISO") == null) { + // Initialization is incomplete + + // Register built-in Chronologies + registerChrono(HijrahChronology.INSTANCE); + registerChrono(JapaneseChronology.INSTANCE); + registerChrono(MinguoChronology.INSTANCE); + registerChrono(ThaiBuddhistChronology.INSTANCE); + + // Register Chronologies from the ServiceLoader + @SuppressWarnings("rawtypes") + ServiceLoader loader = ServiceLoader.load(AbstractChronology.class, null); + for (AbstractChronology chrono : loader) { + String id = chrono.getId(); + if (id.equals("ISO") || registerChrono(chrono) != null) { + // Log the attempt to replace an existing Chronology + PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono"); + logger.warning("Ignoring duplicate Chronology, from ServiceLoader configuration " + id); + } + } + + // finally, register IsoChronology to mark initialization is complete + registerChrono(IsoChronology.INSTANCE); + return true; + } + return false; + } + + //----------------------------------------------------------------------- + /** + * Obtains an instance of {@code Chronology} from a locale. + *

+ * See {@link Chronology#ofLocale(Locale)}. + * + * @param locale the locale to use to obtain the calendar system, not null + * @return the calendar system associated with the locale, not null + * @throws java.time.DateTimeException if the locale-specified calendar cannot be found + */ + static Chronology ofLocale(Locale locale) { + Objects.requireNonNull(locale, "locale"); + String type = locale.getUnicodeLocaleType("ca"); + if (type == null || "iso".equals(type) || "iso8601".equals(type)) { + return IsoChronology.INSTANCE; + } + // Not pre-defined; lookup by the type + do { + Chronology chrono = CHRONOS_BY_TYPE.get(type); + if (chrono != null) { + return chrono; + } + // If not found, do the initialization (once) and repeat the lookup + } while (initCache()); + + // Look for a Chronology using ServiceLoader of the Thread's ContextClassLoader + // Application provided Chronologies must not be cached + @SuppressWarnings("rawtypes") + ServiceLoader loader = ServiceLoader.load(Chronology.class); + for (Chronology chrono : loader) { + if (type.equals(chrono.getCalendarType())) { + return chrono; + } + } + throw new DateTimeException("Unknown calendar system: " + type); + } + + //----------------------------------------------------------------------- + /** + * Obtains an instance of {@code Chronology} from a chronology ID or + * calendar system type. + *

+ * See {@link Chronology#of(String)}. + * + * @param id the chronology ID or calendar system type, not null + * @return the chronology with the identifier requested, not null + * @throws java.time.DateTimeException if the chronology cannot be found + */ + static Chronology of(String id) { + Objects.requireNonNull(id, "id"); + do { + Chronology chrono = of0(id); + if (chrono != null) { + return chrono; + } + // If not found, do the initialization (once) and repeat the lookup + } while (initCache()); + + // Look for a Chronology using ServiceLoader of the Thread's ContextClassLoader + // Application provided Chronologies must not be cached + @SuppressWarnings("rawtypes") + ServiceLoader loader = ServiceLoader.load(Chronology.class); + for (Chronology chrono : loader) { + if (id.equals(chrono.getId()) || id.equals(chrono.getCalendarType())) { + return chrono; + } + } + throw new DateTimeException("Unknown chronology: " + id); + } + + /** + * Obtains an instance of {@code Chronology} from a chronology ID or + * calendar system type. + * + * @param id the chronology ID or calendar system type, not null + * @return the chronology with the identifier requested, or {@code null} if not found + */ + private static Chronology of0(String id) { + Chronology chrono = CHRONOS_BY_ID.get(id); + if (chrono == null) { + chrono = CHRONOS_BY_TYPE.get(id); + } + return chrono; + } + + /** + * Returns the available chronologies. + *

+ * Each returned {@code Chronology} is available for use in the system. + * The set of chronologies includes the system chronologies and + * any chronologies provided by the application via ServiceLoader + * configuration. + * + * @return the independent, modifiable set of the available chronology IDs, not null + */ + static Set getAvailableChronologies() { + initCache(); // force initialization + HashSet chronos = new HashSet<>(CHRONOS_BY_ID.values()); + + /// Add in Chronologies from the ServiceLoader configuration + @SuppressWarnings("rawtypes") + ServiceLoader loader = ServiceLoader.load(Chronology.class); + for (Chronology chrono : loader) { + chronos.add(chrono); + } + return chronos; + } + + //----------------------------------------------------------------------- + /** + * Creates an instance. + */ + protected AbstractChronology() { + } + + //----------------------------------------------------------------------- + /** + * Resolves parsed {@code ChronoField} values into a date during parsing. + *

+ * Most {@code TemporalField} implementations are resolved using the + * resolve method on the field. By contrast, the {@code ChronoField} class + * defines fields that only have meaning relative to the chronology. + * As such, {@code ChronoField} date fields are resolved here in the + * context of a specific chronology. + *

+ * {@code ChronoField} instances are resolved by this method, which may + * be overridden in subclasses. + *

    + *
  • {@code EPOCH_DAY} - If present, this is converted to a date and + * all other date fields are then cross-checked against the date. + *
  • {@code PROLEPTIC_MONTH} - If present, then it is split into the + * {@code YEAR} and {@code MONTH_OF_YEAR}. If the mode is strict or smart + * then the field is validated. + *
  • {@code YEAR_OF_ERA} and {@code ERA} - If both are present, then they + * are combined to form a {@code YEAR}. In lenient mode, the {@code YEAR_OF_ERA} + * range is not validated, in smart and strict mode it is. The {@code ERA} is + * validated for range in all three modes. If only the {@code YEAR_OF_ERA} is + * present, and the mode is smart or lenient, then the last available era + * is assumed. In strict mode, no era is assumed and the {@code YEAR_OF_ERA} is + * left untouched. If only the {@code ERA} is present, then it is left untouched. + *
  • {@code YEAR}, {@code MONTH_OF_YEAR} and {@code DAY_OF_MONTH} - + * If all three are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is smart or strict, then the month and day are validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the first month in the requested year, + * then adding the difference in months, then the difference in days. + * If the mode is smart, and the day-of-month is greater than the maximum for + * the year-month, then the day-of-month is adjusted to the last day-of-month. + * If the mode is strict, then the three fields must form a valid date. + *
  • {@code YEAR} and {@code DAY_OF_YEAR} - + * If both are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the requested year, then adding + * the difference in days. + * If the mode is smart or strict, then the two fields must form a valid date. + *
  • {@code YEAR}, {@code MONTH_OF_YEAR}, {@code ALIGNED_WEEK_OF_MONTH} and + * {@code ALIGNED_DAY_OF_WEEK_IN_MONTH} - + * If all four are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the first month in the requested year, then adding + * the difference in months, then the difference in weeks, then in days. + * If the mode is smart or strict, then the all four fields are validated to + * their outer ranges. The date is then combined in a manner equivalent to + * creating a date on the first day of the requested year and month, then adding + * the amount in weeks and days to reach their values. If the mode is strict, + * the date is additionally validated to check that the day and week adjustment + * did not change the month. + *
  • {@code YEAR}, {@code MONTH_OF_YEAR}, {@code ALIGNED_WEEK_OF_MONTH} and + * {@code DAY_OF_WEEK} - If all four are present, then they are combined to + * form a date. The approach is the same as described above for + * years, months and weeks in {@code ALIGNED_DAY_OF_WEEK_IN_MONTH}. + * The day-of-week is adjusted as the next or same matching day-of-week once + * the years, months and weeks have been handled. + *
  • {@code YEAR}, {@code ALIGNED_WEEK_OF_YEAR} and {@code ALIGNED_DAY_OF_WEEK_IN_YEAR} - + * If all three are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the requested year, then adding + * the difference in weeks, then in days. + * If the mode is smart or strict, then the all three fields are validated to + * their outer ranges. The date is then combined in a manner equivalent to + * creating a date on the first day of the requested year, then adding + * the amount in weeks and days to reach their values. If the mode is strict, + * the date is additionally validated to check that the day and week adjustment + * did not change the year. + *
  • {@code YEAR}, {@code ALIGNED_WEEK_OF_YEAR} and {@code DAY_OF_WEEK} - + * If all three are present, then they are combined to form a date. + * The approach is the same as described above for years and weeks in + * {@code ALIGNED_DAY_OF_WEEK_IN_YEAR}. The day-of-week is adjusted as the + * next or same matching day-of-week once the years and weeks have been handled. + *
+ *

+ * The default implementation is suitable for most calendar systems. + * If {@link java.time.temporal.ChronoField#YEAR_OF_ERA} is found without an {@link java.time.temporal.ChronoField#ERA} + * then the last era in {@link #eras()} is used. + * The implementation assumes a 7 day week, that the first day-of-month + * has the value 1, that first day-of-year has the value 1, and that the + * first of the month and year always exists. + * + * @param fieldValues the map of fields to values, which can be updated, not null + * @param resolverStyle the requested type of resolve, not null + * @return the resolved date, null if insufficient information to create a date + * @throws java.time.DateTimeException if the date cannot be resolved, typically + * because of a conflict in the input data + */ + @Override + public ChronoLocalDate resolveDate(Map fieldValues, ResolverStyle resolverStyle) { + // check epoch-day before inventing era + if (fieldValues.containsKey(EPOCH_DAY)) { + return dateEpochDay(fieldValues.remove(EPOCH_DAY)); + } + + // fix proleptic month before inventing era + resolveProlepticMonth(fieldValues, resolverStyle); + + // invent era if necessary to resolve year-of-era + ChronoLocalDate resolved = resolveYearOfEra(fieldValues, resolverStyle); + if (resolved != null) { + return resolved; + } + + // build date + if (fieldValues.containsKey(YEAR)) { + if (fieldValues.containsKey(MONTH_OF_YEAR)) { + if (fieldValues.containsKey(DAY_OF_MONTH)) { + return resolveYMD(fieldValues, resolverStyle); + } + if (fieldValues.containsKey(ALIGNED_WEEK_OF_MONTH)) { + if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_MONTH)) { + return resolveYMAA(fieldValues, resolverStyle); + } + if (fieldValues.containsKey(DAY_OF_WEEK)) { + return resolveYMAD(fieldValues, resolverStyle); + } + } + } + if (fieldValues.containsKey(DAY_OF_YEAR)) { + return resolveYD(fieldValues, resolverStyle); + } + if (fieldValues.containsKey(ALIGNED_WEEK_OF_YEAR)) { + if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_YEAR)) { + return resolveYAA(fieldValues, resolverStyle); + } + if (fieldValues.containsKey(DAY_OF_WEEK)) { + return resolveYAD(fieldValues, resolverStyle); + } + } + } + return null; + } + + void resolveProlepticMonth(Map fieldValues, ResolverStyle resolverStyle) { + Long pMonth = fieldValues.remove(PROLEPTIC_MONTH); + if (pMonth != null) { + if (resolverStyle != ResolverStyle.LENIENT) { + PROLEPTIC_MONTH.checkValidValue(pMonth); + } + // first day-of-month is likely to be safest for setting proleptic-month + // cannot add to year zero, as not all chronologies have a year zero + ChronoLocalDate chronoDate = dateNow() + .with(DAY_OF_MONTH, 1).with(PROLEPTIC_MONTH, pMonth); + addFieldValue(fieldValues, MONTH_OF_YEAR, chronoDate.get(MONTH_OF_YEAR)); + addFieldValue(fieldValues, YEAR, chronoDate.get(YEAR)); + } + } + + ChronoLocalDate resolveYearOfEra(Map fieldValues, ResolverStyle resolverStyle) { + Long yoeLong = fieldValues.remove(YEAR_OF_ERA); + if (yoeLong != null) { + Long eraLong = fieldValues.remove(ERA); + int yoe; + if (resolverStyle != ResolverStyle.LENIENT) { + yoe = range(YEAR_OF_ERA).checkValidIntValue(yoeLong, YEAR_OF_ERA); + } else { + yoe = Math.toIntExact(yoeLong); + } + if (eraLong != null) { + Era eraObj = eraOf(range(ERA).checkValidIntValue(eraLong, ERA)); + addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); + } else { + if (fieldValues.containsKey(YEAR)) { + int year = range(YEAR).checkValidIntValue(fieldValues.get(YEAR), YEAR); + ChronoLocalDate chronoDate = dateYearDay(year, 1); + addFieldValue(fieldValues, YEAR, prolepticYear(chronoDate.getEra(), yoe)); + } else if (resolverStyle == ResolverStyle.STRICT) { + // do not invent era if strict + // reinstate the field removed earlier, no cross-check issues + fieldValues.put(YEAR_OF_ERA, yoeLong); + } else { + List eras = eras(); + if (eras.isEmpty()) { + addFieldValue(fieldValues, YEAR, yoe); + } else { + Era eraObj = eras.get(eras.size() - 1); + addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); + } + } + } + } else if (fieldValues.containsKey(ERA)) { + range(ERA).checkValidValue(fieldValues.get(ERA), ERA); // always validated + } + return null; + } + + ChronoLocalDate resolveYMD(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); + long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1); + return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS); + } + int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); + ValueRange domRange = range(DAY_OF_MONTH); + int dom = domRange.checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); + if (resolverStyle == ResolverStyle.SMART) { // previous valid + try { + return date(y, moy, dom); + } catch (DateTimeException ex) { + return date(y, moy, 1).with(TemporalAdjuster.lastDayOfMonth()); + } + } + return date(y, moy, dom); + } + + ChronoLocalDate resolveYD(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long days = Math.subtractExact(fieldValues.remove(DAY_OF_YEAR), 1); + return dateYearDay(y, 1).plus(days, DAYS); + } + int doy = range(DAY_OF_YEAR).checkValidIntValue(fieldValues.remove(DAY_OF_YEAR), DAY_OF_YEAR); + return dateYearDay(y, doy); // smart is same as strict + } + + ChronoLocalDate resolveYMAA(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); + long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), 1); + return date(y, 1, 1).plus(months, MONTHS).plus(weeks, WEEKS).plus(days, DAYS); + } + int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); + int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); + int ad = range(ALIGNED_DAY_OF_WEEK_IN_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), ALIGNED_DAY_OF_WEEK_IN_MONTH); + ChronoLocalDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); + if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); + } + return date; + } + + ChronoLocalDate resolveYMAD(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); + long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); + return resolveAligned(date(y, 1, 1), months, weeks, dow); + } + int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); + int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); + int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); + ChronoLocalDate date = date(y, moy, 1).plus((aw - 1) * 7, DAYS).with(nextOrSame(DayOfWeek.of(dow))); + if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); + } + return date; + } + + ChronoLocalDate resolveYAA(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); + long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), 1); + return dateYearDay(y, 1).plus(weeks, WEEKS).plus(days, DAYS); + } + int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); + int ad = range(ALIGNED_DAY_OF_WEEK_IN_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), ALIGNED_DAY_OF_WEEK_IN_YEAR); + ChronoLocalDate date = dateYearDay(y, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); + if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); + } + return date; + } + + ChronoLocalDate resolveYAD(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); + long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); + return resolveAligned(dateYearDay(y, 1), 0, weeks, dow); + } + int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); + int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); + ChronoLocalDate date = dateYearDay(y, 1).plus((aw - 1) * 7, DAYS).with(nextOrSame(DayOfWeek.of(dow))); + if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); + } + return date; + } + + ChronoLocalDate resolveAligned(ChronoLocalDate base, long months, long weeks, long dow) { + ChronoLocalDate date = base.plus(months, MONTHS).plus(weeks, WEEKS); + if (dow > 7) { + date = date.plus((dow - 1) / 7, WEEKS); + dow = ((dow - 1) % 7) + 1; + } else if (dow < 1) { + date = date.plus(Math.subtractExact(dow, 7) / 7, WEEKS); + dow = ((dow + 6) % 7) + 1; + } + return date.with(nextOrSame(DayOfWeek.of((int) dow))); + } + + /** + * Adds a field-value pair to the map, checking for conflicts. + *

+ * If the field is not already present, then the field-value pair is added to the map. + * If the field is already present and it has the same value as that specified, no action occurs. + * If the field is already present and it has a different value to that specified, then + * an exception is thrown. + * + * @param field the field to add, not null + * @param value the value to add, not null + * @throws java.time.DateTimeException if the field is already present with a different value + */ + void addFieldValue(Map fieldValues, ChronoField field, long value) { + Long old = fieldValues.get(field); // check first for better error message + if (old != null && old.longValue() != value) { + throw new DateTimeException("Conflict found: " + field + " " + old + " differs from " + field + " " + value); + } + fieldValues.put(field, value); + } + + //----------------------------------------------------------------------- + /** + * Compares this chronology to another chronology. + *

+ * The comparison order first by the chronology ID string, then by any + * additional information specific to the subclass. + * It is "consistent with equals", as defined by {@link Comparable}. + * + * @implSpec + * This implementation compares the chronology ID. + * Subclasses must compare any additional state that they store. + * + * @param other the other chronology to compare to, not null + * @return the comparator value, negative if less, positive if greater + */ + @Override + public int compareTo(Chronology other) { + return getId().compareTo(other.getId()); + } + + /** + * Checks if this chronology is equal to another chronology. + *

+ * The comparison is based on the entire state of the object. + * + * @implSpec + * This implementation checks the type and calls + * {@link #compareTo(java.time.chrono.Chronology)}. + * + * @param obj the object to check, null returns false + * @return true if this is equal to the other chronology + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof AbstractChronology) { + return compareTo((AbstractChronology) obj) == 0; + } + return false; + } + + /** + * A hash code for this chronology. + *

+ * The hash code should be based on the entire state of the object. + * + * @implSpec + * This implementation is based on the chronology ID and class. + * Subclasses should add any additional state that they store. + * + * @return a suitable hash code + */ + @Override + public int hashCode() { + return getClass().hashCode() ^ getId().hashCode(); + } + + //----------------------------------------------------------------------- + /** + * Outputs this chronology as a {@code String}, using the chronology ID. + * + * @return a string representation of this chronology, not null + */ + @Override + public String toString() { + return getId(); + } + + //----------------------------------------------------------------------- + /** + * Writes the Chronology using a + * dedicated serialized form. + *

+     *  out.writeByte(1);  // identifies this as a Chronology
+     *  out.writeUTF(getId());
+     * 
+ * + * @return the instance of {@code Ser}, not null + */ + Object writeReplace() { + return new Ser(Ser.CHRONO_TYPE, this); + } + + /** + * Defend against malicious streams. + * @return never + * @throws java.io.InvalidObjectException always + */ + private Object readResolve() throws ObjectStreamException { + throw new InvalidObjectException("Deserialization via serialization delegate"); + } + + void writeExternal(DataOutput out) throws IOException { + out.writeUTF(getId()); + } + + static Chronology readExternal(DataInput in) throws IOException { + String id = in.readUTF(); + return Chronology.of(id); + } + +} diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java index 58e4f5d5250..da5f0e719ce 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java @@ -262,7 +262,7 @@ public interface ChronoLocalDate * @see #isEqual */ static Comparator timeLineOrder() { - return Chronology.DATE_ORDER; + return AbstractChronology.DATE_ORDER; } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java index 4c2ddfd31a7..353673c9dcd 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java @@ -136,7 +136,7 @@ public interface ChronoLocalDateTime * @see #isEqual */ static Comparator> timeLineOrder() { - return Chronology.DATE_TIME_ORDER; + return AbstractChronology.DATE_TIME_ORDER; } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java index 033ab997fdd..caec8558e6e 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java @@ -137,7 +137,7 @@ public interface ChronoZonedDateTime * @see #isEqual */ static Comparator> timeLineOrder() { - return Chronology.INSTANT_ORDER; + return AbstractChronology.INSTANT_ORDER; } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/chrono/Chronology.java b/jdk/src/share/classes/java/time/chrono/Chronology.java index ed40f4138f0..22a7e69ae25 100644 --- a/jdk/src/share/classes/java/time/chrono/Chronology.java +++ b/jdk/src/share/classes/java/time/chrono/Chronology.java @@ -61,33 +61,8 @@ */ package java.time.chrono; -import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; -import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; -import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; -import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; -import static java.time.temporal.ChronoField.DAY_OF_MONTH; -import static java.time.temporal.ChronoField.DAY_OF_WEEK; -import static java.time.temporal.ChronoField.DAY_OF_YEAR; -import static java.time.temporal.ChronoField.EPOCH_DAY; -import static java.time.temporal.ChronoField.ERA; -import static java.time.temporal.ChronoField.MONTH_OF_YEAR; -import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; -import static java.time.temporal.ChronoField.YEAR; -import static java.time.temporal.ChronoField.YEAR_OF_ERA; -import static java.time.temporal.ChronoUnit.DAYS; -import static java.time.temporal.ChronoUnit.MONTHS; -import static java.time.temporal.ChronoUnit.WEEKS; -import static java.time.temporal.TemporalAdjuster.nextOrSame; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.io.InvalidObjectException; -import java.io.ObjectStreamException; -import java.io.Serializable; import java.time.Clock; import java.time.DateTimeException; -import java.time.DayOfWeek; import java.time.Instant; import java.time.LocalDate; import java.time.LocalTime; @@ -97,28 +72,21 @@ import java.time.format.ResolverStyle; import java.time.format.TextStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; -import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.ValueRange; -import java.util.Comparator; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; -import java.util.ServiceLoader; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import sun.util.logging.PlatformLogger; /** * A calendar system, used to organize and identify dates. *

* The main date and time API is built on the ISO calendar system. - * This class operates behind the scenes to represent the general concept of a calendar system. + * The chronology operates behind the scenes to represent the general concept of a calendar system. * For example, the Japanese, Minguo, Thai Buddhist and others. *

* Most other calendar systems also operate on the shared concepts of year, month and day, @@ -179,130 +147,14 @@ import sun.util.logging.PlatformLogger; * CLDR type and, if applicable, the CLDR variant, * * @implSpec - * This class must be implemented with care to ensure other classes operate correctly. + * This interface must be implemented with care to ensure other classes operate correctly. * All implementations that can be instantiated must be final, immutable and thread-safe. * Subclasses should be Serializable wherever possible. * * @since 1.8 */ -public abstract class Chronology implements Comparable { +public interface Chronology extends Comparable { - /** - * ChronoLocalDate order constant. - */ - static final Comparator DATE_ORDER = - (Comparator & Serializable) (date1, date2) -> { - return Long.compare(date1.toEpochDay(), date2.toEpochDay()); - }; - /** - * ChronoLocalDateTime order constant. - */ - static final Comparator> DATE_TIME_ORDER = - (Comparator> & Serializable) (dateTime1, dateTime2) -> { - int cmp = Long.compare(dateTime1.toLocalDate().toEpochDay(), dateTime2.toLocalDate().toEpochDay()); - if (cmp == 0) { - cmp = Long.compare(dateTime1.toLocalTime().toNanoOfDay(), dateTime2.toLocalTime().toNanoOfDay()); - } - return cmp; - }; - /** - * ChronoZonedDateTime order constant. - */ - static final Comparator> INSTANT_ORDER = - (Comparator> & Serializable) (dateTime1, dateTime2) -> { - int cmp = Long.compare(dateTime1.toEpochSecond(), dateTime2.toEpochSecond()); - if (cmp == 0) { - cmp = Long.compare(dateTime1.toLocalTime().getNano(), dateTime2.toLocalTime().getNano()); - } - return cmp; - }; - - /** - * Map of available calendars by ID. - */ - private static final ConcurrentHashMap CHRONOS_BY_ID = new ConcurrentHashMap<>(); - /** - * Map of available calendars by calendar type. - */ - private static final ConcurrentHashMap CHRONOS_BY_TYPE = new ConcurrentHashMap<>(); - - /** - * Register a Chronology by its ID and type for lookup by {@link #of(java.lang.String)}. - * Chronologies must not be registered until they are completely constructed. - * Specifically, not in the constructor of Chronology. - * - * @param chrono the chronology to register; not null - * @return the already registered Chronology if any, may be null - */ - static Chronology registerChrono(Chronology chrono) { - return registerChrono(chrono, chrono.getId()); - } - - /** - * Register a Chronology by ID and type for lookup by {@link #of(java.lang.String)}. - * Chronos must not be registered until they are completely constructed. - * Specifically, not in the constructor of Chronology. - * - * @param chrono the chronology to register; not null - * @param id the ID to register the chronology; not null - * @return the already registered Chronology if any, may be null - */ - static Chronology registerChrono(Chronology chrono, String id) { - Chronology prev = CHRONOS_BY_ID.putIfAbsent(id, chrono); - if (prev == null) { - String type = chrono.getCalendarType(); - if (type != null) { - CHRONOS_BY_TYPE.putIfAbsent(type, chrono); - } - } - return prev; - } - - /** - * Initialization of the maps from id and type to Chronology. - * The ServiceLoader is used to find and register any implementations - * of {@link java.time.chrono.Chronology} found in the bootclass loader. - * The built-in chronologies are registered explicitly. - * Calendars configured via the Thread's context classloader are local - * to that thread and are ignored. - *

- * The initialization is done only once using the registration - * of the IsoChronology as the test and the final step. - * Multiple threads may perform the initialization concurrently. - * Only the first registration of each Chronology is retained by the - * ConcurrentHashMap. - * @return true if the cache was initialized - */ - private static boolean initCache() { - if (CHRONOS_BY_ID.get("ISO") == null) { - // Initialization is incomplete - - // Register built-in Chronologies - registerChrono(HijrahChronology.INSTANCE); - registerChrono(JapaneseChronology.INSTANCE); - registerChrono(MinguoChronology.INSTANCE); - registerChrono(ThaiBuddhistChronology.INSTANCE); - - // Register Chronologies from the ServiceLoader - @SuppressWarnings("rawtypes") - ServiceLoader loader = ServiceLoader.load(Chronology.class, null); - for (Chronology chrono : loader) { - String id = chrono.getId(); - if (id.equals("ISO") || registerChrono(chrono) != null) { - // Log the attempt to replace an existing Chronology - PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono"); - logger.warning("Ignoring duplicate Chronology, from ServiceLoader configuration " + id); - } - } - - // finally, register IsoChronology to mark initialization is complete - registerChrono(IsoChronology.INSTANCE); - return true; - } - return false; - } - - //----------------------------------------------------------------------- /** * Obtains an instance of {@code Chronology} from a temporal object. *

@@ -320,7 +172,7 @@ public abstract class Chronology implements Comparable { * @return the chronology, not null * @throws DateTimeException if unable to convert to an {@code Chronology} */ - public static Chronology from(TemporalAccessor temporal) { + static Chronology from(TemporalAccessor temporal) { Objects.requireNonNull(temporal, "temporal"); Chronology obj = temporal.query(TemporalQuery.chronology()); return (obj != null ? obj : IsoChronology.INSTANCE); @@ -367,31 +219,8 @@ public abstract class Chronology implements Comparable { * @return the calendar system associated with the locale, not null * @throws DateTimeException if the locale-specified calendar cannot be found */ - public static Chronology ofLocale(Locale locale) { - Objects.requireNonNull(locale, "locale"); - String type = locale.getUnicodeLocaleType("ca"); - if (type == null || "iso".equals(type) || "iso8601".equals(type)) { - return IsoChronology.INSTANCE; - } - // Not pre-defined; lookup by the type - do { - Chronology chrono = CHRONOS_BY_TYPE.get(type); - if (chrono != null) { - return chrono; - } - // If not found, do the initialization (once) and repeat the lookup - } while (initCache()); - - // Look for a Chronology using ServiceLoader of the Thread's ContextClassLoader - // Application provided Chronologies must not be cached - @SuppressWarnings("rawtypes") - ServiceLoader loader = ServiceLoader.load(Chronology.class); - for (Chronology chrono : loader) { - if (type.equals(chrono.getCalendarType())) { - return chrono; - } - } - throw new DateTimeException("Unknown calendar system: " + type); + static Chronology ofLocale(Locale locale) { + return AbstractChronology.ofLocale(locale); } //----------------------------------------------------------------------- @@ -415,41 +244,8 @@ public abstract class Chronology implements Comparable { * @return the chronology with the identifier requested, not null * @throws DateTimeException if the chronology cannot be found */ - public static Chronology of(String id) { - Objects.requireNonNull(id, "id"); - do { - Chronology chrono = of0(id); - if (chrono != null) { - return chrono; - } - // If not found, do the initialization (once) and repeat the lookup - } while (initCache()); - - // Look for a Chronology using ServiceLoader of the Thread's ContextClassLoader - // Application provided Chronologies must not be cached - @SuppressWarnings("rawtypes") - ServiceLoader loader = ServiceLoader.load(Chronology.class); - for (Chronology chrono : loader) { - if (id.equals(chrono.getId()) || id.equals(chrono.getCalendarType())) { - return chrono; - } - } - throw new DateTimeException("Unknown chronology: " + id); - } - - /** - * Obtains an instance of {@code Chronology} from a chronology ID or - * calendar system type. - * - * @param id the chronology ID or calendar system type, not null - * @return the chronology with the identifier requested, or {@code null} if not found - */ - private static Chronology of0(String id) { - Chronology chrono = CHRONOS_BY_ID.get(id); - if (chrono == null) { - chrono = CHRONOS_BY_TYPE.get(id); - } - return chrono; + static Chronology of(String id) { + return AbstractChronology.of(id); } /** @@ -462,24 +258,8 @@ public abstract class Chronology implements Comparable { * * @return the independent, modifiable set of the available chronology IDs, not null */ - public static Set getAvailableChronologies() { - initCache(); // force initialization - HashSet chronos = new HashSet<>(CHRONOS_BY_ID.values()); - - /// Add in Chronologies from the ServiceLoader configuration - @SuppressWarnings("rawtypes") - ServiceLoader loader = ServiceLoader.load(Chronology.class); - for (Chronology chrono : loader) { - chronos.add(chrono); - } - return chronos; - } - - //----------------------------------------------------------------------- - /** - * Creates an instance. - */ - protected Chronology() { + static Set getAvailableChronologies() { + return AbstractChronology.getAvailableChronologies(); } //----------------------------------------------------------------------- @@ -492,7 +272,7 @@ public abstract class Chronology implements Comparable { * @return the chronology ID, not null * @see #getCalendarType() */ - public abstract String getId(); + String getId(); /** * Gets the calendar type of the calendar system. @@ -507,13 +287,17 @@ public abstract class Chronology implements Comparable { * @return the calendar system type, null if the calendar is not defined by CLDR/LDML * @see #getId() */ - public abstract String getCalendarType(); + String getCalendarType(); //----------------------------------------------------------------------- /** * Obtains a local date in this chronology from the era, year-of-era, * month-of-year and day-of-month fields. * + * @implSpec + * The default implementation combines the era and year-of-era into a proleptic + * year before calling {@link #date(int, int, int)}. + * * @param era the era of the correct type for the chronology, not null * @param yearOfEra the chronology year-of-era * @param month the chronology month-of-year @@ -522,7 +306,7 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if unable to create the date * @throws ClassCastException if the {@code era} is not of the correct type for the chronology */ - public ChronoLocalDate date(Era era, int yearOfEra, int month, int dayOfMonth) { + default ChronoLocalDate date(Era era, int yearOfEra, int month, int dayOfMonth) { return date(prolepticYear(era, yearOfEra), month, dayOfMonth); } @@ -536,12 +320,16 @@ public abstract class Chronology implements Comparable { * @return the local date in this chronology, not null * @throws DateTimeException if unable to create the date */ - public abstract ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth); + ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth); /** * Obtains a local date in this chronology from the era, year-of-era and * day-of-year fields. * + * @implSpec + * The default implementation combines the era and year-of-era into a proleptic + * year before calling {@link #dateYearDay(int, int)}. + * * @param era the era of the correct type for the chronology, not null * @param yearOfEra the chronology year-of-era * @param dayOfYear the chronology day-of-year @@ -549,7 +337,7 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if unable to create the date * @throws ClassCastException if the {@code era} is not of the correct type for the chronology */ - public ChronoLocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear) { + default ChronoLocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear) { return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear); } @@ -562,7 +350,7 @@ public abstract class Chronology implements Comparable { * @return the local date in this chronology, not null * @throws DateTimeException if unable to create the date */ - public abstract ChronoLocalDate dateYearDay(int prolepticYear, int dayOfYear); + ChronoLocalDate dateYearDay(int prolepticYear, int dayOfYear); /** * Obtains a local date in this chronology from the epoch-day. @@ -574,7 +362,7 @@ public abstract class Chronology implements Comparable { * @return the local date in this chronology, not null * @throws DateTimeException if unable to create the date */ - public abstract ChronoLocalDate dateEpochDay(long epochDay); + ChronoLocalDate dateEpochDay(long epochDay); //----------------------------------------------------------------------- /** @@ -585,13 +373,14 @@ public abstract class Chronology implements Comparable { *

* Using this method will prevent the ability to use an alternate clock for testing * because the clock is hard-coded. - *

- * This implementation uses {@link #dateNow(Clock)}. + * + * @implSpec + * The default implementation invokes {@link #dateNow(Clock)}. * * @return the current local date using the system clock and default time-zone, not null * @throws DateTimeException if unable to create the date */ - public ChronoLocalDate dateNow() { + default ChronoLocalDate dateNow() { return dateNow(Clock.systemDefaultZone()); } @@ -604,11 +393,14 @@ public abstract class Chronology implements Comparable { * Using this method will prevent the ability to use an alternate clock for testing * because the clock is hard-coded. * + * @implSpec + * The default implementation invokes {@link #dateNow(Clock)}. + * * @param zone the zone ID to use, not null * @return the current local date using the system clock, not null * @throws DateTimeException if unable to create the date */ - public ChronoLocalDate dateNow(ZoneId zone) { + default ChronoLocalDate dateNow(ZoneId zone) { return dateNow(Clock.system(zone)); } @@ -619,11 +411,14 @@ public abstract class Chronology implements Comparable { * Using this method allows the use of an alternate clock for testing. * The alternate clock may be introduced using {@link Clock dependency injection}. * + * @implSpec + * The default implementation invokes {@link #date(TemporalAccessor)} )}. + * * @param clock the clock to use, not null * @return the current local date, not null * @throws DateTimeException if unable to create the date */ - public ChronoLocalDate dateNow(Clock clock) { + default ChronoLocalDate dateNow(Clock clock) { Objects.requireNonNull(clock, "clock"); return date(LocalDate.now(clock)); } @@ -647,7 +442,7 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if unable to create the date * @see ChronoLocalDate#from(TemporalAccessor) */ - public abstract ChronoLocalDate date(TemporalAccessor temporal); + ChronoLocalDate date(TemporalAccessor temporal); /** * Obtains a local date-time in this chronology from another temporal object. @@ -670,7 +465,7 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if unable to create the date-time * @see ChronoLocalDateTime#from(TemporalAccessor) */ - public ChronoLocalDateTime localDateTime(TemporalAccessor temporal) { + default ChronoLocalDateTime localDateTime(TemporalAccessor temporal) { try { return date(temporal).atTime(LocalTime.from(temporal)); } catch (DateTimeException ex) { @@ -702,7 +497,7 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if unable to create the date-time * @see ChronoZonedDateTime#from(TemporalAccessor) */ - public ChronoZonedDateTime zonedDateTime(TemporalAccessor temporal) { + default ChronoZonedDateTime zonedDateTime(TemporalAccessor temporal) { try { ZoneId zone = ZoneId.from(temporal); try { @@ -728,7 +523,7 @@ public abstract class Chronology implements Comparable { * @return the zoned date-time, not null * @throws DateTimeException if the result exceeds the supported range */ - public ChronoZonedDateTime zonedDateTime(Instant instant, ZoneId zone) { + default ChronoZonedDateTime zonedDateTime(Instant instant, ZoneId zone) { return ChronoZonedDateTimeImpl.ofInstant(this, instant, zone); } @@ -746,7 +541,7 @@ public abstract class Chronology implements Comparable { * @param prolepticYear the proleptic-year to check, not validated for range * @return true if the year is a leap year */ - public abstract boolean isLeapYear(long prolepticYear); + boolean isLeapYear(long prolepticYear); /** * Calculates the proleptic-year given the era and year-of-era. @@ -764,7 +559,7 @@ public abstract class Chronology implements Comparable { * such as if the year is invalid for the era * @throws ClassCastException if the {@code era} is not of the correct type for the chronology */ - public abstract int prolepticYear(Era era, int yearOfEra); + int prolepticYear(Era era, int yearOfEra); /** * Creates the chronology era object from the numeric value. @@ -785,7 +580,7 @@ public abstract class Chronology implements Comparable { * @return the calendar system era, not null * @throws DateTimeException if unable to create the era */ - public abstract Era eraOf(int eraValue); + Era eraOf(int eraValue); /** * Gets the list of eras for the chronology. @@ -796,7 +591,7 @@ public abstract class Chronology implements Comparable { * * @return the list of eras for the chronology, may be immutable, not null */ - public abstract List eras(); + List eras(); //----------------------------------------------------------------------- /** @@ -815,7 +610,7 @@ public abstract class Chronology implements Comparable { * @return the range of valid values for the field, not null * @throws DateTimeException if the range for the field cannot be obtained */ - public abstract ValueRange range(ChronoField field); + ValueRange range(ChronoField field); //----------------------------------------------------------------------- /** @@ -825,28 +620,16 @@ public abstract class Chronology implements Comparable { * suitable for presentation to the user. * The parameters control the style of the returned text and the locale. * + * @implSpec + * The default implementation behaves as the the formatter was used to + * format the chronology textual name. + * * @param style the style of the text required, not null * @param locale the locale to use, not null * @return the text value of the chronology, not null */ - public String getDisplayName(TextStyle style, Locale locale) { - return new DateTimeFormatterBuilder().appendChronologyText(style).toFormatter(locale).format(toTemporal()); - } - - /** - * Converts this chronology to a {@code TemporalAccessor}. - *

- * A {@code Chronology} can be fully represented as a {@code TemporalAccessor}. - * However, the interface is not implemented by this class as most of the - * methods on the interface have no meaning to {@code Chronology}. - *

- * The returned temporal has no supported fields, with the query method - * supporting the return of the chronology using {@link TemporalQuery#chronology()}. - * - * @return a temporal equivalent to this chronology, not null - */ - private TemporalAccessor toTemporal() { - return new TemporalAccessor() { + default String getDisplayName(TextStyle style, Locale locale) { + TemporalAccessor temporal = new TemporalAccessor() { @Override public boolean isSupported(TemporalField field) { return false; @@ -864,6 +647,7 @@ public abstract class Chronology implements Comparable { return TemporalAccessor.super.query(query); } }; + return new DateTimeFormatterBuilder().appendChronologyText(style).toFormatter(locale).format(temporal); } //----------------------------------------------------------------------- @@ -876,82 +660,8 @@ public abstract class Chronology implements Comparable { * As such, {@code ChronoField} date fields are resolved here in the * context of a specific chronology. *

- * {@code ChronoField} instances are resolved by this method, which may - * be overridden in subclasses. - *

    - *
  • {@code EPOCH_DAY} - If present, this is converted to a date and - * all other date fields are then cross-checked against the date. - *
  • {@code PROLEPTIC_MONTH} - If present, then it is split into the - * {@code YEAR} and {@code MONTH_OF_YEAR}. If the mode is strict or smart - * then the field is validated. - *
  • {@code YEAR_OF_ERA} and {@code ERA} - If both are present, then they - * are combined to form a {@code YEAR}. In lenient mode, the {@code YEAR_OF_ERA} - * range is not validated, in smart and strict mode it is. The {@code ERA} is - * validated for range in all three modes. If only the {@code YEAR_OF_ERA} is - * present, and the mode is smart or lenient, then the last available era - * is assumed. In strict mode, no era is assumed and the {@code YEAR_OF_ERA} is - * left untouched. If only the {@code ERA} is present, then it is left untouched. - *
  • {@code YEAR}, {@code MONTH_OF_YEAR} and {@code DAY_OF_MONTH} - - * If all three are present, then they are combined to form a date. - * In all three modes, the {@code YEAR} is validated. - * If the mode is smart or strict, then the month and day are validated. - * If the mode is lenient, then the date is combined in a manner equivalent to - * creating a date on the first day of the first month in the requested year, - * then adding the difference in months, then the difference in days. - * If the mode is smart, and the day-of-month is greater than the maximum for - * the year-month, then the day-of-month is adjusted to the last day-of-month. - * If the mode is strict, then the three fields must form a valid date. - *
  • {@code YEAR} and {@code DAY_OF_YEAR} - - * If both are present, then they are combined to form a date. - * In all three modes, the {@code YEAR} is validated. - * If the mode is lenient, then the date is combined in a manner equivalent to - * creating a date on the first day of the requested year, then adding - * the difference in days. - * If the mode is smart or strict, then the two fields must form a valid date. - *
  • {@code YEAR}, {@code MONTH_OF_YEAR}, {@code ALIGNED_WEEK_OF_MONTH} and - * {@code ALIGNED_DAY_OF_WEEK_IN_MONTH} - - * If all four are present, then they are combined to form a date. - * In all three modes, the {@code YEAR} is validated. - * If the mode is lenient, then the date is combined in a manner equivalent to - * creating a date on the first day of the first month in the requested year, then adding - * the difference in months, then the difference in weeks, then in days. - * If the mode is smart or strict, then the all four fields are validated to - * their outer ranges. The date is then combined in a manner equivalent to - * creating a date on the first day of the requested year and month, then adding - * the amount in weeks and days to reach their values. If the mode is strict, - * the date is additionally validated to check that the day and week adjustment - * did not change the month. - *
  • {@code YEAR}, {@code MONTH_OF_YEAR}, {@code ALIGNED_WEEK_OF_MONTH} and - * {@code DAY_OF_WEEK} - If all four are present, then they are combined to - * form a date. The approach is the same as described above for - * years, months and weeks in {@code ALIGNED_DAY_OF_WEEK_IN_MONTH}. - * The day-of-week is adjusted as the next or same matching day-of-week once - * the years, months and weeks have been handled. - *
  • {@code YEAR}, {@code ALIGNED_WEEK_OF_YEAR} and {@code ALIGNED_DAY_OF_WEEK_IN_YEAR} - - * If all three are present, then they are combined to form a date. - * In all three modes, the {@code YEAR} is validated. - * If the mode is lenient, then the date is combined in a manner equivalent to - * creating a date on the first day of the requested year, then adding - * the difference in weeks, then in days. - * If the mode is smart or strict, then the all three fields are validated to - * their outer ranges. The date is then combined in a manner equivalent to - * creating a date on the first day of the requested year, then adding - * the amount in weeks and days to reach their values. If the mode is strict, - * the date is additionally validated to check that the day and week adjustment - * did not change the year. - *
  • {@code YEAR}, {@code ALIGNED_WEEK_OF_YEAR} and {@code DAY_OF_WEEK} - - * If all three are present, then they are combined to form a date. - * The approach is the same as described above for years and weeks in - * {@code ALIGNED_DAY_OF_WEEK_IN_YEAR}. The day-of-week is adjusted as the - * next or same matching day-of-week once the years and weeks have been handled. - *
- *

- * The default implementation is suitable for most calendar systems. - * If {@link ChronoField#YEAR_OF_ERA} is found without an {@link ChronoField#ERA} - * then the last era in {@link #eras()} is used. - * The implementation assumes a 7 day week, that the first day-of-month - * has the value 1, that first day-of-year has the value 1, and that the - * first of the month and year always exists. + * The default implementation, which explains typical resolve behaviour, + * is provided in {@link AbstractChronology}. * * @param fieldValues the map of fields to values, which can be updated, not null * @param resolverStyle the requested type of resolve, not null @@ -959,233 +669,7 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if the date cannot be resolved, typically * because of a conflict in the input data */ - public ChronoLocalDate resolveDate(Map fieldValues, ResolverStyle resolverStyle) { - // check epoch-day before inventing era - if (fieldValues.containsKey(EPOCH_DAY)) { - return dateEpochDay(fieldValues.remove(EPOCH_DAY)); - } - - // fix proleptic month before inventing era - resolveProlepticMonth(fieldValues, resolverStyle); - - // invent era if necessary to resolve year-of-era - ChronoLocalDate resolved = resolveYearOfEra(fieldValues, resolverStyle); - if (resolved != null) { - return resolved; - } - - // build date - if (fieldValues.containsKey(YEAR)) { - if (fieldValues.containsKey(MONTH_OF_YEAR)) { - if (fieldValues.containsKey(DAY_OF_MONTH)) { - return resolveYMD(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(ALIGNED_WEEK_OF_MONTH)) { - if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_MONTH)) { - return resolveYMAA(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(DAY_OF_WEEK)) { - return resolveYMAD(fieldValues, resolverStyle); - } - } - } - if (fieldValues.containsKey(DAY_OF_YEAR)) { - return resolveYD(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(ALIGNED_WEEK_OF_YEAR)) { - if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_YEAR)) { - return resolveYAA(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(DAY_OF_WEEK)) { - return resolveYAD(fieldValues, resolverStyle); - } - } - } - return null; - } - - void resolveProlepticMonth(Map fieldValues, ResolverStyle resolverStyle) { - Long pMonth = fieldValues.remove(PROLEPTIC_MONTH); - if (pMonth != null) { - if (resolverStyle != ResolverStyle.LENIENT) { - PROLEPTIC_MONTH.checkValidValue(pMonth); - } - // first day-of-month is likely to be safest for setting proleptic-month - // cannot add to year zero, as not all chronologies have a year zero - ChronoLocalDate chronoDate = dateNow() - .with(DAY_OF_MONTH, 1).with(PROLEPTIC_MONTH, pMonth); - addFieldValue(fieldValues, MONTH_OF_YEAR, chronoDate.get(MONTH_OF_YEAR)); - addFieldValue(fieldValues, YEAR, chronoDate.get(YEAR)); - } - } - - ChronoLocalDate resolveYearOfEra(Map fieldValues, ResolverStyle resolverStyle) { - Long yoeLong = fieldValues.remove(YEAR_OF_ERA); - if (yoeLong != null) { - Long eraLong = fieldValues.remove(ERA); - int yoe; - if (resolverStyle != ResolverStyle.LENIENT) { - yoe = range(YEAR_OF_ERA).checkValidIntValue(yoeLong, YEAR_OF_ERA); - } else { - yoe = Math.toIntExact(yoeLong); - } - if (eraLong != null) { - Era eraObj = eraOf(range(ERA).checkValidIntValue(eraLong, ERA)); - addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); - } else { - if (fieldValues.containsKey(YEAR)) { - int year = range(YEAR).checkValidIntValue(fieldValues.get(YEAR), YEAR); - ChronoLocalDate chronoDate = dateYearDay(year, 1); - addFieldValue(fieldValues, YEAR, prolepticYear(chronoDate.getEra(), yoe)); - } else if (resolverStyle == ResolverStyle.STRICT) { - // do not invent era if strict - // reinstate the field removed earlier, no cross-check issues - fieldValues.put(YEAR_OF_ERA, yoeLong); - } else { - List eras = eras(); - if (eras.isEmpty()) { - addFieldValue(fieldValues, YEAR, yoe); - } else { - Era eraObj = eras.get(eras.size() - 1); - addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); - } - } - } - } else if (fieldValues.containsKey(ERA)) { - range(ERA).checkValidValue(fieldValues.get(ERA), ERA); // always validated - } - return null; - } - - ChronoLocalDate resolveYMD(Map fieldValues, ResolverStyle resolverStyle) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - if (resolverStyle == ResolverStyle.LENIENT) { - long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); - long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1); - return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS); - } - int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); - ValueRange domRange = range(DAY_OF_MONTH); - int dom = domRange.checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); - if (resolverStyle == ResolverStyle.SMART) { // previous valid - try { - return date(y, moy, dom); - } catch (DateTimeException ex) { - return date(y, moy, 1).with(TemporalAdjuster.lastDayOfMonth()); - } - } - return date(y, moy, dom); - } - - ChronoLocalDate resolveYD(Map fieldValues, ResolverStyle resolverStyle) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - if (resolverStyle == ResolverStyle.LENIENT) { - long days = Math.subtractExact(fieldValues.remove(DAY_OF_YEAR), 1); - return dateYearDay(y, 1).plus(days, DAYS); - } - int doy = range(DAY_OF_YEAR).checkValidIntValue(fieldValues.remove(DAY_OF_YEAR), DAY_OF_YEAR); - return dateYearDay(y, doy); // smart is same as strict - } - - ChronoLocalDate resolveYMAA(Map fieldValues, ResolverStyle resolverStyle) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - if (resolverStyle == ResolverStyle.LENIENT) { - long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); - long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), 1); - return date(y, 1, 1).plus(months, MONTHS).plus(weeks, WEEKS).plus(days, DAYS); - } - int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); - int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); - int ad = range(ALIGNED_DAY_OF_WEEK_IN_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), ALIGNED_DAY_OF_WEEK_IN_MONTH); - ChronoLocalDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); - if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); - } - return date; - } - - ChronoLocalDate resolveYMAD(Map fieldValues, ResolverStyle resolverStyle) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - if (resolverStyle == ResolverStyle.LENIENT) { - long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); - long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); - return resolveAligned(date(y, 1, 1), months, weeks, dow); - } - int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); - int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); - int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); - ChronoLocalDate date = date(y, moy, 1).plus((aw - 1) * 7, DAYS).with(nextOrSame(DayOfWeek.of(dow))); - if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); - } - return date; - } - - ChronoLocalDate resolveYAA(Map fieldValues, ResolverStyle resolverStyle) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - if (resolverStyle == ResolverStyle.LENIENT) { - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); - long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), 1); - return dateYearDay(y, 1).plus(weeks, WEEKS).plus(days, DAYS); - } - int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); - int ad = range(ALIGNED_DAY_OF_WEEK_IN_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), ALIGNED_DAY_OF_WEEK_IN_YEAR); - ChronoLocalDate date = dateYearDay(y, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); - if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); - } - return date; - } - - ChronoLocalDate resolveYAD(Map fieldValues, ResolverStyle resolverStyle) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - if (resolverStyle == ResolverStyle.LENIENT) { - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); - long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); - return resolveAligned(dateYearDay(y, 1), 0, weeks, dow); - } - int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); - int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); - ChronoLocalDate date = dateYearDay(y, 1).plus((aw - 1) * 7, DAYS).with(nextOrSame(DayOfWeek.of(dow))); - if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); - } - return date; - } - - ChronoLocalDate resolveAligned(ChronoLocalDate base, long months, long weeks, long dow) { - ChronoLocalDate date = base.plus(months, MONTHS).plus(weeks, WEEKS); - if (dow > 7) { - date = date.plus((dow - 1) / 7, WEEKS); - dow = ((dow - 1) % 7) + 1; - } else if (dow < 1) { - date = date.plus(Math.subtractExact(dow, 7) / 7, WEEKS); - dow = ((dow + 6) % 7) + 1; - } - return date.with(nextOrSame(DayOfWeek.of((int) dow))); - } - - /** - * Adds a field-value pair to the map, checking for conflicts. - *

- * If the field is not already present, then the field-value pair is added to the map. - * If the field is already present and it has the same value as that specified, no action occurs. - * If the field is already present and it has a different value to that specified, then - * an exception is thrown. - * - * @param field the field to add, not null - * @param value the value to add, not null - * @throws DateTimeException if the field is already present with a different value - */ - void addFieldValue(Map fieldValues, ChronoField field, long value) { - Long old = fieldValues.get(field); // check first for better error message - if (old != null && old.longValue() != value) { - throw new DateTimeException("Conflict found: " + field + " " + old + " differs from " + field + " " + value); - } - fieldValues.put(field, value); - } + ChronoLocalDate resolveDate(Map fieldValues, ResolverStyle resolverStyle); //----------------------------------------------------------------------- /** @@ -1215,7 +699,7 @@ public abstract class Chronology implements Comparable { * @param days the number of years, may be negative * @return the period in terms of this chronology, not null */ - public ChronoPeriod period(int years, int months, int days) { + default ChronoPeriod period(int years, int months, int days) { return new ChronoPeriodImpl(this, years, months, days); } @@ -1226,107 +710,43 @@ public abstract class Chronology implements Comparable { * The comparison order first by the chronology ID string, then by any * additional information specific to the subclass. * It is "consistent with equals", as defined by {@link Comparable}. - *

- * The default implementation compares the chronology ID. - * Subclasses must compare any additional state that they store. * * @param other the other chronology to compare to, not null * @return the comparator value, negative if less, positive if greater */ @Override - public int compareTo(Chronology other) { - return getId().compareTo(other.getId()); - } + int compareTo(Chronology other); /** * Checks if this chronology is equal to another chronology. *

* The comparison is based on the entire state of the object. - *

- * The default implementation checks the type and calls {@link #compareTo(Chronology)}. * * @param obj the object to check, null returns false * @return true if this is equal to the other chronology */ @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof Chronology) { - return compareTo((Chronology) obj) == 0; - } - return false; - } + boolean equals(Object obj); /** * A hash code for this chronology. *

- * The default implementation is based on the ID and class. - * Subclasses should add any additional state that they store. + * The hash code should be based on the entire state of the object. * * @return a suitable hash code */ @Override - public int hashCode() { - return getClass().hashCode() ^ getId().hashCode(); - } + int hashCode(); //----------------------------------------------------------------------- /** - * Outputs this chronology as a {@code String}, using the ID. + * Outputs this chronology as a {@code String}. + *

+ * The format should include the entire state of the object. * * @return a string representation of this chronology, not null */ @Override - public String toString() { - return getId(); - } - - //----------------------------------------------------------------------- - /** - * Writes the Chronology using a - * dedicated serialized form. - * @serialData - *

-     *  out.writeByte(1);  // identifies a Chronology
-     *  out.writeUTF(getId());
-     * 
- * - * @return the instance of {@code Ser}, not null - */ - Object writeReplace() { - return new Ser(Ser.CHRONO_TYPE, this); - } - - /** - * Defend against malicious streams. - * @return never - * @throws InvalidObjectException always - */ - private Object readResolve() throws InvalidObjectException { - throw new InvalidObjectException("Deserialization via serialization delegate"); - } - - /** - * Write the Chronology id to the stream. - * @param out the output stream - * @throws IOException on any error during the write - */ - void writeExternal(DataOutput out) throws IOException { - out.writeUTF(getId()); - } - - /** - * Reads the Chronology id and creates the Chronology. - * @param in the input stream - * @return the Chronology - * @throws IOException on errors during the read - * @throws DateTimeException if the Chronology cannot be returned - */ - static Chronology readExternal(DataInput in) throws IOException { - String id = in.readUTF(); - return Chronology.of(id); - } + String toString(); } diff --git a/jdk/src/share/classes/java/time/chrono/HijrahChronology.java b/jdk/src/share/classes/java/time/chrono/HijrahChronology.java index 7d4485809c9..277b1010fe4 100644 --- a/jdk/src/share/classes/java/time/chrono/HijrahChronology.java +++ b/jdk/src/share/classes/java/time/chrono/HijrahChronology.java @@ -214,7 +214,7 @@ import sun.util.logging.PlatformLogger; * * @since 1.8 */ -public final class HijrahChronology extends Chronology implements Serializable { +public final class HijrahChronology extends AbstractChronology implements Serializable { /** * The Hijrah Calendar id. @@ -308,8 +308,8 @@ public final class HijrahChronology extends Chronology implements Serializable { try { INSTANCE = new HijrahChronology("Hijrah-umalqura"); // Register it by its aliases - Chronology.registerChrono(INSTANCE, "Hijrah"); - Chronology.registerChrono(INSTANCE, "islamic"); + AbstractChronology.registerChrono(INSTANCE, "Hijrah"); + AbstractChronology.registerChrono(INSTANCE, "islamic"); } catch (DateTimeException ex) { // Absence of Hijrah calendar is fatal to initializing this class. PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono"); @@ -336,7 +336,7 @@ public final class HijrahChronology extends Chronology implements Serializable { try { // Create and register the variant HijrahChronology chrono = new HijrahChronology(id); - Chronology.registerChrono(chrono); + AbstractChronology.registerChrono(chrono); } catch (DateTimeException ex) { // Log error and continue PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono"); diff --git a/jdk/src/share/classes/java/time/chrono/IsoChronology.java b/jdk/src/share/classes/java/time/chrono/IsoChronology.java index 9638f6eea4f..eb71a1fe65c 100644 --- a/jdk/src/share/classes/java/time/chrono/IsoChronology.java +++ b/jdk/src/share/classes/java/time/chrono/IsoChronology.java @@ -120,7 +120,7 @@ import java.util.Objects; * * @since 1.8 */ -public final class IsoChronology extends Chronology implements Serializable { +public final class IsoChronology extends AbstractChronology implements Serializable { /** * Singleton instance of the ISO chronology. diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java b/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java index b01707e63ab..09e5b692ef2 100644 --- a/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java +++ b/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java @@ -120,7 +120,7 @@ import sun.util.calendar.LocalGregorianCalendar; * * @since 1.8 */ -public final class JapaneseChronology extends Chronology implements Serializable { +public final class JapaneseChronology extends AbstractChronology implements Serializable { static final LocalGregorianCalendar JCAL = (LocalGregorianCalendar) CalendarSystem.forName("japanese"); diff --git a/jdk/src/share/classes/java/time/chrono/MinguoChronology.java b/jdk/src/share/classes/java/time/chrono/MinguoChronology.java index db75a8645d6..af0be986c93 100644 --- a/jdk/src/share/classes/java/time/chrono/MinguoChronology.java +++ b/jdk/src/share/classes/java/time/chrono/MinguoChronology.java @@ -105,7 +105,7 @@ import java.util.Map; * * @since 1.8 */ -public final class MinguoChronology extends Chronology implements Serializable { +public final class MinguoChronology extends AbstractChronology implements Serializable { /** * Singleton instance for the Minguo chronology. diff --git a/jdk/src/share/classes/java/time/chrono/Ser.java b/jdk/src/share/classes/java/time/chrono/Ser.java index 5a4e3c12623..317a7696497 100644 --- a/jdk/src/share/classes/java/time/chrono/Ser.java +++ b/jdk/src/share/classes/java/time/chrono/Ser.java @@ -161,7 +161,7 @@ final class Ser implements Externalizable { out.writeByte(type); switch (type) { case CHRONO_TYPE: - ((Chronology) object).writeExternal(out); + ((AbstractChronology) object).writeExternal(out); break; case CHRONO_LOCAL_DATE_TIME_TYPE: ((ChronoLocalDateTimeImpl) object).writeExternal(out); @@ -231,7 +231,7 @@ final class Ser implements Externalizable { private static Object readInternal(byte type, ObjectInput in) throws IOException, ClassNotFoundException { switch (type) { - case CHRONO_TYPE: return Chronology.readExternal(in); + case CHRONO_TYPE: return AbstractChronology.readExternal(in); case CHRONO_LOCAL_DATE_TIME_TYPE: return ChronoLocalDateTimeImpl.readExternal(in); case CHRONO_ZONE_DATE_TIME_TYPE: return ChronoZonedDateTimeImpl.readExternal(in); case JAPANESE_DATE_TYPE: return JapaneseDate.readExternal(in); diff --git a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java index 4ffd15bfcc6..c41aa34c0f1 100644 --- a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java +++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java @@ -106,7 +106,7 @@ import java.util.Map; * * @since 1.8 */ -public final class ThaiBuddhistChronology extends Chronology implements Serializable { +public final class ThaiBuddhistChronology extends AbstractChronology implements Serializable { /** * Singleton instance of the Buddhist chronology. diff --git a/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java b/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java index c111eed3658..c72b7370de8 100644 --- a/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java @@ -59,13 +59,11 @@ package tck.java.time.chrono; import static java.time.temporal.ChronoField.EPOCH_DAY; import java.io.Serializable; - +import java.time.chrono.AbstractChronology; +import java.time.chrono.Era; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; import java.time.temporal.ValueRange; -import java.time.chrono.Chronology; -import java.time.chrono.Era; - import java.util.Arrays; import java.util.List; import java.util.Locale; @@ -95,7 +93,7 @@ import java.util.Locale; *

Implementation notes

* This class is immutable and thread-safe. */ -public final class CopticChronology extends Chronology implements Serializable { +public final class CopticChronology extends AbstractChronology implements Serializable { /** * Singleton instance of the Coptic chronology. From 8379a071b6408db6a1089a3c079638719cf34acf Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Thu, 11 Jul 2013 12:59:03 -0400 Subject: [PATCH 0035/1294] 8016256: Make finalization final Add private methods to final methods check Reviewed-by: coleenp, acorn, ahgross --- hotspot/src/share/vm/classfile/classFileParser.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 65cd2333a9d..f764057f101 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -4481,9 +4481,8 @@ void ClassFileParser::check_final_method_override(instanceKlassHandle this_klass for (int index = 0; index < num_methods; index++) { Method* m = methods->at(index); - // skip private, static and methods - if ((!m->is_private()) && - (!m->is_static()) && + // skip static and methods + if ((!m->is_static()) && (m->name() != vmSymbols::object_initializer_name())) { Symbol* name = m->name(); From be5469fc716a7868f4ae4b705502dbb1bee0bc03 Mon Sep 17 00:00:00 2001 From: Stuart Marks Date: Thu, 11 Jul 2013 13:32:36 -0700 Subject: [PATCH 0036/1294] 8014987: Augment serialization handling Reviewed-by: alanb, coffeys, skoivu --- .../classes/java/io/ObjectInputStream.java | 15 +++++++------- .../classes/java/io/ObjectOutputStream.java | 20 ++++++++++++------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/jdk/src/share/classes/java/io/ObjectInputStream.java b/jdk/src/share/classes/java/io/ObjectInputStream.java index ca0400539f9..0e41b08dc3e 100644 --- a/jdk/src/share/classes/java/io/ObjectInputStream.java +++ b/jdk/src/share/classes/java/io/ObjectInputStream.java @@ -490,11 +490,12 @@ public class ObjectInputStream public void defaultReadObject() throws IOException, ClassNotFoundException { - if (curContext == null) { + SerialCallbackContext ctx = curContext; + if (ctx == null) { throw new NotActiveException("not in call to readObject"); } - Object curObj = curContext.getObj(); - ObjectStreamClass curDesc = curContext.getDesc(); + Object curObj = ctx.getObj(); + ObjectStreamClass curDesc = ctx.getDesc(); bin.setBlockDataMode(false); defaultReadFields(curObj, curDesc); bin.setBlockDataMode(true); @@ -528,11 +529,12 @@ public class ObjectInputStream public ObjectInputStream.GetField readFields() throws IOException, ClassNotFoundException { - if (curContext == null) { + SerialCallbackContext ctx = curContext; + if (ctx == null) { throw new NotActiveException("not in call to readObject"); } - Object curObj = curContext.getObj(); - ObjectStreamClass curDesc = curContext.getDesc(); + Object curObj = ctx.getObj(); + ObjectStreamClass curDesc = ctx.getDesc(); bin.setBlockDataMode(false); GetFieldImpl getField = new GetFieldImpl(curDesc); getField.readFields(); @@ -1967,7 +1969,6 @@ public class ObjectInputStream private void defaultReadFields(Object obj, ObjectStreamClass desc) throws IOException { - // REMIND: is isInstance check necessary? Class cl = desc.forClass(); if (cl != null && obj != null && !cl.isInstance(obj)) { throw new ClassCastException(); diff --git a/jdk/src/share/classes/java/io/ObjectOutputStream.java b/jdk/src/share/classes/java/io/ObjectOutputStream.java index f7a94bb0342..c99aeb9cd67 100644 --- a/jdk/src/share/classes/java/io/ObjectOutputStream.java +++ b/jdk/src/share/classes/java/io/ObjectOutputStream.java @@ -430,11 +430,12 @@ public class ObjectOutputStream * OutputStream */ public void defaultWriteObject() throws IOException { - if ( curContext == null ) { + SerialCallbackContext ctx = curContext; + if (ctx == null) { throw new NotActiveException("not in call to writeObject"); } - Object curObj = curContext.getObj(); - ObjectStreamClass curDesc = curContext.getDesc(); + Object curObj = ctx.getObj(); + ObjectStreamClass curDesc = ctx.getDesc(); bout.setBlockDataMode(false); defaultWriteFields(curObj, curDesc); bout.setBlockDataMode(true); @@ -452,11 +453,12 @@ public class ObjectOutputStream */ public ObjectOutputStream.PutField putFields() throws IOException { if (curPut == null) { - if (curContext == null) { + SerialCallbackContext ctx = curContext; + if (ctx == null) { throw new NotActiveException("not in call to writeObject"); } - Object curObj = curContext.getObj(); - ObjectStreamClass curDesc = curContext.getDesc(); + Object curObj = ctx.getObj(); + ObjectStreamClass curDesc = ctx.getDesc(); curPut = new PutFieldImpl(curDesc); } return curPut; @@ -1516,7 +1518,11 @@ public class ObjectOutputStream private void defaultWriteFields(Object obj, ObjectStreamClass desc) throws IOException { - // REMIND: perform conservative isInstance check here? + Class cl = desc.forClass(); + if (cl != null && obj != null && !cl.isInstance(obj)) { + throw new ClassCastException(); + } + desc.checkDefaultSerialize(); int primDataSize = desc.getPrimDataSize(); From 79bda234fe58acb682b3be6ee3fa064d6fdcec43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?= Date: Mon, 15 Jul 2013 14:44:50 +0200 Subject: [PATCH 0037/1294] 8014349: (cl) Class.getDeclaredClass problematic in some class loader configurations Reviewed-by: mchung, ahgross, darcy --- jdk/src/share/classes/java/lang/Class.java | 18 +++++++++++++++++- jdk/src/share/native/java/lang/Class.c | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index df4d457367d..eb11681ac00 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -1221,9 +1221,25 @@ public final class Class implements java.io.Serializable, * type, or void,then this method returns null. * * @return the declaring class for this class + * @throws SecurityException + * If a security manager, s, is present and the caller's + * class loader is not the same as or an ancestor of the class + * loader for the declaring class and invocation of {@link + * SecurityManager#checkPackageAccess s.checkPackageAccess()} + * denies access to the package of the declaring class * @since JDK1.1 */ - public native Class getDeclaringClass(); + @CallerSensitive + public Class getDeclaringClass() throws SecurityException { + final Class candidate = getDeclaringClass0(); + + if (candidate != null) + candidate.checkPackageAccess( + ClassLoader.getClassLoader(Reflection.getCallerClass()), true); + return candidate; + } + + private native Class getDeclaringClass0(); /** diff --git a/jdk/src/share/native/java/lang/Class.c b/jdk/src/share/native/java/lang/Class.c index e53d3f73b79..b0ba34349d8 100644 --- a/jdk/src/share/native/java/lang/Class.c +++ b/jdk/src/share/native/java/lang/Class.c @@ -69,7 +69,7 @@ static JNINativeMethod methods[] = { {"getDeclaredConstructors0","(Z)[" CTR, (void *)&JVM_GetClassDeclaredConstructors}, {"getProtectionDomain0", "()" PD, (void *)&JVM_GetProtectionDomain}, {"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses}, - {"getDeclaringClass", "()" CLS, (void *)&JVM_GetDeclaringClass}, + {"getDeclaringClass0", "()" CLS, (void *)&JVM_GetDeclaringClass}, {"getGenericSignature0", "()" STR, (void *)&JVM_GetClassSignature}, {"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations}, {"getConstantPool", "()" CPL, (void *)&JVM_GetClassConstantPool}, From 1f1524301201ef37f3180a9b9659eb45d598afa0 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Mon, 15 Jul 2013 20:24:39 -0700 Subject: [PATCH 0038/1294] 8017291: Cast Proxies Aside Reviewed-by: alanb, ahgross --- jdk/src/share/classes/java/lang/ClassLoader.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java index f26eafd980a..3735cd3a782 100644 --- a/jdk/src/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/share/classes/java/lang/ClassLoader.java @@ -57,6 +57,7 @@ import sun.misc.URLClassPath; import sun.misc.VM; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; +import sun.reflect.misc.ReflectUtil; import sun.security.util.SecurityConstants; /** @@ -486,6 +487,13 @@ public abstract class ClassLoader { private void checkPackageAccess(Class cls, ProtectionDomain pd) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { + if (ReflectUtil.isNonPublicProxyClass(cls)) { + for (Class intf: cls.getInterfaces()) { + checkPackageAccess(intf, pd); + } + return; + } + final String name = cls.getName(); final int i = name.lastIndexOf('.'); if (i != -1) { From fb90cdbe873ae541008c71cbc04107b6b893a660 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 16 Jul 2013 21:11:54 +0400 Subject: [PATCH 0039/1294] 8019617: Better view of objects Reviewed-by: art, skoivu --- .../javax/swing/text/html/ObjectView.java | 28 ++++--------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/text/html/ObjectView.java b/jdk/src/share/classes/javax/swing/text/html/ObjectView.java index 4e43cfb6d70..00d3a42c3a6 100644 --- a/jdk/src/share/classes/javax/swing/text/html/ObjectView.java +++ b/jdk/src/share/classes/javax/swing/text/html/ObjectView.java @@ -31,6 +31,9 @@ import javax.swing.text.*; import java.beans.*; import java.lang.reflect.*; +import sun.reflect.misc.MethodUtil; +import sun.reflect.misc.ReflectUtil; + /** * Component decorator that implements the view interface * for <object> elements. @@ -87,6 +90,7 @@ public class ObjectView extends ComponentView { AttributeSet attr = getElement().getAttributes(); String classname = (String) attr.getAttribute(HTML.Attribute.CLASSID); try { + ReflectUtil.checkPackageAccess(classname); Class c = Class.forName(classname, true,Thread.currentThread(). getContextClassLoader()); Object o = c.newInstance(); @@ -115,28 +119,6 @@ public class ObjectView extends ComponentView { return comp; } - /** - * Get a Class object to use for loading the - * classid. If possible, the Classloader - * used to load the associated Document is used. - * This would typically be the same as the ClassLoader - * used to load the EditorKit. If the documents - * ClassLoader is null, - * Class.forName is used. - */ - private Class getClass(String classname) throws ClassNotFoundException { - Class klass; - - Class docClass = getDocument().getClass(); - ClassLoader loader = docClass.getClassLoader(); - if (loader != null) { - klass = loader.loadClass(classname); - } else { - klass = Class.forName(classname); - } - return klass; - } - /** * Initialize this component according the KEY/VALUEs passed in * via the <param> elements in the corresponding @@ -170,7 +152,7 @@ public class ObjectView extends ComponentView { } Object [] args = { value }; try { - writer.invoke(comp, args); + MethodUtil.invoke(writer, comp, args); } catch (Exception ex) { System.err.println("Invocation failed"); // invocation code From b9c256373a815672c9c560483097de86ddfacebe Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Tue, 16 Jul 2013 14:06:04 -0700 Subject: [PATCH 0040/1294] 8012425: Transform TransformerFactory Reviewed-by: alanb, dfuchs, mullan --- .../internal/xsltc/trax/TransformerImpl.java | 2 + .../xalan/internal/xsltc/trax/Util.java | 7 ++ .../validation/StreamValidatorHelper.java | 35 +++--- .../jaxp/validation/ValidatorHandlerImpl.java | 2 + .../internal/parsers/AbstractSAXParser.java | 37 +++--- .../internal/parsers/XML11Configuration.java | 111 +++++++++--------- .../xml/internal/utils/XMLReaderManager.java | 20 +++- 7 files changed, 122 insertions(+), 92 deletions(-) diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java index 63446e734e2..7c33c91a8c8 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java @@ -271,6 +271,7 @@ public final class TransformerImpl extends Transformer _accessExternalDTD = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD); _readerManager = XMLReaderManager.getInstance(_useServicesMechanism); _readerManager.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD); + _readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing); //_isIncremental = tfactory._incremental; } @@ -286,6 +287,7 @@ public final class TransformerImpl extends Transformer */ public void setSecureProcessing(boolean flag) { _isSecureProcessing = flag; + _readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing); } /** * Return the state of the services mechanism feature. diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java index 25c45c04be9..b287a351db4 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java @@ -105,6 +105,13 @@ public final class Util { if (reader == null) { try { reader= XMLReaderFactory.createXMLReader(); + try { + reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, + xsltc.isSecureProcessing()); + } catch (SAXNotRecognizedException e) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + e.getMessage()); + } } catch (Exception e ) { try { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java index 1b4f6875611..95fe7d8d8ec 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java @@ -20,28 +20,27 @@ package com.sun.org.apache.xerces.internal.jaxp.validation; -import java.lang.ref.SoftReference; -import java.io.IOException; - -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.XMLConstants; - import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.parsers.XML11Configuration; +import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; +import java.io.IOException; +import java.lang.ref.SoftReference; +import javax.xml.XMLConstants; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; import org.xml.sax.SAXException; /** @@ -86,6 +85,11 @@ final class StreamValidatorHelper implements ValidatorHelper { Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; private static final String DEFAULT_TRANSFORMER_IMPL = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"; + + /** Property id: security manager. */ + private static final String SECURITY_MANAGER = + Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; + // // Data // @@ -165,6 +169,9 @@ final class StreamValidatorHelper implements ValidatorHelper { private XMLParserConfiguration initialize() { XML11Configuration config = new XML11Configuration(); + if (fComponentManager.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) { + config.setProperty(SECURITY_MANAGER, new SecurityManager()); + } config.setProperty(ENTITY_RESOLVER, fComponentManager.getProperty(ENTITY_RESOLVER)); config.setProperty(ERROR_HANDLER, fComponentManager.getProperty(ERROR_HANDLER)); XMLErrorReporter errorReporter = (XMLErrorReporter) fComponentManager.getProperty(ERROR_REPORTER); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java index 3f493517209..2c3a9842c5e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java @@ -674,6 +674,8 @@ final class ValidatorHandlerImpl extends ValidatorHandler implements SAXParserFactory.newInstance() : new SAXParserFactoryImpl(); spf.setNamespaceAware(true); try { + spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, + fComponentManager.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)); reader = spf.newSAXParser().getXMLReader(); // If this is a Xerces SAX parser, set the security manager if there is one if (reader instanceof com.sun.org.apache.xerces.internal.parsers.SAXParser) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java index 726f31e76b5..53ad2a6b605 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java @@ -20,16 +20,13 @@ package com.sun.org.apache.xerces.internal.parsers; -import java.io.IOException; -import java.util.Locale; - import com.sun.org.apache.xerces.internal.impl.Constants; -import com.sun.org.apache.xerces.internal.util.Status; -import com.sun.org.apache.xerces.internal.xs.PSVIProvider; -import com.sun.org.apache.xerces.internal.util.EntityResolverWrapper; import com.sun.org.apache.xerces.internal.util.EntityResolver2Wrapper; +import com.sun.org.apache.xerces.internal.util.EntityResolverWrapper; import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; +import com.sun.org.apache.xerces.internal.util.SecurityManager; +import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolHash; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.xni.Augmentations; @@ -48,15 +45,17 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; import com.sun.org.apache.xerces.internal.xs.AttributePSVI; import com.sun.org.apache.xerces.internal.xs.ElementPSVI; +import com.sun.org.apache.xerces.internal.xs.PSVIProvider; +import java.io.IOException; +import java.util.Locale; +import javax.xml.XMLConstants; import org.xml.sax.AttributeList; -import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.DTDHandler; import org.xml.sax.DocumentHandler; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; -import org.xml.sax.Locator; import org.xml.sax.Parser; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; @@ -131,6 +130,10 @@ public abstract class AbstractSAXParser protected static final String DOM_NODE = Constants.SAX_PROPERTY_PREFIX + Constants.DOM_NODE_PROPERTY; + /** Property id: security manager. */ + private static final String SECURITY_MANAGER = + Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; + /** Recognized properties. */ private static final String[] RECOGNIZED_PROPERTIES = { LEXICAL_HANDLER, @@ -1645,19 +1648,13 @@ public abstract class AbstractSAXParser // Drop through and perform default processing // } - - // - // Xerces Features - // - - /* - else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) { - String feature = featureId.substring(XERCES_FEATURES_PREFIX.length()); - // - // Drop through and perform default processing - // + else if (featureId.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { + if (state) { + if (fConfiguration.getProperty(SECURITY_MANAGER )==null) { + fConfiguration.setProperty(SECURITY_MANAGER, new SecurityManager()); + } + } } - */ // // Default handling diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java index 32ac6a86d78..b33a5f4093e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java @@ -20,14 +20,6 @@ package com.sun.org.apache.xerces.internal.parsers; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Locale; -import java.util.Properties; -import javax.xml.XMLConstants; - import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl; import com.sun.org.apache.xerces.internal.impl.XML11DocumentScannerImpl; @@ -53,7 +45,6 @@ import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter; import com.sun.org.apache.xerces.internal.util.FeatureState; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; -import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; @@ -72,6 +63,11 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; +import javax.xml.XMLConstants; /** * This class is the configuration used to parse XML 1.0 and XML 1.1 documents. @@ -453,26 +449,26 @@ public class XML11Configuration extends ParserConfigurationSettings XMLGrammarPool grammarPool, XMLComponentManager parentSettings) { - super(parentSettings); + super(parentSettings); - // create a vector to hold all the components in use - // XML 1.0 specialized components - fComponents = new ArrayList(); - // XML 1.1 specialized components - fXML11Components = new ArrayList(); - // Common components for XML 1.1. and XML 1.0 - fCommonComponents = new ArrayList(); + // create a vector to hold all the components in use + // XML 1.0 specialized components + fComponents = new ArrayList(); + // XML 1.1 specialized components + fXML11Components = new ArrayList(); + // Common components for XML 1.1. and XML 1.0 + fCommonComponents = new ArrayList(); - // create table for features and properties - fFeatures = new HashMap(); - fProperties = new HashMap(); + // create table for features and properties + fFeatures = new HashMap(); + fProperties = new HashMap(); // add default recognized features final String[] recognizedFeatures = { CONTINUE_AFTER_FATAL_ERROR, LOAD_EXTERNAL_DTD, // from XMLDTDScannerImpl - VALIDATION, - NAMESPACES, + VALIDATION, + NAMESPACES, NORMALIZE_DATA, SCHEMA_ELEMENT_DEFAULT, SCHEMA_AUGMENT_PSVI, GENERATE_SYNTHETIC_ANNOTATIONS, VALIDATE_ANNOTATIONS, HONOUR_ALL_SCHEMALOCATIONS, NAMESPACE_GROWTH, @@ -483,47 +479,48 @@ public class XML11Configuration extends ParserConfigurationSettings // features might not have been set and it would cause a // not-recognized exception to be thrown. -Ac XMLSCHEMA_VALIDATION, XMLSCHEMA_FULL_CHECKING, - EXTERNAL_GENERAL_ENTITIES, - EXTERNAL_PARAMETER_ENTITIES, - PARSER_SETTINGS, - XMLConstants.FEATURE_SECURE_PROCESSING + EXTERNAL_GENERAL_ENTITIES, + EXTERNAL_PARAMETER_ENTITIES, + PARSER_SETTINGS, + XMLConstants.FEATURE_SECURE_PROCESSING }; + addRecognizedFeatures(recognizedFeatures); - // set state for default features - fFeatures.put(VALIDATION, Boolean.FALSE); - fFeatures.put(NAMESPACES, Boolean.TRUE); - fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE); - fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE); - fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE); - fFeatures.put(LOAD_EXTERNAL_DTD, Boolean.TRUE); - fFeatures.put(SCHEMA_ELEMENT_DEFAULT, Boolean.TRUE); - fFeatures.put(NORMALIZE_DATA, Boolean.TRUE); - fFeatures.put(SCHEMA_AUGMENT_PSVI, Boolean.TRUE); - fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE); - fFeatures.put(VALIDATE_ANNOTATIONS, Boolean.FALSE); - fFeatures.put(HONOUR_ALL_SCHEMALOCATIONS, Boolean.FALSE); - fFeatures.put(NAMESPACE_GROWTH, Boolean.FALSE); - fFeatures.put(TOLERATE_DUPLICATES, Boolean.FALSE); - fFeatures.put(USE_GRAMMAR_POOL_ONLY, Boolean.FALSE); - fFeatures.put(PARSER_SETTINGS, Boolean.TRUE); - fFeatures.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE); + // set state for default features + fFeatures.put(VALIDATION, Boolean.FALSE); + fFeatures.put(NAMESPACES, Boolean.TRUE); + fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE); + fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE); + fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE); + fFeatures.put(LOAD_EXTERNAL_DTD, Boolean.TRUE); + fFeatures.put(SCHEMA_ELEMENT_DEFAULT, Boolean.TRUE); + fFeatures.put(NORMALIZE_DATA, Boolean.TRUE); + fFeatures.put(SCHEMA_AUGMENT_PSVI, Boolean.TRUE); + fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE); + fFeatures.put(VALIDATE_ANNOTATIONS, Boolean.FALSE); + fFeatures.put(HONOUR_ALL_SCHEMALOCATIONS, Boolean.FALSE); + fFeatures.put(NAMESPACE_GROWTH, Boolean.FALSE); + fFeatures.put(TOLERATE_DUPLICATES, Boolean.FALSE); + fFeatures.put(USE_GRAMMAR_POOL_ONLY, Boolean.FALSE); + fFeatures.put(PARSER_SETTINGS, Boolean.TRUE); + fFeatures.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE); // add default recognized properties final String[] recognizedProperties = { - SYMBOL_TABLE, - ERROR_HANDLER, - ENTITY_RESOLVER, + SYMBOL_TABLE, + ERROR_HANDLER, + ENTITY_RESOLVER, ERROR_REPORTER, ENTITY_MANAGER, DOCUMENT_SCANNER, DTD_SCANNER, DTD_PROCESSOR, DTD_VALIDATOR, - DATATYPE_VALIDATOR_FACTORY, - VALIDATION_MANAGER, - SCHEMA_VALIDATOR, - XML_STRING, + DATATYPE_VALIDATOR_FACTORY, + VALIDATION_MANAGER, + SCHEMA_VALIDATOR, + XML_STRING, XMLGRAMMAR_POOL, JAXP_SCHEMA_SOURCE, JAXP_SCHEMA_LANGUAGE, @@ -540,15 +537,15 @@ public class XML11Configuration extends ParserConfigurationSettings }; addRecognizedProperties(recognizedProperties); - if (symbolTable == null) { - symbolTable = new SymbolTable(); - } - fSymbolTable = symbolTable; - fProperties.put(SYMBOL_TABLE, fSymbolTable); + if (symbolTable == null) { + symbolTable = new SymbolTable(); + } + fSymbolTable = symbolTable; + fProperties.put(SYMBOL_TABLE, fSymbolTable); fGrammarPool = grammarPool; if (fGrammarPool != null) { - fProperties.put(XMLGRAMMAR_POOL, fGrammarPool); + fProperties.put(XMLGRAMMAR_POOL, fGrammarPool); } fEntityManager = new XMLEntityManager(); diff --git a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java index 28002037272..279ac53a71f 100644 --- a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java +++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java @@ -26,11 +26,13 @@ import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; import java.util.HashMap; + import javax.xml.XMLConstants; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; @@ -63,6 +65,8 @@ public class XMLReaderManager { private HashMap m_inUse; private boolean m_useServicesMechanism = true; + + private boolean _secureProcessing; /** * protocols allowed for external DTD references in source file and/or stylesheet. */ @@ -118,7 +122,12 @@ public class XMLReaderManager { // TransformerFactory creates a reader via the // XMLReaderFactory if setXMLReader is not used reader = XMLReaderFactory.createXMLReader(); - + try { + reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _secureProcessing); + } catch (SAXNotRecognizedException e) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + e.getMessage()); + } } catch (Exception e) { try { // If unable to create an instance, let's try to use @@ -192,6 +201,15 @@ public class XMLReaderManager { m_useServicesMechanism = flag; } + /** + * Set feature + */ + public void setFeature(String name, boolean value) { + if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { + _secureProcessing = value; + } + } + /** * Get property value */ From a775b1ae8d7146b5e0ac513000884a4ecf680a58 Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Thu, 18 Jul 2013 18:52:14 +0100 Subject: [PATCH 0041/1294] 8015743: Address internet addresses Reviewed-by: alanb, khazra, skoivu --- .../share/classes/java/net/Inet6Address.java | 496 +++++++++++------- .../share/classes/java/net/InetAddress.java | 9 +- jdk/src/share/native/java/net/Inet6Address.c | 15 +- jdk/src/share/native/java/net/net_util.c | 105 +++- jdk/src/share/native/java/net/net_util.h | 15 +- .../native/java/net/Inet6AddressImpl.c | 15 +- .../native/java/net/NetworkInterface.c | 18 +- .../native/java/net/PlainDatagramSocketImpl.c | 3 +- jdk/src/solaris/native/java/net/net_util_md.c | 8 +- .../native/java/net/Inet6AddressImpl.c | 16 +- .../native/java/net/NetworkInterface.c | 16 +- .../native/java/net/NetworkInterface_winXP.c | 12 +- .../java/net/TwoStacksPlainSocketImpl.c | 11 +- jdk/src/windows/native/java/net/net_util_md.c | 6 +- .../net/Inet6Address/serialize/Serialize.java | 181 ++++++- 15 files changed, 657 insertions(+), 269 deletions(-) diff --git a/jdk/src/share/classes/java/net/Inet6Address.java b/jdk/src/share/classes/java/net/Inet6Address.java index 4a2d4e22473..8892631bb30 100644 --- a/jdk/src/share/classes/java/net/Inet6Address.java +++ b/jdk/src/share/classes/java/net/Inet6Address.java @@ -28,7 +28,10 @@ package java.net; import java.io.IOException; import java.io.InvalidObjectException; import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; import java.util.Enumeration; +import java.util.Arrays; /** * This class represents an Internet Protocol version 6 (IPv6) address. @@ -177,37 +180,192 @@ class Inet6Address extends InetAddress { */ private transient int cached_scope_id; // 0 - /** - * Holds a 128-bit (16 bytes) IPv6 address. - * - * @serial - */ - byte[] ipaddress; + private class Inet6AddressHolder { - /** - * scope_id. The scope specified when the object is created. If the object - * is created with an interface name, then the scope_id is not determined - * until the time it is needed. - */ - private int scope_id; // 0 + private Inet6AddressHolder() { + ipaddress = new byte[INADDRSZ]; + } - /** - * This will be set to true when the scope_id field contains a valid - * integer scope_id. - */ - private boolean scope_id_set; // false + private Inet6AddressHolder( + byte[] ipaddress, int scope_id, boolean scope_id_set, + NetworkInterface ifname, boolean scope_ifname_set) + { + this.ipaddress = ipaddress; + this.scope_id = scope_id; + this.scope_id_set = scope_id_set; + this.scope_ifname_set = scope_ifname_set; + this.scope_ifname = ifname; + } - /** - * scoped interface. scope_id is derived from this as the scope_id of the first - * address whose scope is the same as this address for the named interface. - */ - private transient NetworkInterface scope_ifname; // null + /** + * Holds a 128-bit (16 bytes) IPv6 address. + */ + byte[] ipaddress; - /** - * set if the object is constructed with a scoped - * interface instead of a numeric scope id. - */ - private boolean scope_ifname_set; // false; + /** + * scope_id. The scope specified when the object is created. If the object + * is created with an interface name, then the scope_id is not determined + * until the time it is needed. + */ + int scope_id; // 0 + + /** + * This will be set to true when the scope_id field contains a valid + * integer scope_id. + */ + boolean scope_id_set; // false + + /** + * scoped interface. scope_id is derived from this as the scope_id of the first + * address whose scope is the same as this address for the named interface. + */ + NetworkInterface scope_ifname; // null + + /** + * set if the object is constructed with a scoped + * interface instead of a numeric scope id. + */ + boolean scope_ifname_set; // false; + + void setAddr(byte addr[]) { + if (addr.length == INADDRSZ) { // normal IPv6 address + System.arraycopy(addr, 0, ipaddress, 0, INADDRSZ); + } + } + + void init(byte addr[], int scope_id) { + setAddr(addr); + + if (scope_id >= 0) { + this.scope_id = scope_id; + this.scope_id_set = true; + } + } + + void init(byte addr[], NetworkInterface nif) + throws UnknownHostException + { + setAddr(addr); + + if (nif != null) { + this.scope_id = deriveNumericScope(ipaddress, nif); + this.scope_id_set = true; + this.scope_ifname = nif; + this.scope_ifname_set = true; + } + } + + String getHostAddress() { + String s = numericToTextFormat(ipaddress); + if (scope_ifname != null) { /* must check this first */ + s = s + "%" + scope_ifname.getName(); + } else if (scope_id_set) { + s = s + "%" + scope_id; + } + return s; + } + + public boolean equals(Object o) { + if (! (o instanceof Inet6AddressHolder)) { + return false; + } + Inet6AddressHolder that = (Inet6AddressHolder)o; + + return Arrays.equals(this.ipaddress, that.ipaddress); + } + + public int hashCode() { + if (ipaddress != null) { + + int hash = 0; + int i=0; + while (i= 0, or -1 to indicate not being set */ Inet6Address(String hostName, byte addr[], int scope_id) { - holder().hostName = hostName; - if (addr.length == INADDRSZ) { // normal IPv6 address - holder().family = IPv6; - ipaddress = addr.clone(); - } - if (scope_id >= 0) { - this.scope_id = scope_id; - scope_id_set = true; - } + holder.init(hostName, IPv6); + holder6 = new Inet6AddressHolder(); + holder6.init(addr, scope_id); } Inet6Address(String hostName, byte addr[]) { + holder6 = new Inet6AddressHolder(); try { initif (hostName, addr, null); } catch (UnknownHostException e) {} /* cant happen if ifname is null */ @@ -245,12 +397,14 @@ class Inet6Address extends InetAddress { Inet6Address (String hostName, byte addr[], NetworkInterface nif) throws UnknownHostException { + holder6 = new Inet6AddressHolder(); initif (hostName, addr, nif); } Inet6Address (String hostName, byte addr[], String ifname) throws UnknownHostException { + holder6 = new Inet6AddressHolder(); initstr (hostName, addr, ifname); } @@ -341,17 +495,13 @@ class Inet6Address extends InetAddress { private void initif(String hostName, byte addr[], NetworkInterface nif) throws UnknownHostException { - holder().hostName = hostName; + int family = -1; + holder6.init(addr, nif); + if (addr.length == INADDRSZ) { // normal IPv6 address - holder().family = IPv6; - ipaddress = addr.clone(); - } - if (nif != null) { - scope_ifname = nif; - scope_id = deriveNumericScope(nif); - scope_id_set = true; - scope_ifname_set = true; // for consistency + family = IPv6; } + holder.init(hostName, family); } /* check the two Ipv6 addresses and return false if they are both @@ -359,17 +509,22 @@ class Inet6Address extends InetAddress { * (ie. one is sitelocal and the other linklocal) * return true otherwise. */ - private boolean differentLocalAddressTypes(Inet6Address other) { - if (isLinkLocalAddress() && !other.isLinkLocalAddress()) + + private static boolean isDifferentLocalAddressType( + byte[] thisAddr, byte[] otherAddr) { + + if (Inet6Address.isLinkLocalAddress(thisAddr) && + !Inet6Address.isLinkLocalAddress(otherAddr)) { return false; - if (isSiteLocalAddress() && !other.isSiteLocalAddress()) + } + if (Inet6Address.isSiteLocalAddress(thisAddr) && + !Inet6Address.isSiteLocalAddress(otherAddr)) { return false; + } return true; } - private int deriveNumericScope(NetworkInterface ifc) - throws UnknownHostException - { + private static int deriveNumericScope (byte[] thisAddr, NetworkInterface ifc) throws UnknownHostException { Enumeration addresses = ifc.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress addr = addresses.nextElement(); @@ -378,46 +533,60 @@ class Inet6Address extends InetAddress { } Inet6Address ia6_addr = (Inet6Address)addr; /* check if site or link local prefixes match */ - if (!differentLocalAddressTypes(ia6_addr)){ + if (!isDifferentLocalAddressType(thisAddr, ia6_addr.getAddress())){ /* type not the same, so carry on searching */ continue; } /* found a matching address - return its scope_id */ - return ia6_addr.scope_id; + return ia6_addr.getScopeId(); } throw new UnknownHostException ("no scope_id found"); } - private int deriveNumericScope(String ifname) throws UnknownHostException { + private int deriveNumericScope (String ifname) throws UnknownHostException { Enumeration en; try { en = NetworkInterface.getNetworkInterfaces(); } catch (SocketException e) { - throw new UnknownHostException( - "could not enumerate local network interfaces"); + throw new UnknownHostException ("could not enumerate local network interfaces"); } while (en.hasMoreElements()) { NetworkInterface ifc = en.nextElement(); - if (ifc.getName().equals(ifname)) { - Enumeration addresses = ifc.getInetAddresses(); - while (addresses.hasMoreElements()) { - InetAddress addr = addresses.nextElement(); - if (!(addr instanceof Inet6Address)) { - continue; - } - Inet6Address ia6_addr = (Inet6Address)addr; - /* check if site or link local prefixes match */ - if (!differentLocalAddressTypes(ia6_addr)){ - /* type not the same, so carry on searching */ - continue; - } - /* found a matching address - return its scope_id */ - return ia6_addr.scope_id; - } + if (ifc.getName().equals (ifname)) { + return deriveNumericScope(holder6.ipaddress, ifc); } } - throw new UnknownHostException( - "No matching address found for interface : " +ifname); + throw new UnknownHostException ("No matching address found for interface : " +ifname); + } + + /** + * @serialField ipaddress byte[] + * @serialField scope_id int + * @serialField scope_id_set boolean + * @serialField scope_ifname_set boolean + * @serialField ifname String + */ + + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("ipaddress", byte[].class), + new ObjectStreamField("scope_id", int.class), + new ObjectStreamField("scope_id_set", boolean.class), + new ObjectStreamField("scope_ifname_set", boolean.class), + new ObjectStreamField("ifname", String.class) + }; + + private static final long FIELDS_OFFSET; + private static final sun.misc.Unsafe UNSAFE; + + static { + try { + sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe(); + FIELDS_OFFSET = unsafe.objectFieldOffset( + Inet6Address.class.getDeclaredField("holder6")); + UNSAFE = unsafe; + } catch (ReflectiveOperationException e) { + throw new Error(e); + } } /** @@ -427,35 +596,41 @@ class Inet6Address extends InetAddress { */ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { + NetworkInterface scope_ifname = null; if (getClass().getClassLoader() != null) { throw new SecurityException ("invalid address type"); } - s.defaultReadObject(); + ObjectInputStream.GetField gf = s.readFields(); + byte[] ipaddress = (byte[])gf.get("ipaddress", null); + int scope_id = (int)gf.get("scope_id", -1); + boolean scope_id_set = (boolean)gf.get("scope_id_set", false); + boolean scope_ifname_set = (boolean)gf.get("scope_ifname_set", false); + String ifname = (String)gf.get("ifname", null); - if (ifname != null && !ifname.equals("")) { + if (ifname != null && !"".equals (ifname)) { try { scope_ifname = NetworkInterface.getByName(ifname); - if (scope_ifname != null) { - scope_ifname_set = true; - try { - scope_id = deriveNumericScope(scope_ifname); - } catch (UnknownHostException e) { - // typically should not happen, but it may be that - // the machine being used for deserialization has - // the same interface name but without IPv6 configured. - } - } else { + if (scope_ifname == null) { /* the interface does not exist on this system, so we clear * the scope information completely */ scope_id_set = false; scope_ifname_set = false; scope_id = 0; + } else { + scope_ifname_set = true; + try { + scope_id = deriveNumericScope (ipaddress, scope_ifname); + } catch (UnknownHostException e) { + // typically should not happen, but it may be that + // the machine being used for deserialization has + // the same interface name but without IPv6 configured. + } } } catch (SocketException e) {} - } + /* if ifname was not supplied, then the numeric info is used */ ipaddress = ipaddress.clone(); @@ -466,9 +641,38 @@ class Inet6Address extends InetAddress { ipaddress.length); } - if (holder().getFamily() != IPv6) { + if (holder.getFamily() != IPv6) { throw new InvalidObjectException("invalid address family type"); } + + Inet6AddressHolder h = new Inet6AddressHolder( + ipaddress, scope_id, scope_id_set, scope_ifname, scope_ifname_set + ); + + UNSAFE.putObject(this, FIELDS_OFFSET, h); + } + + /** + * default behavior is overridden in order to write the + * scope_ifname field as a String, rather than a NetworkInterface + * which is not serializable + */ + private synchronized void writeObject(ObjectOutputStream s) + throws IOException + { + String ifname = null; + + if (holder6.scope_ifname != null) { + ifname = holder6.scope_ifname.getName(); + holder6.scope_ifname_set = true; + } + ObjectOutputStream.PutField pfields = s.putFields(); + pfields.put("ipaddress", holder6.ipaddress); + pfields.put("scope_id", holder6.scope_id); + pfields.put("scope_id_set", holder6.scope_id_set); + pfields.put("scope_ifname_set", holder6.scope_ifname_set); + pfields.put("ifname", ifname); + s.writeFields(); } /** @@ -483,7 +687,7 @@ class Inet6Address extends InetAddress { */ @Override public boolean isMulticastAddress() { - return ((ipaddress[0] & 0xff) == 0xff); + return holder6.isMulticastAddress(); } /** @@ -496,11 +700,7 @@ class Inet6Address extends InetAddress { */ @Override public boolean isAnyLocalAddress() { - byte test = 0x00; - for (int i = 0; i < INADDRSZ; i++) { - test |= ipaddress[i]; - } - return (test == 0x00); + return holder6.isAnyLocalAddress(); } /** @@ -513,11 +713,7 @@ class Inet6Address extends InetAddress { */ @Override public boolean isLoopbackAddress() { - byte test = 0x00; - for (int i = 0; i < 15; i++) { - test |= ipaddress[i]; - } - return (test == 0x00) && (ipaddress[15] == 0x01); + return holder6.isLoopbackAddress(); } /** @@ -530,6 +726,11 @@ class Inet6Address extends InetAddress { */ @Override public boolean isLinkLocalAddress() { + return holder6.isLinkLocalAddress(); + } + + /* static version of above */ + static boolean isLinkLocalAddress(byte[] ipaddress) { return ((ipaddress[0] & 0xff) == 0xfe && (ipaddress[1] & 0xc0) == 0x80); } @@ -544,6 +745,11 @@ class Inet6Address extends InetAddress { */ @Override public boolean isSiteLocalAddress() { + return holder6.isSiteLocalAddress(); + } + + /* static version of above */ + static boolean isSiteLocalAddress(byte[] ipaddress) { return ((ipaddress[0] & 0xff) == 0xfe && (ipaddress[1] & 0xc0) == 0xc0); } @@ -559,8 +765,7 @@ class Inet6Address extends InetAddress { */ @Override public boolean isMCGlobal() { - return ((ipaddress[0] & 0xff) == 0xff - && (ipaddress[1] & 0x0f) == 0x0e); + return holder6.isMCGlobal(); } /** @@ -574,8 +779,7 @@ class Inet6Address extends InetAddress { */ @Override public boolean isMCNodeLocal() { - return ((ipaddress[0] & 0xff) == 0xff - && (ipaddress[1] & 0x0f) == 0x01); + return holder6.isMCNodeLocal(); } /** @@ -589,8 +793,7 @@ class Inet6Address extends InetAddress { */ @Override public boolean isMCLinkLocal() { - return ((ipaddress[0] & 0xff) == 0xff - && (ipaddress[1] & 0x0f) == 0x02); + return holder6.isMCLinkLocal(); } /** @@ -604,8 +807,7 @@ class Inet6Address extends InetAddress { */ @Override public boolean isMCSiteLocal() { - return ((ipaddress[0] & 0xff) == 0xff - && (ipaddress[1] & 0x0f) == 0x05); + return holder6.isMCSiteLocal(); } /** @@ -619,10 +821,8 @@ class Inet6Address extends InetAddress { */ @Override public boolean isMCOrgLocal() { - return ((ipaddress[0] & 0xff) == 0xff - && (ipaddress[1] & 0x0f) == 0x08); + return holder6.isMCOrgLocal(); } - /** * Returns the raw IP address of this {@code InetAddress} object. The result * is in network byte order: the highest order byte of the address is in @@ -632,7 +832,7 @@ class Inet6Address extends InetAddress { */ @Override public byte[] getAddress() { - return ipaddress.clone(); + return holder6.ipaddress.clone(); } /** @@ -644,7 +844,7 @@ class Inet6Address extends InetAddress { * @since 1.5 */ public int getScopeId() { - return scope_id; + return holder6.scope_id; } /** @@ -655,7 +855,7 @@ class Inet6Address extends InetAddress { * @since 1.5 */ public NetworkInterface getScopedInterface() { - return scope_ifname; + return holder6.scope_ifname; } /** @@ -669,13 +869,7 @@ class Inet6Address extends InetAddress { */ @Override public String getHostAddress() { - String s = numericToTextFormat(ipaddress); - if (scope_ifname != null) { /* must check this first */ - s = s + "%" + scope_ifname.getName(); - } else if (scope_id_set) { - s = s + "%" + scope_id; - } - return s; + return holder6.getHostAddress(); } /** @@ -685,25 +879,7 @@ class Inet6Address extends InetAddress { */ @Override public int hashCode() { - if (ipaddress != null) { - - int hash = 0; - int i=0; - while (iFindClass(env, "java/net/Inet6Address"); CHECK_NULL(c); ia6_class = (*env)->NewGlobalRef(env, c); CHECK_NULL(ia6_class); - ia6_ipaddressID = (*env)->GetFieldID(env, ia6_class, "ipaddress", "[B"); + ia6h_class = (*env)->FindClass(env, "java/net/Inet6Address$Inet6AddressHolder"); + CHECK_NULL(ia6h_class); + ia6_holder6ID = (*env)->GetFieldID(env, ia6_class, "holder6", "Ljava/net/Inet6Address$Inet6AddressHolder;"); + CHECK_NULL(ia6_holder6ID); + ia6_ipaddressID = (*env)->GetFieldID(env, ia6h_class, "ipaddress", "[B"); CHECK_NULL(ia6_ipaddressID); - ia6_scopeidID = (*env)->GetFieldID(env, ia6_class, "scope_id", "I"); + ia6_scopeidID = (*env)->GetFieldID(env, ia6h_class, "scope_id", "I"); CHECK_NULL(ia6_scopeidID); ia6_cachedscopeidID = (*env)->GetFieldID(env, ia6_class, "cached_scope_id", "I"); CHECK_NULL(ia6_cachedscopeidID); - ia6_scopeidsetID = (*env)->GetFieldID(env, ia6_class, "scope_id_set", "Z"); + ia6_scopeidsetID = (*env)->GetFieldID(env, ia6h_class, "scope_id_set", "Z"); CHECK_NULL(ia6_scopeidID); - ia6_scopeifnameID = (*env)->GetFieldID(env, ia6_class, "scope_ifname", "Ljava/net/NetworkInterface;"); + ia6_scopeifnameID = (*env)->GetFieldID(env, ia6h_class, "scope_ifname", "Ljava/net/NetworkInterface;"); CHECK_NULL(ia6_scopeifnameID); ia6_ctrID = (*env)->GetMethodID(env, ia6_class, "", "()V"); CHECK_NULL(ia6_ctrID); diff --git a/jdk/src/share/native/java/net/net_util.c b/jdk/src/share/native/java/net/net_util.c index 5d15f9d9b0e..d52577ce25b 100644 --- a/jdk/src/share/native/java/net/net_util.c +++ b/jdk/src/share/native/java/net/net_util.c @@ -94,6 +94,92 @@ extern jfieldID ia_holderID; extern jfieldID iac_addressID; extern jfieldID iac_familyID; +/** + * set_ methods return JNI_TRUE on success JNI_FALSE on error + * get_ methods that return +ve int return -1 on error + * get_ methods that return objects return NULL on error. + */ +jobject getInet6Address_scopeifname(JNIEnv *env, jobject iaObj) { + jobject holder; + + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID); + CHECK_NULL_RETURN(holder, NULL); + return (*env)->GetObjectField(env, holder, ia6_scopeifnameID); +} + +int setInet6Address_scopeifname(JNIEnv *env, jobject iaObj, jobject scopeifname) { + jobject holder; + + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID); + CHECK_NULL_RETURN(holder, JNI_FALSE); + (*env)->SetObjectField(env, holder, ia6_scopeifnameID, scopeifname); + return JNI_TRUE; +} + +int getInet6Address_scopeid_set(JNIEnv *env, jobject iaObj) { + jobject holder; + + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID); + CHECK_NULL_RETURN(holder, -1); + return (*env)->GetBooleanField(env, holder, ia6_scopeidsetID); +} + +int getInet6Address_scopeid(JNIEnv *env, jobject iaObj) { + jobject holder; + + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID); + CHECK_NULL_RETURN(holder, -1); + return (*env)->GetIntField(env, holder, ia6_scopeidID); +} + +int setInet6Address_scopeid(JNIEnv *env, jobject iaObj, int scopeid) { + jobject holder; + + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID); + CHECK_NULL_RETURN(holder, JNI_FALSE); + (*env)->SetIntField(env, holder, ia6_scopeidID, scopeid); + if (scopeid > 0) { + (*env)->SetBooleanField(env, holder, ia6_scopeidsetID, JNI_TRUE); + } + return JNI_TRUE; +} + + +int getInet6Address_ipaddress(JNIEnv *env, jobject iaObj, char *dest) { + jobject holder, addr; + jbyteArray barr; + + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID); + CHECK_NULL_RETURN(holder, JNI_FALSE); + addr = (*env)->GetObjectField(env, holder, ia6_ipaddressID); + CHECK_NULL_RETURN(addr, JNI_FALSE); + (*env)->GetByteArrayRegion(env, addr, 0, 16, (jbyte *)dest); + return JNI_TRUE; +} + +int setInet6Address_ipaddress(JNIEnv *env, jobject iaObj, char *address) { + jobject holder; + jbyteArray addr; + + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID); + CHECK_NULL_RETURN(holder, JNI_FALSE); + addr = (jbyteArray)(*env)->GetObjectField(env, holder, ia6_ipaddressID); + if (addr == NULL) { + addr = (*env)->NewByteArray(env, 16); + CHECK_NULL_RETURN(addr, JNI_FALSE); + (*env)->SetObjectField(env, holder, ia6_ipaddressID, addr); + } + (*env)->SetByteArrayRegion(env, addr, 0, 16, (jbyte *)address); + return JNI_TRUE; +} + void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) { jobject holder; init(env); @@ -167,6 +253,7 @@ NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) { } else { static jclass inet6Cls = 0; jint scope; + int ret; if (inet6Cls == 0) { jclass c = (*env)->FindClass(env, "java/net/Inet6Address"); CHECK_NULL_RETURN(c, NULL); @@ -176,18 +263,11 @@ NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) { } iaObj = (*env)->NewObject(env, inet6Cls, ia6_ctrID); CHECK_NULL_RETURN(iaObj, NULL); - ipaddress = (*env)->NewByteArray(env, 16); - CHECK_NULL_RETURN(ipaddress, NULL); - (*env)->SetByteArrayRegion(env, ipaddress, 0, 16, - (jbyte *)&(him6->sin6_addr)); - - (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress); - + ret = setInet6Address_ipaddress(env, iaObj, (char *)&(him6->sin6_addr)); + CHECK_NULL_RETURN(ret, NULL); setInetAddress_family(env, iaObj, IPv6); scope = getScopeID(him); - (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); - if (scope > 0) - (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); + setInet6Address_scopeid(env, iaObj, scope); } *port = ntohs(him6->sin6_port); } else @@ -247,9 +327,8 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, struct sockaddr *him, jobject iaObj) if (family == AF_INET) { return JNI_FALSE; } - ipaddress = (*env)->GetObjectField(env, iaObj, ia6_ipaddressID); - scope = (*env)->GetIntField(env, iaObj, ia6_scopeidID); - (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddrCur); + scope = getInet6Address_scopeid(env, iaObj); + getInet6Address_ipaddress(env, iaObj, (char *)caddrCur); if (NET_IsEqual(caddrNew, caddrCur) && cmpScopeID(scope, him)) { return JNI_TRUE; } else { diff --git a/jdk/src/share/native/java/net/net_util.h b/jdk/src/share/native/java/net/net_util.h index 0fd5b6c427f..d38a5f52fcf 100644 --- a/jdk/src/share/native/java/net/net_util.h +++ b/jdk/src/share/native/java/net/net_util.h @@ -58,6 +58,19 @@ extern jfieldID iac_familyID; extern jfieldID iac_hostNameID; extern jfieldID ia_preferIPv6AddressID; +/** (Inet6Address accessors) + * set_ methods return JNI_TRUE on success JNI_FALSE on error + * get_ methods that return int/boolean, return -1 on error + * get_ methods that return objects return NULL on error. + */ +extern jobject getInet6Address_scopeifname(JNIEnv *env, jobject ia6Obj); +extern int setInet6Address_scopeifname(JNIEnv *env, jobject ia6Obj, jobject scopeifname); +extern int getInet6Address_scopeid_set(JNIEnv *env, jobject ia6Obj); +extern int getInet6Address_scopeid(JNIEnv *env, jobject ia6Obj); +extern int setInet6Address_scopeid(JNIEnv *env, jobject ia6Obj, int scopeid); +extern int getInet6Address_ipaddress(JNIEnv *env, jobject ia6Obj, char *dest); +extern int setInet6Address_ipaddress(JNIEnv *env, jobject ia6Obj, char *address); + extern void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address); extern void setInetAddress_family(JNIEnv *env, jobject iaObj, int family); extern void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject h); @@ -93,12 +106,12 @@ extern jfieldID dp_bufLengthID; /* Inet6Address fields */ extern jclass ia6_class; +extern jfieldID ia6_holder6ID; extern jfieldID ia6_ipaddressID; extern jfieldID ia6_scopeidID; extern jfieldID ia6_cachedscopeidID; extern jfieldID ia6_scopeidsetID; extern jfieldID ia6_scopeifnameID; -extern jfieldID ia6_scopeifnamesetID; extern jmethodID ia6_ctrID; /************************************************************************ diff --git a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c index 4fc64867f8b..694826f3aba 100644 --- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c +++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c @@ -120,7 +120,6 @@ static jclass ni_ia4cls; static jclass ni_ia6cls; static jmethodID ni_ia4ctrID; static jmethodID ni_ia6ctrID; -static jfieldID ni_ia6ipaddressID; static int initialized = 0; /* @@ -156,7 +155,6 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls); ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "", "()V"); ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "", "()V"); - ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B"); initialized = 1; } @@ -303,6 +301,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, } while (iterator != NULL) { + int ret1; if (iterator->ai_family == AF_INET) { jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID); if (IS_NULL(iaObj)) { @@ -315,26 +314,22 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, inetIndex++; } else if (iterator->ai_family == AF_INET6) { jint scope = 0; - jbyteArray ipaddress; jobject iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID); if (IS_NULL(iaObj)) { ret = NULL; goto cleanupAndReturn; } - ipaddress = (*env)->NewByteArray(env, 16); - if (IS_NULL(ipaddress)) { + ret1 = setInet6Address_ipaddress(env, iaObj, (char *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr)); + if (!ret1) { ret = NULL; goto cleanupAndReturn; } - (*env)->SetByteArrayRegion(env, ipaddress, 0, 16, - (jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr)); + scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id; if (scope != 0) { /* zero is default value, no need to set */ - (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); - (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); + setInet6Address_scopeid(env, iaObj, scope); } - (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress); setInetAddress_hostName(env, iaObj, host); (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj); inet6Index++; diff --git a/jdk/src/solaris/native/java/net/NetworkInterface.c b/jdk/src/solaris/native/java/net/NetworkInterface.c index 68633db5a18..1c999442168 100644 --- a/jdk/src/solaris/native/java/net/NetworkInterface.c +++ b/jdk/src/solaris/native/java/net/NetworkInterface.c @@ -118,7 +118,6 @@ static jclass ni_ibcls; static jmethodID ni_ia4ctrID; static jmethodID ni_ia6ctrID; static jmethodID ni_ibctrID; -static jfieldID ni_ia6ipaddressID; static jfieldID ni_ibaddressID; static jfieldID ni_ib4broadcastID; static jfieldID ni_ib4maskID; @@ -193,7 +192,6 @@ Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls) { ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "", "()V"); ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "", "()V"); ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "", "()V"); - ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B"); ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;"); ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;"); ni_ib4maskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S"); @@ -332,11 +330,9 @@ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 #ifdef AF_INET6 if (family == AF_INET6) { jbyte *bytes = (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr); - jbyteArray ipaddress = (*env)->GetObjectField(env, iaObj, ni_ia6ipaddressID); jbyte caddr[16]; int i; - - (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr); + getInet6Address_ipaddress(env, iaObj, (char *)caddr); i = 0; while (i < 16) { if (caddr[i] != bytes[i]) { @@ -670,21 +666,17 @@ jobject createNetworkInterface(JNIEnv *env, netif *ifs) { int scope=0; iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID); if (iaObj) { - jbyteArray ipaddress = (*env)->NewByteArray(env, 16); - if (ipaddress == NULL) { + int ret = setInet6Address_ipaddress(env, iaObj, (char *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr)); + if (ret == JNI_FALSE) { return NULL; } - (*env)->SetByteArrayRegion(env, ipaddress, 0, 16, - (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr)); scope = ((struct sockaddr_in6*)addrP->addr)->sin6_scope_id; if (scope != 0) { /* zero is default value, no need to set */ - (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); - (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); - (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj); + setInet6Address_scopeid(env, iaObj, scope); + setInet6Address_scopeifname(env, iaObj, netifObj); } - (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress); } ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); if (ibObj) { diff --git a/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c b/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c index 981bf534a66..09f8e5d0c61 100644 --- a/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c +++ b/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c @@ -2148,8 +2148,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this, caddr[14] = ((address >> 8) & 0xff); caddr[15] = (address & 0xff); } else { - ipaddress = (*env)->GetObjectField(env, iaObj, ia6_ipaddressID); - (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr); + getInet6Address_ipaddress(env, iaObj, caddr); } memcpy((void *)&(mname6.ipv6mr_multiaddr), caddr, sizeof(struct in6_addr)); diff --git a/jdk/src/solaris/native/java/net/net_util_md.c b/jdk/src/solaris/native/java/net/net_util_md.c index 004b6aa5d92..d7ebbd5a7c9 100644 --- a/jdk/src/solaris/native/java/net/net_util_md.c +++ b/jdk/src/solaris/native/java/net/net_util_md.c @@ -782,7 +782,6 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr /* needs work. 1. family 2. clean up him6 etc deallocate memory */ if (ipv6_available() && !(family == IPv4 && v4MappedAddress == JNI_FALSE)) { struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him; - jbyteArray ipaddress; jbyte caddr[16]; jint address; @@ -803,8 +802,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr caddr[15] = (address & 0xff); } } else { - ipaddress = (*env)->GetObjectField(env, iaObj, ia6_ipaddressID); - (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr); + getInet6Address_ipaddress(env, iaObj, (char *)caddr); } memset((char *)him6, 0, sizeof(struct sockaddr_in6)); him6->sin6_port = htons(port); @@ -840,7 +838,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr */ if (!cached_scope_id) { if (ia6_scopeidID) { - scope_id = (int)(*env)->GetIntField(env,iaObj,ia6_scopeidID); + scope_id = getInet6Address_scopeid(env, iaObj); } if (scope_id != 0) { /* check user-specified value for loopback case @@ -884,7 +882,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr if (family != IPv4) { if (ia6_scopeidID) { - him6->sin6_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_scopeidID); + him6->sin6_scope_id = getInet6Address_scopeid(env, iaObj); } } #endif diff --git a/jdk/src/windows/native/java/net/Inet6AddressImpl.c b/jdk/src/windows/native/java/net/Inet6AddressImpl.c index 6f46d7eb642..c124f91f4d5 100644 --- a/jdk/src/windows/native/java/net/Inet6AddressImpl.c +++ b/jdk/src/windows/native/java/net/Inet6AddressImpl.c @@ -77,7 +77,6 @@ static jclass ni_ia4cls; static jclass ni_ia6cls; static jmethodID ni_ia4ctrID; static jmethodID ni_ia6ctrID; -static jfieldID ni_ia6ipaddressID; static int initialized = 0; JNIEXPORT jobjectArray JNICALL @@ -101,7 +100,6 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls); ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "", "()V"); ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "", "()V"); - ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B"); initialized = 1; } if (IS_NULL(host)) { @@ -242,26 +240,22 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj); inetIndex ++; } else if (iterator->ai_family == AF_INET6) { - jint scope = 0; - jbyteArray ipaddress; + jint scope = 0, ret1; jobject iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID); if (IS_NULL(iaObj)) { ret = NULL; goto cleanupAndReturn; } - ipaddress = (*env)->NewByteArray(env, 16); - if (IS_NULL(ipaddress)) { + ret1 = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr)); + + if (ret1 == JNI_FALSE) { ret = NULL; goto cleanupAndReturn; } - (*env)->SetByteArrayRegion(env, ipaddress, 0, 16, - (jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr)); scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id; if (scope != 0) { /* zero is default value, no need to set */ - (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); - (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); + setInet6Address_scopeid(env, iaObj, scope); } - (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress); setInetAddress_hostName(env, iaObj, host); (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj); inet6Index ++; diff --git a/jdk/src/windows/native/java/net/NetworkInterface.c b/jdk/src/windows/native/java/net/NetworkInterface.c index c548930a913..edcccd4ae4c 100644 --- a/jdk/src/windows/native/java/net/NetworkInterface.c +++ b/jdk/src/windows/native/java/net/NetworkInterface.c @@ -72,8 +72,6 @@ jmethodID ni_ia4Ctor; /* Inet4Address() */ jclass ni_ia6cls; /* Inet6Address */ jmethodID ni_ia6ctrID; /* Inet6Address() */ -jfieldID ni_ia6ipaddressID; -jfieldID ni_ia6ipaddressID; jclass ni_ibcls; /* InterfaceAddress */ jmethodID ni_ibctrID; /* InterfaceAddress() */ @@ -520,7 +518,6 @@ Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls) ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address"); ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls); ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "", "()V"); - ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B"); ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress"); ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls); @@ -621,19 +618,16 @@ jobject createNetworkInterface int scope; iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID); if (iaObj) { - jbyteArray ipaddress = (*env)->NewByteArray(env, 16); - if (ipaddress == NULL) { + int ret = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr)); + if (ret == JNI_FALSE) { return NULL; } - (*env)->SetByteArrayRegion(env, ipaddress, 0, 16, - (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr)); + scope = addrs->addr.him6.sin6_scope_id; if (scope != 0) { /* zero is default value, no need to set */ - (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); - (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); - (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj); + setInet6Address_scopeid(env, iaObj, scope); + setInet6Address_scopeifname(env, iaObj, netifObj); } - (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress); ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); if (ibObj == NULL) { free_netaddr(netaddrP); diff --git a/jdk/src/windows/native/java/net/NetworkInterface_winXP.c b/jdk/src/windows/native/java/net/NetworkInterface_winXP.c index 1078d826afa..67374a02583 100644 --- a/jdk/src/windows/native/java/net/NetworkInterface_winXP.c +++ b/jdk/src/windows/native/java/net/NetworkInterface_winXP.c @@ -544,19 +544,15 @@ static jobject createNetworkInterfaceXP(JNIEnv *env, netif *ifs) int scope; iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID); if (iaObj) { - jbyteArray ipaddress = (*env)->NewByteArray(env, 16); - if (ipaddress == NULL) { + int ret = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr)); + if (ret == JNI_FALSE) { return NULL; } - (*env)->SetByteArrayRegion(env, ipaddress, 0, 16, - (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr)); scope = addrs->addr.him6.sin6_scope_id; if (scope != 0) { /* zero is default value, no need to set */ - (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); - (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); - (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj); + setInet6Address_scopeid(env, iaObj, scope); + setInet6Address_scopeifname(env, iaObj, netifObj); } - (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress); ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); if (ibObj == NULL) { free_netaddr(netaddrP); diff --git a/jdk/src/windows/native/java/net/TwoStacksPlainSocketImpl.c b/jdk/src/windows/native/java/net/TwoStacksPlainSocketImpl.c index 6823ddc7c7c..f535073df38 100644 --- a/jdk/src/windows/native/java/net/TwoStacksPlainSocketImpl.c +++ b/jdk/src/windows/native/java/net/TwoStacksPlainSocketImpl.c @@ -728,7 +728,6 @@ Java_java_net_TwoStacksPlainSocketImpl_socketAccept(JNIEnv *env, jobject this, setInetAddress_family(env, socketAddressObj, IPv4); (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj); } else { - jbyteArray addr; /* AF_INET6 -> Inet6Address */ if (inet6Cls == 0) { jclass c = (*env)->FindClass(env, "java/net/Inet6Address"); @@ -751,14 +750,10 @@ Java_java_net_TwoStacksPlainSocketImpl_socketAccept(JNIEnv *env, jobject this, NET_SocketClose(fd); return; } - addr = (*env)->GetObjectField (env, socketAddressObj, ia6_ipaddressID); - (*env)->SetByteArrayRegion (env, addr, 0, 16, (const char *)&him.him6.sin6_addr); + setInet6Address_ipaddress(env, socketAddressObj, (const char *)&him.him6.sin6_addr); setInetAddress_family(env, socketAddressObj, IPv6); - scope = him.him6.sin6_scope_id; - (*env)->SetIntField(env, socketAddressObj, ia6_scopeidID, scope); - if(scope>0) { - (*env)->SetBooleanField(env, socketAddressObj, ia6_scopeidsetID, JNI_TRUE); - } + setInet6Address_scopeid(env, socketAddressObj, him.him6.sin6_scope_id); + } /* fields common to AF_INET and AF_INET6 */ diff --git a/jdk/src/windows/native/java/net/net_util_md.c b/jdk/src/windows/native/java/net/net_util_md.c index 4e5cb50b0bc..6ddb2bcfd78 100644 --- a/jdk/src/windows/native/java/net/net_util_md.c +++ b/jdk/src/windows/native/java/net/net_util_md.c @@ -851,7 +851,6 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr family = (iafam == IPv4)? AF_INET : AF_INET6; if (ipv6_available() && !(family == AF_INET && v4MappedAddress == JNI_FALSE)) { struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him; - jbyteArray ipaddress; jbyte caddr[16]; jint address, scopeid = 0; jint cached_scope_id = 0; @@ -872,10 +871,9 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr caddr[15] = (address & 0xff); } } else { - ipaddress = (*env)->GetObjectField(env, iaObj, ia6_ipaddressID); - scopeid = (jint)(*env)->GetIntField(env, iaObj, ia6_scopeidID); + getInet6Address_ipaddress(env, iaObj, (char *)caddr); + scopeid = getInet6Address_scopeid(env, iaObj); cached_scope_id = (jint)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID); - (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr); } memset((char *)him6, 0, sizeof(struct SOCKADDR_IN6)); diff --git a/jdk/test/java/net/Inet6Address/serialize/Serialize.java b/jdk/test/java/net/Inet6Address/serialize/Serialize.java index c563c8b115a..f7c6fe735fb 100644 --- a/jdk/test/java/net/Inet6Address/serialize/Serialize.java +++ b/jdk/test/java/net/Inet6Address/serialize/Serialize.java @@ -94,7 +94,26 @@ public class Serialize { } finally { ois.close(); } - System.out.println(nobj); + + nobj = (Inet6Address)InetAddress.getByAddress("foo.com", new byte[] { + (byte)0xfe,(byte)0x80,(byte)0,(byte)0,(byte)0,(byte)0,(byte)0,(byte)0, + (byte)0,(byte)0,(byte)0,(byte)0,(byte)0,(byte)0,(byte)0,(byte)1 + }); + if (!test1(nobj, addr1)) { + throw new RuntimeException("failed with " + nobj.toString()); + } + nobj = (Inet6Address)InetAddress.getByAddress("x.bar.com", new byte[] { + (byte)0xfe,(byte)0xC0,(byte)0,(byte)0,(byte)0,(byte)0,(byte)0,(byte)0, + (byte)0,(byte)0,(byte)0,(byte)0,(byte)0,(byte)0,(byte)0,(byte)1 + }); + if (!test1(nobj, addr2)) { + throw new RuntimeException("failed with " + nobj.toString()); + } + nobj = (Inet6Address)InetAddress.getByName("::1"); + if (!test1(nobj, addr3)) { + throw new RuntimeException("failed with " + nobj.toString()); + } + System.out.println("All tests passed"); } @@ -113,4 +132,162 @@ public class Serialize { return false; } } - } + + static boolean test1 (Inet6Address obj, byte[] buf) throws Exception { + ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(buf)); + Inet6Address nobj = (Inet6Address) ois.readObject(); + ois.close(); + + if (nobj.equals(obj)) { + return true; + } else { + return false; + } + } + + // Inet6Address instances serialized with JDK 6 + + static byte[] addr1 = { + (byte)0xac,(byte)0xed,(byte)0x00,(byte)0x05,(byte)0x73,(byte)0x72, + (byte)0x00,(byte)0x15,(byte)0x6a,(byte)0x61,(byte)0x76,(byte)0x61, + (byte)0x2e,(byte)0x6e,(byte)0x65,(byte)0x74,(byte)0x2e,(byte)0x49, + (byte)0x6e,(byte)0x65,(byte)0x74,(byte)0x36,(byte)0x41,(byte)0x64, + (byte)0x64,(byte)0x72,(byte)0x65,(byte)0x73,(byte)0x73,(byte)0x5f, + (byte)0x7c,(byte)0x20,(byte)0x81,(byte)0x52,(byte)0x2c,(byte)0x80, + (byte)0x21,(byte)0x03,(byte)0x00,(byte)0x05,(byte)0x49,(byte)0x00, + (byte)0x08,(byte)0x73,(byte)0x63,(byte)0x6f,(byte)0x70,(byte)0x65, + (byte)0x5f,(byte)0x69,(byte)0x64,(byte)0x5a,(byte)0x00,(byte)0x0c, + (byte)0x73,(byte)0x63,(byte)0x6f,(byte)0x70,(byte)0x65,(byte)0x5f, + (byte)0x69,(byte)0x64,(byte)0x5f,(byte)0x73,(byte)0x65,(byte)0x74, + (byte)0x5a,(byte)0x00,(byte)0x10,(byte)0x73,(byte)0x63,(byte)0x6f, + (byte)0x70,(byte)0x65,(byte)0x5f,(byte)0x69,(byte)0x66,(byte)0x6e, + (byte)0x61,(byte)0x6d,(byte)0x65,(byte)0x5f,(byte)0x73,(byte)0x65, + (byte)0x74,(byte)0x4c,(byte)0x00,(byte)0x06,(byte)0x69,(byte)0x66, + (byte)0x6e,(byte)0x61,(byte)0x6d,(byte)0x65,(byte)0x74,(byte)0x00, + (byte)0x12,(byte)0x4c,(byte)0x6a,(byte)0x61,(byte)0x76,(byte)0x61, + (byte)0x2f,(byte)0x6c,(byte)0x61,(byte)0x6e,(byte)0x67,(byte)0x2f, + (byte)0x53,(byte)0x74,(byte)0x72,(byte)0x69,(byte)0x6e,(byte)0x67, + (byte)0x3b,(byte)0x5b,(byte)0x00,(byte)0x09,(byte)0x69,(byte)0x70, + (byte)0x61,(byte)0x64,(byte)0x64,(byte)0x72,(byte)0x65,(byte)0x73, + (byte)0x73,(byte)0x74,(byte)0x00,(byte)0x02,(byte)0x5b,(byte)0x42, + (byte)0x78,(byte)0x72,(byte)0x00,(byte)0x14,(byte)0x6a,(byte)0x61, + (byte)0x76,(byte)0x61,(byte)0x2e,(byte)0x6e,(byte)0x65,(byte)0x74, + (byte)0x2e,(byte)0x49,(byte)0x6e,(byte)0x65,(byte)0x74,(byte)0x41, + (byte)0x64,(byte)0x64,(byte)0x72,(byte)0x65,(byte)0x73,(byte)0x73, + (byte)0x2d,(byte)0x9b,(byte)0x57,(byte)0xaf,(byte)0x9f,(byte)0xe3, + (byte)0xeb,(byte)0xdb,(byte)0x02,(byte)0x00,(byte)0x03,(byte)0x49, + (byte)0x00,(byte)0x07,(byte)0x61,(byte)0x64,(byte)0x64,(byte)0x72, + (byte)0x65,(byte)0x73,(byte)0x73,(byte)0x49,(byte)0x00,(byte)0x06, + (byte)0x66,(byte)0x61,(byte)0x6d,(byte)0x69,(byte)0x6c,(byte)0x79, + (byte)0x4c,(byte)0x00,(byte)0x08,(byte)0x68,(byte)0x6f,(byte)0x73, + (byte)0x74,(byte)0x4e,(byte)0x61,(byte)0x6d,(byte)0x65,(byte)0x71, + (byte)0x00,(byte)0x7e,(byte)0x00,(byte)0x01,(byte)0x78,(byte)0x70, + (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x02,(byte)0x74,(byte)0x00,(byte)0x07,(byte)0x66, + (byte)0x6f,(byte)0x6f,(byte)0x2e,(byte)0x63,(byte)0x6f,(byte)0x6d, + (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x70,(byte)0x75,(byte)0x72,(byte)0x00,(byte)0x02,(byte)0x5b, + (byte)0x42,(byte)0xac,(byte)0xf3,(byte)0x17,(byte)0xf8,(byte)0x06, + (byte)0x08,(byte)0x54,(byte)0xe0,(byte)0x02,(byte)0x00,(byte)0x00, + (byte)0x78,(byte)0x70,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x10, + (byte)0xfe,(byte)0x80,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x78 + }; + + static byte[] addr2 = { + (byte)0xac,(byte)0xed,(byte)0x00,(byte)0x05,(byte)0x73,(byte)0x72, + (byte)0x00,(byte)0x15,(byte)0x6a,(byte)0x61,(byte)0x76,(byte)0x61, + (byte)0x2e,(byte)0x6e,(byte)0x65,(byte)0x74,(byte)0x2e,(byte)0x49, + (byte)0x6e,(byte)0x65,(byte)0x74,(byte)0x36,(byte)0x41,(byte)0x64, + (byte)0x64,(byte)0x72,(byte)0x65,(byte)0x73,(byte)0x73,(byte)0x5f, + (byte)0x7c,(byte)0x20,(byte)0x81,(byte)0x52,(byte)0x2c,(byte)0x80, + (byte)0x21,(byte)0x03,(byte)0x00,(byte)0x05,(byte)0x49,(byte)0x00, + (byte)0x08,(byte)0x73,(byte)0x63,(byte)0x6f,(byte)0x70,(byte)0x65, + (byte)0x5f,(byte)0x69,(byte)0x64,(byte)0x5a,(byte)0x00,(byte)0x0c, + (byte)0x73,(byte)0x63,(byte)0x6f,(byte)0x70,(byte)0x65,(byte)0x5f, + (byte)0x69,(byte)0x64,(byte)0x5f,(byte)0x73,(byte)0x65,(byte)0x74, + (byte)0x5a,(byte)0x00,(byte)0x10,(byte)0x73,(byte)0x63,(byte)0x6f, + (byte)0x70,(byte)0x65,(byte)0x5f,(byte)0x69,(byte)0x66,(byte)0x6e, + (byte)0x61,(byte)0x6d,(byte)0x65,(byte)0x5f,(byte)0x73,(byte)0x65, + (byte)0x74,(byte)0x4c,(byte)0x00,(byte)0x06,(byte)0x69,(byte)0x66, + (byte)0x6e,(byte)0x61,(byte)0x6d,(byte)0x65,(byte)0x74,(byte)0x00, + (byte)0x12,(byte)0x4c,(byte)0x6a,(byte)0x61,(byte)0x76,(byte)0x61, + (byte)0x2f,(byte)0x6c,(byte)0x61,(byte)0x6e,(byte)0x67,(byte)0x2f, + (byte)0x53,(byte)0x74,(byte)0x72,(byte)0x69,(byte)0x6e,(byte)0x67, + (byte)0x3b,(byte)0x5b,(byte)0x00,(byte)0x09,(byte)0x69,(byte)0x70, + (byte)0x61,(byte)0x64,(byte)0x64,(byte)0x72,(byte)0x65,(byte)0x73, + (byte)0x73,(byte)0x74,(byte)0x00,(byte)0x02,(byte)0x5b,(byte)0x42, + (byte)0x78,(byte)0x72,(byte)0x00,(byte)0x14,(byte)0x6a,(byte)0x61, + (byte)0x76,(byte)0x61,(byte)0x2e,(byte)0x6e,(byte)0x65,(byte)0x74, + (byte)0x2e,(byte)0x49,(byte)0x6e,(byte)0x65,(byte)0x74,(byte)0x41, + (byte)0x64,(byte)0x64,(byte)0x72,(byte)0x65,(byte)0x73,(byte)0x73, + (byte)0x2d,(byte)0x9b,(byte)0x57,(byte)0xaf,(byte)0x9f,(byte)0xe3, + (byte)0xeb,(byte)0xdb,(byte)0x02,(byte)0x00,(byte)0x03,(byte)0x49, + (byte)0x00,(byte)0x07,(byte)0x61,(byte)0x64,(byte)0x64,(byte)0x72, + (byte)0x65,(byte)0x73,(byte)0x73,(byte)0x49,(byte)0x00,(byte)0x06, + (byte)0x66,(byte)0x61,(byte)0x6d,(byte)0x69,(byte)0x6c,(byte)0x79, + (byte)0x4c,(byte)0x00,(byte)0x08,(byte)0x68,(byte)0x6f,(byte)0x73, + (byte)0x74,(byte)0x4e,(byte)0x61,(byte)0x6d,(byte)0x65,(byte)0x71, + (byte)0x00,(byte)0x7e,(byte)0x00,(byte)0x01,(byte)0x78,(byte)0x70, + (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x02,(byte)0x74,(byte)0x00,(byte)0x09,(byte)0x78, + (byte)0x2e,(byte)0x62,(byte)0x61,(byte)0x72,(byte)0x2e,(byte)0x63, + (byte)0x6f,(byte)0x6d,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x00,(byte)0x70,(byte)0x75,(byte)0x72,(byte)0x00, + (byte)0x02,(byte)0x5b,(byte)0x42,(byte)0xac,(byte)0xf3,(byte)0x17, + (byte)0xf8,(byte)0x06,(byte)0x08,(byte)0x54,(byte)0xe0,(byte)0x02, + (byte)0x00,(byte)0x00,(byte)0x78,(byte)0x70,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x10,(byte)0xfe,(byte)0xc0,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01, + (byte)0x78 + }; + + static byte[] addr3 = { + (byte)0xac,(byte)0xed,(byte)0x00,(byte)0x05,(byte)0x73,(byte)0x72, + (byte)0x00,(byte)0x15,(byte)0x6a,(byte)0x61,(byte)0x76,(byte)0x61, + (byte)0x2e,(byte)0x6e,(byte)0x65,(byte)0x74,(byte)0x2e,(byte)0x49, + (byte)0x6e,(byte)0x65,(byte)0x74,(byte)0x36,(byte)0x41,(byte)0x64, + (byte)0x64,(byte)0x72,(byte)0x65,(byte)0x73,(byte)0x73,(byte)0x5f, + (byte)0x7c,(byte)0x20,(byte)0x81,(byte)0x52,(byte)0x2c,(byte)0x80, + (byte)0x21,(byte)0x03,(byte)0x00,(byte)0x05,(byte)0x49,(byte)0x00, + (byte)0x08,(byte)0x73,(byte)0x63,(byte)0x6f,(byte)0x70,(byte)0x65, + (byte)0x5f,(byte)0x69,(byte)0x64,(byte)0x5a,(byte)0x00,(byte)0x0c, + (byte)0x73,(byte)0x63,(byte)0x6f,(byte)0x70,(byte)0x65,(byte)0x5f, + (byte)0x69,(byte)0x64,(byte)0x5f,(byte)0x73,(byte)0x65,(byte)0x74, + (byte)0x5a,(byte)0x00,(byte)0x10,(byte)0x73,(byte)0x63,(byte)0x6f, + (byte)0x70,(byte)0x65,(byte)0x5f,(byte)0x69,(byte)0x66,(byte)0x6e, + (byte)0x61,(byte)0x6d,(byte)0x65,(byte)0x5f,(byte)0x73,(byte)0x65, + (byte)0x74,(byte)0x4c,(byte)0x00,(byte)0x06,(byte)0x69,(byte)0x66, + (byte)0x6e,(byte)0x61,(byte)0x6d,(byte)0x65,(byte)0x74,(byte)0x00, + (byte)0x12,(byte)0x4c,(byte)0x6a,(byte)0x61,(byte)0x76,(byte)0x61, + (byte)0x2f,(byte)0x6c,(byte)0x61,(byte)0x6e,(byte)0x67,(byte)0x2f, + (byte)0x53,(byte)0x74,(byte)0x72,(byte)0x69,(byte)0x6e,(byte)0x67, + (byte)0x3b,(byte)0x5b,(byte)0x00,(byte)0x09,(byte)0x69,(byte)0x70, + (byte)0x61,(byte)0x64,(byte)0x64,(byte)0x72,(byte)0x65,(byte)0x73, + (byte)0x73,(byte)0x74,(byte)0x00,(byte)0x02,(byte)0x5b,(byte)0x42, + (byte)0x78,(byte)0x72,(byte)0x00,(byte)0x14,(byte)0x6a,(byte)0x61, + (byte)0x76,(byte)0x61,(byte)0x2e,(byte)0x6e,(byte)0x65,(byte)0x74, + (byte)0x2e,(byte)0x49,(byte)0x6e,(byte)0x65,(byte)0x74,(byte)0x41, + (byte)0x64,(byte)0x64,(byte)0x72,(byte)0x65,(byte)0x73,(byte)0x73, + (byte)0x2d,(byte)0x9b,(byte)0x57,(byte)0xaf,(byte)0x9f,(byte)0xe3, + (byte)0xeb,(byte)0xdb,(byte)0x02,(byte)0x00,(byte)0x03,(byte)0x49, + (byte)0x00,(byte)0x07,(byte)0x61,(byte)0x64,(byte)0x64,(byte)0x72, + (byte)0x65,(byte)0x73,(byte)0x73,(byte)0x49,(byte)0x00,(byte)0x06, + (byte)0x66,(byte)0x61,(byte)0x6d,(byte)0x69,(byte)0x6c,(byte)0x79, + (byte)0x4c,(byte)0x00,(byte)0x08,(byte)0x68,(byte)0x6f,(byte)0x73, + (byte)0x74,(byte)0x4e,(byte)0x61,(byte)0x6d,(byte)0x65,(byte)0x71, + (byte)0x00,(byte)0x7e,(byte)0x00,(byte)0x01,(byte)0x78,(byte)0x70, + (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x02,(byte)0x70,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x70,(byte)0x75,(byte)0x72, + (byte)0x00,(byte)0x02,(byte)0x5b,(byte)0x42,(byte)0xac,(byte)0xf3, + (byte)0x17,(byte)0xf8,(byte)0x06,(byte)0x08,(byte)0x54,(byte)0xe0, + (byte)0x02,(byte)0x00,(byte)0x00,(byte)0x78,(byte)0x70,(byte)0x00, + (byte)0x00,(byte)0x00,(byte)0x10,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, + (byte)0x01,(byte)0x78 + }; +} From 3d9f33759d5c2e1d6e6d8438d8ae78416bfac086 Mon Sep 17 00:00:00 2001 From: Masayoshi Okutsu Date: Fri, 19 Jul 2013 12:14:34 +0900 Subject: [PATCH 0042/1294] 8001029: Add new date/time capability Reviewed-by: mchung, hawtin --- jdk/src/share/classes/java/util/TimeZone.java | 140 +++++------------- .../util/TimeZone/SetDefaultSecurityTest.java | 67 +++++++++ 2 files changed, 107 insertions(+), 100 deletions(-) create mode 100644 jdk/test/java/util/TimeZone/SetDefaultSecurityTest.java diff --git a/jdk/src/share/classes/java/util/TimeZone.java b/jdk/src/share/classes/java/util/TimeZone.java index ba4abb91f2c..3075bff157a 100644 --- a/jdk/src/share/classes/java/util/TimeZone.java +++ b/jdk/src/share/classes/java/util/TimeZone.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -39,13 +39,9 @@ package java.util; import java.io.Serializable; -import java.lang.ref.SoftReference; import java.security.AccessController; import java.security.PrivilegedAction; import java.time.ZoneId; -import java.util.concurrent.ConcurrentHashMap; -import sun.misc.JavaAWTAccess; -import sun.misc.SharedSecrets; import sun.security.action.GetPropertyAction; import sun.util.calendar.ZoneInfo; import sun.util.calendar.ZoneInfoFile; @@ -596,11 +592,26 @@ abstract public class TimeZone implements Serializable, Cloneable { private static native String getSystemGMTOffsetID(); /** - * Gets the default TimeZone for this host. - * The source of the default TimeZone - * may vary with implementation. - * @return a default TimeZone. - * @see #setDefault + * Gets the default {@code TimeZone} of the Java virtual machine. If the + * cached default {@code TimeZone} is available, its clone is returned. + * Otherwise, the method takes the following steps to determine the default + * time zone. + * + *

    + *
  • Use the {@code user.timezone} property value as the default + * time zone ID if it's available.
  • + *
  • Detect the platform time zone ID. The source of the + * platform time zone and ID mapping may vary with implementation.
  • + *
  • Use {@code GMT} as the last resort if the given or detected + * time zone ID is unknown.
  • + *
+ * + *

The default {@code TimeZone} created from the ID is cached, + * and its clone is returned. The {@code user.timezone} property + * value is set to the ID upon return. + * + * @return the default {@code TimeZone} + * @see #setDefault(TimeZone) */ public static TimeZone getDefault() { return (TimeZone) getDefaultRef().clone(); @@ -611,14 +622,11 @@ abstract public class TimeZone implements Serializable, Cloneable { * method doesn't create a clone. */ static TimeZone getDefaultRef() { - TimeZone defaultZone = getDefaultInAppContext(); + TimeZone defaultZone = defaultTimeZone; if (defaultZone == null) { - defaultZone = defaultTimeZone; - if (defaultZone == null) { - // Need to initialize the default time zone. - defaultZone = setDefaultZone(); - assert defaultZone != null; - } + // Need to initialize the default time zone. + defaultZone = setDefaultZone(); + assert defaultZone != null; } // Don't clone here. return defaultZone; @@ -676,95 +684,27 @@ abstract public class TimeZone implements Serializable, Cloneable { return tz; } - private static boolean hasPermission() { - boolean hasPermission = true; - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - sm.checkPermission(new PropertyPermission - ("user.timezone", "write")); - } catch (SecurityException e) { - hasPermission = false; - } - } - return hasPermission; - } - /** - * Sets the TimeZone that is - * returned by the getDefault method. If zone - * is null, reset the default to the value it had originally when the - * VM first started. - * @param zone the new default time zone + * Sets the {@code TimeZone} that is returned by the {@code getDefault} + * method. {@code zone} is cached. If {@code zone} is null, the cached + * default {@code TimeZone} is cleared. This method doesn't change the value + * of the {@code user.timezone} property. + * + * @param zone the new default {@code TimeZone}, or null + * @throws SecurityException if the security manager's {@code checkPermission} + * denies {@code PropertyPermission("user.timezone", + * "write")} * @see #getDefault + * @see PropertyPermission */ public static void setDefault(TimeZone zone) { - if (hasPermission()) { - synchronized (TimeZone.class) { - defaultTimeZone = zone; - setDefaultInAppContext(null); - } - } else { - setDefaultInAppContext(zone); - } - } - - /** - * Returns the default TimeZone in an AppContext if any AppContext - * has ever used. null is returned if any AppContext hasn't been - * used or if the AppContext doesn't have the default TimeZone. - * - * Note that javaAWTAccess may be null if sun.awt.AppContext class hasn't - * been loaded. If so, it implies that AWTSecurityManager is not our - * SecurityManager and we can use a local static variable. - * This works around a build time issue. - */ - private static TimeZone getDefaultInAppContext() { - // JavaAWTAccess provides access implementation-private methods without using reflection. - JavaAWTAccess javaAWTAccess = SharedSecrets.getJavaAWTAccess(); - - if (javaAWTAccess == null) { - return mainAppContextDefault; - } else { - if (!javaAWTAccess.isDisposed()) { - TimeZone tz = (TimeZone) - javaAWTAccess.get(TimeZone.class); - if (tz == null && javaAWTAccess.isMainAppContext()) { - return mainAppContextDefault; - } else { - return tz; - } - } - } - return null; - } - - /** - * Sets the default TimeZone in the AppContext to the given - * tz. null is handled special: do nothing if any AppContext - * hasn't been used, remove the default TimeZone in the - * AppContext otherwise. - * - * Note that javaAWTAccess may be null if sun.awt.AppContext class hasn't - * been loaded. If so, it implies that AWTSecurityManager is not our - * SecurityManager and we can use a local static variable. - * This works around a build time issue. - */ - private static void setDefaultInAppContext(TimeZone tz) { - // JavaAWTAccess provides access implementation-private methods without using reflection. - JavaAWTAccess javaAWTAccess = SharedSecrets.getJavaAWTAccess(); - - if (javaAWTAccess == null) { - mainAppContextDefault = tz; - } else { - if (!javaAWTAccess.isDisposed()) { - javaAWTAccess.put(TimeZone.class, tz); - if (javaAWTAccess.isMainAppContext()) { - mainAppContextDefault = null; - } - } + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new PropertyPermission + ("user.timezone", "write")); } + defaultTimeZone = zone; } /** diff --git a/jdk/test/java/util/TimeZone/SetDefaultSecurityTest.java b/jdk/test/java/util/TimeZone/SetDefaultSecurityTest.java new file mode 100644 index 00000000000..e749ffe9420 --- /dev/null +++ b/jdk/test/java/util/TimeZone/SetDefaultSecurityTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 8001029 + * @summary Make sure that TimeZone.setDefault throws a SecurityException if the + * security manager doesn't permit. + * @run main/othervm SetDefaultSecurityTest + */ + +import java.util.SimpleTimeZone; +import java.util.TimeZone; + +public class SetDefaultSecurityTest { + static final TimeZone NOWHERE = new SimpleTimeZone(Integer.MAX_VALUE, "Nowhere"); + + public static void main(String[] args) { + TimeZone defaultZone = TimeZone.getDefault(); + + // Make sure that TimeZone.setDefault works for trusted code + TimeZone.setDefault(NOWHERE); + if (!NOWHERE.equals(TimeZone.getDefault())) { + new RuntimeException("TimeZone.setDefault doesn't work for trusted code."); + } + // Restore defaultZone + TimeZone.setDefault(defaultZone); + if (!defaultZone.equals(TimeZone.getDefault())) { + new RuntimeException("TimeZone.setDefault doesn't restore defaultZone."); + } + + // Install a SecurityManager. + System.setSecurityManager(new SecurityManager()); + try { + TimeZone.setDefault(NOWHERE); + throw new RuntimeException("TimeZone.setDefault doesn't throw a SecurityException."); + } catch (SecurityException se) { + // OK + } + TimeZone tz = TimeZone.getDefault(); + if (!defaultZone.equals(tz)) { + throw new RuntimeException("Default TimeZone changed: " + tz); + } + } +} From 20511649934fed3e8094b69b5375107b965c62a9 Mon Sep 17 00:00:00 2001 From: Shanliang Jiang Date: Fri, 19 Jul 2013 13:35:01 +0200 Subject: [PATCH 0043/1294] 8014534: Better profiling support Validation of parameters Reviewed-by: sspitsyn, skoivu, mchung --- .../com/sun/demo/jvmti/hprof/Tracker.java | 26 ++++++++++++++++-- jdk/src/share/demo/jvmti/hprof/hprof_class.c | 14 ++++++++-- jdk/src/share/demo/jvmti/hprof/hprof_event.c | 27 ++++++++++++++----- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/jdk/src/share/classes/com/sun/demo/jvmti/hprof/Tracker.java b/jdk/src/share/classes/com/sun/demo/jvmti/hprof/Tracker.java index f2e33d72454..96950870be2 100644 --- a/jdk/src/share/classes/com/sun/demo/jvmti/hprof/Tracker.java +++ b/jdk/src/share/classes/com/sun/demo/jvmti/hprof/Tracker.java @@ -53,7 +53,10 @@ public class Tracker { public static void ObjectInit(Object obj) { - if ( engaged != 0 ) { + if ( engaged != 0) { + if (obj == null) { + throw new IllegalArgumentException("Null object."); + } nativeObjectInit(Thread.currentThread(), obj); } } @@ -66,7 +69,10 @@ public class Tracker { public static void NewArray(Object obj) { - if ( engaged != 0 ) { + if ( engaged != 0) { + if (obj == null) { + throw new IllegalArgumentException("Null object."); + } nativeNewArray(Thread.currentThread(), obj); } } @@ -82,6 +88,14 @@ public class Tracker { public static void CallSite(int cnum, int mnum) { if ( engaged != 0 ) { + if (cnum < 0) { + throw new IllegalArgumentException("Negative class index"); + } + + if (mnum < 0) { + throw new IllegalArgumentException("Negative method index"); + } + nativeCallSite(Thread.currentThread(), cnum, mnum); } } @@ -95,6 +109,14 @@ public class Tracker { public static void ReturnSite(int cnum, int mnum) { if ( engaged != 0 ) { + if (cnum < 0) { + throw new IllegalArgumentException("Negative class index"); + } + + if (mnum < 0) { + throw new IllegalArgumentException("Negative method index"); + } + nativeReturnSite(Thread.currentThread(), cnum, mnum); } } diff --git a/jdk/src/share/demo/jvmti/hprof/hprof_class.c b/jdk/src/share/demo/jvmti/hprof/hprof_class.c index f25f53ad934..fb16784476f 100644 --- a/jdk/src/share/demo/jvmti/hprof/hprof_class.c +++ b/jdk/src/share/demo/jvmti/hprof/hprof_class.c @@ -527,7 +527,12 @@ class_get_methodID(JNIEnv *env, ClassIndex index, MethodIndex mnum) jmethodID method; info = get_info(index); - HPROF_ASSERT(mnum < info->method_count); + if (mnum >= info->method_count) { + jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); + (*env)->ThrowNew(env, newExcCls, "Illegal mnum"); + + return NULL; + } method = info->method[mnum].method_id; if ( method == NULL ) { char * name; @@ -535,7 +540,12 @@ class_get_methodID(JNIEnv *env, ClassIndex index, MethodIndex mnum) jclass clazz; name = (char *)string_get(info->method[mnum].name_index); - HPROF_ASSERT(name!=NULL); + if (name==NULL) { + jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); + (*env)->ThrowNew(env, newExcCls, "Name not found"); + + return NULL; + } sig = (char *)string_get(info->method[mnum].sig_index); HPROF_ASSERT(sig!=NULL); clazz = class_get_class(env, index); diff --git a/jdk/src/share/demo/jvmti/hprof/hprof_event.c b/jdk/src/share/demo/jvmti/hprof/hprof_event.c index 15dd4ddaa76..7892457d3f8 100644 --- a/jdk/src/share/demo/jvmti/hprof/hprof_event.c +++ b/jdk/src/share/demo/jvmti/hprof/hprof_event.c @@ -195,7 +195,12 @@ event_call(JNIEnv *env, jthread thread, ClassIndex cnum, MethodIndex mnum) HPROF_ASSERT(env!=NULL); HPROF_ASSERT(thread!=NULL); - HPROF_ASSERT(cnum!=0 && cnum!=gdata->tracker_cnum); + if (cnum == 0 || cnum == gdata->tracker_cnum) { + jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); + (*env)->ThrowNew(env, newExcCls, "Illegal cnum."); + + return; + } /* Prevent recursion into any BCI function for this thread (pstatus). */ if ( tls_get_tracker_status(env, thread, JNI_FALSE, @@ -204,8 +209,10 @@ event_call(JNIEnv *env, jthread thread, ClassIndex cnum, MethodIndex mnum) (*pstatus) = 1; method = class_get_methodID(env, cnum, mnum); - HPROF_ASSERT(method!=NULL); - tls_push_method(tls_index, method); + if (method != NULL) { + tls_push_method(tls_index, method); + } + (*pstatus) = 0; } } @@ -248,7 +255,13 @@ event_return(JNIEnv *env, jthread thread, ClassIndex cnum, MethodIndex mnum) HPROF_ASSERT(env!=NULL); HPROF_ASSERT(thread!=NULL); - HPROF_ASSERT(cnum!=0 && cnum!=gdata->tracker_cnum); + + if (cnum == 0 || cnum == gdata->tracker_cnum) { + jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); + (*env)->ThrowNew(env, newExcCls, "Illegal cnum."); + + return; + } /* Prevent recursion into any BCI function for this thread (pstatus). */ if ( tls_get_tracker_status(env, thread, JNI_FALSE, @@ -257,8 +270,10 @@ event_return(JNIEnv *env, jthread thread, ClassIndex cnum, MethodIndex mnum) (*pstatus) = 1; method = class_get_methodID(env, cnum, mnum); - HPROF_ASSERT(method!=NULL); - tls_pop_method(tls_index, thread, method); + if (method != NULL) { + tls_pop_method(tls_index, thread, method); + } + (*pstatus) = 0; } } From bd41c425d2a88e9e78897a43a5e3ea811d453ba4 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Mon, 22 Jul 2013 19:41:07 -0700 Subject: [PATCH 0044/1294] 8017196: Ensure Proxies are handled appropriately Reviewed-by: dfuchs, jrose, jdn, ahgross, chegar --- .../java/lang/invoke/MethodHandles.java | 15 ++++-- .../classes/java/lang/reflect/Proxy.java | 38 +++++++++++---- .../classes/sun/reflect/misc/ReflectUtil.java | 48 +++++++++++++++++++ 3 files changed, 88 insertions(+), 13 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index 3bf24bc8503..1c9a068ed92 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -433,7 +433,7 @@ public class MethodHandles { Lookup(Class lookupClass) { this(lookupClass, ALL_MODES); // make sure we haven't accidentally picked up a privileged class: - checkUnprivilegedlookupClass(lookupClass); + checkUnprivilegedlookupClass(lookupClass, ALL_MODES); } private Lookup(Class lookupClass, int allowedModes) { @@ -487,7 +487,7 @@ public class MethodHandles { // No permissions. newModes = 0; } - checkUnprivilegedlookupClass(requestedLookupClass); + checkUnprivilegedlookupClass(requestedLookupClass, newModes); return new Lookup(requestedLookupClass, newModes); } @@ -503,10 +503,19 @@ public class MethodHandles { /** Package-private version of lookup which is trusted. */ static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED); - private static void checkUnprivilegedlookupClass(Class lookupClass) { + private static void checkUnprivilegedlookupClass(Class lookupClass, int allowedModes) { String name = lookupClass.getName(); if (name.startsWith("java.lang.invoke.")) throw newIllegalArgumentException("illegal lookupClass: "+lookupClass); + + // For caller-sensitive MethodHandles.lookup() + // disallow lookup more restricted packages + if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) { + if (name.startsWith("java.") || + (name.startsWith("sun.") && !name.startsWith("sun.invoke."))) { + throw newIllegalArgumentException("illegal lookupClass: " + lookupClass); + } + } } /** diff --git a/jdk/src/share/classes/java/lang/reflect/Proxy.java b/jdk/src/share/classes/java/lang/reflect/Proxy.java index dd5c2ad4336..f2e4eda4e62 100644 --- a/jdk/src/share/classes/java/lang/reflect/Proxy.java +++ b/jdk/src/share/classes/java/lang/reflect/Proxy.java @@ -347,11 +347,11 @@ public class Proxy implements java.io.Serializable { * s.checkPermission} with * {@code RuntimePermission("getClassLoader")} permission * denies access. - *

  • the caller's class loader is not the same as or an - * ancestor of the class loader for the current class and + *
  • for each proxy interface, {@code intf}, + * the caller's class loader is not the same as or an + * ancestor of the class loader for {@code intf} and * invocation of {@link SecurityManager#checkPackageAccess - * s.checkPackageAccess()} denies access to any one of the - * given proxy interfaces.
  • + * s.checkPackageAccess()} denies access to {@code intf}. * * @throws NullPointerException if the {@code interfaces} array @@ -680,11 +680,11 @@ public class Proxy implements java.io.Serializable { * s.checkPermission} with * {@code RuntimePermission("getClassLoader")} permission * denies access; - *
  • the caller's class loader is not the same as or an - * ancestor of the class loader for the current class and + *
  • for each proxy interface, {@code intf}, + * the caller's class loader is not the same as or an + * ancestor of the class loader for {@code intf} and * invocation of {@link SecurityManager#checkPackageAccess - * s.checkPackageAccess()} denies access to any one of the - * given proxy interfaces.
  • + * s.checkPackageAccess()} denies access to {@code intf}; *
  • any of the given proxy interfaces is non-public and the * caller class is not in the same {@linkplain Package runtime package} * as the non-public interface and the invocation of @@ -795,7 +795,14 @@ public class Proxy implements java.io.Serializable { * @return the invocation handler for the proxy instance * @throws IllegalArgumentException if the argument is not a * proxy instance + * @throws SecurityException if a security manager, s, is present + * and the caller's class loader is not the same as or an + * ancestor of the class loader for the invocation handler + * and invocation of {@link SecurityManager#checkPackageAccess + * s.checkPackageAccess()} denies access to the invocation + * handler's class. */ + @CallerSensitive public static InvocationHandler getInvocationHandler(Object proxy) throws IllegalArgumentException { @@ -806,8 +813,19 @@ public class Proxy implements java.io.Serializable { throw new IllegalArgumentException("not a proxy instance"); } - Proxy p = (Proxy) proxy; - return p.h; + final Proxy p = (Proxy) proxy; + final InvocationHandler ih = p.h; + if (System.getSecurityManager() != null) { + Class ihClass = ih.getClass(); + Class caller = Reflection.getCallerClass(); + if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), + ihClass.getClassLoader())) + { + ReflectUtil.checkPackageAccess(ihClass); + } + } + + return ih; } private static native Class defineClass0(ClassLoader loader, String name, diff --git a/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java b/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java index efd85fca9cb..1f871e8de02 100644 --- a/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java +++ b/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java @@ -26,8 +26,10 @@ package sun.reflect.misc; +import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; +import java.util.Arrays; import sun.reflect.Reflection; public final class ReflectUtil { @@ -250,4 +252,50 @@ public final class ReflectUtil { String pkg = (i != -1) ? name.substring(0, i) : ""; return Proxy.isProxyClass(cls) && !pkg.equals(PROXY_PACKAGE); } + + /** + * Check if the given method is a method declared in the proxy interface + * implemented by the given proxy instance. + * + * @param proxy a proxy instance + * @param method an interface method dispatched to a InvocationHandler + * + * @throws IllegalArgumentException if the given proxy or method is invalid. + */ + public static void checkProxyMethod(Object proxy, Method method) { + // check if it is a valid proxy instance + if (proxy == null || !Proxy.isProxyClass(proxy.getClass())) { + throw new IllegalArgumentException("Not a Proxy instance"); +} + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalArgumentException("Can't handle static method"); + } + + Class c = method.getDeclaringClass(); + if (c == Object.class) { + String name = method.getName(); + if (name.equals("hashCode") || name.equals("equals") || name.equals("toString")) { + return; + } + } + + if (isSuperInterface(proxy.getClass(), c)) { + return; + } + + // disallow any method not declared in one of the proxy intefaces + throw new IllegalArgumentException("Can't handle: " + method); + } + + private static boolean isSuperInterface(Class c, Class intf) { + for (Class i : c.getInterfaces()) { + if (i == intf) { + return true; + } + if (isSuperInterface(i, intf)) { + return true; + } + } + return false; + } } From ff1d4ae90507ecf250df4852ffab15b037670f13 Mon Sep 17 00:00:00 2001 From: Sergey Gabdurakhmanov Date: Tue, 23 Jul 2013 09:30:58 +0400 Subject: [PATCH 0045/1294] 8016357: Update hotspot diagnostic class Add security check to HotSpotDiagnostic.dumpHeap Reviewed-by: fparain, sla, ahgross --- jdk/make/java/management/mapfile-vers | 2 +- jdk/makefiles/mapfiles/libmanagement/mapfile-vers | 2 +- .../com/sun/management/HotSpotDiagnosticMXBean.java | 5 +++++ .../classes/sun/management/HotSpotDiagnostic.java | 12 +++++++++++- .../share/native/sun/management/HotSpotDiagnostic.c | 2 +- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/jdk/make/java/management/mapfile-vers b/jdk/make/java/management/mapfile-vers index 63c4fbf03cc..0ea2ab4eb06 100644 --- a/jdk/make/java/management/mapfile-vers +++ b/jdk/make/java/management/mapfile-vers @@ -57,7 +57,7 @@ SUNWprivate_1.1 { Java_sun_management_GcInfoBuilder_fillGcAttributeInfo; Java_sun_management_GcInfoBuilder_getLastGcInfo0; Java_sun_management_GcInfoBuilder_getNumGcExtAttributes; - Java_sun_management_HotSpotDiagnostic_dumpHeap; + Java_sun_management_HotSpotDiagnostic_dumpHeap0; Java_sun_management_HotspotThread_getInternalThreadCount; Java_sun_management_HotspotThread_getInternalThreadTimes0; Java_sun_management_MemoryImpl_getMemoryManagers0; diff --git a/jdk/makefiles/mapfiles/libmanagement/mapfile-vers b/jdk/makefiles/mapfiles/libmanagement/mapfile-vers index b934fe8b748..724f7bb7100 100644 --- a/jdk/makefiles/mapfiles/libmanagement/mapfile-vers +++ b/jdk/makefiles/mapfiles/libmanagement/mapfile-vers @@ -57,7 +57,7 @@ SUNWprivate_1.1 { Java_sun_management_GcInfoBuilder_fillGcAttributeInfo; Java_sun_management_GcInfoBuilder_getLastGcInfo0; Java_sun_management_GcInfoBuilder_getNumGcExtAttributes; - Java_sun_management_HotSpotDiagnostic_dumpHeap; + Java_sun_management_HotSpotDiagnostic_dumpHeap0; Java_sun_management_HotspotThread_getInternalThreadCount; Java_sun_management_HotspotThread_getInternalThreadTimes0; Java_sun_management_MemoryImpl_getMemoryManagers0; diff --git a/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java b/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java index 2fe8835259f..eaf5447b430 100644 --- a/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java +++ b/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java @@ -66,6 +66,11 @@ public interface HotSpotDiagnosticMXBean extends PlatformManagedObject { * cannot be created, opened, or written to. * @throws UnsupportedOperationException if this operation is not supported. * @throws NullPointerException if outputFile is null. + * @throws SecurityException + * If a security manager exists and its {@link + * java.lang.SecurityManager#checkWrite(java.lang.String)} + * method denies write access to the named file + * or the caller does not have ManagmentPermission("control"). */ public void dumpHeap(String outputFile, boolean live) throws java.io.IOException; diff --git a/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java b/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java index a6d3be1640f..7a4bd99f274 100644 --- a/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java +++ b/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java @@ -40,7 +40,17 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean { public HotSpotDiagnostic() { } - public native void dumpHeap(String outputFile, boolean live) throws IOException; + public void dumpHeap(String outputFile, boolean live) throws IOException { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkWrite(outputFile); + Util.checkControlAccess(); + } + + dumpHeap0(outputFile, live); + } + + private native void dumpHeap0(String outputFile, boolean live) throws IOException; public List getDiagnosticOptions() { List allFlags = Flag.getAllFlags(); diff --git a/jdk/src/share/native/sun/management/HotSpotDiagnostic.c b/jdk/src/share/native/sun/management/HotSpotDiagnostic.c index 8d48b201109..cfa9e9ab8fa 100644 --- a/jdk/src/share/native/sun/management/HotSpotDiagnostic.c +++ b/jdk/src/share/native/sun/management/HotSpotDiagnostic.c @@ -29,7 +29,7 @@ #include "sun_management_HotSpotDiagnostic.h" JNIEXPORT void JNICALL -Java_sun_management_HotSpotDiagnostic_dumpHeap +Java_sun_management_HotSpotDiagnostic_dumpHeap0 (JNIEnv *env, jobject dummy, jstring outputfile, jboolean live) { jmm_interface->DumpHeap0(env, outputfile, live); From 2fac55ced5c5e37112d3d2ab6ed0f7f88a725838 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 17 Jul 2013 18:46:00 +0800 Subject: [PATCH 0046/1294] 8020696: Merge problem for KdcComm.java Reviewed-by: chegar --- jdk/src/share/classes/sun/security/krb5/KdcComm.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/sun/security/krb5/KdcComm.java b/jdk/src/share/classes/sun/security/krb5/KdcComm.java index ae3b0f098b7..3d50f9569d3 100644 --- a/jdk/src/share/classes/sun/security/krb5/KdcComm.java +++ b/jdk/src/share/classes/sun/security/krb5/KdcComm.java @@ -227,15 +227,15 @@ public final class KdcComm { try { ibuf = sendIfPossible(obuf, tempKdc.next(), useTCP); } catch(Exception first) { + boolean ok = false; while(tempKdc.hasNext()) { try { ibuf = sendIfPossible(obuf, tempKdc.next(), useTCP); - if (ibuf != null) { - return ibuf; - } + ok = true; + break; } catch(Exception ignore) {} } - throw first; + if (!ok) throw first; } if (ibuf == null) { throw new IOException("Cannot get a KDC reply"); From 8b314fcc50688a3ae85c2caf68105e2759496c20 Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Wed, 17 Jul 2013 09:31:39 -0700 Subject: [PATCH 0047/1294] 8017298: Better XML support Reviewed-by: alanb, dfuchs, mullan, lancea --- .../impl/XMLDocumentFragmentScannerImpl.java | 11 +- .../internal/impl/XMLEntityManager.java | 16 +- .../xerces/internal/impl/XMLScanner.java | 33 ++- .../internal/impl/msg/XMLMessages.properties | 1 + .../impl/xs/models/CMNodeFactory.java | 23 +- .../xs/traversers/XSAttributeChecker.java | 3 +- .../impl/xs/traversers/XSDHandler.java | 6 +- .../internal/jaxp/DocumentBuilderImpl.java | 4 +- .../xerces/internal/jaxp/SAXParserImpl.java | 6 +- .../validation/StreamValidatorHelper.java | 4 +- .../jaxp/validation/ValidatorHandlerImpl.java | 4 +- .../jaxp/validation/XMLSchemaFactory.java | 14 +- .../XMLSchemaValidatorComponentManager.java | 10 +- .../internal/parsers/AbstractSAXParser.java | 4 +- .../parsers/SecurityConfiguration.java | 6 +- .../xerces/internal/util/SecurityManager.java | 226 ------------------ .../xerces/internal/util/SymbolTable.java | 4 +- .../internal/utils/XMLSecurityManager.java | 147 ++++++++++++ .../internal/xinclude/XIncludeHandler.java | 10 +- .../com/sun/xml/internal/stream/Entity.java | 2 +- 20 files changed, 247 insertions(+), 287 deletions(-) delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java create mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java index 82c009bbdd3..d76a7e22a7e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java @@ -50,9 +50,9 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.xml.internal.stream.Entity; import javax.xml.XMLConstants; @@ -382,7 +382,7 @@ public class XMLDocumentFragmentScannerImpl protected boolean foundBuiltInRefs = false; - protected SecurityManager fSecurityManager = null; + protected XMLSecurityManager fSecurityManager = null; //skip element algorithm static final short MAX_DEPTH_LIMIT = 5 ; @@ -569,8 +569,10 @@ public class XMLDocumentFragmentScannerImpl // xerces features fReportCdataEvent = componentManager.getFeature(Constants.STAX_REPORT_CDATA_EVENT, true); - fSecurityManager = (SecurityManager)componentManager.getProperty(Constants.SECURITY_MANAGER, null); - fElementAttributeLimit = (fSecurityManager != null)?fSecurityManager.getElementAttrLimit():0; + fSecurityManager = (XMLSecurityManager)componentManager.getProperty(Constants.SECURITY_MANAGER, null); + fElementAttributeLimit = (fSecurityManager != null)? + fSecurityManager.getLimit(XMLSecurityManager.Limit.ELEMENT_ATTRIBUTE_LIMIT):0; + fNotifyBuiltInRefs = componentManager.getFeature(NOTIFY_BUILTIN_REFS, false); @@ -951,6 +953,7 @@ public class XMLDocumentFragmentScannerImpl // scan decl super.scanXMLDeclOrTextDecl(scanningTextDecl, fStrings); + fMarkupDepth--; // pseudo-attribute values diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java index ee6ff0a6b2e..5ecd1215a82 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java @@ -28,9 +28,9 @@ import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.util.*; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.URI; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.XNIException; @@ -324,7 +324,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { // stores defaults for entity expansion limit if it has // been set on the configuration. - protected SecurityManager fSecurityManager = null; + protected XMLSecurityManager fSecurityManager = null; /** * True if the document entity is standalone. This should really @@ -1482,7 +1482,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { fEntityResolver = (XMLEntityResolver)componentManager.getProperty(ENTITY_RESOLVER, null); fStaxEntityResolver = (StaxEntityResolverWrapper)componentManager.getProperty(STAX_ENTITY_RESOLVER, null); fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER, null); - fSecurityManager = (SecurityManager)componentManager.getProperty(SECURITY_MANAGER, null); + fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER, null); // JAXP 1.5 feature fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT); @@ -1499,7 +1499,9 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { // a class acting as a component manager but not // implementing that interface for whatever reason. public void reset() { - fEntityExpansionLimit = (fSecurityManager != null)?fSecurityManager.getEntityExpansionLimit():0; + fEntityExpansionLimit = (fSecurityManager != null)? + fSecurityManager.getLimit(XMLSecurityManager.Limit.ENTITY_EXPANSION_LIMIT):0; + // initialize state fStandalone = false; @@ -1635,8 +1637,10 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { } if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() && propertyId.endsWith(Constants.SECURITY_MANAGER_PROPERTY)) { - fSecurityManager = (SecurityManager)value; - fEntityExpansionLimit = (fSecurityManager != null)?fSecurityManager.getEntityExpansionLimit():0; + fSecurityManager = (XMLSecurityManager)value; + fEntityExpansionLimit = (fSecurityManager != null)? + fSecurityManager.getLimit(XMLSecurityManager.Limit.ENTITY_EXPANSION_LIMIT):0; + } } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java index 0c66aa236fa..9fc489b3e02 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java @@ -499,7 +499,7 @@ public abstract class XMLScanner reportFatalError("SDDeclInvalid", new Object[] {standalone}); } } else { - reportFatalError("EncodingDeclRequired", null); + reportFatalError("SDDeclNameInvalid", null); } break; } @@ -564,7 +564,7 @@ public abstract class XMLScanner XMLString value) throws IOException, XNIException { - String name = fEntityScanner.scanName(); + String name = scanPseudoAttributeName(); // XMLEntityManager.print(fEntityManager.getCurrentEntity()); if (name == null) { @@ -616,6 +616,35 @@ public abstract class XMLScanner } // scanPseudoAttribute(XMLString):String + /** + * Scans the name of a pseudo attribute. The only legal names + * in XML 1.0/1.1 documents are 'version', 'encoding' and 'standalone'. + * + * @return the name of the pseudo attribute or null + * if a legal pseudo attribute name could not be scanned. + */ + private String scanPseudoAttributeName() throws IOException, XNIException { + final int ch = fEntityScanner.peekChar(); + switch (ch) { + case 'v': + if (fEntityScanner.skipString(fVersionSymbol)) { + return fVersionSymbol; + } + break; + case 'e': + if (fEntityScanner.skipString(fEncodingSymbol)) { + return fEncodingSymbol; + } + break; + case 's': + if (fEntityScanner.skipString(fStandaloneSymbol)) { + return fStandaloneSymbol; + } + break; + } + return null; + } // scanPseudoAttributeName() + /** * Scans a processing instruction. *

    diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties index 1a5d62af9bb..d0db58ba98d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties @@ -44,6 +44,7 @@ # 2.9 Standalone Document Declaration SDDeclInvalid = The standalone document declaration value must be \"yes\" or \"no\", not \"{0}\". + SDDeclNameInvalid = The standalone name in XML declaration may be misspelled. # 2.12 Language Identification XMLLangInvalid = The xml:lang attribute value \"{0}\" is an invalid language identifier. # 3. Logical Structures diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java index d1831661f88..e3c24dc8938 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java @@ -21,13 +21,13 @@ package com.sun.org.apache.xerces.internal.impl.xs.models; -import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; -import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; -import com.sun.org.apache.xerces.internal.util.SecurityManager ; -import com.sun.org.apache.xerces.internal.impl.dtd.models.CMNode; -import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; -import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; +import com.sun.org.apache.xerces.internal.impl.dtd.models.CMNode; +import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; +import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; +import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; /** * @@ -68,7 +68,7 @@ public class CMNodeFactory { // stores defaults for different security holes (maxOccurLimit in current context) if it has // been set on the configuration. - private SecurityManager fSecurityManager = null; + private XMLSecurityManager fSecurityManager = null; /** default constructor */ public CMNodeFactory() { @@ -77,10 +77,10 @@ public class CMNodeFactory { public void reset(XMLComponentManager componentManager){ fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER); try { - fSecurityManager = (SecurityManager)componentManager.getProperty(SECURITY_MANAGER); + fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER); //we are setting the limit of number of nodes to 3times the maxOccur value.. if(fSecurityManager != null){ - maxNodeLimit = fSecurityManager.getMaxOccurNodeLimit() * MULTIPLICITY ; + maxNodeLimit = fSecurityManager.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT) * MULTIPLICITY ; } } catch (XMLConfigurationException e) { @@ -150,8 +150,9 @@ public class CMNodeFactory { if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() && propertyId.endsWith(Constants.SECURITY_MANAGER_PROPERTY)) { - fSecurityManager = (SecurityManager)value; - maxNodeLimit = (fSecurityManager != null) ? fSecurityManager.getMaxOccurNodeLimit() * MULTIPLICITY : 0 ; + fSecurityManager = (XMLSecurityManager)value; + maxNodeLimit = (fSecurityManager != null) ? + fSecurityManager.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT) * MULTIPLICITY : 0 ; return; } if (suffixLength == Constants.ERROR_REPORTER_PROPERTY.length() && diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java index 3744692c33d..34eaa8457bc 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java @@ -40,6 +40,7 @@ import com.sun.org.apache.xerces.internal.util.DOMUtil; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XMLSymbols; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.xs.XSConstants; import java.util.HashMap; @@ -1194,7 +1195,7 @@ public class XSAttributeChecker { if (!optimize) { //Revisit :: IMO this is not right place to check // maxOccurNodeLimit. - int maxOccurNodeLimit = fSchemaHandler.fSecureProcessing.getMaxOccurNodeLimit(); + int maxOccurNodeLimit = fSchemaHandler.fSecureProcessing.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT); if (max > maxOccurNodeLimit) { reportSchemaFatalError("maxOccurLimit", new Object[] {new Integer(maxOccurNodeLimit)}, element); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java index eba1ac0de20..1bfe85c841b 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java @@ -70,7 +70,6 @@ import com.sun.org.apache.xerces.internal.util.DOMUtil; import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler; import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.SAXInputSource; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.StAXInputSource; import com.sun.org.apache.xerces.internal.util.StAXLocationWrapper; import com.sun.org.apache.xerces.internal.util.SymbolHash; @@ -78,6 +77,7 @@ import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; @@ -257,7 +257,7 @@ public class XSDHandler { * *

    Protected to allow access by any traverser.

    */ - protected SecurityManager fSecureProcessing = null; + protected XMLSecurityManager fSecureProcessing = null; private String fAccessExternalSchema; @@ -3501,7 +3501,7 @@ public class XSDHandler { fSecureProcessing = null; if( componentManager!=null ) { - fSecureProcessing = (SecurityManager) componentManager.getProperty(SECURE_PROCESSING, null); + fSecureProcessing = (XMLSecurityManager) componentManager.getProperty(SECURE_PROCESSING, null); } //set entity resolver diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java index 520bc87ea6a..bdb75becd22 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java @@ -36,7 +36,7 @@ import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator; import com.sun.org.apache.xerces.internal.jaxp.validation.XSGrammarPoolContainer; import com.sun.org.apache.xerces.internal.parsers.DOMParser; -import com.sun.org.apache.xerces.internal.util.SecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; @@ -162,7 +162,7 @@ public class DocumentBuilderImpl extends DocumentBuilder // If the secure processing feature is on set a security manager. if (secureProcessing) { - domParser.setProperty(SECURITY_MANAGER, new SecurityManager()); + domParser.setProperty(SECURITY_MANAGER, new XMLSecurityManager()); /** * By default, secure processing is set, no external access is allowed. diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java index a57c1543d84..6dad379efba 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java @@ -34,8 +34,8 @@ import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator; import com.sun.org.apache.xerces.internal.jaxp.validation.XSGrammarPoolContainer; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.Status; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; @@ -151,7 +151,7 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser // If the secure processing feature is on set a security manager. if (secureProcessing) { - xmlReader.setProperty0(SECURITY_MANAGER, new SecurityManager()); + xmlReader.setProperty0(SECURITY_MANAGER, new XMLSecurityManager()); /** * By default, secure processing is set, no external access is allowed. * However, we need to check if it is actively set on the factory since we @@ -413,7 +413,7 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser } if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { try { - setProperty(SECURITY_MANAGER, value ? new SecurityManager() : null); + setProperty(SECURITY_MANAGER, value ? new XMLSecurityManager() : null); } catch (SAXNotRecognizedException exc) { // If the property is not supported diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java index 95fe7d8d8ec..c560e1e8f54 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java @@ -24,7 +24,7 @@ import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.parsers.XML11Configuration; -import com.sun.org.apache.xerces.internal.util.SecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; @@ -170,7 +170,7 @@ final class StreamValidatorHelper implements ValidatorHelper { private XMLParserConfiguration initialize() { XML11Configuration config = new XML11Configuration(); if (fComponentManager.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) { - config.setProperty(SECURITY_MANAGER, new SecurityManager()); + config.setProperty(SECURITY_MANAGER, new XMLSecurityManager()); } config.setProperty(ENTITY_RESOLVER, fComponentManager.getProperty(ENTITY_RESOLVER)); config.setProperty(ERROR_HANDLER, fComponentManager.getProperty(ERROR_HANDLER)); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java index 2c3a9842c5e..c4de85d32c7 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java @@ -49,10 +49,10 @@ import com.sun.org.apache.xerces.internal.util.SAXLocatorWrapper; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.URI; import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; import com.sun.org.apache.xerces.internal.util.XMLSymbols; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.QName; @@ -679,7 +679,7 @@ final class ValidatorHandlerImpl extends ValidatorHandler implements reader = spf.newSAXParser().getXMLReader(); // If this is a Xerces SAX parser, set the security manager if there is one if (reader instanceof com.sun.org.apache.xerces.internal.parsers.SAXParser) { - SecurityManager securityManager = (SecurityManager) fComponentManager.getProperty(SECURITY_MANAGER); + XMLSecurityManager securityManager = (XMLSecurityManager) fComponentManager.getProperty(SECURITY_MANAGER); if (securityManager != null) { try { reader.setProperty(SECURITY_MANAGER, securityManager); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java index 763fcdbd29f..1c004dcf4e1 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java @@ -41,11 +41,11 @@ import com.sun.org.apache.xerces.internal.util.DOMInputSource; import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.SAXInputSource; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.StAXInputSource; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; @@ -79,7 +79,7 @@ public final class XMLSchemaFactory extends SchemaFactory { private static final String XMLGRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; - /** Property identifier: SecurityManager. */ + /** Property identifier: XMLSecurityManager. */ private static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; @@ -108,8 +108,8 @@ public final class XMLSchemaFactory extends SchemaFactory { /** The ErrorHandlerWrapper */ private ErrorHandlerWrapper fErrorHandlerWrapper; - /** The SecurityManager. */ - private SecurityManager fSecurityManager; + /** The XMLSecurityManager. */ + private XMLSecurityManager fSecurityManager; /** The container for the real grammar pool. */ private XMLGrammarPoolWrapper fXMLGrammarPoolWrapper; @@ -137,7 +137,7 @@ public final class XMLSchemaFactory extends SchemaFactory { fXMLSchemaLoader.setErrorHandler(fErrorHandlerWrapper); // Enable secure processing feature by default - fSecurityManager = new SecurityManager(); + fSecurityManager = new XMLSecurityManager(); fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); //by default, the secure feature is set to true, otherwise the default would have been 'file' @@ -365,7 +365,7 @@ public final class XMLSchemaFactory extends SchemaFactory { "jaxp-secureprocessing-feature", null)); } if (value) { - fSecurityManager = new SecurityManager(); + fSecurityManager = new XMLSecurityManager(); fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); } else { @@ -404,7 +404,7 @@ public final class XMLSchemaFactory extends SchemaFactory { "ProperyNameNull", null)); } if (name.equals(SECURITY_MANAGER)) { - fSecurityManager = (SecurityManager) object; + fSecurityManager = (XMLSecurityManager) object; fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); return; } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java index 241d02cbf85..66847d53998 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java @@ -39,9 +39,9 @@ import com.sun.org.apache.xerces.internal.util.FeatureState; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; @@ -182,7 +182,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin private final HashMap fInitProperties = new HashMap(); /** Stores the initial security manager. */ - private final SecurityManager fInitSecurityManager; + private final XMLSecurityManager fInitSecurityManager; // // User Objects @@ -221,7 +221,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin if (System.getSecurityManager() != null) { _isSecureMode = true; - setProperty(SECURITY_MANAGER, new SecurityManager()); + setProperty(SECURITY_MANAGER, new XMLSecurityManager()); } else { fComponents.put(SECURITY_MANAGER, null); } @@ -242,7 +242,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin // if the secure processing feature is set to true, add a security manager to the configuration Boolean secureProcessing = grammarContainer.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); if (Boolean.TRUE.equals(secureProcessing)) { - fInitSecurityManager = new SecurityManager(); + fInitSecurityManager = new XMLSecurityManager(); } else { fInitSecurityManager = null; @@ -308,7 +308,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin if (_isSecureMode && !value) { throw new XMLConfigurationException(Status.NOT_ALLOWED, XMLConstants.FEATURE_SECURE_PROCESSING); } - setProperty(SECURITY_MANAGER, value ? new SecurityManager() : null); + setProperty(SECURITY_MANAGER, value ? new XMLSecurityManager() : null); return; } fConfigUpdated = true; diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java index 53ad2a6b605..eea7057417b 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java @@ -25,10 +25,10 @@ import com.sun.org.apache.xerces.internal.util.EntityResolver2Wrapper; import com.sun.org.apache.xerces.internal.util.EntityResolverWrapper; import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolHash; import com.sun.org.apache.xerces.internal.util.XMLSymbols; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.QName; @@ -1651,7 +1651,7 @@ public abstract class AbstractSAXParser else if (featureId.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { if (state) { if (fConfiguration.getProperty(SECURITY_MANAGER )==null) { - fConfiguration.setProperty(SECURITY_MANAGER, new SecurityManager()); + fConfiguration.setProperty(SECURITY_MANAGER, new XMLSecurityManager()); } } } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java index df32bfa41d9..53d4ab4a0ea 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java @@ -23,8 +23,8 @@ package com.sun.org.apache.xerces.internal.parsers; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; /** * This configuration allows Xerces to behave in a security-conscious manner; that is, @@ -106,8 +106,8 @@ public class SecurityConfiguration extends XIncludeAwareParserConfiguration XMLComponentManager parentSettings) { super(symbolTable, grammarPool, parentSettings); - // create the SecurityManager property: - setProperty(SECURITY_MANAGER_PROPERTY, new SecurityManager()); + // create the XMLSecurityManager property: + setProperty(SECURITY_MANAGER_PROPERTY, new XMLSecurityManager()); } // (SymbolTable,XMLGrammarPool) } // class SecurityConfiguration diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java deleted file mode 100644 index dd510b622bc..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * The Apache Software License, Version 1.1 - * - * - * Copyright (c) 2003 The Apache Software Foundation. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Xerces" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation and was - * originally based on software copyright (c) 1999, International - * Business Machines, Inc., http://www.apache.org. For more - * information on the Apache Software Foundation, please see - * . - */ - -package com.sun.org.apache.xerces.internal.util; -import com.sun.org.apache.xerces.internal.impl.Constants; -import java.security.AccessController; -import java.security.PrivilegedAction; -/** - * This class is a container for parser settings that relate to - * security, or more specifically, it is intended to be used to prevent denial-of-service - * attacks from being launched against a system running Xerces. - * Any component that is aware of a denial-of-service attack that can arise - * from its processing of a certain kind of document may query its Component Manager - * for the property (http://apache.org/xml/properties/security-manager) - * whose value will be an instance of this class. - * If no value has been set for the property, the component should proceed in the "usual" (spec-compliant) - * manner. If a value has been set, then it must be the case that the component in - * question needs to know what method of this class to query. This class - * will provide defaults for all known security issues, but will also provide - * setters so that those values can be tailored by applications that care. - * - * @author Neil Graham, IBM - * - * @version $Id: SecurityManager.java,v 1.5 2010-11-01 04:40:14 joehw Exp $ - */ -public final class SecurityManager { - - // - // Constants - // - - // default value for entity expansion limit - private final static int DEFAULT_ENTITY_EXPANSION_LIMIT = 64000; - - /** Default value of number of nodes created. **/ - private final static int DEFAULT_MAX_OCCUR_NODE_LIMIT = 5000; - - // - // Data - // - - private final static int DEFAULT_ELEMENT_ATTRIBUTE_LIMIT = 10000; - - /** Entity expansion limit. **/ - private int entityExpansionLimit; - - /** W3C XML Schema maxOccurs limit. **/ - private int maxOccurLimit; - - private int fElementAttributeLimit; - // default constructor. Establishes default values for - // all known security holes. - /** - * Default constructor. Establishes default values - * for known security vulnerabilities. - */ - public SecurityManager() { - entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; - maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT ; - fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; - //We are reading system properties only once , - //at the time of creation of this object , - readSystemProperties(); - } - - /** - *

    Sets the number of entity expansions that the - * parser should permit in a document.

    - * - * @param limit the number of entity expansions - * permitted in a document - */ - public void setEntityExpansionLimit(int limit) { - entityExpansionLimit = limit; - } - - /** - *

    Returns the number of entity expansions - * that the parser permits in a document.

    - * - * @return the number of entity expansions - * permitted in a document - */ - public int getEntityExpansionLimit() { - return entityExpansionLimit; - } - - /** - *

    Sets the limit of the number of content model nodes - * that may be created when building a grammar for a W3C - * XML Schema that contains maxOccurs attributes with values - * other than "unbounded".

    - * - * @param limit the maximum value for maxOccurs other - * than "unbounded" - */ - public void setMaxOccurNodeLimit(int limit){ - maxOccurLimit = limit; - } - - /** - *

    Returns the limit of the number of content model nodes - * that may be created when building a grammar for a W3C - * XML Schema that contains maxOccurs attributes with values - * other than "unbounded".

    - * - * @return the maximum value for maxOccurs other - * than "unbounded" - */ - public int getMaxOccurNodeLimit(){ - return maxOccurLimit; - } - - public int getElementAttrLimit(){ - return fElementAttributeLimit; - } - - public void setElementAttrLimit(int limit){ - fElementAttributeLimit = limit; - } - - private void readSystemProperties(){ - - //TODO: also read SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT - try { - String value = getSystemProperty(Constants.ENTITY_EXPANSION_LIMIT); - if(value != null && !value.equals("")){ - entityExpansionLimit = Integer.parseInt(value); - if (entityExpansionLimit < 0) - entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; - } - else - entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; - }catch(Exception ex){} - - try { - String value = getSystemProperty(Constants.MAX_OCCUR_LIMIT); - if(value != null && !value.equals("")){ - maxOccurLimit = Integer.parseInt(value); - if (maxOccurLimit < 0) - maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT; - } - else - maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT; - }catch(Exception ex){} - - try { - String value = getSystemProperty(Constants.SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT); - if(value != null && !value.equals("")){ - fElementAttributeLimit = Integer.parseInt(value); - if ( fElementAttributeLimit < 0) - fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; - } - else - fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; - - }catch(Exception ex){} - - } - - private String getSystemProperty(final String propName) { - return AccessController.doPrivileged(new PrivilegedAction() { - public String run() { - return System.getProperty(propName); - } - }); - } -} // class SecurityManager diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/util/SymbolTable.java b/jaxp/src/com/sun/org/apache/xerces/internal/util/SymbolTable.java index b3d9ed7f925..8e62c1f1d75 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/util/SymbolTable.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/util/SymbolTable.java @@ -173,7 +173,7 @@ public class SymbolTable { for (int i = 0; i < length; i++) { code = code * 37 + symbol.charAt(i); } - return code & 0x7FFFFFF; + return code & 0x7FFFFFFF; } // hash(String):int @@ -194,7 +194,7 @@ public class SymbolTable { for (int i = 0; i < length; i++) { code = code * 37 + buffer[offset + i]; } - return code & 0x7FFFFFF; + return code & 0x7FFFFFFF; } // hash(char[],int,int):int diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java new file mode 100644 index 00000000000..f70aeb7cb21 --- /dev/null +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.org.apache.xerces.internal.utils; + +import com.sun.org.apache.xerces.internal.impl.Constants; + +/** + * This class manages standard and implementation-specific limitations. + * + */ +public final class XMLSecurityManager { + + /** + * States of the settings of a property, in the order: default value, value + * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system + * properties, and jaxp api properties + */ + public static enum State { + //this order reflects the overriding order + DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY + } + + /** + * Limits managed by the security manager + */ + public static enum Limit { + ENTITY_EXPANSION_LIMIT(64000), + MAX_OCCUR_NODE_LIMIT(5000), + ELEMENT_ATTRIBUTE_LIMIT(10000); + + final int defaultValue; + + Limit(int value) { + this.defaultValue = value; + } + + int defaultValue() { + return defaultValue; + } + } + + /** + * Values of the limits as defined in enum Limit + */ + private final int[] limits; + /** + * States of the settings for each limit in limits above + */ + private State[] states = {State.DEFAULT, State.DEFAULT, State.DEFAULT, State.DEFAULT}; + + /** + * Default constructor. Establishes default values for known security + * vulnerabilities. + */ + public XMLSecurityManager() { + limits = new int[Limit.values().length]; + for (Limit limit : Limit.values()) { + limits[limit.ordinal()] = limit.defaultValue(); + } + //read system properties or jaxp.properties + readSystemProperties(); + } + + /** + * Sets the limit for a specific type of XML constructs. This can be either + * the size or the number of the constructs. + * + * @param type the type of limitation + * @param state the state of limitation + * @param limit the limit to the type + */ + public void setLimit(Limit limit, State state, int value) { + //only update if it shall override + if (state.compareTo(states[limit.ordinal()]) >= 0) { + limits[limit.ordinal()] = value; + states[limit.ordinal()] = state; + } + } + + /** + * Returns the limit set for the type specified + * + * @param limit the type of limitation + * @return the limit to the type + */ + public int getLimit(Limit limit) { + return limits[limit.ordinal()]; + } + + /** + * Read from system properties, or those in jaxp.properties + */ + private void readSystemProperties() { + getSystemProperty(Limit.ENTITY_EXPANSION_LIMIT, Constants.ENTITY_EXPANSION_LIMIT); + getSystemProperty(Limit.MAX_OCCUR_NODE_LIMIT, Constants.MAX_OCCUR_LIMIT); + getSystemProperty(Limit.ELEMENT_ATTRIBUTE_LIMIT, + Constants.SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT); + } + + /** + * Read from system properties, or those in jaxp.properties + * + * @param limit the type of the property + * @param property the property name + */ + private void getSystemProperty(Limit limit, String property) { + try { + String value = SecuritySupport.getSystemProperty(property); + if (value != null && !value.equals("")) { + limits[limit.ordinal()] = Integer.parseInt(value); + states[limit.ordinal()] = State.SYSTEMPROPERTY; + return; + } + + value = SecuritySupport.readJAXPProperty(property); + if (value != null && !value.equals("")) { + limits[limit.ordinal()] = Integer.parseInt(value); + states[limit.ordinal()] = State.JAXPDOTPROPERTIES; + } + } catch (NumberFormatException e) { + //invalid setting ignored + } + } +} diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java index ba7284609e1..228cd72216d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java @@ -37,7 +37,6 @@ import com.sun.org.apache.xerces.internal.util.AugmentationsImpl; import com.sun.org.apache.xerces.internal.util.HTTPInputSource; import com.sun.org.apache.xerces.internal.util.IntStack; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; -import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.URI; import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; @@ -45,6 +44,7 @@ import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl; import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.QName; @@ -292,7 +292,7 @@ public class XIncludeHandler protected SymbolTable fSymbolTable; protected XMLErrorReporter fErrorReporter; protected XMLEntityResolver fEntityResolver; - protected SecurityManager fSecurityManager; + protected XMLSecurityManager fSecurityManager; /** * comma-delimited list of protocols that are allowed for the purpose * of accessing external dtd or entity references @@ -525,8 +525,8 @@ public class XIncludeHandler // Get security manager. try { - SecurityManager value = - (SecurityManager)componentManager.getProperty( + XMLSecurityManager value = + (XMLSecurityManager)componentManager.getProperty( SECURITY_MANAGER); if (value != null) { @@ -681,7 +681,7 @@ public class XIncludeHandler return; } if (propertyId.equals(SECURITY_MANAGER)) { - fSecurityManager = (SecurityManager)value; + fSecurityManager = (XMLSecurityManager)value; if (fChildConfig != null) { fChildConfig.setProperty(propertyId, value); } diff --git a/jaxp/src/com/sun/xml/internal/stream/Entity.java b/jaxp/src/com/sun/xml/internal/stream/Entity.java index 0ae8228a3be..7bbdf692412 100644 --- a/jaxp/src/com/sun/xml/internal/stream/Entity.java +++ b/jaxp/src/com/sun/xml/internal/stream/Entity.java @@ -248,7 +248,7 @@ public abstract class Entity { public int fBufferSize = DEFAULT_BUFFER_SIZE; /** Default buffer size before we've finished with the XMLDecl: */ - public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 28; + public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 64; /** Default internal entity buffer size (1024). */ public static final int DEFAULT_INTERNAL_BUFFER_SIZE = 1024; From dee5d80756e5d64b1971240bc6f014686d8e824b Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 17 Jul 2013 18:46:28 +0200 Subject: [PATCH 0048/1294] 8013502: Improve stream factories Reviewed-by: joehw, mullan, lancea --- jaxp/src/javax/xml/stream/FactoryFinder.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/jaxp/src/javax/xml/stream/FactoryFinder.java b/jaxp/src/javax/xml/stream/FactoryFinder.java index 68f4ef21d66..886caa57ee0 100644 --- a/jaxp/src/javax/xml/stream/FactoryFinder.java +++ b/jaxp/src/javax/xml/stream/FactoryFinder.java @@ -253,7 +253,13 @@ class FactoryFinder { // Use the system property first try { - String systemProp = ss.getSystemProperty(factoryId); + + final String systemProp; + if (type.getName().equals(factoryId)) { + systemProp = ss.getSystemProperty(factoryId); + } else { + systemProp = System.getProperty(factoryId); + } if (systemProp != null) { dPrint("found system property, value=" + systemProp); // There's a bug here - because 'cl' is ignored. @@ -262,7 +268,8 @@ class FactoryFinder { } } catch (SecurityException se) { - if (debug) se.printStackTrace(); + throw new FactoryConfigurationError( + "Failed to read factoryId '" + factoryId + "'", se); } // Try read $java.home/lib/stax.properties followed by From eef8299094596d609d610228ba0775a04f6b6108 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Fri, 19 Jul 2013 16:29:26 +0200 Subject: [PATCH 0049/1294] 8019584: javax/management/remote/mandatory/loading/MissingClassTest.java failed in nightly against jdk7u45: java.io.InvalidObjectException: Invalid notification: null Reviewed-by: mchung, sjiang, dfuchs, ahgross --- .../management/remote/NotificationResult.java | 17 +++++++++-------- .../management/remote/TargetedNotification.java | 8 ++------ .../mandatory/loading/MissingClassTest.java | 2 +- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/jdk/src/share/classes/javax/management/remote/NotificationResult.java b/jdk/src/share/classes/javax/management/remote/NotificationResult.java index 9e7cfaac31d..ff3978d99eb 100644 --- a/jdk/src/share/classes/javax/management/remote/NotificationResult.java +++ b/jdk/src/share/classes/javax/management/remote/NotificationResult.java @@ -132,16 +132,17 @@ public class NotificationResult implements Serializable { } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { - ObjectInputStream.GetField gf = ois.readFields(); - TargetedNotification[] tNotifs = (TargetedNotification[])gf.get("targetedNotifications", null); - long snStart = gf.get("earliestSequenceNumber", -1L); - long snNext = gf.get("nextSequenceNumber", -1L); + ois.defaultReadObject(); try { - validate(tNotifs, snStart, snNext); + validate( + this.targetedNotifications, + this.earliestSequenceNumber, + this.nextSequenceNumber + ); - this.targetedNotifications = tNotifs.length == 0 ? tNotifs : tNotifs.clone(); - this.earliestSequenceNumber = snStart; - this.nextSequenceNumber = snNext; + this.targetedNotifications = this.targetedNotifications.length == 0 ? + this.targetedNotifications : + this.targetedNotifications.clone(); } catch (IllegalArgumentException e) { throw new InvalidObjectException(e.getMessage()); } diff --git a/jdk/src/share/classes/javax/management/remote/TargetedNotification.java b/jdk/src/share/classes/javax/management/remote/TargetedNotification.java index 03aa0ca6235..cc3d0dcc664 100644 --- a/jdk/src/share/classes/javax/management/remote/TargetedNotification.java +++ b/jdk/src/share/classes/javax/management/remote/TargetedNotification.java @@ -132,13 +132,9 @@ public class TargetedNotification implements Serializable { // } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { - ObjectInputStream.GetField gf = ois.readFields(); - Notification notification = (Notification)gf.get("notif", null); - Integer listenerId = (Integer)gf.get("id", null); + ois.defaultReadObject(); try { - validate(notification, listenerId); - this.notif = notification; - this.id = listenerId; + validate(this.notif, this.id); } catch (IllegalArgumentException e) { throw new InvalidObjectException(e.getMessage()); } diff --git a/jdk/test/javax/management/remote/mandatory/loading/MissingClassTest.java b/jdk/test/javax/management/remote/mandatory/loading/MissingClassTest.java index e70d0adfe6e..98eead895bf 100644 --- a/jdk/test/javax/management/remote/mandatory/loading/MissingClassTest.java +++ b/jdk/test/javax/management/remote/mandatory/loading/MissingClassTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4915825 4921009 4934965 4977469 + * @bug 4915825 4921009 4934965 4977469 8019584 * @summary Tests behavior when client or server gets object of unknown class * @author Eamonn McManus * @run clean MissingClassTest SingleClassLoader From 5b17a5cd6dc3ab591cc6a78cc394ed3fcbbb5c09 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Mon, 22 Jul 2013 19:38:08 -0700 Subject: [PATCH 0050/1294] 8017196: Ensure Proxies are handled appropriately Reviewed-by: dfuchs, jrose, jdn, ahgross, chegar --- .../rmi/InvocationHandlerFactoryImpl.java | 14 ++++++++++++-- .../proxy/CompositeInvocationHandlerImpl.java | 11 +++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/InvocationHandlerFactoryImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/InvocationHandlerFactoryImpl.java index 37a5968d87d..076ed1929ea 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/InvocationHandlerFactoryImpl.java +++ b/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/InvocationHandlerFactoryImpl.java @@ -43,6 +43,8 @@ import com.sun.corba.se.spi.orbutil.proxy.InvocationHandlerFactory ; import com.sun.corba.se.spi.orbutil.proxy.DelegateInvocationHandlerImpl ; import com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandler ; import com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl ; +import java.security.AccessController; +import java.security.PrivilegedAction; public class InvocationHandlerFactoryImpl implements InvocationHandlerFactory { @@ -114,24 +116,32 @@ public class InvocationHandlerFactoryImpl implements InvocationHandlerFactory // which extends org.omg.CORBA.Object. This handler delegates all // calls directly to a DynamicStubImpl, which extends // org.omg.CORBA.portable.ObjectImpl. - InvocationHandler dynamicStubHandler = + final InvocationHandler dynamicStubHandler = DelegateInvocationHandlerImpl.create( stub ) ; // Create an invocation handler that handles any remote interface // methods. - InvocationHandler stubMethodHandler = new StubInvocationHandlerImpl( + final InvocationHandler stubMethodHandler = new StubInvocationHandlerImpl( pm, classData, stub ) ; // Create a composite handler that handles the DynamicStub interface // as well as the remote interfaces. final CompositeInvocationHandler handler = new CustomCompositeInvocationHandlerImpl( stub ) ; + + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Void run() { handler.addInvocationHandler( DynamicStub.class, dynamicStubHandler ) ; handler.addInvocationHandler( org.omg.CORBA.Object.class, dynamicStubHandler ) ; handler.addInvocationHandler( Object.class, dynamicStubHandler ) ; + return null; + } + }); + // If the method passed to invoke is not from DynamicStub or its superclasses, // it must be from an implemented interface, so we just handle diff --git a/corba/src/share/classes/com/sun/corba/se/spi/orbutil/proxy/CompositeInvocationHandlerImpl.java b/corba/src/share/classes/com/sun/corba/se/spi/orbutil/proxy/CompositeInvocationHandlerImpl.java index fb81ceee29c..91aacd5afae 100644 --- a/corba/src/share/classes/com/sun/corba/se/spi/orbutil/proxy/CompositeInvocationHandlerImpl.java +++ b/corba/src/share/classes/com/sun/corba/se/spi/orbutil/proxy/CompositeInvocationHandlerImpl.java @@ -36,6 +36,7 @@ import java.lang.reflect.InvocationHandler ; import com.sun.corba.se.spi.logging.CORBALogDomains ; import com.sun.corba.se.impl.logging.ORBUtilSystemException ; +import com.sun.corba.se.impl.presentation.rmi.DynamicAccessPermission; public class CompositeInvocationHandlerImpl implements CompositeInvocationHandler @@ -46,11 +47,13 @@ public class CompositeInvocationHandlerImpl implements public void addInvocationHandler( Class interf, InvocationHandler handler ) { + checkAccess(); classToInvocationHandler.put( interf, handler ) ; } public void setDefaultHandler( InvocationHandler handler ) { + checkAccess(); defaultHandler = handler ; } @@ -78,4 +81,12 @@ public class CompositeInvocationHandlerImpl implements return handler.invoke( proxy, method, args ) ; } + + private static final DynamicAccessPermission perm = new DynamicAccessPermission("access"); + private void checkAccess() { + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(perm); +} + } } From 99860de3cd08c11752b465c31a4257118d70ac28 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Wed, 24 Jul 2013 12:03:57 -0700 Subject: [PATCH 0051/1294] 8020293: JVM crash Reviewed-by: prr, jgodinez --- jdk/src/share/classes/sun/font/GlyphLayout.java | 7 ++++--- jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/sun/font/GlyphLayout.java b/jdk/src/share/classes/sun/font/GlyphLayout.java index d29ecf34cb2..f2fc484caa0 100644 --- a/jdk/src/share/classes/sun/font/GlyphLayout.java +++ b/jdk/src/share/classes/sun/font/GlyphLayout.java @@ -468,9 +468,10 @@ public final class GlyphLayout { _gvdata.grow(); } } - if (_gvdata._count < 0) { - break; - } + } + // Break out of the outer for loop if layout fails. + if (_gvdata._count < 0) { + break; } } diff --git a/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp b/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp index b32f2601b4d..858e3636038 100644 --- a/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp +++ b/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp @@ -104,6 +104,10 @@ Java_sun_font_SunLayoutEngine_initGVIDs int putGV(JNIEnv* env, jint gmask, jint baseIndex, jobject gvdata, const LayoutEngine* engine, int glyphCount) { int count = env->GetIntField(gvdata, gvdCountFID); + if (count < 0) { + JNU_ThrowInternalError(env, "count negative"); + return 0; + } jarray glyphArray = (jarray)env->GetObjectField(gvdata, gvdGlyphsFID); if (IS_NULL(glyphArray)) { From dd0661e5adf498ddb6857b438c245341ae3b9e04 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Wed, 24 Jul 2013 15:18:33 -0700 Subject: [PATCH 0052/1294] 8016675: Make Javadoc pages more robust Reviewed-by: jlaskey, ksrini --- .../formats/html/markup/HtmlWriter.java | 49 ++++++++++- .../testWindowTitle/TestWindowTitle.java | 82 +++++++++++++++++++ .../sun/javadoc/testWindowTitle/p1/C1.java | 27 ++++++ .../sun/javadoc/testWindowTitle/p2/C2.java | 27 ++++++ 4 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java create mode 100644 langtools/test/com/sun/javadoc/testWindowTitle/p1/C1.java create mode 100644 langtools/test/com/sun/javadoc/testWindowTitle/p2/C2.java diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java index 5369733893b..c58e9a66e57 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java @@ -290,7 +290,7 @@ public class HtmlWriter { script.addAttr(HtmlAttr.TYPE, "text/javascript"); String scriptCode = "" + DocletConstants.NL; RawHtml scriptContent = new RawHtml(scriptCode); @@ -299,6 +299,53 @@ public class HtmlWriter { return script; } + /** + * Returns a String with escaped special JavaScript characters. + * + * @param s String that needs to be escaped + * @return a valid escaped JavaScript string + */ + private static String escapeJavaScriptChars(String s) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + char ch = s.charAt(i); + switch (ch) { + case '\b': + sb.append("\\b"); + break; + case '\t': + sb.append("\\t"); + break; + case '\n': + sb.append("\\n"); + break; + case '\f': + sb.append("\\f"); + break; + case '\r': + sb.append("\\r"); + break; + case '"': + sb.append("\\\""); + break; + case '\'': + sb.append("\\\'"); + break; + case '\\': + sb.append("\\\\"); + break; + default: + if (ch < 32 || ch >= 127) { + sb.append(String.format("\\u%04X", (int)ch)); + } else { + sb.append(ch); + } + break; + } + } + return sb.toString(); + } + /** * Returns a content tree for the SCRIPT tag for the main page(index.html). * diff --git a/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java b/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java new file mode 100644 index 00000000000..ca4c96ae693 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, 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 8016675 + * @summary Test for window title. + * @author Bhavesh Patel + * @library ../lib/ + * @build JavadocTester TestWindowTitle + * @run main TestWindowTitle + */ + +public class TestWindowTitle extends JavadocTester { + + private static final String BUG_ID = "8016675"; + private static final String WIN_TITLE = + "Testing \"Window 'Title'\" with a \\ backslash and a / " + + "forward slash and a \u00e8 unicode char also a tab and also a " + + "\t special character another \u0002 unicode)"; + private static final String[][] TEST = { + {BUG_ID + FS + "overview-summary.html", + "parent.document.title=\"Overview (Testing \\\"Window \\\'Title\\\'\\\" " + + "with a \\\\ backslash and a / forward slash and a \\u00E8 unicode char " + + "also a tab and also a \\t special character another \\u0002 unicode))\";" + }, + }; + private static final String[][] NEG_TEST = { + {BUG_ID + FS + "overview-summary.html", + "parent.document.title=\"Overview (Testing \"Window \'Title\'\" " + + "with a \\ backslash and a / forward slash and a \u00E8 unicode char " + + "also a tab and also a \t special character another \u0002 unicode))\";" + }, + }; + private static final String[] ARGS = new String[]{ + "-d", BUG_ID, "-windowtitle", WIN_TITLE, "-sourcepath", SRC_DIR, "p1", "p2" + }; + + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String[] args) { + TestWindowTitle tester = new TestWindowTitle(); + run(tester, ARGS, TEST, NEG_TEST); + tester.printSummary(); + } + + /** + * {@inheritDoc} + */ + public String getBugId() { + return BUG_ID; + } + + /** + * {@inheritDoc} + */ + public String getBugName() { + return getClass().getName(); + } +} diff --git a/langtools/test/com/sun/javadoc/testWindowTitle/p1/C1.java b/langtools/test/com/sun/javadoc/testWindowTitle/p1/C1.java new file mode 100644 index 00000000000..239d7a63de0 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testWindowTitle/p1/C1.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013, 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. + */ + +package p1; + +public class C1 { +} diff --git a/langtools/test/com/sun/javadoc/testWindowTitle/p2/C2.java b/langtools/test/com/sun/javadoc/testWindowTitle/p2/C2.java new file mode 100644 index 00000000000..7d075a6fd9f --- /dev/null +++ b/langtools/test/com/sun/javadoc/testWindowTitle/p2/C2.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013, 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. + */ + +package p2; + +public class C2 { +} From 7abc885152c1d3036c9aaae323a2b7aff39f282b Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Mon, 29 Jul 2013 04:43:41 -0700 Subject: [PATCH 0053/1294] 8021577: JCK test api/javax_management/jmx_serial/modelmbean/ModelMBeanNotificationInfo/serial/index.html#Input has failed since jdk 7u45 b01 Reviewed-by: alanb, dfuchs, ahgross --- .../classes/javax/management/MBeanNotificationInfo.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java b/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java index dfa4ab1f8ff..e3b4aba1252 100644 --- a/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java @@ -210,11 +210,6 @@ public class MBeanNotificationInfo extends MBeanFeatureInfo implements Cloneable ObjectInputStream.GetField gf = ois.readFields(); String[] t = (String[])gf.get("types", null); - if (t == null) { - throw new InvalidObjectException("Trying to deserialize an invalid " + - "instance of " + MBeanNotificationInfo.class + - "[types=null]"); - } - types = t.length == 0 ? t : t.clone(); + types = (t != null && t.length != 0) ? t.clone() : NO_TYPES; } } From 298bc0138712763e4d5c81ec4920abac454929d2 Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Wed, 31 Jul 2013 00:37:01 -0700 Subject: [PATCH 0054/1294] 8014530: Better digital signature processing Reviewed-by: alanb, dfuchs, mullan, lancea --- .../apache/xalan/internal/XalanConstants.java | 121 ++++- .../internal/utils/XMLSecurityManager.java | 449 +++++++++++++++++ .../utils/XMLSecurityPropertyManager.java | 33 ++ .../xalan/internal/xsltc/compiler/Import.java | 2 +- .../internal/xsltc/compiler/Include.java | 2 +- .../xalan/internal/xsltc/compiler/Parser.java | 17 +- .../xalan/internal/xsltc/compiler/XSLTC.java | 11 +- .../xsltc/trax/TemplatesHandlerImpl.java | 4 +- .../xsltc/trax/TransformerFactoryImpl.java | 35 +- .../internal/xsltc/trax/TransformerImpl.java | 4 + .../xalan/internal/xsltc/trax/Util.java | 18 + .../internal/dom/DOMConfigurationImpl.java | 8 + .../xerces/internal/impl/Constants.java | 108 ++++- .../xerces/internal/impl/PropertyManager.java | 24 +- .../impl/XML11NSDocumentScannerImpl.java | 4 +- .../internal/impl/XMLDTDScannerImpl.java | 64 ++- .../impl/XMLDocumentFragmentScannerImpl.java | 61 ++- .../internal/impl/XMLEntityManager.java | 51 +- .../impl/XMLNSDocumentScannerImpl.java | 4 +- .../xerces/internal/impl/XMLScanner.java | 21 +- .../internal/impl/msg/XMLMessages.properties | 10 +- .../impl/xs/models/CMNodeFactory.java | 3 +- .../xs/traversers/XSAttributeChecker.java | 2 +- .../internal/jaxp/DocumentBuilderImpl.java | 29 +- .../xerces/internal/jaxp/SAXParserImpl.java | 94 ++-- .../jaxp/validation/StAXValidatorHelper.java | 14 + .../validation/StreamValidatorHelper.java | 2 + .../jaxp/validation/XMLSchemaFactory.java | 27 +- .../XMLSchemaValidatorComponentManager.java | 49 +- .../xerces/internal/parsers/SAXParser.java | 25 +- .../parsers/SecurityConfiguration.java | 5 +- .../internal/parsers/XML11Configuration.java | 18 +- .../internal/utils/XMLLimitAnalyzer.java | 236 +++++++++ .../internal/utils/XMLSecurityManager.java | 452 ++++++++++++++++-- .../utils/XMLSecurityPropertyManager.java | 35 ++ .../xml/internal/utils/XMLReaderManager.java | 26 +- 36 files changed, 1862 insertions(+), 206 deletions(-) create mode 100644 jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java create mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java index ce50626a612..f4a80afacfe 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java @@ -39,6 +39,116 @@ public final class XalanConstants { // // Constants // + //Xerces security manager + public static final String SECURITY_MANAGER = + "http://apache.org/xml/properties/security-manager"; + + // + // Implementation limits: API properties + // + /** Oracle JAXP property prefix ("http://www.oracle.com/xml/jaxp/properties/"). */ + public static final String ORACLE_JAXP_PROPERTY_PREFIX = + "http://www.oracle.com/xml/jaxp/properties/"; + /** + * JDK entity expansion limit; Note that the existing system property + * "entityExpansionLimit" with no prefix is still observed + */ + public static final String JDK_ENTITY_EXPANSION_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "entityExpansionLimit"; + + /** + * JDK element attribute limit; Note that the existing system property + * "elementAttributeLimit" with no prefix is still observed + */ + public static final String JDK_ELEMENT_ATTRIBUTE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "elementAttributeLimit"; + + /** + * JDK maxOccur limit; Note that the existing system property + * "maxOccurLimit" with no prefix is still observed + */ + public static final String JDK_MAX_OCCUR_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxOccurLimit"; + + /** + * JDK total entity size limit + */ + public static final String JDK_TOTAL_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "totalEntitySizeLimit"; + + /** + * JDK maximum general entity size limit + */ + public static final String JDK_GENEAL_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxGeneralEntitySizeLimit"; + /** + * JDK maximum parameter entity size limit + */ + public static final String JDK_PARAMETER_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxParameterEntitySizeLimit"; + /** + * JDK maximum XML name limit + */ + public static final String JDK_XML_NAME_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxXMLNameLimit"; + /** + * JDK property indicating whether the parser shall print out entity + * count information + * Value: a string "yes" means print, "no" or any other string means not. + */ + public static final String JDK_ENTITY_COUNT_INFO = + ORACLE_JAXP_PROPERTY_PREFIX + "getEntityCountInfo"; + + // + // Implementation limits: corresponding System Properties of the above + // API properties + // + /** + * JDK entity expansion limit; Note that the existing system property + * "entityExpansionLimit" with no prefix is still observed + */ + public static final String SP_ENTITY_EXPANSION_LIMIT = "jdk.xml.entityExpansionLimit"; + + /** + * JDK element attribute limit; Note that the existing system property + * "elementAttributeLimit" with no prefix is still observed + */ + public static final String SP_ELEMENT_ATTRIBUTE_LIMIT = "jdk.xml.elementAttributeLimit"; + + /** + * JDK maxOccur limit; Note that the existing system property + * "maxOccurLimit" with no prefix is still observed + */ + public static final String SP_MAX_OCCUR_LIMIT = "jdk.xml.maxOccurLimit"; + + /** + * JDK total entity size limit + */ + public static final String SP_TOTAL_ENTITY_SIZE_LIMIT = "jdk.xml.totalEntitySizeLimit"; + + /** + * JDK maximum general entity size limit + */ + public static final String SP_GENEAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit"; + /** + * JDK maximum parameter entity size limit + */ + public static final String SP_PARAMETER_ENTITY_SIZE_LIMIT = "jdk.xml.maxParameterEntitySizeLimit"; + /** + * JDK maximum XML name limit + */ + public static final String SP_XML_NAME_LIMIT = "jdk.xml.maxXMLNameLimit"; + + //legacy System Properties + public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit"; + public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ; + public final static String MAX_OCCUR_LIMIT = "maxOccurLimit"; + + /** + * A string "yes" that can be used for properties such as getEntityCountInfo + */ + public static final String JDK_YES = "yes"; + // Oracle Feature: /** *

    Use Service Mechanism

    @@ -51,21 +161,16 @@ public final class XalanConstants { *
  • * {@code false} instruct an object to skip service mechanism and * use the default implementation for that service. - *
  • - * - */ - + * + * + */ public static final String ORACLE_FEATURE_SERVICE_MECHANISM = "http://www.oracle.com/feature/use-service-mechanism"; - /** Oracle JAXP property prefix ("http://www.oracle.com/xml/jaxp/properties/"). */ - public static final String ORACLE_JAXP_PROPERTY_PREFIX = - "http://www.oracle.com/xml/jaxp/properties/"; //System Properties corresponding to ACCESS_EXTERNAL_* properties public static final String SP_ACCESS_EXTERNAL_STYLESHEET = "javax.xml.accessExternalStylesheet"; public static final String SP_ACCESS_EXTERNAL_DTD = "javax.xml.accessExternalDTD"; - //all access keyword public static final String ACCESS_EXTERNAL_ALL = "all"; diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java new file mode 100644 index 00000000000..99a8e2d5f69 --- /dev/null +++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java @@ -0,0 +1,449 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package com.sun.org.apache.xalan.internal.utils; + +import com.sun.org.apache.xalan.internal.XalanConstants; + + +/** + * This class is not the same as that in Xerces. It is used to manage the + * state of corresponding Xerces properties and pass the values over to + * the Xerces Security Manager. + * + * @author Joe Wang Oracle Corp. + * + */ +public final class XMLSecurityManager { + + /** + * States of the settings of a property, in the order: default value, value + * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system + * properties, and jaxp api properties + */ + public static enum State { + //this order reflects the overriding order + + DEFAULT("default"), FSP("FEATURE_SECURE_PROCESSING"), + JAXPDOTPROPERTIES("jaxp.properties"), SYSTEMPROPERTY("system property"), + APIPROPERTY("property"); + + final String literal; + State(String literal) { + this.literal = literal; + } + + String literal() { + return literal; + } + } + + /** + * Limits managed by the security manager + */ + public static enum Limit { + + ENTITY_EXPANSION_LIMIT(XalanConstants.JDK_ENTITY_EXPANSION_LIMIT, + XalanConstants.SP_ENTITY_EXPANSION_LIMIT, 0, 64000), + MAX_OCCUR_NODE_LIMIT(XalanConstants.JDK_MAX_OCCUR_LIMIT, + XalanConstants.SP_MAX_OCCUR_LIMIT, 0, 5000), + ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.JDK_ELEMENT_ATTRIBUTE_LIMIT, + XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, 0, 10000), + TOTAL_ENTITY_SIZE_LIMIT(XalanConstants.JDK_TOTAL_ENTITY_SIZE_LIMIT, + XalanConstants.SP_TOTAL_ENTITY_SIZE_LIMIT, 0, 50000000), + GENEAL_ENTITY_SIZE_LIMIT(XalanConstants.JDK_GENEAL_ENTITY_SIZE_LIMIT, + XalanConstants.SP_GENEAL_ENTITY_SIZE_LIMIT, 0, 0), + PARAMETER_ENTITY_SIZE_LIMIT(XalanConstants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, + XalanConstants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000); + + final String apiProperty; + final String systemProperty; + final int defaultValue; + final int secureValue; + + Limit(String apiProperty, String systemProperty, int value, int secureValue) { + this.apiProperty = apiProperty; + this.systemProperty = systemProperty; + this.defaultValue = value; + this.secureValue = secureValue; + } + + public boolean equalsAPIPropertyName(String propertyName) { + return (propertyName == null) ? false : apiProperty.equals(propertyName); + } + + public boolean equalsSystemPropertyName(String propertyName) { + return (propertyName == null) ? false : systemProperty.equals(propertyName); + } + + public String apiProperty() { + return apiProperty; + } + + String systemProperty() { + return systemProperty; + } + + int defaultValue() { + return defaultValue; + } + + int secureValue() { + return secureValue; + } + } + + /** + * Map old property names with the new ones + */ + public static enum NameMap { + + ENTITY_EXPANSION_LIMIT(XalanConstants.SP_ENTITY_EXPANSION_LIMIT, + XalanConstants.ENTITY_EXPANSION_LIMIT), + MAX_OCCUR_NODE_LIMIT(XalanConstants.SP_MAX_OCCUR_LIMIT, + XalanConstants.MAX_OCCUR_LIMIT), + ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, + XalanConstants.ELEMENT_ATTRIBUTE_LIMIT); + final String newName; + final String oldName; + + NameMap(String newName, String oldName) { + this.newName = newName; + this.oldName = oldName; + } + + String getOldName(String newName) { + if (newName.equals(this.newName)) { + return oldName; + } + return null; + } + } + /** + * Values of the properties + */ + private final int[] values; + /** + * States of the settings for each property + */ + private State[] states; + /** + * States that determine if properties are set explicitly + */ + private boolean[] isSet; + + + /** + * Index of the special entityCountInfo property + */ + private int indexEntityCountInfo = 10000; + private String printEntityCountInfo = ""; + + /** + * Default constructor. Establishes default values for known security + * vulnerabilities. + */ + public XMLSecurityManager() { + this(false); + } + + /** + * Instantiate Security Manager in accordance with the status of + * secure processing + * @param secureProcessing + */ + public XMLSecurityManager(boolean secureProcessing) { + values = new int[Limit.values().length]; + states = new State[Limit.values().length]; + isSet = new boolean[Limit.values().length]; + for (Limit limit : Limit.values()) { + if (secureProcessing) { + values[limit.ordinal()] = limit.secureValue(); + states[limit.ordinal()] = State.FSP; + } else { + values[limit.ordinal()] = limit.defaultValue(); + states[limit.ordinal()] = State.DEFAULT; + } + } + //read system properties or jaxp.properties + readSystemProperties(); + } + + /** + * Setting FEATURE_SECURE_PROCESSING explicitly + */ + public void setSecureProcessing(boolean secure) { + for (Limit limit : Limit.values()) { + if (secure) { + setLimit(limit.ordinal(), State.FSP, limit.secureValue()); + } else { + setLimit(limit.ordinal(), State.FSP, limit.defaultValue()); + } + } + } + + /** + * Set limit by property name and state + * @param propertyName property name + * @param state the state of the property + * @param value the value of the property + * @return true if the property is managed by the security manager; false + * if otherwise. + */ + public boolean setLimit(String propertyName, State state, Object value) { + int index = getIndex(propertyName); + if (index > -1) { + setLimit(index, state, value); + return true; + } + return false; + } + + /** + * Set the value for a specific limit. + * + * @param limit the limit + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(Limit limit, State state, int value) { + setLimit(limit.ordinal(), state, value); + } + + /** + * Set the value of a property by its index + * + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(int index, State state, Object value) { + if (index == indexEntityCountInfo) { + //if it's explicitly set, it's treated as yes no matter the value + printEntityCountInfo = (String)value; + } else { + int temp = 0; + try { + temp = Integer.parseInt((String) value); + if (temp < 0) { + temp = 0; + } + } catch (NumberFormatException e) {} + setLimit(index, state, temp); } + } + + /** + * Set the value of a property by its index + * + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(int index, State state, int value) { + if (index == indexEntityCountInfo) { + //if it's explicitly set, it's treated as yes no matter the value + printEntityCountInfo = XalanConstants.JDK_YES; + } else { + //only update if it shall override + if (state.compareTo(states[index]) >= 0) { + values[index] = value; + states[index] = state; + isSet[index] = true; + } + } + } + + + /** + * Return the value of the specified property. + * + * @param propertyName the property name + * @return the value of the property as a string. If a property is managed + * by this manager, its value shall not be null. + */ + public String getLimitAsString(String propertyName) { + int index = getIndex(propertyName); + if (index > -1) { + return getLimitValueByIndex(index); + } + + return null; + } + + /** + * Return the value of a property by its ordinal + * + * @param limit the property + * @return value of a property + */ + public String getLimitValueAsString(Limit limit) { + return Integer.toString(values[limit.ordinal()]); + } + + /** + * Return the value of the specified property + * + * @param limit the property + * @return the value of the property + */ + public int getLimit(Limit limit) { + return values[limit.ordinal()]; + } + + /** + * Return the value of a property by its ordinal + * + * @param index the index of a property + * @return value of a property + */ + public int getLimitByIndex(int index) { + return values[index]; + } + /** + * Return the value of a property by its index + * + * @param index the index of a property + * @return limit of a property as a string + */ + public String getLimitValueByIndex(int index) { + if (index == indexEntityCountInfo) { + return printEntityCountInfo; + } + + return Integer.toString(values[index]); + } + /** + * Return the state of the limit property + * + * @param limit the limit + * @return the state of the limit property + */ + public State getState(Limit limit) { + return states[limit.ordinal()]; + } + + /** + * Return the state of the limit property + * + * @param limit the limit + * @return the state of the limit property + */ + public String getStateLiteral(Limit limit) { + return states[limit.ordinal()].literal(); + } + + /** + * Get the index by property name + * + * @param propertyName property name + * @return the index of the property if found; return -1 if not + */ + public int getIndex(String propertyName) { + for (Limit limit : Limit.values()) { + if (limit.equalsAPIPropertyName(propertyName)) { + //internally, ordinal is used as index + return limit.ordinal(); + } + } + //special property to return entity count info + if (propertyName.equals(XalanConstants.JDK_ENTITY_COUNT_INFO)) { + return indexEntityCountInfo; + } + return -1; + } + + /** + * Indicate if a property is set explicitly + * @param index + * @return + */ + public boolean isSet(int index) { + return isSet[index]; + } + + public boolean printEntityCountInfo() { + return printEntityCountInfo.equals(XalanConstants.JDK_YES); + } + /** + * Read from system properties, or those in jaxp.properties + */ + private void readSystemProperties() { + + for (Limit limit : Limit.values()) { + if (!getSystemProperty(limit, limit.systemProperty())) { + //if system property is not found, try the older form if any + for (NameMap nameMap : NameMap.values()) { + String oldName = nameMap.getOldName(limit.systemProperty()); + if (oldName != null) { + getSystemProperty(limit, oldName); + } + } + } + } + + } + + /** + * Read from system properties, or those in jaxp.properties + * + * @param property the type of the property + * @param sysPropertyName the name of system property + */ + private boolean getSystemProperty(Limit limit, String sysPropertyName) { + try { + String value = SecuritySupport.getSystemProperty(sysPropertyName); + if (value != null && !value.equals("")) { + values[limit.ordinal()] = Integer.parseInt(value); + states[limit.ordinal()] = State.SYSTEMPROPERTY; + return true; + } + + value = SecuritySupport.readJAXPProperty(sysPropertyName); + if (value != null && !value.equals("")) { + values[limit.ordinal()] = Integer.parseInt(value); + states[limit.ordinal()] = State.JAXPDOTPROPERTIES; + return true; + } + } catch (NumberFormatException e) { + //invalid setting + throw new NumberFormatException("Invalid setting for system property: " + limit.systemProperty()); + } + return false; + } +} diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java index 5f5501a3434..35dc9a5d04b 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java @@ -93,6 +93,23 @@ public final class XMLSecurityPropertyManager { readSystemProperties(); } + /** + * Set limit by property name and state + * @param propertyName property name + * @param state the state of the property + * @param value the value of the property + * @return true if the property is managed by the security property manager; + * false if otherwise. + */ + public boolean setValue(String propertyName, State state, Object value) { + int index = getIndex(propertyName); + if (index > -1) { + setValue(index, state, (String)value); + return true; + } + return false; + } + /** * Set the value for a specific property. * @@ -121,6 +138,22 @@ public final class XMLSecurityPropertyManager { states[index] = state; } } + + /** + * Return the value of the specified property + * + * @param propertyName the property name + * @return the value of the property as a string + */ + public String getValue(String propertyName) { + int index = getIndex(propertyName); + if (index > -1) { + return getValueByIndex(index); + } + + return null; + } + /** * Return the value of the specified property * diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java index fdfbe178d1d..e1971d35c06 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java @@ -86,7 +86,7 @@ final class Import extends TopLevelElement { if (input == null) { docToLoad = SystemIDResolver.getAbsoluteURI(docToLoad, currLoadedDoc); String accessError = SecuritySupport.checkAccess(docToLoad, - xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), + (String)xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), XalanConstants.ACCESS_EXTERNAL_ALL); if (accessError != null) { diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java index 71c129f7cca..5bf12f8dc1b 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java @@ -87,7 +87,7 @@ final class Include extends TopLevelElement { if (input == null) { docToLoad = SystemIDResolver.getAbsoluteURI(docToLoad, currLoadedDoc); String accessError = SecuritySupport.checkAccess(docToLoad, - xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), + (String)xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), XalanConstants.ACCESS_EXTERNAL_ALL); if (accessError != null) { diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java index 3c186a1172b..0903d9a9ef6 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java @@ -28,6 +28,7 @@ import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; @@ -487,6 +488,20 @@ public class Parser implements Constants, ContentHandler { } final XMLReader reader = parser.getXMLReader(); + try { + XMLSecurityManager securityManager = + (XMLSecurityManager)_xsltc.getProperty(XalanConstants.SECURITY_MANAGER); + for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) { + reader.setProperty(limit.apiProperty(), securityManager.getLimitValueAsString(limit)); + } + if (securityManager.printEntityCountInfo()) { + parser.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES); + } + } catch (SAXException se) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + se.getMessage()); + } + return(parse(reader, input)); } catch (ParserConfigurationException e) { @@ -565,7 +580,7 @@ public class Parser implements Constants, ContentHandler { } path = SystemIDResolver.getAbsoluteURI(path); String accessError = SecuritySupport.checkAccess(path, - _xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), + (String)_xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET), XalanConstants.ACCESS_EXTERNAL_ALL); if (accessError != null) { ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR, diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java index 97fff3bf2e0..10823f14689 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java @@ -44,11 +44,11 @@ import javax.xml.XMLConstants; import com.sun.org.apache.bcel.internal.classfile.JavaClass; import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; import com.sun.org.apache.xml.internal.dtm.DTM; -import com.sun.org.apache.xalan.internal.utils.SecuritySupport; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; @@ -146,6 +146,7 @@ public final class XSLTC { */ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT; + private XMLSecurityManager _xmlSecurityManager; /** * XSLTC compiler constructor @@ -184,12 +185,14 @@ public final class XSLTC { /** * Return allowed protocols for accessing external stylesheet. */ - public String getProperty(String name) { + public Object getProperty(String name) { if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) { return _accessExternalStylesheet; } else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { return _accessExternalDTD; + } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { + return _xmlSecurityManager; } return null; } @@ -197,12 +200,14 @@ public final class XSLTC { /** * Set allowed protocols for accessing external stylesheet. */ - public void setProperty(String name, String value) { + public void setProperty(String name, Object value) { if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) { _accessExternalStylesheet = (String)value; } else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { _accessExternalDTD = (String)value; + } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { + _xmlSecurityManager = (XMLSecurityManager)value; } } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java index 879c1cb4de0..ff43ca9410f 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java @@ -29,7 +29,7 @@ import javax.xml.transform.Templates; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; import javax.xml.transform.sax.TemplatesHandler; - +import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.xsltc.compiler.CompilerException; import com.sun.org.apache.xalan.internal.xsltc.compiler.Parser; import com.sun.org.apache.xalan.internal.xsltc.compiler.SourceLoader; @@ -103,6 +103,8 @@ public class TemplatesHandlerImpl (String)tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)); xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, (String)tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD)); + xsltc.setProperty(XalanConstants.SECURITY_MANAGER, + tfactory.getAttribute(XalanConstants.SECURITY_MANAGER)); if ("true".equals(tfactory.getAttribute(TransformerFactoryImpl.ENABLE_INLINING))) diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java index 874892942f9..9b6589d7aa8 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java @@ -27,6 +27,7 @@ import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.Property; import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.State; @@ -218,13 +219,13 @@ public class TransformerFactoryImpl * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element. */ private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT; - /** * protocols allowed for external DTD references in source file and/or stylesheet. */ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT; private XMLSecurityPropertyManager _xmlSecurityPropertyMgr; + private XMLSecurityManager _xmlSecurityManager; /** * javax.xml.transform.sax.TransformerFactory implementation. @@ -250,6 +251,9 @@ public class TransformerFactoryImpl Property.ACCESS_EXTERNAL_DTD); _accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue( Property.ACCESS_EXTERNAL_STYLESHEET); + + //Parser's security manager + _xmlSecurityManager = new XMLSecurityManager(true); } /** @@ -311,11 +315,21 @@ public class TransformerFactoryImpl return Boolean.TRUE; else return Boolean.FALSE; + } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { + return _xmlSecurityManager; } - int index = _xmlSecurityPropertyMgr.getIndex(name); - if (index > -1) { - return _xmlSecurityPropertyMgr.getValueByIndex(index); + /** Check to see if the property is managed by the security manager **/ + String propertyValue = (_xmlSecurityManager != null) ? + _xmlSecurityManager.getLimitAsString(name) : null; + if (propertyValue != null) { + return propertyValue; + } else { + propertyValue = (_xmlSecurityPropertyMgr != null) ? + _xmlSecurityPropertyMgr.getValue(name) : null; + if (propertyValue != null) { + return propertyValue; + } } // Throw an exception for all other attributes @@ -419,10 +433,13 @@ public class TransformerFactoryImpl } } - int index = _xmlSecurityPropertyMgr.getIndex(name); - if (index > -1) { - _xmlSecurityPropertyMgr.setValue(index, - State.APIPROPERTY, (String)value); + if (_xmlSecurityManager != null && + _xmlSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) { + return; + } + + if (_xmlSecurityPropertyMgr != null && + _xmlSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, value)) { _accessExternalDTD = _xmlSecurityPropertyMgr.getValue( Property.ACCESS_EXTERNAL_DTD); _accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue( @@ -473,6 +490,7 @@ public class TransformerFactoryImpl throw new TransformerConfigurationException(err.toString()); } _isNotSecureProcessing = !value; + _xmlSecurityManager.setSecureProcessing(value); // set external access restriction when FSP is explicitly set if (value && XalanConstants.IS_JDK8_OR_ABOVE) { @@ -849,6 +867,7 @@ public class TransformerFactoryImpl if (!_isNotSecureProcessing) xsltc.setSecureProcessing(true); xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, _accessExternalStylesheet); xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD); + xsltc.setProperty(XalanConstants.SECURITY_MANAGER, _xmlSecurityManager); xsltc.init(); // Set a document loader (for xsl:include/import) if defined diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java index 7c33c91a8c8..6bf365fe2a7 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java @@ -25,6 +25,7 @@ package com.sun.org.apache.xalan.internal.xsltc.trax; import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -214,6 +215,7 @@ public final class TransformerImpl extends Transformer */ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT; + private XMLSecurityManager _securityManager; /** * A hashtable to store parameters for the identity transform. These * are not needed during the transformation, but we must keep track of @@ -269,9 +271,11 @@ public final class TransformerImpl extends Transformer _useServicesMechanism = _tfactory.useServicesMechnism(); _accessExternalStylesheet = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET); _accessExternalDTD = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD); + _securityManager = (XMLSecurityManager)_tfactory.getAttribute(XalanConstants.SECURITY_MANAGER); _readerManager = XMLReaderManager.getInstance(_useServicesMechanism); _readerManager.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD); _readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing); + _readerManager.setProperty(XalanConstants.SECURITY_MANAGER, _securityManager); //_isIncremental = tfactory._incremental; } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java index b287a351db4..4c6e02936c3 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java @@ -23,6 +23,7 @@ package com.sun.org.apache.xalan.internal.xsltc.trax; +import com.sun.org.apache.xalan.internal.XalanConstants; import java.io.InputStream; import java.io.Reader; @@ -43,6 +44,7 @@ import javax.xml.transform.stax.StAXSource; import javax.xml.transform.stream.StreamSource; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; @@ -151,6 +153,22 @@ public final class Util { + e.getMessage()); } + try { + XMLSecurityManager securityManager = + (XMLSecurityManager)xsltc.getProperty(XalanConstants.SECURITY_MANAGER); + if (securityManager != null) { + for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) { + reader.setProperty(limit.apiProperty(), + securityManager.getLimitValueAsString(limit)); + } + if (securityManager.printEntityCountInfo()) { + reader.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES); + } + } + } catch (SAXException se) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + se.getMessage()); + } xsltc.setXMLReader(reader); }catch (SAXNotRecognizedException snre ) { throw new TransformerConfigurationException diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java index 832724ac586..1e8dcd98817 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java @@ -33,6 +33,7 @@ import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.utils.ObjectFactory; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; @@ -59,6 +60,7 @@ import org.w3c.dom.DOMStringList; import org.w3c.dom.ls.LSResourceResolver; + /** * Xerces implementation of DOMConfiguration that maintains a table of recognized parameters. * @@ -156,6 +158,9 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; + /** Property identifier: Security property manager. */ private static final String XML_SECURITY_PROPERTY_MANAGER = Constants.XML_SECURITY_PROPERTY_MANAGER; @@ -279,6 +284,7 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings JAXP_SCHEMA_LANGUAGE, DTD_VALIDATOR_FACTORY_PROPERTY, SCHEMA_DV_FACTORY, + SECURITY_MANAGER, XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); @@ -313,6 +319,8 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings fValidationManager = createValidationManager(); setProperty(VALIDATION_MANAGER, fValidationManager); + setProperty(SECURITY_MANAGER, new XMLSecurityManager(true)); + setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager()); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java index bcc2a796b08..579622a7270 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java @@ -174,8 +174,6 @@ public final class Constants { /** JAXP schemaSource language: when used internally may include DTD namespace (DOM) */ public static final String SCHEMA_LANGUAGE = "schemaLanguage"; - public static final String SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ; - /** JAXP Standard property prefix ("http://javax.xml.XMLConstants/property/"). */ public static final String JAXPAPI_PROPERTY_PREFIX = "http://javax.xml.XMLConstants/property/"; @@ -208,6 +206,107 @@ public final class Constants { */ public static final boolean IS_JDK8_OR_ABOVE = isJavaVersionAtLeast(8); + // + // Implementation limits: corresponding System Properties of the above + // API properties + // + /** + * JDK entity expansion limit; Note that the existing system property + * "entityExpansionLimit" with no prefix is still observed + */ + public static final String JDK_ENTITY_EXPANSION_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "entityExpansionLimit"; + + /** + * JDK element attribute limit; Note that the existing system property + * "elementAttributeLimit" with no prefix is still observed + */ + public static final String JDK_ELEMENT_ATTRIBUTE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "elementAttributeLimit"; + + /** + * JDK maxOccur limit; Note that the existing system property + * "maxOccurLimit" with no prefix is still observed + */ + public static final String JDK_MAX_OCCUR_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxOccurLimit"; + + /** + * JDK total entity size limit + */ + public static final String JDK_TOTAL_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "totalEntitySizeLimit"; + + /** + * JDK maximum general entity size limit + */ + public static final String JDK_GENEAL_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxGeneralEntitySizeLimit"; + /** + * JDK maximum parameter entity size limit + */ + public static final String JDK_PARAMETER_ENTITY_SIZE_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxParameterEntitySizeLimit"; + /** + * JDK maximum XML name limit + */ + public static final String JDK_XML_NAME_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "maxXMLNameLimit"; + /** + * JDK property to allow printing out information from the limit analyzer + */ + public static final String JDK_ENTITY_COUNT_INFO = + ORACLE_JAXP_PROPERTY_PREFIX + "getEntityCountInfo"; + + // + // Implementation limits: API properties + // + /** + * JDK entity expansion limit; Note that the existing system property + * "entityExpansionLimit" with no prefix is still observed + */ + public static final String SP_ENTITY_EXPANSION_LIMIT = "jdk.xml.entityExpansionLimit"; + + /** + * JDK element attribute limit; Note that the existing system property + * "elementAttributeLimit" with no prefix is still observed + */ + public static final String SP_ELEMENT_ATTRIBUTE_LIMIT = "jdk.xml.elementAttributeLimit"; + + /** + * JDK maxOccur limit; Note that the existing system property + * "maxOccurLimit" with no prefix is still observed + */ + public static final String SP_MAX_OCCUR_LIMIT = "jdk.xml.maxOccurLimit"; + + /** + * JDK total entity size limit + */ + public static final String SP_TOTAL_ENTITY_SIZE_LIMIT = "jdk.xml.totalEntitySizeLimit"; + + /** + * JDK maximum general entity size limit + */ + public static final String SP_GENEAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit"; + /** + * JDK maximum parameter entity size limit + */ + public static final String SP_PARAMETER_ENTITY_SIZE_LIMIT = "jdk.xml.maxParameterEntitySizeLimit"; + /** + * JDK maximum XML name limit + */ + public static final String SP_XML_NAME_LIMIT = "jdk.xml.maxXMLNameLimit"; + + //legacy System Properties + public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit"; + public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ; + public final static String MAX_OCCUR_LIMIT = "maxOccurLimit"; + + /** + * A string "yes" that can be used for properties such as getEntityCountInfo + */ + public static final String JDK_YES = "yes"; + // // DOM features // @@ -443,7 +542,7 @@ public final class Constants { public static final String LOCALE_PROPERTY = "locale"; /** property identifier: security manager. */ - protected static final String SECURITY_MANAGER = + public static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; @@ -511,9 +610,6 @@ public final class Constants { */ public final static String ATTRIBUTE_DECLARED = "ATTRIBUTE_DECLARED"; - public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit"; - - public final static String MAX_OCCUR_LIMIT = "maxOccurLimit"; /** * {@link org.w3c.dom.TypeInfo} associated with current element/attribute diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java index 0f5119d1fb1..8fbf9162409 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java @@ -25,6 +25,7 @@ package com.sun.org.apache.xerces.internal.impl; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.xml.internal.stream.StaxEntityResolverWrapper; import java.util.HashMap; @@ -50,12 +51,16 @@ public class PropertyManager { private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning"; + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; + /** Property identifier: Security property manager. */ private static final String XML_SECURITY_PROPERTY_MANAGER = Constants.XML_SECURITY_PROPERTY_MANAGER; HashMap supportedProps = new HashMap(); + private XMLSecurityManager fSecurityManager; private XMLSecurityPropertyManager fSecurityPropertyMgr; public static final int CONTEXT_READER = 1; @@ -82,6 +87,7 @@ public class PropertyManager { HashMap properties = propertyManager.getProperties(); supportedProps.putAll(properties); + fSecurityManager = (XMLSecurityManager)getProperty(SECURITY_MANAGER); fSecurityPropertyMgr = (XMLSecurityPropertyManager)getProperty(XML_SECURITY_PROPERTY_MANAGER); } @@ -124,6 +130,8 @@ public class PropertyManager { supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE, new Boolean(false)); supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE, new Boolean(false)); + fSecurityManager = new XMLSecurityManager(true); + supportedProps.put(SECURITY_MANAGER, fSecurityManager); fSecurityPropertyMgr = new XMLSecurityPropertyManager(); supportedProps.put(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); } @@ -142,6 +150,7 @@ public class PropertyManager { */ public boolean containsProperty(String property){ return supportedProps.containsKey(property) || + (fSecurityManager != null && fSecurityManager.getIndex(property) > -1) || (fSecurityPropertyMgr!=null && fSecurityPropertyMgr.getIndex(property) > -1) ; } @@ -169,12 +178,15 @@ public class PropertyManager { supportedProps.put( Constants.XERCES_PROPERTY_PREFIX + Constants.STAX_ENTITY_RESOLVER_PROPERTY , new StaxEntityResolverWrapper((XMLResolver)value)) ; } - int index = (fSecurityPropertyMgr != null) ? fSecurityPropertyMgr.getIndex(property) : -1; - if (index > -1) { - fSecurityPropertyMgr.setValue(index, - XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); - } else { - supportedProps.put(property, value); + //check if the property is managed by security manager + if (fSecurityManager == null || + !fSecurityManager.setLimit(property, XMLSecurityManager.State.APIPROPERTY, value)) { + //check if the property is managed by security property manager + if (fSecurityPropertyMgr == null || + !fSecurityPropertyMgr.setValue(property, XMLSecurityPropertyManager.State.APIPROPERTY, value)) { + //fall back to the existing property manager + supportedProps.put(property, value); + } } if(equivalentProperty != null){ diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java index dbfd46a5d5f..7a826dfcc97 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java @@ -108,6 +108,7 @@ import javax.xml.stream.events.XMLEvent; * @author Elena Litani, IBM * @author Michael Glavassevich, IBM * @author Sunitha Reddy, Sun Microsystems + * @version $Id: XML11NSDocumentScannerImpl.java,v 1.6 2010-11-01 04:39:40 joehw Exp $ */ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl { @@ -236,7 +237,8 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl { // attributes scanAttribute(fAttributes); - if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){ + if (fSecurityManager != null && (!fSecurityManager.isNoLimit(fElementAttributeLimit)) && + fAttributes.getLength() > fElementAttributeLimit){ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "ElementAttributeLimit", new Object[]{rawname, new Integer(fElementAttributeLimit) }, diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java index 6c5553c7979..18a9902d1b7 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java @@ -44,6 +44,8 @@ import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; +import com.sun.xml.internal.stream.Entity; /** * This class is responsible for scanning the declarations found @@ -66,7 +68,7 @@ import com.sun.org.apache.xerces.internal.impl.Constants; * @author Glenn Marcy, IBM * @author Eric Ye, IBM * - * @version $Id: XMLDTDScannerImpl.java,v 1.7 2007/09/26 12:52:40 ndw Exp $ + * @version $Id: XMLDTDScannerImpl.java,v 1.8 2010-11-01 04:39:41 joehw Exp $ */ public class XMLDTDScannerImpl extends XMLScanner @@ -1545,7 +1547,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { // internal entity if (systemId == null) { - scanEntityValue(fLiteral, fLiteral2); + scanEntityValue(name, isPEDecl, fLiteral, fLiteral2); // since we need it's value anyway, let's snag it so it doesn't get corrupted // if a new load takes place before we store the entity values fStringBuffer.clear(); @@ -1610,7 +1612,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { * the use of scanCharReferenceValue), and fStringBuffer2, anything in them * at the time of calling is lost. */ - protected final void scanEntityValue(XMLString value, + protected final void scanEntityValue(String entityName, boolean isPEDecl, XMLString value, XMLString nonNormalizedValue) throws IOException, XNIException { int quote = fEntityScanner.scanChar(); @@ -1622,10 +1624,20 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { XMLString literal = fString; XMLString literal2 = fString; + int countChar = 0; + if (fLimitAnalyzer == null && fSecurityManager != null) { + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); + fLimitAnalyzer.startEntity(entityName); + } + if (fEntityScanner.scanLiteral(quote, fString) != quote) { fStringBuffer.clear(); fStringBuffer2.clear(); do { + if (isPEDecl && fLimitAnalyzer != null) { + checkLimit("%" + entityName, fString.length + countChar); + } + countChar = 0; fStringBuffer.append(fString); fStringBuffer2.append(fString); if (fEntityScanner.skipChar('&')) { @@ -1685,6 +1697,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { } } else { + countChar++; int c = fEntityScanner.peekChar(); if (XMLChar.isHighSurrogate(c)) { scanSurrogates(fStringBuffer2); @@ -1708,9 +1721,17 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { fStringBuffer2.append(fString); literal = fStringBuffer; literal2 = fStringBuffer2; + } else { + if (isPEDecl) { + checkLimit("%" + entityName, literal); + } } value.setValues(literal); nonNormalizedValue.setValues(literal2); + if (fLimitAnalyzer != null) { + fLimitAnalyzer.endEntity(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, entityName); + } + if (!fEntityScanner.skipChar(quote)) { reportFatalError("CloseQuoteMissingInDecl", null); } @@ -2126,6 +2147,43 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler { //new SymbolTable()); } + /** + * Add the count of the content buffer and check if the accumulated + * value exceeds the limit + * @param entityName entity name + * @param buffer content buffer + */ + private void checkLimit(String entityName, XMLString buffer) { + checkLimit(entityName, buffer.length); + } + + /** + * Add the count and check limit + * @param entityName entity name + * @param len length of the buffer + */ + private void checkLimit(String entityName, int len) { + if (fLimitAnalyzer == null) { + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); + } + fLimitAnalyzer.addValue(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, entityName, len); + if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT)) { + fSecurityManager.debugPrint(); + reportFatalError("MaxEntitySizeLimit", new Object[]{entityName, + fLimitAnalyzer.getValue(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT), + fSecurityManager.getLimit(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT), + fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT)}); + } + if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT)) { + fSecurityManager.debugPrint(); + reportFatalError("TotalEntitySizeLimit", + new Object[]{fLimitAnalyzer.getTotalValue(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getLimit(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT)}); + } + + } + public DTDGrammar getGrammar(){ return nvGrammarInfo; } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java index e60c7781156..600527daa93 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java @@ -52,10 +52,12 @@ import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; -import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; +import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer; import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.State; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; -import com.sun.xml.internal.stream.Entity; import javax.xml.XMLConstants; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.events.XMLEvent; @@ -213,11 +215,8 @@ public class XMLDocumentFragmentScannerImpl }; private static final char [] cdata = {'[','C','D','A','T','A','['}; - private static final char [] endTag = {'<','/'}; - - //this variable is also used by XMLDocumentScannerImpl in the same package static final char [] xmlDecl = {'<','?','x','m','l'}; - + private static final char [] endTag = {'<','/'}; // debugging /** Debug scanner state. */ @@ -316,6 +315,7 @@ public class XMLDocumentFragmentScannerImpl protected String fDeclaredEncoding = null; /** Xerces Feature: Disallow doctype declaration. */ protected boolean fDisallowDoctype = false; + /** * comma-delimited list of protocols that are allowed for the purpose * of accessing external dtd or entity references @@ -384,7 +384,6 @@ public class XMLDocumentFragmentScannerImpl protected boolean foundBuiltInRefs = false; - protected XMLSecurityManager fSecurityManager = null; //skip element algorithm static final short MAX_DEPTH_LIMIT = 5 ; @@ -572,10 +571,11 @@ public class XMLDocumentFragmentScannerImpl fReportCdataEvent = componentManager.getFeature(Constants.STAX_REPORT_CDATA_EVENT, true); fSecurityManager = (XMLSecurityManager)componentManager.getProperty(Constants.SECURITY_MANAGER, null); + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); + fElementAttributeLimit = (fSecurityManager != null)? fSecurityManager.getLimit(XMLSecurityManager.Limit.ELEMENT_ATTRIBUTE_LIMIT):0; - fNotifyBuiltInRefs = componentManager.getFeature(NOTIFY_BUILTIN_REFS, false); Object resolver = componentManager.getProperty(ENTITY_RESOLVER, null); @@ -600,9 +600,6 @@ public class XMLDocumentFragmentScannerImpl //xxx: external entities are supported in Xerces // it would be good to define feature for this case fSupportExternalEntities = true; - fSupportExternalEntities = true; - fSupportExternalEntities = true; - fSupportExternalEntities = true; fReplaceEntityReferences = true; fIsCoalesce = false; @@ -673,6 +670,9 @@ public class XMLDocumentFragmentScannerImpl XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) propertyManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); + + fSecurityManager = (XMLSecurityManager)propertyManager.getProperty(Constants.SECURITY_MANAGER); + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); } // reset(XMLComponentManager) /** @@ -958,7 +958,6 @@ public class XMLDocumentFragmentScannerImpl // scan decl super.scanXMLDeclOrTextDecl(scanningTextDecl, fStrings); - fMarkupDepth--; // pseudo-attribute values @@ -1325,7 +1324,8 @@ public class XMLDocumentFragmentScannerImpl fAddDefaultAttr = true; do { scanAttribute(fAttributes); - if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){ + if (fSecurityManager != null && !fSecurityManager.isNoLimit(fElementAttributeLimit) && + fAttributes.getLength() > fElementAttributeLimit){ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "ElementAttributeLimit", new Object[]{rawname, new Integer(fAttributes.getLength()) }, @@ -2039,6 +2039,13 @@ public class XMLDocumentFragmentScannerImpl } // getDriverName():String + /** + * Check the protocol used in the systemId against allowed protocols + * + * @param systemId the Id of the URI + * @param allowedProtocols a list of allowed protocols separated by comma + * @return the name of the protocol if rejected, null otherwise + */ String checkAccess(String systemId, String allowedProtocols) throws IOException { String baseSystemId = fEntityScanner.getBaseSystemId(); String expandedSystemId = fEntityManager.expandSystemId(systemId, baseSystemId,fStrictURI); @@ -2836,6 +2843,8 @@ public class XMLDocumentFragmentScannerImpl if(DEBUG){ System.out.println("NOT USING THE BUFFER, STRING = " + fTempString.toString()); } + //check limit before returning event + checkLimit(fContentBuffer); if(dtdGrammarUtil!= null && dtdGrammarUtil.isIgnorableWhiteSpace(fContentBuffer)){ if(DEBUG)System.out.println("Return SPACE EVENT"); return XMLEvent.SPACE; @@ -2934,6 +2943,8 @@ public class XMLDocumentFragmentScannerImpl fLastSectionWasCharacterData = true ; continue; }else{ + //check limit before returning event + checkLimit(fContentBuffer); if(dtdGrammarUtil!= null && dtdGrammarUtil.isIgnorableWhiteSpace(fContentBuffer)){ if(DEBUG)System.out.println("Return SPACE EVENT"); return XMLEvent.SPACE; @@ -3144,6 +3155,30 @@ public class XMLDocumentFragmentScannerImpl } //while loop }//next + /** + * Add the count of the content buffer and check if the accumulated + * value exceeds the limit + * @param buffer content buffer + */ + protected void checkLimit(XMLStringBuffer buffer) { + if (fLimitAnalyzer.isTracking(fCurrentEntityName)) { + fLimitAnalyzer.addValue(Limit.GENEAL_ENTITY_SIZE_LIMIT, fCurrentEntityName, buffer.length); + if (fSecurityManager.isOverLimit(Limit.GENEAL_ENTITY_SIZE_LIMIT)) { + fSecurityManager.debugPrint(); + reportFatalError("MaxEntitySizeLimit", new Object[]{fCurrentEntityName, + fLimitAnalyzer.getValue(Limit.GENEAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getLimit(Limit.GENEAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getStateLiteral(Limit.GENEAL_ENTITY_SIZE_LIMIT)}); + } + if (fSecurityManager.isOverLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT)) { + fSecurityManager.debugPrint(); + reportFatalError("TotalEntitySizeLimit", + new Object[]{fLimitAnalyzer.getTotalValue(Limit.TOTAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getStateLiteral(Limit.TOTAL_ENTITY_SIZE_LIMIT)}); + } + } + } // // Protected methods diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java index ac25ae0ccde..59f3aa00e2d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java @@ -30,8 +30,9 @@ import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.util.*; import com.sun.org.apache.xerces.internal.util.URI; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; -import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; +import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer; import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.XNIException; @@ -174,7 +175,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { /** access external dtd: file protocol */ static final String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT; - // recognized features and properties /** Recognized features. */ @@ -307,6 +307,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { /** used to restrict external access */ protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT; + // settings /** @@ -324,10 +325,13 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { */ protected int fBufferSize = DEFAULT_BUFFER_SIZE; - // stores defaults for entity expansion limit if it has - // been set on the configuration. + /** Security Manager */ protected XMLSecurityManager fSecurityManager = null; + protected XMLLimitAnalyzer fLimitAnalyzer = null; + + protected int entityExpansionIndex; + /** * True if the document entity is standalone. This should really * only be set by the document source (e.g. XMLDocumentScanner). @@ -352,10 +356,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { /** XML 1.1 entity scanner. */ protected XMLEntityScanner fXML11EntityScanner; - /** entity expansion limit (contains useful data if and only if - fSecurityManager is non-null) */ - protected int fEntityExpansionLimit = 0; - /** count of entities expanded: */ protected int fEntityExpansionCount = 0; @@ -833,6 +833,9 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { fCurrentEntity.setEncodingExternallySpecified(encodingExternallySpecified); fEntityScanner.setCurrentEntity(fCurrentEntity); fResourceIdentifier.setValues(publicId, literalSystemId, baseSystemId, expandedSystemId); + if (fLimitAnalyzer != null) { + fLimitAnalyzer.startEntity(name); + } return encoding; } //setupCurrentEntity(String, XMLInputSource, boolean, boolean): String @@ -1294,10 +1297,13 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { //expansions exceeds the entity expansion limit, parser will throw fatal error. // Note that this represents the nesting level of open entities. fEntityExpansionCount++; - if( fSecurityManager != null && fEntityExpansionCount > fEntityExpansionLimit ){ - fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, - "EntityExpansionLimitExceeded", - new Object[]{new Integer(fEntityExpansionLimit) }, + if(fLimitAnalyzer != null) { + fLimitAnalyzer.addValue(entityExpansionIndex, name, 1); + } + if( fSecurityManager != null && fSecurityManager.isOverLimit(entityExpansionIndex)){ + fSecurityManager.debugPrint(); + fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,"EntityExpansionLimitExceeded", + new Object[]{fSecurityManager.getLimitValueByIndex(entityExpansionIndex)}, XMLErrorReporter.SEVERITY_FATAL_ERROR ); // is there anything better to do than reset the counter? // at least one can envision debugging applications where this might @@ -1361,6 +1367,12 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { if(fCurrentEntity != null){ //close the reader try{ + if (fLimitAnalyzer != null) { + fLimitAnalyzer.endEntity(XMLSecurityManager.Limit.GENEAL_ENTITY_SIZE_LIMIT, fCurrentEntity.name); + if (fCurrentEntity.name.equals("[xml]")) { + fSecurityManager.debugPrint(); + } + } fCurrentEntity.close(); }catch(IOException ex){ throw new XNIException(ex); @@ -1426,6 +1438,9 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) propertyManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); + fSecurityManager = (XMLSecurityManager)propertyManager.getProperty(SECURITY_MANAGER); + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); + // initialize state //fStandalone = false; fEntities.clear(); @@ -1486,6 +1501,8 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { fStaxEntityResolver = (StaxEntityResolverWrapper)componentManager.getProperty(STAX_ENTITY_RESOLVER, null); fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER, null); fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER, null); + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); + entityExpansionIndex = fSecurityManager.getIndex(Constants.JDK_ENTITY_EXPANSION_LIMIT); // JAXP 1.5 feature XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER, null); @@ -1506,9 +1523,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { // a class acting as a component manager but not // implementing that interface for whatever reason. public void reset() { - fEntityExpansionLimit = (fSecurityManager != null)? - fSecurityManager.getLimit(XMLSecurityManager.Limit.ENTITY_EXPANSION_LIMIT):0; - // initialize state fStandalone = false; @@ -1645,9 +1659,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() && propertyId.endsWith(Constants.SECURITY_MANAGER_PROPERTY)) { fSecurityManager = (XMLSecurityManager)value; - fEntityExpansionLimit = (fSecurityManager != null)? - fSecurityManager.getLimit(XMLSecurityManager.Limit.ENTITY_EXPANSION_LIMIT):0; - + fLimitAnalyzer = fSecurityManager.getLimitAnalyzer(); } } @@ -1656,9 +1668,8 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { { XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)value; fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); + } } - } - /** * Returns a list of property identifiers that are recognized by * this component. This method may return null if no properties diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java index b0461eb9138..464511c368c 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java @@ -58,6 +58,7 @@ import javax.xml.stream.events.XMLEvent; * @author Neeraj Bajaj, Sun Microsystems * @author Venugopal Rao K, Sun Microsystems * @author Elena Litani, IBM + * @version $Id: XMLNSDocumentScannerImpl.java,v 1.11 2010-11-01 04:39:41 joehw Exp $ */ public class XMLNSDocumentScannerImpl extends XMLDocumentScannerImpl { @@ -251,7 +252,8 @@ public class XMLNSDocumentScannerImpl do { scanAttribute(fAttributes); - if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){ + if (fSecurityManager != null && (!fSecurityManager.isNoLimit(fElementAttributeLimit)) && + fAttributes.getLength() > fElementAttributeLimit){ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "ElementAttributeLimit", new Object[]{rawname, new Integer(fAttributes.getLength()) }, diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java index 9fc489b3e02..70de7869e78 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java @@ -32,6 +32,8 @@ import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl; import com.sun.org.apache.xerces.internal.util.XMLStringBuffer; +import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.XMLAttributes; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; @@ -106,6 +108,9 @@ public abstract class XMLScanner protected static final String ENTITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; + // debugging /** Debug attribute normalization. */ @@ -159,6 +164,12 @@ public abstract class XMLScanner /** xxx this should be available from EntityManager Entity storage */ protected XMLEntityStorage fEntityStore = null ; + /** Security manager. */ + protected XMLSecurityManager fSecurityManager = null; + + /** Limit analyzer. */ + protected XMLLimitAnalyzer fLimitAnalyzer = null; + // protected data /** event type */ @@ -256,6 +267,7 @@ public abstract class XMLScanner fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE); fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER); fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER); + fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER); //this step is extra because we have separated the storage of entity fEntityStore = fEntityManager.getEntityStore() ; @@ -293,6 +305,10 @@ public abstract class XMLScanner fEntityManager = (XMLEntityManager)value; } } + + if (propertyId.equals(SECURITY_MANAGER)) { + fSecurityManager = (XMLSecurityManager)value; + } /*else if(propertyId.equals(Constants.STAX_PROPERTIES)){ fStaxProperties = (HashMap)value; //TODO::discuss with neeraj what are his thoughts on passing properties. @@ -352,6 +368,8 @@ public abstract class XMLScanner fEntityManager = (XMLEntityManager)propertyManager.getProperty(ENTITY_MANAGER); fEntityStore = fEntityManager.getEntityStore() ; fEntityScanner = (XMLEntityScanner)fEntityManager.getEntityScanner() ; + fSecurityManager = (XMLSecurityManager)propertyManager.getProperty(SECURITY_MANAGER); + //fEntityManager.reset(); // DTD preparsing defaults: fValidation = false; @@ -510,8 +528,9 @@ public abstract class XMLScanner sawSpace = fEntityScanner.skipSpaces(); } // restore original literal value - if(currLiteral) + if(currLiteral) { currEnt.literal = true; + } // REVISIT: should we remove this error reporting? if (scanningTextDecl && state != STATE_DONE) { reportFatalError("MorePseudoAttributes", null); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties index d0db58ba98d..200b904b105 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties @@ -293,8 +293,10 @@ InvalidCharInLiteral=InvalidCharInLiteral -#Application can set the limit of number of entities that should be expanded by the parser. -EntityExpansionLimitExceeded=The parser has encountered more than \"{0}\" entity expansions in this document; this is the limit imposed by the application. +# Implementation limits + EntityExpansionLimitExceeded=JAXP00010001: The parser has encountered more than \"{0}\" entity expansions in this document; this is the limit imposed by the JDK. + ElementAttributeLimit=JAXP00010002: Element \"{0}\" has more than \"{1}\" attributes, \"{1}\" is the limit imposed by the JDK. + MaxEntitySizeLimit=JAXP00010003: The length of entity \"{0}\" is \"{1}\" that exceeds the \"{2}\" limit set by \"{3}\". + TotalEntitySizeLimit=JAXP00010004: The accumulated size \"{0}\" of entities exceeded the \"{1}\" limit set by \"{2}\". + MaxXMLNameLimit=JAXP00010005: The name \"{0}\" exceeded the \"{1}\" limit set by \"{2}\". -# Application can set the limit of number of attributes of entity that should be expanded by the parser. -ElementAttributeLimit= Element \"{0}\" has more than \"{1}\" attributes, \"{1}\" is the limit imposed by the application. diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java index e3c24dc8938..6aa06b8828d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java @@ -109,7 +109,8 @@ public class CMNodeFactory { } public void nodeCountCheck(){ - if( fSecurityManager != null && nodeCount++ > maxNodeLimit){ + if( fSecurityManager != null && !fSecurityManager.isNoLimit(maxNodeLimit) && + nodeCount++ > maxNodeLimit){ if(DEBUG){ System.out.println("nodeCount = " + nodeCount ) ; System.out.println("nodeLimit = " + maxNodeLimit ) ; diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java index 34eaa8457bc..f9eea6a4dc4 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java @@ -1196,7 +1196,7 @@ public class XSAttributeChecker { //Revisit :: IMO this is not right place to check // maxOccurNodeLimit. int maxOccurNodeLimit = fSchemaHandler.fSecureProcessing.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT); - if (max > maxOccurNodeLimit) { + if (max > maxOccurNodeLimit && !fSchemaHandler.fSecureProcessing.isNoLimit(maxOccurNodeLimit)) { reportSchemaFatalError("maxOccurLimit", new Object[] {new Integer(maxOccurNodeLimit)}, element); // reset max values in case processing continues on error diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java index f19f81dbef8..e73c12d24da 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java @@ -46,7 +46,6 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; -import javax.xml.XMLConstants; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.xml.sax.EntityResolver; @@ -125,6 +124,7 @@ public class DocumentBuilderImpl extends DocumentBuilder /** Initial EntityResolver */ private final EntityResolver fInitEntityResolver; + private XMLSecurityManager fSecurityManager; private XMLSecurityPropertyManager fSecurityPropertyMgr; DocumentBuilderImpl(DocumentBuilderFactoryImpl dbf, Hashtable dbfAttrs, Hashtable features) @@ -173,10 +173,10 @@ public class DocumentBuilderImpl extends DocumentBuilder fSecurityPropertyMgr = new XMLSecurityPropertyManager(); domParser.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); - // If the secure processing feature is on set a security manager. - if (secureProcessing) { - domParser.setProperty(SECURITY_MANAGER, new XMLSecurityManager()); + fSecurityManager = new XMLSecurityManager(secureProcessing); + domParser.setProperty(SECURITY_MANAGER, fSecurityManager); + if (secureProcessing) { /** * If secure processing is explicitly set on the factory, the * access properties will be set unless the corresponding @@ -250,9 +250,9 @@ public class DocumentBuilderImpl extends DocumentBuilder String feature = (String) entry.getKey(); boolean value = ((Boolean) entry.getValue()).booleanValue(); domParser.setFeature(feature, value); - } } } + } /** * Set any DocumentBuilderFactory attributes of our underlying DOMParser @@ -303,14 +303,17 @@ public class DocumentBuilderImpl extends DocumentBuilder } } } else { - int index = fSecurityPropertyMgr.getIndex(name); - if (index > -1) { - fSecurityPropertyMgr.setValue(index, - XMLSecurityPropertyManager.State.APIPROPERTY, (String)val); - } else { - // Let Xerces code handle the property - domParser.setProperty(name, val); - } + //check if the property is managed by security manager + if (fSecurityManager == null || + !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, val)) { + //check if the property is managed by security property manager + if (fSecurityPropertyMgr == null || + !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, val)) { + //fall back to the existing property manager + domParser.setProperty(name, val); + } + } + } } } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java index a60d1e5085d..d95b1ca8851 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java @@ -112,7 +112,8 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser /** Initial EntityResolver */ private final EntityResolver fInitEntityResolver; - private XMLSecurityPropertyManager fSecurityPropertyMgr; + private final XMLSecurityManager fSecurityManager; + private final XMLSecurityPropertyManager fSecurityPropertyMgr; /** * Create a SAX parser with the associated features @@ -130,8 +131,10 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser SAXParserImpl(SAXParserFactoryImpl spf, Hashtable features, boolean secureProcessing) throws SAXException { + fSecurityManager = new XMLSecurityManager(secureProcessing); + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); // Instantiate a SAXParser directly and not through SAX so that we use the right ClassLoader - xmlReader = new JAXPSAXParser(this); + xmlReader = new JAXPSAXParser(this, fSecurityPropertyMgr, fSecurityManager); // JAXP "namespaceAware" == SAX Namespaces feature // Note: there is a compatibility problem here with default values: @@ -150,12 +153,11 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser xmlReader.setFeature0(XINCLUDE_FEATURE, true); } - fSecurityPropertyMgr = new XMLSecurityPropertyManager(); xmlReader.setProperty0(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); - // If the secure processing feature is on set a security manager. + xmlReader.setProperty0(SECURITY_MANAGER, fSecurityManager); + if (secureProcessing) { - xmlReader.setProperty0(SECURITY_MANAGER, new XMLSecurityManager()); /** * By default, secure processing is set, no external access is allowed. * However, we need to check if it is actively set on the factory since we @@ -163,6 +165,7 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser * the default value */ if (features != null) { + Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING); if (temp != null) { boolean value = ((Boolean) temp).booleanValue(); @@ -397,14 +400,43 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser private final HashMap fInitFeatures = new HashMap(); private final HashMap fInitProperties = new HashMap(); private final SAXParserImpl fSAXParser; + private XMLSecurityManager fSecurityManager; + private XMLSecurityPropertyManager fSecurityPropertyMgr; public JAXPSAXParser() { - this(null); + this(null, null, null); } - JAXPSAXParser(SAXParserImpl saxParser) { + JAXPSAXParser(SAXParserImpl saxParser, XMLSecurityPropertyManager securityPropertyMgr, + XMLSecurityManager securityManager) { super(); fSAXParser = saxParser; + fSecurityManager = securityManager; + fSecurityPropertyMgr = securityPropertyMgr; + /** + * This class may be used directly. So initialize the security manager if + * it is null. + */ + if (fSecurityManager == null) { + fSecurityManager = new XMLSecurityManager(true); + try { + super.setProperty(SECURITY_MANAGER, fSecurityManager); + } catch (SAXException e) { + throw new UnsupportedOperationException( + SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), + "property-not-recognized", new Object [] {SECURITY_MANAGER}), e); + } + } + if (fSecurityPropertyMgr == null) { + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + try { + super.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + } catch (SAXException e) { + throw new UnsupportedOperationException( + SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), + "property-not-recognized", new Object [] {SECURITY_MANAGER}), e); + } + } } /** @@ -420,7 +452,8 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser } if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { try { - setProperty(SECURITY_MANAGER, value ? new XMLSecurityManager() : null); + fSecurityManager.setSecureProcessing(value); + setProperty(SECURITY_MANAGER, fSecurityManager); } catch (SAXNotRecognizedException exc) { // If the property is not supported @@ -456,13 +489,7 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser throw new NullPointerException(); } if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { - try { - return (super.getProperty(SECURITY_MANAGER) != null); - } - // If the property is not supported the value must be false. - catch (SAXException exc) { - return false; - } + return fSecurityManager.isSecureProcessing(); } return super.getFeature(name); } @@ -541,17 +568,21 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser if (fSAXParser != null && fSAXParser.fSchemaValidator != null) { setSchemaValidatorProperty(name, value); } - /** Check to see if the property is managed by the property manager **/ - int index = fSAXParser.fSecurityPropertyMgr.getIndex(name); - if (index > -1) { - fSAXParser.fSecurityPropertyMgr.setValue(index, - XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); - } else { - if (!fInitProperties.containsKey(name)) { - fInitProperties.put(name, super.getProperty(name)); + + //check if the property is managed by security manager + if (fSecurityManager == null || + !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) { + //check if the property is managed by security property manager + if (fSecurityPropertyMgr == null || + !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, value)) { + //fall back to the existing property manager + if (!fInitProperties.containsKey(name)) { + fInitProperties.put(name, super.getProperty(name)); + } + super.setProperty(name, value); } - super.setProperty(name, value); } + } public synchronized Object getProperty(String name) @@ -564,9 +595,18 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser // JAXP 1.2 support return fSAXParser.schemaLanguage; } - int index = fSAXParser.fSecurityPropertyMgr.getIndex(name); - if (index > -1) { - return fSAXParser.fSecurityPropertyMgr.getValueByIndex(index); + + /** Check to see if the property is managed by the security manager **/ + String propertyValue = (fSecurityManager != null) ? + fSecurityManager.getLimitAsString(name) : null; + if (propertyValue != null) { + return propertyValue; + } else { + propertyValue = (fSecurityPropertyMgr != null) ? + fSecurityPropertyMgr.getValue(name) : null; + if (propertyValue != null) { + return propertyValue; + } } return super.getProperty(name); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java index f398e037d18..5af27e26fc1 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java @@ -26,6 +26,7 @@ package com.sun.org.apache.xerces.internal.jaxp.validation; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import java.io.IOException; import javax.xml.transform.Result; @@ -73,6 +74,19 @@ public final class StAXValidatorHelper implements ValidatorHelper { SAXTransformerFactory tf = fComponentManager.getFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ? (SAXTransformerFactory)SAXTransformerFactory.newInstance() : (SAXTransformerFactory) TransformerFactory.newInstance(DEFAULT_TRANSFORMER_IMPL, StAXValidatorHelper.class.getClassLoader()); + XMLSecurityManager securityManager = (XMLSecurityManager)fComponentManager.getProperty(Constants.SECURITY_MANAGER); + if (securityManager != null) { + for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) { + if (securityManager.isSet(limit.ordinal())){ + tf.setAttribute(limit.apiProperty(), + securityManager.getLimitValueAsString(limit)); + } + } + if (securityManager.printEntityCountInfo()) { + tf.setAttribute(Constants.JDK_ENTITY_COUNT_INFO, "yes"); + } + } + identityTransformer1 = tf.newTransformer(); identityTransformer2 = tf.newTransformerHandler(); } catch (TransformerConfigurationException e) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java index bb1694c5160..d6c04fd984a 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java @@ -189,6 +189,8 @@ final class StreamValidatorHelper implements ValidatorHelper { config.setDTDContentModelHandler(null); config.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, fComponentManager.getProperty(Constants.XML_SECURITY_PROPERTY_MANAGER)); + config.setProperty(Constants.SECURITY_MANAGER, + fComponentManager.getProperty(Constants.SECURITY_MANAGER)); fConfiguration = new SoftReference(config); return config; } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java index 3a59da745ed..34eba4c4791 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java @@ -107,7 +107,7 @@ public final class XMLSchemaFactory extends SchemaFactory { /** The ErrorHandlerWrapper */ private ErrorHandlerWrapper fErrorHandlerWrapper; - /** The XMLSecurityManager. */ + /** The SecurityManager. */ private XMLSecurityManager fSecurityManager; /** The Security property manager. */ @@ -141,7 +141,7 @@ public final class XMLSchemaFactory extends SchemaFactory { fXMLSchemaLoader.setErrorHandler(fErrorHandlerWrapper); // Enable secure processing feature by default - fSecurityManager = new XMLSecurityManager(); + fSecurityManager = new XMLSecurityManager(true); fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); fSecurityPropertyMgr = new XMLSecurityPropertyManager(); @@ -301,7 +301,7 @@ public final class XMLSchemaFactory extends SchemaFactory { "FeatureNameNull", null)); } if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { - return (fSecurityManager != null); + return (fSecurityManager != null && fSecurityManager.isSecureProcessing()); } try { return fXMLSchemaLoader.getFeature(name); @@ -365,17 +365,15 @@ public final class XMLSchemaFactory extends SchemaFactory { SAXMessageFormatter.formatMessage(null, "jaxp-secureprocessing-feature", null)); } - if (value) { - fSecurityManager = new XMLSecurityManager(); + fSecurityManager.setSecureProcessing(value); + if (value) { if (Constants.IS_JDK8_OR_ABOVE) { fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); } - } else { - fSecurityManager = null; } fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); @@ -420,12 +418,15 @@ public final class XMLSchemaFactory extends SchemaFactory { "property-not-supported", new Object [] {name})); } try { - int index = fSecurityPropertyMgr.getIndex(name); - if (index > -1) { - fSecurityPropertyMgr.setValue(index, - XMLSecurityPropertyManager.State.APIPROPERTY, (String)object); - } else { - fXMLSchemaLoader.setProperty(name, object); + //check if the property is managed by security manager + if (fSecurityManager == null || + !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, object)) { + //check if the property is managed by security property manager + if (fSecurityPropertyMgr == null || + !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, object)) { + //fall back to the existing property manager + fXMLSchemaLoader.setProperty(name, object); + } } } catch (XMLConfigurationException e) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java index 8b006fa7361..dcbbabd4d4a 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java @@ -181,7 +181,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin private final HashMap fInitProperties = new HashMap(); /** Stores the initial security manager. */ - private final XMLSecurityManager fInitSecurityManager; + private XMLSecurityManager fInitSecurityManager; /** Stores the initial security property manager. */ private final XMLSecurityPropertyManager fSecurityPropertyMgr; @@ -221,12 +221,6 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin fComponents.put(ENTITY_RESOLVER, null); fComponents.put(ERROR_HANDLER, null); - if (System.getSecurityManager() != null) { - _isSecureMode = true; - setProperty(SECURITY_MANAGER, new XMLSecurityManager()); - } else { - fComponents.put(SECURITY_MANAGER, null); - } fComponents.put(SYMBOL_TABLE, new SymbolTable()); // setup grammar pool @@ -241,15 +235,21 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin addRecognizedParamsAndSetDefaults(fErrorReporter, grammarContainer); addRecognizedParamsAndSetDefaults(fSchemaValidator, grammarContainer); - // if the secure processing feature is set to true, add a security manager to the configuration - Boolean secureProcessing = grammarContainer.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); - if (Boolean.TRUE.equals(secureProcessing)) { - fInitSecurityManager = new XMLSecurityManager(); + boolean secureProcessing = grammarContainer.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); + if (System.getSecurityManager() != null) { + _isSecureMode = true; + secureProcessing = true; } - else { - fInitSecurityManager = null; + + fInitSecurityManager = (XMLSecurityManager) + grammarContainer.getProperty(SECURITY_MANAGER); + if (fInitSecurityManager != null ) { + fInitSecurityManager.setSecureProcessing(secureProcessing); + } else { + fInitSecurityManager = new XMLSecurityManager(secureProcessing); } - fComponents.put(SECURITY_MANAGER, fInitSecurityManager); + + setProperty(SECURITY_MANAGER, fInitSecurityManager); //pass on properties set on SchemaFactory fSecurityPropertyMgr = (XMLSecurityPropertyManager) @@ -281,7 +281,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin return FeatureState.is(fUseGrammarPoolOnly); } else if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(featureId)) { - return FeatureState.is(getProperty(SECURITY_MANAGER) != null); + return FeatureState.is(fInitSecurityManager.isSecureProcessing()); } else if (SCHEMA_ELEMENT_DEFAULT.equals(featureId)) { return FeatureState.is(true); //pre-condition: VALIDATION and SCHEMA_VALIDATION are always true @@ -311,7 +311,9 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin if (_isSecureMode && !value) { throw new XMLConfigurationException(Status.NOT_ALLOWED, XMLConstants.FEATURE_SECURE_PROCESSING); } - setProperty(SECURITY_MANAGER, value ? new XMLSecurityManager() : null); + + fInitSecurityManager.setSecureProcessing(value); + setProperty(SECURITY_MANAGER, fInitSecurityManager); if (value && Constants.IS_JDK8_OR_ABOVE) { fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, @@ -390,10 +392,19 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin fComponents.put(propertyId, value); return; } - if (!fInitProperties.containsKey(propertyId)) { - fInitProperties.put(propertyId, super.getProperty(propertyId)); + //check if the property is managed by security manager + if (fInitSecurityManager == null || + !fInitSecurityManager.setLimit(propertyId, XMLSecurityManager.State.APIPROPERTY, value)) { + //check if the property is managed by security property manager + if (fSecurityPropertyMgr == null || + !fSecurityPropertyMgr.setValue(propertyId, XMLSecurityPropertyManager.State.APIPROPERTY, value)) { + //fall back to the existing property manager + if (!fInitProperties.containsKey(propertyId)) { + fInitProperties.put(propertyId, super.getProperty(propertyId)); + } + super.setProperty(propertyId, value); + } } - super.setProperty(propertyId, value); } /** diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java index cf9e9a79f92..8432b54541e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java @@ -22,6 +22,7 @@ package com.sun.org.apache.xerces.internal.parsers; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; @@ -76,6 +77,8 @@ public class SAXParser XMLGRAMMAR_POOL, }; + XMLSecurityManager securityManager; + XMLSecurityPropertyManager securityPropertyManager; // // Constructors // @@ -129,18 +132,30 @@ public class SAXParser */ public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { - XMLSecurityPropertyManager spm = new XMLSecurityPropertyManager(); - int index = spm.getIndex(name); + if (securityPropertyManager == null) { + securityPropertyManager = new XMLSecurityPropertyManager(); + } + int index = securityPropertyManager.getIndex(name); if (index > -1) { /** * this is a direct call to this parser, not a subclass since * internally the support of this property is done through * XMLSecurityPropertyManager */ - spm.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); - super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, spm); + securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); + super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); } else { - super.setProperty(name, value); + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + } + + //check if the property is managed by security manager + if (securityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) { + super.setProperty(Constants.SECURITY_MANAGER, securityManager); + } else { + super.setProperty(name, value); + } + } } } // class SAXParser diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java index 53d4ab4a0ea..65c85d164ca 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java @@ -44,6 +44,7 @@ import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; * * @author Neil Graham, IBM * + * @version $Id: SecurityConfiguration.java,v 1.6 2010-11-01 04:40:09 joehw Exp $ */ public class SecurityConfiguration extends XIncludeAwareParserConfiguration { @@ -106,8 +107,8 @@ public class SecurityConfiguration extends XIncludeAwareParserConfiguration XMLComponentManager parentSettings) { super(symbolTable, grammarPool, parentSettings); - // create the XMLSecurityManager property: - setProperty(SECURITY_MANAGER_PROPERTY, new XMLSecurityManager()); + // create the SecurityManager property: + setProperty(SECURITY_MANAGER_PROPERTY, new XMLSecurityManager(true)); } // (SymbolTable,XMLGrammarPool) } // class SecurityConfiguration diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java index 62dec4a54e7..3f22807e37e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java @@ -20,6 +20,12 @@ package com.sun.org.apache.xerces.internal.parsers; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; +import javax.xml.XMLConstants; + import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl; import com.sun.org.apache.xerces.internal.impl.XML11DocumentScannerImpl; @@ -46,6 +52,7 @@ import com.sun.org.apache.xerces.internal.util.FeatureState; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; @@ -63,11 +70,6 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Locale; -import javax.xml.XMLConstants; /** * This class is the configuration used to parse XML 1.0 and XML 1.1 documents. @@ -278,6 +280,8 @@ public class XML11Configuration extends ParserConfigurationSettings private static final String XML_SECURITY_PROPERTY_MANAGER = Constants.XML_SECURITY_PROPERTY_MANAGER; + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; // debugging @@ -483,7 +487,6 @@ public class XML11Configuration extends ParserConfigurationSettings PARSER_SETTINGS, XMLConstants.FEATURE_SECURE_PROCESSING }; - addRecognizedFeatures(recognizedFeatures); // set state for default features fFeatures.put(VALIDATION, Boolean.FALSE); @@ -531,6 +534,7 @@ public class XML11Configuration extends ParserConfigurationSettings SCHEMA_NONS_LOCATION, LOCALE, SCHEMA_DV_FACTORY, + SECURITY_MANAGER, XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); @@ -581,6 +585,8 @@ public class XML11Configuration extends ParserConfigurationSettings fProperties.put(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager()); + fProperties.put(SECURITY_MANAGER, new XMLSecurityManager(true)); + // add message formatters if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { XMLMessageFormatter xmft = new XMLMessageFormatter(); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java new file mode 100644 index 00000000000..41724b6c50d --- /dev/null +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java @@ -0,0 +1,236 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package com.sun.org.apache.xerces.internal.utils; + +import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit; +import java.util.Formatter; +import java.util.HashMap; +import java.util.Map; + +/** + * A helper for analyzing entity expansion limits + * + * @author Joe Wang Oracle Corp. + * + */ +public final class XMLLimitAnalyzer { + + /** + * Map old property names with the new ones + */ + public static enum NameMap { + ENTITY_EXPANSION_LIMIT(Constants.SP_ENTITY_EXPANSION_LIMIT, Constants.ENTITY_EXPANSION_LIMIT), + MAX_OCCUR_NODE_LIMIT(Constants.SP_MAX_OCCUR_LIMIT, Constants.MAX_OCCUR_LIMIT), + ELEMENT_ATTRIBUTE_LIMIT(Constants.SP_ELEMENT_ATTRIBUTE_LIMIT, Constants.ELEMENT_ATTRIBUTE_LIMIT); + + final String newName; + final String oldName; + + NameMap(String newName, String oldName) { + this.newName = newName; + this.oldName = oldName; + } + + String getOldName(String newName) { + if (newName.equals(this.newName)) { + return oldName; + } + return null; + } + } + + private XMLSecurityManager securityManager; + /** + * Max value accumulated for each property + */ + private final int[] values; + /** + * Names of the entities corresponding to their max values + */ + private final String[] names; + /** + * Total value of accumulated entities + */ + private final int[] totalValue; + + /** + * Maintain values of the top 10 elements in the process of parsing + */ + private final Map[] caches; + + private String entityStart, entityEnd; + /** + * Default constructor. Establishes default values for known security + * vulnerabilities. + */ + public XMLLimitAnalyzer(XMLSecurityManager securityManager) { + this.securityManager = securityManager; + values = new int[Limit.values().length]; + totalValue = new int[Limit.values().length]; + names = new String[Limit.values().length]; + caches = new Map[Limit.values().length]; + } + + /** + * Add the value to the current max count for the specified property + * To find the max value of all entities, set no limit + * + * @param limit the type of the property + * @param entityName the name of the entity + * @param value the value of the entity + */ + public void addValue(Limit limit, String entityName, int value) { + addValue(limit.ordinal(), entityName, value); + } + + /** + * Add the value to the current count by the index of the property + * @param index the index of the property + * @param entityName the name of the entity + * @param value the value of the entity + */ + public void addValue(int index, String entityName, int value) { + if (index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() || + index == Limit.MAX_OCCUR_NODE_LIMIT.ordinal() || + index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal()) { + totalValue[index] += value; + return; + } + + Map cache; + if (caches[index] == null) { + cache = new HashMap(10); + caches[index] = cache; + } else { + cache = caches[index]; + } + + int accumulatedValue = value; + if (cache.containsKey(entityName)) { + accumulatedValue += cache.get(entityName).intValue(); + cache.put(entityName, Integer.valueOf(accumulatedValue)); + } else { + cache.put(entityName, Integer.valueOf(value)); + } + + if (accumulatedValue > values[index]) { + values[index] = accumulatedValue; + names[index] = entityName; + } + + + if (index == Limit.GENEAL_ENTITY_SIZE_LIMIT.ordinal() || + index == Limit.PARAMETER_ENTITY_SIZE_LIMIT.ordinal()) { + totalValue[Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()] += value; + } + } + + /** + * Return the value of the current max count for the specified property + * + * @param limit the property + * @return the value of the property + */ + public int getValue(Limit limit) { + return values[limit.ordinal()]; + } + + public int getValue(int index) { + return values[index]; + } + /** + * Return the total value accumulated so far + * + * @param limit the property + * @return the accumulated value of the property + */ + public int getTotalValue(Limit limit) { + return totalValue[limit.ordinal()]; + } + + public int getTotalValue(int index) { + return totalValue[index]; + } + /** + * Return the current max value (count or length) by the index of a property + * @param index the index of a property + * @return count of a property + */ + public int getValueByIndex(int index) { + return values[index]; + } + + public void startEntity(String name) { + entityStart = name; + } + + public boolean isTracking(String name) { + return entityStart.equals(name); + } + /** + * Stop tracking the entity + * @param limit the limit property + * @param name the name of an entity + */ + public void endEntity(Limit limit, String name) { + entityStart = ""; + Map cache = caches[limit.ordinal()]; + if (cache != null) { + cache.remove(name); + } + } + + public void debugPrint() { + Formatter formatter = new Formatter(); + System.out.println(formatter.format("%30s %15s %15s %15s %30s", + "Property","Limit","Total size","Size","Entity Name")); + + for (Limit limit : Limit.values()) { + formatter = new Formatter(); + System.out.println(formatter.format("%30s %15d %15d %15d %30s", + limit.name(), + securityManager.getLimit(limit), + totalValue[limit.ordinal()], + values[limit.ordinal()], + names[limit.ordinal()])); + } + } +} diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java index f70aeb7cb21..1ddb651d6df 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java @@ -40,108 +40,482 @@ public final class XMLSecurityManager { */ public static enum State { //this order reflects the overriding order - DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY + + DEFAULT("default"), FSP("FEATURE_SECURE_PROCESSING"), + JAXPDOTPROPERTIES("jaxp.properties"), SYSTEMPROPERTY("system property"), + APIPROPERTY("property"); + + final String literal; + State(String literal) { + this.literal = literal; + } + + String literal() { + return literal; + } } /** * Limits managed by the security manager */ public static enum Limit { - ENTITY_EXPANSION_LIMIT(64000), - MAX_OCCUR_NODE_LIMIT(5000), - ELEMENT_ATTRIBUTE_LIMIT(10000); + ENTITY_EXPANSION_LIMIT(Constants.JDK_ENTITY_EXPANSION_LIMIT, Constants.SP_ENTITY_EXPANSION_LIMIT, 0, 64000), + MAX_OCCUR_NODE_LIMIT(Constants.JDK_MAX_OCCUR_LIMIT, Constants.SP_MAX_OCCUR_LIMIT, 0, 5000), + ELEMENT_ATTRIBUTE_LIMIT(Constants.JDK_ELEMENT_ATTRIBUTE_LIMIT, Constants.SP_ELEMENT_ATTRIBUTE_LIMIT, 0, 10000), + TOTAL_ENTITY_SIZE_LIMIT(Constants.JDK_TOTAL_ENTITY_SIZE_LIMIT, Constants.SP_TOTAL_ENTITY_SIZE_LIMIT, 0, 50000000), + GENEAL_ENTITY_SIZE_LIMIT(Constants.JDK_GENEAL_ENTITY_SIZE_LIMIT, Constants.SP_GENEAL_ENTITY_SIZE_LIMIT, 0, 0), + PARAMETER_ENTITY_SIZE_LIMIT(Constants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, Constants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000); + + final String apiProperty; + final String systemProperty; final int defaultValue; + final int secureValue; - Limit(int value) { + Limit(String apiProperty, String systemProperty, int value, int secureValue) { + this.apiProperty = apiProperty; + this.systemProperty = systemProperty; this.defaultValue = value; + this.secureValue = secureValue; + } + + public boolean equalsAPIPropertyName(String propertyName) { + return (propertyName == null) ? false : apiProperty.equals(propertyName); + } + + public boolean equalsSystemPropertyName(String propertyName) { + return (propertyName == null) ? false : systemProperty.equals(propertyName); + } + + public String apiProperty() { + return apiProperty; + } + + String systemProperty() { + return systemProperty; } int defaultValue() { return defaultValue; } + + int secureValue() { + return secureValue; + } } /** - * Values of the limits as defined in enum Limit + * Map old property names with the new ones */ - private final int[] limits; + public static enum NameMap { + + ENTITY_EXPANSION_LIMIT(Constants.SP_ENTITY_EXPANSION_LIMIT, Constants.ENTITY_EXPANSION_LIMIT), + MAX_OCCUR_NODE_LIMIT(Constants.SP_MAX_OCCUR_LIMIT, Constants.MAX_OCCUR_LIMIT), + ELEMENT_ATTRIBUTE_LIMIT(Constants.SP_ELEMENT_ATTRIBUTE_LIMIT, Constants.ELEMENT_ATTRIBUTE_LIMIT); + final String newName; + final String oldName; + + NameMap(String newName, String oldName) { + this.newName = newName; + this.oldName = oldName; + } + + String getOldName(String newName) { + if (newName.equals(this.newName)) { + return oldName; + } + return null; + } + } + private static final int NO_LIMIT = 0; /** - * States of the settings for each limit in limits above + * Values of the properties */ - private State[] states = {State.DEFAULT, State.DEFAULT, State.DEFAULT, State.DEFAULT}; + private final int[] values; + /** + * States of the settings for each property + */ + private State[] states; + /** + * Flag indicating if secure processing is set + */ + boolean secureProcessing; + + /** + * States that determine if properties are set explicitly + */ + private boolean[] isSet; + + + private XMLLimitAnalyzer limitAnalyzer; + /** + * Index of the special entityCountInfo property + */ + private int indexEntityCountInfo = 10000; + private String printEntityCountInfo = ""; /** * Default constructor. Establishes default values for known security * vulnerabilities. */ public XMLSecurityManager() { - limits = new int[Limit.values().length]; + this(false); + } + + /** + * Instantiate Security Manager in accordance with the status of + * secure processing + * @param secureProcessing + */ + public XMLSecurityManager(boolean secureProcessing) { + limitAnalyzer = new XMLLimitAnalyzer(this); + values = new int[Limit.values().length]; + states = new State[Limit.values().length]; + isSet = new boolean[Limit.values().length]; + this.secureProcessing = secureProcessing; for (Limit limit : Limit.values()) { - limits[limit.ordinal()] = limit.defaultValue(); + if (secureProcessing) { + values[limit.ordinal()] = limit.secureValue; + states[limit.ordinal()] = State.FSP; + } else { + values[limit.ordinal()] = limit.defaultValue(); + states[limit.ordinal()] = State.DEFAULT; + } } //read system properties or jaxp.properties readSystemProperties(); } /** - * Sets the limit for a specific type of XML constructs. This can be either - * the size or the number of the constructs. - * - * @param type the type of limitation - * @param state the state of limitation - * @param limit the limit to the type + * Setting FEATURE_SECURE_PROCESSING explicitly */ - public void setLimit(Limit limit, State state, int value) { - //only update if it shall override - if (state.compareTo(states[limit.ordinal()]) >= 0) { - limits[limit.ordinal()] = value; - states[limit.ordinal()] = state; + public void setSecureProcessing(boolean secure) { + secureProcessing = secure; + for (Limit limit : Limit.values()) { + if (secure) { + setLimit(limit.ordinal(), State.FSP, limit.secureValue()); + } else { + setLimit(limit.ordinal(), State.FSP, limit.defaultValue()); + } } } /** - * Returns the limit set for the type specified + * Return the state of secure processing + * @return the state of secure processing + */ + public boolean isSecureProcessing() { + return secureProcessing; + } + + + /** + * Set limit by property name and state + * @param propertyName property name + * @param state the state of the property + * @param value the value of the property + * @return true if the property is managed by the security manager; false + * if otherwise. + */ + public boolean setLimit(String propertyName, State state, Object value) { + int index = getIndex(propertyName); + if (index > -1) { + setLimit(index, state, value); + return true; + } + return false; + } + + /** + * Set the value for a specific limit. * - * @param limit the type of limitation - * @return the limit to the type + * @param limit the limit + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(Limit limit, State state, int value) { + setLimit(limit.ordinal(), state, value); + } + + /** + * Set the value of a property by its index + * + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(int index, State state, Object value) { + if (index == indexEntityCountInfo) { + printEntityCountInfo = (String)value; + } else { + int temp = 0; + try { + temp = Integer.parseInt((String) value); + if (temp < 0) { + temp = 0; + } + } catch (NumberFormatException e) {} + setLimit(index, state, temp); + } + } + + /** + * Set the value of a property by its index + * + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(int index, State state, int value) { + if (index == indexEntityCountInfo) { + //if it's explicitly set, it's treated as yes no matter the value + printEntityCountInfo = Constants.JDK_YES; + } else { + //only update if it shall override + if (state.compareTo(states[index]) >= 0) { + values[index] = value; + states[index] = state; + isSet[index] = true; + } + } + } + + /** + * Return the value of the specified property + * + * @param propertyName the property name + * @return the value of the property as a string. If a property is managed + * by this manager, its value shall not be null. + */ + public String getLimitAsString(String propertyName) { + int index = getIndex(propertyName); + if (index > -1) { + return getLimitValueByIndex(index); + } + + return null; + } + /** + * Return the value of the specified property + * + * @param limit the property + * @return the value of the property */ public int getLimit(Limit limit) { - return limits[limit.ordinal()]; + return values[limit.ordinal()]; + } + + /** + * Return the value of a property by its ordinal + * + * @param limit the property + * @return value of a property + */ + public String getLimitValueAsString(Limit limit) { + return Integer.toString(values[limit.ordinal()]); + } + + /** + * Return the value of a property by its ordinal + * + * @param index the index of a property + * @return limit of a property as a string + */ + public String getLimitValueByIndex(int index) { + if (index == indexEntityCountInfo) { + return printEntityCountInfo; + } + + return Integer.toString(values[index]); + } + + /** + * Return the state of the limit property + * + * @param limit the limit + * @return the state of the limit property + */ + public State getState(Limit limit) { + return states[limit.ordinal()]; + } + + /** + * Return the state of the limit property + * + * @param limit the limit + * @return the state of the limit property + */ + public String getStateLiteral(Limit limit) { + return states[limit.ordinal()].literal(); + } + + /** + * Get the index by property name + * + * @param propertyName property name + * @return the index of the property if found; return -1 if not + */ + public int getIndex(String propertyName) { + for (Limit limit : Limit.values()) { + if (limit.equalsAPIPropertyName(propertyName)) { + //internally, ordinal is used as index + return limit.ordinal(); + } + } + //special property to return entity count info + if (propertyName.equals(Constants.JDK_ENTITY_COUNT_INFO)) { + return indexEntityCountInfo; + } + return -1; + } + + /** + * Check if there's no limit defined by the Security Manager + * @param limit + * @return + */ + public boolean isNoLimit(int limit) { + return limit==NO_LIMIT; + } + /** + * Check if the size (length or count) of the specified limit property is + * over the limit + * + * @param limit the type of the limit property + * @param entityName the name of the entity + * @param size the size (count or length) of the entity + * @return true if the size is over the limit, false otherwise + */ + public boolean isOverLimit(Limit limit, String entityName, int size) { + return isOverLimit(limit.ordinal(), entityName, size); + } + + /** + * Check if the value (length or count) of the specified limit property is + * over the limit + * + * @param index the index of the limit property + * @param entityName the name of the entity + * @param size the size (count or length) of the entity + * @return true if the size is over the limit, false otherwise + */ + public boolean isOverLimit(int index, String entityName, int size) { + if (values[index] == NO_LIMIT) { + return false; + } + if (size > values[index]) { + limitAnalyzer.addValue(index, entityName, size); + return true; + } + return false; + } + + /** + * Check against cumulated value + * + * @param limit the type of the limit property + * @param size the size (count or length) of the entity + * @return true if the size is over the limit, false otherwise + */ + public boolean isOverLimit(Limit limit) { + return isOverLimit(limit.ordinal()); + } + + public boolean isOverLimit(int index) { + if (values[index] == NO_LIMIT) { + return false; + } + + if (index==Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() || + index==Limit.ENTITY_EXPANSION_LIMIT.ordinal() || + index==Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()) { + return (limitAnalyzer.getTotalValue(index) > values[index]); + } else { + return (limitAnalyzer.getValue(index) > values[index]); + } + } + + public void debugPrint() { + if (printEntityCountInfo.equals(Constants.JDK_YES)) { + limitAnalyzer.debugPrint(); + } + } + + /** + * Return the limit analyzer + * + * @return the limit analyzer + */ + public XMLLimitAnalyzer getLimitAnalyzer() { + return limitAnalyzer; + } + + /** + * Set limit analyzer + * + * @param analyzer a limit analyzer + */ + public void setLimitAnalyzer(XMLLimitAnalyzer analyzer) { + limitAnalyzer = analyzer; + } + + /** + * Indicate if a property is set explicitly + * @param index + * @return + */ + public boolean isSet(int index) { + return isSet[index]; + } + + public boolean printEntityCountInfo() { + return printEntityCountInfo.equals(Constants.JDK_YES); } /** * Read from system properties, or those in jaxp.properties */ private void readSystemProperties() { - getSystemProperty(Limit.ENTITY_EXPANSION_LIMIT, Constants.ENTITY_EXPANSION_LIMIT); - getSystemProperty(Limit.MAX_OCCUR_NODE_LIMIT, Constants.MAX_OCCUR_LIMIT); - getSystemProperty(Limit.ELEMENT_ATTRIBUTE_LIMIT, - Constants.SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT); + + for (Limit limit : Limit.values()) { + if (!getSystemProperty(limit, limit.systemProperty())) { + //if system property is not found, try the older form if any + for (NameMap nameMap : NameMap.values()) { + String oldName = nameMap.getOldName(limit.systemProperty()); + if (oldName != null) { + getSystemProperty(limit, oldName); + } + } + } + } + } /** * Read from system properties, or those in jaxp.properties * - * @param limit the type of the property - * @param property the property name + * @param property the type of the property + * @param sysPropertyName the name of system property */ - private void getSystemProperty(Limit limit, String property) { + private boolean getSystemProperty(Limit limit, String sysPropertyName) { try { - String value = SecuritySupport.getSystemProperty(property); + String value = SecuritySupport.getSystemProperty(sysPropertyName); if (value != null && !value.equals("")) { - limits[limit.ordinal()] = Integer.parseInt(value); + values[limit.ordinal()] = Integer.parseInt(value); states[limit.ordinal()] = State.SYSTEMPROPERTY; - return; + return true; } - value = SecuritySupport.readJAXPProperty(property); + value = SecuritySupport.readJAXPProperty(sysPropertyName); if (value != null && !value.equals("")) { - limits[limit.ordinal()] = Integer.parseInt(value); + values[limit.ordinal()] = Integer.parseInt(value); states[limit.ordinal()] = State.JAXPDOTPROPERTIES; + return true; } } catch (NumberFormatException e) { - //invalid setting ignored + //invalid setting + throw new NumberFormatException("Invalid setting for system property: " + limit.systemProperty()); } + return false; } } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java index c6bb0310702..4286f043e50 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java @@ -91,6 +91,24 @@ public final class XMLSecurityPropertyManager { readSystemProperties(); } + + /** + * Set limit by property name and state + * @param propertyName property name + * @param state the state of the property + * @param value the value of the property + * @return true if the property is managed by the security property manager; + * false if otherwise. + */ + public boolean setValue(String propertyName, State state, Object value) { + int index = getIndex(propertyName); + if (index > -1) { + setValue(index, state, (String)value); + return true; + } + return false; + } + /** * Set the value for a specific property. * @@ -119,6 +137,23 @@ public final class XMLSecurityPropertyManager { states[index] = state; } } + + + /** + * Return the value of the specified property + * + * @param propertyName the property name + * @return the value of the property as a string + */ + public String getValue(String propertyName) { + int index = getIndex(propertyName); + if (index > -1) { + return getValueByIndex(index); + } + + return null; + } + /** * Return the value of the specified property * diff --git a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java index 805586093ca..a9c9aab1d50 100644 --- a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java +++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java @@ -25,6 +25,7 @@ package com.sun.org.apache.xml.internal.utils; import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import java.util.HashMap; import javax.xml.XMLConstants; @@ -72,6 +73,8 @@ public class XMLReaderManager { */ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT; + private XMLSecurityManager _xmlSecurityManager; + /** * Hidden constructor */ @@ -173,6 +176,21 @@ public class XMLReaderManager { + se.getMessage()); } + try { + if (_xmlSecurityManager != null) { + for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) { + reader.setProperty(limit.apiProperty(), + _xmlSecurityManager.getLimitValueAsString(limit)); + } + if (_xmlSecurityManager.printEntityCountInfo()) { + reader.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES); + } + } + } catch (SAXException se) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + se.getMessage()); + } + return reader; } @@ -215,9 +233,11 @@ public class XMLReaderManager { /** * Get property value */ - public String getProperty(String name) { + public Object getProperty(String name) { if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { return _accessExternalDTD; + } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { + return _xmlSecurityManager; } return null; } @@ -225,9 +245,11 @@ public class XMLReaderManager { /** * Set property. */ - public void setProperty(String name, String value) { + public void setProperty(String name, Object value) { if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { _accessExternalDTD = (String)value; + } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { + _xmlSecurityManager = (XMLSecurityManager)value; } } } From d590d5e7d896a1b5ddda76668d698dafc40554dd Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Wed, 31 Jul 2013 10:54:46 -0700 Subject: [PATCH 0055/1294] 8021366: java_util/Properties/PropertiesWithOtherEncodings fails during 7u45 nightly testing Reviewed-by: lancea, alanb, dfuchs, mullan --- jaxp/src/com/sun/xml/internal/stream/Entity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jaxp/src/com/sun/xml/internal/stream/Entity.java b/jaxp/src/com/sun/xml/internal/stream/Entity.java index 7bbdf692412..0ae8228a3be 100644 --- a/jaxp/src/com/sun/xml/internal/stream/Entity.java +++ b/jaxp/src/com/sun/xml/internal/stream/Entity.java @@ -248,7 +248,7 @@ public abstract class Entity { public int fBufferSize = DEFAULT_BUFFER_SIZE; /** Default buffer size before we've finished with the XMLDecl: */ - public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 64; + public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 28; /** Default internal entity buffer size (1024). */ public static final int DEFAULT_INTERNAL_BUFFER_SIZE = 1024; From b520de4e1e7f245db43a627084be0ce7640c8c3b Mon Sep 17 00:00:00 2001 From: Miroslav Kos Date: Thu, 1 Aug 2013 16:09:17 -0400 Subject: [PATCH 0056/1294] 8017505: Better Client Service Reviewed-by: mullan, ahgross, mgrebac --- .../api/server/AbstractInstanceResolver.java | 4 +- .../ws/api/server/InstanceResolver.java | 4 +- .../internal/ws/api/server/MethodUtil.java | 94 +++++++++++++++++++ .../internal/ws/client/sei/MethodUtil.java | 94 +++++++++++++++++++ .../xml/internal/ws/client/sei/SEIStub.java | 23 ++++- .../ws/policy/privateutil/MethodUtil.java | 92 ++++++++++++++++++ .../ws/policy/privateutil/PolicyUtils.java | 8 +- 7 files changed, 309 insertions(+), 10 deletions(-) create mode 100644 jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/MethodUtil.java create mode 100644 jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/MethodUtil.java create mode 100644 jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/MethodUtil.java diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/AbstractInstanceResolver.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/AbstractInstanceResolver.java index e670ac452e6..560e98e9085 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/AbstractInstanceResolver.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/AbstractInstanceResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ public abstract class AbstractInstanceResolver extends InstanceResolver { if (!method.isAccessible()) { method.setAccessible(true); } - method.invoke(instance,args); + MethodUtil.invoke(instance,method, args); } catch (IllegalAccessException e) { throw new ServerRtException("server.rt.err",e); } catch (InvocationTargetException e) { diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/InstanceResolver.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/InstanceResolver.java index 625f59f47b0..7c11e6455f7 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/InstanceResolver.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/InstanceResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -232,7 +232,7 @@ public abstract class InstanceResolver { public Object invoke(Packet p, Method m, Object... args) throws InvocationTargetException, IllegalAccessException { T t = resolve(p); try { - return m.invoke(t, args ); + return MethodUtil.invoke(t, m, args ); } finally { postInvoke(p,t); } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/MethodUtil.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/MethodUtil.java new file mode 100644 index 00000000000..c8497055678 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/server/MethodUtil.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.api.server; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Utility class to invoke sun.reflect.misc.MethodUtil.invoke() if available. If not (other then Oracle JDK) fallbacks + * to java.lang,reflect.Method.invoke() + * + * Be careful, copy of this class exists in several packages, iny modification must be done to other copies too! + */ +class MethodUtil { + + private static final Logger LOGGER = Logger.getLogger(MethodUtil.class.getName()); + private static final Method INVOKE_METHOD; + + static { + Method method; + try { + Class clazz = Class.forName("sun.reflect.misc.MethodUtil"); + method = clazz.getMethod("invoke", Method.class, Object.class, Object[].class); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil found; it will be used to invoke methods."); + } + } catch (Throwable t) { + method = null; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil not found, probably non-Oracle JVM"); + } + } + INVOKE_METHOD = method; + } + + static Object invoke(Object target, Method method, Object[] args) throws IllegalAccessException, InvocationTargetException { + if (INVOKE_METHOD != null) { + // sun.reflect.misc.MethodUtil.invoke(method, owner, args) + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method using sun.reflect.misc.MethodUtil"); + } + try { + return INVOKE_METHOD.invoke(null, method, target, args); + } catch (InvocationTargetException ite) { + // unwrap invocation exception added by reflection code ... + throw unwrapException(ite); + } + } else { + // other then Oracle JDK ... + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method directly, probably non-Oracle JVM"); + } + return method.invoke(target, args); + } + } + + private static InvocationTargetException unwrapException(InvocationTargetException ite) { + Throwable targetException = ite.getTargetException(); + if (targetException != null && targetException instanceof InvocationTargetException) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Unwrapping invocation target exception"); + } + return (InvocationTargetException) targetException; + } else { + return ite; + } + } + +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/MethodUtil.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/MethodUtil.java new file mode 100644 index 00000000000..f0daea51faf --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/MethodUtil.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.client.sei; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Utility class to invoke sun.reflect.misc.MethodUtil.invoke() if available. If not (other then Oracle JDK) fallbacks + * to java.lang,reflect.Method.invoke() + *

    + * Be careful, copy of this class exists in several packages, iny modification must be done to other copies too! + */ +class MethodUtil { + + private static final Logger LOGGER = Logger.getLogger(MethodUtil.class.getName()); + private static final Method INVOKE_METHOD; + + static { + Method method; + try { + Class clazz = Class.forName("sun.reflect.misc.MethodUtil"); + method = clazz.getMethod("invoke", Method.class, Object.class, Object[].class); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil found; it will be used to invoke methods."); + } + } catch (Throwable t) { + method = null; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil not found, probably non-Oracle JVM"); + } + } + INVOKE_METHOD = method; + } + + static Object invoke(Object target, Method method, Object[] args) throws IllegalAccessException, InvocationTargetException { + if (INVOKE_METHOD != null) { + // sun.reflect.misc.MethodUtil.invoke(method, owner, args) + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method using sun.reflect.misc.MethodUtil"); + } + try { + return INVOKE_METHOD.invoke(null, method, target, args); + } catch (InvocationTargetException ite) { + // unwrap invocation exception added by reflection code ... + throw unwrapException(ite); + } + } else { + // other then Oracle JDK ... + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method directly, probably non-Oracle JVM"); + } + return method.invoke(target, args); + } + } + + private static InvocationTargetException unwrapException(InvocationTargetException ite) { + Throwable targetException = ite.getTargetException(); + if (targetException != null && targetException instanceof InvocationTargetException) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Unwrapping invocation target exception"); + } + return (InvocationTargetException) targetException; + } else { + return ite; + } + } + +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/SEIStub.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/SEIStub.java index 7a5f0e3a1a7..9ad1f6edfba 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/SEIStub.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/SEIStub.java @@ -28,6 +28,7 @@ package com.sun.xml.internal.ws.client.sei; import com.sun.istack.internal.NotNull; import com.sun.istack.internal.Nullable; import com.sun.xml.internal.ws.api.SOAPVersion; +import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; import com.sun.xml.internal.ws.api.client.WSPortInfo; import com.sun.xml.internal.ws.api.databinding.Databinding; import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; @@ -36,12 +37,16 @@ import com.sun.xml.internal.ws.api.message.Headers; import com.sun.xml.internal.ws.api.message.Packet; import com.sun.xml.internal.ws.api.model.MEP; import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation; -import com.sun.xml.internal.ws.api.pipe.Tube; import com.sun.xml.internal.ws.api.pipe.Fiber; +import com.sun.xml.internal.ws.api.pipe.Tube; import com.sun.xml.internal.ws.api.server.Container; import com.sun.xml.internal.ws.api.server.ContainerResolver; import com.sun.xml.internal.ws.binding.BindingImpl; -import com.sun.xml.internal.ws.client.*; +import com.sun.xml.internal.ws.client.AsyncResponseImpl; +import com.sun.xml.internal.ws.client.RequestContext; +import com.sun.xml.internal.ws.client.ResponseContextReceiver; +import com.sun.xml.internal.ws.client.Stub; +import com.sun.xml.internal.ws.client.WSServiceDelegate; import com.sun.xml.internal.ws.model.JavaMethodImpl; import com.sun.xml.internal.ws.model.SOAPSEIModel; import com.sun.xml.internal.ws.wsdl.OperationDispatcher; @@ -50,6 +55,8 @@ import javax.xml.namespace.QName; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; @@ -132,6 +139,7 @@ public final class SEIStub extends Stub implements InvocationHandler { private final Map methodHandlers = new HashMap(); public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + validateInputs(proxy, method); Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer()); try { MethodHandler handler = methodHandlers.get(method); @@ -155,6 +163,17 @@ public final class SEIStub extends Stub implements InvocationHandler { } } + private void validateInputs(Object proxy, Method method) { + if (proxy == null || !Proxy.isProxyClass(proxy.getClass())) { + throw new IllegalStateException("Passed object is not proxy!"); + } + Class declaringClass = method.getDeclaringClass(); + if (method == null || declaringClass == null + || Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("Invoking static method is not allowed!"); + } + } + public final Packet doProcess(Packet request, RequestContext rc, ResponseContextReceiver receiver) { return super.process(request, rc, receiver); } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/MethodUtil.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/MethodUtil.java new file mode 100644 index 00000000000..ad2ad4a6ef5 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/MethodUtil.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.policy.privateutil; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Utility class to invoke sun.reflect.misc.MethodUtil.invoke() if available. If not (other then Oracle JDK) fallbacks + * to java.lang,reflect.Method.invoke() + */ +class MethodUtil { + + private static final Logger LOGGER = Logger.getLogger(MethodUtil.class.getName()); + private static final Method INVOKE_METHOD; + + static { + Method method; + try { + Class clazz = Class.forName("sun.reflect.misc.MethodUtil"); + method = clazz.getMethod("invoke", Method.class, Object.class, Object[].class); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil found; it will be used to invoke methods."); + } + } catch (Throwable t) { + method = null; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil not found, probably non-Oracle JVM"); + } + } + INVOKE_METHOD = method; + } + + static Object invoke(Object target, Method method, Object[] args) throws IllegalAccessException, InvocationTargetException { + if (INVOKE_METHOD != null) { + // sun.reflect.misc.MethodUtil.invoke(method, owner, args) + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method using sun.reflect.misc.MethodUtil"); + } + try { + return INVOKE_METHOD.invoke(null, method, target, args); + } catch (InvocationTargetException ite) { + // unwrap invocation exception added by reflection code ... + throw unwrapException(ite); + } + } else { + // other then Oracle JDK ... + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Invoking method directly, probably non-Oracle JVM"); + } + return method.invoke(target, args); + } + } + + private static InvocationTargetException unwrapException(InvocationTargetException ite) { + Throwable targetException = ite.getTargetException(); + if (targetException != null && targetException instanceof InvocationTargetException) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Unwrapping invocation target exception"); + } + return (InvocationTargetException) targetException; + } else { + return ite; + } + } + +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/PolicyUtils.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/PolicyUtils.java index d3a2752ad5e..ec537d88358 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/PolicyUtils.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/PolicyUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -282,13 +282,13 @@ public final class PolicyUtils { /** * Reflection utilities wrapper */ - public static class Reflection { + static class Reflection { private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyUtils.Reflection.class); /** * Reflectively invokes specified method on the specified target */ - public static T invoke(final Object target, final String methodName, + static T invoke(final Object target, final String methodName, final Class resultClass, final Object... parameters) throws RuntimePolicyUtilsException { Class[] parameterTypes; if (parameters != null && parameters.length > 0) { @@ -311,7 +311,7 @@ public final class PolicyUtils { final Object[] parameters, final Class[] parameterTypes) throws RuntimePolicyUtilsException { try { final Method method = target.getClass().getMethod(methodName, parameterTypes); - final Object result = method.invoke(target, parameters); + final Object result = MethodUtil.invoke(target, method,parameters); return resultClass.cast(result); } catch (IllegalArgumentException e) { From adf52d0164028f9a7ceedeb0afc633f4f0bcd0fb Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Thu, 1 Aug 2013 14:09:39 -0700 Subject: [PATCH 0057/1294] 8021286: Improve MacOS resourcing Reviewed-by: okutsu --- jdk/make/sun/awt/FILES_c_macosx.gmk | 28 ----- jdk/make/sun/awt/FILES_export_macosx.gmk | 29 ----- jdk/make/sun/awt/Makefile | 2 - jdk/makefiles/CompileNativeLibraries.gmk | 4 - .../com/apple/laf/AquaLookAndFeel.java | 4 +- .../apple/resources/MacOSXResourceBundle.java | 110 ------------------ .../apple/resources/MacOSXResourceBundle.m | 110 ------------------ 7 files changed, 1 insertion(+), 286 deletions(-) delete mode 100644 jdk/make/sun/awt/FILES_c_macosx.gmk delete mode 100644 jdk/make/sun/awt/FILES_export_macosx.gmk delete mode 100644 jdk/src/macosx/classes/com/apple/resources/MacOSXResourceBundle.java delete mode 100644 jdk/src/macosx/native/com/apple/resources/MacOSXResourceBundle.m diff --git a/jdk/make/sun/awt/FILES_c_macosx.gmk b/jdk/make/sun/awt/FILES_c_macosx.gmk deleted file mode 100644 index d6bef30bb2a..00000000000 --- a/jdk/make/sun/awt/FILES_c_macosx.gmk +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (c) 1995, 2012, 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. -# - -FILES_AWT_objc = \ - $(TARGDIR)MacOSXResourceBundle.m - diff --git a/jdk/make/sun/awt/FILES_export_macosx.gmk b/jdk/make/sun/awt/FILES_export_macosx.gmk deleted file mode 100644 index c7f0e003cb9..00000000000 --- a/jdk/make/sun/awt/FILES_export_macosx.gmk +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright (c) 1995, 2012, 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. -# - -# FILES_export definitions for Mac OS X - -FILES_export += \ - com/apple/resources/MacOSXResourceBundle.java diff --git a/jdk/make/sun/awt/Makefile b/jdk/make/sun/awt/Makefile index dc4c250cf74..c45ecb9fe45 100644 --- a/jdk/make/sun/awt/Makefile +++ b/jdk/make/sun/awt/Makefile @@ -145,8 +145,6 @@ ifeq ($(PLATFORM), macosx) # # Files # -include FILES_c_macosx.gmk -include FILES_export_macosx.gmk FILES_objc = $(FILES_AWT_objc) OTHER_LDLIBS = -lmlib_image $(JVMLIB) $(LIBM) \ diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 02bf3be808c..fa416032473 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.gmk @@ -558,11 +558,7 @@ endif ifeq ($(OPENJDK_TARGET_OS),macosx) LIBAWT_FILES += awt_LoadLibrary.c img_colors.c - LIBAWT_DIRS += $(JDK_TOPDIR)/src/macosx/native/com/apple/resources - LIBAWT_FILES += awt_LoadLibrary.c MacOSXResourceBundle.m LIBAWT_CFLAGS += -F/System/Library/Frameworks/JavaVM.framework/Frameworks - - LIBAWT_MacOSXResourceBundle.m_CFLAGS:=-O0 endif ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc) diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java b/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java index 457b82d36a3..046d693e329 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java @@ -37,8 +37,6 @@ import javax.swing.plaf.basic.BasicLookAndFeel; import sun.swing.*; import apple.laf.*; -import com.apple.resources.MacOSXResourceBundle; - public class AquaLookAndFeel extends BasicLookAndFeel { static final String sOldPropertyPrefix = "com.apple.macos."; // old prefix for things like 'useScreenMenuBar' static final String sPropertyPrefix = "apple.laf."; // new prefix for things like 'useScreenMenuBar' @@ -252,7 +250,7 @@ public class AquaLookAndFeel extends BasicLookAndFeel { table.setDefaultLocale(Locale.getDefault()); table.addResourceBundle(PKG_PREFIX + "resources.aqua"); try { - final ResourceBundle aquaProperties = MacOSXResourceBundle.getMacResourceBundle(PKG_PREFIX + "resources.aqua"); + final ResourceBundle aquaProperties = ResourceBundle.getBundle(PKG_PREFIX + "resources.aqua"); final Enumeration propertyKeys = aquaProperties.getKeys(); while (propertyKeys.hasMoreElements()) { diff --git a/jdk/src/macosx/classes/com/apple/resources/MacOSXResourceBundle.java b/jdk/src/macosx/classes/com/apple/resources/MacOSXResourceBundle.java deleted file mode 100644 index 143584b0b87..00000000000 --- a/jdk/src/macosx/classes/com/apple/resources/MacOSXResourceBundle.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.apple.resources; - -import java.security.*; -import java.util.PropertyResourceBundle; -import java.util.ResourceBundle; -import java.io.*; - -public class MacOSXResourceBundle extends PropertyResourceBundle { - MacOSXResourceBundle(InputStream stream) throws IOException { - super(stream); - } - - void setItsParent(ResourceBundle rb) { - setParent(rb); - } - - public static ResourceBundle getMacResourceBundle(String baseJavaBundle) throws Exception { - return getMacResourceBundle(baseJavaBundle, null); - } - - public static ResourceBundle getMacResourceBundle(String baseJavaBundle, String filename) throws Exception { - LoadNativeBundleAction lnba = new LoadNativeBundleAction(baseJavaBundle, filename); - return (ResourceBundle)java.security.AccessController.doPrivileged(lnba); - } -} - -class LoadNativeBundleAction implements PrivilegedExceptionAction { - String mBaseJavaBundle; - String mFilenameOverride; - - LoadNativeBundleAction(String baseJavaBundle, String filenameOverride) { - mBaseJavaBundle = baseJavaBundle; - mFilenameOverride = filenameOverride; - } - - public Object run() { - java.util.ResourceBundle returnValue = null; - MacOSXResourceBundle macOSrb = null; - - // Load the Mac OS X resources. - // Use a base filename if we were given one. Otherwise, we will look for the last piece of the bundle path - // with '.properties' appended. Either way, the native method will take care of the extension. - String filename = mFilenameOverride; - - if (filename == null) { - filename = mBaseJavaBundle.substring(mBaseJavaBundle.lastIndexOf('.') + 1); - } - - File propsFile = null; - String propertyFileName = getPathToBundleFile(filename); - InputStream stream = null; - - try { - propsFile = new File(propertyFileName); - stream = new FileInputStream(propsFile); - stream = new java.io.BufferedInputStream(stream); - macOSrb = new MacOSXResourceBundle(stream); - } catch (Exception e) { - //e.printStackTrace(); - //System.out.println("Failed to create resources from application bundle. Using Java-based resources."); - } finally { - try { - if (stream != null) stream.close(); - stream = null; - } catch (Exception e) { - e.printStackTrace(); - } - } - - returnValue = ResourceBundle.getBundle(mBaseJavaBundle); - - // If we have a platform-specific bundle, make it the parent of the generic bundle, so failures propagate up to the parent. - if (returnValue != null) { - if (macOSrb != null) { - macOSrb.setItsParent(returnValue); - returnValue = macOSrb; - } - } - - return returnValue; - } - - private static native String getPathToBundleFile(String filename); -} - diff --git a/jdk/src/macosx/native/com/apple/resources/MacOSXResourceBundle.m b/jdk/src/macosx/native/com/apple/resources/MacOSXResourceBundle.m deleted file mode 100644 index 0b98d2b0588..00000000000 --- a/jdk/src/macosx/native/com/apple/resources/MacOSXResourceBundle.m +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 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. - */ - -#import -#import -#import - -#ifndef MAXPATHLEN -#define MAXPATHLEN PATH_MAX -#endif - -static jboolean -GetPathFromCurrentBinary(char *buf, jint bufsize) -{ - Dl_info dlinfo; - dladdr((void *)GetPathFromCurrentBinary, &dlinfo); - if (realpath(dlinfo.dli_fname, buf) == NULL) { -// fprintf(stderr, "Error: realpath(`%s') failed.\n", dlinfo.dli_fname); - return JNI_FALSE; - } - - const char *libawt = "lib/libawt.dylib"; - int strLen, libawtLen; - - strLen = strlen(buf); - libawtLen = strlen(libawt); - - if (strLen < libawtLen || - strcmp(buf + strLen - libawtLen, libawt) != 0) { - return JNI_FALSE; - } - - buf[strLen - libawtLen] = '\0'; - - return JNI_TRUE; -} - -#define JAVA_DLL "libjava.dylib" - -static jboolean -GetJREPath(char *buf, jint bufsize) -{ - /* try to get the path from the current binary, if not, bail to the framework */ - if (GetPathFromCurrentBinary(buf, bufsize) == JNI_TRUE) { - /* does the rest of the JRE exist? */ - char libjava[MAXPATHLEN]; - snprintf(libjava, MAXPATHLEN, "%s/lib/" JAVA_DLL, buf); - if (access(libjava, F_OK) == 0) { - return JNI_TRUE; - } - } - - return JNI_FALSE; -} - -static NSString *getRunningJavaBundle() -{ - char path[MAXPATHLEN]; - GetJREPath(path, MAXPATHLEN); - return [[NSString alloc] initWithFormat:@"%@/bundle", [NSString stringWithUTF8String:path]]; -} - -/* - * Class: com_apple_resources_LoadNativeBundleAction - * Method: getPathToBundleFile - * Signature: (Ljava/lang/String)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_com_apple_resources_LoadNativeBundleAction_getPathToBundleFile - (JNIEnv *env, jclass klass, jstring filename) -{ - jstring returnVal = NULL; - if (filename == NULL) { - return NULL; - } - -JNF_COCOA_ENTER(env); - NSBundle *javaBundle = [NSBundle bundleWithPath:getRunningJavaBundle()]; - NSString *baseFilename = JNFJavaToNSString(env, filename); - NSString *propertyFilePath = [javaBundle pathForResource:baseFilename ofType:@"properties"]; - - if (propertyFilePath != nil) { - returnVal = JNFNSToJavaString(env, propertyFilePath); - } -JNF_COCOA_EXIT(env); - - return returnVal; -} From 10738dc29803a286a22c0973f85ffaac94ef6b5a Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Sun, 4 Aug 2013 02:50:02 +0400 Subject: [PATCH 0058/1294] 8021282: Better recycling of object instances Reviewed-by: art --- .../classes/com/apple/laf/AquaUtils.java | 193 ++++++++++-------- 1 file changed, 104 insertions(+), 89 deletions(-) diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java b/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java index 0592da714a2..a5f5501cb35 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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,6 +29,7 @@ import java.awt.*; import java.awt.image.*; import java.lang.ref.SoftReference; import java.lang.reflect.Method; +import java.security.AccessController; import java.security.PrivilegedAction; import java.util.*; @@ -41,56 +42,68 @@ import sun.awt.AppContext; import sun.lwawt.macosx.CImage; import sun.lwawt.macosx.CImage.Creator; import sun.lwawt.macosx.CPlatformWindow; +import sun.misc.Launcher; +import sun.reflect.misc.ReflectUtil; +import sun.security.action.GetPropertyAction; import sun.swing.SwingUtilities2; import com.apple.laf.AquaImageFactory.SlicedImageControl; -public class AquaUtils { - final static String ANIMATIONS_SYSTEM_PROPERTY = "swing.enableAnimations"; +final class AquaUtils { - /* + private static final String ANIMATIONS_PROPERTY = "swing.enableAnimations"; + + /** + * Suppresses default constructor, ensuring non-instantiability. + */ + private AquaUtils() { + } + + /** * Convenience function for determining ComponentOrientation. Helps us * avoid having Munge directives throughout the code. */ - public static boolean isLeftToRight(final Component c) { + static boolean isLeftToRight(final Component c) { return c.getComponentOrientation().isLeftToRight(); } - public static void enforceComponentOrientation(Component c, ComponentOrientation orientation) { + static void enforceComponentOrientation(final Component c, final ComponentOrientation orientation) { c.setComponentOrientation(orientation); if (c instanceof Container) { - for (Component child : ((Container)c).getComponents()) { + for (final Component child : ((Container)c).getComponents()) { enforceComponentOrientation(child, orientation); } } } - private static CImage.Creator getCImageCreatorInternal() { - return java.security.AccessController.doPrivileged(new PrivilegedAction() { + private static Creator getCImageCreatorInternal() { + return AccessController.doPrivileged(new PrivilegedAction() { + @Override public Creator run() { try { final Method getCreatorMethod = CImage.class.getDeclaredMethod("getCreator", new Class[] {}); getCreatorMethod.setAccessible(true); - return (CImage.Creator)getCreatorMethod.invoke(null, new Object[] {}); - } catch (final Exception e) { + return (Creator)getCreatorMethod.invoke(null, new Object[] {}); + } catch (final Exception ignored) { return null; } } }); } - private static final RecyclableSingleton cImageCreator = new RecyclableSingleton() { + private static final RecyclableSingleton cImageCreator = new RecyclableSingleton() { @Override protected Creator getInstance() { return getCImageCreatorInternal(); } }; - static CImage.Creator getCImageCreator() { + static Creator getCImageCreator() { return cImageCreator.get(); } - protected static Image generateSelectedDarkImage(final Image image) { + static Image generateSelectedDarkImage(final Image image) { final ImageProducer prod = new FilteredImageSource(image.getSource(), new IconImageFilter() { + @Override int getGreyFor(final int gray) { return gray * 75 / 100; } @@ -98,8 +111,9 @@ public class AquaUtils { return Toolkit.getDefaultToolkit().createImage(prod); } - protected static Image generateDisabledImage(final Image image) { + static Image generateDisabledImage(final Image image) { final ImageProducer prod = new FilteredImageSource(image.getSource(), new IconImageFilter() { + @Override int getGreyFor(final int gray) { return 255 - ((255 - gray) * 65 / 100); } @@ -107,19 +121,20 @@ public class AquaUtils { return Toolkit.getDefaultToolkit().createImage(prod); } - protected static Image generateLightenedImage(final Image image, final int percent) { + static Image generateLightenedImage(final Image image, final int percent) { final GrayFilter filter = new GrayFilter(true, percent); final ImageProducer prod = new FilteredImageSource(image.getSource(), filter); return Toolkit.getDefaultToolkit().createImage(prod); } - static abstract class IconImageFilter extends RGBImageFilter { - public IconImageFilter() { + private abstract static class IconImageFilter extends RGBImageFilter { + IconImageFilter() { super(); canFilterIndexColorModel = true; } - public int filterRGB(final int x, final int y, final int rgb) { + @Override + public final int filterRGB(final int x, final int y, final int rgb) { final int red = (rgb >> 16) & 0xff; final int green = (rgb >> 8) & 0xff; final int blue = rgb & 0xff; @@ -135,14 +150,14 @@ public class AquaUtils { return result; } - abstract int getGreyFor(final int gray); + abstract int getGreyFor(int gray); } - public abstract static class RecyclableObject { - protected SoftReference objectRef = null; + abstract static class RecyclableObject { + private SoftReference objectRef; - public T get() { - T referent = null; + T get() { + T referent; if (objectRef != null && (referent = objectRef.get()) != null) return referent; referent = create(); objectRef = new SoftReference(referent); @@ -152,8 +167,8 @@ public class AquaUtils { protected abstract T create(); } - public abstract static class RecyclableSingleton { - public T get() { + abstract static class RecyclableSingleton { + final T get() { final AppContext appContext = AppContext.getAppContext(); SoftReference ref = (SoftReference) appContext.get(this); if (ref != null) { @@ -166,38 +181,36 @@ public class AquaUtils { return object; } - public void reset() { - AppContext appContext = AppContext.getAppContext(); - appContext.remove(this); + void reset() { + AppContext.getAppContext().remove(this); } - protected abstract T getInstance(); + abstract T getInstance(); } - public static class RecyclableSingletonFromDefaultConstructor extends RecyclableSingleton { - protected final Class clazz; + static class RecyclableSingletonFromDefaultConstructor extends RecyclableSingleton { + private final Class clazz; - public RecyclableSingletonFromDefaultConstructor(final Class clazz) { + RecyclableSingletonFromDefaultConstructor(final Class clazz) { this.clazz = clazz; } - protected T getInstance() { + @Override + T getInstance() { try { + ReflectUtil.checkPackageAccess(clazz); return clazz.newInstance(); - } catch (final InstantiationException e) { - e.printStackTrace(); - } catch (final IllegalAccessException e) { - e.printStackTrace(); + } catch (InstantiationException | IllegalAccessException ignored) { } return null; } } - public abstract static class LazyKeyedSingleton { - protected Map refs; + abstract static class LazyKeyedSingleton { + private Map refs; - public V get(final K key) { - if (refs == null) refs = new HashMap(); + V get(final K key) { + if (refs == null) refs = new HashMap<>(); final V cachedValue = refs.get(key); if (cachedValue != null) return cachedValue; @@ -207,44 +220,45 @@ public class AquaUtils { return value; } - protected abstract V getInstance(final K key); + protected abstract V getInstance(K key); } - static final RecyclableSingleton enableAnimations = new RecyclableSingleton() { + private static final RecyclableSingleton enableAnimations = new RecyclableSingleton() { @Override protected Boolean getInstance() { - final String sizeProperty = (String)java.security.AccessController.doPrivileged((PrivilegedAction)new sun.security.action.GetPropertyAction(ANIMATIONS_SYSTEM_PROPERTY)); - return new Boolean(!"false".equals(sizeProperty)); // should be true by default + final String sizeProperty = (String) AccessController.doPrivileged((PrivilegedAction)new GetPropertyAction( + ANIMATIONS_PROPERTY)); + return !"false".equals(sizeProperty); // should be true by default } }; - static boolean animationsEnabled() { + private static boolean animationsEnabled() { return enableAnimations.get(); } - static final int MENU_BLINK_DELAY = 50; // 50ms == 3/60 sec, according to the spec - protected static void blinkMenu(final Selectable selectable) { + private static final int MENU_BLINK_DELAY = 50; // 50ms == 3/60 sec, according to the spec + static void blinkMenu(final Selectable selectable) { if (!animationsEnabled()) return; try { selectable.paintSelected(false); Thread.sleep(MENU_BLINK_DELAY); selectable.paintSelected(true); Thread.sleep(MENU_BLINK_DELAY); - } catch (final InterruptedException e) { } + } catch (final InterruptedException ignored) { } } interface Selectable { - void paintSelected(final boolean selected); + void paintSelected(boolean selected); } interface JComponentPainter { - public void paint(JComponent c, Graphics g, int x, int y, int w, int h); + void paint(JComponent c, Graphics g, int x, int y, int w, int h); } interface Painter { - public void paint(final Graphics g, int x, int y, int w, int h); + void paint(Graphics g, int x, int y, int w, int h); } - public static void paintDropShadowText(final Graphics g, final JComponent c, final Font font, final FontMetrics metrics, final int x, final int y, final int offsetX, final int offsetY, final Color textColor, final Color shadowColor, final String text) { + static void paintDropShadowText(final Graphics g, final JComponent c, final Font font, final FontMetrics metrics, final int x, final int y, final int offsetX, final int offsetY, final Color textColor, final Color shadowColor, final String text) { g.setFont(font); g.setColor(shadowColor); SwingUtilities2.drawString(c, g, text, x + offsetX, y + offsetY + metrics.getAscent()); @@ -252,22 +266,22 @@ public class AquaUtils { SwingUtilities2.drawString(c, g, text, x, y + metrics.getAscent()); } - public static class ShadowBorder implements Border { - final Painter prePainter; - final Painter postPainter; + static class ShadowBorder implements Border { + private final Painter prePainter; + private final Painter postPainter; - final int offsetX; - final int offsetY; - final float distance; - final int blur; - final Insets insets; - final ConvolveOp blurOp; + private final int offsetX; + private final int offsetY; + private final float distance; + private final int blur; + private final Insets insets; + private final ConvolveOp blurOp; - public ShadowBorder(final Painter prePainter, final Painter postPainter, final int offsetX, final int offsetY, final float distance, final float intensity, final int blur) { + ShadowBorder(final Painter prePainter, final Painter postPainter, final int offsetX, final int offsetY, final float distance, final float intensity, final int blur) { this.prePainter = prePainter; this.postPainter = postPainter; this.offsetX = offsetX; this.offsetY = offsetY; this.distance = distance; this.blur = blur; final int halfBlur = blur / 2; - this.insets = new Insets(halfBlur - offsetY, halfBlur - offsetX, halfBlur + offsetY, halfBlur + offsetX); + insets = new Insets(halfBlur - offsetY, halfBlur - offsetX, halfBlur + offsetY, halfBlur + offsetX); final float blurry = intensity / (blur * blur); final float[] blurKernel = new float[blur * blur]; @@ -275,14 +289,17 @@ public class AquaUtils { blurOp = new ConvolveOp(new Kernel(blur, blur, blurKernel)); } - public boolean isBorderOpaque() { + @Override + public final boolean isBorderOpaque() { return false; } - public Insets getBorderInsets(final Component c) { + @Override + public final Insets getBorderInsets(final Component c) { return insets; } + @Override public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) { final BufferedImage img = new BufferedImage(width + blur * 2, height + blur * 2, BufferedImage.TYPE_INT_ARGB_PRE); paintToImage(img, x, y, width, height); @@ -290,7 +307,7 @@ public class AquaUtils { g.drawImage(img, -blur, -blur, null); } - protected void paintToImage(final BufferedImage img, final int x, final int y, final int width, final int height) { + private void paintToImage(final BufferedImage img, final int x, final int y, final int width, final int height) { // clear the prior image Graphics2D imgG = (Graphics2D)img.getGraphics(); imgG.setComposite(AlphaComposite.Clear); @@ -319,10 +336,10 @@ public class AquaUtils { } } - public static class SlicedShadowBorder extends ShadowBorder { - final SlicedImageControl slices; + static class SlicedShadowBorder extends ShadowBorder { + private final SlicedImageControl slices; - public SlicedShadowBorder(final Painter prePainter, final Painter postPainter, final int offsetX, final int offsetY, final float distance, final float intensity, final int blur, final int templateWidth, final int templateHeight, final int leftCut, final int topCut, final int rightCut, final int bottomCut) { + SlicedShadowBorder(final Painter prePainter, final Painter postPainter, final int offsetX, final int offsetY, final float distance, final float intensity, final int blur, final int templateWidth, final int templateHeight, final int leftCut, final int topCut, final int rightCut, final int bottomCut) { super(prePainter, postPainter, offsetX, offsetY, distance, intensity, blur); final BufferedImage i = new BufferedImage(templateWidth, templateHeight, BufferedImage.TYPE_INT_ARGB_PRE); @@ -331,15 +348,12 @@ public class AquaUtils { slices = new SlicedImageControl(i, leftCut, topCut, rightCut, bottomCut, false); } + @Override public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) { slices.paint(g, x, y, width, height); } } - public interface NineSliceMetricsProvider { - - } - // static void debugFrame(String name, Image image) { // JFrame f = new JFrame(name); // f.setContentPane(new JLabel(new ImageIcon(image))); @@ -350,28 +364,30 @@ public class AquaUtils { // special casing naughty applications, like InstallAnywhere // REGR: JButton: Myst IV: the buttons of 1.0.3 updater have redraw issue static boolean shouldUseOpaqueButtons() { - final ClassLoader launcherClassLoader = sun.misc.Launcher.getLauncher().getClassLoader(); + final ClassLoader launcherClassLoader = Launcher.getLauncher().getClassLoader(); if (classExists(launcherClassLoader, "com.installshield.wizard.platform.macosx.MacOSXUtils")) return true; return false; } - static boolean classExists(final ClassLoader classLoader, final String clazzName) { + private static boolean classExists(final ClassLoader classLoader, final String clazzName) { try { return Class.forName(clazzName, false, classLoader) != null; - } catch (final Throwable e) { } + } catch (final Throwable ignored) { } return false; } - private static RecyclableSingleton getJComponentGetFlagMethod = new RecyclableSingleton() { + private static final RecyclableSingleton getJComponentGetFlagMethod = new RecyclableSingleton() { + @Override protected Method getInstance() { - return java.security.AccessController.doPrivileged( + return AccessController.doPrivileged( new PrivilegedAction() { + @Override public Method run() { try { final Method method = JComponent.class.getDeclaredMethod("getFlag", new Class[] { int.class }); method.setAccessible(true); return method; - } catch (final Throwable e) { + } catch (final Throwable ignored) { return null; } } @@ -380,18 +396,18 @@ public class AquaUtils { } }; - private static final Integer OPAQUE_SET_FLAG = new Integer(24); // private int JComponent.OPAQUE_SET - protected static boolean hasOpaqueBeenExplicitlySet(final JComponent c) { + private static final Integer OPAQUE_SET_FLAG = 24; // private int JComponent.OPAQUE_SET + static boolean hasOpaqueBeenExplicitlySet(final JComponent c) { final Method method = getJComponentGetFlagMethod.get(); if (method == null) return false; try { return Boolean.TRUE.equals(method.invoke(c, OPAQUE_SET_FLAG)); - } catch (final Throwable e) { + } catch (final Throwable ignored) { return false; } } - protected static boolean isWindowTextured(final Component c) { + private static boolean isWindowTextured(final Component c) { if (!(c instanceof JComponent)) { return false; } @@ -412,13 +428,12 @@ public class AquaUtils { return new Color(color.getRed(), color.getGreen(), color.getBlue(), 0); } - protected static void fillRect(final Graphics g, final Component c) { + static void fillRect(final Graphics g, final Component c) { fillRect(g, c, c.getBackground(), 0, 0, c.getWidth(), c.getHeight()); } - protected static void fillRect(final Graphics g, final Component c, - final Color color, final int x, final int y, - final int w, final int h) { + static void fillRect(final Graphics g, final Component c, final Color color, + final int x, final int y, final int w, final int h) { if (!(g instanceof Graphics2D)) { return; } From a3b45465c6003b542aafe8969f5a5f13d3b2ca48 Mon Sep 17 00:00:00 2001 From: Shanliang Jiang Date: Tue, 6 Aug 2013 10:33:42 +0200 Subject: [PATCH 0059/1294] 8019292: Better Attribute Value Exceptions Reviewed-by: dfuchs, dholmes, ahgross --- .../BadAttributeValueExpException.java | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/javax/management/BadAttributeValueExpException.java b/jdk/src/share/classes/javax/management/BadAttributeValueExpException.java index 9ed27e91fa3..2eda233d24a 100644 --- a/jdk/src/share/classes/javax/management/BadAttributeValueExpException.java +++ b/jdk/src/share/classes/javax/management/BadAttributeValueExpException.java @@ -25,6 +25,9 @@ package javax.management; +import java.io.IOException; +import java.io.ObjectInputStream; + /** * Thrown when an invalid MBean attribute is passed to a query @@ -41,17 +44,19 @@ public class BadAttributeValueExpException extends Exception { private static final long serialVersionUID = -3105272988410493376L; /** - * @serial The attribute value that originated this exception + * @serial A string representation of the attribute that originated this exception. + * for example, the string value can be the return of {@code attribute.toString()} */ private Object val; /** - * Constructs an BadAttributeValueExpException with the specified Object. + * Constructs a BadAttributeValueExpException using the specified Object to + * create the toString() value. * * @param val the inappropriate value. */ public BadAttributeValueExpException (Object val) { - this.val = val; + this.val = val == null ? null : val.toString(); } @@ -62,4 +67,25 @@ public class BadAttributeValueExpException extends Exception { return "BadAttributeValueException: " + val; } + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + ObjectInputStream.GetField gf = ois.readFields(); + Object valObj = gf.get("val", null); + + if (valObj == null) { + val = null; + } else if (valObj instanceof String) { + val= valObj; + } else if (System.getSecurityManager() == null + || valObj instanceof Long + || valObj instanceof Integer + || valObj instanceof Float + || valObj instanceof Double + || valObj instanceof Byte + || valObj instanceof Short + || valObj instanceof Boolean) { + val = valObj.toString(); + } else { // the serialized object is from a version without JDK-8019292 fix + val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName(); + } + } } From 68d1aae1be91153f3df0736e8a96ed99d36945a6 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 7 Aug 2013 14:37:22 +0400 Subject: [PATCH 0060/1294] 8021969: The index_AccessAllowed jnlp can not load successfully with exception thrown in the log Reviewed-by: art, skoivu --- jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java b/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java index 3c1691545f4..400553dd854 100644 --- a/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java +++ b/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java @@ -145,11 +145,7 @@ public class DataFlavor implements Externalizable, Cloneable { } catch (SecurityException exception) { // ignore secured class loaders } - if (fallback != null) { - return Class.forName(className, true, fallback); - } else { - throw new ClassNotFoundException(className); - } + return Class.forName(className, true, fallback); } /* From 046a6fa8e2263dc23bc39d97294922c71cf893b7 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Thu, 8 Aug 2013 19:16:27 +0200 Subject: [PATCH 0061/1294] 8021360: object not exported" on start of JMXConnectorServer for RMI-IIOP protocol with security manager Reviewed-by: alanb, ahgross, smarks, coffeys --- .../remote/protocol/iiop/IIOPProxyImpl.java | 46 +++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/com/sun/jmx/remote/protocol/iiop/IIOPProxyImpl.java b/jdk/src/share/classes/com/sun/jmx/remote/protocol/iiop/IIOPProxyImpl.java index d4171b24282..b0fe91bf728 100644 --- a/jdk/src/share/classes/com/sun/jmx/remote/protocol/iiop/IIOPProxyImpl.java +++ b/jdk/src/share/classes/com/sun/jmx/remote/protocol/iiop/IIOPProxyImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009,2013, 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,13 +36,34 @@ import java.rmi.RemoteException; import java.rmi.NoSuchObjectException; import com.sun.jmx.remote.internal.IIOPProxy; +import java.io.SerializablePermission; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.Permissions; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.security.ProtectionDomain; /** - * An implementatin of IIOPProxy that simply delegates to the appropriate + * An implementation of IIOPProxy that simply delegates to the appropriate * RMI-IIOP and CORBA APIs. */ public class IIOPProxyImpl implements IIOPProxy { + // special ACC used to initialize the IIOP stub + // the only allowed privilege is SerializablePermission("enableSubclassImplementation") + private static final AccessControlContext STUB_ACC; + + static { + Permissions p = new Permissions(); + p.add(new SerializablePermission("enableSubclassImplementation")); + STUB_ACC = new AccessControlContext( + new ProtectionDomain[]{ + new ProtectionDomain(null, p) + } + ); + } + public IIOPProxyImpl() { } @Override @@ -113,7 +134,24 @@ public class IIOPProxyImpl implements IIOPProxy { } @Override - public Remote toStub(Remote obj) throws NoSuchObjectException { - return PortableRemoteObject.toStub(obj); + public Remote toStub(final Remote obj) throws NoSuchObjectException { + if (System.getSecurityManager() == null) { + return PortableRemoteObject.toStub(obj); + } else { + try { + return AccessController.doPrivileged(new PrivilegedExceptionAction() { + + @Override + public Remote run() throws Exception { + return PortableRemoteObject.toStub(obj); + } + }, STUB_ACC); + } catch (PrivilegedActionException e) { + if (e.getException() instanceof NoSuchObjectException) { + throw (NoSuchObjectException)e.getException(); + } + throw new RuntimeException("Unexpected exception type", e.getException()); + } + } } } From b2e34525abe6f046e30087a74b9c66200784a524 Mon Sep 17 00:00:00 2001 From: Sergey Gabdurakhmanov Date: Fri, 9 Aug 2013 11:03:33 +0400 Subject: [PATCH 0062/1294] 8020789: Disable exporting of gc.heap_dump diagnostic command Reviewed-by: fparain, ahgross --- hotspot/src/share/vm/services/diagnosticCommand.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp index 79c922a8586..162010e425e 100644 --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp @@ -48,7 +48,7 @@ void DCmdRegistrant::register_dcmds(){ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); #if INCLUDE_SERVICES // Heap dumping/inspection supported - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); #endif // INCLUDE_SERVICES From cd65f6f9739f4bf09fa9e14433acc203ec3c907f Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Thu, 29 Aug 2013 18:58:18 -0700 Subject: [PATCH 0063/1294] 8023881: IDN.USE_STD3_ASCII_RULES option is too strict to use Unicode in IDN.toASCII Reviewed-by: michaelm --- jdk/src/share/classes/java/net/IDN.java | 40 +++++----- jdk/test/java/net/IDN/UseSTD3ASCIIRules.java | 80 ++++++++++++++++++++ 2 files changed, 99 insertions(+), 21 deletions(-) create mode 100644 jdk/test/java/net/IDN/UseSTD3ASCIIRules.java diff --git a/jdk/src/share/classes/java/net/IDN.java b/jdk/src/share/classes/java/net/IDN.java index ed2f3a38159..34642b9824c 100644 --- a/jdk/src/share/classes/java/net/IDN.java +++ b/jdk/src/share/classes/java/net/IDN.java @@ -292,13 +292,17 @@ public final class IDN { if (useSTD3ASCIIRules) { for (int i = 0; i < dest.length(); i++) { int c = dest.charAt(i); - if (!isLDHChar(c)) { - throw new IllegalArgumentException("Contains non-LDH characters"); + if (isNonLDHAsciiCodePoint(c)) { + throw new IllegalArgumentException( + "Contains non-LDH ASCII characters"); } } - if (dest.charAt(0) == '-' || dest.charAt(dest.length() - 1) == '-') { - throw new IllegalArgumentException("Has leading or trailing hyphen"); + if (dest.charAt(0) == '-' || + dest.charAt(dest.length() - 1) == '-') { + + throw new IllegalArgumentException( + "Has leading or trailing hyphen"); } } @@ -401,26 +405,20 @@ public final class IDN { // // LDH stands for "letter/digit/hyphen", with characters restricted to the // 26-letter Latin alphabet , the digits <0-9>, and the hyphen - // <-> - // non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x56..0x60, 0x7B..0x7F + // <->. + // Non LDH refers to characters in the ASCII range, but which are not + // letters, digits or the hypen. // - private static boolean isLDHChar(int ch){ - // high runner case - if(ch > 0x007A){ - return false; - } - //['-' '0'..'9' 'A'..'Z' 'a'..'z'] - if((ch == 0x002D) || - (0x0030 <= ch && ch <= 0x0039) || - (0x0041 <= ch && ch <= 0x005A) || - (0x0061 <= ch && ch <= 0x007A) - ){ - return true; - } - return false; + // non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x5B..0x60, 0x7B..0x7F + // + private static boolean isNonLDHAsciiCodePoint(int ch){ + return (0x0000 <= ch && ch <= 0x002C) || + (0x002E <= ch && ch <= 0x002F) || + (0x003A <= ch && ch <= 0x0040) || + (0x005B <= ch && ch <= 0x0060) || + (0x007B <= ch && ch <= 0x007F); } - // // search dots in a string and return the index of that character; // or if there is no dots, return the length of input string diff --git a/jdk/test/java/net/IDN/UseSTD3ASCIIRules.java b/jdk/test/java/net/IDN/UseSTD3ASCIIRules.java new file mode 100644 index 00000000000..0afc4a912ca --- /dev/null +++ b/jdk/test/java/net/IDN/UseSTD3ASCIIRules.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, 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 8023881 + * @summary IDN.USE_STD3_ASCII_RULES option is too strict to use Unicode + * in IDN.toASCII + */ + +import java.net.*; + +public class UseSTD3ASCIIRules { + + public static void main(String[] args) throws Exception { + // Per Section 4.1, RFC 3490, if the UseSTD3ASCIIRules flag is set, + // then perform these checks: + // + // (a) Verify the absence of non-LDH ASCII code points; that is, the + // absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F. + // + // (b) Verify the absence of leading and trailing hyphen-minus; that + // is, the absence of U+002D at the beginning and end of the + // sequence. + String[] illegalNames = { + "www.example.com-", + "-www.example.com", + "-www.example.com-", + "www.ex\u002Cmple.com", + "www.ex\u007Bmple.com", + "www.ex\u007Fmple.com" + }; + + String[] legalNames = { + "www.ex-ample.com", + "www.ex\u002Dmple.com", // www.ex-mple.com + "www.ex\u007Ample.com", // www.exzmple.com + "www.ex\u3042mple.com", // www.xn--exmple-j43e.com + "www.\u3042\u3044\u3046.com", // www.xn--l8jeg.com + "www.\u793A\u4F8B.com" // www.xn--fsq092h.com + }; + + for (String name : illegalNames) { + try { + System.out.println("Convering illegal IDN: " + name); + IDN.toASCII(name, IDN.USE_STD3_ASCII_RULES); + throw new Exception( + "Expected to get IllegalArgumentException for " + name); + } catch (IllegalArgumentException iae) { + // That's the right behavior. + } + } + + for (String name : legalNames) { + System.out.println("Convering legal IDN: " + name); + System.out.println("\tThe ACE form is: " + + IDN.toASCII(name, IDN.USE_STD3_ASCII_RULES)); + } + } +} From dbca0a2b8590e59b65e4bb9adfff1d92d96f3757 Mon Sep 17 00:00:00 2001 From: Shanliang Jiang Date: Fri, 30 Aug 2013 12:49:41 +0200 Subject: [PATCH 0064/1294] 6566891: RMIConnector: map value referencing map key in WeakHashMap prevents map entry to be removed Reviewed-by: egahlin, jbachorik, dfuchs, dholmes --- .../management/remote/rmi/RMIConnector.java | 33 +++-- .../RMIConnectorInternalMapTest.java | 122 ++++++++++++++++++ .../RMIConnectorNullSubjectConnTest.java | 105 +++++++++++++++ 3 files changed, 250 insertions(+), 10 deletions(-) create mode 100644 jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java create mode 100644 jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java diff --git a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java index 53e6754e6ed..4868b94b2ff 100644 --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java @@ -405,14 +405,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable throw new IOException("Not connected"); } - MBeanServerConnection rmbsc = rmbscMap.get(delegationSubject); - if (rmbsc != null) { - return rmbsc; - } - - rmbsc = new RemoteMBeanServerConnection(delegationSubject); - rmbscMap.put(delegationSubject, rmbsc); - return rmbsc; + return getConnectionWithSubject(delegationSubject); } public void @@ -1831,7 +1824,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable // Initialization of transient variables. private void initTransients() { - rmbscMap = new WeakHashMap(); + rmbscMap = new WeakHashMap>(); connected = false; terminated = false; @@ -2011,6 +2004,25 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable private final ClassLoader loader; } + private MBeanServerConnection getConnectionWithSubject(Subject delegationSubject) { + MBeanServerConnection conn = null; + + if (delegationSubject == null) { + if (nullSubjectConnRef == null + || (conn = nullSubjectConnRef.get()) == null) { + conn = new RemoteMBeanServerConnection(null); + nullSubjectConnRef = new WeakReference(conn); + } + } else { + WeakReference wr = rmbscMap.get(delegationSubject); + if (wr == null || (conn = wr.get()) == null) { + conn = new RemoteMBeanServerConnection(delegationSubject); + rmbscMap.put(delegationSubject, new WeakReference(conn)); + } + } + return conn; + } + /* The following section of code avoids a class loading problem with RMI. The problem is that an RMI stub, when deserializing @@ -2551,7 +2563,8 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable private transient long clientNotifSeqNo = 0; - private transient WeakHashMap rmbscMap; + private transient WeakHashMap> rmbscMap; + private transient WeakReference nullSubjectConnRef = null; private transient RMINotifClient rmiNotifClient; // = new RMINotifClient(new Integer(0)); diff --git a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java new file mode 100644 index 00000000000..86efed134f3 --- /dev/null +++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.management.ManagementFactory; +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Map; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXPrincipal; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.rmi.RMIConnector; +import javax.security.auth.Subject; + +/* + * @test + * @bug 6566891 + * @summary Check no memory leak on RMIConnector's rmbscMap + * @author Shanliang JIANG + * @run clean RMIConnectorInternalMapTest + * @run build RMIConnectorInternalMapTest + * @run main RMIConnectorInternalMapTest + */ + +public class RMIConnectorInternalMapTest { + public static void main(String[] args) throws Exception { + System.out.println("---RMIConnectorInternalMapTest starting..."); + + JMXConnectorServer connectorServer = null; + JMXConnector connectorClient = null; + + try { + MBeanServer mserver = ManagementFactory.getPlatformMBeanServer(); + JMXServiceURL serverURL = new JMXServiceURL("rmi", "localhost", 0); + connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serverURL, null, mserver); + connectorServer.start(); + + JMXServiceURL serverAddr = connectorServer.getAddress(); + connectorClient = JMXConnectorFactory.connect(serverAddr, null); + connectorClient.connect(); + + Field rmbscMapField = RMIConnector.class.getDeclaredField("rmbscMap"); + rmbscMapField.setAccessible(true); + Map> map = + (Map>) rmbscMapField.get(connectorClient); + if (map != null && !map.isEmpty()) { // failed + throw new RuntimeException("RMIConnector's rmbscMap must be empty at the initial time."); + } + + Subject delegationSubject = + new Subject(true, + Collections.singleton(new JMXPrincipal("delegate")), + Collections.EMPTY_SET, + Collections.EMPTY_SET); + MBeanServerConnection mbsc1 = + connectorClient.getMBeanServerConnection(delegationSubject); + MBeanServerConnection mbsc2 = + connectorClient.getMBeanServerConnection(delegationSubject); + + if (mbsc1 == null) { + throw new RuntimeException("Got null connection."); + } + if (mbsc1 != mbsc2) { + throw new RuntimeException("Not got same connection with a same subject."); + } + + map = (Map>) rmbscMapField.get(connectorClient); + if (map == null || map.isEmpty()) { // failed + throw new RuntimeException("RMIConnector's rmbscMap has wrong size " + + "after creating a delegated connection."); + } + + delegationSubject = null; + mbsc1 = null; + mbsc2 = null; + + int i = 0; + while (!map.isEmpty() && i++ < 60) { + System.gc(); + Thread.sleep(100); + } + System.out.println("---GC times: " + i); + + if (!map.isEmpty()) { + throw new RuntimeException("Failed to clean RMIConnector's rmbscMap"); + } else { + System.out.println("---RMIConnectorInternalMapTest: PASSED!"); + } + } finally { + try { + connectorClient.close(); + connectorServer.stop(); + } catch (Exception e) { + } + } + } +} diff --git a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java new file mode 100644 index 00000000000..7b5224e9b92 --- /dev/null +++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.management.ManagementFactory; +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.rmi.RMIConnector; + +/* + * @test + * @bug 6566891 + * @summary Check no memory leak on RMIConnector's nullSubjectConn + * @author Shanliang JIANG + * @run clean RMIConnectorNullSubjectConnTest + * @run build RMIConnectorNullSubjectConnTest + * @run main RMIConnectorNullSubjectConnTest + */ + +public class RMIConnectorNullSubjectConnTest { + public static void main(String[] args) throws Exception { + System.out.println("---RMIConnectorNullSubjectConnTest starting..."); + + JMXConnectorServer connectorServer = null; + JMXConnector connectorClient = null; + + try { + MBeanServer mserver = ManagementFactory.getPlatformMBeanServer(); + JMXServiceURL serverURL = new JMXServiceURL("rmi", "localhost", 0); + connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serverURL, null, mserver); + connectorServer.start(); + + JMXServiceURL serverAddr = connectorServer.getAddress(); + connectorClient = JMXConnectorFactory.connect(serverAddr, null); + connectorClient.connect(); + + Field nullSubjectConnField = RMIConnector.class.getDeclaredField("nullSubjectConnRef"); + nullSubjectConnField.setAccessible(true); + + WeakReference weak = + (WeakReference)nullSubjectConnField.get(connectorClient); + + if (weak != null && weak.get() != null) { + throw new RuntimeException("nullSubjectConnRef must be null at initial time."); + } + + MBeanServerConnection conn1 = connectorClient.getMBeanServerConnection(null); + MBeanServerConnection conn2 = connectorClient.getMBeanServerConnection(null); + if (conn1 == null) { + throw new RuntimeException("A connection with null subject should not be null."); + } else if (conn1 != conn2) { + throw new RuntimeException("The 2 connections with null subject are not equal."); + } + + conn1 = null; + conn2 = null; + int i = 1; + do { + System.gc(); + Thread.sleep(100); + weak = (WeakReference)nullSubjectConnField.get(connectorClient); + } while ((weak != null && weak.get() != null) && i++ < 60); + + System.out.println("---GC times: " + i); + + if (weak != null && weak.get() != null) { + throw new RuntimeException("Failed to clean RMIConnector's nullSubjectConn"); + } else { + System.out.println("---RMIConnectorNullSubjectConnTest: PASSED!"); + } + } finally { + try { + connectorClient.close(); + connectorServer.stop(); + } catch (Exception e) { + } + } + } +} From d6854baa4e31c6d02fa25ca51e6d8dd1b539e6ea Mon Sep 17 00:00:00 2001 From: Dan Xu Date: Fri, 30 Aug 2013 16:45:45 -0700 Subject: [PATCH 0065/1294] 8023765: Improve MaxPathLength.java testcase and reduce its test load 7160013: java/io/File/MaxPathLength.java fails Reviewed-by: alanb --- jdk/test/ProblemList.txt | 7 --- jdk/test/java/io/File/MaxPathLength.java | 67 ++++++++++++++---------- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 1f594fe3d3b..26c4eb54a55 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -205,13 +205,6 @@ sun/net/www/http/HttpClient/ProxyTest.java generic-all ############################################################################ -# jdk_io - -# 7160013 -#java/io/File/MaxPathLength.java windows-all - -############################################################################ - # jdk_nio # 6963118 diff --git a/jdk/test/java/io/File/MaxPathLength.java b/jdk/test/java/io/File/MaxPathLength.java index 7ec379cf1d1..9fd6183f36d 100644 --- a/jdk/test/java/io/File/MaxPathLength.java +++ b/jdk/test/java/io/File/MaxPathLength.java @@ -22,7 +22,7 @@ */ /* @test - @bug 4759207 4403166 4165006 4403166 6182812 6274272 + @bug 4759207 4403166 4165006 4403166 6182812 6274272 7160013 @summary Test to see if win32 path length can be greater than 260 */ @@ -37,6 +37,10 @@ public class MaxPathLength { "areallylongfilenamethatsforsur"; private static boolean isWindows = false; + private final static int MAX_LENGTH = 256; + + private static int counter = 0; + public static void main(String[] args) throws Exception { String osName = System.getProperty("os.name"); if (osName.startsWith("Windows")) { @@ -45,33 +49,39 @@ public class MaxPathLength { for (int i = 4; i < 7; i++) { String name = fileName; - while (name.length() < 256) { + while (name.length() < MAX_LENGTH) { testLongPath (i, name, false); testLongPath (i, name, true); - name += "A"; + name = getNextName(name); } } // test long paths on windows + // And these long pathes cannot be handled on Solaris and Mac platforms if (isWindows) { String name = fileName; - while (name.length() < 256) { + while (name.length() < MAX_LENGTH) { testLongPath (20, name, false); testLongPath (20, name, true); - name += "A"; + name = getNextName(name); } } } + private static String getNextName(String fName) { + return (fName.length() < MAX_LENGTH/2) ? fName + fName + : fName + "A"; + } + static void testLongPath(int max, String fn, boolean tryAbsolute) throws Exception { String[] created = new String[max]; String pathString = "."; for (int i = 0; i < max -1; i++) { - pathString = pathString + pathComponent; + pathString = pathString + pathComponent + (counter++); created[max - 1 -i] = pathString; - } + File dirFile = new File(pathString); File f = new File(pathString + sep + fn); @@ -88,9 +98,10 @@ public class MaxPathLength { System.err.println("Warning: Test directory structure exists already!"); return; } - Files.createDirectories(dirFile.toPath()); try { + Files.createDirectories(dirFile.toPath()); + if (tryAbsolute) dirFile = new File(dirFile.getCanonicalPath()); if (!dirFile.isDirectory()) @@ -99,6 +110,7 @@ public class MaxPathLength { if (!f.createNewFile()) { throw new RuntimeException ("File.createNewFile() failed"); } + if (!f.exists()) throw new RuntimeException ("File.exists() failed"); if (!f.isFile()) @@ -107,11 +119,14 @@ public class MaxPathLength { throw new RuntimeException ("File.canRead() failed"); if (!f.canWrite()) throw new RuntimeException ("File.canWrite() failed"); + if (!f.delete()) throw new RuntimeException ("File.delete() failed"); + FileOutputStream fos = new FileOutputStream(f); fos.write(1); fos.close(); + if (f.length() != 1) throw new RuntimeException ("File.length() failed"); long time = System.currentTimeMillis(); @@ -148,30 +163,26 @@ public class MaxPathLength { throw new RuntimeException ("File.renameTo() failed for lenth=" + abPath.length()); } - return; + } else { + if (!nf.canRead()) + throw new RuntimeException ("Renamed file is not readable"); + if (!nf.canWrite()) + throw new RuntimeException ("Renamed file is not writable"); + if (nf.length() != 1) + throw new RuntimeException ("Renamed file's size is not correct"); + if (!nf.renameTo(f)) { + created[0] = nf.getPath(); + } + /* add a script to test these two if we got a regression later + if (!f.setReadOnly()) + throw new RuntimeException ("File.setReadOnly() failed"); + f.deleteOnExit(); + */ } - if (!nf.canRead()) - throw new RuntimeException ("Renamed file is not readable"); - if (!nf.canWrite()) - throw new RuntimeException ("Renamed file is not writable"); - if (nf.length() != 1) - throw new RuntimeException ("Renamed file's size is not correct"); - nf.renameTo(f); - /* add a script to test these two if we got a regression later - if (!f.setReadOnly()) - throw new RuntimeException ("File.setReadOnly() failed"); - f.deleteOnExit(); - */ } finally { // Clean up for (int i = 0; i < max; i++) { - pathString = created[i]; - // Only works with completex canonical paths - File df = new File(pathString); - pathString = df.getCanonicalPath(); - df = new File(pathString); - if (!df.delete()) - System.out.printf("Delete failed->%s\n", pathString); + Files.deleteIfExists((new File(created[i])).toPath()); } } } From 1cff90b3353b16370bd7784ab1f2dd52367d3d1f Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Sun, 1 Sep 2013 20:00:03 -0700 Subject: [PATCH 0066/1294] 8024068: sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java fails Reviewed-by: weijun --- .../security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java index 4d5460739cd..a6a6912c0aa 100644 --- a/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java +++ b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java @@ -34,7 +34,7 @@ public class IllegalSNIName { public static void main(String[] args) throws Exception { String[] illegalNames = { - "example\u3003\u3002com", + "example\u3002\u3002com", "example..com", "com\u3002", "com.", From ff0317b09805c47be8bf6a09cc07150c2dcea4e6 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Mon, 2 Sep 2013 14:02:35 +0100 Subject: [PATCH 0067/1294] 8024103: AtomicLongArray getAndAccumulate/accumulateAndGet have int type for new value arg Reviewed-by: alanb, psandoz --- .../classes/java/util/concurrent/atomic/AtomicLongArray.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java index bf7aa6ecca8..28174a586ff 100644 --- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java +++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java @@ -303,7 +303,7 @@ public class AtomicLongArray implements java.io.Serializable { * @return the previous value * @since 1.8 */ - public final long getAndAccumulate(int i, int x, + public final long getAndAccumulate(int i, long x, LongBinaryOperator accumulatorFunction) { long offset = checkedByteOffset(i); long prev, next; @@ -329,7 +329,7 @@ public class AtomicLongArray implements java.io.Serializable { * @return the updated value * @since 1.8 */ - public final long accumulateAndGet(int i, int x, + public final long accumulateAndGet(int i, long x, LongBinaryOperator accumulatorFunction) { long offset = checkedByteOffset(i); long prev, next; From b81e7785d1fd24ed0833d7b14b04a9383734cfcd Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Mon, 2 Sep 2013 18:28:50 +0200 Subject: [PATCH 0068/1294] 8016127: NLS: logging.properties translatability recommendation 8024131: Issues with cached localizedLevelName in java.util.logging.Level This fix updates logging.properties resource bundles to follow internationalization guidelines. It also fixes a caching issue with localizedLevelName. The regression test that was added needs both fixes to pass. Reviewed-by: mchung, alanb --- .../classes/java/util/logging/Level.java | 72 +++++++++++- .../util/logging/resources/logging.properties | 18 +-- .../logging/resources/logging_de.properties | 18 +-- .../logging/resources/logging_es.properties | 18 +-- .../logging/resources/logging_fr.properties | 18 +-- .../logging/resources/logging_it.properties | 18 +-- .../logging/resources/logging_ja.properties | 12 +- .../logging/resources/logging_ko.properties | 18 +-- .../resources/logging_pt_BR.properties | 18 +-- .../logging/resources/logging_sv.properties | 18 +-- .../resources/logging_zh_CN.properties | 18 +-- .../resources/logging_zh_TW.properties | 12 +- .../java/util/logging/LocalizedLevelName.java | 103 ++++++++++++++++++ 13 files changed, 262 insertions(+), 99 deletions(-) create mode 100644 jdk/test/java/util/logging/LocalizedLevelName.java diff --git a/jdk/src/share/classes/java/util/logging/Level.java b/jdk/src/share/classes/java/util/logging/Level.java index 6847518ce02..936925624e4 100644 --- a/jdk/src/share/classes/java/util/logging/Level.java +++ b/jdk/src/share/classes/java/util/logging/Level.java @@ -27,6 +27,7 @@ package java.util.logging; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; @@ -63,7 +64,7 @@ import java.util.ResourceBundle; */ public class Level implements java.io.Serializable { - private static String defaultBundle = "sun.util.logging.resources.logging"; + private static final String defaultBundle = "sun.util.logging.resources.logging"; /** * @serial The non-localized name of the level. @@ -81,7 +82,8 @@ public class Level implements java.io.Serializable { private final String resourceBundleName; // localized level name - private String localizedLevelName; + private transient String localizedLevelName; + private transient Locale cachedLocale; /** * OFF is a special level that can be used to turn off logging. @@ -209,6 +211,7 @@ public class Level implements java.io.Serializable { this.value = value; this.resourceBundleName = resourceBundleName; this.localizedLevelName = resourceBundleName == null ? name : null; + this.cachedLocale = null; KnownLevel.add(this); } @@ -250,17 +253,71 @@ public class Level implements java.io.Serializable { return this.name; } - final synchronized String getLocalizedLevelName() { + private String computeLocalizedLevelName(Locale newLocale) { + ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName, newLocale); + final String localizedName = rb.getString(name); + + final boolean isDefaultBundle = defaultBundle.equals(resourceBundleName); + if (!isDefaultBundle) return localizedName; + + // This is a trick to determine whether the name has been translated + // or not. If it has not been translated, we need to use Locale.ROOT + // when calling toUpperCase(). + final Locale rbLocale = rb.getLocale(); + final Locale locale = + Locale.ROOT.equals(rbLocale) + || name.equals(localizedName.toUpperCase(Locale.ROOT)) + ? Locale.ROOT : rbLocale; + + // ALL CAPS in a resource bundle's message indicates no translation + // needed per Oracle translation guideline. To workaround this + // in Oracle JDK implementation, convert the localized level name + // to uppercase for compatibility reason. + return Locale.ROOT.equals(locale) ? name : localizedName.toUpperCase(locale); + } + + // Avoid looking up the localizedLevelName twice if we already + // have it. + final String getCachedLocalizedLevelName() { + if (localizedLevelName != null) { - return localizedLevelName; + if (cachedLocale != null) { + if (cachedLocale.equals(Locale.getDefault())) { + // OK: our cached value was looked up with the same + // locale. We can use it. + return localizedLevelName; + } + } } + if (resourceBundleName == null) { + // No resource bundle: just use the name. + return name; + } + + // We need to compute the localized name. + // Either because it's the first time, or because our cached + // value is for a different locale. Just return null. + return null; + } + + final synchronized String getLocalizedLevelName() { + + // See if we have a cached localized name + final String cachedLocalizedName = getCachedLocalizedLevelName(); + if (cachedLocalizedName != null) { + return cachedLocalizedName; + } + + // No cached localized name or cache invalid. + // Need to compute the localized name. + final Locale newLocale = Locale.getDefault(); try { - ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName); - localizedLevelName = rb.getString(name); + localizedLevelName = computeLocalizedLevelName(newLocale); } catch (Exception ex) { localizedLevelName = name; } + cachedLocale = newLocale; return localizedLevelName; } @@ -318,6 +375,7 @@ public class Level implements java.io.Serializable { * * @return the non-localized name of the Level, for example "INFO". */ + @Override public final String toString() { return name; } @@ -420,6 +478,7 @@ public class Level implements java.io.Serializable { * Compare two objects for value equality. * @return true if and only if the two objects have the same level value. */ + @Override public boolean equals(Object ox) { try { Level lx = (Level)ox; @@ -433,6 +492,7 @@ public class Level implements java.io.Serializable { * Generate a hashcode. * @return a hashcode based on the level value */ + @Override public int hashCode() { return this.value; } diff --git a/jdk/src/share/classes/sun/util/logging/resources/logging.properties b/jdk/src/share/classes/sun/util/logging/resources/logging.properties index da17c47f8fd..248b4d7fcbe 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging.properties @@ -27,20 +27,20 @@ # these are the same as the non-localized level name. # The following ALL CAPS words should be translated. -ALL=ALL +ALL=All # The following ALL CAPS words should be translated. -SEVERE=SEVERE +SEVERE=Severe # The following ALL CAPS words should be translated. -WARNING=WARNING +WARNING=Warning # The following ALL CAPS words should be translated. -INFO=INFO +INFO=Info # The following ALL CAPS words should be translated. -CONFIG= CONFIG +CONFIG= Config # The following ALL CAPS words should be translated. -FINE=FINE +FINE=Fine # The following ALL CAPS words should be translated. -FINER=FINER +FINER=Finer # The following ALL CAPS words should be translated. -FINEST=FINEST +FINEST=Finest # The following ALL CAPS words should be translated. -OFF=OFF +OFF=Off diff --git a/jdk/src/share/classes/sun/util/logging/resources/logging_de.properties b/jdk/src/share/classes/sun/util/logging/resources/logging_de.properties index da17c47f8fd..1aa8ef4e22c 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging_de.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging_de.properties @@ -27,20 +27,20 @@ # these are the same as the non-localized level name. # The following ALL CAPS words should be translated. -ALL=ALL +ALL=Alle # The following ALL CAPS words should be translated. -SEVERE=SEVERE +SEVERE=Schwerwiegend # The following ALL CAPS words should be translated. -WARNING=WARNING +WARNING=Warnung # The following ALL CAPS words should be translated. -INFO=INFO +INFO=Information # The following ALL CAPS words should be translated. -CONFIG= CONFIG +CONFIG= Konfiguration # The following ALL CAPS words should be translated. -FINE=FINE +FINE=Fein # The following ALL CAPS words should be translated. -FINER=FINER +FINER=Feiner # The following ALL CAPS words should be translated. -FINEST=FINEST +FINEST=Am feinsten # The following ALL CAPS words should be translated. -OFF=OFF +OFF=Deaktiviert diff --git a/jdk/src/share/classes/sun/util/logging/resources/logging_es.properties b/jdk/src/share/classes/sun/util/logging/resources/logging_es.properties index da17c47f8fd..90de2e88238 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging_es.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging_es.properties @@ -27,20 +27,20 @@ # these are the same as the non-localized level name. # The following ALL CAPS words should be translated. -ALL=ALL +ALL=Todo # The following ALL CAPS words should be translated. -SEVERE=SEVERE +SEVERE=Grave # The following ALL CAPS words should be translated. -WARNING=WARNING +WARNING=Advertencia # The following ALL CAPS words should be translated. -INFO=INFO +INFO=Informaci\u00F3n # The following ALL CAPS words should be translated. -CONFIG= CONFIG +CONFIG= Configurar # The following ALL CAPS words should be translated. -FINE=FINE +FINE=Detallado # The following ALL CAPS words should be translated. -FINER=FINER +FINER=Muy Detallado # The following ALL CAPS words should be translated. -FINEST=FINEST +FINEST=M\u00E1s Detallado # The following ALL CAPS words should be translated. -OFF=OFF +OFF=Desactivado diff --git a/jdk/src/share/classes/sun/util/logging/resources/logging_fr.properties b/jdk/src/share/classes/sun/util/logging/resources/logging_fr.properties index da17c47f8fd..af34d6fa414 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging_fr.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging_fr.properties @@ -27,20 +27,20 @@ # these are the same as the non-localized level name. # The following ALL CAPS words should be translated. -ALL=ALL +ALL=Tout # The following ALL CAPS words should be translated. -SEVERE=SEVERE +SEVERE=Grave # The following ALL CAPS words should be translated. -WARNING=WARNING +WARNING=Avertissement # The following ALL CAPS words should be translated. -INFO=INFO +INFO=Infos # The following ALL CAPS words should be translated. -CONFIG= CONFIG +CONFIG= Config # The following ALL CAPS words should be translated. -FINE=FINE +FINE=Pr\u00E9cis # The following ALL CAPS words should be translated. -FINER=FINER +FINER=Plus pr\u00E9cis # The following ALL CAPS words should be translated. -FINEST=FINEST +FINEST=Le plus pr\u00E9cis # The following ALL CAPS words should be translated. -OFF=OFF +OFF=D\u00E9sactiv\u00E9 diff --git a/jdk/src/share/classes/sun/util/logging/resources/logging_it.properties b/jdk/src/share/classes/sun/util/logging/resources/logging_it.properties index da17c47f8fd..73a3b5c59cf 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging_it.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging_it.properties @@ -27,20 +27,20 @@ # these are the same as the non-localized level name. # The following ALL CAPS words should be translated. -ALL=ALL +ALL=Tutto # The following ALL CAPS words should be translated. -SEVERE=SEVERE +SEVERE=Grave # The following ALL CAPS words should be translated. -WARNING=WARNING +WARNING=Avvertenza # The following ALL CAPS words should be translated. -INFO=INFO +INFO=Informazioni # The following ALL CAPS words should be translated. -CONFIG= CONFIG +CONFIG= Configurazione # The following ALL CAPS words should be translated. -FINE=FINE +FINE=Buono # The following ALL CAPS words should be translated. -FINER=FINER +FINER=Migliore # The following ALL CAPS words should be translated. -FINEST=FINEST +FINEST=Ottimale # The following ALL CAPS words should be translated. -OFF=OFF +OFF=Non attivo diff --git a/jdk/src/share/classes/sun/util/logging/resources/logging_ja.properties b/jdk/src/share/classes/sun/util/logging/resources/logging_ja.properties index 980c33549c5..60358d1c86e 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging_ja.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging_ja.properties @@ -29,18 +29,18 @@ # The following ALL CAPS words should be translated. ALL=\u3059\u3079\u3066 # The following ALL CAPS words should be translated. -SEVERE=SEVERE +SEVERE=\u91CD\u5927 # The following ALL CAPS words should be translated. -WARNING=WARNING +WARNING=\u8B66\u544A # The following ALL CAPS words should be translated. INFO=\u60C5\u5831 # The following ALL CAPS words should be translated. -CONFIG= CONFIG +CONFIG= \u69CB\u6210 # The following ALL CAPS words should be translated. -FINE=\u8A73\u7D30\u30EC\u30D9\u30EB(\u4F4E) +FINE=\u666E\u901A # The following ALL CAPS words should be translated. -FINER=FINER +FINER=\u8A73\u7D30 # The following ALL CAPS words should be translated. -FINEST=FINEST +FINEST=\u6700\u3082\u8A73\u7D30 # The following ALL CAPS words should be translated. OFF=\u30AA\u30D5 diff --git a/jdk/src/share/classes/sun/util/logging/resources/logging_ko.properties b/jdk/src/share/classes/sun/util/logging/resources/logging_ko.properties index da17c47f8fd..6d5dc551e67 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging_ko.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging_ko.properties @@ -27,20 +27,20 @@ # these are the same as the non-localized level name. # The following ALL CAPS words should be translated. -ALL=ALL +ALL=\uBAA8\uB450 # The following ALL CAPS words should be translated. -SEVERE=SEVERE +SEVERE=\uC2EC\uAC01 # The following ALL CAPS words should be translated. -WARNING=WARNING +WARNING=\uACBD\uACE0 # The following ALL CAPS words should be translated. -INFO=INFO +INFO=\uC815\uBCF4 # The following ALL CAPS words should be translated. -CONFIG= CONFIG +CONFIG= \uAD6C\uC131 # The following ALL CAPS words should be translated. -FINE=FINE +FINE=\uBBF8\uC138 # The following ALL CAPS words should be translated. -FINER=FINER +FINER=\uBCF4\uB2E4 \uBBF8\uC138 # The following ALL CAPS words should be translated. -FINEST=FINEST +FINEST=\uAC00\uC7A5 \uBBF8\uC138 # The following ALL CAPS words should be translated. -OFF=OFF +OFF=\uD574\uC81C diff --git a/jdk/src/share/classes/sun/util/logging/resources/logging_pt_BR.properties b/jdk/src/share/classes/sun/util/logging/resources/logging_pt_BR.properties index da17c47f8fd..29229f2c7c1 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging_pt_BR.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging_pt_BR.properties @@ -27,20 +27,20 @@ # these are the same as the non-localized level name. # The following ALL CAPS words should be translated. -ALL=ALL +ALL=Tudo # The following ALL CAPS words should be translated. -SEVERE=SEVERE +SEVERE=Grave # The following ALL CAPS words should be translated. -WARNING=WARNING +WARNING=Advert\u00EAncia # The following ALL CAPS words should be translated. -INFO=INFO +INFO=Informa\u00E7\u00F5es # The following ALL CAPS words should be translated. -CONFIG= CONFIG +CONFIG= Configura\u00E7\u00E3o # The following ALL CAPS words should be translated. -FINE=FINE +FINE=Detalhado # The following ALL CAPS words should be translated. -FINER=FINER +FINER=Mais Detalhado # The following ALL CAPS words should be translated. -FINEST=FINEST +FINEST=O Mais Detalhado # The following ALL CAPS words should be translated. -OFF=OFF +OFF=Desativado diff --git a/jdk/src/share/classes/sun/util/logging/resources/logging_sv.properties b/jdk/src/share/classes/sun/util/logging/resources/logging_sv.properties index 4c8dd1d2dcb..b7607863ffb 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging_sv.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging_sv.properties @@ -27,20 +27,20 @@ # these are the same as the non-localized level name. # The following ALL CAPS words should be translated. -ALL=ALLA +ALL=Alla # The following ALL CAPS words should be translated. -SEVERE=SEVERE +SEVERE=Allvarlig # The following ALL CAPS words should be translated. -WARNING=WARNING +WARNING=Varning # The following ALL CAPS words should be translated. -INFO=INFO +INFO=Info # The following ALL CAPS words should be translated. -CONFIG= CONFIG +CONFIG= Konfig # The following ALL CAPS words should be translated. -FINE=FINE +FINE=Fin # The following ALL CAPS words should be translated. -FINER=FINER +FINER=Finare # The following ALL CAPS words should be translated. -FINEST=FINEST +FINEST=Finaste # The following ALL CAPS words should be translated. -OFF=OFF +OFF=Av diff --git a/jdk/src/share/classes/sun/util/logging/resources/logging_zh_CN.properties b/jdk/src/share/classes/sun/util/logging/resources/logging_zh_CN.properties index da17c47f8fd..67dd2b8b50a 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging_zh_CN.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging_zh_CN.properties @@ -27,20 +27,20 @@ # these are the same as the non-localized level name. # The following ALL CAPS words should be translated. -ALL=ALL +ALL=\u5168\u90E8 # The following ALL CAPS words should be translated. -SEVERE=SEVERE +SEVERE=\u4E25\u91CD # The following ALL CAPS words should be translated. -WARNING=WARNING +WARNING=\u8B66\u544A # The following ALL CAPS words should be translated. -INFO=INFO +INFO=\u4FE1\u606F # The following ALL CAPS words should be translated. -CONFIG= CONFIG +CONFIG= \u914D\u7F6E # The following ALL CAPS words should be translated. -FINE=FINE +FINE=\u8BE6\u7EC6 # The following ALL CAPS words should be translated. -FINER=FINER +FINER=\u8F83\u8BE6\u7EC6 # The following ALL CAPS words should be translated. -FINEST=FINEST +FINEST=\u975E\u5E38\u8BE6\u7EC6 # The following ALL CAPS words should be translated. -OFF=OFF +OFF=\u7981\u7528 diff --git a/jdk/src/share/classes/sun/util/logging/resources/logging_zh_TW.properties b/jdk/src/share/classes/sun/util/logging/resources/logging_zh_TW.properties index d7ad070a69e..4875bc825c1 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging_zh_TW.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging_zh_TW.properties @@ -27,20 +27,20 @@ # these are the same as the non-localized level name. # The following ALL CAPS words should be translated. -ALL=\u6240\u6709 +ALL=\u5168\u90E8 # The following ALL CAPS words should be translated. -SEVERE=SEVERE +SEVERE=\u56B4\u91CD # The following ALL CAPS words should be translated. -WARNING=WARNING +WARNING=\u8B66\u544A # The following ALL CAPS words should be translated. INFO=\u8CC7\u8A0A # The following ALL CAPS words should be translated. -CONFIG= CONFIG +CONFIG= \u7D44\u614B # The following ALL CAPS words should be translated. FINE=\u8A73\u7D30 # The following ALL CAPS words should be translated. -FINER=FINER +FINER=\u8F03\u8A73\u7D30 # The following ALL CAPS words should be translated. -FINEST=FINEST +FINEST=\u6700\u8A73\u7D30 # The following ALL CAPS words should be translated. OFF=\u95DC\u9589 diff --git a/jdk/test/java/util/logging/LocalizedLevelName.java b/jdk/test/java/util/logging/LocalizedLevelName.java new file mode 100644 index 00000000000..cdb425a294f --- /dev/null +++ b/jdk/test/java/util/logging/LocalizedLevelName.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.*; +import java.util.logging.*; + +/* + * @test + * @bug 8016127 8024131 + * @summary test logging.properties localized + * @run main/othervm LocalizedLevelName + */ + +public class LocalizedLevelName { + private static Object[] namesMap = { + "SEVERE", Locale.ENGLISH, "Severe", Level.SEVERE, + "WARNING", Locale.FRENCH, "Avertissement", Level.WARNING, + "INFO", Locale.ITALIAN, "Informazioni", Level.INFO, + "SEVERE", Locale.FRENCH, "Grave", Level.SEVERE, + "CONFIG", Locale.GERMAN, "Konfiguration", Level.CONFIG, + "ALL", Locale.ROOT, "All", Level.ALL, + "SEVERE", Locale.ROOT, "Severe", Level.SEVERE, + "WARNING", Locale.ROOT, "Warning", Level.WARNING, + "CONFIG", Locale.ROOT, "Config", Level.CONFIG, + "INFO", Locale.ROOT, "Info", Level.INFO, + "FINE", Locale.ROOT, "Fine", Level.FINE, + "FINER", Locale.ROOT, "Finer", Level.FINER, + "FINEST", Locale.ROOT, "Finest", Level.FINEST + }; + + public static void main(String args[]) throws Exception { + Locale defaultLocale = Locale.getDefault(); + for (int i=0; i localized(" + Locale.ENGLISH + ", " + + key + ")=" + en); + System.out.println(" => localized(" + locale + ", " + key + + ")=" + other); + if (!key.equals(en.toUpperCase(Locale.ROOT))) { + throw new RuntimeException("Expect " + key + + " equals upperCase(" + en + ")"); + } + if (!Locale.ENGLISH.equals(locale) && !Locale.ROOT.equals(locale) + && key.equals(other.toUpperCase(Locale.ROOT))) { + throw new RuntimeException("Expect " + key + + " not equals upperCase(" + other +")"); + } + if ((Locale.ENGLISH.equals(locale) || Locale.ROOT.equals(locale)) + && !key.equals(other.toUpperCase(Locale.ROOT))) { + throw new RuntimeException("Expect " + key + + " equals upperCase(" + other +")"); + } + if (!other.equals(expectedTranslation)) { + throw new RuntimeException("Expected \"" + expectedTranslation + + "\" for '" + locale + "' but got \"" + other + "\""); + } + Locale.setDefault(locale); + final String levelName = level.getLocalizedName(); + System.out.println("Level.getLocalizedName() is: " + levelName); + if (!levelName.equals(other.toUpperCase(locale))) { + throw new RuntimeException("Expected \"" + + other.toUpperCase(locale) + "\" for '" + + locale + "' but got \"" + levelName + "\""); + } + Locale.setDefault(defaultLocale); + } + } + + private static final String RBNAME = "sun.util.logging.resources.logging"; + private static String getLocalizedMessage(Locale locale, String key) { + ResourceBundle rb = ResourceBundle.getBundle(RBNAME, locale); + return rb.getString(key); + } +} From f4dda09731a2ceb1a6a633589f14a7a68828eeeb Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Mon, 2 Sep 2013 16:03:34 +0200 Subject: [PATCH 0069/1294] 7172176: java/jconsole test/sun/tools/jconsole/ImmutableResourceTest.sh failing Reviewed-by: mchung, mfang --- .../classes/sun/tools/jconsole/Resources.java | 6 +- jdk/test/ProblemList.txt | 4 - .../tools/jconsole/ImmutableResourceTest.java | 60 --- .../tools/jconsole/ImmutableResourceTest.sh | 111 ----- .../sun/tools/jconsole/ResourceCheckTest.java | 469 +++++------------- .../sun/tools/jconsole/ResourceCheckTest.sh | 4 +- 6 files changed, 118 insertions(+), 536 deletions(-) delete mode 100644 jdk/test/sun/tools/jconsole/ImmutableResourceTest.java delete mode 100644 jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh diff --git a/jdk/src/share/classes/sun/tools/jconsole/Resources.java b/jdk/src/share/classes/sun/tools/jconsole/Resources.java index 785be24d2e6..20af2e9f9e9 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/Resources.java +++ b/jdk/src/share/classes/sun/tools/jconsole/Resources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.text.MessageFormat; import java.util.Collections; -import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; @@ -40,7 +40,7 @@ import java.util.ResourceBundle; */ public final class Resources { private static Map MNEMONIC_LOOKUP = Collections - .synchronizedMap(new HashMap()); + .synchronizedMap(new IdentityHashMap()); private Resources() { throw new AssertionError(); diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 26c4eb54a55..1ac61aa2c3f 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -305,10 +305,6 @@ sun/security/krb5/auto/BadKdc4.java solaris-sparcv9 # 6461635 com/sun/tools/attach/BasicTests.sh generic-all -# 7172176 -sun/tools/jconsole/ResourceCheckTest.sh generic-all -sun/tools/jconsole/ImmutableResourceTest.sh generic-all - # 7132203 sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all diff --git a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java b/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java deleted file mode 100644 index 082776667a4..00000000000 --- a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * - * - * This isn't the test case: ImmutableResourceTest.sh is. - * Refer to ImmutableResourceTest.sh when running this test. - * - * @bug 6287579 - * @summary SubClasses of ListResourceBundle should fix getContents() - */ -import java.util.ResourceBundle; - -public class ImmutableResourceTest { - - public static void main(String[] args) throws Exception { - - /* Reach under the covers and get the message strings */ - sun.tools.jconsole.resources.JConsoleResources jcr = - new sun.tools.jconsole.resources.JConsoleResources (); - Object [][] testData = jcr.getContents(); - - /* Shred our copy of the message strings */ - for (int ii = 0; ii < testData.length; ii++) { - testData[ii][0] = "xxx"; - testData[ii][1] = "yyy"; - } - - /* - * Try a lookup for the shredded key. - * If this is successful we have a problem. - */ - String ss = sun.tools.jconsole.Resources.getText("xxx"); - if ("yyy".equals(ss)) { - throw new Exception ("SubClasses of ListResourceBundle should fix getContents()"); - } - System.out.println("...Finished."); - } -} diff --git a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh b/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh deleted file mode 100644 index dedf21271b0..00000000000 --- a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh +++ /dev/null @@ -1,111 +0,0 @@ -# -# Copyright (c) 2005, 2012, 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 6287579 -# @summary SubClasses of ListResourceBundle should fix getContents() -# -# @run shell ImmutableResourceTest.sh - -# Beginning of subroutines: -status=1 - -#Call this from anywhere to fail the test with an error message -# usage: fail "reason why the test failed" -fail() - { echo "The test failed :-(" - echo "$*" 1>&2 - echo "exit status was $status" - exit $status - } #end of fail() - -#Call this from anywhere to pass the test with a message -# usage: pass "reason why the test passed if applicable" -pass() - { echo "The test passed!!!" - echo "$*" 1>&2 - exit 0 - } #end of pass() - -# end of subroutines - -# The beginning of the script proper - -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - PATHSEP=":" - ;; - - Windows* | CYGWIN*) - PATHSEP=";" - ;; - - # catch all other OSs - * ) - echo "Unrecognized system! $OS" - fail "Unrecognized system! $OS" - ;; -esac - -TARGETCLASS="ImmutableResourceTest" -if [ -z "${TESTJAVA}" ] ; then - # TESTJAVA is not set, so the test is running stand-alone. - # TESTJAVA holds the path to the root directory of the build of the JDK - # to be tested. That is, any java files run explicitly in this shell - # should use TESTJAVA in the path to the java interpreter. - # So, we'll set this to the JDK spec'd on the command line. If none - # is given on the command line, tell the user that and use a default. - # THIS IS THE JDK BEING TESTED. - if [ -n "$1" ] ; then - TESTJAVA=$1 - else - TESTJAVA=$JAVA_HOME - fi - TESTSRC=. - TESTCLASSES=. - #Deal with .class files: -fi -# -echo "JDK under test is: $TESTJAVA" -# -CP="-classpath ${TESTCLASSES}${PATHSEP}${TESTJAVA}/lib/jconsole.jar" -# Compile the test class using the classpath we need: -# -env -# -set -vx -# -#Compile. jconsole.jar is required on the classpath. -${TESTJAVA}/bin/javac -d "${TESTCLASSES}" ${CP} -g \ - "${TESTSRC}"/"${TARGETCLASS}".java -# -#Run the test class, again with the classpath we need: -${TESTJAVA}/bin/java ${CP} ${TARGETCLASS} -status=$? -echo "test status was: $status" -if [ $status -eq "0" ]; - then pass "" - - else fail "unspecified test failure" -fi diff --git a/jdk/test/sun/tools/jconsole/ResourceCheckTest.java b/jdk/test/sun/tools/jconsole/ResourceCheckTest.java index 6d4e27be860..1ed5bb642c7 100644 --- a/jdk/test/sun/tools/jconsole/ResourceCheckTest.java +++ b/jdk/test/sun/tools/jconsole/ResourceCheckTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,377 +27,134 @@ * This isn't the test case: ResourceCheckTest.sh is. * Refer to ResourceCheckTest.sh when running this test. * - * @bug 5008856 5023573 5024917 5062569 + * @bug 5008856 5023573 5024917 5062569 7172176 * @summary 'missing resource key' error for key = "Operating system" */ -import java.awt.event.KeyEvent; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.ResourceBundle; +import sun.tools.jconsole.Messages; import sun.tools.jconsole.Resources; +/* + * Ensures that there is a one-to-one mapping between constants in the + * Message class and the keys in the sun.tools.jconsole.resources.messages + * bundle. + * + * An error will be thrown if there is a: + * + * - key in the resource bundle that doesn't have a public static field with + * the same name in the Message class. + * + * - public static field in the Message class that doesn't have a key with + * the same name in the resource bundle. + * + * - message with a mnemonic identifier(&) for which a mnemonic can't + * be looked up using Resources#getMnemonicInt(). + * + */ public class ResourceCheckTest { + private static final String MISSING_RESOURCE_KEY_PREFIX = "missing message for"; + private static final String RESOURCE_BUNDLE = "sun.tools.jconsole.resources.messages"; + private static final String NEW_LINE = String.format("%n"); - public static void main(String[] args){ - Object [][] testData = { - {"<", "", "", "", ""}, - {"<<", "", "", "", ""}, - {">", "", "", "", ""}, - {" 1 day", "", "", "", ""}, - {" 1 hour", "", "", "", ""}, - {" 1 min", "", "", "", ""}, - {" 1 month", "", "", "", ""}, - {" 1 year", "", "", "", ""}, - {" 2 hours", "", "", "", ""}, - {" 3 hours", "", "", "", ""}, - {" 3 months", "", "", "", ""}, - {" 5 min", "", "", "", ""}, - {" 6 hours", "", "", "", ""}, - {" 6 months", "", "", "", ""}, - {" 7 days", "", "", "", ""}, - {"10 min", "", "", "", ""}, - {"12 hours", "", "", "", ""}, - {"30 min", "", "", "", ""}, - {"ACTION", "", "", "", ""}, - {"ACTION_INFO", "", "", "", ""}, - {"All", "", "", "", ""}, - {"Architecture", "", "", "", ""}, - {"Attribute", "", "", "", ""}, - {"Attribute value", "", "", "", ""}, - {"Attribute values", "", "", "", ""}, - {"Attributes", "", "", "", ""}, - {"Blank", "", "", "", ""}, - {"BlockedCount WaitedCount", "BlockedCount", "WaitedCount", "", ""}, - {"Boot class path", "", "", "", ""}, - {"BorderedComponent.moreOrLessButton.toolTip", "", "", "", ""}, - {"Close", "", "", "", ""}, - {"CPU Usage", "", "", "", ""}, - {"CPUUsageFormat","PhonyPercentage", "", "", ""}, - {"Cancel", "", "", "", ""}, - {"Cascade", "", "", "", ""}, - {"Cascade.mnemonic", "", "", "", ""}, - {"Chart:", "", "", "", ""}, - {"Chart:.mnemonic", "", "", "", ""}, - {"ClassTab.infoLabelFormat", "LoadedCount", "UnloadedCount", "TotalCount", ""}, - {"ClassTab.loadedClassesPlotter.accessibleName", "", "", "", ""}, - {"Class path", "", "", "", ""}, - {"Classes", "", "", "", ""}, - {"ClassName", "", "", "", ""}, - {"Column.Name", "", "", "", ""}, - {"Column.PID", "", "", "", ""}, - {"Committed", "", "", "", ""}, - {"Committed memory", "", "", "", ""}, - {"Committed virtual memory", "", "", "", ""}, - {"Compiler", "", "", "", ""}, - {"Connect...", "", "", "", ""}, - {"Connect", "", "", "", ""}, - {"Connect.mnemonic", "", "", "", ""}, - {"ConnectDialog.connectButton.toolTip", "", "", "", ""}, - {"ConnectDialog.accessibleDescription", "", "", "", ""}, - {"ConnectDialog.masthead.accessibleName", "", "", "", ""}, - {"ConnectDialog.masthead.title", "", "", "", ""}, - {"ConnectDialog.statusBar.accessibleName", "", "", "", ""}, - {"ConnectDialog.title", "", "", "", ""}, - {"Connected. Click to disconnect.", "", "", "", ""}, - {"connectingTo1", "PhonyConnectionName", "", "", ""}, - {"connectingTo2", "PhonyConnectionName", "", "", ""}, - {"connectionFailed1", "", "", "", ""}, - {"connectionFailed2", "PhonyConnectionName", "", "", ""}, - {"connectionLost1", "", "", "", ""}, - {"connectionLost2", "PhonyConnectionName", "", "", ""}, - {"Connection failed", "", "", "", ""}, - {"Connection", "", "", "", ""}, - {"Connection.mnemonic", "", "", "", ""}, - {"Connection name", "", "", "", ""}, - {"ConnectionName (disconnected)", "Phony", "Phony", "", ""}, - {"Constructor", "", "", "", ""}, - {"Create", "Phony", "Phony", "", ""}, - {"Current classes loaded", "", "", "", ""}, - {"Current heap size", "", "", "", ""}, - {"Current value", "PhonyValue", "", "", ""}, - {"Daemon threads", "", "", "", ""}, - {"deadlockAllTab", "", "", "", ""}, - {"deadlockTab", "", "", "", ""}, - {"deadlockTabN", "PhonyInt", "", "", ""}, - {"Description", "", "", "", ""}, - {"Descriptor", "", "", "", ""}, - {"Details", "", "", "", ""}, - {"Detect Deadlock", "", "", "", ""}, - {"Detect Deadlock.mnemonic", "", "", "", ""}, - {"Detect Deadlock.toolTip", "", "", "", ""}, - {"Dimension is not supported:", "", "", "", ""}, - {"Discard chart", "", "", "", ""}, - {"Disconnected. Click to connect.", "", "", "", ""}, - {"Double click to expand/collapse", "", "", "", ""}, - {"Double click to visualize", "", "", "", ""}, - {"DurationDaysHoursMinutes", 0, 13, 54, ""}, - {"DurationDaysHoursMinutes", 1, 13, 54, ""}, - {"DurationDaysHoursMinutes", 2, 13, 54, ""}, - {"DurationDaysHoursMinutes", 1024, 13, 45, ""}, - {"DurationHoursMinutes", 0, 13, "", ""}, - {"DurationHoursMinutes", 1, 0, "", ""}, - {"DurationHoursMinutes", 1, 1, "", ""}, - {"DurationHoursMinutes", 2, 42, "", ""}, - {"DurationMinutes", 0, "", "", ""}, - {"DurationMinutes", 1, "", "", ""}, - {"DurationMinutes", 2, "", "", ""}, - {"DurationSeconds", 0, "", "", ""}, - {"DurationSeconds", 1, "", "", ""}, - {"DurationSeconds", 2, "", "", ""}, - {"Empty array", "", "", "", ""}, - {"Error", "", "", "", ""}, - {"Error: MBeans already exist", "", "", "", ""}, - {"Error: MBeans do not exist", "", "", "", ""}, - {"Event", "", "", "", ""}, - {"Exit", "", "", "", ""}, - {"Exit.mnemonic", "", "", "", ""}, - {"expand", "", "", "", ""}, - {"Fail to load plugin", "", "", "", ""}, - {"FileChooser.fileExists.cancelOption", "", "", "", ""}, - {"FileChooser.fileExists.message", "PhonyFileName", "", "", ""}, - {"FileChooser.fileExists.okOption", "", "", "", ""}, - {"FileChooser.fileExists.title", "", "", "", ""}, - {"FileChooser.savedFile", "PhonyFilePath", "PhonyFileSize", "", ""}, - {"FileChooser.saveFailed.message", "PhonyFilePath", "PhonyMessage", "", ""}, - {"FileChooser.saveFailed.title", "", "", "", ""}, - {"Free physical memory", "", "", "", ""}, - {"Free swap space", "", "", "", ""}, - {"Garbage collector", "", "", "", ""}, - {"GC time", "", "", "", ""}, - {"GC time details", 54, "Phony", 11, ""}, - {"GcInfo", "Phony", -1, 768, ""}, - {"GcInfo", "Phony", 0, 768, ""}, - {"GcInfo", "Phony", 1, 768, ""}, - {"Heap", "", "", "", ""}, - {"Heap Memory Usage", "", "", "", ""}, - {"Help.AboutDialog.accessibleDescription", "", "", "", ""}, - {"Help.AboutDialog.jConsoleVersion", "DummyVersion", "", "", ""}, - {"Help.AboutDialog.javaVersion", "DummyVersion", "", "", ""}, - {"Help.AboutDialog.masthead.accessibleName", "", "", "", ""}, - {"Help.AboutDialog.masthead.title", "", "", "", ""}, - {"Help.AboutDialog.title", "", "", "", ""}, - {"Help.AboutDialog.userGuideLink", "DummyMessage", "", "", ""}, - {"Help.AboutDialog.userGuideLink.mnemonic", "", "", "", ""}, - {"Help.AboutDialog.userGuideLink.url", "DummyURL", "", "", ""}, - {"HelpMenu.About.title", "", "", "", ""}, - {"HelpMenu.About.title.mnemonic", "", "", "", ""}, - {"HelpMenu.UserGuide.title", "", "", "", ""}, - {"HelpMenu.UserGuide.title.mnemonic", "", "", "", ""}, - {"HelpMenu.title", "", "", "", ""}, - {"HelpMenu.title.mnemonic", "", "", "", ""}, - {"Hotspot MBeans...", "", "", "", ""}, - {"Hotspot MBeans....mnemonic", "", "", "", ""}, - {"Hotspot MBeans.dialog.accessibleDescription", "", "", "", ""}, - {"Impact", "", "", "", ""}, - {"Info", "", "", "", ""}, - {"INFO", "", "", "", ""}, - {"Invalid plugin path", "", "", "", ""}, - {"Invalid URL", "", "", "", ""}, - {"Is", "", "", "", ""}, - {"Java Monitoring & Management Console", "", "", "", ""}, - {"Java Virtual Machine", "", "", "", ""}, - {"JConsole: ", "", "", "", ""}, - {"JConsole.accessibleDescription", "", "", "", ""}, - {"JConsole version", "PhonyVersion", "", "", ""}, - {"JIT compiler", "", "", "", ""}, - {"Library path", "", "", "", ""}, - {"Live Threads", "", "", "", ""}, - {"Loaded", "", "", "", ""}, - {"Local Process:", "", "", "", ""}, - {"Local Process:.mnemonic", "", "", "", ""}, - {"Manage Hotspot MBeans in: ", "", "", "", ""}, - {"Management Not Enabled", "", "", "", ""}, - {"Management Will Be Enabled", "", "", "", ""}, - {"Masthead.font", "", "", "", ""}, - {"Max", "", "", "", ""}, - {"Max", "", "", "", ""}, - {"Maximum heap size", "", "", "", ""}, - {"MBeanAttributeInfo", "", "", "", ""}, - {"MBeanInfo", "", "", "", ""}, - {"MBeanNotificationInfo", "", "", "", ""}, - {"MBeanOperationInfo", "", "", "", ""}, - {"MBeans", "", "", "", ""}, - {"MBeansTab.clearNotificationsButton", "", "", "", ""}, - {"MBeansTab.clearNotificationsButton.mnemonic", "", "", "", ""}, - {"MBeansTab.clearNotificationsButton.toolTip", "", "", "", ""}, - {"MBeansTab.compositeNavigationMultiple", 0, 0, "", ""}, - {"MBeansTab.compositeNavigationSingle", "", "", "", ""}, - {"MBeansTab.refreshAttributesButton", "", "", "", ""}, - {"MBeansTab.refreshAttributesButton.mnemonic", "", "", "", ""}, - {"MBeansTab.refreshAttributesButton.toolTip", "", "", "", ""}, - {"MBeansTab.subscribeNotificationsButton", "", "", "", ""}, - {"MBeansTab.subscribeNotificationsButton.mnemonic", "", "", "", ""}, - {"MBeansTab.subscribeNotificationsButton.toolTip", "", "", "", ""}, - {"MBeansTab.tabularNavigationMultiple", 0, 0, "", ""}, - {"MBeansTab.tabularNavigationSingle", "", "", "", ""}, - {"MBeansTab.unsubscribeNotificationsButton", "", "", "", ""}, - {"MBeansTab.unsubscribeNotificationsButton.mnemonic", "", "", "", ""}, - {"MBeansTab.unsubscribeNotificationsButton.toolTip", "", "", "", ""}, - {"Memory", "", "", "", ""}, - {"MemoryPoolLabel", "PhonyMemoryPool", "", "", ""}, - {"MemoryTab.heapPlotter.accessibleName", "", "", "", ""}, - {"MemoryTab.infoLabelFormat", "UsedCount", "CommittedCount", "MaxCount", ""}, - {"MemoryTab.nonHeapPlotter.accessibleName", "", "", "", ""}, - {"MemoryTab.poolChart.aboveThreshold", "Threshold", "", "", ""}, - {"MemoryTab.poolChart.accessibleName", "", "", "", ""}, - {"MemoryTab.poolChart.belowThreshold", "Threshold", "", "", ""}, - {"MemoryTab.poolPlotter.accessibleName", "PhonyMemoryPool", "", "", ""}, - {"Message", "", "", "", ""}, - {"Method successfully invoked", "", "", "", ""}, - {"Monitor locked", "", "", "", ""}, - {"Minimize All", "", "", "", ""}, - {"Minimize All.mnemonic", "", "", "", ""}, - {"Name", "", "", "", ""}, - {"Name and Build", "PhonyName", "PhonyBuild", "", ""}, - {"Name Build and Mode", "PhonyName", "PhonyBuild", "PhonyMode", ""}, - {"Name State", "PhonyName", "PhonyState", "", ""}, - {"Name State LockName", "PhonyName", "PhonyState", "PhonyLock", ""}, - {"Name State LockName LockOwner", "PhonyName", "PhonyState", "PhonyLock", "PhonyOwner"}, - {"New Connection...", "", "", "", ""}, - {"New Connection....mnemonic", "", "", "", ""}, - {"No deadlock detected", "", "", "", ""}, - {"Non-Heap", "", "", "", ""}, - {"Non-Heap Memory Usage", "", "", "", ""}, - {"Notification", "", "", "", ""}, - {"Notification buffer", "", "", "", ""}, - {"Notifications", "", "", "", ""}, - {"NotifTypes", "", "", "", ""}, - {"Number of Loaded Classes", "", "", "", ""}, - {"Number of processors", "", "", "", ""}, - {"Number of Threads", "", "", "", ""}, - {"ObjectName", "", "", "", ""}, - {"Operating System", "", "", "", ""}, - {"Operation", "", "", "", ""}, - {"Operation invocation", "", "", "", ""}, - {"Operation return value", "", "", "", ""}, - {"Operations", "", "", "", ""}, - {"Overview", "", "", "", ""}, - {"OverviewPanel.plotter.accessibleName", "PhonyPlotter", "", "", ""}, - {"Parameter", "", "", "", ""}, - {"Password: ", "", "", "", ""}, - {"Password: .mnemonic", "", "", "", ""}, - {"Password.accessibleName", "", "", "", ""}, - {"Peak", "", "", "", ""}, - {"Perform GC", "", "", "", ""}, - {"Perform GC.mnemonic", "", "", "", ""}, - {"Perform GC.toolTip", "", "", "", ""}, - {"Plotter.accessibleName", "", "", "", ""}, - {"Plotter.accessibleName.keyAndValue", "Key", "Value", "", ""}, - {"Plotter.accessibleName.noData", "", "", "", ""}, - {"Plotter.saveAsMenuItem", "", "", "", ""}, - {"Plotter.saveAsMenuItem.mnemonic", "", "", "", ""}, - {"Plotter.timeRangeMenu", "", "", "", ""}, - {"Plotter.timeRangeMenu.mnemonic", "", "", "", ""}, - {"plot", "", "", "", ""}, - {"Problem adding listener", "", "", "", ""}, - {"Problem displaying MBean", "", "", "", ""}, - {"Problem invoking", "", "", "", ""}, - {"Problem removing listener", "", "", "", ""}, - {"Problem setting attribute", "", "", "", ""}, - {"Process CPU time", "", "", "", ""}, - {"Readable", "", "", "", ""}, - {"Reconnect", "", "", "", ""}, - {"Remote Process:", "", "", "", ""}, - {"Remote Process:.mnemonic", "", "", "", ""}, - {"Remote Process.textField.accessibleName", "", "", "", ""}, - {"remoteTF.usage", "", "", "", ""}, - {"Restore All", "", "", "", ""}, - {"Restore All.mnemonic", "", "", "", ""}, - {"ReturnType", "", "", "", ""}, - {"SeqNum", "", "", "", ""}, - {"Size Bytes", 512, "", "", ""}, - {"Size Gb", 512, "", "", ""}, - {"Size Kb", 512, "", "", ""}, - {"Size Mb", 512, "", "", ""}, - {"Source", "", "", "", ""}, - {"Stack trace", "", "", "", ""}, - {"SummaryTab.headerDateTimeFormat", "", "", "", ""}, - {"SummaryTab.pendingFinalization.label", "", "", "", ""}, - {"SummaryTab.pendingFinalization.value", "ObjectCount", "", "", ""}, - {"SummaryTab.tabName", "", "", "", ""}, - {"SummaryTab.vmVersion", "VMName", "VMVersion", "", ""}, - {"ThreadTab.infoLabelFormat", "LiveCount", "PeakCount", "TotalCount", ""}, - {"ThreadTab.threadInfo.accessibleName", "", "", "", ""}, - {"ThreadTab.threadPlotter.accessibleName", "", "", "", ""}, - {"Threads", "", "", "", ""}, - {"Threshold", "", "", "", ""}, - {"Tile", "", "", "", ""}, - {"Tile.mnemonic", "", "", "", ""}, - {"Time", "", "", "", ""}, - {"Time Range:", "", "", "", ""}, - {"Time Range:.mnemonic", "", "", "", ""}, - {"TimeStamp", "", "", "", ""}, - {"Total classes loaded", "", "", "", ""}, - {"Total classes unloaded", "", "", "", ""}, - {"Total compile time", "", "", "", ""}, - {"Total Loaded", "", "", "", ""}, - {"Total physical memory", "", "", "", ""}, - {"Total swap space", "", "", "", ""}, - {"Total threads started", "", "", "", ""}, - {"Type", "", "", "", ""}, - {"Unavailable", "", "", "", ""}, - {"UNKNOWN", "", "", "", ""}, - {"Unregister", "", "", "", ""}, - {"Uptime", "", "", "", ""}, - {"Usage Threshold", "", "", "", ""}, - {"Used", "", "", "", ""}, - {"Username: ", "", "", "", ""}, - {"Username: .mnemonic", "", "", "", ""}, - {"Username.accessibleName", "", "", "", ""}, - {"UserData", "", "", "", ""}, - {"Value", "", "", "", ""}, - {"Vendor", "", "", "", ""}, - {"Verbose Output", "", "", "", ""}, - {"Verbose Output.toolTip", "", "", "", ""}, - {"visualize", "", "", "", ""}, - {"VM", "", "", "", ""}, - {"VMInternalFrame.accessibleDescription", "", "", "", ""}, - {"VM arguments", "", "", "", ""}, - {"Virtual Machine", "", "", "", ""}, - {"Window", "", "", "", ""}, - {"Window.mnemonic", "", "", "", ""}, - {"Writable", "", "", "", ""}, - {"zz usage text", "PhonyName", "", "", ""}, - }; - //boolean verbose = false; - boolean verbose = true; - - long badLookups = 0; - System.out.println("Start..."); - for (int ii = 0; ii < testData.length; ii++) { - String key = (String)testData[ii][0]; - - if (key.endsWith(".mnemonic")) { - String baseKey = key.substring(0, key.length() - ".mnemonic".length()); - int mnemonic = Resources.getMnemonicInt(baseKey); - if (mnemonic == 0) { - badLookups++; - System.out.println("****lookup failed for key = " + key); + public static void main(String... args) { + List errors = new ArrayList<>(); + // Ensure that all Message fields have a corresponding key/value + // in the resource bundle and that mnemonics can be looked + // up where applicable. + ResourceBundle rb = ResourceBundle.getBundle(RESOURCE_BUNDLE); + for (Field field : Messages.class.getFields()) { + if (isResourceKeyField(field)) { + String resourceKey = field.getName(); + String message = readField(field); + if (message.startsWith(MISSING_RESOURCE_KEY_PREFIX)) { + errors.add("Can't find message (and perhaps mnemonic) for " + + Messages.class.getSimpleName() + "." + + resourceKey + " in resource bundle."); } else { - if (verbose) { - System.out.println(" mnemonic: " + KeyEvent.getKeyText(mnemonic)); + String resourceMessage = rb.getString(resourceKey); + if (hasMnemonicIdentifier(resourceMessage)) { + int mi = Resources.getMnemonicInt(message); + if (mi == 0) { + errors.add("Could not look up mnemonic for message '" + + message + "'."); + } } } - continue; } + } - String ss = Resources.getText(key, - testData[ii][1], - testData[ii][2], - testData[ii][3], - testData[ii][4]); - if (ss.startsWith("missing resource key")) { - badLookups++; - System.out.println("****lookup failed for key = " + key); - } else { - if (verbose) { - System.out.println(" " + ss); + // Ensure that there is Message class field for every resource key. + for (String key : Collections.list(rb.getKeys())) { + try { + Messages.class.getField(key); + } catch (NoSuchFieldException nfe) { + errors.add("Can't find static field (" + + Messages.class.getSimpleName() + "." + key + + ") matching '" + key + + "' in resource bundle. Unused message?"); + } + } + + if (errors.size() > 0) { + throwError(errors); + } + } + + private static String readField(Field field) { + try { + return (String) field.get(null); + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new Error("Could not access field " + field.getName() + + " when trying to read resource message."); + } + } + + private static boolean isResourceKeyField(Field field) { + int modifiers = field.getModifiers(); + return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers); + } + + private static boolean hasMnemonicIdentifier(String s) { + for (int i = 0; i < s.length() - 1; i++) { + if (s.charAt(i) == '&') { + if (s.charAt(i + 1) != '&') { + return true; + } else { + i++; } } } - if (badLookups > 0) { - throw new Error ("Resource lookup failed " + badLookups + - " time(s); Test failed"); + return false; + } + + private static void throwError(List errors) { + StringBuffer buffer = new StringBuffer(); + buffer.append("Found "); + buffer.append(errors.size()); + buffer.append(" error(s) when checking one-to-one mapping "); + buffer.append("between Message and resource bundle keys in "); + buffer.append(RESOURCE_BUNDLE); + buffer.append(" with "); + buffer.append(Locale.getDefault()); + buffer.append(" locale."); + buffer.append(NEW_LINE); + int errorIndex = 1; + for (String error : errors) { + buffer.append("Error "); + buffer.append(errorIndex); + buffer.append(": "); + buffer.append(error); + buffer.append(NEW_LINE); + errorIndex++; } - System.out.println("...Finished."); + throw new Error(buffer.toString()); } } diff --git a/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh b/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh index bec63a7992f..01c2e4b6f01 100644 --- a/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh +++ b/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2013, 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 @@ -54,7 +54,7 @@ pass() OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin) PATHSEP=":" ;; From 9b5513a8e8d82a40dacc910ddfa3d88bdecb6887 Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Tue, 3 Sep 2013 11:29:12 -0700 Subject: [PATCH 0070/1294] 8024015: TEST.groups: move jdk/lambda tests from jdk_other to jdk_lang Reviewed-by: alanb, mchung --- jdk/test/TEST.groups | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/TEST.groups b/jdk/test/TEST.groups index 0674bdc1d91..ed70cbf6704 100644 --- a/jdk/test/TEST.groups +++ b/jdk/test/TEST.groups @@ -27,6 +27,7 @@ jdk_lang = \ sun/invoke \ sun/misc \ sun/reflect \ + jdk/lambda \ vm jdk_util = \ @@ -133,7 +134,6 @@ jdk_other = \ javax/xml \ -javax/xml/crypto \ jdk/asm \ - jdk/lambda \ com/sun/jndi \ com/sun/corba \ lib/testlibrary \ From f7b61b93f1d44b921df005f950e5836fad15c8cc Mon Sep 17 00:00:00 2001 From: Brian Goetz Date: Wed, 28 Aug 2013 14:13:03 -0700 Subject: [PATCH 0071/1294] 8022176: Weaken contract of java.lang.AutoCloseable Reviewed-by: alanb, martin, mduigou, psandoz --- .../classes/java/lang/AutoCloseable.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/lang/AutoCloseable.java b/jdk/src/share/classes/java/lang/AutoCloseable.java index ce0fffe5939..be47cd0835f 100644 --- a/jdk/src/share/classes/java/lang/AutoCloseable.java +++ b/jdk/src/share/classes/java/lang/AutoCloseable.java @@ -26,7 +26,24 @@ package java.lang; /** - * A resource that must be closed when it is no longer needed. + * An object that may hold resources (such as file or socket handles) + * until it is closed. The {@link #close()} method of an {@code AutoCloseable} + * object is called automatically when exiting a {@code + * try}-with-resources block for which the object has been declared in + * the resource specification header. This construction ensures prompt + * release, avoiding resource exhaustion exceptions and errors that + * may otherwise occur. + * + * @apiNote + *

    It is possible, and in fact common, for a base class to + * implement AutoCloseable even though not all of its subclasses or + * instances will hold releasable resources. For code that must operate + * in complete generality, or when it is known that the {@code AutoCloseable} + * instance requires resource release, it is recommended to use {@code + * try}-with-resources constructions. However, when using facilities such as + * {@link java.util.stream.Stream} that support both I/O-based and + * non-I/O-based forms, {@code try}-with-resources blocks are in + * general unnecessary when using non-I/O-based forms. * * @author Josh Bloch * @since 1.7 From 45d26c95711c9e57c51394ceeb10fd69d320c62a Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Tue, 3 Sep 2013 11:44:34 -0700 Subject: [PATCH 0072/1294] 8024178: Difference in Stream.collect(Collector) methods located in jdk8 and jdk8-lambda repos Reviewed-by: mduigou --- jdk/src/share/classes/java/util/stream/DelegatingStream.java | 2 +- jdk/src/share/classes/java/util/stream/ReferencePipeline.java | 2 +- jdk/src/share/classes/java/util/stream/Stream.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/java/util/stream/DelegatingStream.java b/jdk/src/share/classes/java/util/stream/DelegatingStream.java index 2dab1a4430c..fbe7735a515 100644 --- a/jdk/src/share/classes/java/util/stream/DelegatingStream.java +++ b/jdk/src/share/classes/java/util/stream/DelegatingStream.java @@ -209,7 +209,7 @@ public class DelegatingStream implements Stream { } @Override - public R collect(Collector collector) { + public R collect(Collector collector) { return delegate.collect(collector); } diff --git a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java index 1fffff48b18..6c6fe647ee9 100644 --- a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java +++ b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java @@ -493,7 +493,7 @@ abstract class ReferencePipeline @Override @SuppressWarnings("unchecked") - public final R collect(Collector collector) { + public final R collect(Collector collector) { A container; if (isParallel() && (collector.characteristics().contains(Collector.Characteristics.CONCURRENT)) diff --git a/jdk/src/share/classes/java/util/stream/Stream.java b/jdk/src/share/classes/java/util/stream/Stream.java index 59d703b118e..1071b20110e 100644 --- a/jdk/src/share/classes/java/util/stream/Stream.java +++ b/jdk/src/share/classes/java/util/stream/Stream.java @@ -657,7 +657,7 @@ public interface Stream extends BaseStream> { * @see #collect(Supplier, BiConsumer, BiConsumer) * @see Collectors */ - R collect(Collector collector); + R collect(Collector collector); /** * Returns the minimum element of this stream according to the provided From 7bc062de1deb8ae4c5cca937970e1fb5794946d0 Mon Sep 17 00:00:00 2001 From: Brian Goetz Date: Tue, 3 Sep 2013 12:16:01 -0700 Subject: [PATCH 0073/1294] 8017513: Support for closeable streams 8022237: j.u.s.BaseStream.onClose() has an issue in implementation or requires spec clarification 8022572: Same exception instances thrown from j.u.stream.Stream.onClose() handlers are not listed as suppressed BaseStream implements AutoCloseable; Remove CloseableStream and DelegatingStream Reviewed-by: alanb, mduigou, psandoz --- .../share/classes/java/nio/file/Files.java | 298 +++++++++++------- .../java/util/stream/AbstractPipeline.java | 44 ++- .../classes/java/util/stream/BaseStream.java | 32 +- .../java/util/stream/CloseableStream.java | 57 ---- .../java/util/stream/DelegatingStream.java | 270 ---------------- .../java/util/stream/DoublePipeline.java | 9 +- .../java/util/stream/DoubleStream.java | 6 +- .../classes/java/util/stream/IntPipeline.java | 9 +- .../classes/java/util/stream/IntStream.java | 6 +- .../java/util/stream/LongPipeline.java | 9 +- .../classes/java/util/stream/LongStream.java | 6 +- .../java/util/stream/ReferencePipeline.java | 36 ++- .../classes/java/util/stream/Stream.java | 6 +- .../classes/java/util/stream/Streams.java | 57 ++++ jdk/test/java/nio/file/Files/StreamTest.java | 103 +++--- .../util/stream/DoubleStreamTestScenario.java | 3 +- .../util/stream/IntStreamTestScenario.java | 3 +- .../util/stream/LongStreamTestScenario.java | 3 +- .../java/util/stream/StreamTestScenario.java | 3 +- .../java/util/stream/StreamCloseTest.java | 166 ++++++++++ 20 files changed, 578 insertions(+), 548 deletions(-) delete mode 100644 jdk/src/share/classes/java/util/stream/CloseableStream.java delete mode 100644 jdk/src/share/classes/java/util/stream/DelegatingStream.java create mode 100644 jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java index 721184c1533..f084040c179 100644 --- a/jdk/src/share/classes/java/nio/file/Files.java +++ b/jdk/src/share/classes/java/nio/file/Files.java @@ -25,34 +25,56 @@ package java.nio.file; -import java.nio.file.attribute.*; -import java.nio.file.spi.FileSystemProvider; -import java.nio.file.spi.FileTypeDetector; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.UncheckedIOException; +import java.io.Writer; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.SeekableByteChannel; -import java.io.Closeable; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.Writer; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.*; -import java.util.function.BiPredicate; -import java.util.stream.CloseableStream; -import java.util.stream.DelegatingStream; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.DosFileAttributes; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.attribute.FileOwnerAttributeView; +import java.nio.file.attribute.FileStoreAttributeView; +import java.nio.file.attribute.FileTime; +import java.nio.file.attribute.PosixFileAttributeView; +import java.nio.file.attribute.PosixFileAttributes; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.UserPrincipal; +import java.nio.file.spi.FileSystemProvider; +import java.nio.file.spi.FileTypeDetector; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.ServiceLoader; +import java.util.Set; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.BiPredicate; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; /** * This class consists exclusively of static methods that operate on files, @@ -74,6 +96,21 @@ public final class Files { return path.getFileSystem().provider(); } + /** + * Convert a Closeable to a Runnable by converting checked IOException + * to UncheckedIOException + */ + private static Runnable asUncheckedRunnable(Closeable c) { + return () -> { + try { + c.close(); + } + catch (IOException e) { + throw new UncheckedIOException(e); + } + }; + } + // -- File contents -- /** @@ -3228,29 +3265,7 @@ public final class Files { // -- Stream APIs -- /** - * Implementation of CloseableStream - */ - private static class DelegatingCloseableStream extends DelegatingStream - implements CloseableStream - { - private final Closeable closeable; - - DelegatingCloseableStream(Closeable c, Stream delegate) { - super(delegate); - this.closeable = c; - } - - public void close() { - try { - closeable.close(); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - } - } - - /** - * Return a lazily populated {@code CloseableStream}, the elements of + * Return a lazily populated {@code Stream}, the elements of * which are the entries in the directory. The listing is not recursive. * *

    The elements of the stream are {@link Path} objects that are @@ -3264,10 +3279,13 @@ public final class Files { * reflect updates to the directory that occur after returning from this * method. * - *

    When not using the try-with-resources construct, then the stream's - * {@link CloseableStream#close close} method should be invoked after the - * operation is completed so as to free any resources held for the open - * directory. Operating on a closed stream behaves as if the end of stream + *

    The returned stream encapsulates a {@link DirectoryStream}. + * If timely disposal of file system resources is required, the + * {@code try}-with-resources construct should be used to ensure that the + * stream's {@link Stream#close close} method is invoked after the stream + * operations are completed. + * + *

    Operating on a closed stream behaves as if the end of stream * has been reached. Due to read-ahead, one or more elements may be * returned after the stream has been closed. * @@ -3278,7 +3296,7 @@ public final class Files { * * @param dir The path to the directory * - * @return The {@code CloseableStream} describing the content of the + * @return The {@code Stream} describing the content of the * directory * * @throws NotDirectoryException @@ -3294,43 +3312,54 @@ public final class Files { * @see #newDirectoryStream(Path) * @since 1.8 */ - public static CloseableStream list(Path dir) throws IOException { + public static Stream list(Path dir) throws IOException { DirectoryStream ds = Files.newDirectoryStream(dir); - final Iterator delegate = ds.iterator(); + try { + final Iterator delegate = ds.iterator(); - // Re-wrap DirectoryIteratorException to UncheckedIOException - Iterator it = new Iterator() { - public boolean hasNext() { - try { - return delegate.hasNext(); - } catch (DirectoryIteratorException e) { - throw new UncheckedIOException(e.getCause()); + // Re-wrap DirectoryIteratorException to UncheckedIOException + Iterator it = new Iterator() { + @Override + public boolean hasNext() { + try { + return delegate.hasNext(); + } catch (DirectoryIteratorException e) { + throw new UncheckedIOException(e.getCause()); + } } - } - public Path next() { - try { - return delegate.next(); - } catch (DirectoryIteratorException e) { - throw new UncheckedIOException(e.getCause()); + @Override + public Path next() { + try { + return delegate.next(); + } catch (DirectoryIteratorException e) { + throw new UncheckedIOException(e.getCause()); + } } - } - }; + }; - Stream s = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), - false); - return new DelegatingCloseableStream<>(ds, s); + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false) + .onClose(asUncheckedRunnable(ds)); + } catch (Error|RuntimeException e) { + try { + ds.close(); + } catch (IOException ex) { + try { + e.addSuppressed(ex); + } catch (Throwable ignore) {} + } + throw e; + } } /** - * Return a {@code CloseableStream} that is lazily populated with {@code + * Return a {@code Stream} that is lazily populated with {@code * Path} by walking the file tree rooted at a given starting file. The * file tree is traversed depth-first, the elements in the stream * are {@link Path} objects that are obtained as if by {@link * Path#resolve(Path) resolving} the relative path against {@code start}. * *

    The {@code stream} walks the file tree as elements are consumed. - * The {@code CloseableStream} returned is guaranteed to have at least one + * The {@code Stream} returned is guaranteed to have at least one * element, the starting file itself. For each file visited, the stream * attempts to read its {@link BasicFileAttributes}. If the file is a * directory and can be opened successfully, entries in the directory, and @@ -3370,10 +3399,11 @@ public final class Files { *

    When a security manager is installed and it denies access to a file * (or directory), then it is ignored and not included in the stream. * - *

    When not using the try-with-resources construct, then the stream's - * {@link CloseableStream#close close} method should be invoked after the - * operation is completed so as to free any resources held for the open - * directory. Operate the stream after it is closed will throw an + *

    The returned stream encapsulates one or more {@link DirectoryStream}s. + * If timely disposal of file system resources is required, the + * {@code try}-with-resources construct should be used to ensure that the + * stream's {@link Stream#close close} method is invoked after the stream + * operations are completed. Operating on a closed stream will result in an * {@link java.lang.IllegalStateException}. * *

    If an {@link IOException} is thrown when accessing the directory @@ -3388,7 +3418,7 @@ public final class Files { * @param options * options to configure the traversal * - * @return the {@link CloseableStream} of {@link Path} + * @return the {@link Stream} of {@link Path} * * @throws IllegalArgumentException * if the {@code maxDepth} parameter is negative @@ -3401,21 +3431,22 @@ public final class Files { * if an I/O error is thrown when accessing the starting file. * @since 1.8 */ - public static CloseableStream walk(Path start, int maxDepth, - FileVisitOption... options) - throws IOException - { + public static Stream walk(Path start, int maxDepth, + FileVisitOption... options) + throws IOException { FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options); - - Stream s = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), - false). - map(entry -> entry.file()); - return new DelegatingCloseableStream<>(iterator, s); + try { + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false) + .onClose(iterator::close) + .map(entry -> entry.file()); + } catch (Error|RuntimeException e) { + iterator.close(); + throw e; + } } /** - * Return a {@code CloseableStream} that is lazily populated with {@code + * Return a {@code Stream} that is lazily populated with {@code * Path} by walking the file tree rooted at a given starting file. The * file tree is traversed depth-first, the elements in the stream * are {@link Path} objects that are obtained as if by {@link @@ -3428,12 +3459,19 @@ public final class Files { * * In other words, it visits all levels of the file tree. * + *

    The returned stream encapsulates one or more {@link DirectoryStream}s. + * If timely disposal of file system resources is required, the + * {@code try}-with-resources construct should be used to ensure that the + * stream's {@link Stream#close close} method is invoked after the stream + * operations are completed. Operating on a closed stream will result in an + * {@link java.lang.IllegalStateException}. + * * @param start * the starting file * @param options * options to configure the traversal * - * @return the {@link CloseableStream} of {@link Path} + * @return the {@link Stream} of {@link Path} * * @throws SecurityException * If the security manager denies access to the starting file. @@ -3446,15 +3484,14 @@ public final class Files { * @see #walk(Path, int, FileVisitOption...) * @since 1.8 */ - public static CloseableStream walk(Path start, - FileVisitOption... options) - throws IOException - { + public static Stream walk(Path start, + FileVisitOption... options) + throws IOException { return walk(start, Integer.MAX_VALUE, options); } /** - * Return a {@code CloseableStream} that is lazily populated with {@code + * Return a {@code Stream} that is lazily populated with {@code * Path} by searching for files in a file tree rooted at a given starting * file. * @@ -3463,12 +3500,19 @@ public final class Files { * {@link BiPredicate} is invoked with its {@link Path} and {@link * BasicFileAttributes}. The {@code Path} object is obtained as if by * {@link Path#resolve(Path) resolving} the relative path against {@code - * start} and is only included in the returned {@link CloseableStream} if + * start} and is only included in the returned {@link Stream} if * the {@code BiPredicate} returns true. Compare to calling {@link * java.util.stream.Stream#filter filter} on the {@code Stream} * returned by {@code walk} method, this method may be more efficient by * avoiding redundant retrieval of the {@code BasicFileAttributes}. * + *

    The returned stream encapsulates one or more {@link DirectoryStream}s. + * If timely disposal of file system resources is required, the + * {@code try}-with-resources construct should be used to ensure that the + * stream's {@link Stream#close close} method is invoked after the stream + * operations are completed. Operating on a closed stream will result in an + * {@link java.lang.IllegalStateException}. + * *

    If an {@link IOException} is thrown when accessing the directory * after returned from this method, it is wrapped in an {@link * UncheckedIOException} which will be thrown from the method that caused @@ -3484,7 +3528,7 @@ public final class Files { * @param options * options to configure the traversal * - * @return the {@link CloseableStream} of {@link Path} + * @return the {@link Stream} of {@link Path} * * @throws IllegalArgumentException * if the {@code maxDepth} parameter is negative @@ -3499,24 +3543,25 @@ public final class Files { * @see #walk(Path, int, FileVisitOption...) * @since 1.8 */ - public static CloseableStream find(Path start, - int maxDepth, - BiPredicate matcher, - FileVisitOption... options) - throws IOException - { + public static Stream find(Path start, + int maxDepth, + BiPredicate matcher, + FileVisitOption... options) + throws IOException { FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options); - - Stream s = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), - false). - filter(entry -> matcher.test(entry.file(), entry.attributes())). - map(entry -> entry.file()); - return new DelegatingCloseableStream<>(iterator, s); + try { + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false) + .onClose(iterator::close) + .filter(entry -> matcher.test(entry.file(), entry.attributes())) + .map(entry -> entry.file()); + } catch (Error|RuntimeException e) { + iterator.close(); + throw e; + } } /** - * Read all lines from a file as a {@code CloseableStream}. Unlike {@link + * Read all lines from a file as a {@code Stream}. Unlike {@link * #readAllLines(Path, Charset) readAllLines}, this method does not read * all lines into a {@code List}, but instead populates lazily as the stream * is consumed. @@ -3528,22 +3573,24 @@ public final class Files { *

    After this method returns, then any subsequent I/O exception that * occurs while reading from the file or when a malformed or unmappable byte * sequence is read, is wrapped in an {@link UncheckedIOException} that will - * be thrown form the + * be thrown from the * {@link java.util.stream.Stream} method that caused the read to take * place. In case an {@code IOException} is thrown when closing the file, * it is also wrapped as an {@code UncheckedIOException}. * - *

    When not using the try-with-resources construct, then stream's - * {@link CloseableStream#close close} method should be invoked after - * operation is completed so as to free any resources held for the open - * file. + *

    The returned stream encapsulates a {@link Reader}. If timely + * disposal of file system resources is required, the try-with-resources + * construct should be used to ensure that the stream's + * {@link Stream#close close} method is invoked after the stream operations + * are completed. + * * * @param path * the path to the file * @param cs * the charset to use for decoding * - * @return the lines from the file as a {@code CloseableStream} + * @return the lines from the file as a {@code Stream} * * @throws IOException * if an I/O error occurs opening the file @@ -3557,10 +3604,19 @@ public final class Files { * @see java.io.BufferedReader#lines() * @since 1.8 */ - public static CloseableStream lines(Path path, Charset cs) - throws IOException - { + public static Stream lines(Path path, Charset cs) throws IOException { BufferedReader br = Files.newBufferedReader(path, cs); - return new DelegatingCloseableStream<>(br, br.lines()); + try { + return br.lines().onClose(asUncheckedRunnable(br)); + } catch (Error|RuntimeException e) { + try { + br.close(); + } catch (IOException ex) { + try { + e.addSuppressed(ex); + } catch (Throwable ignore) {} + } + throw e; + } } } diff --git a/jdk/src/share/classes/java/util/stream/AbstractPipeline.java b/jdk/src/share/classes/java/util/stream/AbstractPipeline.java index 3b2f5bdc5f7..dd60c2520e4 100644 --- a/jdk/src/share/classes/java/util/stream/AbstractPipeline.java +++ b/jdk/src/share/classes/java/util/stream/AbstractPipeline.java @@ -71,6 +71,9 @@ import java.util.function.Supplier; */ abstract class AbstractPipeline> extends PipelineHelper implements BaseStream { + private static final String MSG_STREAM_LINKED = "stream has already been operated upon or closed"; + private static final String MSG_CONSUMED = "source already consumed or closed"; + /** * Backlink to the head of the pipeline chain (self if this is the source * stage). @@ -137,6 +140,8 @@ abstract class AbstractPipeline> */ private boolean sourceAnyStateful; + private Runnable sourceCloseAction; + /** * True if pipeline is parallel, otherwise the pipeline is sequential; only * valid for the source stage. @@ -195,7 +200,7 @@ abstract class AbstractPipeline> */ AbstractPipeline(AbstractPipeline previousStage, int opFlags) { if (previousStage.linkedOrConsumed) - throw new IllegalStateException("stream has already been operated upon"); + throw new IllegalStateException(MSG_STREAM_LINKED); previousStage.linkedOrConsumed = true; previousStage.nextStage = this; @@ -221,7 +226,7 @@ abstract class AbstractPipeline> final R evaluate(TerminalOp terminalOp) { assert getOutputShape() == terminalOp.inputShape(); if (linkedOrConsumed) - throw new IllegalStateException("stream has already been operated upon"); + throw new IllegalStateException(MSG_STREAM_LINKED); linkedOrConsumed = true; return isParallel() @@ -238,7 +243,7 @@ abstract class AbstractPipeline> @SuppressWarnings("unchecked") final Node evaluateToArrayNode(IntFunction generator) { if (linkedOrConsumed) - throw new IllegalStateException("stream has already been operated upon"); + throw new IllegalStateException(MSG_STREAM_LINKED); linkedOrConsumed = true; // If the last intermediate operation is stateful then @@ -266,7 +271,7 @@ abstract class AbstractPipeline> throw new IllegalStateException(); if (linkedOrConsumed) - throw new IllegalStateException("stream has already been operated upon"); + throw new IllegalStateException(MSG_STREAM_LINKED); linkedOrConsumed = true; if (sourceStage.sourceSpliterator != null) { @@ -282,7 +287,7 @@ abstract class AbstractPipeline> return s; } else { - throw new IllegalStateException("source already consumed"); + throw new IllegalStateException(MSG_CONSUMED); } } @@ -302,12 +307,35 @@ abstract class AbstractPipeline> return (S) this; } + @Override + public void close() { + linkedOrConsumed = true; + sourceSupplier = null; + sourceSpliterator = null; + if (sourceStage.sourceCloseAction != null) { + Runnable closeAction = sourceStage.sourceCloseAction; + sourceStage.sourceCloseAction = null; + closeAction.run(); + } + } + + @Override + @SuppressWarnings("unchecked") + public S onClose(Runnable closeHandler) { + Runnable existingHandler = sourceStage.sourceCloseAction; + sourceStage.sourceCloseAction = + (existingHandler == null) + ? closeHandler + : Streams.composeWithExceptions(existingHandler, closeHandler); + return (S) this; + } + // Primitive specialization use co-variant overrides, hence is not final @Override @SuppressWarnings("unchecked") public Spliterator spliterator() { if (linkedOrConsumed) - throw new IllegalStateException("stream has already been operated upon"); + throw new IllegalStateException(MSG_STREAM_LINKED); linkedOrConsumed = true; if (this == sourceStage) { @@ -324,7 +352,7 @@ abstract class AbstractPipeline> return lazySpliterator(s); } else { - throw new IllegalStateException("source already consumed"); + throw new IllegalStateException(MSG_CONSUMED); } } else { @@ -424,7 +452,7 @@ abstract class AbstractPipeline> sourceStage.sourceSupplier = null; } else { - throw new IllegalStateException("source already consumed"); + throw new IllegalStateException(MSG_CONSUMED); } if (isParallel()) { diff --git a/jdk/src/share/classes/java/util/stream/BaseStream.java b/jdk/src/share/classes/java/util/stream/BaseStream.java index 94dbc7de73f..9c87a309098 100644 --- a/jdk/src/share/classes/java/util/stream/BaseStream.java +++ b/jdk/src/share/classes/java/util/stream/BaseStream.java @@ -35,7 +35,8 @@ import java.util.Spliterator; * @param type of stream implementing {@code BaseStream} * @since 1.8 */ -public interface BaseStream> { +public interface BaseStream> + extends AutoCloseable { /** * Returns an iterator for the elements of this stream. * @@ -103,4 +104,33 @@ public interface BaseStream> { * @return an unordered stream */ S unordered(); + + /** + * Returns an equivalent stream with an additional close handler. Close + * handlers are run when the {@link #close()} method + * is called on the stream, and are executed in the order they were + * added. All close handlers are run, even if earlier close handlers throw + * exceptions. If any close handler throws an exception, the first + * exception thrown will be relayed to the caller of {@code close()}, with + * any remaining exceptions added to that exception as suppressed exceptions + * (unless one of the remaining exceptions is the same exception as the + * first exception, since an exception cannot suppress itself.) May + * return itself. + * + *

    This is an intermediate + * operation. + * + * @param closeHandler A task to execute when the stream is closed + * @return a stream with a handler that is run if the stream is closed + */ + S onClose(Runnable closeHandler); + + /** + * Closes this stream, causing all close handlers for this stream pipeline + * to be called. + * + * @see AutoCloseable#close() + */ + @Override + void close(); } diff --git a/jdk/src/share/classes/java/util/stream/CloseableStream.java b/jdk/src/share/classes/java/util/stream/CloseableStream.java deleted file mode 100644 index bbcce516f99..00000000000 --- a/jdk/src/share/classes/java/util/stream/CloseableStream.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util.stream; - -/** - * A {@code CloseableStream} is a {@code Stream} that can be closed. - * The close method is invoked to release resources that the object is - * holding (such as open files). - * - * @param The type of stream elements - * @since 1.8 - */ -public interface CloseableStream extends Stream, AutoCloseable { - - /** - * Closes this resource, relinquishing any underlying resources. - * This method is invoked automatically on objects managed by the - * {@code try}-with-resources statement. Does nothing if called when - * the resource has already been closed. - * - * This method does not allow throwing checked {@code Exception}s like - * {@link AutoCloseable#close() AutoCloseable.close()}. Cases where the - * close operation may fail require careful attention by implementers. It - * is strongly advised to relinquish the underlying resources and to - * internally mark the resource as closed. The {@code close} - * method is unlikely to be invoked more than once and so this ensures - * that the resources are released in a timely manner. Furthermore it - * reduces problems that could arise when the resource wraps, or is - * wrapped, by another resource. - * - * @see AutoCloseable#close() - */ - void close(); -} diff --git a/jdk/src/share/classes/java/util/stream/DelegatingStream.java b/jdk/src/share/classes/java/util/stream/DelegatingStream.java deleted file mode 100644 index fbe7735a515..00000000000 --- a/jdk/src/share/classes/java/util/stream/DelegatingStream.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util.stream; - -import java.util.Comparator; -import java.util.Iterator; -import java.util.Objects; -import java.util.Optional; -import java.util.Spliterator; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.BinaryOperator; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.IntFunction; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.function.ToDoubleFunction; -import java.util.function.ToIntFunction; -import java.util.function.ToLongFunction; - -/** - * A {@code Stream} implementation that delegates operations to another {@code - * Stream}. - * - * @param type of stream elements for this stream and underlying delegate - * stream - * - * @since 1.8 - */ -public class DelegatingStream implements Stream { - final private Stream delegate; - - /** - * Construct a {@code Stream} that delegates operations to another {@code - * Stream}. - * - * @param delegate the underlying {@link Stream} to which we delegate all - * {@code Stream} methods - * @throws NullPointerException if the delegate is null - */ - public DelegatingStream(Stream delegate) { - this.delegate = Objects.requireNonNull(delegate); - } - - // -- BaseStream methods -- - - @Override - public Spliterator spliterator() { - return delegate.spliterator(); - } - - @Override - public boolean isParallel() { - return delegate.isParallel(); - } - - @Override - public Iterator iterator() { - return delegate.iterator(); - } - - // -- Stream methods -- - - @Override - public Stream filter(Predicate predicate) { - return delegate.filter(predicate); - } - - @Override - public Stream map(Function mapper) { - return delegate.map(mapper); - } - - @Override - public IntStream mapToInt(ToIntFunction mapper) { - return delegate.mapToInt(mapper); - } - - @Override - public LongStream mapToLong(ToLongFunction mapper) { - return delegate.mapToLong(mapper); - } - - @Override - public DoubleStream mapToDouble(ToDoubleFunction mapper) { - return delegate.mapToDouble(mapper); - } - - @Override - public Stream flatMap(Function> mapper) { - return delegate.flatMap(mapper); - } - - @Override - public IntStream flatMapToInt(Function mapper) { - return delegate.flatMapToInt(mapper); - } - - @Override - public LongStream flatMapToLong(Function mapper) { - return delegate.flatMapToLong(mapper); - } - - @Override - public DoubleStream flatMapToDouble(Function mapper) { - return delegate.flatMapToDouble(mapper); - } - - @Override - public Stream distinct() { - return delegate.distinct(); - } - - @Override - public Stream sorted() { - return delegate.sorted(); - } - - @Override - public Stream sorted(Comparator comparator) { - return delegate.sorted(comparator); - } - - @Override - public void forEach(Consumer action) { - delegate.forEach(action); - } - - @Override - public void forEachOrdered(Consumer action) { - delegate.forEachOrdered(action); - } - - @Override - public Stream peek(Consumer consumer) { - return delegate.peek(consumer); - } - - @Override - public Stream limit(long maxSize) { - return delegate.limit(maxSize); - } - - @Override - public Stream substream(long startingOffset) { - return delegate.substream(startingOffset); - } - - @Override - public Stream substream(long startingOffset, long endingOffset) { - return delegate.substream(startingOffset, endingOffset); - } - - @Override - public A[] toArray(IntFunction generator) { - return delegate.toArray(generator); - } - - @Override - public Object[] toArray() { - return delegate.toArray(); - } - - @Override - public T reduce(T identity, BinaryOperator accumulator) { - return delegate.reduce(identity, accumulator); - } - - @Override - public Optional reduce(BinaryOperator accumulator) { - return delegate.reduce(accumulator); - } - - @Override - public U reduce(U identity, BiFunction accumulator, - BinaryOperator combiner) { - return delegate.reduce(identity, accumulator, combiner); - } - - @Override - public R collect(Supplier resultFactory, - BiConsumer accumulator, - BiConsumer combiner) { - return delegate.collect(resultFactory, accumulator, combiner); - } - - @Override - public R collect(Collector collector) { - return delegate.collect(collector); - } - - @Override - public Optional max(Comparator comparator) { - return delegate.max(comparator); - } - - @Override - public Optional min(Comparator comparator) { - return delegate.min(comparator); - } - - @Override - public long count() { - return delegate.count(); - } - - @Override - public boolean anyMatch(Predicate predicate) { - return delegate.anyMatch(predicate); - } - - @Override - public boolean allMatch(Predicate predicate) { - return delegate.allMatch(predicate); - } - - @Override - public boolean noneMatch(Predicate predicate) { - return delegate.noneMatch(predicate); - } - - @Override - public Optional findFirst() { - return delegate.findFirst(); - } - - @Override - public Optional findAny() { - return delegate.findAny(); - } - - @Override - public Stream unordered() { - return delegate.unordered(); - } - - @Override - public Stream sequential() { - return delegate.sequential(); - } - - @Override - public Stream parallel() { - return delegate.parallel(); - } -} diff --git a/jdk/src/share/classes/java/util/stream/DoublePipeline.java b/jdk/src/share/classes/java/util/stream/DoublePipeline.java index f894fa0abb9..75981d5801f 100644 --- a/jdk/src/share/classes/java/util/stream/DoublePipeline.java +++ b/jdk/src/share/classes/java/util/stream/DoublePipeline.java @@ -266,10 +266,11 @@ abstract class DoublePipeline @Override public void accept(double t) { - // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it - DoubleStream result = mapper.apply(t); - if (result != null) - result.sequential().forEach(i -> downstream.accept(i)); + try (DoubleStream result = mapper.apply(t)) { + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + if (result != null) + result.sequential().forEach(i -> downstream.accept(i)); + } } }; } diff --git a/jdk/src/share/classes/java/util/stream/DoubleStream.java b/jdk/src/share/classes/java/util/stream/DoubleStream.java index 93a83991e0b..bf356926154 100644 --- a/jdk/src/share/classes/java/util/stream/DoubleStream.java +++ b/jdk/src/share/classes/java/util/stream/DoubleStream.java @@ -752,7 +752,8 @@ public interface DoubleStream extends BaseStream { * elements of a first {@code DoubleStream} succeeded by all the elements of the * second {@code DoubleStream}. The resulting stream is ordered if both * of the input streams are ordered, and parallel if either of the input - * streams is parallel. + * streams is parallel. When the resulting stream is closed, the close + * handlers for both input streams are invoked. * * @param a the first stream * @param b the second stream to concatenate on to end of the first stream @@ -764,7 +765,8 @@ public interface DoubleStream extends BaseStream { Spliterator.OfDouble split = new Streams.ConcatSpliterator.OfDouble( a.spliterator(), b.spliterator()); - return StreamSupport.doubleStream(split, a.isParallel() || b.isParallel()); + DoubleStream stream = StreamSupport.doubleStream(split, a.isParallel() || b.isParallel()); + return stream.onClose(Streams.composedClose(a, b)); } /** diff --git a/jdk/src/share/classes/java/util/stream/IntPipeline.java b/jdk/src/share/classes/java/util/stream/IntPipeline.java index f7dc79317d3..f35bc1d7a8e 100644 --- a/jdk/src/share/classes/java/util/stream/IntPipeline.java +++ b/jdk/src/share/classes/java/util/stream/IntPipeline.java @@ -302,10 +302,11 @@ abstract class IntPipeline @Override public void accept(int t) { - // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it - IntStream result = mapper.apply(t); - if (result != null) - result.sequential().forEach(i -> downstream.accept(i)); + try (IntStream result = mapper.apply(t)) { + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + if (result != null) + result.sequential().forEach(i -> downstream.accept(i)); + } } }; } diff --git a/jdk/src/share/classes/java/util/stream/IntStream.java b/jdk/src/share/classes/java/util/stream/IntStream.java index 883b03cbd3d..c107ca46de9 100644 --- a/jdk/src/share/classes/java/util/stream/IntStream.java +++ b/jdk/src/share/classes/java/util/stream/IntStream.java @@ -806,7 +806,8 @@ public interface IntStream extends BaseStream { * elements of a first {@code IntStream} succeeded by all the elements of the * second {@code IntStream}. The resulting stream is ordered if both * of the input streams are ordered, and parallel if either of the input - * streams is parallel. + * streams is parallel. When the resulting stream is closed, the close + * handlers for both input streams are invoked. * * @param a the first stream * @param b the second stream to concatenate on to end of the first stream @@ -818,7 +819,8 @@ public interface IntStream extends BaseStream { Spliterator.OfInt split = new Streams.ConcatSpliterator.OfInt( a.spliterator(), b.spliterator()); - return StreamSupport.intStream(split, a.isParallel() || b.isParallel()); + IntStream stream = StreamSupport.intStream(split, a.isParallel() || b.isParallel()); + return stream.onClose(Streams.composedClose(a, b)); } /** diff --git a/jdk/src/share/classes/java/util/stream/LongPipeline.java b/jdk/src/share/classes/java/util/stream/LongPipeline.java index 3c199feab59..a59ec3f5f00 100644 --- a/jdk/src/share/classes/java/util/stream/LongPipeline.java +++ b/jdk/src/share/classes/java/util/stream/LongPipeline.java @@ -283,10 +283,11 @@ abstract class LongPipeline @Override public void accept(long t) { - // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it - LongStream result = mapper.apply(t); - if (result != null) - result.sequential().forEach(i -> downstream.accept(i)); + try (LongStream result = mapper.apply(t)) { + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + if (result != null) + result.sequential().forEach(i -> downstream.accept(i)); + } } }; } diff --git a/jdk/src/share/classes/java/util/stream/LongStream.java b/jdk/src/share/classes/java/util/stream/LongStream.java index 8fce0d68d65..e64c67204dc 100644 --- a/jdk/src/share/classes/java/util/stream/LongStream.java +++ b/jdk/src/share/classes/java/util/stream/LongStream.java @@ -812,7 +812,8 @@ public interface LongStream extends BaseStream { * elements of a first {@code LongStream} succeeded by all the elements of the * second {@code LongStream}. The resulting stream is ordered if both * of the input streams are ordered, and parallel if either of the input - * streams is parallel. + * streams is parallel. When the resulting stream is closed, the close + * handlers for both input streams are invoked. * * @param a the first stream * @param b the second stream to concatenate on to end of the first stream @@ -824,7 +825,8 @@ public interface LongStream extends BaseStream { Spliterator.OfLong split = new Streams.ConcatSpliterator.OfLong( a.spliterator(), b.spliterator()); - return StreamSupport.longStream(split, a.isParallel() || b.isParallel()); + LongStream stream = StreamSupport.longStream(split, a.isParallel() || b.isParallel()); + return stream.onClose(Streams.composedClose(a, b)); } /** diff --git a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java index 6c6fe647ee9..42d711f4b2b 100644 --- a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java +++ b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java @@ -264,10 +264,11 @@ abstract class ReferencePipeline @Override public void accept(P_OUT u) { - // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it - Stream result = mapper.apply(u); - if (result != null) - result.sequential().forEach(downstream); + try (Stream result = mapper.apply(u)) { + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + if (result != null) + result.sequential().forEach(downstream); + } } }; } @@ -291,10 +292,11 @@ abstract class ReferencePipeline @Override public void accept(P_OUT u) { - // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it - IntStream result = mapper.apply(u); - if (result != null) - result.sequential().forEach(downstreamAsInt); + try (IntStream result = mapper.apply(u)) { + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + if (result != null) + result.sequential().forEach(downstreamAsInt); + } } }; } @@ -318,10 +320,11 @@ abstract class ReferencePipeline @Override public void accept(P_OUT u) { - // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it - DoubleStream result = mapper.apply(u); - if (result != null) - result.sequential().forEach(downstreamAsDouble); + try (DoubleStream result = mapper.apply(u)) { + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + if (result != null) + result.sequential().forEach(downstreamAsDouble); + } } }; } @@ -345,10 +348,11 @@ abstract class ReferencePipeline @Override public void accept(P_OUT u) { - // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it - LongStream result = mapper.apply(u); - if (result != null) - result.sequential().forEach(downstreamAsLong); + try (LongStream result = mapper.apply(u)) { + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + if (result != null) + result.sequential().forEach(downstreamAsLong); + } } }; } diff --git a/jdk/src/share/classes/java/util/stream/Stream.java b/jdk/src/share/classes/java/util/stream/Stream.java index 1071b20110e..715729f24a7 100644 --- a/jdk/src/share/classes/java/util/stream/Stream.java +++ b/jdk/src/share/classes/java/util/stream/Stream.java @@ -891,7 +891,8 @@ public interface Stream extends BaseStream> { * elements of a first {@code Stream} succeeded by all the elements of the * second {@code Stream}. The resulting stream is ordered if both * of the input streams are ordered, and parallel if either of the input - * streams is parallel. + * streams is parallel. When the resulting stream is closed, the close + * handlers for both input streams are invoked. * * @param The type of stream elements * @param a the first stream @@ -906,7 +907,8 @@ public interface Stream extends BaseStream> { @SuppressWarnings("unchecked") Spliterator split = new Streams.ConcatSpliterator.OfRef<>( (Spliterator) a.spliterator(), (Spliterator) b.spliterator()); - return StreamSupport.stream(split, a.isParallel() || b.isParallel()); + Stream stream = StreamSupport.stream(split, a.isParallel() || b.isParallel()); + return stream.onClose(Streams.composedClose(a, b)); } /** diff --git a/jdk/src/share/classes/java/util/stream/Streams.java b/jdk/src/share/classes/java/util/stream/Streams.java index 15c3dcae497..8af33f2b3c2 100644 --- a/jdk/src/share/classes/java/util/stream/Streams.java +++ b/jdk/src/share/classes/java/util/stream/Streams.java @@ -833,4 +833,61 @@ final class Streams { } } } + + /** + * Given two Runnables, return a Runnable that executes both in sequence, + * even if the first throws an exception, and if both throw exceptions, add + * any exceptions thrown by the second as suppressed exceptions of the first. + */ + static Runnable composeWithExceptions(Runnable a, Runnable b) { + return new Runnable() { + @Override + public void run() { + try { + a.run(); + } + catch (Throwable e1) { + try { + b.run(); + } + catch (Throwable e2) { + try { + e1.addSuppressed(e2); + } catch (Throwable ignore) {} + } + throw e1; + } + b.run(); + } + }; + } + + /** + * Given two streams, return a Runnable that + * executes both of their {@link BaseStream#close} methods in sequence, + * even if the first throws an exception, and if both throw exceptions, add + * any exceptions thrown by the second as suppressed exceptions of the first. + */ + static Runnable composedClose(BaseStream a, BaseStream b) { + return new Runnable() { + @Override + public void run() { + try { + a.close(); + } + catch (Throwable e1) { + try { + b.close(); + } + catch (Throwable e2) { + try { + e1.addSuppressed(e2); + } catch (Throwable ignore) {} + } + throw e1; + } + b.close(); + } + }; + } } diff --git a/jdk/test/java/nio/file/Files/StreamTest.java b/jdk/test/java/nio/file/Files/StreamTest.java index b5ff2977257..5304492f1db 100644 --- a/jdk/test/java/nio/file/Files/StreamTest.java +++ b/jdk/test/java/nio/file/Files/StreamTest.java @@ -43,14 +43,13 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.BasicFileAttributes; import java.util.Arrays; -import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.TreeSet; import java.util.function.BiPredicate; -import java.util.stream.CloseableStream; +import java.util.stream.Stream; import java.util.stream.Collectors; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -138,14 +137,14 @@ public class StreamTest { } public void testBasic() { - try (CloseableStream s = Files.list(testFolder)) { - Object[] actual = s.sorted(Comparator.naturalOrder()).toArray(); + try (Stream s = Files.list(testFolder)) { + Object[] actual = s.sorted().toArray(); assertEquals(actual, level1); } catch (IOException ioe) { fail("Unexpected IOException"); } - try (CloseableStream s = Files.list(testFolder.resolve("empty"))) { + try (Stream s = Files.list(testFolder.resolve("empty"))) { int count = s.mapToInt(p -> 1).reduce(0, Integer::sum); assertEquals(count, 0, "Expect empty stream."); } catch (IOException ioe) { @@ -154,8 +153,8 @@ public class StreamTest { } public void testWalk() { - try (CloseableStream s = Files.walk(testFolder)) { - Object[] actual = s.sorted(Comparator.naturalOrder()).toArray(); + try (Stream s = Files.walk(testFolder)) { + Object[] actual = s.sorted().toArray(); assertEquals(actual, all); } catch (IOException ioe) { fail("Unexpected IOException"); @@ -163,9 +162,9 @@ public class StreamTest { } public void testWalkOneLevel() { - try (CloseableStream s = Files.walk(testFolder, 1)) { + try (Stream s = Files.walk(testFolder, 1)) { Object[] actual = s.filter(path -> ! path.equals(testFolder)) - .sorted(Comparator.naturalOrder()) + .sorted() .toArray(); assertEquals(actual, level1); } catch (IOException ioe) { @@ -176,8 +175,8 @@ public class StreamTest { public void testWalkFollowLink() { // If link is not supported, the directory structure won't have link. // We still want to test the behavior with FOLLOW_LINKS option. - try (CloseableStream s = Files.walk(testFolder, FileVisitOption.FOLLOW_LINKS)) { - Object[] actual = s.sorted(Comparator.naturalOrder()).toArray(); + try (Stream s = Files.walk(testFolder, FileVisitOption.FOLLOW_LINKS)) { + Object[] actual = s.sorted().toArray(); assertEquals(actual, all_folowLinks); } catch (IOException ioe) { fail("Unexpected IOException"); @@ -185,7 +184,7 @@ public class StreamTest { } private void validateFileSystemLoopException(Path start, Path... causes) { - try (CloseableStream s = Files.walk(start, FileVisitOption.FOLLOW_LINKS)) { + try (Stream s = Files.walk(start, FileVisitOption.FOLLOW_LINKS)) { try { int count = s.mapToInt(p -> 1).reduce(0, Integer::sum); fail("Should got FileSystemLoopException, but got " + count + "elements."); @@ -282,28 +281,28 @@ public class StreamTest { public void testFind() throws IOException { PathBiPredicate pred = new PathBiPredicate((path, attrs) -> true); - try (CloseableStream s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { + try (Stream s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { Set result = s.collect(Collectors.toCollection(TreeSet::new)); assertEquals(pred.visited(), all); assertEquals(result.toArray(new Path[0]), pred.visited()); } pred = new PathBiPredicate((path, attrs) -> attrs.isSymbolicLink()); - try (CloseableStream s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { + try (Stream s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { s.forEach(path -> assertTrue(Files.isSymbolicLink(path))); assertEquals(pred.visited(), all); } pred = new PathBiPredicate((path, attrs) -> path.getFileName().toString().startsWith("e")); - try (CloseableStream s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { + try (Stream s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { s.forEach(path -> assertEquals(path.getFileName().toString(), "empty")); assertEquals(pred.visited(), all); } pred = new PathBiPredicate((path, attrs) -> path.getFileName().toString().startsWith("l") && attrs.isRegularFile()); - try (CloseableStream s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { + try (Stream s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { s.forEach(path -> fail("Expect empty stream")); assertEquals(pred.visited(), all); } @@ -317,14 +316,14 @@ public class StreamTest { try { // zero lines assertTrue(Files.size(tmpfile) == 0, "File should be empty"); - try (CloseableStream s = Files.lines(tmpfile, US_ASCII)) { + try (Stream s = Files.lines(tmpfile, US_ASCII)) { assertEquals(s.mapToInt(l -> 1).reduce(0, Integer::sum), 0, "No line expected"); } // one line byte[] hi = { (byte)'h', (byte)'i' }; Files.write(tmpfile, hi); - try (CloseableStream s = Files.lines(tmpfile, US_ASCII)) { + try (Stream s = Files.lines(tmpfile, US_ASCII)) { List lines = s.collect(Collectors.toList()); assertTrue(lines.size() == 1, "One line expected"); assertTrue(lines.get(0).equals("hi"), "'Hi' expected"); @@ -334,7 +333,7 @@ public class StreamTest { List expected = Arrays.asList("hi", "there"); Files.write(tmpfile, expected, US_ASCII); assertTrue(Files.size(tmpfile) > 0, "File is empty"); - try (CloseableStream s = Files.lines(tmpfile, US_ASCII)) { + try (Stream s = Files.lines(tmpfile, US_ASCII)) { List lines = s.collect(Collectors.toList()); assertTrue(lines.equals(expected), "Unexpected lines"); } @@ -342,7 +341,7 @@ public class StreamTest { // MalformedInputException byte[] bad = { (byte)0xff, (byte)0xff }; Files.write(tmpfile, bad); - try (CloseableStream s = Files.lines(tmpfile, US_ASCII)) { + try (Stream s = Files.lines(tmpfile, US_ASCII)) { try { List lines = s.collect(Collectors.toList()); throw new RuntimeException("UncheckedIOException expected"); @@ -378,7 +377,7 @@ public class StreamTest { fsp.setFaultyMode(false); Path fakeRoot = fs.getRoot(); try { - try (CloseableStream s = Files.list(fakeRoot)) { + try (Stream s = Files.list(fakeRoot)) { s.forEach(path -> assertEquals(path.getFileName().toString(), "DirectoryIteratorException")); } } catch (UncheckedIOException uioe) { @@ -398,7 +397,7 @@ public class StreamTest { } try { - try (CloseableStream s = Files.list(fakeRoot)) { + try (Stream s = Files.list(fakeRoot)) { s.forEach(path -> fail("should not get here")); } } catch (UncheckedIOException uioe) { @@ -427,12 +426,12 @@ public class StreamTest { try { fsp.setFaultyMode(false); Path fakeRoot = fs.getRoot(); - try (CloseableStream s = Files.list(fakeRoot.resolve("dir2"))) { + try (Stream s = Files.list(fakeRoot.resolve("dir2"))) { // only one file s.forEach(path -> assertEquals(path.getFileName().toString(), "IOException")); } - try (CloseableStream s = Files.walk(fakeRoot.resolve("empty"))) { + try (Stream s = Files.walk(fakeRoot.resolve("empty"))) { String[] result = s.map(path -> path.getFileName().toString()) .toArray(String[]::new); // ordered as depth-first @@ -440,13 +439,13 @@ public class StreamTest { } fsp.setFaultyMode(true); - try (CloseableStream s = Files.list(fakeRoot.resolve("dir2"))) { + try (Stream s = Files.list(fakeRoot.resolve("dir2"))) { s.forEach(path -> fail("should have caused exception")); } catch (UncheckedIOException uioe) { assertTrue(uioe.getCause() instanceof FaultyFileSystem.FaultyException); } - try (CloseableStream s = Files.walk(fakeRoot.resolve("empty"))) { + try (Stream s = Files.walk(fakeRoot.resolve("empty"))) { String[] result = s.map(path -> path.getFileName().toString()) .toArray(String[]::new); fail("should not reach here due to IOException"); @@ -454,7 +453,7 @@ public class StreamTest { assertTrue(uioe.getCause() instanceof FaultyFileSystem.FaultyException); } - try (CloseableStream s = Files.walk( + try (Stream s = Files.walk( fakeRoot.resolve("empty").resolve("IOException"))) { String[] result = s.map(path -> path.getFileName().toString()) @@ -502,20 +501,20 @@ public class StreamTest { fsp.setFaultyMode(false); Path fakeRoot = fs.getRoot(); // validate setting - try (CloseableStream s = Files.list(fakeRoot.resolve("empty"))) { + try (Stream s = Files.list(fakeRoot.resolve("empty"))) { String[] result = s.map(path -> path.getFileName().toString()) .toArray(String[]::new); assertEqualsNoOrder(result, new String[] { "SecurityException", "sample" }); } - try (CloseableStream s = Files.walk(fakeRoot.resolve("dir2"))) { + try (Stream s = Files.walk(fakeRoot.resolve("dir2"))) { String[] result = s.map(path -> path.getFileName().toString()) .toArray(String[]::new); assertEqualsNoOrder(result, new String[] { "dir2", "SecurityException", "fileInSE", "file" }); } if (supportsLinks) { - try (CloseableStream s = Files.list(fakeRoot.resolve("dir"))) { + try (Stream s = Files.list(fakeRoot.resolve("dir"))) { String[] result = s.map(path -> path.getFileName().toString()) .toArray(String[]::new); assertEqualsNoOrder(result, new String[] { "d1", "f1", "lnDir2", "SecurityException", "lnDirSE", "lnFileSE" }); @@ -525,13 +524,13 @@ public class StreamTest { // execute test fsp.setFaultyMode(true); // ignore file cause SecurityException - try (CloseableStream s = Files.walk(fakeRoot.resolve("empty"))) { + try (Stream s = Files.walk(fakeRoot.resolve("empty"))) { String[] result = s.map(path -> path.getFileName().toString()) .toArray(String[]::new); assertEqualsNoOrder(result, new String[] { "empty", "sample" }); } // skip folder cause SecurityException - try (CloseableStream s = Files.walk(fakeRoot.resolve("dir2"))) { + try (Stream s = Files.walk(fakeRoot.resolve("dir2"))) { String[] result = s.map(path -> path.getFileName().toString()) .toArray(String[]::new); assertEqualsNoOrder(result, new String[] { "dir2", "file" }); @@ -539,14 +538,14 @@ public class StreamTest { if (supportsLinks) { // not following links - try (CloseableStream s = Files.walk(fakeRoot.resolve("dir"))) { + try (Stream s = Files.walk(fakeRoot.resolve("dir"))) { String[] result = s.map(path -> path.getFileName().toString()) .toArray(String[]::new); assertEqualsNoOrder(result, new String[] { "dir", "d1", "f1", "lnDir2", "lnDirSE", "lnFileSE" }); } // following links - try (CloseableStream s = Files.walk(fakeRoot.resolve("dir"), FileVisitOption.FOLLOW_LINKS)) { + try (Stream s = Files.walk(fakeRoot.resolve("dir"), FileVisitOption.FOLLOW_LINKS)) { String[] result = s.map(path -> path.getFileName().toString()) .toArray(String[]::new); // ?? Should fileInSE show up? @@ -556,19 +555,19 @@ public class StreamTest { } // list instead of walk - try (CloseableStream s = Files.list(fakeRoot.resolve("empty"))) { + try (Stream s = Files.list(fakeRoot.resolve("empty"))) { String[] result = s.map(path -> path.getFileName().toString()) .toArray(String[]::new); assertEqualsNoOrder(result, new String[] { "sample" }); } - try (CloseableStream s = Files.list(fakeRoot.resolve("dir2"))) { + try (Stream s = Files.list(fakeRoot.resolve("dir2"))) { String[] result = s.map(path -> path.getFileName().toString()) .toArray(String[]::new); assertEqualsNoOrder(result, new String[] { "file" }); } // root cause SecurityException should be reported - try (CloseableStream s = Files.walk( + try (Stream s = Files.walk( fakeRoot.resolve("dir2").resolve("SecurityException"))) { String[] result = s.map(path -> path.getFileName().toString()) @@ -579,7 +578,7 @@ public class StreamTest { } // Walk a file cause SecurityException, we should get SE - try (CloseableStream s = Files.walk( + try (Stream s = Files.walk( fakeRoot.resolve("dir").resolve("SecurityException"))) { String[] result = s.map(path -> path.getFileName().toString()) @@ -590,7 +589,7 @@ public class StreamTest { } // List a file cause SecurityException, we should get SE as cannot read attribute - try (CloseableStream s = Files.list( + try (Stream s = Files.list( fakeRoot.resolve("dir2").resolve("SecurityException"))) { String[] result = s.map(path -> path.getFileName().toString()) @@ -600,7 +599,7 @@ public class StreamTest { assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException); } - try (CloseableStream s = Files.list( + try (Stream s = Files.list( fakeRoot.resolve("dir").resolve("SecurityException"))) { String[] result = s.map(path -> path.getFileName().toString()) @@ -627,7 +626,7 @@ public class StreamTest { } public void testConstructException() { - try (CloseableStream s = Files.lines(testFolder.resolve("notExist"), Charset.forName("UTF-8"))) { + try (Stream s = Files.lines(testFolder.resolve("notExist"), Charset.forName("UTF-8"))) { s.forEach(l -> fail("File is not even exist!")); } catch (IOException ioe) { assertTrue(ioe instanceof NoSuchFileException); @@ -635,24 +634,26 @@ public class StreamTest { } public void testClosedStream() throws IOException { - try (CloseableStream s = Files.list(testFolder)) { + try (Stream s = Files.list(testFolder)) { s.close(); - Object[] actual = s.sorted(Comparator.naturalOrder()).toArray(); - assertTrue(actual.length <= level1.length); - } - - try (CloseableStream s = Files.walk(testFolder)) { - s.close(); - Object[] actual = s.sorted(Comparator.naturalOrder()).toArray(); + Object[] actual = s.sorted().toArray(); fail("Operate on closed stream should throw IllegalStateException"); } catch (IllegalStateException ex) { // expected } - try (CloseableStream s = Files.find(testFolder, Integer.MAX_VALUE, + try (Stream s = Files.walk(testFolder)) { + s.close(); + Object[] actual = s.sorted().toArray(); + fail("Operate on closed stream should throw IllegalStateException"); + } catch (IllegalStateException ex) { + // expected + } + + try (Stream s = Files.find(testFolder, Integer.MAX_VALUE, (p, attr) -> true)) { s.close(); - Object[] actual = s.sorted(Comparator.naturalOrder()).toArray(); + Object[] actual = s.sorted().toArray(); fail("Operate on closed stream should throw IllegalStateException"); } catch (IllegalStateException ex) { // expected diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestScenario.java b/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestScenario.java index d4459cf0c9b..43b99973dd2 100644 --- a/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestScenario.java +++ b/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestScenario.java @@ -40,7 +40,7 @@ import java.util.function.Function; @SuppressWarnings({"rawtypes", "unchecked"}) public enum DoubleStreamTestScenario implements OpTestCase.BaseStreamTestScenario { - STREAM_FOR_EACH(false) { + STREAM_FOR_EACH_WITH_CLOSE(false) { > void _run(TestData data, DoubleConsumer b, Function m) { DoubleStream s = m.apply(data.stream()); @@ -48,6 +48,7 @@ public enum DoubleStreamTestScenario implements OpTestCase.BaseStreamTestScenari s = s.sequential(); } s.forEach(b); + s.close(); } }, diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestScenario.java b/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestScenario.java index f399cdeef25..4127a7b5a81 100644 --- a/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestScenario.java +++ b/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestScenario.java @@ -40,7 +40,7 @@ import java.util.function.IntConsumer; @SuppressWarnings({"rawtypes", "unchecked"}) public enum IntStreamTestScenario implements OpTestCase.BaseStreamTestScenario { - STREAM_FOR_EACH(false) { + STREAM_FOR_EACH_WITH_CLOSE(false) { > void _run(TestData data, IntConsumer b, Function m) { IntStream s = m.apply(data.stream()); @@ -48,6 +48,7 @@ public enum IntStreamTestScenario implements OpTestCase.BaseStreamTestScenario { s = s.sequential(); } s.forEach(b); + s.close(); } }, diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestScenario.java b/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestScenario.java index 3010745a55d..0a334bc0261 100644 --- a/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestScenario.java +++ b/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestScenario.java @@ -40,7 +40,7 @@ import java.util.function.LongConsumer; @SuppressWarnings({"rawtypes", "unchecked"}) public enum LongStreamTestScenario implements OpTestCase.BaseStreamTestScenario { - STREAM_FOR_EACH(false) { + STREAM_FOR_EACH_WITH_CLOSE(false) { > void _run(TestData data, LongConsumer b, Function m) { LongStream s = m.apply(data.stream()); @@ -48,6 +48,7 @@ public enum LongStreamTestScenario implements OpTestCase.BaseStreamTestScenario s = s.sequential(); } s.forEach(b); + s.close(); } }, diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestScenario.java b/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestScenario.java index b1abd4320db..d1a446234a7 100644 --- a/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestScenario.java +++ b/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestScenario.java @@ -39,7 +39,7 @@ import java.util.function.Function; @SuppressWarnings({"rawtypes", "unchecked"}) public enum StreamTestScenario implements OpTestCase.BaseStreamTestScenario { - STREAM_FOR_EACH(false) { + STREAM_FOR_EACH_WITH_CLOSE(false) { > void _run(TestData data, Consumer b, Function> m) { Stream s = m.apply(data.stream()); @@ -47,6 +47,7 @@ public enum StreamTestScenario implements OpTestCase.BaseStreamTestScenario { s = s.sequential(); } s.forEach(b); + s.close(); } }, diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java new file mode 100644 index 00000000000..51ffd4b9010 --- /dev/null +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2013, 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. + */ +package org.openjdk.tests.java.util.stream; + +import java.util.Arrays; +import java.util.stream.OpTestCase; +import java.util.stream.Stream; + +import org.testng.annotations.Test; + +import static java.util.stream.LambdaTestHelpers.countTo; + +/** + * StreamCloseTest + * + * @author Brian Goetz + */ +@Test(groups = { "serialization-hostile" }) +public class StreamCloseTest extends OpTestCase { + public void testEmptyCloseHandler() { + try (Stream ints = countTo(100).stream()) { + ints.forEach(i -> {}); + } + } + + public void testOneCloseHandler() { + final boolean[] holder = new boolean[1]; + Runnable closer = () -> { holder[0] = true; }; + + try (Stream ints = countTo(100).stream()) { + ints.onClose(closer); + ints.forEach(i -> {}); + } + assertTrue(holder[0]); + + Arrays.fill(holder, false); + try (Stream ints = countTo(100).stream().onClose(closer)) { + ints.forEach(i -> {}); + } + assertTrue(holder[0]); + + Arrays.fill(holder, false); + try (Stream ints = countTo(100).stream().filter(e -> true).onClose(closer)) { + ints.forEach(i -> {}); + } + assertTrue(holder[0]); + + Arrays.fill(holder, false); + try (Stream ints = countTo(100).stream().filter(e -> true).onClose(closer).filter(e -> true)) { + ints.forEach(i -> {}); + } + assertTrue(holder[0]); + } + + public void testTwoCloseHandlers() { + final boolean[] holder = new boolean[2]; + Runnable close1 = () -> { holder[0] = true; }; + Runnable close2 = () -> { holder[1] = true; }; + + try (Stream ints = countTo(100).stream()) { + ints.onClose(close1).onClose(close2); + ints.forEach(i -> {}); + } + assertTrue(holder[0] && holder[1]); + + Arrays.fill(holder, false); + try (Stream ints = countTo(100).stream().onClose(close1).onClose(close2)) { + ints.forEach(i -> {}); + } + assertTrue(holder[0] && holder[1]); + + Arrays.fill(holder, false); + try (Stream ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2)) { + ints.forEach(i -> {}); + } + assertTrue(holder[0] && holder[1]); + + Arrays.fill(holder, false); + try (Stream ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).filter(e -> true)) { + ints.forEach(i -> {}); + } + assertTrue(holder[0] && holder[1]); + } + + public void testCascadedExceptions() { + final boolean[] holder = new boolean[3]; + boolean caught = false; + Runnable close1 = () -> { holder[0] = true; throw new RuntimeException("1"); }; + Runnable close2 = () -> { holder[1] = true; throw new RuntimeException("2"); }; + Runnable close3 = () -> { holder[2] = true; throw new RuntimeException("3"); }; + + try (Stream ints = countTo(100).stream()) { + ints.onClose(close1).onClose(close2).onClose(close3); + ints.forEach(i -> {}); + } + catch (RuntimeException e) { + assertCascaded(e, 3); + assertTrue(holder[0] && holder[1] && holder[2]); + caught = true; + } + assertTrue(caught); + + Arrays.fill(holder, false); + caught = false; + try (Stream ints = countTo(100).stream().onClose(close1).onClose(close2).onClose(close3)) { + ints.forEach(i -> {}); + } + catch (RuntimeException e) { + assertCascaded(e, 3); + assertTrue(holder[0] && holder[1] && holder[2]); + caught = true; + } + assertTrue(caught); + + caught = false; + Arrays.fill(holder, false); + try (Stream ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).onClose(close3)) { + ints.forEach(i -> {}); + } + catch (RuntimeException e) { + assertCascaded(e, 3); + assertTrue(holder[0] && holder[1] && holder[2]); + caught = true; + } + assertTrue(caught); + + caught = false; + Arrays.fill(holder, false); + try (Stream ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).filter(e -> true).onClose(close3)) { + ints.forEach(i -> {}); + } + catch (RuntimeException e) { + assertCascaded(e, 3); + assertTrue(holder[0] && holder[1] && holder[2]); + caught = true; + } + assertTrue(caught); + } + + private void assertCascaded(RuntimeException e, int n) { + assertTrue(e.getMessage().equals("1")); + assertTrue(e.getSuppressed().length == n - 1); + for (int i=0; i Date: Tue, 3 Sep 2013 22:37:07 +0100 Subject: [PATCH 0074/1294] 8017195: Introduce option to setKeepAlive parameter on CORBA sockets Reviewed-by: chegar, msheppar --- .../sun/corba/transport/KeepAliveSockets.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 jdk/test/com/sun/corba/transport/KeepAliveSockets.java diff --git a/jdk/test/com/sun/corba/transport/KeepAliveSockets.java b/jdk/test/com/sun/corba/transport/KeepAliveSockets.java new file mode 100644 index 00000000000..4d9b9d97855 --- /dev/null +++ b/jdk/test/com/sun/corba/transport/KeepAliveSockets.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013, 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 8017195 + * @summary Introduce option to setKeepAlive parameter on CORBA sockets + * + * @run main/othervm KeepAliveSockets + * @run main/othervm -Dcom.sun.CORBA.transport.enableTcpKeepAlive KeepAliveSockets + * @run main/othervm -Dcom.sun.CORBA.transport.enableTcpKeepAlive=true KeepAliveSockets + * @run main/othervm -Dcom.sun.CORBA.transport.enableTcpKeepAlive=false KeepAliveSockets + */ + +import java.lang.*; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.nio.channels.ServerSocketChannel; +import java.util.*; +import com.sun.corba.se.impl.orb.*; + +import com.sun.corba.se.impl.transport.*; + +public class KeepAliveSockets { + + public static void main(String[] args) throws Exception { + + boolean keepAlive = false; + String prop = System.getProperty("com.sun.CORBA.transport.enableTcpKeepAlive"); + if (prop != null) + keepAlive = !"false".equalsIgnoreCase(prop); + + DefaultSocketFactoryImpl sfImpl = new DefaultSocketFactoryImpl(); + ORBImpl orb = new ORBImpl(); + orb.set_parameters(null); + sfImpl.setORB(orb); + + ServerSocketChannel ssc = ServerSocketChannel.open(); + ssc.socket().bind(new InetSocketAddress(0)); + + InetSocketAddress isa = new InetSocketAddress("localhost", ssc.socket().getLocalPort()); + Socket s = sfImpl.createSocket("ignore", isa); + System.out.println("Received factory socket" + s); + if (keepAlive != s.getKeepAlive()) + throw new RuntimeException("KeepAlive value not honoured in CORBA socket"); + } + +} From 25af2121aa224df049dbf1dbc50dc869523bdeed Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Tue, 3 Sep 2013 16:05:45 -0700 Subject: [PATCH 0075/1294] 8023997: j.l.String.join(java.lang.CharSequence, java.lang.Iterable) sample doesn't compile and is incorrect Reviewed-by: alanb --- jdk/src/share/classes/java/lang/String.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/lang/String.java b/jdk/src/share/classes/java/lang/String.java index 651a85017ed..e9d75afbbce 100644 --- a/jdk/src/share/classes/java/lang/String.java +++ b/jdk/src/share/classes/java/lang/String.java @@ -2457,8 +2457,8 @@ public final class String * String message = String.join(" ", strings); * //message returned is: "Java is cool" * - * Set strings = new HashSet<>(); - * Strings.add("Java"); strings.add("is"); + * Set strings = new LinkedHashSet<>(); + * strings.add("Java"); strings.add("is"); * strings.add("very"); strings.add("cool"); * String message = String.join("-", strings); * //message returned is: "Java-is-very-cool" From 7fc1c28757b950e48af2058b2bb7c45f7c9979b2 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Tue, 3 Sep 2013 23:47:27 -0400 Subject: [PATCH 0076/1294] 8024140: [TESTBUG] Profile based regression test groups for jdk repo Reviewed-by: alanb, chegar --- jdk/test/TEST.groups | 338 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 338 insertions(+) diff --git a/jdk/test/TEST.groups b/jdk/test/TEST.groups index ed70cbf6704..a59b38853ff 100644 --- a/jdk/test/TEST.groups +++ b/jdk/test/TEST.groups @@ -212,3 +212,341 @@ jdk_desktop = \ :jdk_swing \ :jdk_sound \ :jdk_imageio + +############################################################################### +# Profile-based Test Group Definitions +# +# These groups define the tests that cover the different possible runtimes: +# - compact1, compact2, compact3, full JRE, JDK +# +# In addition they support testing of the minimal VM on compact1 and compact2. +# Essentially this defines groups based around the specified API's and VM +# services available in the runtime. +# +# The groups are defined hierarchically in two forms: +# - The need_xxx groups list all the tests that have a dependency on +# a specific profile. This is either because it tests a feature in +# that profile, or the test infrastructure uses a feature in that +# profile. +# - The primary groups are defined in terms of the other primary groups +# combined with the needs_xxx groups (including and excluding them as +# appropriate). For example the jre can run all tests from compact3, plus +# those from needs_jre, but excluding those from need_jdk. +# +# The bottom group defines all the actual tests to be considered, simply +# by listing the top-level test directories. + +# Full JDK can run all tests +# +jdk = \ + :jre \ + :needs_jdk + +# Tests that require a full JDK to execute. Either they test a feature +# only in the JDK or they use tools that are only in the JDK. The latter +# can be resolved in some cases by using tools from the compile-jdk. +# +needs_jdk = \ + :jdk_jdi \ + com/sun/tools \ + demo \ + sun/security/tools/jarsigner \ + sun/rmi/rmic \ + sun/tools \ + sun/jvmstat \ + tools \ + com/sun/jmx/remote/NotificationMarshalVersions/TestSerializationMismatch.java \ + java/io/Serializable/serialver \ + java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java \ + java/lang/invoke/lambda/LambdaAccessControlTest.java \ + java/lang/System/MacEncoding/TestFileEncoding.java \ + java/net/URLClassLoader/closetest/GetResourceAsStream.java \ + java/util/Collections/EmptyIterator.java \ + java/util/concurrent/locks/Lock/TimedAcquireLeak.java \ + java/util/jar/Manifest/CreateManifest.java \ + java/util/jar/JarInputStream/ExtraFileInMetaInf.java \ + java/util/logging/AnonLoggerWeakRefLeak.sh \ + java/util/logging/LoggerWeakRefLeak.sh \ + java/util/zip/3GBZipFiles.sh \ + jdk/lambda/FDTest.java \ + jdk/lambda/separate/Compiler.java \ + sun/management/jdp/JdpTest.sh \ + sun/management/jmxremote/bootstrap/JvmstatCountersTest.java \ + sun/management/jmxremote/bootstrap/LocalManagementTest.sh \ + sun/misc/JarIndex/metaInfFilenames/Basic.java \ + sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java \ + sun/reflect/CallerSensitive/CallerSensitiveFinder.java \ + sun/reflect/CallerSensitive/MissingCallerSensitive.java \ + sun/security/util/Resources/NewNamesFormat.java \ + vm/verifier/defaultMethods/DefaultMethodRegressionTestsRun.java + +# JRE adds further tests to compact3 +# +jre = \ + :compact3 \ + :needs_jre \ + -:needs_jdk + +# Tests that require the full JRE +# +needs_jre = \ + :needs_charsets \ + :jdk_desktop \ + com/sun/corba \ + com/sun/jndi/cosnaming \ + sun/net/ftp \ + sun/net/www/protocol/ftp \ + sun/security/tools/policytool \ + java/net/URI/URItoURLTest.java \ + java/net/URL/URIToURLTest.java \ + java/net/URLConnection/HandleContentTypeWithAttrs.java \ + java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh \ + java/security/Security/ClassLoaderDeadlock/Deadlock.sh \ + java/util/logging/Listeners.java \ + java/util/logging/ListenersWithSM.java \ + java/util/ResourceBundle/Control/Bug6530694.java \ + java/text/Bidi/BidiConformance.java \ + java/text/Bidi/BidiEmbeddingTest.java \ + java/text/Bidi/Bug6665028.java \ + java/text/Bidi/Bug7042148.java \ + java/text/Bidi/Bug7051769.java \ + javax/crypto/Cipher/CipherStreamClose.java \ + javax/management/monitor/AttributeArbitraryDataTypeTest.java \ + jdk/lambda/vm/InterfaceAccessFlagsTest.java \ + sun/misc/URLClassPath/ClassnameCharTest.java + +# Tests dependent on the optional charsets.jar +# These are isolated for easy exclusions +# +needs_charsets = \ + java/io/OutputStreamWriter/TestWrite.java \ + java/nio/charset/RemovingSunIO/SunioAlias.java \ + java/nio/charset/coders/Check.java \ + java/nio/charset/Charset/CharsetContainmentTest.java \ + java/nio/charset/Charset/Contains.java \ + java/nio/charset/Charset/NIOCharsetAvailabilityTest.java \ + java/nio/charset/Charset/RegisteredCharsets.java \ + java/nio/charset/CharsetEncoder/Flush.java \ + java/nio/charset/coders/CheckSJISMappingProp.sh \ + java/nio/charset/coders/ResetISO2022JP.java \ + java/util/Locale/InternationalBAT.java \ + java/util/Locale/LocaleProviders.sh \ + java/util/Calendar/CldrFormatNamesTest.java \ + java/util/TimeZone/CLDRDisplayNamesTest.java \ + java/util/zip/ZipCoding.java \ + sun/nio/cs/EucJpLinux0212.java \ + sun/nio/cs/EUCJPUnderflowDecodeTest.java \ + sun/nio/cs/EuroConverter.java \ + sun/nio/cs/JISAutoDetectTest.java \ + sun/nio/cs/OLD/TestIBMDB.java \ + sun/nio/cs/SJISCanEncode.java \ + sun/nio/cs/Test6254467.java \ + sun/nio/cs/TestCompoundTest.java \ + sun/nio/cs/TestCp834_SBCS.java \ + sun/nio/cs/TestEUC_TW.java \ + sun/nio/cs/TestISO2022CNDecoder.java \ + sun/nio/cs/TestISO2022JPEncoder.java \ + sun/nio/cs/TestISO2022JPSubBytes.java \ + sun/nio/cs/TestIllegalSJIS.java \ + sun/nio/cs/TestJIS0208Decoder.java \ + sun/nio/cs/TestJIS0212Decoder.java \ + sun/nio/cs/TestMiscEUC_JP.java \ + sun/nio/cs/TestSJIS0213_SM.java \ + sun/nio/cs/BufferUnderflowEUCTWTest.java \ + sun/nio/cs/CheckCaseInsensitiveEncAliases.java \ + sun/nio/cs/CheckHistoricalNames.java \ + sun/nio/cs/EucJpLinuxDecoderRecoveryTest.java \ + sun/nio/cs/HWKatakanaMS932EncodeTest.java \ + sun/nio/cs/ISCIITest.java \ + sun/nio/cs/LatinCharReplacementTWTest.java \ + sun/nio/cs/NIOJISAutoDetectTest.java \ + sun/nio/cs/StreamEncoderClose.java \ + sun/nio/cs/SurrogateGB18030Test.java \ + sun/nio/cs/SurrogateTestEUCTW.java \ + sun/nio/cs/SurrogateTestHKSCS.java \ + sun/nio/cs/TestConverterDroppedCharacters.java \ + sun/nio/cs/TestCp93xSISO.java \ + sun/nio/cs/TestIBM1364.java \ + sun/nio/cs/TestIBMBugs.java \ + sun/nio/cs/TestIllegalISO2022Esc.java \ + sun/nio/cs/TestISO2022JP.java \ + sun/nio/cs/TestMS5022X.java \ + sun/nio/cs/TestSJIS0213.java \ + sun/nio/cs/TestTrailingEscapesISO2022JP.java \ + sun/nio/cs/TestUni2HKSCS.java \ + sun/nio/cs/ZeroedByteArrayEUCTWTest.java + +# Compact 3 adds further tests to compact2 +# +compact3 = \ + :compact2 \ + :needs_compact3 \ + -:needs_jre \ + -:needs_jdk + + +# Tests that require compact3 API's +# +needs_compact3 = \ + :jdk_instrument \ + :jdk_jmx \ + :jdk_management \ + :jdk_sctp \ + com/sun/jndi \ + com/sun/org/apache/xml/internal/security \ + com/sun/security/auth \ + com/sun/security/sasl \ + com/sun/security/jgss \ + com/sun/tracing \ + java/util/prefs \ + javax/naming \ + javax/security \ + javax/smartcardio \ + javax/sql/rowset \ + javax/xml/crypto \ + sun/security/acl \ + sun/security/jgss \ + sun/security/krb5 \ + java/lang/System/MacEncoding/TestFileEncoding.java \ + java/nio/channels/AsynchronousSocketChannel/Leaky.java \ + java/security/PermissionCollection/Concurrent.java \ + java/security/Principal/Implies.java \ + java/security/cert/GetInstance.java \ + java/util/logging/DrainFindDeadlockTest.java \ + java/util/logging/LoggingMXBeanTest.java \ + sun/net/www/http/KeepAliveCache/B5045306.java \ + sun/security/provider/PolicyFile/Alias.java \ + sun/security/provider/PolicyFile/Comparator.java \ + sun/security/provider/PolicyFile/SelfWildcard.java \ + sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/SSLEngineDeadlock.java \ + sun/security/util/Oid/OidFormat.java \ + sun/security/util/Resources/Format.java \ + sun/security/util/Resources/NewNamesFormat.java + +# Compact 2 adds full VM tests +compact2 = \ + :compact2_minimal \ + :compact1 \ + :needs_full_vm_compact2 \ + -:needs_compact3 \ + -:needs_jre \ + -:needs_jdk + +# Tests that require compact2 API's and a full VM +# +needs_full_vm_compact2 = + +# Minimal VM on Compact 2 adds in some compact2 tests +# +compact2_minimal = \ + :compact1_minimal \ + :needs_compact2 \ + -:needs_compact3 \ + -:needs_jre \ + -:needs_jdk + +# Tests that require compact2 API's +# +needs_compact2 = \ + :jdk_rmi \ + :jdk_time \ + com/sun/org/apache \ + com/sun/net/httpserver \ + java/sql \ + javax/sql \ + javax/xml \ + jdk/lambda \ + sun/net/www/http \ + sun/net/www/protocol/http \ + java/io/BufferedReader/Lines.java \ + java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java \ + java/lang/CharSequence/DefaultTest.java \ + java/lang/IntegralPrimitiveToString.java \ + java/lang/PrimitiveSumMinMaxTest.java \ + java/lang/String/StringJoinTest.java \ + java/lang/Thread/StopThrowable.java \ + java/net/Authenticator/Deadlock.java \ + java/net/CookieHandler/LocalHostCookie.java \ + java/net/CookieHandler/CookieManagerTest.java \ + java/net/CookieHandler/EmptyCookieHeader.java \ + java/net/HttpCookie/IllegalCookieNameTest.java \ + java/net/HttpURLConnection/UnmodifiableMaps.java \ + java/net/HttpURLPermission/URLTest.java \ + java/net/ResponseCache/Test.java \ + java/net/URLClassLoader/ClassLoad.java \ + java/net/URLClassLoader/closetest/CloseTest.java \ + java/nio/Buffer/Chars.java \ + java/nio/file/Files/StreamTest.java \ + java/security/BasicPermission/Wildcard.java \ + java/util/Arrays/ParallelPrefix.java \ + java/util/Arrays/SetAllTest.java \ + java/util/BitSet/BitSetStreamTest.java \ + java/util/Collection/CollectionDefaults.java \ + java/util/Collection/ListDefaults.java \ + java/util/Collections/CheckedIdentityMap.java \ + java/util/Collections/CheckedMapBash.java \ + java/util/Collections/CheckedSetBash.java \ + java/util/Collections/EmptyCollectionSerialization.java \ + java/util/Collections/EmptyNavigableMap.java \ + java/util/Collections/EmptyNavigableSet.java \ + java/util/Collections/UnmodifiableMapEntrySet.java \ + java/util/Comparator/BasicTest.java \ + java/util/Comparator/TypeTest.java \ + java/util/Iterator/IteratorDefaults.java \ + java/util/Iterator/PrimitiveIteratorDefaults.java \ + java/util/Map/BasicSerialization.java \ + java/util/Map/Defaults.java \ + java/util/Map/EntryComparators.java \ + java/util/Optional/Basic.java \ + java/util/Optional/BasicDouble.java \ + java/util/Optional/BasicInt.java \ + java/util/Optional/BasicLong.java \ + java/util/Random/RandomStreamTest.java \ + java/util/ResourceBundle/Bug6359330.java \ + java/util/Spliterator/SpliteratorCharacteristics.java \ + java/util/Spliterator/SpliteratorCollisions.java \ + java/util/Spliterator/SpliteratorLateBindingFailFastTest.java \ + java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java \ + java/util/StringJoiner/MergeTest.java \ + java/util/StringJoiner/StringJoinerTest.java \ + java/util/concurrent/atomic/AtomicReferenceTest.java \ + java/util/function/BinaryOperator/BasicTest.java \ + java/util/logging/LoggerSupplierAPIsTest.java \ + java/util/zip/ZipFile/StreamZipEntriesTest.java \ + java/util/zip/ZipFile/DeleteTempJar.java \ + javax/crypto/Cipher/CipherStreamClose.java \ + sun/misc/URLClassPath/ClassnameCharTest.java \ + sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java \ + sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java + +# Compact 1 adds full VM tests +# +compact1 = \ + :compact1_minimal \ + :needs_full_vm_compact1 \ + -:needs_compact2 \ + -:needs_full_vm_compact2 \ + -:needs_compact3 \ + -:needs_jre \ + -:needs_jdk + +# Tests that require compact1 API's and a full VM +# +needs_full_vm_compact1 = + +# All tests that run on the most minimal configuration: Minimal VM on Compact 1 +compact1_minimal = \ + com \ + java \ + javax \ + jdk \ + lib \ + sample \ + sun \ + vm \ + -:needs_full_vm_compact1 \ + -:needs_full_vm_compact2 \ + -:needs_compact2 \ + -:needs_compact3 \ + -:needs_jre \ + -:needs_jdk From 59440ee0bef7cce9a5f528e7840d098b89e9fc43 Mon Sep 17 00:00:00 2001 From: John Rose Date: Tue, 3 Sep 2013 21:42:56 -0700 Subject: [PATCH 0077/1294] 8008688: Make MethodHandleInfo public A major overhaul to MethodHandleInfo and method handles in general. Reviewed-by: vlivanov, twisti --- .../AbstractValidatingLambdaMetafactory.java | 2 +- .../java/lang/invoke/InfoFromMemberName.java | 145 ++++ .../classes/java/lang/invoke/Invokers.java | 2 + .../classes/java/lang/invoke/MemberName.java | 41 +- .../java/lang/invoke/MethodHandle.java | 40 +- .../java/lang/invoke/MethodHandleImpl.java | 75 +- .../java/lang/invoke/MethodHandleInfo.java | 286 +++++-- .../java/lang/invoke/MethodHandleNatives.java | 63 +- .../java/lang/invoke/MethodHandles.java | 93 ++- .../java/lang/invoke/SerializedLambda.java | 2 +- .../java/lang/invoke/7087570/Test7087570.java | 130 +-- .../java/lang/invoke/RevealDirectTest.java | 753 ++++++++++++++++++ .../java/lang/invoke/jtreg.security.policy | 9 + 13 files changed, 1437 insertions(+), 204 deletions(-) create mode 100644 jdk/src/share/classes/java/lang/invoke/InfoFromMemberName.java create mode 100644 jdk/test/java/lang/invoke/RevealDirectTest.java create mode 100644 jdk/test/java/lang/invoke/jtreg.security.policy diff --git a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java index 79b3b69fcf3..92a44a048f3 100644 --- a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java +++ b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java @@ -124,7 +124,7 @@ import static sun.invoke.util.Wrapper.isWrapperType; this.samMethodType = samMethodType; this.implMethod = implMethod; - this.implInfo = new MethodHandleInfo(implMethod); + this.implInfo = caller.revealDirect(implMethod); // @@@ Temporary work-around pending resolution of 8005119 this.implKind = (implInfo.getReferenceKind() == MethodHandleInfo.REF_invokeSpecial) ? MethodHandleInfo.REF_invokeVirtual diff --git a/jdk/src/share/classes/java/lang/invoke/InfoFromMemberName.java b/jdk/src/share/classes/java/lang/invoke/InfoFromMemberName.java new file mode 100644 index 00000000000..0ecd005a8d3 --- /dev/null +++ b/jdk/src/share/classes/java/lang/invoke/InfoFromMemberName.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.invoke; + +import java.security.*; +import java.lang.reflect.*; +import java.lang.invoke.MethodHandleNatives.Constants; +import java.lang.invoke.MethodHandles.Lookup; +import static java.lang.invoke.MethodHandleStatics.*; + +/* + * Auxiliary to MethodHandleInfo, wants to nest in MethodHandleInfo but must be non-public. + */ +/*non-public*/ +final +class InfoFromMemberName implements MethodHandleInfo { + private final MemberName member; + private final int referenceKind; + + InfoFromMemberName(Lookup lookup, MemberName member, byte referenceKind) { + assert(member.isResolved() || member.isMethodHandleInvoke()); + assert(member.referenceKindIsConsistentWith(referenceKind)); + this.member = member; + this.referenceKind = referenceKind; + } + + @Override + public Class getDeclaringClass() { + return member.getDeclaringClass(); + } + + @Override + public String getName() { + return member.getName(); + } + + @Override + public MethodType getMethodType() { + return member.getMethodOrFieldType(); + } + + @Override + public int getModifiers() { + return member.getModifiers(); + } + + @Override + public int getReferenceKind() { + return referenceKind; + } + + @Override + public String toString() { + return MethodHandleInfo.toString(getReferenceKind(), getDeclaringClass(), getName(), getMethodType()); + } + + @Override + public T reflectAs(Class expected, Lookup lookup) { + if (member.isMethodHandleInvoke() && !member.isVarargs()) { + // This member is an instance of a signature-polymorphic method, which cannot be reflected + // A method handle invoker can come in either of two forms: + // A generic placeholder (present in the source code, and varargs) + // and a signature-polymorphic instance (synthetic and not varargs). + // For more information see comments on {@link MethodHandleNatives#linkMethod}. + throw new IllegalArgumentException("cannot reflect signature polymorphic method"); + } + Member mem = AccessController.doPrivileged(new PrivilegedAction() { + public Member run() { + try { + return reflectUnchecked(); + } catch (ReflectiveOperationException ex) { + throw new IllegalArgumentException(ex); + } + } + }); + try { + Class defc = getDeclaringClass(); + byte refKind = (byte) getReferenceKind(); + lookup.checkAccess(refKind, defc, convertToMemberName(refKind, mem)); + } catch (IllegalAccessException ex) { + throw new IllegalArgumentException(ex); + } + return expected.cast(mem); + } + + private Member reflectUnchecked() throws ReflectiveOperationException { + byte refKind = (byte) getReferenceKind(); + Class defc = getDeclaringClass(); + boolean isPublic = Modifier.isPublic(getModifiers()); + if (MethodHandleNatives.refKindIsMethod(refKind)) { + if (isPublic) + return defc.getMethod(getName(), getMethodType().parameterArray()); + else + return defc.getDeclaredMethod(getName(), getMethodType().parameterArray()); + } else if (MethodHandleNatives.refKindIsConstructor(refKind)) { + if (isPublic) + return defc.getConstructor(getMethodType().parameterArray()); + else + return defc.getDeclaredConstructor(getMethodType().parameterArray()); + } else if (MethodHandleNatives.refKindIsField(refKind)) { + if (isPublic) + return defc.getField(getName()); + else + return defc.getDeclaredField(getName()); + } else { + throw new IllegalArgumentException("referenceKind="+refKind); + } + } + + private static MemberName convertToMemberName(byte refKind, Member mem) throws IllegalAccessException { + if (mem instanceof Method) { + boolean wantSpecial = (refKind == REF_invokeSpecial); + return new MemberName((Method) mem, wantSpecial); + } else if (mem instanceof Constructor) { + return new MemberName((Constructor) mem); + } else if (mem instanceof Field) { + boolean isSetter = (refKind == REF_putField || refKind == REF_putStatic); + return new MemberName((Field) mem, isSetter); + } + throw new InternalError(mem.getClass().getName()); + } +} diff --git a/jdk/src/share/classes/java/lang/invoke/Invokers.java b/jdk/src/share/classes/java/lang/invoke/Invokers.java index 8d8e019d722..0ef6078b6b5 100644 --- a/jdk/src/share/classes/java/lang/invoke/Invokers.java +++ b/jdk/src/share/classes/java/lang/invoke/Invokers.java @@ -87,6 +87,7 @@ class Invokers { lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_INVOKER); invoker = SimpleMethodHandle.make(invokerType, lform); } + invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invokeExact", mtype)); assert(checkInvoker(invoker)); exactInvoker = invoker; return invoker; @@ -110,6 +111,7 @@ class Invokers { lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_INVOKER); invoker = SimpleMethodHandle.make(invokerType, lform); } + invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invoke", mtype)); assert(checkInvoker(invoker)); generalInvoker = invoker; return invoker; diff --git a/jdk/src/share/classes/java/lang/invoke/MemberName.java b/jdk/src/share/classes/java/lang/invoke/MemberName.java index dfb468417d6..910574befe7 100644 --- a/jdk/src/share/classes/java/lang/invoke/MemberName.java +++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java @@ -320,14 +320,18 @@ import java.util.Objects; /** Utility method to query if this member is a method handle invocation (invoke or invokeExact). */ public boolean isMethodHandleInvoke() { - final int bits = Modifier.NATIVE | Modifier.FINAL; + final int bits = MH_INVOKE_MODS; final int negs = Modifier.STATIC; if (testFlags(bits | negs, bits) && clazz == MethodHandle.class) { - return name.equals("invoke") || name.equals("invokeExact"); + return isMethodHandleInvokeName(name); } return false; } + public static boolean isMethodHandleInvokeName(String name) { + return name.equals("invoke") || name.equals("invokeExact"); + } + private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC; /** Utility method to query the modifier flags of this member. */ public boolean isStatic() { @@ -482,12 +486,27 @@ import java.util.Objects; m.getClass(); // NPE check // fill in vmtarget, vmindex while we have m in hand: MethodHandleNatives.init(this, m); + if (clazz == null) { // MHN.init failed + if (m.getDeclaringClass() == MethodHandle.class && + isMethodHandleInvokeName(m.getName())) { + // The JVM did not reify this signature-polymorphic instance. + // Need a special case here. + // See comments on MethodHandleNatives.linkMethod. + MethodType type = MethodType.methodType(m.getReturnType(), m.getParameterTypes()); + int flags = flagsMods(IS_METHOD, m.getModifiers(), REF_invokeVirtual); + init(MethodHandle.class, m.getName(), type, flags); + if (isMethodHandleInvoke()) + return; + } + throw new LinkageError(m.toString()); + } assert(isResolved() && this.clazz != null); this.name = m.getName(); if (this.type == null) this.type = new Object[] { m.getReturnType(), m.getParameterTypes() }; if (wantSpecial) { - assert(!isAbstract()) : this; + if (isAbstract()) + throw new AbstractMethodError(this.toString()); if (getReferenceKind() == REF_invokeVirtual) changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual); else if (getReferenceKind() == REF_invokeInterface) @@ -562,6 +581,22 @@ import java.util.Objects; initResolved(true); } + /** + * Create a name for a signature-polymorphic invoker. + * This is a placeholder for a signature-polymorphic instance + * (of MH.invokeExact, etc.) that the JVM does not reify. + * See comments on {@link MethodHandleNatives#linkMethod}. + */ + static MemberName makeMethodHandleInvoke(String name, MethodType type) { + return makeMethodHandleInvoke(name, type, MH_INVOKE_MODS | SYNTHETIC); + } + static MemberName makeMethodHandleInvoke(String name, MethodType type, int mods) { + MemberName mem = new MemberName(MethodHandle.class, name, type, REF_invokeVirtual); + mem.flags |= mods; // it's not resolved, but add these modifiers anyway + assert(mem.isMethodHandleInvoke()) : mem; + return mem; + } + // bare-bones constructor; the JVM will fill it in MemberName() { } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java index df784d35e5b..408cbd08abc 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java @@ -1284,6 +1284,11 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); return null; // DMH returns DMH.member } + /*non-public*/ + MethodHandle withInternalMemberName(MemberName member) { + return MethodHandleImpl.makeWrappedMember(this, member); + } + /*non-public*/ boolean isInvokeSpecial() { return false; // DMH.Special returns true @@ -1356,7 +1361,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); MethodHandle rebind() { // Bind 'this' into a new invoker, of the known class BMH. MethodType type2 = type(); - LambdaForm form2 = reinvokerForm(type2.basicType()); + LambdaForm form2 = reinvokerForm(this); // form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) } return BoundMethodHandle.bindSingle(type2, form2, this); } @@ -1369,23 +1374,38 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); /** Create a LF which simply reinvokes a target of the given basic type. * The target MH must override {@link #reinvokerTarget} to provide the target. */ - static LambdaForm reinvokerForm(MethodType mtype) { - mtype = mtype.basicType(); + static LambdaForm reinvokerForm(MethodHandle target) { + MethodType mtype = target.type().basicType(); LambdaForm reinvoker = mtype.form().cachedLambdaForm(MethodTypeForm.LF_REINVOKE); if (reinvoker != null) return reinvoker; - MethodHandle MH_invokeBasic = MethodHandles.basicInvoker(mtype); + if (mtype.parameterSlotCount() >= MethodType.MAX_MH_ARITY) + return makeReinvokerForm(target.type(), target); // cannot cache this + reinvoker = makeReinvokerForm(mtype, null); + return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, reinvoker); + } + private static LambdaForm makeReinvokerForm(MethodType mtype, MethodHandle customTargetOrNull) { + boolean customized = (customTargetOrNull != null); + MethodHandle MH_invokeBasic = customized ? null : MethodHandles.basicInvoker(mtype); final int THIS_BMH = 0; final int ARG_BASE = 1; final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); int nameCursor = ARG_LIMIT; - final int NEXT_MH = nameCursor++; + final int NEXT_MH = customized ? -1 : nameCursor++; final int REINVOKE = nameCursor++; LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); - names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]); - Object[] targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class); - targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH - names[REINVOKE] = new LambdaForm.Name(MH_invokeBasic, targetArgs); - return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, new LambdaForm("BMH.reinvoke", ARG_LIMIT, names)); + Object[] targetArgs; + MethodHandle targetMH; + if (customized) { + targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class); + targetMH = customTargetOrNull; + } else { + names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]); + targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class); + targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH + targetMH = MethodHandles.basicInvoker(mtype); + } + names[REINVOKE] = new LambdaForm.Name(targetMH, targetArgs); + return new LambdaForm("BMH.reinvoke", ARG_LIMIT, names); } private static final LambdaForm.NamedFunction NF_reinvokerTarget; diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java index 04eda964966..5ab7f7adb7b 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -317,7 +317,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; private MethodHandle cache; AsVarargsCollector(MethodHandle target, MethodType type, Class arrayType) { - super(type, reinvokerForm(type)); + super(type, reinvokerForm(target)); this.target = target; this.arrayType = arrayType; this.cache = target.asCollector(arrayType, 0); @@ -778,16 +778,27 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } static Empty throwException(T t) throws T { throw t; } - static MethodHandle FAKE_METHOD_HANDLE_INVOKE; - static - MethodHandle fakeMethodHandleInvoke(MemberName method) { - MethodType type = method.getInvocationType(); - assert(type.equals(MethodType.methodType(Object.class, Object[].class))); - MethodHandle mh = FAKE_METHOD_HANDLE_INVOKE; + static MethodHandle[] FAKE_METHOD_HANDLE_INVOKE = new MethodHandle[2]; + static MethodHandle fakeMethodHandleInvoke(MemberName method) { + int idx; + assert(method.isMethodHandleInvoke()); + switch (method.getName()) { + case "invoke": idx = 0; break; + case "invokeExact": idx = 1; break; + default: throw new InternalError(method.getName()); + } + MethodHandle mh = FAKE_METHOD_HANDLE_INVOKE[idx]; if (mh != null) return mh; - mh = throwException(type.insertParameterTypes(0, UnsupportedOperationException.class)); + MethodType type = MethodType.methodType(Object.class, UnsupportedOperationException.class, + MethodHandle.class, Object[].class); + mh = throwException(type); mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke MethodHandle")); - FAKE_METHOD_HANDLE_INVOKE = mh; + if (!method.getInvocationType().equals(mh.type())) + throw new InternalError(method.toString()); + mh = mh.withInternalMemberName(method); + mh = mh.asVarargsCollector(Object[].class); + assert(method.isVarargs()); + FAKE_METHOD_HANDLE_INVOKE[idx] = mh; return mh; } @@ -821,7 +832,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; MethodHandle vamh = prepareForInvoker(mh); // Cache the result of makeInjectedInvoker once per argument class. MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass); - return restoreToType(bccInvoker.bindTo(vamh), mh.type()); + return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName()); } private static MethodHandle makeInjectedInvoker(Class hostClass) { @@ -876,8 +887,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } // Undo the adapter effect of prepareForInvoker: - private static MethodHandle restoreToType(MethodHandle vamh, MethodType type) { - return vamh.asCollector(Object[].class, type.parameterCount()).asType(type); + private static MethodHandle restoreToType(MethodHandle vamh, MethodType type, MemberName member) { + MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount()); + mh = mh.asType(type); + mh = mh.withInternalMemberName(member); + return mh; } private static final MethodHandle MH_checkCallerClass; @@ -939,4 +953,41 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } } } + + + /** This subclass allows a wrapped method handle to be re-associated with an arbitrary member name. */ + static class WrappedMember extends MethodHandle { + private final MethodHandle target; + private final MemberName member; + + private WrappedMember(MethodHandle target, MethodType type, MemberName member) { + super(type, reinvokerForm(target)); + this.target = target; + this.member = member; + } + + @Override + MethodHandle reinvokerTarget() { + return target; + } + @Override + MemberName internalMemberName() { + return member; + } + @Override + boolean isInvokeSpecial() { + return target.isInvokeSpecial(); + } + @Override + MethodHandle viewAsType(MethodType newType) { + return new WrappedMember(target, newType, member); + } + } + + static MethodHandle makeWrappedMember(MethodHandle target, MemberName member) { + if (member.equals(target.internalMemberName())) + return target; + return new WrappedMember(target, target.type(), member); + } + } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java index 380ca59b6e1..72fd8e91035 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java @@ -24,80 +24,246 @@ */ package java.lang.invoke; + +import java.lang.reflect.*; +import java.util.*; import java.lang.invoke.MethodHandleNatives.Constants; +import java.lang.invoke.MethodHandles.Lookup; +import static java.lang.invoke.MethodHandleStatics.*; /** - * Cracking (reflecting) method handles back into their constituent symbolic parts. + * A symbolic reference obtained by cracking a method handle into its consitutent symbolic parts. + * To crack a direct method handle, call {@link Lookup#revealDirect Lookup.revealDirect}. + *

    + * A direct method handle represents a method, constructor, or field without + * any intervening argument bindings or other transformations. + * The method, constructor, or field referred to by a direct method handle is called + * its underlying member. + * Direct method handles may be obtained in any of these ways: + *

    + * In all of these cases, it is possible to crack the resulting direct method handle + * to recover a symbolic reference for the underlying method, constructor, or field. + * Cracking must be done via a {@code Lookup} object equivalent to that which created + * the target method handle, or which has enough access permissions to recreate + * an equivalent method handle. * + *

    Reference kinds

    + * The Lookup Factory Methods + * correspond to all major use cases for methods, constructors, and fields. + * These use cases may be distinguished using small integers as follows: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    reference kinddescriptive namescopememberbehavior
    {@code 1}{@code REF_getField}{@code class}{@code FT f;}{@code (T) this.f;}
    {@code 2}{@code REF_getStatic}{@code class} or {@code interface}{@code static}
    {@code FT f;}
    {@code (T) C.f;}
    {@code 3}{@code REF_putField}{@code class}{@code FT f;}{@code this.f = x;}
    {@code 4}{@code REF_putStatic}{@code class}{@code static}
    {@code FT f;}
    {@code C.f = arg;}
    {@code 5}{@code REF_invokeVirtual}{@code class}{@code T m(A*);}{@code (T) this.m(arg*);}
    {@code 6}{@code REF_invokeStatic}{@code class} or {@code interface}{@code static}
    {@code T m(A*);}
    {@code (T) C.m(arg*);}
    {@code 7}{@code REF_invokeSpecial}{@code class} or {@code interface}{@code T m(A*);}{@code (T) super.m(arg*);}
    {@code 8}{@code REF_newInvokeSpecial}{@code class}{@code C(A*);}{@code new C(arg*);}
    {@code 9}{@code REF_invokeInterface}{@code interface}{@code T m(A*);}{@code (T) this.m(arg*);}
    + * @since 1.8 */ -final class MethodHandleInfo { - public static final int - REF_getField = Constants.REF_getField, - REF_getStatic = Constants.REF_getStatic, - REF_putField = Constants.REF_putField, - REF_putStatic = Constants.REF_putStatic, - REF_invokeVirtual = Constants.REF_invokeVirtual, - REF_invokeStatic = Constants.REF_invokeStatic, - REF_invokeSpecial = Constants.REF_invokeSpecial, - REF_newInvokeSpecial = Constants.REF_newInvokeSpecial, - REF_invokeInterface = Constants.REF_invokeInterface; +public +interface MethodHandleInfo { + /** + * A direct method handle reference kind, + * as defined in the table above. + */ + public static final int + REF_getField = Constants.REF_getField, + REF_getStatic = Constants.REF_getStatic, + REF_putField = Constants.REF_putField, + REF_putStatic = Constants.REF_putStatic, + REF_invokeVirtual = Constants.REF_invokeVirtual, + REF_invokeStatic = Constants.REF_invokeStatic, + REF_invokeSpecial = Constants.REF_invokeSpecial, + REF_newInvokeSpecial = Constants.REF_newInvokeSpecial, + REF_invokeInterface = Constants.REF_invokeInterface; - private final Class declaringClass; - private final String name; - private final MethodType methodType; - private final int referenceKind; + /** + * Returns the reference kind of the cracked method handle, which in turn + * determines whether the method handle's underlying member was a constructor, method, or field. + * See the table above for definitions. + * @return the integer code for the kind of reference used to access the underlying member + */ + public int getReferenceKind(); - public MethodHandleInfo(MethodHandle mh) { - MemberName mn = mh.internalMemberName(); - if (mn == null) throw new IllegalArgumentException("not a direct method handle"); - this.declaringClass = mn.getDeclaringClass(); - this.name = mn.getName(); - this.methodType = mn.getMethodOrFieldType(); - byte refKind = mn.getReferenceKind(); - if (refKind == REF_invokeSpecial && !mh.isInvokeSpecial()) - // Devirtualized method invocation is usually formally virtual. - refKind = REF_invokeVirtual; - this.referenceKind = refKind; - } + /** + * Returns the class in which the cracked method handle's underlying member was defined. + * @return the declaring class of the underlying member + */ + public Class getDeclaringClass(); - public Class getDeclaringClass() { - return declaringClass; - } + /** + * Returns the name of the cracked method handle's underlying member. + * This is {@code "<init>"} if the underlying member was a constructor, + * else it is a simple method name or field name. + * @return the simple name of the underlying member + */ + public String getName(); - public String getName() { - return name; - } + /** + * Returns the nominal type of the cracked symbolic reference, expressed as a method type. + * If the reference is to a constructor, the return type will be {@code void}. + * If it is to a non-static method, the method type will not mention the {@code this} parameter. + * If it is to a field and the requested access is to read the field, + * the method type will have no parameters and return the field type. + * If it is to a field and the requested access is to write the field, + * the method type will have one parameter of the field type and return {@code void}. + *

    + * Note that original direct method handle may include a leading {@code this} parameter, + * or (in the case of a constructor) will replace the {@code void} return type + * with the constructed class. + * The nominal type does not include any {@code this} parameter, + * and (in the case of a constructor) will return {@code void}. + * @return the type of the underlying member, expressed as a method type + */ + public MethodType getMethodType(); - public MethodType getMethodType() { - return methodType; - } + // Utility methods. + // NOTE: class/name/type and reference kind constitute a symbolic reference + // member and modifiers are an add-on, derived from Core Reflection (or the equivalent) - public int getModifiers() { - return -1; //TODO - } + /** + * Reflects the underlying member as a method, constructor, or field object. + * If the underlying member is public, it is reflected as if by + * {@code getMethod}, {@code getConstructor}, or {@code getField}. + * Otherwise, it is reflected as if by + * {@code getDeclaredMethod}, {@code getDeclaredConstructor}, or {@code getDeclaredField}. + * The underlying member must be accessible to the given lookup object. + * @param the desired type of the result, either {@link Member} or a subtype + * @param expected a class object representing the desired result type {@code T} + * @param lookup the lookup object that created this MethodHandleInfo, or one with equivalent access privileges + * @return a reference to the method, constructor, or field object + * @exception ClassCastException if the member is not of the expected type + * @exception NullPointerException if either argument is {@code null} + * @exception IllegalArgumentException if the underlying member is not accessible to the given lookup object + */ + public T reflectAs(Class expected, Lookup lookup); - public int getReferenceKind() { - return referenceKind; - } + /** + * Returns the access modifiers of the underlying member. + * @return the Java language modifiers for underlying member, + * or -1 if the member cannot be accessed + * @see Modifier + * @see reflectAs + */ + public int getModifiers(); - static String getReferenceKindString(int referenceKind) { - switch (referenceKind) { - case REF_getField: return "getfield"; - case REF_getStatic: return "getstatic"; - case REF_putField: return "putfield"; - case REF_putStatic: return "putstatic"; - case REF_invokeVirtual: return "invokevirtual"; - case REF_invokeStatic: return "invokestatic"; - case REF_invokeSpecial: return "invokespecial"; - case REF_newInvokeSpecial: return "newinvokespecial"; - case REF_invokeInterface: return "invokeinterface"; - default: return "UNKNOWN_REFENCE_KIND" + "[" + referenceKind + "]"; - } + /** + * Determines if the underlying member was a variable arity method or constructor. + * Such members are represented by method handles that are varargs collectors. + * @implSpec + * This produces a result equivalent to: + *

    {@code
    +     *     getReferenceKind() >= REF_invokeVirtual && Modifier.isTransient(getModifiers())
    +     * }
    + * + * + * @return {@code true} if and only if the underlying member was declared with variable arity. + */ + // spelling derived from java.lang.reflect.Executable, not MethodHandle.isVarargsCollector + public default boolean isVarArgs() { + // fields are never varargs: + if (MethodHandleNatives.refKindIsField((byte) getReferenceKind())) + return false; + // not in the public API: Modifier.VARARGS + final int ACC_VARARGS = 0x00000080; // from JVMS 4.6 (Table 4.20) + assert(ACC_VARARGS == Modifier.TRANSIENT); + return Modifier.isTransient(getModifiers()); } - @Override - public String toString() { - return String.format("%s %s.%s:%s", getReferenceKindString(referenceKind), - declaringClass.getName(), name, methodType); + /** + * Returns the descriptive name of the given reference kind, + * as defined in the table above. + * The conventional prefix "REF_" is omitted. + * @param referenceKind an integer code for a kind of reference used to access a class member + * @return a mixed-case string such as {@code "getField"} + * @exception IllegalArgumentException if the argument is not a valid + * reference kind number + */ + public static String referenceKindToString(int referenceKind) { + if (!MethodHandleNatives.refKindIsValid(referenceKind)) + throw newIllegalArgumentException("invalid reference kind", referenceKind); + return MethodHandleNatives.refKindName((byte)referenceKind); + } + + /** + * Returns a string representation for a {@code MethodHandleInfo}, + * given the four parts of its symbolic reference. + * This is defined to be of the form {@code "RK C.N:MT"}, where {@code RK} is the + * {@linkplain #referenceKindToString reference kind string} for {@code kind}, + * {@code C} is the {@linkplain java.lang.Class#getName name} of {@code defc} + * {@code N} is the {@code name}, and + * {@code MT} is the {@code type}. + * These four values may be obtained from the + * {@linkplain #getReferenceKind reference kind}, + * {@linkplain #getDeclaringClass declaring class}, + * {@linkplain #getName member name}, + * and {@linkplain #getMethodType method type} + * of a {@code MethodHandleInfo} object. + * + * @implSpec + * This produces a result equivalent to: + *
    {@code
    +     *     String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type)
    +     * }
    + * + * @param kind the {@linkplain #getReferenceKind reference kind} part of the symbolic reference + * @param defc the {@linkplain #getDeclaringClass declaring class} part of the symbolic reference + * @param name the {@linkplain #getName member name} part of the symbolic reference + * @param type the {@linkplain #getMethodType method type} part of the symbolic reference + * @return a string of the form {@code "RK C.N:MT"} + * @exception IllegalArgumentException if the first argument is not a valid + * reference kind number + * @exception NullPointerException if any reference argument is {@code null} + */ + public static String toString(int kind, Class defc, String name, MethodType type) { + Objects.requireNonNull(name); Objects.requireNonNull(type); + return String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type); } } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java index 06e61a7dd8b..4f83e82158c 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -205,6 +205,9 @@ class MethodHandleNatives { static boolean refKindIsMethod(byte refKind) { return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial); } + static boolean refKindIsConstructor(byte refKind) { + return (refKind == REF_newInvokeSpecial); + } static boolean refKindHasReceiver(byte refKind) { assert(refKindIsValid(refKind)); return (refKind & 1) != 0; @@ -313,7 +316,65 @@ class MethodHandleNatives { * The method assumes the following arguments on the stack: * 0: the method handle being invoked * 1-N: the arguments to the method handle invocation - * N+1: an implicitly added type argument (the given MethodType) + * N+1: an optional, implicitly added argument (typically the given MethodType) + *

    + * The nominal method at such a call site is an instance of + * a signature-polymorphic method (see @PolymorphicSignature). + * Such method instances are user-visible entities which are + * "split" from the generic placeholder method in {@code MethodHandle}. + * (Note that the placeholder method is not identical with any of + * its instances. If invoked reflectively, is guaranteed to throw an + * {@code UnsupportedOperationException}.) + * If the signature-polymorphic method instance is ever reified, + * it appears as a "copy" of the original placeholder + * (a native final member of {@code MethodHandle}) except + * that its type descriptor has shape required by the instance, + * and the method instance is not varargs. + * The method instance is also marked synthetic, since the + * method (by definition) does not appear in Java source code. + *

    + * The JVM is allowed to reify this method as instance metadata. + * For example, {@code invokeBasic} is always reified. + * But the JVM may instead call {@code linkMethod}. + * If the result is an * ordered pair of a {@code (method, appendix)}, + * the method gets all the arguments (0..N inclusive) + * plus the appendix (N+1), and uses the appendix to complete the call. + * In this way, one reusable method (called a "linker method") + * can perform the function of any number of polymorphic instance + * methods. + *

    + * Linker methods are allowed to be weakly typed, with any or + * all references rewritten to {@code Object} and any primitives + * (except {@code long}/{@code float}/{@code double}) + * rewritten to {@code int}. + * A linker method is trusted to return a strongly typed result, + * according to the specific method type descriptor of the + * signature-polymorphic instance it is emulating. + * This can involve (as necessary) a dynamic check using + * data extracted from the appendix argument. + *

    + * The JVM does not inspect the appendix, other than to pass + * it verbatim to the linker method at every call. + * This means that the JDK runtime has wide latitude + * for choosing the shape of each linker method and its + * corresponding appendix. + * Linker methods should be generated from {@code LambdaForm}s + * so that they do not become visible on stack traces. + *

    + * The {@code linkMethod} call is free to omit the appendix + * (returning null) and instead emulate the required function + * completely in the linker method. + * As a corner case, if N==255, no appendix is possible. + * In this case, the method returned must be custom-generated to + * to perform any needed type checking. + *

    + * If the JVM does not reify a method at a call site, but instead + * calls {@code linkMethod}, the corresponding call represented + * in the bytecodes may mention a valid method which is not + * representable with a {@code MemberName}. + * Therefore, use cases for {@code linkMethod} tend to correspond to + * special cases in reflective code such as {@code findVirtual} + * or {@code revealDirect}. */ static MemberName linkMethod(Class callerClass, int refKind, Class defc, String name, Object type, diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index 78b01215636..f0f9447e001 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -26,8 +26,6 @@ package java.lang.invoke; import java.lang.reflect.*; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.List; import java.util.ArrayList; import java.util.Arrays; @@ -54,6 +52,7 @@ import sun.security.util.SecurityConstants; * *

    * @author John Rose, JSR 292 EG + * @since 1.7 */ public class MethodHandles { @@ -96,6 +95,38 @@ public class MethodHandles { return Lookup.PUBLIC_LOOKUP; } + /** + * Performs an unchecked "crack" of a direct method handle. + * The result is as if the user had obtained a lookup object capable enough + * to crack the target method handle, called + * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect} + * on the target to obtain its symbolic reference, and then called + * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs} + * to resolve the symbolic reference to a member. + *

    + * If there is a security manager, its {@code checkPermission} method + * is called with a {@code ReflectPermission("suppressAccessChecks")} permission. + * @param the desired type of the result, either {@link Member} or a subtype + * @param target a direct method handle to crack into symbolic reference components + * @param expected a class object representing the desired result type {@code T} + * @return a reference to the method, constructor, or field object + * @exception SecurityException if the caller is not privileged to call {@code setAccessible} + * @exception NullPointerException if either argument is {@code null} + * @exception IllegalArgumentException if the target is not a direct method handle + * @exception ClassCastException if the member is not of the expected type + * @since 1.8 + */ + public static T + reflectAs(Class expected, MethodHandle target) { + SecurityManager smgr = System.getSecurityManager(); + if (smgr != null) smgr.checkPermission(ACCESS_PERMISSION); + Lookup lookup = Lookup.IMPL_LOOKUP; // use maximally privileged lookup + return lookup.revealDirect(target).reflectAs(expected, lookup); + } + // Copied from AccessibleObject, as used by Method.setAccessible, etc.: + static final private java.security.Permission ACCESS_PERMISSION = + new ReflectPermission("suppressAccessChecks"); + /** * A lookup object is a factory for creating method handles, * when the creation requires access checking. @@ -647,6 +678,7 @@ public class MethodHandles { return invoker(type); if ("invokeExact".equals(name)) return exactInvoker(type); + assert(!MemberName.isMethodHandleInvokeName(name)); return null; } @@ -892,6 +924,10 @@ return mh1; * @throws NullPointerException if the argument is null */ public MethodHandle unreflect(Method m) throws IllegalAccessException { + if (m.getDeclaringClass() == MethodHandle.class) { + MethodHandle mh = unreflectForMH(m); + if (mh != null) return mh; + } MemberName method = new MemberName(m); byte refKind = method.getReferenceKind(); if (refKind == REF_invokeSpecial) @@ -900,6 +936,12 @@ return mh1; Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this; return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method)); } + private MethodHandle unreflectForMH(Method m) { + // these names require special lookups because they throw UnsupportedOperationException + if (MemberName.isMethodHandleInvokeName(m.getName())) + return MethodHandleImpl.fakeMethodHandleInvoke(new MemberName(m)); + return null; + } /** * Produces a method handle for a reflected method. @@ -1004,6 +1046,46 @@ return mh1; return unreflectField(f, true); } + /** + * Cracks a direct method handle created by this lookup object or a similar one. + * Security and access checks are performed to ensure that this lookup object + * is capable of reproducing the target method handle. + * This means that the cracking may fail if target is a direct method handle + * but was created by an unrelated lookup object. + * @param target a direct method handle to crack into symbolic reference components + * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object + * @exception SecurityException if a security manager is present and it + * refuses access + * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails + * @exception NullPointerException if the target is {@code null} + * @since 1.8 + */ + public MethodHandleInfo revealDirect(MethodHandle target) { + MemberName member = target.internalMemberName(); + if (member == null || (!member.isResolved() && !member.isMethodHandleInvoke())) + throw newIllegalArgumentException("not a direct method handle"); + Class defc = member.getDeclaringClass(); + byte refKind = member.getReferenceKind(); + assert(MethodHandleNatives.refKindIsValid(refKind)); + if (refKind == REF_invokeSpecial && !target.isInvokeSpecial()) + // Devirtualized method invocation is usually formally virtual. + // To avoid creating extra MemberName objects for this common case, + // we encode this extra degree of freedom using MH.isInvokeSpecial. + refKind = REF_invokeVirtual; + if (refKind == REF_invokeVirtual && defc.isInterface()) + // Symbolic reference is through interface but resolves to Object method (toString, etc.) + refKind = REF_invokeInterface; + // Check SM permissions and member access before cracking. + try { + checkSecurityManager(defc, member); + checkAccess(refKind, defc, member); + } catch (IllegalAccessException ex) { + throw new IllegalArgumentException(ex); + } + // Produce the handle to the results. + return new InfoFromMemberName(this, member, refKind); + } + /// Helper methods, all package-private. MemberName resolveOrFail(byte refKind, Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException { @@ -1201,12 +1283,12 @@ return mh1; private MethodHandle getDirectMethodCommon(byte refKind, Class refc, MemberName method, boolean doRestrict, Class callerClass) throws IllegalAccessException { checkMethod(refKind, refc, method); - if (method.isMethodHandleInvoke()) - return fakeMethodHandleInvoke(method); + assert(!method.isMethodHandleInvoke()); Class refcAsSuper; if (refKind == REF_invokeSpecial && refc != lookupClass() && + !refc.isInterface() && refc != (refcAsSuper = lookupClass().getSuperclass()) && refc.isAssignableFrom(lookupClass())) { assert(!method.getName().equals("")); // not this code path @@ -1234,9 +1316,6 @@ return mh1; mh = restrictReceiver(method, mh, lookupClass()); return mh; } - private MethodHandle fakeMethodHandleInvoke(MemberName method) { - return throwException(method.getReturnType(), UnsupportedOperationException.class); - } private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh, Class callerClass) throws IllegalAccessException { diff --git a/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java b/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java index a775fc43e34..9be96ff685b 100644 --- a/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java +++ b/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java @@ -225,7 +225,7 @@ public final class SerializedLambda implements Serializable { @Override public String toString() { - String implKind=MethodHandleInfo.getReferenceKindString(implMethodKind); + String implKind=MethodHandleInfo.referenceKindToString(implMethodKind); return String.format("SerializedLambda[%s=%s, %s=%s.%s:%s, " + "%s=%s %s.%s:%s, %s=%s, %s=%d]", "capturingClass", capturingClass, diff --git a/jdk/test/java/lang/invoke/7087570/Test7087570.java b/jdk/test/java/lang/invoke/7087570/Test7087570.java index 572faccdf5a..732467b8c62 100644 --- a/jdk/test/java/lang/invoke/7087570/Test7087570.java +++ b/jdk/test/java/lang/invoke/7087570/Test7087570.java @@ -35,20 +35,9 @@ import java.util.*; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; +import static java.lang.invoke.MethodHandleInfo.*; public class Test7087570 { - // XXX may remove the following constant declarations when MethodHandleInfo is made public - private static final int - REF_getField = 1, - REF_getStatic = 2, - REF_putField = 3, - REF_putStatic = 4, - REF_invokeVirtual = 5, - REF_invokeStatic = 6, - REF_invokeSpecial = 7, - REF_newInvokeSpecial = 8, - REF_invokeInterface = 9, - REF_LIMIT = 10; private static final TestMethodData[] TESTS = new TestMethodData[] { // field accessors @@ -87,17 +76,17 @@ public class Test7087570 { } private static void doTest(MethodHandle mh, TestMethodData testMethod) { - Object mhi = newMethodHandleInfo(mh); + MethodHandleInfo mhi = LOOKUP.revealDirect(mh); System.out.printf("%s.%s: %s, nominal refKind: %s, actual refKind: %s\n", testMethod.clazz.getName(), testMethod.name, testMethod.methodType, - REF_KIND_NAMES[testMethod.referenceKind], - REF_KIND_NAMES[getReferenceKind(mhi)]); - assertEquals(testMethod.name, getName(mhi)); - assertEquals(testMethod.methodType, getMethodType(mhi)); - assertEquals(testMethod.declaringClass, getDeclaringClass(mhi)); + referenceKindToString(testMethod.referenceKind), + referenceKindToString(mhi.getReferenceKind())); + assertEquals(testMethod.name, mhi.getName()); + assertEquals(testMethod.methodType, mhi.getMethodType()); + assertEquals(testMethod.declaringClass, mhi.getDeclaringClass()); assertEquals(testMethod.referenceKind == REF_invokeSpecial, isInvokeSpecial(mh)); - assertRefKindEquals(testMethod.referenceKind, getReferenceKind(mhi)); + assertRefKindEquals(testMethod.referenceKind, mhi.getReferenceKind()); } private static void testWithLookup() throws Throwable { @@ -122,50 +111,8 @@ public class Test7087570 { return methodType(void.class, clazz); } - private static final String[] REF_KIND_NAMES = { - "MH::invokeBasic", - "REF_getField", "REF_getStatic", "REF_putField", "REF_putStatic", - "REF_invokeVirtual", "REF_invokeStatic", "REF_invokeSpecial", - "REF_newInvokeSpecial", "REF_invokeInterface" - }; - private static final Lookup LOOKUP = lookup(); - // XXX may remove the following reflective logic when MethodHandleInfo is made public - private static final MethodHandle MH_IS_INVOKESPECIAL; - private static final MethodHandle MHI_CONSTRUCTOR; - private static final MethodHandle MHI_GET_NAME; - private static final MethodHandle MHI_GET_METHOD_TYPE; - private static final MethodHandle MHI_GET_DECLARING_CLASS; - private static final MethodHandle MHI_GET_REFERENCE_KIND; - - static { - try { - // This is white box testing. Use reflection to grab private implementation bits. - String magicName = "IMPL_LOOKUP"; - Field magicLookup = MethodHandles.Lookup.class.getDeclaredField(magicName); - // This unit test will fail if a security manager is installed. - magicLookup.setAccessible(true); - // Forbidden fruit... - Lookup directInvokeLookup = (Lookup) magicLookup.get(null); - Class mhiClass = Class.forName("java.lang.invoke.MethodHandleInfo", false, MethodHandle.class.getClassLoader()); - MH_IS_INVOKESPECIAL = directInvokeLookup - .findVirtual(MethodHandle.class, "isInvokeSpecial", methodType(boolean.class)); - MHI_CONSTRUCTOR = directInvokeLookup - .findConstructor(mhiClass, methodType(void.class, MethodHandle.class)); - MHI_GET_NAME = directInvokeLookup - .findVirtual(mhiClass, "getName", methodType(String.class)); - MHI_GET_METHOD_TYPE = directInvokeLookup - .findVirtual(mhiClass, "getMethodType", methodType(MethodType.class)); - MHI_GET_DECLARING_CLASS = directInvokeLookup - .findVirtual(mhiClass, "getDeclaringClass", methodType(Class.class)); - MHI_GET_REFERENCE_KIND = directInvokeLookup - .findVirtual(mhiClass, "getReferenceKind", methodType(int.class)); - } catch (ReflectiveOperationException ex) { - throw new Error(ex); - } - } - private static class TestMethodData { final Class clazz; final String name; @@ -208,7 +155,9 @@ public class Test7087570 { return LOOKUP.findStatic(testMethod.clazz, testMethod.name, testMethod.methodType); case REF_invokeSpecial: Class thisClass = LOOKUP.lookupClass(); - return LOOKUP.findSpecial(testMethod.clazz, testMethod.name, testMethod.methodType, thisClass); + MethodHandle smh = LOOKUP.findSpecial(testMethod.clazz, testMethod.name, testMethod.methodType, thisClass); + noteInvokeSpecial(smh); + return smh; case REF_newInvokeSpecial: return LOOKUP.findConstructor(testMethod.clazz, testMethod.methodType); default: @@ -238,7 +187,9 @@ public class Test7087570 { case REF_invokeSpecial: { Method m = testMethod.clazz.getDeclaredMethod(testMethod.name, testMethod.methodType.parameterArray()); Class thisClass = LOOKUP.lookupClass(); - return LOOKUP.unreflectSpecial(m, thisClass); + MethodHandle smh = LOOKUP.unreflectSpecial(m, thisClass); + noteInvokeSpecial(smh); + return smh; } case REF_newInvokeSpecial: { Constructor c = testMethod.clazz.getDeclaredConstructor(testMethod.methodType.parameterArray()); @@ -249,59 +200,20 @@ public class Test7087570 { } } - private static Object newMethodHandleInfo(MethodHandle mh) { - try { - return MHI_CONSTRUCTOR.invoke(mh); - } catch (Throwable ex) { - throw new Error(ex); - } + private static List specialMethodHandles = new ArrayList<>(); + private static void noteInvokeSpecial(MethodHandle mh) { + specialMethodHandles.add(mh); + assert(isInvokeSpecial(mh)); } - private static boolean isInvokeSpecial(MethodHandle mh) { - try { - return (boolean) MH_IS_INVOKESPECIAL.invokeExact(mh); - } catch (Throwable ex) { - throw new Error(ex); - } - } - - private static String getName(Object mhi) { - try { - return (String) MHI_GET_NAME.invoke(mhi); - } catch (Throwable ex) { - throw new Error(ex); - } - } - - private static MethodType getMethodType(Object mhi) { - try { - return (MethodType) MHI_GET_METHOD_TYPE.invoke(mhi); - } catch (Throwable ex) { - throw new Error(ex); - } - } - - private static Class getDeclaringClass(Object mhi) { - try { - return (Class) MHI_GET_DECLARING_CLASS.invoke(mhi); - } catch (Throwable ex) { - throw new Error(ex); - } - } - - private static int getReferenceKind(Object mhi) { - try { - return (int) MHI_GET_REFERENCE_KIND.invoke(mhi); - } catch (Throwable ex) { - throw new Error(ex); - } + return specialMethodHandles.contains(mh); } private static void assertRefKindEquals(int expect, int observed) { if (expect == observed) return; - String msg = "expected " + REF_KIND_NAMES[(int) expect] + - " but observed " + REF_KIND_NAMES[(int) observed]; + String msg = "expected " + referenceKindToString(expect) + + " but observed " + referenceKindToString(observed); System.out.println("FAILED: " + msg); throw new AssertionError(msg); } diff --git a/jdk/test/java/lang/invoke/RevealDirectTest.java b/jdk/test/java/lang/invoke/RevealDirectTest.java new file mode 100644 index 00000000000..f05b19077c1 --- /dev/null +++ b/jdk/test/java/lang/invoke/RevealDirectTest.java @@ -0,0 +1,753 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @summary verify Lookup.revealDirect on a variety of input handles + * @compile -XDignore.symbol.file RevealDirectTest.java + * @run junit/othervm -ea -esa test.java.lang.invoke.RevealDirectTest + * + * @test + * @summary verify Lookup.revealDirect on a variety of input handles, with security manager + * @run main/othervm/policy=jtreg.security.policy/secure=java.lang.SecurityManager -ea -esa test.java.lang.invoke.RevealDirectTest + */ + +/* To run manually: + * $ $JAVA8X_HOME/bin/javac -cp $JUNIT4_JAR -d ../../../.. -XDignore.symbol.file RevealDirectTest.java + * $ $JAVA8X_HOME/bin/java -cp $JUNIT4_JAR:../../../.. -ea -esa org.junit.runner.JUnitCore test.java.lang.invoke.RevealDirectTest + * $ $JAVA8X_HOME/bin/java -cp $JUNIT4_JAR:../../../.. -ea -esa -Djava.security.manager test.java.lang.invoke.RevealDirectTest + */ + +package test.java.lang.invoke; + +import java.lang.reflect.*; +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; +import static java.lang.invoke.MethodHandleInfo.*; +import java.util.*; +import static org.junit.Assert.*; +import org.junit.*; + +public class RevealDirectTest { + public static void main(String... av) throws Throwable { + // Run the @Test methods explicitly, in case we don't want to use the JUnitCore driver. + // This appears to be necessary when running with a security manager. + Throwable fail = null; + for (Method test : RevealDirectTest.class.getDeclaredMethods()) { + if (!test.isAnnotationPresent(Test.class)) continue; + try { + test.invoke(new RevealDirectTest()); + } catch (Throwable ex) { + if (ex instanceof InvocationTargetException) + ex = ex.getCause(); + if (fail == null) fail = ex; + System.out.println("Testcase: "+test.getName() + +"("+test.getDeclaringClass().getName() + +"):\tCaused an ERROR"); + System.out.println(ex); + ex.printStackTrace(System.out); + } + } + if (fail != null) throw fail; + } + + public interface SimpleSuperInterface { + public abstract int getInt(); + public static void printAll(String... args) { + System.out.println(Arrays.toString(args)); + } + public int NICE_CONSTANT = 42; + } + public interface SimpleInterface extends SimpleSuperInterface { + default float getFloat() { return getInt(); } + public static void printAll(String[] args) { + System.out.println(Arrays.toString(args)); + } + } + public static class Simple implements SimpleInterface, Cloneable { + public int intField; + public final int finalField; + private static String stringField; + public int getInt() { return NICE_CONSTANT; } + private static Number getNum() { return 804; } + public Simple clone() { + try { + return (Simple) super.clone(); + } catch (CloneNotSupportedException ex) { + throw new RuntimeException(ex); + } + } + Simple() { finalField = -NICE_CONSTANT; } + private static Lookup localLookup() { return lookup(); } + private static List members() { return getMembers(lookup().lookupClass()); }; + } + + static boolean VERBOSE = false; + + @Test public void testSimple() throws Throwable { + if (VERBOSE) System.out.println("@Test testSimple"); + testOnMembers("testSimple", Simple.members(), Simple.localLookup()); + } + @Test public void testPublicLookup() throws Throwable { + if (VERBOSE) System.out.println("@Test testPublicLookup"); + List mems = publicOnly(Simple.members()); + Lookup pubLookup = publicLookup(), privLookup = Simple.localLookup(); + testOnMembers("testPublicLookup/1", mems, pubLookup); + // reveal using publicLookup: + testOnMembers("testPublicLookup/2", mems, privLookup, pubLookup); + // lookup using publicLookup, but reveal using private: + testOnMembers("testPublicLookup/3", mems, pubLookup, privLookup); + } + @Test public void testPublicLookupNegative() throws Throwable { + if (VERBOSE) System.out.println("@Test testPublicLookupNegative"); + List mems = nonPublicOnly(Simple.members()); + Lookup pubLookup = publicLookup(), privLookup = Simple.localLookup(); + testOnMembersNoLookup("testPublicLookupNegative/1", mems, pubLookup); + testOnMembersNoReveal("testPublicLookupNegative/2", mems, privLookup, pubLookup); + testOnMembersNoReflect("testPublicLookupNegative/3", mems, privLookup, pubLookup); + } + @Test public void testJavaLangClass() throws Throwable { + if (VERBOSE) System.out.println("@Test testJavaLangClass"); + List mems = callerSensitive(false, publicOnly(getMembers(Class.class))); + mems = limit(20, mems); + testOnMembers("testJavaLangClass", mems, Simple.localLookup()); + } + @Test public void testCallerSensitive() throws Throwable { + if (VERBOSE) System.out.println("@Test testCallerSensitive"); + List mems = union(getMembers(MethodHandles.class, "lookup"), + getMembers(Method.class, "invoke"), + getMembers(Field.class, "get", "set", "getLong"), + getMembers(Class.class)); + mems = callerSensitive(true, publicOnly(mems)); + mems = limit(10, mems); + testOnMembers("testCallerSensitive", mems, Simple.localLookup()); + } + @Test public void testCallerSensitiveNegative() throws Throwable { + if (VERBOSE) System.out.println("@Test testCallerSensitiveNegative"); + List mems = union(getMembers(MethodHandles.class, "lookup"), + getMembers(Class.class, "forName"), + getMembers(Method.class, "invoke")); + mems = callerSensitive(true, publicOnly(mems)); + // CS methods cannot be looked up with publicLookup + testOnMembersNoLookup("testCallerSensitiveNegative", mems, publicLookup()); + } + @Test public void testMethodHandleNatives() throws Throwable { + if (VERBOSE) System.out.println("@Test testMethodHandleNatives"); + List mems = getMembers(MethodHandle.class, "invoke", "invokeExact"); + testOnMembers("testMethodHandleNatives", mems, Simple.localLookup()); + } + @Test public void testMethodHandleInvokes() throws Throwable { + if (VERBOSE) System.out.println("@Test testMethodHandleInvokes"); + List types = new ArrayList<>(); + Class[] someParamTypes = { void.class, int.class, Object.class, Object[].class }; + for (Class rt : someParamTypes) { + for (Class p0 : someParamTypes) { + if (p0 == void.class) { types.add(methodType(rt)); continue; } + for (Class p1 : someParamTypes) { + if (p1 == void.class) { types.add(methodType(rt, p0)); continue; } + for (Class p2 : someParamTypes) { + if (p2 == void.class) { types.add(methodType(rt, p0, p1)); continue; } + types.add(methodType(rt, p0, p1, p2)); + } + } + } + } + List mems = union(getPolyMembers(MethodHandle.class, "invoke", types), + getPolyMembers(MethodHandle.class, "invokeExact", types)); + testOnMembers("testMethodHandleInvokes/1", mems, Simple.localLookup()); + testOnMembers("testMethodHandleInvokes/2", mems, publicLookup()); + } + + static List getPolyMembers(Class cls, String name, List types) { + assert(cls == MethodHandle.class); + ArrayList mems = new ArrayList<>(); + for (MethodType type : types) { + mems.add(new SignaturePolymorphicMethod(name, type)); + } + return mems; + } + static List getMembers(Class cls) { + return getMembers(cls, (String[]) null); + } + static List getMembers(Class cls, String... onlyNames) { + List names = (onlyNames == null || onlyNames.length == 0 ? null : Arrays.asList(onlyNames)); + ArrayList res = new ArrayList<>(); + for (Class sup : getSupers(cls)) { + res.addAll(getDeclaredMembers(sup, "getDeclaredFields")); + res.addAll(getDeclaredMembers(sup, "getDeclaredMethods")); + res.addAll(getDeclaredMembers(sup, "getDeclaredConstructors")); + } + res = new ArrayList<>(new LinkedHashSet<>(res)); + for (int i = 0; i < res.size(); i++) { + Member mem = res.get(i); + if (!canBeReached(mem, cls) || + res.indexOf(mem) != i || + mem.isSynthetic() || + (names != null && !names.contains(mem.getName())) + ) { + res.remove(i--); + } + } + return res; + } + static List> getSupers(Class cls) { + ArrayList> res = new ArrayList<>(); + ArrayList> intfs = new ArrayList<>(); + for (Class sup = cls; sup != null; sup = sup.getSuperclass()) { + res.add(sup); + for (Class intf : cls.getInterfaces()) { + if (!intfs.contains(intf)) + intfs.add(intf); + } + } + for (int i = 0; i < intfs.size(); i++) { + for (Class intf : intfs.get(i).getInterfaces()) { + if (!intfs.contains(intf)) + intfs.add(intf); + } + } + res.addAll(intfs); + //System.out.println("getSupers => "+res); + return res; + } + static boolean hasSM() { + return (System.getSecurityManager() != null); + } + static List getDeclaredMembers(Class cls, String accessor) { + Member[] mems = {}; + Method getter = getMethod(Class.class, accessor); + if (hasSM()) { + try { + mems = (Member[]) invokeMethod(getter, cls); + } catch (SecurityException ex) { + //if (VERBOSE) ex.printStackTrace(); + accessor = accessor.replace("Declared", ""); + getter = getMethod(Class.class, accessor); + if (VERBOSE) System.out.println("replaced accessor: "+getter); + } + } + if (mems.length == 0) { + try { + mems = (Member[]) invokeMethod(getter, cls); + } catch (SecurityException ex) { + ex.printStackTrace(); + } + } + if (VERBOSE) System.out.println(accessor+" "+cls.getName()+" => "+mems.length+" members"); + return Arrays.asList(mems); + } + static Method getMethod(Class cls, String name) { + try { + return cls.getMethod(name); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + static Object invokeMethod(Method m, Object recv, Object... args) { + try { + return m.invoke(recv, args); + } catch (InvocationTargetException ex) { + Throwable ex2 = ex.getCause(); + if (ex2 instanceof RuntimeException) throw (RuntimeException) ex2; + if (ex2 instanceof Error) throw (Error) ex2; + throw new AssertionError(ex); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static List limit(int len, List mems) { + if (mems.size() <= len) return mems; + return mems.subList(0, len); + } + @SafeVarargs + static List union(List mems, List... mem2s) { + for (List mem2 : mem2s) { + for (Member m : mem2) { + if (!mems.contains(m)) + mems.add(m); + } + } + return mems; + } + static List callerSensitive(boolean cond, List members) { + for (Iterator i = members.iterator(); i.hasNext(); ) { + Member mem = i.next(); + if (isCallerSensitive(mem) != cond) + i.remove(); + } + if (members.isEmpty()) throw new AssertionError("trivial result"); + return members; + } + static boolean isCallerSensitive(Member mem) { + if (!(mem instanceof AnnotatedElement)) return false; + AnnotatedElement ae = (AnnotatedElement) mem; + if (CS_CLASS != null) + return ae.isAnnotationPresent(sun.reflect.CallerSensitive.class); + for (java.lang.annotation.Annotation a : ae.getDeclaredAnnotations()) { + if (a.toString().contains(".CallerSensitive")) + return true; + } + return false; + } + static final Class CS_CLASS; + static { + Class c = null; + try { + c = sun.reflect.CallerSensitive.class; + } catch (SecurityException | LinkageError ex) { + } + CS_CLASS = c; + } + static List publicOnly(List members) { + return removeMods(members, Modifier.PUBLIC, 0); + } + static List nonPublicOnly(List members) { + return removeMods(members, Modifier.PUBLIC, -1); + } + static List removeMods(List members, int mask, int bits) { + int publicMods = (mask & Modifier.PUBLIC); + members = new ArrayList<>(members); + for (Iterator i = members.iterator(); i.hasNext(); ) { + Member mem = i.next(); + int mods = mem.getModifiers(); + if ((publicMods & mods) != 0 && + (publicMods & mem.getDeclaringClass().getModifiers()) == 0) + mods -= publicMods; + if ((mods & mask) == (bits & mask)) + i.remove(); + } + return members; + } + + void testOnMembers(String tname, List mems, Lookup lookup, Lookup... lookups) throws Throwable { + if (VERBOSE) System.out.println("testOnMembers "+mems); + Lookup revLookup = (lookups.length > 0) ? lookups[0] : null; + if (revLookup == null) revLookup = lookup; + Lookup refLookup = (lookups.length > 1) ? lookups[1] : null; + if (refLookup == null) refLookup = lookup; + assert(lookups.length <= 2); + testOnMembersImpl(tname, mems, lookup, revLookup, refLookup, NO_FAIL); + } + void testOnMembersNoLookup(String tname, List mems, Lookup lookup) throws Throwable { + if (VERBOSE) System.out.println("testOnMembersNoLookup "+mems); + testOnMembersImpl(tname, mems, lookup, null, null, FAIL_LOOKUP); + } + void testOnMembersNoReveal(String tname, List mems, + Lookup lookup, Lookup negLookup) throws Throwable { + if (VERBOSE) System.out.println("testOnMembersNoReveal "+mems); + testOnMembersImpl(tname, mems, lookup, negLookup, null, FAIL_REVEAL); + } + void testOnMembersNoReflect(String tname, List mems, + Lookup lookup, Lookup negLookup) throws Throwable { + if (VERBOSE) System.out.println("testOnMembersNoReflect "+mems); + testOnMembersImpl(tname, mems, lookup, lookup, negLookup, FAIL_REFLECT); + } + void testOnMembersImpl(String tname, List mems, + Lookup lookup, + Lookup revLookup, + Lookup refLookup, + int failureMode) throws Throwable { + Throwable fail = null; + int failCount = 0; + failureModeCounts = new int[FAIL_MODE_COUNT]; + long tm0 = System.currentTimeMillis(); + for (Member mem : mems) { + try { + testWithMember(mem, lookup, revLookup, refLookup, failureMode); + } catch (Throwable ex) { + if (fail == null) fail = ex; + if (++failCount > 10) { System.out.println("*** FAIL: too many failures"); break; } + System.out.println("*** FAIL: "+mem+" => "+ex); + if (VERBOSE) ex.printStackTrace(System.out); + } + } + long tm1 = System.currentTimeMillis(); + System.out.printf("@Test %s executed %s tests in %d ms", + tname, testKinds(failureModeCounts), (tm1-tm0)).println(); + if (fail != null) throw fail; + } + static String testKinds(int[] modes) { + int pos = modes[0], neg = -pos; + for (int n : modes) neg += n; + if (neg == 0) return pos + " positive"; + String negs = ""; + for (int n : modes) negs += "/"+n; + negs = negs.replaceFirst("/"+pos+"/", ""); + negs += " negative"; + if (pos == 0) return negs; + return pos + " positive, " + negs; + } + static class SignaturePolymorphicMethod implements Member { // non-reflected instance of MH.invoke* + final String name; + final MethodType type; + SignaturePolymorphicMethod(String name, MethodType type) { + this.name = name; + this.type = type; + } + public String toString() { + String typeStr = type.toString(); + if (isVarArgs()) typeStr = typeStr.replaceFirst("\\[\\])$", "...)"); + return (Modifier.toString(getModifiers()) + +typeStr.substring(0, typeStr.indexOf('('))+" " + +getDeclaringClass().getTypeName()+"." + +getName()+typeStr.substring(typeStr.indexOf('('))); + } + public boolean equals(Object x) { + return (x instanceof SignaturePolymorphicMethod && equals((SignaturePolymorphicMethod)x)); + } + public boolean equals(SignaturePolymorphicMethod that) { + return this.name.equals(that.name) && this.type.equals(that.type); + } + public int hashCode() { + return name.hashCode() * 31 + type.hashCode(); + } + public Class getDeclaringClass() { return MethodHandle.class; } + public String getName() { return name; } + public MethodType getMethodType() { return type; } + public int getModifiers() { return Modifier.PUBLIC | Modifier.FINAL | Modifier.NATIVE | SYNTHETIC; } + public boolean isVarArgs() { return Modifier.isTransient(getModifiers()); } + public boolean isSynthetic() { return true; } + public Class getReturnType() { return type.returnType(); } + public Class[] getParameterTypes() { return type.parameterArray(); } + static final int SYNTHETIC = 0x00001000; + } + static class UnreflectResult { // a tuple + final MethodHandle mh; + final Throwable ex; + final byte kind; + final Member mem; + final int var; + UnreflectResult(MethodHandle mh, byte kind, Member mem, int var) { + this.mh = mh; + this.ex = null; + this.kind = kind; + this.mem = mem; + this.var = var; + } + UnreflectResult(Throwable ex, byte kind, Member mem, int var) { + this.mh = null; + this.ex = ex; + this.kind = kind; + this.mem = mem; + this.var = var; + } + public String toString() { + return toInfoString()+"/v"+var; + } + public String toInfoString() { + return String.format("%s %s.%s:%s", MethodHandleInfo.referenceKindToString(kind), + mem.getDeclaringClass().getName(), name(mem), type(mem, kind)); + } + static String name(Member mem) { + if (mem instanceof Constructor) return ""; + return mem.getName(); + } + static MethodType type(Member mem, byte kind) { + if (mem instanceof Field) { + Class type = ((Field)mem).getType(); + if (kind == REF_putStatic || kind == REF_putField) + return methodType(void.class, type); + return methodType(type); + } else if (mem instanceof SignaturePolymorphicMethod) { + return ((SignaturePolymorphicMethod)mem).getMethodType(); + } + Class[] params = ((Executable)mem).getParameterTypes(); + if (mem instanceof Constructor) + return methodType(void.class, params); + Class type = ((Method)mem).getReturnType(); + return methodType(type, params); + } + } + static UnreflectResult unreflectMember(Lookup lookup, Member mem, int variation) { + byte[] refKind = {0}; + try { + return unreflectMemberOrThrow(lookup, mem, variation, refKind); + } catch (ReflectiveOperationException|SecurityException ex) { + return new UnreflectResult(ex, refKind[0], mem, variation); + } + } + static UnreflectResult unreflectMemberOrThrow(Lookup lookup, Member mem, int variation, + byte[] refKind) throws ReflectiveOperationException { + Class cls = lookup.lookupClass(); + Class defc = mem.getDeclaringClass(); + String name = mem.getName(); + int mods = mem.getModifiers(); + boolean isStatic = Modifier.isStatic(mods); + MethodHandle mh = null; + byte kind = 0; + if (mem instanceof Method) { + Method m = (Method) mem; + MethodType type = methodType(m.getReturnType(), m.getParameterTypes()); + boolean canBeSpecial = (!isStatic && + (lookup.lookupModes() & Modifier.PRIVATE) != 0 && + defc.isAssignableFrom(cls) && + (!defc.isInterface() || Arrays.asList(cls.getInterfaces()).contains(defc))); + if (variation >= 2) + kind = REF_invokeSpecial; + else if (isStatic) + kind = REF_invokeStatic; + else if (defc.isInterface()) + kind = REF_invokeInterface; + else + kind = REF_invokeVirtual; + refKind[0] = kind; + switch (variation) { + case 0: + mh = lookup.unreflect(m); + break; + case 1: + if (defc == MethodHandle.class && + !isStatic && + m.isVarArgs() && + Modifier.isFinal(mods) && + Modifier.isNative(mods)) { + break; + } + if (isStatic) + mh = lookup.findStatic(defc, name, type); + else + mh = lookup.findVirtual(defc, name, type); + break; + case 2: + if (!canBeSpecial) + break; + mh = lookup.unreflectSpecial(m, lookup.lookupClass()); + break; + case 3: + if (!canBeSpecial) + break; + mh = lookup.findSpecial(defc, name, type, lookup.lookupClass()); + break; + } + } else if (mem instanceof SignaturePolymorphicMethod) { + SignaturePolymorphicMethod m = (SignaturePolymorphicMethod) mem; + MethodType type = methodType(m.getReturnType(), m.getParameterTypes()); + kind = REF_invokeVirtual; + refKind[0] = kind; + switch (variation) { + case 0: + mh = lookup.findVirtual(defc, name, type); + break; + } + } else if (mem instanceof Constructor) { + name = ""; // not used + Constructor m = (Constructor) mem; + MethodType type = methodType(void.class, m.getParameterTypes()); + kind = REF_newInvokeSpecial; + refKind[0] = kind; + switch (variation) { + case 0: + mh = lookup.unreflectConstructor(m); + break; + case 1: + mh = lookup.findConstructor(defc, type); + break; + } + } else if (mem instanceof Field) { + Field m = (Field) mem; + Class type = m.getType(); + boolean canHaveSetter = !Modifier.isFinal(mods); + if (variation >= 2) + kind = (byte)(isStatic ? REF_putStatic : REF_putField); + else + kind = (byte)(isStatic ? REF_getStatic : REF_getField); + refKind[0] = kind; + switch (variation) { + case 0: + mh = lookup.unreflectGetter(m); + break; + case 1: + if (isStatic) + mh = lookup.findStaticGetter(defc, name, type); + else + mh = lookup.findGetter(defc, name, type); + break; + case 3: + if (!canHaveSetter) + break; + mh = lookup.unreflectSetter(m); + break; + case 2: + if (!canHaveSetter) + break; + if (isStatic) + mh = lookup.findStaticSetter(defc, name, type); + else + mh = lookup.findSetter(defc, name, type); + break; + } + } else { + throw new IllegalArgumentException(String.valueOf(mem)); + } + if (mh == null) + // ran out of valid variations; return null to caller + return null; + return new UnreflectResult(mh, kind, mem, variation); + } + static boolean canBeReached(Member mem, Class cls) { + Class defc = mem.getDeclaringClass(); + String name = mem.getName(); + int mods = mem.getModifiers(); + if (mem instanceof Constructor) { + name = ""; // according to 292 spec. + } + if (defc == cls) + return true; + if (name.startsWith("<")) + return false; // only my own constructors + if (Modifier.isPrivate(mods)) + return false; // only my own constructors + if (defc.getPackage() == cls.getPackage()) + return true; // package access or greater OK + if (Modifier.isPublic(mods)) + return true; // publics always OK + if (Modifier.isProtected(mods) && defc.isAssignableFrom(cls)) + return true; // protected OK + return false; + } + static boolean consistent(UnreflectResult res, MethodHandleInfo info) { + assert(res.mh != null); + assertEquals(res.kind, info.getReferenceKind()); + assertEquals(res.mem.getModifiers(), info.getModifiers()); + assertEquals(res.mem.getDeclaringClass(), info.getDeclaringClass()); + String expectName = res.mem.getName(); + if (res.kind == REF_newInvokeSpecial) + expectName = ""; + assertEquals(expectName, info.getName()); + MethodType expectType = res.mh.type(); + if ((res.kind & 1) == (REF_getField & 1)) + expectType = expectType.dropParameterTypes(0, 1); + if (res.kind == REF_newInvokeSpecial) + expectType = expectType.changeReturnType(void.class); + assertEquals(expectType, info.getMethodType()); + assertEquals(res.mh.isVarargsCollector(), isVarArgs(info)); + assertEquals(res.toInfoString(), info.toString()); + assertEquals(res.toInfoString(), MethodHandleInfo.toString(info.getReferenceKind(), info.getDeclaringClass(), info.getName(), info.getMethodType())); + return true; + } + static boolean isVarArgs(MethodHandleInfo info) { + return info.isVarArgs(); + } + static boolean consistent(Member mem, Member mem2) { + assertEquals(mem, mem2); + return true; + } + static boolean consistent(MethodHandleInfo info, MethodHandleInfo info2) { + assertEquals(info.getReferenceKind(), info2.getReferenceKind()); + assertEquals(info.getModifiers(), info2.getModifiers()); + assertEquals(info.getDeclaringClass(), info2.getDeclaringClass()); + assertEquals(info.getName(), info2.getName()); + assertEquals(info.getMethodType(), info2.getMethodType()); + assertEquals(isVarArgs(info), isVarArgs(info)); + return true; + } + static boolean consistent(MethodHandle mh, MethodHandle mh2) { + assertEquals(mh.type(), mh2.type()); + assertEquals(mh.isVarargsCollector(), mh2.isVarargsCollector()); + return true; + } + int[] failureModeCounts; + static final int NO_FAIL=0, FAIL_LOOKUP=1, FAIL_REVEAL=2, FAIL_REFLECT=3, FAIL_MODE_COUNT=4; + void testWithMember(Member mem, + Lookup lookup, // initial lookup of member => MH + Lookup revLookup, // reveal MH => info + Lookup refLookup, // reflect info => member + int failureMode) throws Throwable { + boolean expectEx1 = (failureMode == FAIL_LOOKUP); // testOnMembersNoLookup + boolean expectEx2 = (failureMode == FAIL_REVEAL); // testOnMembersNoReveal + boolean expectEx3 = (failureMode == FAIL_REFLECT); // testOnMembersNoReflect + for (int variation = 0; ; variation++) { + UnreflectResult res = unreflectMember(lookup, mem, variation); + failureModeCounts[failureMode] += 1; + if (variation == 0) assert(res != null); + if (res == null) break; + if (VERBOSE && variation == 0) + System.out.println("from "+mem.getDeclaringClass().getSimpleName()); + MethodHandle mh = res.mh; + Throwable ex1 = res.ex; + if (VERBOSE) System.out.println(" "+variation+": "+res+" << "+(mh != null ? mh : ex1)); + if (expectEx1 && ex1 != null) + continue; // this is OK; we expected that lookup to fail + if (expectEx1) + throw new AssertionError("unexpected lookup for negative test"); + if (ex1 != null && !expectEx1) { + if (failureMode != NO_FAIL) + throw new AssertionError("unexpected lookup failure for negative test", ex1); + throw ex1; + } + MethodHandleInfo info; + try { + info = revLookup.revealDirect(mh); + if (expectEx2) throw new AssertionError("unexpected revelation for negative test"); + } catch (Throwable ex2) { + if (VERBOSE) System.out.println(" "+variation+": "+res+" => "+mh.getClass().getName()+" => (EX2)"+ex2); + if (expectEx2) + continue; // this is OK; we expected the reflect to fail + if (failureMode != NO_FAIL) + throw new AssertionError("unexpected revelation failure for negative test", ex2); + throw ex2; + } + assert(consistent(res, info)); + Member mem2; + try { + mem2 = info.reflectAs(Member.class, refLookup); + if (expectEx3) throw new AssertionError("unexpected reflection for negative test"); + assert(!(mem instanceof SignaturePolymorphicMethod)); + } catch (IllegalArgumentException ex3) { + if (VERBOSE) System.out.println(" "+variation+": "+info+" => (EX3)"+ex3); + if (expectEx3) + continue; // this is OK; we expected the reflect to fail + if (mem instanceof SignaturePolymorphicMethod) + continue; // this is OK; we cannot reflect MH.invokeExact(a,b,c) + if (failureMode != NO_FAIL) + throw new AssertionError("unexpected reflection failure for negative test", ex3); + throw ex3; + } + assert(consistent(mem, mem2)); + UnreflectResult res2 = unreflectMember(lookup, mem2, variation); + MethodHandle mh2 = res2.mh; + assert(consistent(mh, mh2)); + MethodHandleInfo info2 = lookup.revealDirect(mh2); + assert(consistent(info, info2)); + assert(consistent(res, info2)); + Member mem3; + if (hasSM()) + mem3 = info2.reflectAs(Member.class, lookup); + else + mem3 = MethodHandles.reflectAs(Member.class, mh2); + assert(consistent(mem2, mem3)); + if (hasSM()) { + try { + MethodHandles.reflectAs(Member.class, mh2); + throw new AssertionError("failed to throw on "+mem3); + } catch (SecurityException ex3) { + // OK... + } + } + } + } +} diff --git a/jdk/test/java/lang/invoke/jtreg.security.policy b/jdk/test/java/lang/invoke/jtreg.security.policy new file mode 100644 index 00000000000..d32c7af9b3f --- /dev/null +++ b/jdk/test/java/lang/invoke/jtreg.security.policy @@ -0,0 +1,9 @@ +/* + * security policy used by the test process + * must allow file reads so that jtreg itself can run + */ + +grant { + // standard test activation permissions + permission java.io.FilePermission "*", "read"; +}; From 1f2ba9f2286e0de55a160f5d15a9db64e7024f06 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Mon, 12 Aug 2013 12:22:10 +0200 Subject: [PATCH 0078/1294] 8024182: test/java/util/Arrays/SetAllTest.java fails to compile due to recent compiler changes Use explicit lambda due to javac simplfying rules for overload resolution with implicit lambdas Reviewed-by: alanb, mduigou --- jdk/test/java/util/Arrays/SetAllTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/test/java/util/Arrays/SetAllTest.java b/jdk/test/java/util/Arrays/SetAllTest.java index 2388a7bfd55..528d3c57b54 100644 --- a/jdk/test/java/util/Arrays/SetAllTest.java +++ b/jdk/test/java/util/Arrays/SetAllTest.java @@ -167,13 +167,13 @@ public class SetAllTest { public void testStringSetNulls() { String[] ar = new String[2]; try { - Arrays.setAll(null, i -> "X"); + Arrays.setAll(null, (IntFunction) i -> "X"); fail("Arrays.setAll(null, foo) should throw NPE"); } catch (NullPointerException npe) { // expected } try { - Arrays.parallelSetAll(null, i -> "X"); + Arrays.parallelSetAll(null, (IntFunction) i -> "X"); fail("Arrays.parallelSetAll(null, foo) should throw NPE"); } catch (NullPointerException npe) { // expected From 30f059b5fce32e14fc0cb890b8a950be5e582356 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Mon, 12 Aug 2013 17:37:02 +0200 Subject: [PATCH 0079/1294] 8015107: NPG: Use consistent naming for metaspace concepts Reviewed-by: coleenp, mgerdin, hseigel --- .../classes/sun/jvm/hotspot/runtime/VM.java | 2 +- .../sun/jvm/hotspot/tools/HeapSummary.java | 24 ++++----- .../cpu/sparc/vm/c1_LIRAssembler_sparc.cpp | 8 +-- .../cpu/sparc/vm/c1_MacroAssembler_sparc.cpp | 4 +- .../src/cpu/sparc/vm/macroAssembler_sparc.cpp | 18 +++---- hotspot/src/cpu/sparc/vm/sparc.ad | 8 +-- .../src/cpu/sparc/vm/stubGenerator_sparc.cpp | 6 +-- .../src/cpu/sparc/vm/vtableStubs_sparc.cpp | 4 +- hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp | 2 +- .../src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 20 ++++---- .../src/cpu/x86/vm/c1_LIRGenerator_x86.cpp | 4 +- .../src/cpu/x86/vm/c1_MacroAssembler_x86.cpp | 8 +-- hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp | 24 ++++----- hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp | 4 +- hotspot/src/cpu/x86/vm/x86_64.ad | 6 +-- .../concurrentMarkSweepGeneration.cpp | 4 +- hotspot/src/share/vm/memory/metaspace.cpp | 32 ++++++------ hotspot/src/share/vm/memory/metaspace.hpp | 4 +- .../src/share/vm/memory/metaspaceCounters.cpp | 4 +- hotspot/src/share/vm/memory/universe.cpp | 2 +- hotspot/src/share/vm/memory/universe.hpp | 6 +-- hotspot/src/share/vm/oops/arrayOop.hpp | 2 +- hotspot/src/share/vm/oops/instanceOop.hpp | 4 +- hotspot/src/share/vm/oops/oop.inline.hpp | 18 +++---- hotspot/src/share/vm/opto/cfgnode.cpp | 2 +- hotspot/src/share/vm/opto/compile.cpp | 4 +- hotspot/src/share/vm/opto/connode.cpp | 2 +- hotspot/src/share/vm/opto/library_call.cpp | 2 +- hotspot/src/share/vm/opto/live.cpp | 2 +- hotspot/src/share/vm/opto/macro.cpp | 2 +- hotspot/src/share/vm/opto/memnode.cpp | 4 +- hotspot/src/share/vm/opto/type.cpp | 2 +- hotspot/src/share/vm/runtime/arguments.cpp | 44 +++++++++-------- hotspot/src/share/vm/runtime/globals.hpp | 10 ++-- hotspot/src/share/vm/services/memoryPool.cpp | 2 +- .../src/share/vm/services/memoryService.cpp | 2 +- .../arguments/TestCompressedClassFlags.java | 49 +++++++++++++++++++ ...> CompressedClassSpaceSizeInJmapHeap.java} | 14 +++--- .../gc/metaspace/TestMetaspaceMemoryPool.java | 4 +- .../metaspace/TestMetaspacePerfCounters.java | 14 +++--- .../CDSCompressedKPtrs.java | 6 +-- .../CDSCompressedKPtrsError.java | 16 +++--- .../CompressedKlassPointerAndOops.java | 4 +- 43 files changed, 228 insertions(+), 175 deletions(-) create mode 100644 hotspot/test/gc/arguments/TestCompressedClassFlags.java rename hotspot/test/gc/metaspace/{ClassMetaspaceSizeInJmapHeap.java => CompressedClassSpaceSizeInJmapHeap.java} (83%) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java index f84da894ac2..319d2430af2 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java @@ -792,7 +792,7 @@ public class VM { public boolean isCompressedKlassPointersEnabled() { if (compressedKlassPointersEnabled == null) { - Flag flag = getCommandLineFlag("UseCompressedKlassPointers"); + Flag flag = getCommandLineFlag("UseCompressedClassPointers"); compressedKlassPointersEnabled = (flag == null) ? Boolean.FALSE: (flag.getBool()? Boolean.TRUE: Boolean.FALSE); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java index a0123dd4c99..daab682aaef 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java @@ -66,18 +66,18 @@ public class HeapSummary extends Tool { printGCAlgorithm(flagMap); System.out.println(); System.out.println("Heap Configuration:"); - printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap)); - printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap)); - printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap)); - printValMB("NewSize = ", getFlagValue("NewSize", flagMap)); - printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap)); - printValMB("OldSize = ", getFlagValue("OldSize", flagMap)); - printValue("NewRatio = ", getFlagValue("NewRatio", flagMap)); - printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap)); - printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap)); - printValMB("ClassMetaspaceSize = ", getFlagValue("ClassMetaspaceSize", flagMap)); - printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap)); - printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes()); + printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap)); + printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap)); + printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap)); + printValMB("NewSize = ", getFlagValue("NewSize", flagMap)); + printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap)); + printValMB("OldSize = ", getFlagValue("OldSize", flagMap)); + printValue("NewRatio = ", getFlagValue("NewRatio", flagMap)); + printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap)); + printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap)); + printValMB("CompressedClassSpaceSize = ", getFlagValue("CompressedClassSpaceSize", flagMap)); + printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap)); + printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes()); System.out.println(); System.out.println("Heap Usage:"); diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp index 12d51571ccb..cb4c04a388b 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -105,7 +105,7 @@ bool LIR_Assembler::is_single_instruction(LIR_Op* op) { if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false; } - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { if (src->is_address() && !src->is_stack() && src->type() == T_ADDRESS && src->as_address_ptr()->disp() == oopDesc::klass_offset_in_bytes()) return false; } @@ -963,7 +963,7 @@ int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType typ case T_METADATA: __ ld_ptr(base, offset, to_reg->as_register()); break; case T_ADDRESS: #ifdef _LP64 - if (offset == oopDesc::klass_offset_in_bytes() && UseCompressedKlassPointers) { + if (offset == oopDesc::klass_offset_in_bytes() && UseCompressedClassPointers) { __ lduw(base, offset, to_reg->as_register()); __ decode_klass_not_null(to_reg->as_register()); } else @@ -2208,7 +2208,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // We don't know the array types are compatible if (basic_type != T_OBJECT) { // Simple test for basic type arrays - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { // We don't need decode because we just need to compare __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp); __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2); @@ -2342,7 +2342,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // but not necessarily exactly of type default_type. Label known_ok, halt; metadata2reg(op->expected_type()->constant_encoding(), tmp); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { // tmp holds the default type. It currently comes uncompressed after the // load of a constant, so encode it. __ encode_klass_not_null(tmp); diff --git a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp index bf4074b30fd..6d10ab81aaf 100644 --- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp @@ -186,7 +186,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register set((intx)markOopDesc::prototype(), t1); } st_ptr(t1, obj, oopDesc::mark_offset_in_bytes()); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { // Save klass mov(klass, t1); encode_klass_not_null(t1); @@ -196,7 +196,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register } if (len->is_valid()) { st(len, obj, arrayOopDesc::length_offset_in_bytes()); - } else if (UseCompressedKlassPointers) { + } else if (UseCompressedClassPointers) { // otherwise length is in the class gap store_klass_gap(G0, obj); } diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp index d2c4e3b0261..9f1f2e53371 100644 --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp @@ -3911,7 +3911,7 @@ void MacroAssembler::load_klass(Register src_oop, Register klass) { // The number of bytes in this code is used by // MachCallDynamicJavaNode::ret_addr_offset() // if this changes, change that. - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { lduw(src_oop, oopDesc::klass_offset_in_bytes(), klass); decode_klass_not_null(klass); } else { @@ -3920,7 +3920,7 @@ void MacroAssembler::load_klass(Register src_oop, Register klass) { } void MacroAssembler::store_klass(Register klass, Register dst_oop) { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { assert(dst_oop != klass, "not enough registers"); encode_klass_not_null(klass); st(klass, dst_oop, oopDesc::klass_offset_in_bytes()); @@ -3930,7 +3930,7 @@ void MacroAssembler::store_klass(Register klass, Register dst_oop) { } void MacroAssembler::store_klass_gap(Register s, Register d) { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { assert(s != d, "not enough registers"); st(s, d, oopDesc::klass_gap_offset_in_bytes()); } @@ -4089,7 +4089,7 @@ void MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) { } void MacroAssembler::encode_klass_not_null(Register r) { - assert (UseCompressedKlassPointers, "must be compressed"); + assert (UseCompressedClassPointers, "must be compressed"); assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized"); assert(r != G6_heapbase, "bad register choice"); set((intptr_t)Universe::narrow_klass_base(), G6_heapbase); @@ -4105,7 +4105,7 @@ void MacroAssembler::encode_klass_not_null(Register src, Register dst) { if (src == dst) { encode_klass_not_null(src); } else { - assert (UseCompressedKlassPointers, "must be compressed"); + assert (UseCompressedClassPointers, "must be compressed"); assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized"); set((intptr_t)Universe::narrow_klass_base(), dst); sub(src, dst, dst); @@ -4119,7 +4119,7 @@ void MacroAssembler::encode_klass_not_null(Register src, Register dst) { // generated by decode_klass_not_null() and reinit_heapbase(). Hence, if // the instructions they generate change, then this method needs to be updated. int MacroAssembler::instr_size_for_decode_klass_not_null() { - assert (UseCompressedKlassPointers, "only for compressed klass ptrs"); + assert (UseCompressedClassPointers, "only for compressed klass ptrs"); // set + add + set int num_instrs = insts_for_internal_set((intptr_t)Universe::narrow_klass_base()) + 1 + insts_for_internal_set((intptr_t)Universe::narrow_ptrs_base()); @@ -4135,7 +4135,7 @@ int MacroAssembler::instr_size_for_decode_klass_not_null() { void MacroAssembler::decode_klass_not_null(Register r) { // Do not add assert code to this unless you change vtableStubs_sparc.cpp // pd_code_size_limit. - assert (UseCompressedKlassPointers, "must be compressed"); + assert (UseCompressedClassPointers, "must be compressed"); assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized"); assert(r != G6_heapbase, "bad register choice"); set((intptr_t)Universe::narrow_klass_base(), G6_heapbase); @@ -4151,7 +4151,7 @@ void MacroAssembler::decode_klass_not_null(Register src, Register dst) { } else { // Do not add assert code to this unless you change vtableStubs_sparc.cpp // pd_code_size_limit. - assert (UseCompressedKlassPointers, "must be compressed"); + assert (UseCompressedClassPointers, "must be compressed"); assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized"); if (Universe::narrow_klass_shift() != 0) { assert((src != G6_heapbase) && (dst != G6_heapbase), "bad register choice"); @@ -4167,7 +4167,7 @@ void MacroAssembler::decode_klass_not_null(Register src, Register dst) { } void MacroAssembler::reinit_heapbase() { - if (UseCompressedOops || UseCompressedKlassPointers) { + if (UseCompressedOops || UseCompressedClassPointers) { if (Universe::heap() != NULL) { set((intptr_t)Universe::narrow_ptrs_base(), G6_heapbase); } else { diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad index a72bffdadeb..58c113a0c1a 100644 --- a/hotspot/src/cpu/sparc/vm/sparc.ad +++ b/hotspot/src/cpu/sparc/vm/sparc.ad @@ -557,7 +557,7 @@ int MachCallDynamicJavaNode::ret_addr_offset() { int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); int klass_load_size; - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { assert(Universe::heap() != NULL, "java heap should be initialized"); klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord; } else { @@ -1657,7 +1657,7 @@ uint BoxLockNode::size(PhaseRegAlloc *ra_) const { void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { st->print_cr("\nUEP:"); #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { assert(Universe::heap() != NULL, "java heap should be initialized"); st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass"); st->print_cr("\tSET Universe::narrow_klass_base,R_G6_heap_base"); @@ -1897,7 +1897,7 @@ bool Matcher::narrow_oop_use_complex_address() { bool Matcher::narrow_klass_use_complex_address() { NOT_LP64(ShouldNotCallThis()); - assert(UseCompressedKlassPointers, "only for compressed klass code"); + assert(UseCompressedClassPointers, "only for compressed klass code"); return false; } @@ -2561,7 +2561,7 @@ encode %{ int off = __ offset(); __ load_klass(O0, G3_scratch); int klass_load_size; - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { assert(Universe::heap() != NULL, "java heap should be initialized"); klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord; } else { diff --git a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp index 214940cdbfb..612ae118ee4 100644 --- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp @@ -2945,7 +2945,7 @@ class StubGenerator: public StubCodeGenerator { BLOCK_COMMENT("arraycopy argument klass checks"); // get src->klass() - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ delayed()->nop(); // ??? not good __ load_klass(src, G3_src_klass); } else { @@ -2980,7 +2980,7 @@ class StubGenerator: public StubCodeGenerator { // Load 32-bits signed value. Use br() instruction with it to check icc. __ lduw(G3_src_klass, lh_offset, G5_lh); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ load_klass(dst, G4_dst_klass); } // Handle objArrays completely differently... @@ -2988,7 +2988,7 @@ class StubGenerator: public StubCodeGenerator { __ set(objArray_lh, O5_temp); __ cmp(G5_lh, O5_temp); __ br(Assembler::equal, false, Assembler::pt, L_objArray); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ delayed()->nop(); } else { __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass); diff --git a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp index 39663758035..ce19d4d7e7b 100644 --- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp @@ -218,13 +218,13 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) { // ld;ld;ld,jmp,nop const int basic = 5*BytesPerInstWord + // shift;add for load_klass (only shift with zero heap based) - (UseCompressedKlassPointers ? + (UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); return basic + slop; } else { const int basic = (28 LP64_ONLY(+ 6)) * BytesPerInstWord + // shift;add for load_klass (only shift with zero heap based) - (UseCompressedKlassPointers ? + (UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); return (basic + slop); } diff --git a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp index ea5d6d39da6..2d1b5f1f3c7 100644 --- a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp @@ -148,7 +148,7 @@ static int adjust_reg_range(int range) { // Reduce the number of available regs (to free r12) in case of compressed oops - if (UseCompressedOops || UseCompressedKlassPointers) return range - 1; + if (UseCompressedOops || UseCompressedClassPointers) return range - 1; return range; } diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index 334d0cc92db..735d343898f 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -341,7 +341,7 @@ int LIR_Assembler::check_icache() { Register receiver = FrameMap::receiver_opr->as_register(); Register ic_klass = IC_Klass; const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); - const bool do_post_padding = VerifyOops || UseCompressedKlassPointers; + const bool do_post_padding = VerifyOops || UseCompressedClassPointers; if (!do_post_padding) { // insert some nops so that the verified entry point is aligned on CodeEntryAlignment while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { @@ -1263,7 +1263,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch break; case T_ADDRESS: - if (UseCompressedKlassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) { + if (UseCompressedClassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) { __ movl(dest->as_register(), from_addr); } else { __ movptr(dest->as_register(), from_addr); @@ -1371,7 +1371,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch __ verify_oop(dest->as_register()); } else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) { #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ decode_klass_not_null(dest->as_register()); } #endif @@ -1716,7 +1716,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L } else if (obj == klass_RInfo) { klass_RInfo = dst; } - if (k->is_loaded() && !UseCompressedKlassPointers) { + if (k->is_loaded() && !UseCompressedClassPointers) { select_different_registers(obj, dst, k_RInfo, klass_RInfo); } else { Rtmp1 = op->tmp3()->as_register(); @@ -1754,7 +1754,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L // get object class // not a safepoint as obj null check happens earlier #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ load_klass(Rtmp1, obj); __ cmpptr(k_RInfo, Rtmp1); } else { @@ -3294,7 +3294,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // We don't know the array types are compatible if (basic_type != T_OBJECT) { // Simple test for basic type arrays - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ movl(tmp, src_klass_addr); __ cmpl(tmp, dst_klass_addr); } else { @@ -3456,21 +3456,21 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { Label known_ok, halt; __ mov_metadata(tmp, default_type->constant_encoding()); #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ encode_klass_not_null(tmp); } #endif if (basic_type != T_OBJECT) { - if (UseCompressedKlassPointers) __ cmpl(tmp, dst_klass_addr); + if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr); else __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::notEqual, halt); - if (UseCompressedKlassPointers) __ cmpl(tmp, src_klass_addr); + if (UseCompressedClassPointers) __ cmpl(tmp, src_klass_addr); else __ cmpptr(tmp, src_klass_addr); __ jcc(Assembler::equal, known_ok); } else { - if (UseCompressedKlassPointers) __ cmpl(tmp, dst_klass_addr); + if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr); else __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::equal, known_ok); __ cmpptr(src, dst); diff --git a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp index e6638581bcf..308befddc77 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @@ -1239,7 +1239,7 @@ void LIRGenerator::do_CheckCast(CheckCast* x) { } LIR_Opr reg = rlock_result(x); LIR_Opr tmp3 = LIR_OprFact::illegalOpr; - if (!x->klass()->is_loaded() || UseCompressedKlassPointers) { + if (!x->klass()->is_loaded() || UseCompressedClassPointers) { tmp3 = new_register(objectType); } __ checkcast(reg, obj.result(), x->klass(), @@ -1261,7 +1261,7 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) { } obj.load_item(); LIR_Opr tmp3 = LIR_OprFact::illegalOpr; - if (!x->klass()->is_loaded() || UseCompressedKlassPointers) { + if (!x->klass()->is_loaded() || UseCompressedClassPointers) { tmp3 = new_register(objectType); } __ instanceof(reg, obj.result(), x->klass(), diff --git a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp index d9ae6ce5de5..805fe5a48ca 100644 --- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp @@ -157,7 +157,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype()); } #ifdef _LP64 - if (UseCompressedKlassPointers) { // Take care not to kill klass + if (UseCompressedClassPointers) { // Take care not to kill klass movptr(t1, klass); encode_klass_not_null(t1); movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1); @@ -171,7 +171,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len); } #ifdef _LP64 - else if (UseCompressedKlassPointers) { + else if (UseCompressedClassPointers) { xorptr(t1, t1); store_klass_gap(obj, t1); } @@ -334,7 +334,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check"); int start_offset = offset(); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { load_klass(rscratch1, receiver); cmpptr(rscratch1, iCache); } else { @@ -345,7 +345,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); - assert(UseCompressedKlassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry"); + assert(UseCompressedClassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry"); } diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index b331f694959..fed50ef4286 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -1635,7 +1635,7 @@ void MacroAssembler::call_VM_base(Register oop_result, #ifdef ASSERT // TraceBytecodes does not use r12 but saves it over the call, so don't verify // r12 is the heapbase. - LP64_ONLY(if ((UseCompressedOops || UseCompressedKlassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");) + LP64_ONLY(if ((UseCompressedOops || UseCompressedClassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");) #endif // ASSERT assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); @@ -4802,7 +4802,7 @@ void MacroAssembler::restore_cpu_control_state_after_jni() { void MacroAssembler::load_klass(Register dst, Register src) { #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); decode_klass_not_null(dst); } else @@ -4817,7 +4817,7 @@ void MacroAssembler::load_prototype_header(Register dst, Register src) { void MacroAssembler::store_klass(Register dst, Register src) { #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { encode_klass_not_null(src); movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); } else @@ -4892,7 +4892,7 @@ void MacroAssembler::store_heap_oop_null(Address dst) { #ifdef _LP64 void MacroAssembler::store_klass_gap(Register dst, Register src) { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { // Store to klass gap in destination movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src); } @@ -5075,7 +5075,7 @@ void MacroAssembler::encode_klass_not_null(Register dst, Register src) { // when (Universe::heap() != NULL). Hence, if the instructions they // generate change, then this method needs to be updated. int MacroAssembler::instr_size_for_decode_klass_not_null() { - assert (UseCompressedKlassPointers, "only for compressed klass ptrs"); + assert (UseCompressedClassPointers, "only for compressed klass ptrs"); // mov64 + addq + shlq? + mov64 (for reinit_heapbase()). return (Universe::narrow_klass_shift() == 0 ? 20 : 24); } @@ -5085,7 +5085,7 @@ int MacroAssembler::instr_size_for_decode_klass_not_null() { void MacroAssembler::decode_klass_not_null(Register r) { // Note: it will change flags assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); assert(r != r12_heapbase, "Decoding a klass in r12"); // Cannot assert, unverified entry point counts instructions (see .ad file) // vtableStubs also counts instructions in pd_code_size_limit. @@ -5103,7 +5103,7 @@ void MacroAssembler::decode_klass_not_null(Register r) { void MacroAssembler::decode_klass_not_null(Register dst, Register src) { // Note: it will change flags assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); if (dst == src) { decode_klass_not_null(dst); } else { @@ -5141,7 +5141,7 @@ void MacroAssembler::set_narrow_oop(Address dst, jobject obj) { } void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); int klass_index = oop_recorder()->find_index(k); RelocationHolder rspec = metadata_Relocation::spec(klass_index); @@ -5149,7 +5149,7 @@ void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { } void MacroAssembler::set_narrow_klass(Address dst, Klass* k) { - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); int klass_index = oop_recorder()->find_index(k); RelocationHolder rspec = metadata_Relocation::spec(klass_index); @@ -5175,7 +5175,7 @@ void MacroAssembler::cmp_narrow_oop(Address dst, jobject obj) { } void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) { - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); int klass_index = oop_recorder()->find_index(k); RelocationHolder rspec = metadata_Relocation::spec(klass_index); @@ -5183,7 +5183,7 @@ void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) { } void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) { - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); int klass_index = oop_recorder()->find_index(k); RelocationHolder rspec = metadata_Relocation::spec(klass_index); @@ -5191,7 +5191,7 @@ void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) { } void MacroAssembler::reinit_heapbase() { - if (UseCompressedOops || UseCompressedKlassPointers) { + if (UseCompressedOops || UseCompressedClassPointers) { if (Universe::heap() != NULL) { if (Universe::narrow_oop_base() == NULL) { MacroAssembler::xorptr(r12_heapbase, r12_heapbase); diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp index 518da23eb60..5f5f94f41a5 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp @@ -211,11 +211,11 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) { if (is_vtable_stub) { // Vtable stub size return (DebugVtables ? 512 : 24) + (CountCompiledCalls ? 13 : 0) + - (UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); + (UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); } else { // Itable stub size return (DebugVtables ? 512 : 74) + (CountCompiledCalls ? 13 : 0) + - (UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); + (UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); } // In order to tune these parameters, run the JVM with VM options // +PrintMiscellaneous and +WizardMode to see information about diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad index f550208e94d..ed13b3da1d1 100644 --- a/hotspot/src/cpu/x86/vm/x86_64.ad +++ b/hotspot/src/cpu/x86/vm/x86_64.ad @@ -1391,7 +1391,7 @@ uint BoxLockNode::size(PhaseRegAlloc *ra_) const #ifndef PRODUCT void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); @@ -1408,7 +1408,7 @@ void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { MacroAssembler masm(&cbuf); uint insts_size = cbuf.insts_size(); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { masm.load_klass(rscratch1, j_rarg0); masm.cmpptr(rax, rscratch1); } else { @@ -1557,7 +1557,7 @@ bool Matcher::narrow_oop_use_complex_address() { } bool Matcher::narrow_klass_use_complex_address() { - assert(UseCompressedKlassPointers, "only for compressed klass code"); + assert(UseCompressedClassPointers, "only for compressed klass code"); return (LogKlassAlignmentInBytes <= 3); } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 04b550c718b..2fc6edd34df 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -230,7 +230,7 @@ ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration( // depends on this property. debug_only( FreeChunk* junk = NULL; - assert(UseCompressedKlassPointers || + assert(UseCompressedClassPointers || junk->prev_addr() == (void*)(oop(junk)->klass_addr()), "Offset of FreeChunk::_prev within FreeChunk must match" " that of OopDesc::_klass within OopDesc"); @@ -1407,7 +1407,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num, assert(!((FreeChunk*)obj_ptr)->is_free(), "Error, block will look free but show wrong size"); OrderAccess::storestore(); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { // Copy gap missed by (aligned) header size calculation below obj->set_klass_gap(old->klass_gap()); } diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index cd46888c9c2..1c5cec84d5f 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -423,7 +423,7 @@ class VirtualSpaceList : public CHeapObj { // Can this virtual list allocate >1 spaces? Also, used to determine // whether to allocate unlimited small chunks in this virtual space bool _is_class; - bool can_grow() const { return !is_class() || !UseCompressedKlassPointers; } + bool can_grow() const { return !is_class() || !UseCompressedClassPointers; } // Sum of space in all virtual spaces and number of virtual spaces size_t _virtual_space_total; @@ -2836,7 +2836,7 @@ void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address // to work with compressed klass pointers. bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) { assert(cds_base != 0 && UseSharedSpaces, "Only use with CDS"); - assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs"); + assert(UseCompressedClassPointers, "Only use with CompressedKlassPtrs"); address lower_base = MIN2((address)metaspace_base, cds_base); address higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()), (address)(metaspace_base + class_metaspace_size())); @@ -2846,7 +2846,7 @@ bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cd // Try to allocate the metaspace at the requested addr. void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) { assert(using_class_space(), "called improperly"); - assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs"); + assert(UseCompressedClassPointers, "Only use with CompressedKlassPtrs"); assert(class_metaspace_size() < KlassEncodingMetaspaceMax, "Metaspace size is too big"); @@ -2869,9 +2869,9 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a // If no successful allocation then try to allocate the space anywhere. If // that fails then OOM doom. At this point we cannot try allocating the - // metaspace as if UseCompressedKlassPointers is off because too much - // initialization has happened that depends on UseCompressedKlassPointers. - // So, UseCompressedKlassPointers cannot be turned off at this point. + // metaspace as if UseCompressedClassPointers is off because too much + // initialization has happened that depends on UseCompressedClassPointers. + // So, UseCompressedClassPointers cannot be turned off at this point. if (!metaspace_rs.is_reserved()) { metaspace_rs = ReservedSpace(class_metaspace_size(), os::vm_allocation_granularity(), false); @@ -2904,12 +2904,12 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a } } -// For UseCompressedKlassPointers the class space is reserved above the top of +// For UseCompressedClassPointers the class space is reserved above the top of // the Java heap. The argument passed in is at the base of the compressed space. void Metaspace::initialize_class_space(ReservedSpace rs) { // The reserved space size may be bigger because of alignment, esp with UseLargePages - assert(rs.size() >= ClassMetaspaceSize, - err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize)); + assert(rs.size() >= CompressedClassSpaceSize, + err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize)); assert(using_class_space(), "Must be using class space"); _class_space_list = new VirtualSpaceList(rs); } @@ -2921,7 +2921,7 @@ void Metaspace::global_initialize() { int max_alignment = os::vm_page_size(); size_t cds_total = 0; - set_class_metaspace_size(align_size_up(ClassMetaspaceSize, + set_class_metaspace_size(align_size_up(CompressedClassSpaceSize, os::vm_allocation_granularity())); MetaspaceShared::set_max_alignment(max_alignment); @@ -2941,8 +2941,8 @@ void Metaspace::global_initialize() { #ifdef _LP64 // Set the compressed klass pointer base so that decoding of these pointers works // properly when creating the shared archive. - assert(UseCompressedOops && UseCompressedKlassPointers, - "UseCompressedOops and UseCompressedKlassPointers must be set"); + assert(UseCompressedOops && UseCompressedClassPointers, + "UseCompressedOops and UseCompressedClassPointers must be set"); Universe::set_narrow_klass_base((address)_space_list->current_virtual_space()->bottom()); if (TraceMetavirtualspaceAllocation && Verbose) { gclog_or_tty->print_cr("Setting_narrow_klass_base to Address: " PTR_FORMAT, @@ -2979,7 +2979,7 @@ void Metaspace::global_initialize() { } #ifdef _LP64 - // If UseCompressedKlassPointers is set then allocate the metaspace area + // If UseCompressedClassPointers is set then allocate the metaspace area // above the heap and above the CDS area (if it exists). if (using_class_space()) { if (UseSharedSpaces) { @@ -2997,7 +2997,7 @@ void Metaspace::global_initialize() { // on the medium chunk list. The next chunk will be small and progress // from there. This size calculated by -version. _first_class_chunk_word_size = MIN2((size_t)MediumChunk*6, - (ClassMetaspaceSize/BytesPerWord)*2); + (CompressedClassSpaceSize/BytesPerWord)*2); _first_class_chunk_word_size = align_word_size_up(_first_class_chunk_word_size); // Arbitrarily set the initial virtual space to a multiple // of the boot class loader size. @@ -3064,7 +3064,7 @@ size_t Metaspace::align_word_size_up(size_t word_size) { MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { // DumpSharedSpaces doesn't use class metadata area (yet) - // Also, don't use class_vsm() unless UseCompressedKlassPointers is true. + // Also, don't use class_vsm() unless UseCompressedClassPointers is true. if (mdtype == ClassType && using_class_space()) { return class_vsm()->allocate(word_size); } else { @@ -3213,7 +3213,7 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, MetaspaceAux::dump(gclog_or_tty); } // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support - const char* space_string = (mdtype == ClassType) ? "Class Metadata space" : + const char* space_string = (mdtype == ClassType) ? "Compressed class space" : "Metadata space"; report_java_out_of_memory(space_string); diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 88f089494d3..591acf30075 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -213,9 +213,9 @@ class Metaspace : public CHeapObj { void iterate(AllocRecordClosure *closure); - // Return TRUE only if UseCompressedKlassPointers is True and DumpSharedSpaces is False. + // Return TRUE only if UseCompressedClassPointers is True and DumpSharedSpaces is False. static bool using_class_space() { - return NOT_LP64(false) LP64_ONLY(UseCompressedKlassPointers && !DumpSharedSpaces); + return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces); } }; diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.cpp b/hotspot/src/share/vm/memory/metaspaceCounters.cpp index eb7bebd28b6..32eda2b4ed8 100644 --- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp +++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp @@ -109,7 +109,7 @@ size_t CompressedClassSpaceCounters::calculate_capacity() { } void CompressedClassSpaceCounters::update_performance_counters() { - if (UsePerfData && UseCompressedKlassPointers) { + if (UsePerfData && UseCompressedClassPointers) { assert(_perf_counters != NULL, "Should be initialized"); size_t capacity = calculate_capacity(); @@ -125,7 +125,7 @@ void CompressedClassSpaceCounters::initialize_performance_counters() { assert(_perf_counters == NULL, "Should only be initialized once"); const char* ns = "compressedclassspace"; - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { size_t min_capacity = MetaspaceAux::min_chunk_size(); size_t capacity = calculate_capacity(); size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type); diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 143c0c00c45..d0f34b33ae1 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -1028,7 +1028,7 @@ bool universe_post_init() { msg = java_lang_String::create_from_str("Metadata space", CHECK_false); java_lang_Throwable::set_message(Universe::_out_of_memory_error_metaspace, msg()); - msg = java_lang_String::create_from_str("Class Metadata space", CHECK_false); + msg = java_lang_String::create_from_str("Compressed class space", CHECK_false); java_lang_Throwable::set_message(Universe::_out_of_memory_error_class_metaspace, msg()); msg = java_lang_String::create_from_str("Requested array size exceeds VM limit", CHECK_false); diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp index a8b541d03a1..4c698f95174 100644 --- a/hotspot/src/share/vm/memory/universe.hpp +++ b/hotspot/src/share/vm/memory/universe.hpp @@ -181,7 +181,7 @@ class Universe: AllStatic { // For UseCompressedOops. static struct NarrowPtrStruct _narrow_oop; - // For UseCompressedKlassPointers. + // For UseCompressedClassPointers. static struct NarrowPtrStruct _narrow_klass; static address _narrow_ptrs_base; @@ -229,7 +229,7 @@ class Universe: AllStatic { _narrow_oop._base = base; } static void set_narrow_klass_base(address base) { - assert(UseCompressedKlassPointers, "no compressed klass ptrs?"); + assert(UseCompressedClassPointers, "no compressed klass ptrs?"); _narrow_klass._base = base; } static void set_narrow_oop_use_implicit_null_checks(bool use) { @@ -353,7 +353,7 @@ class Universe: AllStatic { static int narrow_oop_shift() { return _narrow_oop._shift; } static bool narrow_oop_use_implicit_null_checks() { return _narrow_oop._use_implicit_null_checks; } - // For UseCompressedKlassPointers + // For UseCompressedClassPointers static address narrow_klass_base() { return _narrow_klass._base; } static bool is_narrow_klass_base(void* addr) { return (narrow_klass_base() == (address)addr); } static int narrow_klass_shift() { return _narrow_klass._shift; } diff --git a/hotspot/src/share/vm/oops/arrayOop.hpp b/hotspot/src/share/vm/oops/arrayOop.hpp index 806b7b7289a..0e5ceffe35a 100644 --- a/hotspot/src/share/vm/oops/arrayOop.hpp +++ b/hotspot/src/share/vm/oops/arrayOop.hpp @@ -65,7 +65,7 @@ class arrayOopDesc : public oopDesc { // declared nonstatic fields in arrayOopDesc if not compressed, otherwise // it occupies the second half of the _klass field in oopDesc. static int length_offset_in_bytes() { - return UseCompressedKlassPointers ? klass_gap_offset_in_bytes() : + return UseCompressedClassPointers ? klass_gap_offset_in_bytes() : sizeof(arrayOopDesc); } diff --git a/hotspot/src/share/vm/oops/instanceOop.hpp b/hotspot/src/share/vm/oops/instanceOop.hpp index 9ebb9d4720b..bdac1992e6f 100644 --- a/hotspot/src/share/vm/oops/instanceOop.hpp +++ b/hotspot/src/share/vm/oops/instanceOop.hpp @@ -37,9 +37,9 @@ class instanceOopDesc : public oopDesc { // If compressed, the offset of the fields of the instance may not be aligned. static int base_offset_in_bytes() { - // offset computation code breaks if UseCompressedKlassPointers + // offset computation code breaks if UseCompressedClassPointers // only is true - return (UseCompressedOops && UseCompressedKlassPointers) ? + return (UseCompressedOops && UseCompressedClassPointers) ? klass_gap_offset_in_bytes() : sizeof(instanceOopDesc); } diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp index 9a6c1e1787b..f1823f2e2b1 100644 --- a/hotspot/src/share/vm/oops/oop.inline.hpp +++ b/hotspot/src/share/vm/oops/oop.inline.hpp @@ -69,7 +69,7 @@ inline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) { } inline Klass* oopDesc::klass() const { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { return Klass::decode_klass_not_null(_metadata._compressed_klass); } else { return _metadata._klass; @@ -78,7 +78,7 @@ inline Klass* oopDesc::klass() const { inline Klass* oopDesc::klass_or_null() const volatile { // can be NULL in CMS - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { return Klass::decode_klass(_metadata._compressed_klass); } else { return _metadata._klass; @@ -86,19 +86,19 @@ inline Klass* oopDesc::klass_or_null() const volatile { } inline int oopDesc::klass_gap_offset_in_bytes() { - assert(UseCompressedKlassPointers, "only applicable to compressed klass pointers"); + assert(UseCompressedClassPointers, "only applicable to compressed klass pointers"); return oopDesc::klass_offset_in_bytes() + sizeof(narrowKlass); } inline Klass** oopDesc::klass_addr() { // Only used internally and with CMS and will not work with // UseCompressedOops - assert(!UseCompressedKlassPointers, "only supported with uncompressed klass pointers"); + assert(!UseCompressedClassPointers, "only supported with uncompressed klass pointers"); return (Klass**) &_metadata._klass; } inline narrowKlass* oopDesc::compressed_klass_addr() { - assert(UseCompressedKlassPointers, "only called by compressed klass pointers"); + assert(UseCompressedClassPointers, "only called by compressed klass pointers"); return &_metadata._compressed_klass; } @@ -106,7 +106,7 @@ inline void oopDesc::set_klass(Klass* k) { // since klasses are promoted no store check is needed assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*"); assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*"); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { *compressed_klass_addr() = Klass::encode_klass_not_null(k); } else { *klass_addr() = k; @@ -118,7 +118,7 @@ inline int oopDesc::klass_gap() const { } inline void oopDesc::set_klass_gap(int v) { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()) = v; } } @@ -126,7 +126,7 @@ inline void oopDesc::set_klass_gap(int v) { inline void oopDesc::set_klass_to_list_ptr(oop k) { // This is only to be used during GC, for from-space objects, so no // barrier is needed. - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { _metadata._compressed_klass = (narrowKlass)encode_heap_oop(k); // may be null (parnew overflow handling) } else { _metadata._klass = (Klass*)(address)k; @@ -135,7 +135,7 @@ inline void oopDesc::set_klass_to_list_ptr(oop k) { inline oop oopDesc::list_ptr_from_klass() { // This is only to be used during GC, for from-space objects. - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { return decode_heap_oop((narrowOop)_metadata._compressed_klass); } else { // Special case for GC diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp index 4185ada5d1c..36347fb9202 100644 --- a/hotspot/src/share/vm/opto/cfgnode.cpp +++ b/hotspot/src/share/vm/opto/cfgnode.cpp @@ -1932,7 +1932,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) { #ifdef _LP64 // Push DecodeN/DecodeNKlass down through phi. // The rest of phi graph will transform by split EncodeP node though phis up. - if ((UseCompressedOops || UseCompressedKlassPointers) && can_reshape && progress == NULL) { + if ((UseCompressedOops || UseCompressedClassPointers) && can_reshape && progress == NULL) { bool may_push = true; bool has_decodeN = false; bool is_decodeN = false; diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index b426bcce1a2..69b6ca05c84 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -2631,7 +2631,7 @@ void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) { addp->in(AddPNode::Base) == n->in(AddPNode::Base), "Base pointers must match" ); #ifdef _LP64 - if ((UseCompressedOops || UseCompressedKlassPointers) && + if ((UseCompressedOops || UseCompressedClassPointers) && addp->Opcode() == Op_ConP && addp == n->in(AddPNode::Base) && n->in(AddPNode::Offset)->is_Con()) { @@ -3018,7 +3018,7 @@ void Compile::final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_ // Skip next transformation if compressed oops are not used. if ((UseCompressedOops && !Matcher::gen_narrow_oop_implicit_null_checks()) || - (!UseCompressedOops && !UseCompressedKlassPointers)) + (!UseCompressedOops && !UseCompressedClassPointers)) return; // Go over safepoints nodes to skip DecodeN/DecodeNKlass nodes for debug edges. diff --git a/hotspot/src/share/vm/opto/connode.cpp b/hotspot/src/share/vm/opto/connode.cpp index eb343a822e5..b59025ad4f3 100644 --- a/hotspot/src/share/vm/opto/connode.cpp +++ b/hotspot/src/share/vm/opto/connode.cpp @@ -630,7 +630,7 @@ const Type *EncodePKlassNode::Value( PhaseTransform *phase ) const { if (t == Type::TOP) return Type::TOP; assert (t != TypePtr::NULL_PTR, "null klass?"); - assert(UseCompressedKlassPointers && t->isa_klassptr(), "only klass ptr here"); + assert(UseCompressedClassPointers && t->isa_klassptr(), "only klass ptr here"); return t->make_narrowklass(); } diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 60525d73ef7..d3f5e18440c 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -4199,7 +4199,7 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b // 12 - 64-bit VM, compressed klass // 16 - 64-bit VM, normal klass if (base_off % BytesPerLong != 0) { - assert(UseCompressedKlassPointers, ""); + assert(UseCompressedClassPointers, ""); if (is_array) { // Exclude length to copy by 8 bytes words. base_off += sizeof(int); diff --git a/hotspot/src/share/vm/opto/live.cpp b/hotspot/src/share/vm/opto/live.cpp index 280d22204c2..70bcd8549c9 100644 --- a/hotspot/src/share/vm/opto/live.cpp +++ b/hotspot/src/share/vm/opto/live.cpp @@ -321,7 +321,7 @@ void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const { #ifdef _LP64 UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_CastPP || UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN || - UseCompressedKlassPointers && check->as_Mach()->ideal_Opcode() == Op_DecodeNKlass || + UseCompressedClassPointers && check->as_Mach()->ideal_Opcode() == Op_DecodeNKlass || #endif check->as_Mach()->ideal_Opcode() == Op_LoadP || check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) { diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp index 137c529ed0c..06bf9e608c0 100644 --- a/hotspot/src/share/vm/opto/macro.cpp +++ b/hotspot/src/share/vm/opto/macro.cpp @@ -2191,7 +2191,7 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) { Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes()); klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) ); #ifdef _LP64 - if (UseCompressedKlassPointers && klass_node->is_DecodeNKlass()) { + if (UseCompressedClassPointers && klass_node->is_DecodeNKlass()) { assert(klass_node->in(1)->Opcode() == Op_LoadNKlass, "sanity"); klass_node->in(1)->init_req(0, ctrl); } else diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index aa03b5ff6c5..01deaf07701 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -1971,7 +1971,7 @@ Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* a assert(adr_type != NULL, "expecting TypeKlassPtr"); #ifdef _LP64 if (adr_type->is_ptr_to_narrowklass()) { - assert(UseCompressedKlassPointers, "no compressed klasses"); + assert(UseCompressedClassPointers, "no compressed klasses"); Node* load_klass = gvn.transform(new (C) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass())); return new (C) DecodeNKlassNode(load_klass, load_klass->bottom_type()->make_ptr()); } @@ -2309,7 +2309,7 @@ StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, cons val = gvn.transform(new (C) EncodePNode(val, val->bottom_type()->make_narrowoop())); return new (C) StoreNNode(ctl, mem, adr, adr_type, val); } else if (adr->bottom_type()->is_ptr_to_narrowklass() || - (UseCompressedKlassPointers && val->bottom_type()->isa_klassptr() && + (UseCompressedClassPointers && val->bottom_type()->isa_klassptr() && adr->bottom_type()->isa_rawptr())) { val = gvn.transform(new (C) EncodePKlassNode(val, val->bottom_type()->make_narrowklass())); return new (C) StoreNKlassNode(ctl, mem, adr, adr_type, val); diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index fabcf1cad16..5fa6bfa8815 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -2381,7 +2381,7 @@ TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int #ifdef _LP64 if (_offset != 0) { if (_offset == oopDesc::klass_offset_in_bytes()) { - _is_ptr_to_narrowklass = UseCompressedKlassPointers; + _is_ptr_to_narrowklass = UseCompressedClassPointers; } else if (klass() == NULL) { // Array with unknown body type assert(this->isa_aryptr(), "only arrays without klass"); diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index d8a6f90eeef..fbce8b6b695 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1439,7 +1439,7 @@ void Arguments::set_use_compressed_oops() { if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) { warning("Max heap size too large for Compressed Oops"); FLAG_SET_DEFAULT(UseCompressedOops, false); - FLAG_SET_DEFAULT(UseCompressedKlassPointers, false); + FLAG_SET_DEFAULT(UseCompressedClassPointers, false); } } #endif // _LP64 @@ -1452,22 +1452,22 @@ void Arguments::set_use_compressed_oops() { void Arguments::set_use_compressed_klass_ptrs() { #ifndef ZERO #ifdef _LP64 - // UseCompressedOops must be on for UseCompressedKlassPointers to be on. + // UseCompressedOops must be on for UseCompressedClassPointers to be on. if (!UseCompressedOops) { - if (UseCompressedKlassPointers) { - warning("UseCompressedKlassPointers requires UseCompressedOops"); + if (UseCompressedClassPointers) { + warning("UseCompressedClassPointers requires UseCompressedOops"); } - FLAG_SET_DEFAULT(UseCompressedKlassPointers, false); + FLAG_SET_DEFAULT(UseCompressedClassPointers, false); } else { - // Turn on UseCompressedKlassPointers too - if (FLAG_IS_DEFAULT(UseCompressedKlassPointers)) { - FLAG_SET_ERGO(bool, UseCompressedKlassPointers, true); + // Turn on UseCompressedClassPointers too + if (FLAG_IS_DEFAULT(UseCompressedClassPointers)) { + FLAG_SET_ERGO(bool, UseCompressedClassPointers, true); } - // Check the ClassMetaspaceSize to make sure we use compressed klass ptrs. - if (UseCompressedKlassPointers) { - if (ClassMetaspaceSize > KlassEncodingMetaspaceMax) { - warning("Class metaspace size is too large for UseCompressedKlassPointers"); - FLAG_SET_DEFAULT(UseCompressedKlassPointers, false); + // Check the CompressedClassSpaceSize to make sure we use compressed klass ptrs. + if (UseCompressedClassPointers) { + if (CompressedClassSpaceSize > KlassEncodingMetaspaceMax) { + warning("CompressedClassSpaceSize is too large for UseCompressedClassPointers"); + FLAG_SET_DEFAULT(UseCompressedClassPointers, false); } } } @@ -2148,8 +2148,8 @@ bool Arguments::check_vm_args_consistency() { status = status && verify_object_alignment(); - status = status && verify_interval(ClassMetaspaceSize, 1*M, 3*G, - "ClassMetaspaceSize"); + status = status && verify_interval(CompressedClassSpaceSize, 1*M, 3*G, + "CompressedClassSpaceSize"); status = status && verify_interval(MarkStackSizeMax, 1, (max_jint - 1), "MarkStackSizeMax"); @@ -3274,13 +3274,13 @@ void Arguments::set_shared_spaces_flags() { } UseSharedSpaces = false; #ifdef _LP64 - if (!UseCompressedOops || !UseCompressedKlassPointers) { + if (!UseCompressedOops || !UseCompressedClassPointers) { vm_exit_during_initialization( - "Cannot dump shared archive when UseCompressedOops or UseCompressedKlassPointers is off.", NULL); + "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL); } } else { - // UseCompressedOops and UseCompressedKlassPointers must be on for UseSharedSpaces. - if (!UseCompressedOops || !UseCompressedKlassPointers) { + // UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces. + if (!UseCompressedOops || !UseCompressedClassPointers) { no_shared_spaces(); } #endif @@ -3581,7 +3581,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) { FLAG_SET_DEFAULT(ProfileInterpreter, false); FLAG_SET_DEFAULT(UseBiasedLocking, false); LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedOops, false)); - LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedKlassPointers, false)); + LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedClassPointers, false)); #endif // CC_INTERP #ifdef COMPILER2 @@ -3610,6 +3610,10 @@ jint Arguments::parse(const JavaVMInitArgs* args) { DebugNonSafepoints = true; } + if (FLAG_IS_CMDLINE(CompressedClassSpaceSize) && !UseCompressedClassPointers) { + warning("Setting CompressedClassSpaceSize has no effect when compressed class pointers are not used"); + } + #ifndef PRODUCT if (CompileTheWorld) { // Force NmethodSweeper to sweep whole CodeCache each time. diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index c9bcbe1f4d3..2633bf21265 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -443,8 +443,8 @@ class CommandLineFlags { "Use 32-bit object references in 64-bit VM " \ "lp64_product means flag is always constant in 32 bit VM") \ \ - lp64_product(bool, UseCompressedKlassPointers, false, \ - "Use 32-bit klass pointers in 64-bit VM " \ + lp64_product(bool, UseCompressedClassPointers, false, \ + "Use 32-bit class pointers in 64-bit VM " \ "lp64_product means flag is always constant in 32 bit VM") \ \ notproduct(bool, CheckCompressedOops, true, \ @@ -3039,9 +3039,9 @@ class CommandLineFlags { product(uintx, MaxMetaspaceSize, max_uintx, \ "Maximum size of Metaspaces (in bytes)") \ \ - product(uintx, ClassMetaspaceSize, 1*G, \ - "Maximum size of InstanceKlass area in Metaspace used for " \ - "UseCompressedKlassPointers") \ + product(uintx, CompressedClassSpaceSize, 1*G, \ + "Maximum size of class area in Metaspace when compressed " \ + "class pointers are used") \ \ product(uintx, MinHeapFreeRatio, 40, \ "Min percentage of heap free after GC to avoid expansion") \ diff --git a/hotspot/src/share/vm/services/memoryPool.cpp b/hotspot/src/share/vm/services/memoryPool.cpp index 777b8b8f382..7a17f0bd138 100644 --- a/hotspot/src/share/vm/services/memoryPool.cpp +++ b/hotspot/src/share/vm/services/memoryPool.cpp @@ -280,7 +280,7 @@ size_t MetaspacePool::calculate_max_size() const { } CompressedKlassSpacePool::CompressedKlassSpacePool() : - MemoryPool("Compressed Class Space", NonHeap, capacity_in_bytes(), ClassMetaspaceSize, true, false) { } + MemoryPool("Compressed Class Space", NonHeap, capacity_in_bytes(), CompressedClassSpaceSize, true, false) { } size_t CompressedKlassSpacePool::used_in_bytes() { return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType); diff --git a/hotspot/src/share/vm/services/memoryService.cpp b/hotspot/src/share/vm/services/memoryService.cpp index bf0fb9cad24..6508cd2086a 100644 --- a/hotspot/src/share/vm/services/memoryService.cpp +++ b/hotspot/src/share/vm/services/memoryService.cpp @@ -409,7 +409,7 @@ void MemoryService::add_metaspace_memory_pools() { mgr->add_pool(_metaspace_pool); _pools_list->append(_metaspace_pool); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { _compressed_class_pool = new CompressedKlassSpacePool(); mgr->add_pool(_compressed_class_pool); _pools_list->append(_compressed_class_pool); diff --git a/hotspot/test/gc/arguments/TestCompressedClassFlags.java b/hotspot/test/gc/arguments/TestCompressedClassFlags.java new file mode 100644 index 00000000000..4135debd89c --- /dev/null +++ b/hotspot/test/gc/arguments/TestCompressedClassFlags.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.*; + +/* + * @test + * @bug 8015107 + * @summary Tests that VM prints a warning when -XX:CompressedClassSpaceSize + * is used together with -XX:-UseCompressedClassPointers + * @library /testlibrary + */ +public class TestCompressedClassFlags { + public static void main(String[] args) throws Exception { + if (Platform.is64bit()) { + OutputAnalyzer output = runJava("-XX:CompressedClassSpaceSize=1g", + "-XX:-UseCompressedClassPointers", + "-version"); + output.shouldContain("warning"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + } + + private static OutputAnalyzer runJava(String ... args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args); + return new OutputAnalyzer(pb.start()); + } +} diff --git a/hotspot/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java b/hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java similarity index 83% rename from hotspot/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java rename to hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java index b3258466a2d..8152a9eb1ca 100644 --- a/hotspot/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java +++ b/hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java @@ -22,11 +22,11 @@ */ /* - * @test ClassMetaspaceSizeInJmapHeap + * @test CompressedClassSpaceSizeInJmapHeap * @bug 8004924 - * @summary Checks that jmap -heap contains the flag ClassMetaspaceSize + * @summary Checks that jmap -heap contains the flag CompressedClassSpaceSize * @library /testlibrary - * @run main/othervm -XX:ClassMetaspaceSize=50m ClassMetaspaceSizeInJmapHeap + * @run main/othervm -XX:CompressedClassSpaceSize=50m CompressedClassSpaceSizeInJmapHeap */ import com.oracle.java.testlibrary.*; @@ -35,7 +35,7 @@ import java.io.File; import java.nio.charset.Charset; import java.util.List; -public class ClassMetaspaceSizeInJmapHeap { +public class CompressedClassSpaceSizeInJmapHeap { public static void main(String[] args) throws Exception { String pid = Integer.toString(ProcessTools.getProcessId()); @@ -44,16 +44,16 @@ public class ClassMetaspaceSizeInJmapHeap { .addToolArg(pid); ProcessBuilder pb = new ProcessBuilder(jmap.getCommand()); - File out = new File("ClassMetaspaceSizeInJmapHeap.stdout.txt"); + File out = new File("CompressedClassSpaceSizeInJmapHeap.stdout.txt"); pb.redirectOutput(out); - File err = new File("ClassMetaspaceSizeInJmapHeap.stderr.txt"); + File err = new File("CompressedClassSpaceSizeInJmapHeap.stderr.txt"); pb.redirectError(err); run(pb); OutputAnalyzer output = new OutputAnalyzer(read(out)); - output.shouldContain("ClassMetaspaceSize = 52428800 (50.0MB)"); + output.shouldContain("CompressedClassSpaceSize = 52428800 (50.0MB)"); out.delete(); } diff --git a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java index 440f91cbd85..105ba240ddf 100644 --- a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java +++ b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java @@ -36,8 +36,8 @@ import java.lang.management.ManagementFactory; * MemoryManagerMXBean is created. * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops TestMetaspaceMemoryPool * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:MaxMetaspaceSize=60m TestMetaspaceMemoryPool - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers TestMetaspaceMemoryPool - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:ClassMetaspaceSize=60m TestMetaspaceMemoryPool + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers TestMetaspaceMemoryPool + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:CompressedClassSpaceSize=60m TestMetaspaceMemoryPool */ public class TestMetaspaceMemoryPool { public static void main(String[] args) { diff --git a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java index 26934249a7c..9672d90a5d0 100644 --- a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java +++ b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java @@ -33,13 +33,13 @@ import static com.oracle.java.testlibrary.Asserts.*; * @summary Tests that performance counters for metaspace and compressed class * space exists and works. * - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters * - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters */ public class TestMetaspacePerfCounters { public static Class fooClass = null; @@ -99,6 +99,6 @@ public class TestMetaspacePerfCounters { } private static boolean isUsingCompressedClassPointers() { - return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedKlassPointers"); + return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedClassPointers"); } } diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java index 4ce2e82c771..c32c05ebd27 100644 --- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java +++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java @@ -24,7 +24,7 @@ /* * @test * @bug 8003424 - * @summary Testing UseCompressedKlassPointers with CDS + * @summary Testing UseCompressedClassPointers with CDS * @library /testlibrary * @run main CDSCompressedKPtrs */ @@ -36,7 +36,7 @@ public class CDSCompressedKPtrs { ProcessBuilder pb; if (Platform.is64bit()) { pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedKlassPointers", "-XX:+UseCompressedOops", + "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); try { @@ -44,7 +44,7 @@ public class CDSCompressedKPtrs { output.shouldHaveExitValue(0); pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedKlassPointers", "-XX:+UseCompressedOops", + "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version"); output = new OutputAnalyzer(pb.start()); output.shouldContain("sharing"); diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java index b2cb84ac988..05b4ac9af28 100644 --- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java +++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java @@ -24,7 +24,7 @@ /* * @test * @bug 8003424 - * @summary Test that cannot use CDS if UseCompressedKlassPointers is turned off. + * @summary Test that cannot use CDS if UseCompressedClassPointers is turned off. * @library /testlibrary * @run main CDSCompressedKPtrsError */ @@ -36,7 +36,7 @@ public class CDSCompressedKPtrsError { ProcessBuilder pb; if (Platform.is64bit()) { pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedOops", "-XX:+UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UseCompressedOops", "-XX:+UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); try { @@ -44,21 +44,21 @@ public class CDSCompressedKPtrsError { output.shouldHaveExitValue(0); pb = ProcessTools.createJavaProcessBuilder( - "-XX:-UseCompressedKlassPointers", "-XX:-UseCompressedOops", + "-XX:-UseCompressedClassPointers", "-XX:-UseCompressedOops", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Unable to use shared archive"); output.shouldHaveExitValue(0); pb = ProcessTools.createJavaProcessBuilder( - "-XX:-UseCompressedKlassPointers", "-XX:+UseCompressedOops", + "-XX:-UseCompressedClassPointers", "-XX:+UseCompressedOops", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Unable to use shared archive"); output.shouldHaveExitValue(0); pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedKlassPointers", "-XX:-UseCompressedOops", + "-XX:+UseCompressedClassPointers", "-XX:-UseCompressedOops", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Unable to use shared archive"); @@ -71,19 +71,19 @@ public class CDSCompressedKPtrsError { // Test bad options with -Xshare:dump. pb = ProcessTools.createJavaProcessBuilder( - "-XX:-UseCompressedOops", "-XX:+UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions", + "-XX:-UseCompressedOops", "-XX:+UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Cannot dump shared archive"); pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedOops", "-XX:-UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UseCompressedOops", "-XX:-UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Cannot dump shared archive"); pb = ProcessTools.createJavaProcessBuilder( - "-XX:-UseCompressedOops", "-XX:-UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions", + "-XX:-UseCompressedOops", "-XX:-UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Cannot dump shared archive"); diff --git a/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java b/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java index dd0c26d9f10..228d8cb6a7a 100644 --- a/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java +++ b/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java @@ -25,7 +25,7 @@ * @test * @bug 8000968 * @key regression - * @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32 + * @summary NPG: UseCompressedClassPointers asserts with ObjectAlignmentInBytes=32 * @library /testlibrary */ @@ -52,7 +52,7 @@ public class CompressedKlassPointerAndOops { OutputAnalyzer output; pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedKlassPointers", + "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops", "-XX:ObjectAlignmentInBytes=" + alignment, "-version"); From ac42104fef46f3d20133383985fea56247768156 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Mon, 12 Aug 2013 19:57:21 +0400 Subject: [PATCH 0080/1294] 8021275: Better screening for ScreenMenu Reviewed-by: art --- .../classes/com/apple/laf/ScreenMenu.java | 144 +++++++++--------- 1 file changed, 75 insertions(+), 69 deletions(-) diff --git a/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java b/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java index 5f78ff6e061..87393408487 100644 --- a/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java +++ b/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java @@ -36,7 +36,10 @@ import sun.awt.SunToolkit; import sun.lwawt.LWToolkit; import sun.lwawt.macosx.*; -class ScreenMenu extends Menu implements ContainerListener, ComponentListener, ScreenMenuPropertyHandler { +final class ScreenMenu extends Menu + implements ContainerListener, ComponentListener, + ScreenMenuPropertyHandler { + static { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { @@ -48,20 +51,22 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S } // screen menu stuff - public static native long addMenuListeners(ScreenMenu listener, long nativeMenu); - public static native void removeMenuListeners(long modelPtr); + private static native long addMenuListeners(ScreenMenu listener, long nativeMenu); + private static native void removeMenuListeners(long modelPtr); - long fModelPtr = 0; + private transient long fModelPtr; - Hashtable fItems; - JMenu fInvoker; + private final Hashtable fItems; + private final JMenu fInvoker; - Component fLastMouseEventTarget; - Rectangle fLastTargetRect; + private Component fLastMouseEventTarget; + private Rectangle fLastTargetRect; private volatile Rectangle[] fItemBounds; + private ScreenMenuPropertyListener fPropertyListener; + // Array of child hashes used to see if we need to recreate the Menu. - int childHashArray[]; + private int childHashArray[]; ScreenMenu(final JMenu invoker) { super(invoker.getText()); @@ -74,25 +79,12 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S updateItems(); } - // I'm always 'visible', but never on screen - static class ScreenMenuComponent extends Container { - public boolean isVisible() { return true; } - public boolean isShowing() { return true; } - public void setVisible(final boolean b) {} - public void show() {} - } - - ScreenMenuComponent makeScreenMenuComponent() { - return new ScreenMenuComponent(); - } - - /** * Determine if we need to tear down the Menu and re-create it, since the contents may have changed in the Menu opened listener and * we do not get notified of it, because EDT is busy in our code. We only need to update if the menu contents have changed in some * way, such as the number of menu items, the text of the menuitems, icon, shortcut etc. */ - static boolean needsUpdate(final Component items[], final int childHashArray[]) { + private static boolean needsUpdate(final Component items[], final int childHashArray[]) { if (items == null || childHashArray == null) { return true; } @@ -112,7 +104,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S * Used to recreate the AWT based Menu structure that implements the Screen Menu. * Also computes hashcode and stores them so that we can compare them later in needsUpdate. */ - void updateItems() { + private void updateItems() { final int count = fInvoker.getMenuComponentCount(); final Component[] items = fInvoker.getMenuComponents(); if (needsUpdate(items, childHashArray)) { @@ -163,16 +155,14 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S LWCToolkit.invokeAndWait(new Runnable() { public void run() { invoker.setSelected(false); - - // Null out the tracking rectangles and the array. + // Null out the tracking rectangles and the array. if (fItemBounds != null) { - for (int i = 0; i < fItemBounds.length; i++) { - fItemBounds[i] = null; - } + for (int i = 0; i < fItemBounds.length; i++) { + fItemBounds[i] = null; + } } - - fItemBounds = null; - } + fItemBounds = null; + } }, invoker); } catch (final Exception e) { e.printStackTrace(); @@ -237,49 +227,56 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S }); } - ScreenMenuPropertyListener fPropertyListener; + @Override public void addNotify() { - super.addNotify(); - if (fModelPtr == 0) { - fInvoker.addContainerListener(this); - fInvoker.addComponentListener(this); - fPropertyListener = new ScreenMenuPropertyListener(this); - fInvoker.addPropertyChangeListener(fPropertyListener); + synchronized (getTreeLock()) { + super.addNotify(); + if (fModelPtr == 0) { + fInvoker.addContainerListener(this); + fInvoker.addComponentListener(this); + fPropertyListener = new ScreenMenuPropertyListener(this); + fInvoker.addPropertyChangeListener(fPropertyListener); - final Icon icon = fInvoker.getIcon(); - if (icon != null) { - this.setIcon(icon); - } + final Icon icon = fInvoker.getIcon(); + if (icon != null) { + setIcon(icon); + } - final String tooltipText = fInvoker.getToolTipText(); - if (tooltipText != null) { - this.setToolTipText(tooltipText); - } - final MenuComponentPeer peer = getPeer(); - if (peer instanceof CMenu) { - final CMenu menu = (CMenu)peer; - final long nativeMenu = menu.getNativeMenu(); - fModelPtr = addMenuListeners(this, nativeMenu); + final String tooltipText = fInvoker.getToolTipText(); + if (tooltipText != null) { + setToolTipText(tooltipText); + } + final MenuComponentPeer peer = getPeer(); + if (peer instanceof CMenu) { + final CMenu menu = (CMenu) peer; + final long nativeMenu = menu.getNativeMenu(); + fModelPtr = addMenuListeners(this, nativeMenu); + } } } } + @Override public void removeNotify() { - // Call super so that the NSMenu has been removed, before we release the delegate in removeMenuListeners - super.removeNotify(); - fItems.clear(); - if (fModelPtr != 0) { - removeMenuListeners(fModelPtr); - fModelPtr = 0; - fInvoker.removeContainerListener(this); - fInvoker.removeComponentListener(this); - fInvoker.removePropertyChangeListener(fPropertyListener); + synchronized (getTreeLock()) { + // Call super so that the NSMenu has been removed, before we release + // the delegate in removeMenuListeners + super.removeNotify(); + fItems.clear(); + if (fModelPtr != 0) { + removeMenuListeners(fModelPtr); + fModelPtr = 0; + fInvoker.removeContainerListener(this); + fInvoker.removeComponentListener(this); + fInvoker.removePropertyChangeListener(fPropertyListener); + } } } /** * Invoked when a component has been added to the container. */ + @Override public void componentAdded(final ContainerEvent e) { addItem(e.getChild()); } @@ -287,23 +284,26 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S /** * Invoked when a component has been removed from the container. */ + @Override public void componentRemoved(final ContainerEvent e) { final Component child = e.getChild(); final MenuItem sm = fItems.get(child); if (sm == null) return; - remove(sm); - fItems.remove(sm); - } + remove(sm); + fItems.remove(sm); + } /** * Invoked when the component's size changes. */ + @Override public void componentResized(final ComponentEvent e) {} /** * Invoked when the component's position changes. */ + @Override public void componentMoved(final ComponentEvent e) {} /** @@ -311,6 +311,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S * See componentHidden - we should still have a MenuItem * it just isn't inserted */ + @Override public void componentShown(final ComponentEvent e) { setVisible(true); } @@ -321,11 +322,12 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S * so we remove the ScreenMenuItem from the ScreenMenu * but leave it in fItems */ + @Override public void componentHidden(final ComponentEvent e) { setVisible(false); } - public void setVisible(final boolean b) { + private void setVisible(final boolean b) { // Tell our parent to add/remove us final MenuContainer parent = getParent(); @@ -333,20 +335,24 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S if (parent instanceof ScreenMenu) { final ScreenMenu sm = (ScreenMenu)parent; sm.setChildVisible(fInvoker, b); - } + } } } + @Override public void setChildVisible(final JMenuItem child, final boolean b) { fItems.remove(child); updateItems(); } + @Override public void setAccelerator(final KeyStroke ks) {} // only check and radio items can be indeterminate + @Override public void setIndeterminate(boolean indeterminate) { } + @Override public void setToolTipText(final String text) { final MenuComponentPeer peer = getPeer(); if (!(peer instanceof CMenuItem)) return; @@ -355,6 +361,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S cmi.setToolTipText(text); } + @Override public void setIcon(final Icon i) { final MenuComponentPeer peer = getPeer(); if (!(peer instanceof CMenuItem)) return; @@ -374,9 +381,8 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S /** * Gets a hashCode for a JMenu or JMenuItem or subclass so that we can compare for * changes in the Menu. - * */ - static int getHashCode(final Component m) { + private static int getHashCode(final Component m) { int hashCode = m.hashCode(); if (m instanceof JMenuItem) { @@ -408,7 +414,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S return hashCode; } - void addItem(final Component m) { + private void addItem(final Component m) { if (!m.isVisible()) return; MenuItem sm = fItems.get(m); From 53b5f75095fbfdc11d0816de508bdde491844095 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Mon, 12 Aug 2013 13:47:21 -0700 Subject: [PATCH 0081/1294] 8022066: Evaluation of method reference to signature polymorphic method crashes VM Reviewed-by: jrose --- .../java/lang/invoke/MethodHandles.java | 4 + .../lang/invoke/MethodHandleConstants.java | 188 ++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 jdk/test/java/lang/invoke/MethodHandleConstants.java diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index 8a435d06fca..2ee21d667c0 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -1289,6 +1289,10 @@ return mh1; : resolveOrFail(refKind, defc, name, (Class) type); return getDirectField(refKind, defc, field); } else if (MethodHandleNatives.refKindIsMethod(refKind)) { + if (defc == MethodHandle.class && refKind == REF_invokeVirtual) { + MethodHandle mh = findVirtualForMH(name, (MethodType) type); + if (mh != null) return mh; + } MemberName method = (resolved != null) ? resolved : resolveOrFail(refKind, defc, name, (MethodType) type); return getDirectMethod(refKind, defc, method, lookupClass); diff --git a/jdk/test/java/lang/invoke/MethodHandleConstants.java b/jdk/test/java/lang/invoke/MethodHandleConstants.java new file mode 100644 index 00000000000..57e041ba7bb --- /dev/null +++ b/jdk/test/java/lang/invoke/MethodHandleConstants.java @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2010, 2013, 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 8022066 + * @summary smoke test for method handle constants + * @build indify.Indify + * @compile MethodHandleConstants.java + * @run main/othervm + * indify.Indify + * --verify-specifier-count=0 + * --expand-properties --classpath ${test.classes} + * --java test.java.lang.invoke.MethodHandleConstants --check-output + * @run main/othervm + * indify.Indify + * --expand-properties --classpath ${test.classes} + * --java test.java.lang.invoke.MethodHandleConstants --security-manager + */ + +package test.java.lang.invoke; + +import java.util.*; +import java.io.*; +import java.lang.invoke.*; +import java.security.*; + +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; + +public class MethodHandleConstants { + public static void main(String... av) throws Throwable { + if (av.length > 0 && av[0].equals("--check-output")) openBuf(); + if (av.length > 0 && av[0].equals("--security-manager")) setSM(); + System.out.println("Obtaining method handle constants:"); + testCase(MH_String_replace_C2(), String.class, "replace", String.class, String.class, char.class, char.class); + testCase(MH_MethodHandle_invokeExact_SC2(), MethodHandle.class, "invokeExact", String.class, MethodHandle.class, String.class, char.class, char.class); + testCase(MH_MethodHandle_invoke_SC2(), MethodHandle.class, "invoke", String.class, MethodHandle.class, String.class, char.class, char.class); + testCase(MH_Class_forName_S(), Class.class, "forName", Class.class, String.class); + testCase(MH_Class_forName_SbCL(), Class.class, "forName", Class.class, String.class, boolean.class, ClassLoader.class); + System.out.println("Done."); + closeBuf(); + } + + private static void testCase(MethodHandle mh, Class defc, String name, Class rtype, Class... ptypes) throws Throwable { + System.out.println(mh); + // we include defc, because we assume it is a non-static MH: + MethodType mt = methodType(rtype, ptypes); + assertEquals(mh.type(), mt); + // FIXME: Use revealDirect to find out more + } + private static void assertEquals(Object exp, Object act) { + if (exp == act || (exp != null && exp.equals(act))) return; + throw new AssertionError("not equal: "+exp+", "+act); + } + + private static void setSM() { + Policy.setPolicy(new TestPolicy()); + System.setSecurityManager(new SecurityManager()); + } + + private static PrintStream oldOut; + private static ByteArrayOutputStream buf; + private static void openBuf() { + oldOut = System.out; + buf = new ByteArrayOutputStream(); + System.setOut(new PrintStream(buf)); + } + private static void closeBuf() { + if (buf == null) return; + System.out.flush(); + System.setOut(oldOut); + String[] haveLines = new String(buf.toByteArray()).split("[\n\r]+"); + for (String line : haveLines) System.out.println(line); + Iterator iter = Arrays.asList(haveLines).iterator(); + for (String want : EXPECT_OUTPUT) { + String have = iter.hasNext() ? iter.next() : "[EOF]"; + if (want.equals(have)) continue; + System.err.println("want line: "+want); + System.err.println("have line: "+have); + throw new AssertionError("unexpected output: "+have); + } + if (iter.hasNext()) + throw new AssertionError("unexpected output: "+iter.next()); + } + private static final String[] EXPECT_OUTPUT = { + "Obtaining method handle constants:", + "MethodHandle(String,char,char)String", + "MethodHandle(MethodHandle,String,char,char)String", + "MethodHandle(MethodHandle,String,char,char)String", + "MethodHandle(String)Class", + "MethodHandle(String,boolean,ClassLoader)Class", + "Done." + }; + + // String.replace(String, char, char) + private static MethodType MT_String_replace_C2() { + shouldNotCallThis(); + return methodType(String.class, char.class, char.class); + } + private static MethodHandle MH_String_replace_C2() throws ReflectiveOperationException { + shouldNotCallThis(); + return lookup().findVirtual(String.class, "replace", MT_String_replace_C2()); + } + + // MethodHandle.invokeExact(...) + private static MethodType MT_MethodHandle_invokeExact_SC2() { + shouldNotCallThis(); + return methodType(String.class, String.class, char.class, char.class); + } + private static MethodHandle MH_MethodHandle_invokeExact_SC2() throws ReflectiveOperationException { + shouldNotCallThis(); + return lookup().findVirtual(MethodHandle.class, "invokeExact", MT_MethodHandle_invokeExact_SC2()); + } + + // MethodHandle.invoke(...) + private static MethodType MT_MethodHandle_invoke_SC2() { + shouldNotCallThis(); + return methodType(String.class, String.class, char.class, char.class); + } + private static MethodHandle MH_MethodHandle_invoke_SC2() throws ReflectiveOperationException { + shouldNotCallThis(); + return lookup().findVirtual(MethodHandle.class, "invoke", MT_MethodHandle_invoke_SC2()); + } + + // Class.forName(String) + private static MethodType MT_Class_forName_S() { + shouldNotCallThis(); + return methodType(Class.class, String.class); + } + private static MethodHandle MH_Class_forName_S() throws ReflectiveOperationException { + shouldNotCallThis(); + return lookup().findStatic(Class.class, "forName", MT_Class_forName_S()); + } + + // Class.forName(String, boolean, ClassLoader) + private static MethodType MT_Class_forName_SbCL() { + shouldNotCallThis(); + return methodType(Class.class, String.class, boolean.class, ClassLoader.class); + } + private static MethodHandle MH_Class_forName_SbCL() throws ReflectiveOperationException { + shouldNotCallThis(); + return lookup().findStatic(Class.class, "forName", MT_Class_forName_SbCL()); + } + + private static void shouldNotCallThis() { + // if this gets called, the transformation has not taken place + if (System.getProperty("MethodHandleConstants.allow-untransformed") != null) return; + throw new AssertionError("this code should be statically transformed away by Indify"); + } + + static class TestPolicy extends Policy { + final PermissionCollection permissions = new Permissions(); + TestPolicy() { + permissions.add(new java.io.FilePermission("<>", "read")); + } + public PermissionCollection getPermissions(ProtectionDomain domain) { + return permissions; + } + + public PermissionCollection getPermissions(CodeSource codesource) { + return permissions; + } + + public boolean implies(ProtectionDomain domain, Permission perm) { + return permissions.implies(perm); + } + } +} From 73aa07b6c5c56bc747c0ff14ac13ff3fdea70b39 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Wed, 14 Aug 2013 10:17:57 -0700 Subject: [PATCH 0082/1294] 8021355: REGRESSION: Five closed/java/awt/SplashScreen tests fail since 7u45 b01 on Linux, Solaris Reviewed-by: dholmes, anthony, ahgross, erikj --- jdk/src/solaris/bin/java_md_solinux.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/jdk/src/solaris/bin/java_md_solinux.c b/jdk/src/solaris/bin/java_md_solinux.c index b0028bde78d..05a5b3e34d8 100644 --- a/jdk/src/solaris/bin/java_md_solinux.c +++ b/jdk/src/solaris/bin/java_md_solinux.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -958,9 +958,27 @@ static void* hSplashLib = NULL; void* SplashProcAddress(const char* name) { if (!hSplashLib) { - const char * splashLibPath; - splashLibPath = SPLASHSCREEN_SO; - hSplashLib = dlopen(splashLibPath, RTLD_LAZY | RTLD_GLOBAL); + int ret; + char jrePath[MAXPATHLEN]; + char splashPath[MAXPATHLEN]; + + if (!GetJREPath(jrePath, sizeof(jrePath), GetArch(), JNI_FALSE)) { + JLI_ReportErrorMessage(JRE_ERROR1); + return NULL; + } + ret = JLI_Snprintf(splashPath, sizeof(splashPath), "%s/lib/%s/%s", + jrePath, GetArch(), SPLASHSCREEN_SO); + + if (ret >= (int) sizeof(splashPath)) { + JLI_ReportErrorMessage(JRE_ERROR11); + return NULL; + } + if (ret < 0) { + JLI_ReportErrorMessage(JRE_ERROR13); + return NULL; + } + hSplashLib = dlopen(splashPath, RTLD_LAZY | RTLD_GLOBAL); + JLI_TraceLauncher("Info: loaded %s\n", splashPath); } if (hSplashLib) { void* sym = dlsym(hSplashLib, name); From 9b8991f944b3a1e10a073ab4b26ef3dd32511191 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 14 Aug 2013 15:25:16 +0800 Subject: [PATCH 0083/1294] 8022931: Enhance Kerberos exceptions Reviewed-by: xuelei, ahgross --- .../javax/security/auth/kerberos/KeyTab.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java b/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java index 631b7d02275..db815395e3a 100644 --- a/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java +++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java @@ -26,6 +26,7 @@ package javax.security.auth.kerberos; import java.io.File; +import java.security.AccessControlException; import java.util.Objects; import sun.security.krb5.EncryptionKey; import sun.security.krb5.KerberosSecrets; @@ -214,9 +215,22 @@ public final class KeyTab { return new KeyTab(princ, null, true); } - //Takes a snapshot of the keytab content + // Takes a snapshot of the keytab content. This method is called by + // JavaxSecurityAuthKerberosAccessImpl so no more private sun.security.krb5.internal.ktab.KeyTab takeSnapshot() { - return sun.security.krb5.internal.ktab.KeyTab.getInstance(file); + try { + return sun.security.krb5.internal.ktab.KeyTab.getInstance(file); + } catch (AccessControlException ace) { + if (file != null) { + // It's OK to show the name if caller specified it + throw ace; + } else { + AccessControlException ace2 = new AccessControlException( + "Access to default keytab denied (modified exception)"); + ace2.setStackTrace(ace.getStackTrace()); + throw ace2; + } + } } /** From 73ddb82395f11287b3e46abef29c720d1c98b958 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 19 Aug 2013 12:30:48 +0200 Subject: [PATCH 0084/1294] 8022719: tools/launcher/RunpathTest.java fails after 8012146 Reviewed-by: chegar --- jdk/test/tools/launcher/RunpathTest.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/jdk/test/tools/launcher/RunpathTest.java b/jdk/test/tools/launcher/RunpathTest.java index 631be16d975..675d7630dbe 100644 --- a/jdk/test/tools/launcher/RunpathTest.java +++ b/jdk/test/tools/launcher/RunpathTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 7190813 + * @bug 7190813, 8022719 * @summary Check for extended RPATHs on *nixes * @compile -XDignore.symbol.file RunpathTest.java * @run main RunpathTest @@ -65,12 +65,10 @@ public class RunpathTest extends TestHelper { void testRpath() { if (isDualMode && is64Bit) { - String expectedRpath = ".*RPATH.*\\$ORIGIN/../../lib/" + getJreArch() - + ":\\$ORIGIN/../../jre/lib/" + getJreArch() + ".*"; + String expectedRpath = ".*RPATH.*\\$ORIGIN/../../lib/" + getJreArch() + ".*"; elfCheck(java64Cmd, expectedRpath); } else { - String expectedRpath = ".*RPATH.*\\$ORIGIN/../lib/" + getJreArch() - + ":\\$ORIGIN/../jre/lib/" + getJreArch() + ".*"; + String expectedRpath = ".*RPATH.*\\$ORIGIN/../lib/" + getJreArch() + ".*"; elfCheck(javaCmd, expectedRpath); } } From c130ed36602208230609811e52c78c5fe58a784c Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 19 Aug 2013 14:48:08 +0200 Subject: [PATCH 0085/1294] 8023231: Remove comma from jtreg bug line Reviewed-by: alanb, chegar --- jdk/test/tools/launcher/RunpathTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/tools/launcher/RunpathTest.java b/jdk/test/tools/launcher/RunpathTest.java index 675d7630dbe..79b8b0ecca7 100644 --- a/jdk/test/tools/launcher/RunpathTest.java +++ b/jdk/test/tools/launcher/RunpathTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 7190813, 8022719 + * @bug 7190813 8022719 * @summary Check for extended RPATHs on *nixes * @compile -XDignore.symbol.file RunpathTest.java * @run main RunpathTest From 49058214db19c8fa61461a60b97b77e3d2ab3fbe Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Mon, 19 Aug 2013 15:22:59 +0100 Subject: [PATCH 0086/1294] 8022940: Enhance CORBA translations Reviewed-by: coffeys, alanb, skoivu --- .../rmi/IDLNameTranslatorImpl.java | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/IDLNameTranslatorImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/IDLNameTranslatorImpl.java index dfe6581cc11..86a47992a72 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/IDLNameTranslatorImpl.java +++ b/corba/src/share/classes/com/sun/corba/se/impl/presentation/rmi/IDLNameTranslatorImpl.java @@ -905,28 +905,4 @@ public class IDLNameTranslatorImpl implements IDLNameTranslator { return contents.toString(); } - - public static void main(String[] args) { - - Class remoteInterface = java.rmi.Remote.class; - - if( args.length > 0 ) { - String className = args[0]; - try { - remoteInterface = Class.forName(className); - } catch(Exception e) { - e.printStackTrace(); - System.exit(-1); - } - } - - System.out.println("Building name translation for " + remoteInterface); - try { - IDLNameTranslator nameTranslator = - IDLNameTranslatorImpl.get(remoteInterface); - System.out.println(nameTranslator); - } catch(IllegalStateException ise) { - ise.printStackTrace(); - } - } } From 1b5eaa621e907e871ba0637cb7510ae7795f94de Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 19 Aug 2013 17:47:21 +0200 Subject: [PATCH 0087/1294] 8015614: Update build settings Reviewed-by: tbell, dholmes, ahgross --- hotspot/make/windows/makefiles/compile.make | 9 +++++++-- hotspot/make/windows/makefiles/sa.make | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/hotspot/make/windows/makefiles/compile.make b/hotspot/make/windows/makefiles/compile.make index 6f8dcce3406..93454d75399 100644 --- a/hotspot/make/windows/makefiles/compile.make +++ b/hotspot/make/windows/makefiles/compile.make @@ -180,6 +180,7 @@ DEBUG_OPT_OPTION = /Od PRODUCT_OPT_OPTION = /O2 /Oy- FASTDEBUG_OPT_OPTION = /O2 /Oy- DEBUG_OPT_OPTION = /Od +SAFESEH_FLAG = /SAFESEH !endif !if "$(COMPILER_NAME)" == "VS2005" @@ -198,6 +199,7 @@ LD_FLAGS = /manifest $(LD_FLAGS) $(BUFFEROVERFLOWLIB) !if "x$(MT)" == "x" MT=mt.exe !endif +SAFESEH_FLAG = /SAFESEH !endif !if "$(COMPILER_NAME)" == "VS2008" @@ -211,6 +213,7 @@ LD_FLAGS = /manifest $(LD_FLAGS) !if "x$(MT)" == "x" MT=mt.exe !endif +SAFESEH_FLAG = /SAFESEH !endif !if "$(COMPILER_NAME)" == "VS2010" @@ -240,9 +243,11 @@ LD_FLAGS = /manifest $(LD_FLAGS) !if "x$(MT)" == "x" MT=mt.exe !endif -!if "$(BUILDARCH)" == "i486" -LD_FLAGS = /SAFESEH $(LD_FLAGS) +SAFESEH_FLAG = /SAFESEH !endif + +!if "$(BUILDARCH)" == "i486" +LD_FLAGS = $(SAFESEH_FLAG) $(LD_FLAGS) !endif # If NO_OPTIMIZATIONS is defined in the environment, turn everything off diff --git a/hotspot/make/windows/makefiles/sa.make b/hotspot/make/windows/makefiles/sa.make index 9363f0e5e6f..356c4fd6b50 100644 --- a/hotspot/make/windows/makefiles/sa.make +++ b/hotspot/make/windows/makefiles/sa.make @@ -107,6 +107,9 @@ SA_LFLAGS = $(SA_LD_FLAGS) -nologo -subsystem:console -machine:$(MACHINE) !if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" SA_LFLAGS = $(SA_LFLAGS) -map -debug !endif +!if "$(BUILDARCH)" == "i486" +SA_LFLAGS = $(SAFESEH_FLAG) $(SA_LFLAGS) +!endif # Note that we do not keep sawindbj.obj around as it would then # get included in the dumpbin command in build_vm_def.sh From 6ef251ac19d069528159ccc911b82f043e636300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rickard=20B=C3=A4ckman?= Date: Tue, 20 Aug 2013 09:37:01 +0200 Subject: [PATCH 0088/1294] 8022283: Assertion failed: assert(is_loaded() && field->holder()->is_loaded() && klass()->is_subclass_of (field->holder())) failed: invalid access Reviewed-by: roland, twisti --- hotspot/src/share/vm/c1/c1_GraphBuilder.cpp | 2 +- hotspot/src/share/vm/ci/ciInstance.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index 1d0b9243de2..b7ea6eebb26 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -1583,7 +1583,7 @@ void GraphBuilder::access_field(Bytecodes::Code code) { ObjectType* obj_type = obj->type()->as_ObjectType(); if (obj_type->is_constant() && !PatchALot) { ciObject* const_oop = obj_type->constant_value(); - if (!const_oop->is_null_object()) { + if (!const_oop->is_null_object() && const_oop->is_loaded()) { if (field->is_constant()) { ciConstant field_val = field->constant_value_of(const_oop); BasicType field_type = field_val.basic_type(); diff --git a/hotspot/src/share/vm/ci/ciInstance.cpp b/hotspot/src/share/vm/ci/ciInstance.cpp index 2d29c0dc8e2..a74eb04f4a7 100644 --- a/hotspot/src/share/vm/ci/ciInstance.cpp +++ b/hotspot/src/share/vm/ci/ciInstance.cpp @@ -60,10 +60,10 @@ ciType* ciInstance::java_mirror_type() { // // Constant value of a field. ciConstant ciInstance::field_value(ciField* field) { - assert(is_loaded() && - field->holder()->is_loaded() && - klass()->is_subclass_of(field->holder()), - "invalid access"); + assert(is_loaded(), "invalid access - must be loaded"); + assert(field->holder()->is_loaded(), "invalid access - holder must be loaded"); + assert(klass()->is_subclass_of(field->holder()), "invalid access - must be subclass"); + VM_ENTRY_MARK; ciConstant result; Handle obj = get_oop(); From b3505de64053a05578292514fec3477980b90e8a Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Tue, 20 Aug 2013 09:02:25 -0700 Subject: [PATCH 0089/1294] 8022682: Supporting XOM Reviewed-by: alanb, chegar, lancea --- .../xerces/internal/impl/PropertyManager.java | 19 ++ .../jaxp/validation/XMLSchemaFactory.java | 10 +- .../xerces/internal/parsers/DOMParser.java | 48 ++++ .../internal/parsers/DTDConfiguration.java | 11 +- .../parsers/NonValidatingConfiguration.java | 11 +- .../xerces/internal/parsers/SAXParser.java | 40 +++- .../internal/parsers/XML11Configuration.java | 4 - .../xerces/internal/parsers/XMLParser.java | 18 ++ .../xerces/internal/util/SecurityManager.java | 215 ++++++++++++++++++ .../internal/utils/XMLLimitAnalyzer.java | 3 + .../internal/utils/XMLSecurityManager.java | 34 +++ 11 files changed, 395 insertions(+), 18 deletions(-) create mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java index 8fbf9162409..2c8f3aff2c2 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java @@ -178,6 +178,25 @@ public class PropertyManager { supportedProps.put( Constants.XERCES_PROPERTY_PREFIX + Constants.STAX_ENTITY_RESOLVER_PROPERTY , new StaxEntityResolverWrapper((XMLResolver)value)) ; } + /** + * It's possible for users to set a security manager through the interface. + * If it's the old SecurityManager, convert it to the new XMLSecurityManager + */ + if (property.equals(Constants.SECURITY_MANAGER)) { + fSecurityManager = XMLSecurityManager.convert(value, fSecurityManager); + supportedProps.put(Constants.SECURITY_MANAGER, fSecurityManager); + return; + } + if (property.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) { + if (value == null) { + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + } else { + fSecurityPropertyMgr = (XMLSecurityPropertyManager)value; + } + supportedProps.put(Constants.XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + return; + } + //check if the property is managed by security manager if (fSecurityManager == null || !fSecurityManager.setLimit(property, XMLSecurityManager.State.APIPROPERTY, value)) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java index 34eba4c4791..f2dadd0fc4a 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java @@ -408,9 +408,17 @@ public final class XMLSchemaFactory extends SchemaFactory { "ProperyNameNull", null)); } if (name.equals(SECURITY_MANAGER)) { - fSecurityManager = (XMLSecurityManager) object; + fSecurityManager = XMLSecurityManager.convert(object, fSecurityManager); fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); return; + } else if (name.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) { + if (object == null) { + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + } else { + fSecurityPropertyMgr = (XMLSecurityPropertyManager)object; + } + fXMLSchemaLoader.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + return; } else if (name.equals(XMLGRAMMAR_POOL)) { throw new SAXNotSupportedException( diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java index f681fadbd33..f2020efda4b 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java @@ -29,6 +29,7 @@ import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; @@ -531,7 +532,54 @@ public class DOMParser */ public void setProperty(String propertyId, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { + /** + * It's possible for users to set a security manager through the interface. + * If it's the old SecurityManager, convert it to the new XMLSecurityManager + */ + if (propertyId.equals(Constants.SECURITY_MANAGER)) { + securityManager = XMLSecurityManager.convert(value, securityManager); + setProperty0(Constants.SECURITY_MANAGER, securityManager); + return; + } + if (propertyId.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) { + if (value == null) { + securityPropertyManager = new XMLSecurityPropertyManager(); + } else { + securityPropertyManager = (XMLSecurityPropertyManager)value; + } + setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); + return; + } + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + setProperty0(Constants.SECURITY_MANAGER, securityManager); + } + + if (securityPropertyManager == null) { + securityPropertyManager = new XMLSecurityPropertyManager(); + setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); + } + int index = securityPropertyManager.getIndex(propertyId); + + if (index > -1) { + /** + * this is a direct call to this parser, not a subclass since + * internally the support of this property is done through + * XMLSecurityPropertyManager + */ + securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); + } else { + //check if the property is managed by security manager + if (!securityManager.setLimit(propertyId, XMLSecurityManager.State.APIPROPERTY, value)) { + //fall back to the default configuration to handle the property + setProperty0(propertyId, value); + } + } + } + + public void setProperty0(String propertyId, Object value) + throws SAXNotRecognizedException, SAXNotSupportedException { try { fConfiguration.setProperty(propertyId, value); } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java index 0cdfd654b78..838dd9f5ec4 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java @@ -184,6 +184,13 @@ public class DTDConfiguration protected static final String LOCALE = Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + /** Property identifier: Security property manager. */ + protected static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; + // debugging /** Set to true and recompile to print exception stack trace. */ @@ -328,7 +335,9 @@ public class DTDConfiguration VALIDATION_MANAGER, JAXP_SCHEMA_SOURCE, JAXP_SCHEMA_LANGUAGE, - LOCALE + LOCALE, + SECURITY_MANAGER, + XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java index 55339157c90..fb81834fce9 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java @@ -157,6 +157,13 @@ public class NonValidatingConfiguration protected static final String LOCALE = Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + /** Property identifier: Security property manager. */ + protected static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + + /** Property identifier: Security manager. */ + private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; + // debugging /** Set to true and recompile to print exception stack trace. */ @@ -310,7 +317,9 @@ public class NonValidatingConfiguration XMLGRAMMAR_POOL, DATATYPE_VALIDATOR_FACTORY, VALIDATION_MANAGER, - LOCALE + LOCALE, + SECURITY_MANAGER, + XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java index 8432b54541e..48b8a1ed538 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java @@ -77,8 +77,7 @@ public class SAXParser XMLGRAMMAR_POOL, }; - XMLSecurityManager securityManager; - XMLSecurityPropertyManager securityPropertyManager; + // // Constructors // @@ -132,9 +131,35 @@ public class SAXParser */ public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { + /** + * It's possible for users to set a security manager through the interface. + * If it's the old SecurityManager, convert it to the new XMLSecurityManager + */ + if (name.equals(Constants.SECURITY_MANAGER)) { + securityManager = XMLSecurityManager.convert(value, securityManager); + super.setProperty(Constants.SECURITY_MANAGER, securityManager); + return; + } + if (name.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) { + if (value == null) { + securityPropertyManager = new XMLSecurityPropertyManager(); + } else { + securityPropertyManager = (XMLSecurityPropertyManager)value; + } + super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); + return; + } + + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + super.setProperty(Constants.SECURITY_MANAGER, securityManager); + } + if (securityPropertyManager == null) { securityPropertyManager = new XMLSecurityPropertyManager(); + super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); } + int index = securityPropertyManager.getIndex(name); if (index > -1) { /** @@ -143,19 +168,12 @@ public class SAXParser * XMLSecurityPropertyManager */ securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); - super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); } else { - if (securityManager == null) { - securityManager = new XMLSecurityManager(true); - } - //check if the property is managed by security manager - if (securityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) { - super.setProperty(Constants.SECURITY_MANAGER, securityManager); - } else { + if (!securityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) { + //fall back to the default configuration to handle the property super.setProperty(name, value); } - } } } // class SAXParser diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java index 3f22807e37e..bbcbceed10e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java @@ -583,10 +583,6 @@ public class XML11Configuration extends ParserConfigurationSettings fVersionDetector = new XMLVersionDetector(); - fProperties.put(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager()); - - fProperties.put(SECURITY_MANAGER, new XMLSecurityManager(true)); - // add message formatters if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { XMLMessageFormatter xmft = new XMLMessageFormatter(); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XMLParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XMLParser.java index 210b7ce9cc6..970cc51cd26 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XMLParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XMLParser.java @@ -23,6 +23,8 @@ package com.sun.org.apache.xerces.internal.parsers; import java.io.IOException; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; @@ -78,6 +80,13 @@ public abstract class XMLParser { /** The parser configuration. */ protected XMLParserConfiguration fConfiguration; + /** The XML Security Manager. */ + XMLSecurityManager securityManager; + + /** The XML Security Property Manager. */ + XMLSecurityPropertyManager securityPropertyManager; + + // // Constructors // @@ -118,6 +127,15 @@ public abstract class XMLParser { */ public void parse(XMLInputSource inputSource) throws XNIException, IOException { + // null indicates that the parser is called directly, initialize them + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + fConfiguration.setProperty(Constants.SECURITY_MANAGER, securityManager); + } + if (securityPropertyManager == null) { + securityPropertyManager = new XMLSecurityPropertyManager(); + fConfiguration.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); + } reset(); fConfiguration.parse(inputSource); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java new file mode 100644 index 00000000000..d916f5bc516 --- /dev/null +++ b/jaxp/src/com/sun/org/apache/xerces/internal/util/SecurityManager.java @@ -0,0 +1,215 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * The Apache Software License, Version 1.1 + * + * + * Copyright (c) 2003 The Apache Software Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Xerces" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation and was + * originally based on software copyright (c) 1999, International + * Business Machines, Inc., http://www.apache.org. For more + * information on the Apache Software Foundation, please see + * . + */ + +package com.sun.org.apache.xerces.internal.util; +import com.sun.org.apache.xerces.internal.impl.Constants; +/** + * This class is a container for parser settings that relate to + * security, or more specifically, it is intended to be used to prevent denial-of-service + * attacks from being launched against a system running Xerces. + * Any component that is aware of a denial-of-service attack that can arise + * from its processing of a certain kind of document may query its Component Manager + * for the property (http://apache.org/xml/properties/security-manager) + * whose value will be an instance of this class. + * If no value has been set for the property, the component should proceed in the "usual" (spec-compliant) + * manner. If a value has been set, then it must be the case that the component in + * question needs to know what method of this class to query. This class + * will provide defaults for all known security issues, but will also provide + * setters so that those values can be tailored by applications that care. + * + * @author Neil Graham, IBM + * + */ +public final class SecurityManager { + + // + // Constants + // + + // default value for entity expansion limit + private final static int DEFAULT_ENTITY_EXPANSION_LIMIT = 64000; + + /** Default value of number of nodes created. **/ + private final static int DEFAULT_MAX_OCCUR_NODE_LIMIT = 5000; + + // + // Data + // + + private final static int DEFAULT_ELEMENT_ATTRIBUTE_LIMIT = 10000; + + /** Entity expansion limit. **/ + private int entityExpansionLimit; + + /** W3C XML Schema maxOccurs limit. **/ + private int maxOccurLimit; + + private int fElementAttributeLimit; + // default constructor. Establishes default values for + // all known security holes. + /** + * Default constructor. Establishes default values + * for known security vulnerabilities. + */ + public SecurityManager() { + entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; + maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT ; + fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; + //We are reading system properties only once , + //at the time of creation of this object , + readSystemProperties(); + } + + /** + *

    Sets the number of entity expansions that the + * parser should permit in a document.

    + * + * @param limit the number of entity expansions + * permitted in a document + */ + public void setEntityExpansionLimit(int limit) { + entityExpansionLimit = limit; + } + + /** + *

    Returns the number of entity expansions + * that the parser permits in a document.

    + * + * @return the number of entity expansions + * permitted in a document + */ + public int getEntityExpansionLimit() { + return entityExpansionLimit; + } + + /** + *

    Sets the limit of the number of content model nodes + * that may be created when building a grammar for a W3C + * XML Schema that contains maxOccurs attributes with values + * other than "unbounded".

    + * + * @param limit the maximum value for maxOccurs other + * than "unbounded" + */ + public void setMaxOccurNodeLimit(int limit){ + maxOccurLimit = limit; + } + + /** + *

    Returns the limit of the number of content model nodes + * that may be created when building a grammar for a W3C + * XML Schema that contains maxOccurs attributes with values + * other than "unbounded".

    + * + * @return the maximum value for maxOccurs other + * than "unbounded" + */ + public int getMaxOccurNodeLimit(){ + return maxOccurLimit; + } + + public int getElementAttrLimit(){ + return fElementAttributeLimit; + } + + public void setElementAttrLimit(int limit){ + fElementAttributeLimit = limit; + } + + private void readSystemProperties(){ + + try { + String value = System.getProperty(Constants.ENTITY_EXPANSION_LIMIT); + if(value != null && !value.equals("")){ + entityExpansionLimit = Integer.parseInt(value); + if (entityExpansionLimit < 0) + entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; + } + else + entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT; + }catch(Exception ex){} + + try { + String value = System.getProperty(Constants.MAX_OCCUR_LIMIT); + if(value != null && !value.equals("")){ + maxOccurLimit = Integer.parseInt(value); + if (maxOccurLimit < 0) + maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT; + } + else + maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT; + }catch(Exception ex){} + + try { + String value = System.getProperty(Constants.ELEMENT_ATTRIBUTE_LIMIT); + if(value != null && !value.equals("")){ + fElementAttributeLimit = Integer.parseInt(value); + if ( fElementAttributeLimit < 0) + fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; + } + else + fElementAttributeLimit = DEFAULT_ELEMENT_ATTRIBUTE_LIMIT; + + }catch(Exception ex){} + + } + +} // class SecurityManager diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java index 41724b6c50d..82667edeed0 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java @@ -203,6 +203,9 @@ public final class XMLLimitAnalyzer { } public boolean isTracking(String name) { + if (entityStart == null) { + return false; + } return entityStart.equals(name); } /** diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java index 1ddb651d6df..a28e80dc81a 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java @@ -26,6 +26,7 @@ package com.sun.org.apache.xerces.internal.utils; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.util.SecurityManager; /** * This class manages standard and implementation-specific limitations. @@ -518,4 +519,37 @@ public final class XMLSecurityManager { } return false; } + + + /** + * Convert a value set through setProperty to XMLSecurityManager. + * If the value is an instance of XMLSecurityManager, use it to override the default; + * If the value is an old SecurityManager, convert to the new XMLSecurityManager. + * + * @param value user specified security manager + * @param securityManager an instance of XMLSecurityManager + * @return an instance of the new security manager XMLSecurityManager + */ + static public XMLSecurityManager convert(Object value, XMLSecurityManager securityManager) { + if (value == null) { + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + } + return securityManager; + } + if (XMLSecurityManager.class.isAssignableFrom(value.getClass())) { + return (XMLSecurityManager)value; + } else { + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + } + if (SecurityManager.class.isAssignableFrom(value.getClass())) { + SecurityManager origSM = (SecurityManager)value; + securityManager.setLimit(Limit.MAX_OCCUR_NODE_LIMIT, State.APIPROPERTY, origSM.getMaxOccurNodeLimit()); + securityManager.setLimit(Limit.ENTITY_EXPANSION_LIMIT, State.APIPROPERTY, origSM.getEntityExpansionLimit()); + securityManager.setLimit(Limit.ELEMENT_ATTRIBUTE_LIMIT, State.APIPROPERTY, origSM.getElementAttrLimit()); + } + return securityManager; + } + } } From ccfb92c6a964753f48307d1c4cd6242bc43b7c1d Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 23 Aug 2013 11:41:37 -0700 Subject: [PATCH 0090/1294] 8012972: Incremental Inlining should support scalar replaced object in debug info Store in _first_index not absolute index but an index relative to the last (youngest) jvms->_scloff value Reviewed-by: roland, twisti --- .../src/share/vm/compiler/compileBroker.cpp | 2 +- hotspot/src/share/vm/opto/callnode.cpp | 23 ++++++++----------- hotspot/src/share/vm/opto/callnode.hpp | 12 +++++++--- .../src/share/vm/opto/generateOptoStub.cpp | 1 + hotspot/src/share/vm/opto/macro.cpp | 14 +++++++---- hotspot/src/share/vm/opto/node.cpp | 15 ++++++++++++ hotspot/src/share/vm/opto/node.hpp | 1 + hotspot/src/share/vm/opto/output.cpp | 12 +++++----- 8 files changed, 53 insertions(+), 27 deletions(-) diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 685cd74c70a..e8f57b24e19 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -1718,7 +1718,7 @@ static void codecache_print(bool detailed) CodeCache::print_summary(&s, detailed); } ttyLocker ttyl; - tty->print_cr(s.as_string()); + tty->print(s.as_string()); } // ------------------------------------------------------------------ diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index cce6c5f29b4..594b650decb 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -458,7 +458,7 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) st->print("={"); uint nf = spobj->n_fields(); if (nf > 0) { - uint first_ind = spobj->first_index(); + uint first_ind = spobj->first_index(mcall->jvms()); Node* fld_node = mcall->in(first_ind); ciField* cifield; if (iklass != NULL) { @@ -1063,7 +1063,6 @@ void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) { int scloff = jvms->scloff(); int endoff = jvms->endoff(); assert(endoff == (int)req(), "no other states or debug info after me"); - assert(jvms->scl_size() == 0, "parsed code should not have scalar objects"); Node* top = Compile::current()->top(); for (uint i = 0; i < grow_by; i++) { ins_req(monoff, top); @@ -1079,32 +1078,31 @@ void SafePointNode::push_monitor(const FastLockNode *lock) { const int MonitorEdges = 2; assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges"); assert(req() == jvms()->endoff(), "correct sizing"); - assert((jvms()->scl_size() == 0), "parsed code should not have scalar objects"); int nextmon = jvms()->scloff(); if (GenerateSynchronizationCode) { - add_req(lock->box_node()); - add_req(lock->obj_node()); + ins_req(nextmon, lock->box_node()); + ins_req(nextmon+1, lock->obj_node()); } else { Node* top = Compile::current()->top(); - add_req(top); - add_req(top); + ins_req(nextmon, top); + ins_req(nextmon, top); } - jvms()->set_scloff(nextmon+MonitorEdges); + jvms()->set_scloff(nextmon + MonitorEdges); jvms()->set_endoff(req()); } void SafePointNode::pop_monitor() { // Delete last monitor from debug info - assert((jvms()->scl_size() == 0), "parsed code should not have scalar objects"); debug_only(int num_before_pop = jvms()->nof_monitors()); - const int MonitorEdges = (1<scloff(); int endoff = jvms()->endoff(); int new_scloff = scloff - MonitorEdges; int new_endoff = endoff - MonitorEdges; jvms()->set_scloff(new_scloff); jvms()->set_endoff(new_endoff); - while (scloff > new_scloff) del_req(--scloff); + while (scloff > new_scloff) del_req_ordered(--scloff); assert(jvms()->nof_monitors() == num_before_pop-1, ""); } @@ -1169,13 +1167,12 @@ uint SafePointScalarObjectNode::match_edge(uint idx) const { } SafePointScalarObjectNode* -SafePointScalarObjectNode::clone(int jvms_adj, Dict* sosn_map) const { +SafePointScalarObjectNode::clone(Dict* sosn_map) const { void* cached = (*sosn_map)[(void*)this]; if (cached != NULL) { return (SafePointScalarObjectNode*)cached; } SafePointScalarObjectNode* res = (SafePointScalarObjectNode*)Node::clone(); - res->_first_index += jvms_adj; sosn_map->Insert((void*)this, (void*)res); return res; } diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp index ebcca023315..def2ad43b1f 100644 --- a/hotspot/src/share/vm/opto/callnode.hpp +++ b/hotspot/src/share/vm/opto/callnode.hpp @@ -449,14 +449,17 @@ public: // at a safepoint. class SafePointScalarObjectNode: public TypeNode { - uint _first_index; // First input edge index of a SafePoint node where + uint _first_index; // First input edge relative index of a SafePoint node where // states of the scalarized object fields are collected. + // It is relative to the last (youngest) jvms->_scloff. uint _n_fields; // Number of non-static fields of the scalarized object. DEBUG_ONLY(AllocateNode* _alloc;) virtual uint hash() const ; // { return NO_HASH; } virtual uint cmp( const Node &n ) const; + uint first_index() const { return _first_index; } + public: SafePointScalarObjectNode(const TypeOopPtr* tp, #ifdef ASSERT @@ -469,7 +472,10 @@ public: virtual const RegMask &out_RegMask() const; virtual uint match_edge(uint idx) const; - uint first_index() const { return _first_index; } + uint first_index(JVMState* jvms) const { + assert(jvms != NULL, "missed JVMS"); + return jvms->scloff() + _first_index; + } uint n_fields() const { return _n_fields; } #ifdef ASSERT @@ -485,7 +491,7 @@ public: // corresponds appropriately to "this" in "new_call". Assumes that // "sosn_map" is a map, specific to the translation of "s" to "new_call", // mapping old SafePointScalarObjectNodes to new, to avoid multiple copies. - SafePointScalarObjectNode* clone(int jvms_adj, Dict* sosn_map) const; + SafePointScalarObjectNode* clone(Dict* sosn_map) const; #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; diff --git a/hotspot/src/share/vm/opto/generateOptoStub.cpp b/hotspot/src/share/vm/opto/generateOptoStub.cpp index c5ebd5ad524..9b64d1f10e2 100644 --- a/hotspot/src/share/vm/opto/generateOptoStub.cpp +++ b/hotspot/src/share/vm/opto/generateOptoStub.cpp @@ -61,6 +61,7 @@ void GraphKit::gen_stub(address C_function, JVMState* jvms = new (C) JVMState(0); jvms->set_bci(InvocationEntryBci); jvms->set_monoff(max_map); + jvms->set_scloff(max_map); jvms->set_endoff(max_map); { SafePointNode *map = new (C) SafePointNode( max_map, jvms ); diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp index 56b9c939147..137c529ed0c 100644 --- a/hotspot/src/share/vm/opto/macro.cpp +++ b/hotspot/src/share/vm/opto/macro.cpp @@ -72,6 +72,8 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal int jvms_adj = new_dbg_start - old_dbg_start; assert (new_dbg_start == newcall->req(), "argument count mismatch"); + // SafePointScalarObject node could be referenced several times in debug info. + // Use Dict to record cloned nodes. Dict* sosn_map = new Dict(cmpkey,hashkey); for (uint i = old_dbg_start; i < oldcall->req(); i++) { Node* old_in = oldcall->in(i); @@ -79,8 +81,8 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal if (old_in != NULL && old_in->is_SafePointScalarObject()) { SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject(); uint old_unique = C->unique(); - Node* new_in = old_sosn->clone(jvms_adj, sosn_map); - if (old_unique != C->unique()) { + Node* new_in = old_sosn->clone(sosn_map); + if (old_unique != C->unique()) { // New node? new_in->set_req(0, C->root()); // reset control edge new_in = transform_later(new_in); // Register new node. } @@ -725,7 +727,11 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray 0) { SafePointNode* sfpt = safepoints.pop(); Node* mem = sfpt->memory(); - uint first_ind = sfpt->req(); + assert(sfpt->jvms() != NULL, "missed JVMS"); + // Fields of scalar objs are referenced only at the end + // of regular debuginfo at the last (youngest) JVMS. + // Record relative start index. + uint first_ind = (sfpt->req() - sfpt->jvms()->scloff()); SafePointScalarObjectNode* sobj = new (C) SafePointScalarObjectNode(res_type, #ifdef ASSERT alloc, @@ -799,7 +805,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray in(i)->is_SafePointScalarObject()) { SafePointScalarObjectNode* scobj = sfpt_done->in(i)->as_SafePointScalarObject(); - if (scobj->first_index() == sfpt_done->req() && + if (scobj->first_index(jvms) == sfpt_done->req() && scobj->n_fields() == (uint)nfields) { assert(scobj->alloc() == alloc, "sanity"); sfpt_done->set_req(i, res); diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp index f2100040ffe..1df5eb51a8c 100644 --- a/hotspot/src/share/vm/opto/node.cpp +++ b/hotspot/src/share/vm/opto/node.cpp @@ -773,6 +773,21 @@ void Node::del_req( uint idx ) { _in[_cnt] = NULL; // NULL out emptied slot } +//------------------------------del_req_ordered-------------------------------- +// Delete the required edge and compact the edge array with preserved order +void Node::del_req_ordered( uint idx ) { + assert( idx < _cnt, "oob"); + assert( !VerifyHashTableKeys || _hash_lock == 0, + "remove node from hash table before modifying it"); + // First remove corresponding def-use edge + Node *n = in(idx); + if (n != NULL) n->del_out((Node *)this); + if (idx < _cnt - 1) { // Not last edge ? + Copy::conjoint_words_to_lower((HeapWord*)&_in[idx+1], (HeapWord*)&_in[idx], ((_cnt-idx-1)*sizeof(Node*))); + } + _in[--_cnt] = NULL; // NULL out emptied slot +} + //------------------------------ins_req---------------------------------------- // Insert a new required input at the end void Node::ins_req( uint idx, Node *n ) { diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index 0690d21b122..65089bad1a8 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -384,6 +384,7 @@ protected: void add_req( Node *n ); // Append a NEW required input void add_req_batch( Node* n, uint m ); // Append m NEW required inputs (all n). void del_req( uint idx ); // Delete required edge & compact + void del_req_ordered( uint idx ); // Delete required edge & compact with preserved order void ins_req( uint i, Node *n ); // Insert a NEW required input void set_req( uint i, Node *n ) { assert( is_not_dead(n), "can not use dead node"); diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index 8a06acdc983..0f1d31c07fe 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -639,7 +639,7 @@ void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local, new ConstantOopWriteValue(cik->java_mirror()->constant_encoding())); Compile::set_sv_for_object_node(objs, sv); - uint first_ind = spobj->first_index(); + uint first_ind = spobj->first_index(sfpt->jvms()); for (uint i = 0; i < spobj->n_fields(); i++) { Node* fld_node = sfpt->in(first_ind+i); (void)FillLocArray(sv->field_values()->length(), sfpt, fld_node, sv->field_values(), objs); @@ -894,7 +894,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { GrowableArray *monarray = new GrowableArray(num_mon); // Loop over monitors and insert into array - for(idx = 0; idx < num_mon; idx++) { + for (idx = 0; idx < num_mon; idx++) { // Grab the node that defines this monitor Node* box_node = sfn->monitor_box(jvms, idx); Node* obj_node = sfn->monitor_obj(jvms, idx); @@ -902,11 +902,11 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { // Create ScopeValue for object ScopeValue *scval = NULL; - if( obj_node->is_SafePointScalarObject() ) { + if (obj_node->is_SafePointScalarObject()) { SafePointScalarObjectNode* spobj = obj_node->as_SafePointScalarObject(); scval = Compile::sv_for_node_id(objs, spobj->_idx); if (scval == NULL) { - const Type *t = obj_node->bottom_type(); + const Type *t = spobj->bottom_type(); ciKlass* cik = t->is_oopptr()->klass(); assert(cik->is_instance_klass() || cik->is_array_klass(), "Not supported allocation."); @@ -914,14 +914,14 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { new ConstantOopWriteValue(cik->java_mirror()->constant_encoding())); Compile::set_sv_for_object_node(objs, sv); - uint first_ind = spobj->first_index(); + uint first_ind = spobj->first_index(youngest_jvms); for (uint i = 0; i < spobj->n_fields(); i++) { Node* fld_node = sfn->in(first_ind+i); (void)FillLocArray(sv->field_values()->length(), sfn, fld_node, sv->field_values(), objs); } scval = sv; } - } else if( !obj_node->is_Con() ) { + } else if (!obj_node->is_Con()) { OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node); if( obj_node->bottom_type()->base() == Type::NarrowOop ) { scval = new_loc_value( _regalloc, obj_reg, Location::narrowoop ); From dac98bcc0d95da85a651053c1cc6627c8814cc6e Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 23 Aug 2013 18:04:35 -0700 Subject: [PATCH 0091/1294] 8023472: C2 optimization breaks with G1 Set control edge for previous value load in G1 pre-barrier Reviewed-by: twisti --- hotspot/src/share/vm/opto/graphKit.cpp | 2 +- .../test/compiler/gcbarriers/G1CrashTest.java | 84 +++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 hotspot/test/compiler/gcbarriers/G1CrashTest.java diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index a363b11a5b8..2f435db6516 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -3595,7 +3595,7 @@ void GraphKit::g1_write_barrier_pre(bool do_load, if (do_load) { // load original value // alias_idx correct?? - pre_val = __ load(no_ctrl, adr, val_type, bt, alias_idx); + pre_val = __ load(__ ctrl(), adr, val_type, bt, alias_idx); } // if (pre_val != NULL) diff --git a/hotspot/test/compiler/gcbarriers/G1CrashTest.java b/hotspot/test/compiler/gcbarriers/G1CrashTest.java new file mode 100644 index 00000000000..e8c6f015132 --- /dev/null +++ b/hotspot/test/compiler/gcbarriers/G1CrashTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013, 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 8023472 + * @summary C2 optimization breaks with G1 + * + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -Dcount=100000 G1CrashTest + * + * @author pbiswal@palantir.com + */ + +public class G1CrashTest { + static Object[] set = new Object[11]; + + public static void main(String[] args) throws InterruptedException { + for (int j = 0; j < Integer.getInteger("count"); j++) { + Object key = new Object(); + insertKey(key); + if (j > set.length / 2) { + Object[] oldKeys = set; + set = new Object[2 * set.length - 1]; + for (Object o : oldKeys) { + if (o != null) + insertKey(o); + } + } + } + } + + static void insertKey(Object key) { + int hash = key.hashCode() & 0x7fffffff; + int index = hash % set.length; + Object cur = set[index]; + if (cur == null) + set[index] = key; + else + insertKeyRehash(key, index, hash, cur); + } + + static void insertKeyRehash(Object key, int index, int hash, Object cur) { + int loopIndex = index; + int firstRemoved = -1; + do { + if (cur == "dead") + firstRemoved = 1; + index--; + if (index < 0) + index += set.length; + cur = set[index]; + if (cur == null) { + if (firstRemoved != -1) + set[firstRemoved] = "dead"; + else + set[index] = key; + return; + } + } while (index != loopIndex); + if (firstRemoved != -1) + set[firstRemoved] = null; + } +} From f188c2bf708f8ab80ae17665309921fedf37068e Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Wed, 21 Aug 2013 13:34:45 +0200 Subject: [PATCH 0092/1294] 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked Do patching rather bailing out for unlinked call with appendix Reviewed-by: twisti, kvn --- .../src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp | 5 +- .../cpu/sparc/vm/c1_LIRAssembler_sparc.cpp | 2 +- .../src/cpu/sparc/vm/c1_Runtime1_sparc.cpp | 6 + hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp | 3 +- .../src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 2 +- hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp | 7 + hotspot/src/share/vm/c1/c1_CodeStubs.hpp | 5 +- hotspot/src/share/vm/c1/c1_GraphBuilder.cpp | 28 +++- hotspot/src/share/vm/c1/c1_LIR.hpp | 2 - hotspot/src/share/vm/c1/c1_LIRAssembler.cpp | 11 ++ hotspot/src/share/vm/c1/c1_LIRAssembler.hpp | 2 + hotspot/src/share/vm/c1/c1_Runtime1.cpp | 127 +++++++++++++----- hotspot/src/share/vm/c1/c1_Runtime1.hpp | 2 + hotspot/src/share/vm/c1/c1_globals.cpp | 2 +- hotspot/src/share/vm/c1/c1_globals.hpp | 10 +- hotspot/src/share/vm/ci/ciEnv.cpp | 4 + hotspot/src/share/vm/ci/ciEnv.hpp | 1 + hotspot/src/share/vm/ci/ciMethod.hpp | 4 + hotspot/src/share/vm/ci/ciObjectFactory.cpp | 5 +- hotspot/src/share/vm/ci/ciObjectFactory.hpp | 2 + hotspot/src/share/vm/runtime/globals.cpp | 3 +- .../share/vm/runtime/globals_extension.hpp | 5 +- .../src/share/vm/runtime/sharedRuntime.cpp | 9 +- 23 files changed, 184 insertions(+), 63 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp index 113665220ae..c6039055300 100644 --- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp @@ -307,7 +307,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { assert(a_byte == *start++, "should be the same code"); } #endif - } else if (_id == load_mirror_id) { + } else if (_id == load_mirror_id || _id == load_appendix_id) { // produce a copy of the load mirror instruction for use by the being initialized case #ifdef ASSERT address start = __ pc(); @@ -384,6 +384,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { case access_field_id: target = Runtime1::entry_for(Runtime1::access_field_patching_id); break; case load_klass_id: target = Runtime1::entry_for(Runtime1::load_klass_patching_id); reloc_type = relocInfo::metadata_type; break; case load_mirror_id: target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); reloc_type = relocInfo::oop_type; break; + case load_appendix_id: target = Runtime1::entry_for(Runtime1::load_appendix_patching_id); reloc_type = relocInfo::oop_type; break; default: ShouldNotReachHere(); } __ bind(call_patch); @@ -397,7 +398,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { ce->add_call_info_here(_info); __ br(Assembler::always, false, Assembler::pt, _patch_site_entry); __ delayed()->nop(); - if (_id == load_klass_id || _id == load_mirror_id) { + if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) { CodeSection* cs = __ code_section(); address pc = (address)_pc_start; RelocIterator iter(cs, pc, pc + 1); diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp index 64745015923..12d51571ccb 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -520,7 +520,7 @@ void LIR_Assembler::jobject2reg(jobject o, Register reg) { void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo *info) { // Allocate a new index in table to hold the object once it's been patched int oop_index = __ oop_recorder()->allocate_oop_index(NULL); - PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_mirror_id, oop_index); + PatchingStub* patch = new PatchingStub(_masm, patching_id(info), oop_index); AddressLiteral addrlit(NULL, oop_Relocation::spec(oop_index)); assert(addrlit.rspec().type() == relocInfo::oop_type, "must be an oop reloc"); diff --git a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp index be4ae63e6aa..bc633103586 100644 --- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp @@ -804,6 +804,12 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { } break; + case load_appendix_patching_id: + { __ set_info("load_appendix_patching", dont_gc_arguments); + oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_appendix_patching)); + } + break; + case dtrace_object_alloc_id: { // O0: object __ set_info("dtrace_object_alloc", dont_gc_arguments); diff --git a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp index cef3cdbbeaa..1e0c3d9c55c 100644 --- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp @@ -402,6 +402,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { case access_field_id: target = Runtime1::entry_for(Runtime1::access_field_patching_id); break; case load_klass_id: target = Runtime1::entry_for(Runtime1::load_klass_patching_id); reloc_type = relocInfo::metadata_type; break; case load_mirror_id: target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); reloc_type = relocInfo::oop_type; break; + case load_appendix_id: target = Runtime1::entry_for(Runtime1::load_appendix_patching_id); reloc_type = relocInfo::oop_type; break; default: ShouldNotReachHere(); } __ bind(call_patch); @@ -419,7 +420,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { for (int j = __ offset() ; j < jmp_off + 5 ; j++ ) { __ nop(); } - if (_id == load_klass_id || _id == load_mirror_id) { + if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) { CodeSection* cs = __ code_section(); RelocIterator iter(cs, (address)_pc_start, (address)(_pc_start + 1)); relocInfo::change_reloc_info_for_address(&iter, (address) _pc_start, reloc_type, relocInfo::none); diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index b5bceeb60c6..334d0cc92db 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -362,7 +362,7 @@ int LIR_Assembler::check_icache() { void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo* info) { jobject o = NULL; - PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_mirror_id); + PatchingStub* patch = new PatchingStub(_masm, patching_id(info)); __ movoop(reg, o); patching_epilog(patch, lir_patch_normal, reg, info); } diff --git a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp index ff9c11d86f5..e4066e6b4db 100644 --- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -1499,6 +1499,13 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { } break; + case load_appendix_patching_id: + { StubFrame f(sasm, "load_appendix_patching", dont_gc_arguments); + // we should set up register map + oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_appendix_patching)); + } + break; + case dtrace_object_alloc_id: { // rax,: object StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments); diff --git a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp index 7235cd6c38a..5f4a04c5b6c 100644 --- a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp +++ b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp @@ -364,7 +364,8 @@ class PatchingStub: public CodeStub { enum PatchID { access_field_id, load_klass_id, - load_mirror_id + load_mirror_id, + load_appendix_id }; enum constants { patch_info_size = 3 @@ -417,7 +418,7 @@ class PatchingStub: public CodeStub { } NativeMovRegMem* n_move = nativeMovRegMem_at(pc_start()); n_move->set_offset(field_offset); - } else if (_id == load_klass_id || _id == load_mirror_id) { + } else if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) { assert(_obj != noreg, "must have register object for load_klass/load_mirror"); #ifdef ASSERT // verify that we're pointing at a NativeMovConstReg diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index b84c8911e4c..1d0b9243de2 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -1667,9 +1667,8 @@ void GraphBuilder::invoke(Bytecodes::Code code) { const Bytecodes::Code bc_raw = stream()->cur_bc_raw(); assert(declared_signature != NULL, "cannot be null"); - // FIXME bail out for now - if (Bytecodes::has_optional_appendix(bc_raw) && !will_link) { - BAILOUT("unlinked call site (FIXME needs patching or recompile support)"); + if (!C1PatchInvokeDynamic && Bytecodes::has_optional_appendix(bc_raw) && !will_link) { + BAILOUT("unlinked call site (C1PatchInvokeDynamic is off)"); } // we have to make sure the argument size (incl. the receiver) @@ -1713,10 +1712,23 @@ void GraphBuilder::invoke(Bytecodes::Code code) { code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial; break; } + } else { + if (bc_raw == Bytecodes::_invokehandle) { + assert(!will_link, "should come here only for unlinked call"); + code = Bytecodes::_invokespecial; + } } // Push appendix argument (MethodType, CallSite, etc.), if one. - if (stream()->has_appendix()) { + bool patch_for_appendix = false; + int patching_appendix_arg = 0; + if (C1PatchInvokeDynamic && + (Bytecodes::has_optional_appendix(bc_raw) && (!will_link || PatchALot))) { + Value arg = append(new Constant(new ObjectConstant(compilation()->env()->unloaded_ciinstance()), copy_state_before())); + apush(arg); + patch_for_appendix = true; + patching_appendix_arg = (will_link && stream()->has_appendix()) ? 0 : 1; + } else if (stream()->has_appendix()) { ciObject* appendix = stream()->get_appendix(); Value arg = append(new Constant(new ObjectConstant(appendix))); apush(arg); @@ -1732,7 +1744,8 @@ void GraphBuilder::invoke(Bytecodes::Code code) { if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() && !(// %%% FIXME: Are both of these relevant? target->is_method_handle_intrinsic() || - target->is_compiled_lambda_form())) { + target->is_compiled_lambda_form()) && + !patch_for_appendix) { Value receiver = NULL; ciInstanceKlass* receiver_klass = NULL; bool type_is_exact = false; @@ -1850,7 +1863,8 @@ void GraphBuilder::invoke(Bytecodes::Code code) { // check if we could do inlining if (!PatchALot && Inline && klass->is_loaded() && (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized()) - && target->is_loaded()) { + && target->is_loaded() + && !patch_for_appendix) { // callee is known => check if we have static binding assert(target->is_loaded(), "callee must be known"); if (code == Bytecodes::_invokestatic || @@ -1901,7 +1915,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) { code == Bytecodes::_invokespecial || code == Bytecodes::_invokevirtual || code == Bytecodes::_invokeinterface; - Values* args = state()->pop_arguments(target->arg_size_no_receiver()); + Values* args = state()->pop_arguments(target->arg_size_no_receiver() + patching_appendix_arg); Value recv = has_receiver ? apop() : NULL; int vtable_index = Method::invalid_vtable_index; diff --git a/hotspot/src/share/vm/c1/c1_LIR.hpp b/hotspot/src/share/vm/c1/c1_LIR.hpp index fab85e5750f..d0dca72f386 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.hpp +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp @@ -1211,8 +1211,6 @@ class LIR_OpJavaCall: public LIR_OpCall { bool is_invokedynamic() const { return code() == lir_dynamic_call; } bool is_method_handle_invoke() const { return - is_invokedynamic() // An invokedynamic is always a MethodHandle call site. - || method()->is_compiled_lambda_form() // Java-generated adapter || method()->is_method_handle_intrinsic(); // JVM-generated MH intrinsic diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp index a76f5bb2ec3..9ae527054fe 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp @@ -93,12 +93,23 @@ void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_cod default: ShouldNotReachHere(); } + } else if (patch->id() == PatchingStub::load_appendix_id) { + Bytecodes::Code bc_raw = info->scope()->method()->raw_code_at_bci(info->stack()->bci()); + assert(Bytecodes::has_optional_appendix(bc_raw), "unexpected appendix resolution"); } else { ShouldNotReachHere(); } #endif } +PatchingStub::PatchID LIR_Assembler::patching_id(CodeEmitInfo* info) { + IRScope* scope = info->scope(); + Bytecodes::Code bc_raw = scope->method()->raw_code_at_bci(info->stack()->bci()); + if (Bytecodes::has_optional_appendix(bc_raw)) { + return PatchingStub::load_appendix_id; + } + return PatchingStub::load_mirror_id; +} //--------------------------------------------------------------- diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp index 4ced297c07b..57df2725ee2 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp @@ -119,6 +119,8 @@ class LIR_Assembler: public CompilationResourceObj { void comp_op(LIR_Condition condition, LIR_Opr src, LIR_Opr result, LIR_Op2* op); + PatchingStub::PatchID patching_id(CodeEmitInfo* info); + public: LIR_Assembler(Compilation* c); ~LIR_Assembler(); diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 9a1c4cce21f..037bc31f658 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -819,6 +819,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i KlassHandle init_klass(THREAD, NULL); // klass needed by load_klass_patching code KlassHandle load_klass(THREAD, NULL); // klass needed by load_klass_patching code Handle mirror(THREAD, NULL); // oop needed by load_mirror_patching code + Handle appendix(THREAD, NULL); // oop needed by appendix_patching code bool load_klass_or_mirror_patch_id = (stub_id == Runtime1::load_klass_patching_id || stub_id == Runtime1::load_mirror_patching_id); @@ -888,10 +889,32 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i mirror = Handle(THREAD, m); } break; - default: Unimplemented(); + default: fatal("unexpected bytecode for load_klass_or_mirror_patch_id"); } // convert to handle load_klass = KlassHandle(THREAD, k); + } else if (stub_id == load_appendix_patching_id) { + Bytecode_invoke bytecode(caller_method, bci); + Bytecodes::Code bc = bytecode.invoke_code(); + + CallInfo info; + constantPoolHandle pool(thread, caller_method->constants()); + int index = bytecode.index(); + LinkResolver::resolve_invoke(info, Handle(), pool, index, bc, CHECK); + appendix = info.resolved_appendix(); + switch (bc) { + case Bytecodes::_invokehandle: { + int cache_index = ConstantPool::decode_cpcache_index(index, true); + assert(cache_index >= 0 && cache_index < pool->cache()->length(), "unexpected cache index"); + pool->cache()->entry_at(cache_index)->set_method_handle(pool, info); + break; + } + case Bytecodes::_invokedynamic: { + pool->invokedynamic_cp_cache_entry_at(index)->set_dynamic_call(pool, info); + break; + } + default: fatal("unexpected bytecode for load_appendix_patching_id"); + } } else { ShouldNotReachHere(); } @@ -992,8 +1015,8 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i n_copy->data() == (intptr_t)Universe::non_oop_word(), "illegal init value"); if (stub_id == Runtime1::load_klass_patching_id) { - assert(load_klass() != NULL, "klass not set"); - n_copy->set_data((intx) (load_klass())); + assert(load_klass() != NULL, "klass not set"); + n_copy->set_data((intx) (load_klass())); } else { assert(mirror() != NULL, "klass not set"); n_copy->set_data((intx) (mirror())); @@ -1002,43 +1025,55 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i if (TracePatching) { Disassembler::decode(copy_buff, copy_buff + *byte_count, tty); } + } + } else if (stub_id == Runtime1::load_appendix_patching_id) { + NativeMovConstReg* n_copy = nativeMovConstReg_at(copy_buff); + assert(n_copy->data() == 0 || + n_copy->data() == (intptr_t)Universe::non_oop_word(), + "illegal init value"); + n_copy->set_data((intx) (appendix())); -#if defined(SPARC) || defined(PPC) - // Update the location in the nmethod with the proper - // metadata. When the code was generated, a NULL was stuffed - // in the metadata table and that table needs to be update to - // have the right value. On intel the value is kept - // directly in the instruction instead of in the metadata - // table, so set_data above effectively updated the value. - nmethod* nm = CodeCache::find_nmethod(instr_pc); - assert(nm != NULL, "invalid nmethod_pc"); - RelocIterator mds(nm, copy_buff, copy_buff + 1); - bool found = false; - while (mds.next() && !found) { - if (mds.type() == relocInfo::oop_type) { - assert(stub_id == Runtime1::load_mirror_patching_id, "wrong stub id"); - oop_Relocation* r = mds.oop_reloc(); - oop* oop_adr = r->oop_addr(); - *oop_adr = mirror(); - r->fix_oop_relocation(); - found = true; - } else if (mds.type() == relocInfo::metadata_type) { - assert(stub_id == Runtime1::load_klass_patching_id, "wrong stub id"); - metadata_Relocation* r = mds.metadata_reloc(); - Metadata** metadata_adr = r->metadata_addr(); - *metadata_adr = load_klass(); - r->fix_metadata_relocation(); - found = true; - } - } - assert(found, "the metadata must exist!"); -#endif - + if (TracePatching) { + Disassembler::decode(copy_buff, copy_buff + *byte_count, tty); } } else { ShouldNotReachHere(); } +#if defined(SPARC) || defined(PPC) + if (load_klass_or_mirror_patch_id || + stub_id == Runtime1::load_appendix_patching_id) { + // Update the location in the nmethod with the proper + // metadata. When the code was generated, a NULL was stuffed + // in the metadata table and that table needs to be update to + // have the right value. On intel the value is kept + // directly in the instruction instead of in the metadata + // table, so set_data above effectively updated the value. + nmethod* nm = CodeCache::find_nmethod(instr_pc); + assert(nm != NULL, "invalid nmethod_pc"); + RelocIterator mds(nm, copy_buff, copy_buff + 1); + bool found = false; + while (mds.next() && !found) { + if (mds.type() == relocInfo::oop_type) { + assert(stub_id == Runtime1::load_mirror_patching_id || + stub_id == Runtime1::load_appendix_patching_id, "wrong stub id"); + oop_Relocation* r = mds.oop_reloc(); + oop* oop_adr = r->oop_addr(); + *oop_adr = stub_id == Runtime1::load_mirror_patching_id ? mirror() : appendix(); + r->fix_oop_relocation(); + found = true; + } else if (mds.type() == relocInfo::metadata_type) { + assert(stub_id == Runtime1::load_klass_patching_id, "wrong stub id"); + metadata_Relocation* r = mds.metadata_reloc(); + Metadata** metadata_adr = r->metadata_addr(); + *metadata_adr = load_klass(); + r->fix_metadata_relocation(); + found = true; + } + } + assert(found, "the metadata must exist!"); + } +#endif if (do_patch) { // replace instructions // first replace the tail, then the call @@ -1077,7 +1112,8 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i ICache::invalidate_range(instr_pc, *byte_count); NativeGeneralJump::replace_mt_safe(instr_pc, copy_buff); - if (load_klass_or_mirror_patch_id) { + if (load_klass_or_mirror_patch_id || + stub_id == Runtime1::load_appendix_patching_id) { relocInfo::relocType rtype = (stub_id == Runtime1::load_klass_patching_id) ? relocInfo::metadata_type : @@ -1118,7 +1154,8 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i // If we are patching in a non-perm oop, make sure the nmethod // is on the right list. - if (ScavengeRootsInCode && mirror.not_null() && mirror()->is_scavengable()) { + if (ScavengeRootsInCode && ((mirror.not_null() && mirror()->is_scavengable()) || + (appendix.not_null() && appendix->is_scavengable()))) { MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag); nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); guarantee(nm != NULL, "only nmethods can contain non-perm oops"); @@ -1179,6 +1216,24 @@ int Runtime1::move_mirror_patching(JavaThread* thread) { return caller_is_deopted(); } +int Runtime1::move_appendix_patching(JavaThread* thread) { +// +// NOTE: we are still in Java +// + Thread* THREAD = thread; + debug_only(NoHandleMark nhm;) + { + // Enter VM mode + + ResetNoHandleMark rnhm; + patch_code(thread, load_appendix_patching_id); + } + // Back in JAVA, use no oops DON'T safepoint + + // Return true if calling code is deoptimized + + return caller_is_deopted(); +} // // Entry point for compiled code. We want to patch a nmethod. // We don't do a normal VM transition here because we want to diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.hpp b/hotspot/src/share/vm/c1/c1_Runtime1.hpp index 9b12d26226e..e41f2f188dc 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.hpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.hpp @@ -67,6 +67,7 @@ class StubAssembler; stub(access_field_patching) \ stub(load_klass_patching) \ stub(load_mirror_patching) \ + stub(load_appendix_patching) \ stub(g1_pre_barrier_slow) \ stub(g1_post_barrier_slow) \ stub(fpu2long_stub) \ @@ -160,6 +161,7 @@ class Runtime1: public AllStatic { static int access_field_patching(JavaThread* thread); static int move_klass_patching(JavaThread* thread); static int move_mirror_patching(JavaThread* thread); + static int move_appendix_patching(JavaThread* thread); static void patch_code(JavaThread* thread, StubID stub_id); diff --git a/hotspot/src/share/vm/c1/c1_globals.cpp b/hotspot/src/share/vm/c1/c1_globals.cpp index a611f033ee6..553b9aa4322 100644 --- a/hotspot/src/share/vm/c1/c1_globals.cpp +++ b/hotspot/src/share/vm/c1/c1_globals.cpp @@ -25,4 +25,4 @@ #include "precompiled.hpp" #include "c1/c1_globals.hpp" -C1_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_NOTPRODUCT_FLAG) +C1_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG) diff --git a/hotspot/src/share/vm/c1/c1_globals.hpp b/hotspot/src/share/vm/c1/c1_globals.hpp index 844880be256..3dceebc9d5b 100644 --- a/hotspot/src/share/vm/c1/c1_globals.hpp +++ b/hotspot/src/share/vm/c1/c1_globals.hpp @@ -54,7 +54,7 @@ // // Defines all global flags used by the client compiler. // -#define C1_FLAGS(develop, develop_pd, product, product_pd, notproduct) \ +#define C1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \ \ /* Printing */ \ notproduct(bool, PrintC1Statistics, false, \ @@ -333,15 +333,19 @@ "Use CHA and exact type results at call sites when updating MDOs")\ \ product(bool, C1UpdateMethodData, trueInTiered, \ - "Update MethodData*s in Tier1-generated code") \ + "Update MethodData*s in Tier1-generated code") \ \ develop(bool, PrintCFGToFile, false, \ "print control flow graph to a separate file during compilation") \ \ + diagnostic(bool, C1PatchInvokeDynamic, true, \ + "Patch invokedynamic appendix not known at compile time") \ + \ + \ // Read default values for c1 globals -C1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_NOTPRODUCT_FLAG) +C1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG) #endif // SHARE_VM_C1_C1_GLOBALS_HPP diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp index 7776db5eb6d..0102b2b21f0 100644 --- a/hotspot/src/share/vm/ci/ciEnv.cpp +++ b/hotspot/src/share/vm/ci/ciEnv.cpp @@ -1150,6 +1150,10 @@ void ciEnv::record_out_of_memory_failure() { record_method_not_compilable("out of memory"); } +ciInstance* ciEnv::unloaded_ciinstance() { + GUARDED_VM_ENTRY(return _factory->get_unloaded_object_constant();) +} + void ciEnv::dump_replay_data(outputStream* out) { VM_ENTRY_MARK; MutexLocker ml(Compile_lock); diff --git a/hotspot/src/share/vm/ci/ciEnv.hpp b/hotspot/src/share/vm/ci/ciEnv.hpp index 45dd42eb25e..01f417d2f9d 100644 --- a/hotspot/src/share/vm/ci/ciEnv.hpp +++ b/hotspot/src/share/vm/ci/ciEnv.hpp @@ -400,6 +400,7 @@ public: static ciInstanceKlass* unloaded_ciinstance_klass() { return _unloaded_ciinstance_klass; } + ciInstance* unloaded_ciinstance(); ciKlass* find_system_klass(ciSymbol* klass_name); // Note: To find a class from its name string, use ciSymbol::make, diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp index 8305547c56f..ddff0ac9b9a 100644 --- a/hotspot/src/share/vm/ci/ciMethod.hpp +++ b/hotspot/src/share/vm/ci/ciMethod.hpp @@ -177,6 +177,10 @@ class ciMethod : public ciMetadata { address bcp = code() + bci; return Bytecodes::java_code_at(NULL, bcp); } + Bytecodes::Code raw_code_at_bci(int bci) { + address bcp = code() + bci; + return Bytecodes::code_at(NULL, bcp); + } BCEscapeAnalyzer *get_bcea(); ciMethodBlocks *get_method_blocks(); diff --git a/hotspot/src/share/vm/ci/ciObjectFactory.cpp b/hotspot/src/share/vm/ci/ciObjectFactory.cpp index cc1be034dd9..a22fcf62c8c 100644 --- a/hotspot/src/share/vm/ci/ciObjectFactory.cpp +++ b/hotspot/src/share/vm/ci/ciObjectFactory.cpp @@ -563,7 +563,10 @@ ciInstance* ciObjectFactory::get_unloaded_method_type_constant(ciSymbol* signatu return get_unloaded_instance(ciEnv::_MethodType_klass->as_instance_klass()); } - +ciInstance* ciObjectFactory::get_unloaded_object_constant() { + if (ciEnv::_Object_klass == NULL) return NULL; + return get_unloaded_instance(ciEnv::_Object_klass->as_instance_klass()); +} //------------------------------------------------------------------ // ciObjectFactory::get_empty_methodData diff --git a/hotspot/src/share/vm/ci/ciObjectFactory.hpp b/hotspot/src/share/vm/ci/ciObjectFactory.hpp index 29de514b2ea..ba3d88c1202 100644 --- a/hotspot/src/share/vm/ci/ciObjectFactory.hpp +++ b/hotspot/src/share/vm/ci/ciObjectFactory.hpp @@ -131,6 +131,8 @@ public: ciInstance* get_unloaded_method_type_constant(ciSymbol* signature); + ciInstance* get_unloaded_object_constant(); + // Get the ciMethodData representing the methodData for a method // with none. ciMethodData* get_empty_methodData(); diff --git a/hotspot/src/share/vm/runtime/globals.cpp b/hotspot/src/share/vm/runtime/globals.cpp index a6c47bfe1de..280e15976de 100644 --- a/hotspot/src/share/vm/runtime/globals.cpp +++ b/hotspot/src/share/vm/runtime/globals.cpp @@ -205,6 +205,7 @@ void Flag::print_as_flag(outputStream* st) { #define C1_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 product}", DEFAULT }, #define C1_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 pd product}", DEFAULT }, +#define C1_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 diagnostic}", DEFAULT }, #ifdef PRODUCT #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ @@ -260,7 +261,7 @@ static Flag flagTable[] = { G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT) #endif // INCLUDE_ALL_GCS #ifdef COMPILER1 - C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT) + C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_DIAGNOSTIC_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT) #endif #ifdef COMPILER2 C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, C2_PD_DEVELOP_FLAG_STRUCT, C2_PRODUCT_FLAG_STRUCT, C2_PD_PRODUCT_FLAG_STRUCT, C2_DIAGNOSTIC_FLAG_STRUCT, C2_EXPERIMENTAL_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT) diff --git a/hotspot/src/share/vm/runtime/globals_extension.hpp b/hotspot/src/share/vm/runtime/globals_extension.hpp index 00d06fe276c..bc4fd4a74bc 100644 --- a/hotspot/src/share/vm/runtime/globals_extension.hpp +++ b/hotspot/src/share/vm/runtime/globals_extension.hpp @@ -57,6 +57,7 @@ #define C1_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), #define C1_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), +#define C1_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), #ifdef PRODUCT #define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc) /* flag is constant */ #define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc) /* flag is constant */ @@ -99,7 +100,7 @@ typedef enum { G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER) #endif // INCLUDE_ALL_GCS #ifdef COMPILER1 - C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, C1_PD_DEVELOP_FLAG_MEMBER, C1_PRODUCT_FLAG_MEMBER, C1_PD_PRODUCT_FLAG_MEMBER, C1_NOTPRODUCT_FLAG_MEMBER) + C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, C1_PD_DEVELOP_FLAG_MEMBER, C1_PRODUCT_FLAG_MEMBER, C1_PD_PRODUCT_FLAG_MEMBER, C1_DIAGNOSTIC_FLAG_MEMBER, C1_NOTPRODUCT_FLAG_MEMBER) #endif #ifdef COMPILER2 C2_FLAGS(C2_DEVELOP_FLAG_MEMBER, C2_PD_DEVELOP_FLAG_MEMBER, C2_PRODUCT_FLAG_MEMBER, C2_PD_PRODUCT_FLAG_MEMBER, C2_DIAGNOSTIC_FLAG_MEMBER, C2_EXPERIMENTAL_FLAG_MEMBER, C2_NOTPRODUCT_FLAG_MEMBER) @@ -131,6 +132,7 @@ typedef enum { #define C1_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), #define C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), #ifdef PRODUCT #define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */ #define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) /* flag is constant */ @@ -204,6 +206,7 @@ typedef enum { C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE, C1_PRODUCT_FLAG_MEMBER_WITH_TYPE, C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE, + C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE, C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE) #endif #ifdef COMPILER2 diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index 874f5939146..d014eda2f80 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -1051,7 +1051,8 @@ Handle SharedRuntime::find_callee_info_helper(JavaThread* thread, // Find receiver for non-static call if (bc != Bytecodes::_invokestatic && - bc != Bytecodes::_invokedynamic) { + bc != Bytecodes::_invokedynamic && + bc != Bytecodes::_invokehandle) { // This register map must be update since we need to find the receiver for // compiled frames. The receiver might be in a register. RegisterMap reg_map2(thread); @@ -1078,7 +1079,7 @@ Handle SharedRuntime::find_callee_info_helper(JavaThread* thread, #ifdef ASSERT // Check that the receiver klass is of the right subtype and that it is initialized for virtual calls - if (bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic) { + if (bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic && bc != Bytecodes::_invokehandle) { assert(receiver.not_null(), "should have thrown exception"); KlassHandle receiver_klass(THREAD, receiver->klass()); Klass* rk = constants->klass_ref_at(bytecode_index, CHECK_(nullHandle)); @@ -1240,9 +1241,9 @@ methodHandle SharedRuntime::resolve_sub_helper(JavaThread *thread, #endif if (is_virtual) { - assert(receiver.not_null(), "sanity check"); + assert(receiver.not_null() || invoke_code == Bytecodes::_invokehandle, "sanity check"); bool static_bound = call_info.resolved_method()->can_be_statically_bound(); - KlassHandle h_klass(THREAD, receiver->klass()); + KlassHandle h_klass(THREAD, invoke_code == Bytecodes::_invokehandle ? NULL : receiver->klass()); CompiledIC::compute_monomorphic_entry(callee_method, h_klass, is_optimized, static_bound, virtual_call_info, CHECK_(methodHandle())); From 80fea6f3059607431f01aa31fb09cd36e595705a Mon Sep 17 00:00:00 2001 From: Stefan Johansson Date: Thu, 22 Aug 2013 10:50:41 +0200 Subject: [PATCH 0093/1294] 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld When using NUMA and large pages we need to ease the requirement on which node the memory should be allocated on. To avoid the SIGBUS we now use the memory policy MPOL_PREFERRED, which prefers a certain node, instead of MPOL_BIND, which requires a certain node. Reviewed-by: jmasa, pliden --- hotspot/src/os/linux/vm/os_linux.cpp | 15 +++++++++++++++ hotspot/src/os/linux/vm/os_linux.hpp | 8 ++++++++ 2 files changed, 23 insertions(+) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index df58be635d1..ca57bf23ad7 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -2796,7 +2796,19 @@ void os::numa_make_global(char *addr, size_t bytes) { Linux::numa_interleave_memory(addr, bytes); } +// Define for numa_set_bind_policy(int). Setting the argument to 0 will set the +// bind policy to MPOL_PREFERRED for the current thread. +#define USE_MPOL_PREFERRED 0 + void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { + // To make NUMA and large pages more robust when both enabled, we need to ease + // the requirements on where the memory should be allocated. MPOL_BIND is the + // default policy and it will force memory to be allocated on the specified + // node. Changing this to MPOL_PREFERRED will prefer to allocate the memory on + // the specified node, but will not force it. Using this policy will prevent + // getting SIGBUS when trying to allocate large pages on NUMA nodes with no + // free large pages. + Linux::numa_set_bind_policy(USE_MPOL_PREFERRED); Linux::numa_tonode_memory(addr, bytes, lgrp_hint); } @@ -2898,6 +2910,8 @@ bool os::Linux::libnuma_init() { libnuma_dlsym(handle, "numa_tonode_memory"))); set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t, libnuma_dlsym(handle, "numa_interleave_memory"))); + set_numa_set_bind_policy(CAST_TO_FN_PTR(numa_set_bind_policy_func_t, + libnuma_dlsym(handle, "numa_set_bind_policy"))); if (numa_available() != -1) { @@ -2964,6 +2978,7 @@ os::Linux::numa_max_node_func_t os::Linux::_numa_max_node; os::Linux::numa_available_func_t os::Linux::_numa_available; os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory; +os::Linux::numa_set_bind_policy_func_t os::Linux::_numa_set_bind_policy; unsigned long* os::Linux::_numa_all_nodes; bool os::pd_uncommit_memory(char* addr, size_t size) { diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp index 8c5032fc23b..dc7107e0e57 100644 --- a/hotspot/src/os/linux/vm/os_linux.hpp +++ b/hotspot/src/os/linux/vm/os_linux.hpp @@ -221,6 +221,7 @@ private: typedef int (*numa_available_func_t)(void); typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node); typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask); + typedef void (*numa_set_bind_policy_func_t)(int policy); static sched_getcpu_func_t _sched_getcpu; static numa_node_to_cpus_func_t _numa_node_to_cpus; @@ -228,6 +229,7 @@ private: static numa_available_func_t _numa_available; static numa_tonode_memory_func_t _numa_tonode_memory; static numa_interleave_memory_func_t _numa_interleave_memory; + static numa_set_bind_policy_func_t _numa_set_bind_policy; static unsigned long* _numa_all_nodes; static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; } @@ -236,6 +238,7 @@ private: static void set_numa_available(numa_available_func_t func) { _numa_available = func; } static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; } static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; } + static void set_numa_set_bind_policy(numa_set_bind_policy_func_t func) { _numa_set_bind_policy = func; } static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; } static int sched_getcpu_syscall(void); public: @@ -253,6 +256,11 @@ public: _numa_interleave_memory(start, size, _numa_all_nodes); } } + static void numa_set_bind_policy(int policy) { + if (_numa_set_bind_policy != NULL) { + _numa_set_bind_policy(policy); + } + } static int get_node_by_cpu(int cpu_id); }; From 27e891247ea20d9523d30bb00008f427ad5d693f Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Thu, 22 Aug 2013 11:23:15 +0200 Subject: [PATCH 0094/1294] 8020692: TestGCEventMixed.java failed because of timestamp in event after end event Reviewed-by: mgerdin, stefank --- .../gc_implementation/g1/g1CollectedHeap.cpp | 4 +-- .../gc_implementation/shared/gcTraceSend.cpp | 27 ++++++++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index eb249a68a34..bd01ec3b602 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2493,11 +2493,11 @@ void G1CollectedHeap::register_concurrent_cycle_start(jlong start_time) { void G1CollectedHeap::register_concurrent_cycle_end() { if (_concurrent_cycle_started) { - _gc_timer_cm->register_gc_end(os::elapsed_counter()); - if (_cm->has_aborted()) { _gc_tracer_cm->report_concurrent_mode_failure(); } + + _gc_timer_cm->register_gc_end(os::elapsed_counter()); _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions()); _concurrent_cycle_started = false; diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp index da0c3856dd6..f08b7d1c52e 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp @@ -28,6 +28,7 @@ #include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/gcWhen.hpp" #include "gc_implementation/shared/copyFailedInfo.hpp" +#include "runtime/os.hpp" #include "trace/tracing.hpp" #include "trace/traceBackend.hpp" #if INCLUDE_ALL_GCS @@ -54,11 +55,12 @@ void GCTracer::send_garbage_collection_event() const { } void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const { - EventGCReferenceStatistics e; + EventGCReferenceStatistics e(UNTIMED); if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_type((u1)type); e.set_count(count); + e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -105,20 +107,22 @@ static TraceStructCopyFailed to_trace_struct(const CopyFailedInfo& cf_info) { } void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_info) const { - EventPromotionFailed e; + EventPromotionFailed e(UNTIMED); if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_data(to_trace_struct(pf_info)); e.set_thread(pf_info.thread()->thread_id()); + e.set_endtime(os::elapsed_counter()); e.commit(); } } // Common to CMS and G1 void OldGCTracer::send_concurrent_mode_failure_event() { - EventConcurrentModeFailure e; + EventConcurrentModeFailure e(UNTIMED); if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); + e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -136,7 +140,7 @@ void G1NewTracer::send_g1_young_gc_event() { } void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) { - EventEvacuationInfo e; + EventEvacuationInfo e(UNTIMED); if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_cSetRegions(info->collectionset_regions()); @@ -147,15 +151,17 @@ void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) { e.set_allocRegionsUsedAfter(info->alloc_regions_used_before() + info->bytes_copied()); e.set_bytesCopied(info->bytes_copied()); e.set_regionsFreed(info->regions_freed()); + e.set_endtime(os::elapsed_counter()); e.commit(); } } void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const { - EventEvacuationFailed e; + EventEvacuationFailed e(UNTIMED); if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_data(to_trace_struct(ef_info)); + e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -189,12 +195,13 @@ class GCHeapSummaryEventSender : public GCHeapSummaryVisitor { void visit(const GCHeapSummary* heap_summary) const { const VirtualSpaceSummary& heap_space = heap_summary->heap(); - EventGCHeapSummary e; + EventGCHeapSummary e(UNTIMED); if (e.should_commit()) { e.set_gcId(_id); e.set_when((u1)_when); e.set_heapSpace(to_trace_struct(heap_space)); e.set_heapUsed(heap_summary->used()); + e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -209,7 +216,7 @@ class GCHeapSummaryEventSender : public GCHeapSummaryVisitor { const SpaceSummary& from_space = ps_heap_summary->from(); const SpaceSummary& to_space = ps_heap_summary->to(); - EventPSHeapSummary e; + EventPSHeapSummary e(UNTIMED); if (e.should_commit()) { e.set_gcId(_id); e.set_when((u1)_when); @@ -220,6 +227,7 @@ class GCHeapSummaryEventSender : public GCHeapSummaryVisitor { e.set_edenSpace(to_trace_struct(ps_heap_summary->eden())); e.set_fromSpace(to_trace_struct(ps_heap_summary->from())); e.set_toSpace(to_trace_struct(ps_heap_summary->to())); + e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -241,13 +249,14 @@ static TraceStructMetaspaceSizes to_trace_struct(const MetaspaceSizes& sizes) { } void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const { - EventMetaspaceSummary e; + EventMetaspaceSummary e(UNTIMED); if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_when((u1) when); e.set_metaspace(to_trace_struct(meta_space_summary.meta_space())); e.set_dataSpace(to_trace_struct(meta_space_summary.data_space())); e.set_classSpace(to_trace_struct(meta_space_summary.class_space())); + e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -282,8 +291,6 @@ class PhaseSender : public PhaseVisitor { default: /* Ignore sending this phase */ break; } } - -#undef send_phase }; void GCTracer::send_phase_events(TimePartitions* time_partitions) const { From eaece57c8db014d1daace8ad1163a5d46e756e8a Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 22 Aug 2013 17:17:25 +0400 Subject: [PATCH 0095/1294] 8023536: Some regression tests have a wrong header Reviewed-by: alexsch --- jdk/test/java/beans/Performance/Test7122740.java | 2 +- jdk/test/java/beans/Performance/Test7184799.java | 2 +- jdk/test/javax/swing/JTree/8013571/Test8013571.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/test/java/beans/Performance/Test7122740.java b/jdk/test/java/beans/Performance/Test7122740.java index 4924c6e8f77..eb0cf3fc974 100644 --- a/jdk/test/java/beans/Performance/Test7122740.java +++ b/jdk/test/java/beans/Performance/Test7122740.java @@ -23,7 +23,7 @@ /* * @test - * @bug 7122740 + * @bug 7187618 7122740 * @summary Tests just a benchmark of PropertyDescriptor(String, Class) performance * @author Sergey Malenkov * @run main/manual Test7122740 diff --git a/jdk/test/java/beans/Performance/Test7184799.java b/jdk/test/java/beans/Performance/Test7184799.java index 563328abc7f..255638e8105 100644 --- a/jdk/test/java/beans/Performance/Test7184799.java +++ b/jdk/test/java/beans/Performance/Test7184799.java @@ -23,7 +23,7 @@ /* * @test - * @bug 7184799 + * @bug 7187618 7184799 * @summary Tests just a benchmark of Introspector.getBeanInfo(Class) performance * @author Sergey Malenkov * @run main/manual Test7184799 diff --git a/jdk/test/javax/swing/JTree/8013571/Test8013571.java b/jdk/test/javax/swing/JTree/8013571/Test8013571.java index 15ad391dcf2..7ad92cdb3e3 100644 --- a/jdk/test/javax/swing/JTree/8013571/Test8013571.java +++ b/jdk/test/javax/swing/JTree/8013571/Test8013571.java @@ -27,8 +27,8 @@ import javax.swing.tree.DefaultTreeModel; /* * @test - * @bug 8016545 - * @summary Tests beans with public fields + * @bug 8013571 + * @summary Tests null as a root of TreeModelEvent * @author Sergey Malenkov */ From a4b39faa4fd60cc8171d7c81fd209b4e51590b53 Mon Sep 17 00:00:00 2001 From: Paul Rank Date: Thu, 22 Aug 2013 10:01:47 -0700 Subject: [PATCH 0096/1294] 8024896: Refactor java.time serialization tests into separate subpackage Move serialization tests to .serial subpackage Reviewed-by: sherman --- .../java/time/tck/java/time/TCKDuration.java | 20 -- .../java/time/tck/java/time/TCKInstant.java | 18 -- .../java/time/tck/java/time/TCKLocalDate.java | 22 -- .../time/tck/java/time/TCKLocalDateTime.java | 25 -- .../java/time/tck/java/time/TCKLocalTime.java | 57 ---- .../java/time/tck/java/time/TCKMonthDay.java | 18 -- .../time/tck/java/time/TCKOffsetDateTime.java | 37 --- .../time/tck/java/time/TCKOffsetTime.java | 34 --- .../java/time/tck/java/time/TCKPeriod.java | 8 - jdk/test/java/time/tck/java/time/TCKYear.java | 19 -- .../java/time/tck/java/time/TCKYearMonth.java | 18 -- .../java/time/tck/java/time/TCKZoneId.java | 104 ------- .../time/tck/java/time/TCKZoneOffset.java | 40 --- .../time/tck/java/time/TCKZonedDateTime.java | 48 ---- .../java/time/chrono/TCKChronoLocalDate.java | 17 -- .../time/chrono/TCKChronoLocalDateTime.java | 17 -- .../chrono/serial/TCKChronoLocalDate.java | 111 ++++++++ .../chrono/serial/TCKChronoLocalDateTime.java | 110 ++++++++ .../TCKChronologySerialization.java | 8 +- .../tck/java/time/serial/TCKDuration.java | 95 +++++++ .../time/tck/java/time/serial/TCKInstant.java | 95 +++++++ .../tck/java/time/serial/TCKLocalDate.java | 107 +++++++ .../java/time/serial/TCKLocalDateTime.java | 104 +++++++ .../tck/java/time/serial/TCKLocalTime.java | 145 ++++++++++ .../tck/java/time/serial/TCKMonthDay.java | 107 +++++++ .../java/time/serial/TCKOffsetDateTime.java | 127 +++++++++ .../tck/java/time/serial/TCKOffsetTime.java | 122 ++++++++ .../time/tck/java/time/serial/TCKPeriod.java | 82 ++++++ .../time/tck/java/time/serial/TCKYear.java | 94 +++++++ .../tck/java/time/serial/TCKYearMonth.java | 106 +++++++ .../time/tck/java/time/serial/TCKZoneId.java | 263 ++++++++++++++++++ .../tck/java/time/serial/TCKZoneOffset.java | 118 ++++++++ .../java/time/serial/TCKZonedDateTime.java | 143 ++++++++++ .../tck/java/time/temporal/TCKWeekFields.java | 6 - .../time/temporal/serial/TCKWeekFields.java | 94 +++++++ .../tck/java/time/zone/TCKFixedZoneRules.java | 18 -- .../time/zone/TCKZoneOffsetTransition.java | 14 - .../zone/TCKZoneOffsetTransitionRule.java | 25 -- .../time/tck/java/time/zone/TCKZoneRules.java | 21 -- .../time/zone/serial/TCKFixedZoneRules.java | 117 ++++++++ .../zone/serial/TCKZoneOffsetTransition.java | 91 ++++++ .../serial/TCKZoneOffsetTransitionRule.java | 114 ++++++++ .../java/time/zone/serial/TCKZoneRules.java | 122 ++++++++ 43 files changed, 2471 insertions(+), 590 deletions(-) create mode 100644 jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java create mode 100644 jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java rename jdk/test/java/time/tck/java/time/chrono/{ => serial}/TCKChronologySerialization.java (96%) create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKDuration.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKInstant.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKPeriod.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKYear.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKZoneId.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java create mode 100644 jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java create mode 100644 jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java create mode 100644 jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java create mode 100644 jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java create mode 100644 jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java diff --git a/jdk/test/java/time/tck/java/time/TCKDuration.java b/jdk/test/java/time/tck/java/time/TCKDuration.java index bae2cf69805..c3bb0c9c906 100644 --- a/jdk/test/java/time/tck/java/time/TCKDuration.java +++ b/jdk/test/java/time/tck/java/time/TCKDuration.java @@ -103,26 +103,6 @@ public class TCKDuration extends AbstractTCKTest { private static final long CYCLE_SECS = 146097L * 86400L; - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(Duration.ofHours(5)); - assertSerializable(Duration.ofHours(0)); - assertSerializable(Duration.ofHours(-5)); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(1); - dos.writeLong(654321); - dos.writeInt(123456789); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(Duration.ofSeconds(654321, 123456789), bytes); - } - //----------------------------------------------------------------------- // constants //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKInstant.java b/jdk/test/java/time/tck/java/time/TCKInstant.java index 05d7b83fcf1..bb3a765de42 100644 --- a/jdk/test/java/time/tck/java/time/TCKInstant.java +++ b/jdk/test/java/time/tck/java/time/TCKInstant.java @@ -154,24 +154,6 @@ public class TCKInstant extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(Instant.ofEpochMilli(134l)); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(2); - dos.writeLong(654321); - dos.writeInt(123456789); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(Instant.ofEpochSecond(654321, 123456789), bytes); - } - //----------------------------------------------------------------------- private void check(Instant instant, long epochSecs, int nos) { assertEquals(instant.getEpochSecond(), epochSecs); diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDate.java b/jdk/test/java/time/tck/java/time/TCKLocalDate.java index 597dd4f6574..3d4cbbbc884 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java @@ -196,28 +196,6 @@ public class TCKLocalDate extends AbstractDateTimeTest { return list; } - - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(TEST_2007_07_15); - assertSerializable(LocalDate.MIN); - assertSerializable(LocalDate.MAX); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(3); - dos.writeInt(2012); - dos.writeByte(9); - dos.writeByte(16); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalDate.of(2012, 9, 16), bytes); - } - //----------------------------------------------------------------------- private void check(LocalDate test, int y, int m, int d) { assertEquals(test.getYear(), y); diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java index f55bdb4a961..040704cd9bc 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java @@ -241,31 +241,6 @@ public class TCKLocalDateTime extends AbstractDateTimeTest { return LocalDateTime.of(year, month, day, 0, 0); } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(TEST_2007_07_15_12_30_40_987654321); - assertSerializable(LocalDateTime.MIN); - assertSerializable(LocalDateTime.MAX); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(5); - dos.writeInt(2012); - dos.writeByte(9); - dos.writeByte(16); - dos.writeByte(22); - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(459_000_000); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalDateTime.of(2012, 9, 16, 22, 17, 59, 459_000_000), bytes); - } - //----------------------------------------------------------------------- // constants //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/TCKLocalTime.java index dbba80d1cec..2291b5ca16b 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java @@ -191,64 +191,7 @@ public class TCKLocalTime extends AbstractDateTimeTest { } //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(TEST_12_30_40_987654321); - assertSerializable(LocalTime.MIN); - assertSerializable(LocalTime.MAX); - } - @Test - public void test_serialization_format_h() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(4); - dos.writeByte(-1 - 22); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalTime.of(22, 0), bytes); - } - - @Test - public void test_serialization_format_hm() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(4); - dos.writeByte(22); - dos.writeByte(-1 - 17); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalTime.of(22, 17), bytes); - } - - @Test - public void test_serialization_format_hms() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(4); - dos.writeByte(22); - dos.writeByte(17); - dos.writeByte(-1 - 59); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalTime.of(22, 17, 59), bytes); - } - - @Test - public void test_serialization_format_hmsn() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(4); - dos.writeByte(22); - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(459_000_000); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalTime.of(22, 17, 59, 459_000_000), bytes); - } - - //----------------------------------------------------------------------- private void check(LocalTime test, int h, int m, int s, int n) { assertEquals(test.getHour(), h); assertEquals(test.getMinute(), m); diff --git a/jdk/test/java/time/tck/java/time/TCKMonthDay.java b/jdk/test/java/time/tck/java/time/TCKMonthDay.java index f2a2b93f473..e9b1730cb71 100644 --- a/jdk/test/java/time/tck/java/time/TCKMonthDay.java +++ b/jdk/test/java/time/tck/java/time/TCKMonthDay.java @@ -136,24 +136,6 @@ public class TCKMonthDay extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws ClassNotFoundException, IOException { - assertSerializable(TEST_07_15); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(13); // java.time.temporal.Ser.MONTH_DAY_TYPE - dos.writeByte(9); - dos.writeByte(16); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(MonthDay.of(9, 16), bytes); - } - //----------------------------------------------------------------------- void check(MonthDay test, int m, int d) { assertEquals(test.getMonth().getValue(), m); diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java index 7cfc2a61dec..0cf024fdde1 100644 --- a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java @@ -209,43 +209,6 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(TEST_2008_6_30_11_30_59_000000500); - assertSerializable(OffsetDateTime.MIN); - assertSerializable(OffsetDateTime.MAX); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(10); // java.time.Ser.OFFSET_DATE_TIME_TYPE - } - byte[] bytes = baos.toByteArray(); - ByteArrayOutputStream baosDateTime = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baosDateTime) ) { - dos.writeByte(5); - dos.writeInt(2012); - dos.writeByte(9); - dos.writeByte(16); - dos.writeByte(22); - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(464_000_000); - } - byte[] bytesDateTime = baosDateTime.toByteArray(); - ByteArrayOutputStream baosOffset = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baosOffset) ) { - dos.writeByte(8); - dos.writeByte(4); // quarter hours stored: 3600 / 900 - } - byte[] bytesOffset = baosOffset.toByteArray(); - LocalDateTime ldt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 464_000_000); - assertSerializedBySer(OffsetDateTime.of(ldt, ZoneOffset.ofHours(1)), bytes, bytesDateTime, bytesOffset); - } - //----------------------------------------------------------------------- // constants //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java index b3d7e5b26a9..ee5b2d3f69f 100644 --- a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java +++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java @@ -183,40 +183,6 @@ public class TCKOffsetTime extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(TEST_11_30_59_500_PONE); - assertSerializable(OffsetTime.MIN); - assertSerializable(OffsetTime.MAX); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(9); // java.time.Ser.OFFSET_TIME_TYPE - } - byte[] bytes = baos.toByteArray(); - ByteArrayOutputStream baosTime = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baosTime) ) { - dos.writeByte(4); - dos.writeByte(22); - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(464_000_000); - } - byte[] bytesTime = baosTime.toByteArray(); - ByteArrayOutputStream baosOffset = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baosOffset) ) { - dos.writeByte(8); - dos.writeByte(4); // quarter hours stored: 3600 / 900 - } - byte[] bytesOffset = baosOffset.toByteArray(); - assertSerializedBySer(OffsetTime.of(22, 17, 59, 464_000_000, ZoneOffset.ofHours(1)), bytes, - bytesTime, bytesOffset); - } - //----------------------------------------------------------------------- // constants //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKPeriod.java b/jdk/test/java/time/tck/java/time/TCKPeriod.java index 7a06b95e6ef..3a1fe42ec45 100644 --- a/jdk/test/java/time/tck/java/time/TCKPeriod.java +++ b/jdk/test/java/time/tck/java/time/TCKPeriod.java @@ -86,14 +86,6 @@ import org.testng.annotations.Test; @Test public class TCKPeriod extends AbstractTCKTest { - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(Period.ZERO); - assertSerializable(Period.ofDays(1)); - assertSerializable(Period.of(1, 2, 3)); - } - //----------------------------------------------------------------------- // ofYears(int) //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKYear.java b/jdk/test/java/time/tck/java/time/TCKYear.java index 53f0db0b56e..c0a35967a7b 100644 --- a/jdk/test/java/time/tck/java/time/TCKYear.java +++ b/jdk/test/java/time/tck/java/time/TCKYear.java @@ -151,25 +151,6 @@ public class TCKYear extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(Year.of(2)); - assertSerializable(Year.of(0)); - assertSerializable(Year.of(-2)); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(11); // java.time.temporal.Ser.YEAR_TYPE - dos.writeInt(2012); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(Year.of(2012), bytes); - } - //----------------------------------------------------------------------- // now() //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKYearMonth.java b/jdk/test/java/time/tck/java/time/TCKYearMonth.java index 66f691b0746..e1f1a466574 100644 --- a/jdk/test/java/time/tck/java/time/TCKYearMonth.java +++ b/jdk/test/java/time/tck/java/time/TCKYearMonth.java @@ -156,24 +156,6 @@ public class TCKYearMonth extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws IOException, ClassNotFoundException { - assertSerializable(TEST_2008_06); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(12); // java.time.temporal.Ser.YEAR_MONTH_TYPE - dos.writeInt(2012); - dos.writeByte(9); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(YearMonth.of(2012, 9), bytes); - } - //----------------------------------------------------------------------- void check(YearMonth test, int y, int m) { assertEquals(test.getYear(), y); diff --git a/jdk/test/java/time/tck/java/time/TCKZoneId.java b/jdk/test/java/time/tck/java/time/TCKZoneId.java index c63b393d29d..0d47403db4e 100644 --- a/jdk/test/java/time/tck/java/time/TCKZoneId.java +++ b/jdk/test/java/time/tck/java/time/TCKZoneId.java @@ -92,110 +92,6 @@ import org.testng.annotations.Test; @Test public class TCKZoneId extends AbstractTCKTest { - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(ZoneId.of("Europe/London")); - assertSerializable(ZoneId.of("America/Chicago")); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(7); - dos.writeUTF("Europe/London"); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(ZoneId.of("Europe/London"), bytes); - } - - @Test - public void test_deserialization_lenient_characters() throws Exception { - // an ID can be loaded without validation during deserialization - String id = "QWERTYUIOPASDFGHJKLZXCVBNM~/._+-"; - ZoneId deser = deserialize(id); - // getId, equals, hashCode, toString and normalized are OK - assertEquals(deser.getId(), id); - assertEquals(deser.toString(), id); - assertEquals(deser, deser); - assertEquals(deser.hashCode(), deser.hashCode()); - assertEquals(deser.normalized(), deser); - // getting the rules is not - try { - deser.getRules(); - fail(); - } catch (ZoneRulesException ex) { - // expected - } - } - - @Test(expectedExceptions=DateTimeException.class) - public void test_deserialization_lenient_badCharacters() throws Exception { - // an ID can be loaded without validation during deserialization - // but there is a check to ensure the ID format is valid - deserialize("|!?"); - } - - @Test(dataProvider="offsetBasedValid") - public void test_deserialization_lenient_offsetNotAllowed_noPrefix(String input, String resolvedId) throws Exception { - ZoneId deserialized = deserialize(input); - assertEquals(deserialized, ZoneId.of(input)); - assertEquals(deserialized, ZoneId.of(resolvedId)); - } - - @Test(dataProvider="offsetBasedValidPrefix") - public void test_deserialization_lenient_offsetNotAllowed_prefixUTC(String input, String resolvedId, String offsetId) throws Exception { - ZoneId deserialized = deserialize("UTC" + input); - assertEquals(deserialized, ZoneId.of("UTC" + input)); - assertEquals(deserialized, ZoneId.of("UTC" + resolvedId)); - } - - @Test(dataProvider="offsetBasedValidPrefix") - public void test_deserialization_lenient_offsetNotAllowed_prefixGMT(String input, String resolvedId, String offsetId) throws Exception { - ZoneId deserialized = deserialize("GMT" + input); - assertEquals(deserialized, ZoneId.of("GMT" + input)); - assertEquals(deserialized, ZoneId.of("GMT" + resolvedId)); - } - - @Test(dataProvider="offsetBasedValidPrefix") - public void test_deserialization_lenient_offsetNotAllowed_prefixUT(String input, String resolvedId, String offsetId) throws Exception { - ZoneId deserialized = deserialize("UT" + input); - assertEquals(deserialized, ZoneId.of("UT" + input)); - assertEquals(deserialized, ZoneId.of("UT" + resolvedId)); - } - - private ZoneId deserialize(String id) throws Exception { - String serClass = ZoneId.class.getPackage().getName() + ".Ser"; - Class serCls = Class.forName(serClass); - Field field = serCls.getDeclaredField("serialVersionUID"); - field.setAccessible(true); - long serVer = (Long) field.get(null); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos)) { - dos.writeShort(ObjectStreamConstants.STREAM_MAGIC); - dos.writeShort(ObjectStreamConstants.STREAM_VERSION); - dos.writeByte(ObjectStreamConstants.TC_OBJECT); - dos.writeByte(ObjectStreamConstants.TC_CLASSDESC); - dos.writeUTF(serClass); - dos.writeLong(serVer); - dos.writeByte(ObjectStreamConstants.SC_EXTERNALIZABLE | ObjectStreamConstants.SC_BLOCK_DATA); - dos.writeShort(0); // number of fields - dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of classdesc - dos.writeByte(ObjectStreamConstants.TC_NULL); // no superclasses - dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA); - dos.writeByte(1 + 2 + id.length()); // length of data (1 byte + 2 bytes UTF length + 32 bytes UTF) - dos.writeByte(7); // ZoneId - dos.writeUTF(id); - dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of blockdata - } - ZoneId deser = null; - try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { - deser = (ZoneId) ois.readObject(); - } - return deser; - } - //----------------------------------------------------------------------- // OLD_SHORT_IDS //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKZoneOffset.java b/jdk/test/java/time/tck/java/time/TCKZoneOffset.java index 94f2eb52e64..cf9098a188b 100644 --- a/jdk/test/java/time/tck/java/time/TCKZoneOffset.java +++ b/jdk/test/java/time/tck/java/time/TCKZoneOffset.java @@ -120,46 +120,6 @@ public class TCKZoneOffset extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(ZoneOffset.of("+01:30")); - } - - @Test - public void test_serialization_format_quarterPositive() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(8); - dos.writeByte(6); // stored as quarter hours - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(ZoneOffset.ofHoursMinutes(1, 30), bytes); - } - - @Test - public void test_serialization_format_quarterNegative() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(8); - dos.writeByte(-10); // stored as quarter hours - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(ZoneOffset.ofHoursMinutes(-2, -30), bytes); - } - - @Test - public void test_serialization_format_full() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(8); - dos.writeByte(127); - dos.writeInt(53265); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(ZoneOffset.ofTotalSeconds(53265), bytes); - } - //----------------------------------------------------------------------- // constants //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java index d1db67fca90..1f5bee32283 100644 --- a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java @@ -222,54 +222,6 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws ClassNotFoundException, IOException { - assertSerializable(TEST_DATE_TIME); - } - - @Test - public void test_serialization_format_zoneId() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(6); - dos.writeInt(2012); // date - dos.writeByte(9); - dos.writeByte(16); - dos.writeByte(22); // time - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(470_000_000); - dos.writeByte(4); // offset - dos.writeByte(7); // zoneId - dos.writeUTF("Europe/London"); - } - byte[] bytes = baos.toByteArray(); - ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneId.of("Europe/London")); - assertSerializedBySer(zdt, bytes); - } - - @Test - public void test_serialization_format_zoneOffset() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(6); - dos.writeInt(2012); // date - dos.writeByte(9); - dos.writeByte(16); - dos.writeByte(22); // time - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(470_000_000); - dos.writeByte(4); // offset - dos.writeByte(8); // zoneId - dos.writeByte(4); - } - byte[] bytes = baos.toByteArray(); - ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneOffset.ofHours(1)); - assertSerializedBySer(zdt, bytes); - } - //----------------------------------------------------------------------- // now() //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java index 92f083ef6f4..32001354ff2 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java @@ -306,23 +306,6 @@ public class TCKChronoLocalDate { } } - //----------------------------------------------------------------------- - // Test Serialization of Calendars - //----------------------------------------------------------------------- - @Test( dataProvider="calendars") - public void test_ChronoSerialization(Chronology chrono) throws Exception { - LocalDate ref = LocalDate.of(2013, 1, 5); - ChronoLocalDate orginal = chrono.date(ref); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - @SuppressWarnings("unchecked") - ChronoLocalDate ser = (ChronoLocalDate) in.readObject(); - assertEquals(ser, orginal, "deserialized date is wrong"); - } //----------------------------------------------------------------------- @Test(dataProvider="calendars") diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java index 129a1903998..7ca03e2e3fb 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java @@ -317,23 +317,6 @@ public class TCKChronoLocalDateTime { } } - //----------------------------------------------------------------------- - // Test Serialization of ISO via chrono API - //----------------------------------------------------------------------- - @Test( dataProvider="calendars") - public void test_ChronoLocalDateTimeSerialization(Chronology chrono) throws Exception { - LocalDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3); - ChronoLocalDateTime orginal = chrono.date(ref).atTime(ref.toLocalTime()); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - ChronoLocalDateTime ser = (ChronoLocalDateTime) in.readObject(); - assertEquals(ser, orginal, "deserialized date is wrong"); - } - //----------------------------------------------------------------------- @Test(dataProvider="calendars") public void test_from_TemporalAccessor(Chronology chrono) { diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java new file mode 100644 index 00000000000..4bec5cdc952 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono.serial; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.LocalDate; +import java.time.chrono.*; + +import static org.testng.Assert.assertEquals; + +/** + * Test assertions that must be true for all built-in chronologies. + */ +@Test +public class TCKChronoLocalDate { + + //----------------------------------------------------------------------- + // regular data factory for names and descriptions of available calendars + //----------------------------------------------------------------------- + @DataProvider(name = "calendars") + Chronology[][] data_of_calendars() { + return new Chronology[][]{ + {HijrahChronology.INSTANCE}, + {IsoChronology.INSTANCE}, + {JapaneseChronology.INSTANCE}, + {MinguoChronology.INSTANCE}, + {ThaiBuddhistChronology.INSTANCE}}; + } + + + //----------------------------------------------------------------------- + // Test Serialization of Calendars + //----------------------------------------------------------------------- + @Test( dataProvider="calendars") + public void test_ChronoSerialization(Chronology chrono) throws Exception { + LocalDate ref = LocalDate.of(2013, 1, 5); + ChronoLocalDate orginal = chrono.date(ref); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(orginal); + out.close(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bais); + @SuppressWarnings("unchecked") + ChronoLocalDate ser = (ChronoLocalDate) in.readObject(); + assertEquals(ser, orginal, "deserialized date is wrong"); + } + + //----------------------------------------------------------------------- + +} diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java new file mode 100644 index 00000000000..1ab1cda92c5 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono.serial; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.chrono.*; + +import static org.testng.Assert.assertEquals; + +/** + * Test assertions that must be true for all built-in chronologies. + */ +@Test +public class TCKChronoLocalDateTime { + + //----------------------------------------------------------------------- + // regular data factory for available calendars + //----------------------------------------------------------------------- + @DataProvider(name = "calendars") + Chronology[][] data_of_calendars() { + return new Chronology[][]{ + {HijrahChronology.INSTANCE}, + {IsoChronology.INSTANCE}, + {JapaneseChronology.INSTANCE}, + {MinguoChronology.INSTANCE}, + {ThaiBuddhistChronology.INSTANCE}}; + } + + //----------------------------------------------------------------------- + // Test Serialization ZonedDateTime for each Chronology + //----------------------------------------------------------------------- + @Test( dataProvider="calendars") + public void test_ChronoLocalDateTimeSerialization(Chronology chrono) throws Exception { + LocalDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3); + ChronoLocalDateTime orginal = chrono.date(ref).atTime(ref.toLocalTime()); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(orginal); + out.close(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bais); + ChronoLocalDateTime ser = (ChronoLocalDateTime) in.readObject(); + assertEquals(ser, orginal, "deserialized date is wrong"); + } + + //----------------------------------------------------------------------- + +} diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java similarity index 96% rename from jdk/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java rename to jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java index 35620ad755e..aed919adafa 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java @@ -54,7 +54,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package tck.java.time.chrono; +package tck.java.time.chrono.serial; import static org.testng.Assert.assertEquals; @@ -73,6 +73,7 @@ import java.time.chrono.ThaiBuddhistChronology; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +@Test public class TCKChronologySerialization { //----------------------------------------------------------------------- @@ -93,13 +94,12 @@ public class TCKChronologySerialization { //----------------------------------------------------------------------- @Test(dataProvider="calendars") public void test_ChronoSerialization(Chronology chrono) throws Exception { + System.out.printf(" ChronoSerialization: %s%n", chrono); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(baos); out.writeObject(chrono); out.close(); - - byte[] bytes = baos.toByteArray(); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bais); @SuppressWarnings("unchecked") diff --git a/jdk/test/java/time/tck/java/time/serial/TCKDuration.java b/jdk/test/java/time/tck/java/time/serial/TCKDuration.java new file mode 100644 index 00000000000..e4a9a3f9a18 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKDuration.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.Duration; + +/** + * Test Duration. + */ +@Test +public class TCKDuration extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(Duration.ofHours(5)); + assertSerializable(Duration.ofHours(0)); + assertSerializable(Duration.ofHours(-5)); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(1); + dos.writeLong(654321); + dos.writeInt(123456789); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(Duration.ofSeconds(654321, 123456789), bytes); + } + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKInstant.java b/jdk/test/java/time/tck/java/time/serial/TCKInstant.java new file mode 100644 index 00000000000..783ad586375 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKInstant.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.Instant; + +/** + * Test Instant. + */ +@Test +public class TCKInstant extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(Instant.ofEpochMilli(134l)); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(2); + dos.writeLong(654321); + dos.writeInt(123456789); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(Instant.ofEpochSecond(654321, 123456789), bytes); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java new file mode 100644 index 00000000000..aeaa96d372d --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.LocalDate; + +/** + * Test LocalDate. + */ +@Test +public class TCKLocalDate extends AbstractTCKTest { + + private LocalDate TEST_2007_07_15; + + @BeforeMethod + public void setUp() { + TEST_2007_07_15 = LocalDate.of(2007, 7, 15); + } + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(TEST_2007_07_15); + assertSerializable(LocalDate.MIN); + assertSerializable(LocalDate.MAX); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(3); + dos.writeInt(2012); + dos.writeByte(9); + dos.writeByte(16); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalDate.of(2012, 9, 16), bytes); + } + + //----------------------------------------------------------------------- + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java new file mode 100644 index 00000000000..a2ae9d2357c --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.LocalDateTime; + +/** + * Test LocalDateTime. + */ +@Test +public class TCKLocalDateTime extends AbstractTCKTest { + + private LocalDateTime TEST_2007_07_15_12_30_40_987654321 = LocalDateTime.of(2007, 7, 15, 12, 30, 40, 987654321); + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(TEST_2007_07_15_12_30_40_987654321); + assertSerializable(LocalDateTime.MIN); + assertSerializable(LocalDateTime.MAX); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(5); + dos.writeInt(2012); + dos.writeByte(9); + dos.writeByte(16); + dos.writeByte(22); + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(459_000_000); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalDateTime.of(2012, 9, 16, 22, 17, 59, 459_000_000), bytes); + } + + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java new file mode 100644 index 00000000000..06f2ce4c898 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.LocalTime; + +/** + * Test LocalTime. + */ +@Test +public class TCKLocalTime extends AbstractTCKTest { + + + private LocalTime TEST_12_30_40_987654321; + + + @BeforeMethod + public void setUp() { + TEST_12_30_40_987654321 = LocalTime.of(12, 30, 40, 987654321); + } + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(TEST_12_30_40_987654321); + assertSerializable(LocalTime.MIN); + assertSerializable(LocalTime.MAX); + } + + @Test + public void test_serialization_format_h() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(4); + dos.writeByte(-1 - 22); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalTime.of(22, 0), bytes); + } + + @Test + public void test_serialization_format_hm() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(4); + dos.writeByte(22); + dos.writeByte(-1 - 17); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalTime.of(22, 17), bytes); + } + + @Test + public void test_serialization_format_hms() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(4); + dos.writeByte(22); + dos.writeByte(17); + dos.writeByte(-1 - 59); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalTime.of(22, 17, 59), bytes); + } + + @Test + public void test_serialization_format_hmsn() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(4); + dos.writeByte(22); + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(459_000_000); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalTime.of(22, 17, 59, 459_000_000), bytes); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java b/jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java new file mode 100644 index 00000000000..cd441663099 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.time.MonthDay; + +/** + * Test MonthDay. + */ +@Test +public class TCKMonthDay extends AbstractTCKTest { + + private MonthDay TEST_07_15; + + @BeforeMethod + public void setUp() { + TEST_07_15 = MonthDay.of(7, 15); + } + + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws ClassNotFoundException, IOException { + assertSerializable(TEST_07_15); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(13); // java.time.temporal.Ser.MONTH_DAY_TYPE + dos.writeByte(9); + dos.writeByte(16); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(MonthDay.of(9, 16), bytes); + } + + //----------------------------------------------------------------------- + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java new file mode 100644 index 00000000000..8a1406b8727 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * Test OffsetDateTime. + */ +@Test +public class TCKOffsetDateTime extends AbstractTCKTest { + + private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); + private OffsetDateTime TEST_2008_6_30_11_30_59_000000500; + + @BeforeMethod + public void setUp() { + TEST_2008_6_30_11_30_59_000000500 = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 500, OFFSET_PONE); + } + + //----------------------------------------------------------------------- + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(TEST_2008_6_30_11_30_59_000000500); + assertSerializable(OffsetDateTime.MIN); + assertSerializable(OffsetDateTime.MAX); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(10); // java.time.Ser.OFFSET_DATE_TIME_TYPE + } + byte[] bytes = baos.toByteArray(); + ByteArrayOutputStream baosDateTime = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baosDateTime) ) { + dos.writeByte(5); + dos.writeInt(2012); + dos.writeByte(9); + dos.writeByte(16); + dos.writeByte(22); + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(464_000_000); + } + byte[] bytesDateTime = baosDateTime.toByteArray(); + ByteArrayOutputStream baosOffset = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baosOffset) ) { + dos.writeByte(8); + dos.writeByte(4); // quarter hours stored: 3600 / 900 + } + byte[] bytesOffset = baosOffset.toByteArray(); + LocalDateTime ldt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 464_000_000); + assertSerializedBySer(OffsetDateTime.of(ldt, ZoneOffset.ofHours(1)), bytes, bytesDateTime, bytesOffset); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java new file mode 100644 index 00000000000..6bdddba2fb3 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.OffsetTime; +import java.time.ZoneOffset; + +/** + * Test OffsetTime. + */ +@Test +public class TCKOffsetTime extends AbstractTCKTest { + + private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); + private OffsetTime TEST_11_30_59_500_PONE; + + @BeforeMethod + public void setUp() { + TEST_11_30_59_500_PONE = OffsetTime.of(11, 30, 59, 500, OFFSET_PONE); + } + + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(TEST_11_30_59_500_PONE); + assertSerializable(OffsetTime.MIN); + assertSerializable(OffsetTime.MAX); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(9); // java.time.Ser.OFFSET_TIME_TYPE + } + byte[] bytes = baos.toByteArray(); + ByteArrayOutputStream baosTime = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baosTime) ) { + dos.writeByte(4); + dos.writeByte(22); + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(464_000_000); + } + byte[] bytesTime = baosTime.toByteArray(); + ByteArrayOutputStream baosOffset = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baosOffset) ) { + dos.writeByte(8); + dos.writeByte(4); // quarter hours stored: 3600 / 900 + } + byte[] bytesOffset = baosOffset.toByteArray(); + assertSerializedBySer(OffsetTime.of(22, 17, 59, 464_000_000, ZoneOffset.ofHours(1)), bytes, + bytesTime, bytesOffset); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKPeriod.java b/jdk/test/java/time/tck/java/time/serial/TCKPeriod.java new file mode 100644 index 00000000000..2f94df132f0 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKPeriod.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.time.Period; + +/** + * Test Period. + */ +@Test +public class TCKPeriod extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(Period.ZERO); + assertSerializable(Period.ofDays(1)); + assertSerializable(Period.of(1, 2, 3)); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKYear.java b/jdk/test/java/time/tck/java/time/serial/TCKYear.java new file mode 100644 index 00000000000..954dacf0c99 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKYear.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.Year; + +/** + * Test Year. + */ +@Test +public class TCKYear extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(Year.of(2)); + assertSerializable(Year.of(0)); + assertSerializable(Year.of(-2)); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(11); // java.time.temporal.Ser.YEAR_TYPE + dos.writeInt(2012); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(Year.of(2012), bytes); + } + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java b/jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java new file mode 100644 index 00000000000..675767d976c --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.time.YearMonth; + +/** + * Test YearMonth. + */ +@Test +public class TCKYearMonth extends AbstractTCKTest { + + private YearMonth TEST_2008_06; + + @BeforeMethod + public void setUp() { + TEST_2008_06 = YearMonth.of(2008, 6); + } + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws IOException, ClassNotFoundException { + assertSerializable(TEST_2008_06); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(12); // java.time.temporal.Ser.YEAR_MONTH_TYPE + dos.writeInt(2012); + dos.writeByte(9); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(YearMonth.of(2012, 9), bytes); + } + + //----------------------------------------------------------------------- + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZoneId.java b/jdk/test/java/time/tck/java/time/serial/TCKZoneId.java new file mode 100644 index 00000000000..26923f12a80 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKZoneId.java @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.*; +import java.lang.reflect.Field; +import java.time.DateTimeException; +import java.time.ZoneId; +import java.time.zone.ZoneRulesException; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; + +/** + * Test ZoneId. + */ +@Test +public class TCKZoneId extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(ZoneId.of("Europe/London")); + assertSerializable(ZoneId.of("America/Chicago")); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(7); + dos.writeUTF("Europe/London"); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(ZoneId.of("Europe/London"), bytes); + } + + @Test + public void test_deserialization_lenient_characters() throws Exception { + // an ID can be loaded without validation during deserialization + String id = "QWERTYUIOPASDFGHJKLZXCVBNM~/._+-"; + ZoneId deser = deserialize(id); + // getId, equals, hashCode, toString and normalized are OK + assertEquals(deser.getId(), id); + assertEquals(deser.toString(), id); + assertEquals(deser, deser); + assertEquals(deser.hashCode(), deser.hashCode()); + assertEquals(deser.normalized(), deser); + // getting the rules is not + try { + deser.getRules(); + fail(); + } catch (ZoneRulesException ex) { + // expected + } + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_deserialization_lenient_badCharacters() throws Exception { + // an ID can be loaded without validation during deserialization + // but there is a check to ensure the ID format is valid + deserialize("|!?"); + } + + @Test(dataProvider="offsetBasedValid") + public void test_deserialization_lenient_offsetNotAllowed_noPrefix(String input, String resolvedId) throws Exception { + ZoneId deserialized = deserialize(input); + assertEquals(deserialized, ZoneId.of(input)); + assertEquals(deserialized, ZoneId.of(resolvedId)); + } + + @Test(dataProvider="offsetBasedValidPrefix") + public void test_deserialization_lenient_offsetNotAllowed_prefixUTC(String input, String resolvedId, String offsetId) throws Exception { + ZoneId deserialized = deserialize("UTC" + input); + assertEquals(deserialized, ZoneId.of("UTC" + input)); + assertEquals(deserialized, ZoneId.of("UTC" + resolvedId)); + } + + @Test(dataProvider="offsetBasedValidPrefix") + public void test_deserialization_lenient_offsetNotAllowed_prefixGMT(String input, String resolvedId, String offsetId) throws Exception { + ZoneId deserialized = deserialize("GMT" + input); + assertEquals(deserialized, ZoneId.of("GMT" + input)); + assertEquals(deserialized, ZoneId.of("GMT" + resolvedId)); + } + + @Test(dataProvider="offsetBasedValidPrefix") + public void test_deserialization_lenient_offsetNotAllowed_prefixUT(String input, String resolvedId, String offsetId) throws Exception { + ZoneId deserialized = deserialize("UT" + input); + assertEquals(deserialized, ZoneId.of("UT" + input)); + assertEquals(deserialized, ZoneId.of("UT" + resolvedId)); + } + + private ZoneId deserialize(String id) throws Exception { + String serClass = ZoneId.class.getPackage().getName() + ".Ser"; + Class serCls = Class.forName(serClass); + Field field = serCls.getDeclaredField("serialVersionUID"); + field.setAccessible(true); + long serVer = (Long) field.get(null); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos)) { + dos.writeShort(ObjectStreamConstants.STREAM_MAGIC); + dos.writeShort(ObjectStreamConstants.STREAM_VERSION); + dos.writeByte(ObjectStreamConstants.TC_OBJECT); + dos.writeByte(ObjectStreamConstants.TC_CLASSDESC); + dos.writeUTF(serClass); + dos.writeLong(serVer); + dos.writeByte(ObjectStreamConstants.SC_EXTERNALIZABLE | ObjectStreamConstants.SC_BLOCK_DATA); + dos.writeShort(0); // number of fields + dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of classdesc + dos.writeByte(ObjectStreamConstants.TC_NULL); // no superclasses + dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA); + dos.writeByte(1 + 2 + id.length()); // length of data (1 byte + 2 bytes UTF length + 32 bytes UTF) + dos.writeByte(7); // ZoneId + dos.writeUTF(id); + dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of blockdata + } + ZoneId deser = null; + try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { + deser = (ZoneId) ois.readObject(); + } + return deser; + } + + //----------------------------------------------------------------------- + // regular factory and .normalized() + //----------------------------------------------------------------------- + @DataProvider(name="offsetBasedValid") + Object[][] data_offsetBasedValid() { + return new Object[][] { + {"Z", "Z"}, + {"+0", "Z"}, + {"-0", "Z"}, + {"+00", "Z"}, + {"+0000", "Z"}, + {"+00:00", "Z"}, + {"+000000", "Z"}, + {"+00:00:00", "Z"}, + {"-00", "Z"}, + {"-0000", "Z"}, + {"-00:00", "Z"}, + {"-000000", "Z"}, + {"-00:00:00", "Z"}, + {"+5", "+05:00"}, + {"+01", "+01:00"}, + {"+0100", "+01:00"}, + {"+01:00", "+01:00"}, + {"+010000", "+01:00"}, + {"+01:00:00", "+01:00"}, + {"+12", "+12:00"}, + {"+1234", "+12:34"}, + {"+12:34", "+12:34"}, + {"+123456", "+12:34:56"}, + {"+12:34:56", "+12:34:56"}, + {"-02", "-02:00"}, + {"-5", "-05:00"}, + {"-0200", "-02:00"}, + {"-02:00", "-02:00"}, + {"-020000", "-02:00"}, + {"-02:00:00", "-02:00"}, + }; + } + + //----------------------------------------------------------------------- + @DataProvider(name="offsetBasedValidPrefix") + Object[][] data_offsetBasedValidPrefix() { + return new Object[][] { + {"", "", "Z"}, + {"+0", "", "Z"}, + {"-0", "", "Z"}, + {"+00", "", "Z"}, + {"+0000", "", "Z"}, + {"+00:00", "", "Z"}, + {"+000000", "", "Z"}, + {"+00:00:00", "", "Z"}, + {"-00", "", "Z"}, + {"-0000", "", "Z"}, + {"-00:00", "", "Z"}, + {"-000000", "", "Z"}, + {"-00:00:00", "", "Z"}, + {"+5", "+05:00", "+05:00"}, + {"+01", "+01:00", "+01:00"}, + {"+0100", "+01:00", "+01:00"}, + {"+01:00", "+01:00", "+01:00"}, + {"+010000", "+01:00", "+01:00"}, + {"+01:00:00", "+01:00", "+01:00"}, + {"+12", "+12:00", "+12:00"}, + {"+1234", "+12:34", "+12:34"}, + {"+12:34", "+12:34", "+12:34"}, + {"+123456", "+12:34:56", "+12:34:56"}, + {"+12:34:56", "+12:34:56", "+12:34:56"}, + {"-02", "-02:00", "-02:00"}, + {"-5", "-05:00", "-05:00"}, + {"-0200", "-02:00", "-02:00"}, + {"-02:00", "-02:00", "-02:00"}, + {"-020000", "-02:00", "-02:00"}, + {"-02:00:00", "-02:00", "-02:00"}, + }; + } + + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java b/jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java new file mode 100644 index 00000000000..61196e909a1 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.ZoneOffset; + +/** + * Test ZoneOffset. + */ +@Test +public class TCKZoneOffset extends AbstractTCKTest { + + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(ZoneOffset.of("+01:30")); + } + + @Test + public void test_serialization_format_quarterPositive() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(8); + dos.writeByte(6); // stored as quarter hours + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(ZoneOffset.ofHoursMinutes(1, 30), bytes); + } + + @Test + public void test_serialization_format_quarterNegative() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(8); + dos.writeByte(-10); // stored as quarter hours + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(ZoneOffset.ofHoursMinutes(-2, -30), bytes); + } + + @Test + public void test_serialization_format_full() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(8); + dos.writeByte(127); + dos.writeInt(53265); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(ZoneOffset.ofTotalSeconds(53265), bytes); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java new file mode 100644 index 00000000000..a44946b7450 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +/** + * Test ZonedDateTime. + */ +@Test +public class TCKZonedDateTime extends AbstractTCKTest { + + private static final ZoneOffset OFFSET_0100 = ZoneOffset.ofHours(1); + private static final ZoneId ZONE_0100 = OFFSET_0100; + private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris"); + private LocalDateTime TEST_LOCAL_2008_06_30_11_30_59_500; + private ZonedDateTime TEST_DATE_TIME; + + + @BeforeMethod + public void setUp() { + TEST_LOCAL_2008_06_30_11_30_59_500 = LocalDateTime.of(2008, 6, 30, 11, 30, 59, 500); + TEST_DATE_TIME = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100); + } + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws ClassNotFoundException, IOException { + assertSerializable(TEST_DATE_TIME); + } + + @Test + public void test_serialization_format_zoneId() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(6); + dos.writeInt(2012); // date + dos.writeByte(9); + dos.writeByte(16); + dos.writeByte(22); // time + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(470_000_000); + dos.writeByte(4); // offset + dos.writeByte(7); // zoneId + dos.writeUTF("Europe/London"); + } + byte[] bytes = baos.toByteArray(); + ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneId.of("Europe/London")); + assertSerializedBySer(zdt, bytes); + } + + @Test + public void test_serialization_format_zoneOffset() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(6); + dos.writeInt(2012); // date + dos.writeByte(9); + dos.writeByte(16); + dos.writeByte(22); // time + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(470_000_000); + dos.writeByte(4); // offset + dos.writeByte(8); // zoneId + dos.writeByte(4); + } + byte[] bytes = baos.toByteArray(); + ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneOffset.ofHours(1)); + assertSerializedBySer(zdt, bytes); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java index 4367ee92511..f2e94884371 100644 --- a/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java +++ b/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java @@ -713,12 +713,6 @@ public class TCKWeekFields extends AbstractTCKTest { } } - //----------------------------------------------------------------------- - @Test(dataProvider="weekFields") - public void test_serializable_singleton(DayOfWeek firstDayOfWeek, int minDays) throws IOException, ClassNotFoundException { - WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays); - assertSerializableSame(weekDef); // spec state singleton - } //----------------------------------------------------------------------- @DataProvider(name="weekFields") diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java new file mode 100644 index 00000000000..749515e7c9d --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal.serial; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.IOException; +import java.time.DayOfWeek; +import java.time.temporal.WeekFields; + +/** + * Test WeekFields. + */ +@Test +public class TCKWeekFields extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test(dataProvider="weekFields") + public void test_serializable_singleton(DayOfWeek firstDayOfWeek, int minDays) throws IOException, ClassNotFoundException { + WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays); + assertSerializableSame(weekDef); // spec state singleton + } + + //----------------------------------------------------------------------- + @DataProvider(name="weekFields") + Object[][] data_weekFields() { + Object[][] objects = new Object[49][]; + int i = 0; + for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) { + for (int minDays = 1; minDays <= 7; minDays++) { + objects[i++] = new Object[] {firstDayOfWeek, minDays}; + } + } + return objects; + } + + +} diff --git a/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java b/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java index 418d1ad9ec2..08df5433349 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java @@ -107,25 +107,7 @@ public class TCKFixedZoneRules { //----------------------------------------------------------------------- // Basics //----------------------------------------------------------------------- - @Test(dataProvider="rules") - public void test_serialization(ZoneRules test, ZoneOffset expectedOffset) throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(test); - baos.close(); - byte[] bytes = baos.toByteArray(); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - ObjectInputStream in = new ObjectInputStream(bais); - ZoneRules result = (ZoneRules) in.readObject(); - - assertEquals(result, test); - assertEquals(result.getClass(), test.getClass()); - } - - //----------------------------------------------------------------------- - // basics - //----------------------------------------------------------------------- @Test(dataProvider="rules") public void test_getOffset_Instant(ZoneRules test, ZoneOffset expectedOffset) { assertEquals(test.getOffset(INSTANT), expectedOffset); diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java index c5da309d872..891deb76733 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java @@ -146,20 +146,6 @@ public class TCKZoneOffsetTransition extends AbstractTCKTest { assertSerializable(test); } - //----------------------------------------------------------------------- - @Test - public void test_serialization_unusual1() throws Exception { - LocalDateTime ldt = LocalDateTime.of(Year.MAX_VALUE, 12, 31, 1, 31, 53); - ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("-10:02:34")); - assertSerializable(test); - } - - @Test - public void test_serialization_unusual2() throws Exception { - LocalDateTime ldt = LocalDateTime.of(Year.MIN_VALUE, 1, 1, 12, 1, 3); - ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("+10:02:34")); - assertSerializable(test); - } //----------------------------------------------------------------------- // isValidOffset() diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java index fedded75337..9ad26627edd 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java @@ -210,31 +210,6 @@ public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { assertSerializable(test); } - @Test - public void test_serialization_unusualOffsets() throws Exception { - ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( - Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.STANDARD, - ZoneOffset.ofHoursMinutesSeconds(-12, -20, -50), - ZoneOffset.ofHoursMinutesSeconds(-4, -10, -34), - ZoneOffset.ofHours(-18)); - assertSerializable(test); - } - - @Test - public void test_serialization_endOfDay() throws Exception { - ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( - Month.MARCH, 20, DayOfWeek.FRIDAY, LocalTime.MIDNIGHT, true, TimeDefinition.UTC, - OFFSET_0200, OFFSET_0200, OFFSET_0300); - assertSerializable(test); - } - - @Test - public void test_serialization_unusualTime() throws Exception { - ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( - Month.MARCH, 20, DayOfWeek.WEDNESDAY, LocalTime.of(13, 34, 56), false, TimeDefinition.STANDARD, - OFFSET_0200, OFFSET_0200, OFFSET_0300); - assertSerializable(test); - } //----------------------------------------------------------------------- // createTransition() diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java index af07063ebe7..19f8239c230 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java @@ -103,28 +103,7 @@ public class TCKZoneRules { private static final int OVERLAP = 2; private static final int GAP = 0; - //----------------------------------------------------------------------- - // Basics - //----------------------------------------------------------------------- - public void test_serialization_loaded() throws Exception { - assertSerialization(europeLondon()); - assertSerialization(europeParis()); - assertSerialization(americaNewYork()); - } - private void assertSerialization(ZoneRules test) throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(test); - baos.close(); - byte[] bytes = baos.toByteArray(); - - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - ObjectInputStream in = new ObjectInputStream(bais); - ZoneRules result = (ZoneRules) in.readObject(); - - assertEquals(result, test); - } //----------------------------------------------------------------------- // Europe/London diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java new file mode 100644 index 00000000000..b5d88d4f983 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.zone.serial; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.ZoneOffset; +import java.time.zone.ZoneRules; + +import static org.testng.Assert.assertEquals; + +/** + * Test ZoneRules for fixed offset time-zones. + */ +@Test +public class TCKFixedZoneRules { + + private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); + private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2); + private static final ZoneOffset OFFSET_M18 = ZoneOffset.ofHours(-18); + + private ZoneRules make(ZoneOffset offset) { + return offset.getRules(); + } + + @DataProvider(name="rules") + Object[][] data_rules() { + return new Object[][] { + {make(OFFSET_PONE), OFFSET_PONE}, + {make(OFFSET_PTWO), OFFSET_PTWO}, + {make(OFFSET_M18), OFFSET_M18}, + }; + } + + //----------------------------------------------------------------------- + // Basics + //----------------------------------------------------------------------- + @Test(dataProvider="rules") + public void test_serialization(ZoneRules test, ZoneOffset expectedOffset) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(test); + baos.close(); + byte[] bytes = baos.toByteArray(); + + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + ObjectInputStream in = new ObjectInputStream(bais); + ZoneRules result = (ZoneRules) in.readObject(); + + assertEquals(result, test); + assertEquals(result.getClass(), test.getClass()); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java new file mode 100644 index 00000000000..a57d31eaf71 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.zone.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.time.LocalDateTime; +import java.time.Year; +import java.time.ZoneOffset; +import java.time.zone.ZoneOffsetTransition; + +/** + * Test ZoneOffsetTransition. + */ +@Test +public class TCKZoneOffsetTransition extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization_unusual1() throws Exception { + LocalDateTime ldt = LocalDateTime.of(Year.MAX_VALUE, 12, 31, 1, 31, 53); + ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("-10:02:34")); + assertSerializable(test); + } + + @Test + public void test_serialization_unusual2() throws Exception { + LocalDateTime ldt = LocalDateTime.of(Year.MIN_VALUE, 1, 1, 12, 1, 3); + ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("+10:02:34")); + assertSerializable(test); + } + +} diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java new file mode 100644 index 00000000000..1ccae56c8d9 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.zone.serial; + +import static org.testng.Assert.assertEquals; + +import java.time.DayOfWeek; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.time.ZoneOffset; +import java.time.zone.ZoneOffsetTransitionRule; +import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +/** + * Test ZoneOffsetTransitionRule. + */ +@Test +public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { + + private static final LocalTime TIME_0100 = LocalTime.of(1, 0); + private static final ZoneOffset OFFSET_0200 = ZoneOffset.ofHours(2); + private static final ZoneOffset OFFSET_0300 = ZoneOffset.ofHours(3); + + + + @Test + public void test_serialization_unusualOffsets() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.STANDARD, + ZoneOffset.ofHoursMinutesSeconds(-12, -20, -50), + ZoneOffset.ofHoursMinutesSeconds(-4, -10, -34), + ZoneOffset.ofHours(-18)); + assertSerializable(test); + } + + @Test + public void test_serialization_endOfDay() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, 20, DayOfWeek.FRIDAY, LocalTime.MIDNIGHT, true, TimeDefinition.UTC, + OFFSET_0200, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } + + @Test + public void test_serialization_unusualTime() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, 20, DayOfWeek.WEDNESDAY, LocalTime.of(13, 34, 56), false, TimeDefinition.STANDARD, + OFFSET_0200, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java new file mode 100644 index 00000000000..6f83223f07c --- /dev/null +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.zone.serial; + +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.ZoneId; +import java.time.zone.ZoneRules; + +import static org.testng.Assert.assertEquals; + +/** + * Test ZoneRules. + */ +@Test +public class TCKZoneRules { + + public void test_serialization_loaded() throws Exception { + assertSerialization(europeLondon()); + assertSerialization(europeParis()); + assertSerialization(americaNewYork()); + } + + private void assertSerialization(ZoneRules test) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(test); + baos.close(); + byte[] bytes = baos.toByteArray(); + + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + ObjectInputStream in = new ObjectInputStream(bais); + ZoneRules result = (ZoneRules) in.readObject(); + + assertEquals(result, test); + } + + //----------------------------------------------------------------------- + // Europe/London + //----------------------------------------------------------------------- + private ZoneRules europeLondon() { + return ZoneId.of("Europe/London").getRules(); + } + + + //----------------------------------------------------------------------- + // Europe/Paris + //----------------------------------------------------------------------- + private ZoneRules europeParis() { + return ZoneId.of("Europe/Paris").getRules(); + } + + //----------------------------------------------------------------------- + // America/New_York + //----------------------------------------------------------------------- + private ZoneRules americaNewYork() { + return ZoneId.of("America/New_York").getRules(); + } + + +} From df7849845e87da6200a8ee68eb33f8fd588c8070 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 22 Aug 2013 21:05:11 +0400 Subject: [PATCH 0097/1294] 7057769: JScrollBar spec should specify that unit increment & decrement functionality may not be present Reviewed-by: alexsch --- jdk/src/share/classes/javax/swing/JScrollBar.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/jdk/src/share/classes/javax/swing/JScrollBar.java b/jdk/src/share/classes/javax/swing/JScrollBar.java index 6abda2eaa79..8cbbbc8551b 100644 --- a/jdk/src/share/classes/javax/swing/JScrollBar.java +++ b/jdk/src/share/classes/javax/swing/JScrollBar.java @@ -344,6 +344,9 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible * that override this method and delegate to the viewports * Scrollable view, if it has one. The Scrollable interface * provides a more specialized version of this method. + *

    + * Some look and feels implement custom scrolling behavior + * and ignore this property. * * @param direction is -1 or 1 for up/down respectively * @return the value of the unitIncrement property @@ -361,6 +364,10 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible *

    * Note, that if the argument is equal to the value of Integer.MIN_VALUE, * the most look and feels will not provide the scrolling to the right/down. + *

    + * Some look and feels implement custom scrolling behavior + * and ignore this property. + * * @see #getUnitIncrement * @beaninfo * preferred: true @@ -387,6 +394,9 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible * that override this method and delegate to the viewports * Scrollable view, if it has one. The Scrollable interface * provides a more specialized version of this method. + *

    + * Some look and feels implement custom scrolling behavior + * and ignore this property. * * @param direction is -1 or 1 for up/down respectively * @return the value of the blockIncrement property @@ -404,6 +414,10 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible *

    * Note, that if the argument is equal to the value of Integer.MIN_VALUE, * the most look and feels will not provide the scrolling to the right/down. + *

    + * Some look and feels implement custom scrolling behavior + * and ignore this property. + * * @see #getBlockIncrement() * @beaninfo * preferred: true From 9e84a85d64267b06197c4228e433d4e3335c3f33 Mon Sep 17 00:00:00 2001 From: Vadim Pakhnushev Date: Fri, 23 Aug 2013 14:13:38 +0400 Subject: [PATCH 0098/1294] 8023052: JVM crash in native layout Reviewed-by: bae, prr --- jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp b/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp index b32f2601b4d..8036a64c4be 100644 --- a/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp +++ b/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp @@ -179,6 +179,10 @@ JNIEXPORT void JNICALL Java_sun_font_SunLayoutEngine_nativeLayout FontInstanceAdapter fia(env, font2d, strike, mat, 72, 72, (le_int32) upem, (TTLayoutTableCache *) layoutTables); LEErrorCode success = LE_NO_ERROR; LayoutEngine *engine = LayoutEngine::layoutEngineFactory(&fia, script, lang, typo_flags & TYPO_MASK, success); + if (engine == NULL) { + env->SetIntField(gvdata, gvdCountFID, -1); // flag failure + return; + } if (min < 0) min = 0; if (max < min) max = min; /* defensive coding */ // have to copy, yuck, since code does upcalls now. this will be soooo slow From a7e60f4913a41f21d43e13cd0301994cb9f9c935 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 23 Aug 2013 19:29:39 +0400 Subject: [PATCH 0099/1294] 7080613: java.beans.DefaultPersistenceDelegate.instantiate(..) doesn't throw NPE Reviewed-by: alexsch --- jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java | 1 + jdk/src/share/classes/java/beans/PersistenceDelegate.java | 1 + 2 files changed, 2 insertions(+) diff --git a/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java b/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java index de6a1b75178..0d056c2e8e5 100644 --- a/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java +++ b/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java @@ -149,6 +149,7 @@ public class DefaultPersistenceDelegate extends PersistenceDelegate { * @return An expression whose value is oldInstance. * * @throws NullPointerException if {@code out} is {@code null} + * and this value is used in the method * * @see #DefaultPersistenceDelegate(String[]) */ diff --git a/jdk/src/share/classes/java/beans/PersistenceDelegate.java b/jdk/src/share/classes/java/beans/PersistenceDelegate.java index bbdcdbf060c..4124d2ff935 100644 --- a/jdk/src/share/classes/java/beans/PersistenceDelegate.java +++ b/jdk/src/share/classes/java/beans/PersistenceDelegate.java @@ -162,6 +162,7 @@ public abstract class PersistenceDelegate { * @return An expression whose value is oldInstance. * * @throws NullPointerException if {@code out} is {@code null} + * and this value is used in the method */ protected abstract Expression instantiate(Object oldInstance, Encoder out); From e412d7e8d119d5d23af15efecac7945f528a993f Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Sat, 24 Aug 2013 00:14:46 -0700 Subject: [PATCH 0100/1294] 8023683: Enhance class file parsing Use the value returned by REALLOC_RESOURCE_ARRAY() Reviewed-by: coleenp, ahgross --- hotspot/src/share/vm/classfile/classFileParser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index e7b9c90363b..9ef6af65475 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -2178,8 +2178,8 @@ methodHandle ClassFileParser::parse_method(bool is_interface, } if (lvt_cnt == max_lvt_cnt) { max_lvt_cnt <<= 1; - REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt); - REALLOC_RESOURCE_ARRAY(u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt); + localvariable_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt); + localvariable_table_start = REALLOC_RESOURCE_ARRAY(u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt); } localvariable_table_start[lvt_cnt] = parse_localvariable_table(code_length, @@ -2207,8 +2207,8 @@ methodHandle ClassFileParser::parse_method(bool is_interface, // Parse local variable type table if (lvtt_cnt == max_lvtt_cnt) { max_lvtt_cnt <<= 1; - REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt); - REALLOC_RESOURCE_ARRAY(u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt); + localvariable_type_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt); + localvariable_type_table_start = REALLOC_RESOURCE_ARRAY(u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt); } localvariable_type_table_start[lvtt_cnt] = parse_localvariable_table(code_length, From be8c8aac48e6c376645ae2e1dff8c09723008988 Mon Sep 17 00:00:00 2001 From: Niclas Adlertz Date: Mon, 26 Aug 2013 12:50:23 +0200 Subject: [PATCH 0101/1294] 8023691: Create interface for nodes in class Block Create public methods for accessing the nodes in a block Reviewed-by: kvn, roland --- hotspot/src/share/vm/adlc/output_c.cpp | 2 +- hotspot/src/share/vm/opto/block.cpp | 94 +++++++------- hotspot/src/share/vm/opto/block.hpp | 46 ++++++- hotspot/src/share/vm/opto/buildOopMap.cpp | 14 +-- hotspot/src/share/vm/opto/chaitin.cpp | 30 ++--- hotspot/src/share/vm/opto/coalesce.cpp | 40 +++--- hotspot/src/share/vm/opto/compile.cpp | 6 +- hotspot/src/share/vm/opto/domgraph.cpp | 6 +- hotspot/src/share/vm/opto/gcm.cpp | 38 +++--- .../src/share/vm/opto/idealGraphPrinter.cpp | 8 +- hotspot/src/share/vm/opto/ifg.cpp | 28 ++--- hotspot/src/share/vm/opto/lcm.cpp | 74 +++++------ hotspot/src/share/vm/opto/live.cpp | 16 +-- hotspot/src/share/vm/opto/output.cpp | 118 +++++++++--------- hotspot/src/share/vm/opto/phaseX.cpp | 12 +- hotspot/src/share/vm/opto/postaloc.cpp | 14 +-- hotspot/src/share/vm/opto/reg_split.cpp | 44 +++---- 17 files changed, 314 insertions(+), 276 deletions(-) diff --git a/hotspot/src/share/vm/adlc/output_c.cpp b/hotspot/src/share/vm/adlc/output_c.cpp index a9bd95177eb..b8978591355 100644 --- a/hotspot/src/share/vm/adlc/output_c.cpp +++ b/hotspot/src/share/vm/adlc/output_c.cpp @@ -1095,7 +1095,7 @@ static void check_peepmatch_instruction_sequence(FILE *fp, PeepMatch *pmatch, Pe fprintf(fp, " // Identify previous instruction if inside this block\n"); fprintf(fp, " if( "); print_block_index(fp, inst_position); - fprintf(fp, " > 0 ) {\n Node *n = block->_nodes.at("); + fprintf(fp, " > 0 ) {\n Node *n = block->get_node("); print_block_index(fp, inst_position); fprintf(fp, ");\n inst%d = (n->is_Mach()) ? ", inst_position); fprintf(fp, "n->as_Mach() : NULL;\n }\n"); diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp index 5a6b791b24a..41872cce667 100644 --- a/hotspot/src/share/vm/opto/block.cpp +++ b/hotspot/src/share/vm/opto/block.cpp @@ -112,9 +112,9 @@ uint Block::compute_loop_alignment() { // exceeds OptoLoopAlignment. uint Block::compute_first_inst_size(uint& sum_size, uint inst_cnt, PhaseRegAlloc* ra) { - uint last_inst = _nodes.size(); + uint last_inst = number_of_nodes(); for( uint j = 0; j < last_inst && inst_cnt > 0; j++ ) { - uint inst_size = _nodes[j]->size(ra); + uint inst_size = get_node(j)->size(ra); if( inst_size > 0 ) { inst_cnt--; uint sz = sum_size + inst_size; @@ -131,8 +131,8 @@ uint Block::compute_first_inst_size(uint& sum_size, uint inst_cnt, } uint Block::find_node( const Node *n ) const { - for( uint i = 0; i < _nodes.size(); i++ ) { - if( _nodes[i] == n ) + for( uint i = 0; i < number_of_nodes(); i++ ) { + if( get_node(i) == n ) return i; } ShouldNotReachHere(); @@ -141,7 +141,7 @@ uint Block::find_node( const Node *n ) const { // Find and remove n from block list void Block::find_remove( const Node *n ) { - _nodes.remove(find_node(n)); + remove_node(find_node(n)); } // Return empty status of a block. Empty blocks contain only the head, other @@ -154,10 +154,10 @@ int Block::is_Empty() const { } int success_result = completely_empty; - int end_idx = _nodes.size()-1; + int end_idx = number_of_nodes() - 1; // Check for ending goto - if ((end_idx > 0) && (_nodes[end_idx]->is_MachGoto())) { + if ((end_idx > 0) && (get_node(end_idx)->is_MachGoto())) { success_result = empty_with_goto; end_idx--; } @@ -170,7 +170,7 @@ int Block::is_Empty() const { // Ideal nodes are allowable in empty blocks: skip them Only MachNodes // turn directly into code, because only MachNodes have non-trivial // emit() functions. - while ((end_idx > 0) && !_nodes[end_idx]->is_Mach()) { + while ((end_idx > 0) && !get_node(end_idx)->is_Mach()) { end_idx--; } @@ -344,8 +344,8 @@ void Block::dump() const { void Block::dump(const PhaseCFG* cfg) const { dump_head(cfg); - for (uint i=0; i< _nodes.size(); i++) { - _nodes[i]->dump(); + for (uint i=0; i< number_of_nodes(); i++) { + get_node(i)->dump(); } tty->print("\n"); } @@ -434,7 +434,7 @@ uint PhaseCFG::build_cfg() { map_node_to_block(p, bb); map_node_to_block(x, bb); if( x != p ) { // Only for root is x == p - bb->_nodes.push((Node*)x); + bb->push_node((Node*)x); } // Now handle predecessors ++sum; // Count 1 for self block @@ -469,11 +469,11 @@ uint PhaseCFG::build_cfg() { assert( x != proj, "" ); // Map basic block of projection map_node_to_block(proj, pb); - pb->_nodes.push(proj); + pb->push_node(proj); } // Insert self as a child of my predecessor block pb->_succs.map(pb->_num_succs++, get_block_for_node(np)); - assert( pb->_nodes[ pb->_nodes.size() - pb->_num_succs ]->is_block_proj(), + assert( pb->get_node(pb->number_of_nodes() - pb->_num_succs)->is_block_proj(), "too many control users, not a CFG?" ); } } @@ -495,7 +495,7 @@ void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) { // surrounding blocks. float freq = in->_freq * in->succ_prob(succ_no); // get ProjNode corresponding to the succ_no'th successor of the in block - ProjNode* proj = in->_nodes[in->_nodes.size() - in->_num_succs + succ_no]->as_Proj(); + ProjNode* proj = in->get_node(in->number_of_nodes() - in->_num_succs + succ_no)->as_Proj(); // create region for basic block RegionNode* region = new (C) RegionNode(2); region->init_req(1, proj); @@ -507,7 +507,7 @@ void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) { Node* gto = _goto->clone(); // get a new goto node gto->set_req(0, region); // add it to the basic block - block->_nodes.push(gto); + block->push_node(gto); map_node_to_block(gto, block); C->regalloc()->set_bad(gto->_idx); // hook up successor block @@ -527,9 +527,9 @@ void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) { // Does this block end in a multiway branch that cannot have the default case // flipped for another case? static bool no_flip_branch( Block *b ) { - int branch_idx = b->_nodes.size() - b->_num_succs-1; + int branch_idx = b->number_of_nodes() - b->_num_succs-1; if( branch_idx < 1 ) return false; - Node *bra = b->_nodes[branch_idx]; + Node *bra = b->get_node(branch_idx); if( bra->is_Catch() ) return true; if( bra->is_Mach() ) { @@ -550,16 +550,16 @@ static bool no_flip_branch( Block *b ) { void PhaseCFG::convert_NeverBranch_to_Goto(Block *b) { // Find true target int end_idx = b->end_idx(); - int idx = b->_nodes[end_idx+1]->as_Proj()->_con; + int idx = b->get_node(end_idx+1)->as_Proj()->_con; Block *succ = b->_succs[idx]; Node* gto = _goto->clone(); // get a new goto node gto->set_req(0, b->head()); - Node *bp = b->_nodes[end_idx]; - b->_nodes.map(end_idx,gto); // Slam over NeverBranch + Node *bp = b->get_node(end_idx); + b->map_node(gto, end_idx); // Slam over NeverBranch map_node_to_block(gto, b); C->regalloc()->set_bad(gto->_idx); - b->_nodes.pop(); // Yank projections - b->_nodes.pop(); // Yank projections + b->pop_node(); // Yank projections + b->pop_node(); // Yank projections b->_succs.map(0,succ); // Map only successor b->_num_succs = 1; // remap successor's predecessors if necessary @@ -575,8 +575,8 @@ void PhaseCFG::convert_NeverBranch_to_Goto(Block *b) { // Scan through block, yanking dead path from // all regions and phis. dead->head()->del_req(j); - for( int k = 1; dead->_nodes[k]->is_Phi(); k++ ) - dead->_nodes[k]->del_req(j); + for( int k = 1; dead->get_node(k)->is_Phi(); k++ ) + dead->get_node(k)->del_req(j); } // Helper function to move block bx to the slot following b_index. Return @@ -620,7 +620,7 @@ void PhaseCFG::move_to_end(Block *b, uint i) { if (e != Block::not_empty) { if (e == Block::empty_with_goto) { // Remove the goto, but leave the block. - b->_nodes.pop(); + b->pop_node(); } // Mark this block as a connector block, which will cause it to be // ignored in certain functions such as non_connector_successor(). @@ -663,7 +663,7 @@ void PhaseCFG::remove_empty_blocks() { // to give a fake exit path to infinite loops. At this late stage they // need to turn into Goto's so that when you enter the infinite loop you // indeed hang. - if (block->_nodes[block->end_idx()]->Opcode() == Op_NeverBranch) { + if (block->get_node(block->end_idx())->Opcode() == Op_NeverBranch) { convert_NeverBranch_to_Goto(block); } @@ -720,9 +720,9 @@ void PhaseCFG::fixup_flow() { // exchange the true and false targets. if (no_flip_branch(block)) { // Find fall through case - if must fall into its target - int branch_idx = block->_nodes.size() - block->_num_succs; + int branch_idx = block->number_of_nodes() - block->_num_succs; for (uint j2 = 0; j2 < block->_num_succs; j2++) { - const ProjNode* p = block->_nodes[branch_idx + j2]->as_Proj(); + const ProjNode* p = block->get_node(branch_idx + j2)->as_Proj(); if (p->_con == 0) { // successor j2 is fall through case if (block->non_connector_successor(j2) != bnext) { @@ -743,14 +743,14 @@ void PhaseCFG::fixup_flow() { // Remove all CatchProjs for (uint j = 0; j < block->_num_succs; j++) { - block->_nodes.pop(); + block->pop_node(); } } else if (block->_num_succs == 1) { // Block ends in a Goto? if (bnext == bs0) { // We fall into next block; remove the Goto - block->_nodes.pop(); + block->pop_node(); } } else if(block->_num_succs == 2) { // Block ends in a If? @@ -759,9 +759,9 @@ void PhaseCFG::fixup_flow() { // be projections (in any order), the 3rd last node must be // the IfNode (we have excluded other 2-way exits such as // CatchNodes already). - MachNode* iff = block->_nodes[block->_nodes.size() - 3]->as_Mach(); - ProjNode* proj0 = block->_nodes[block->_nodes.size() - 2]->as_Proj(); - ProjNode* proj1 = block->_nodes[block->_nodes.size() - 1]->as_Proj(); + MachNode* iff = block->get_node(block->number_of_nodes() - 3)->as_Mach(); + ProjNode* proj0 = block->get_node(block->number_of_nodes() - 2)->as_Proj(); + ProjNode* proj1 = block->get_node(block->number_of_nodes() - 1)->as_Proj(); // Assert that proj0 and succs[0] match up. Similarly for proj1 and succs[1]. assert(proj0->raw_out(0) == block->_succs[0]->head(), "Mismatch successor 0"); @@ -833,8 +833,8 @@ void PhaseCFG::fixup_flow() { iff->as_MachIf()->negate(); } - block->_nodes.pop(); // Remove IfFalse & IfTrue projections - block->_nodes.pop(); + block->pop_node(); // Remove IfFalse & IfTrue projections + block->pop_node(); } else { // Multi-exit block, e.g. a switch statement @@ -895,13 +895,13 @@ void PhaseCFG::verify() const { // Verify sane CFG for (uint i = 0; i < number_of_blocks(); i++) { Block* block = get_block(i); - uint cnt = block->_nodes.size(); + uint cnt = block->number_of_nodes(); uint j; for (j = 0; j < cnt; j++) { - Node *n = block->_nodes[j]; + Node *n = block->get_node(j); assert(get_block_for_node(n) == block, ""); if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) { - assert(j == 1 || block->_nodes[j-1]->is_Phi(), "CreateEx must be first instruction in block"); + assert(j == 1 || block->get_node(j-1)->is_Phi(), "CreateEx must be first instruction in block"); } for (uint k = 0; k < n->req(); k++) { Node *def = n->in(k); @@ -930,14 +930,14 @@ void PhaseCFG::verify() const { } j = block->end_idx(); - Node* bp = (Node*)block->_nodes[block->_nodes.size() - 1]->is_block_proj(); + Node* bp = (Node*)block->get_node(block->number_of_nodes() - 1)->is_block_proj(); assert(bp, "last instruction must be a block proj"); - assert(bp == block->_nodes[j], "wrong number of successors for this block"); + assert(bp == block->get_node(j), "wrong number of successors for this block"); if (bp->is_Catch()) { - while (block->_nodes[--j]->is_MachProj()) { + while (block->get_node(--j)->is_MachProj()) { ; } - assert(block->_nodes[j]->is_MachCall(), "CatchProj must follow call"); + assert(block->get_node(j)->is_MachCall(), "CatchProj must follow call"); } else if (bp->is_Mach() && bp->as_Mach()->ideal_Opcode() == Op_If) { assert(block->_num_succs == 2, "Conditional branch must have two targets"); } @@ -1440,9 +1440,9 @@ void Trace::fixup_blocks(PhaseCFG &cfg) { Block *bnext = next(b); Block *bs0 = b->non_connector_successor(0); - MachNode *iff = b->_nodes[b->_nodes.size()-3]->as_Mach(); - ProjNode *proj0 = b->_nodes[b->_nodes.size()-2]->as_Proj(); - ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj(); + MachNode *iff = b->get_node(b->number_of_nodes() - 3)->as_Mach(); + ProjNode *proj0 = b->get_node(b->number_of_nodes() - 2)->as_Proj(); + ProjNode *proj1 = b->get_node(b->number_of_nodes() - 1)->as_Proj(); if (bnext == bs0) { // Fall-thru case in succs[0], should be in succs[1] @@ -1454,8 +1454,8 @@ void Trace::fixup_blocks(PhaseCFG &cfg) { b->_succs.map( 1, tbs0 ); // Flip projections to match targets - b->_nodes.map(b->_nodes.size()-2, proj1); - b->_nodes.map(b->_nodes.size()-1, proj0); + b->map_node(proj1, b->number_of_nodes() - 2); + b->map_node(proj0, b->number_of_nodes() - 1); } } } diff --git a/hotspot/src/share/vm/opto/block.hpp b/hotspot/src/share/vm/opto/block.hpp index 7cc566cf007..01478d3af04 100644 --- a/hotspot/src/share/vm/opto/block.hpp +++ b/hotspot/src/share/vm/opto/block.hpp @@ -105,15 +105,53 @@ class CFGElement : public ResourceObj { // any optimization pass. They are created late in the game. class Block : public CFGElement { friend class VMStructs; - public: + +private: // Nodes in this block, in order Node_List _nodes; +public: + + // Get the node at index 'at_index', if 'at_index' is out of bounds return NULL + Node* get_node(uint at_index) const { + return _nodes[at_index]; + } + + // Get the number of nodes in this block + uint number_of_nodes() const { + return _nodes.size(); + } + + // Map a node 'node' to index 'to_index' in the block, if the index is out of bounds the size of the node list is increased + void map_node(Node* node, uint to_index) { + _nodes.map(to_index, node); + } + + // Insert a node 'node' at index 'at_index', moving all nodes that are on a higher index one step, if 'at_index' is out of bounds we crash + void insert_node(Node* node, uint at_index) { + _nodes.insert(at_index, node); + } + + // Remove a node at index 'at_index' + void remove_node(uint at_index) { + _nodes.remove(at_index); + } + + // Push a node 'node' onto the node list + void push_node(Node* node) { + _nodes.push(node); + } + + // Pop the last node off the node list + Node* pop_node() { + return _nodes.pop(); + } + // Basic blocks have a Node which defines Control for all Nodes pinned in // this block. This Node is a RegionNode. Exception-causing Nodes // (division, subroutines) and Phi functions are always pinned. Later, // every Node will get pinned to some block. - Node *head() const { return _nodes[0]; } + Node *head() const { return get_node(0); } // CAUTION: num_preds() is ONE based, so that predecessor numbers match // input edges to Regions and Phis. @@ -274,7 +312,7 @@ class Block : public CFGElement { // Add an instruction to an existing block. It must go after the head // instruction and before the end instruction. - void add_inst( Node *n ) { _nodes.insert(end_idx(),n); } + void add_inst( Node *n ) { insert_node(n, end_idx()); } // Find node in block uint find_node( const Node *n ) const; // Find and remove n from block list @@ -550,7 +588,7 @@ class PhaseCFG : public Phase { // Insert a node into a block at index and map the node to the block void insert(Block *b, uint idx, Node *n) { - b->_nodes.insert( idx, n ); + b->insert_node(n , idx); map_node_to_block(n, b); } diff --git a/hotspot/src/share/vm/opto/buildOopMap.cpp b/hotspot/src/share/vm/opto/buildOopMap.cpp index 746511114a7..e63be38ed11 100644 --- a/hotspot/src/share/vm/opto/buildOopMap.cpp +++ b/hotspot/src/share/vm/opto/buildOopMap.cpp @@ -121,8 +121,8 @@ struct OopFlow : public ResourceObj { // Given reaching-defs for this block start, compute it for this block end void OopFlow::compute_reach( PhaseRegAlloc *regalloc, int max_reg, Dict *safehash ) { - for( uint i=0; i<_b->_nodes.size(); i++ ) { - Node *n = _b->_nodes[i]; + for( uint i=0; i<_b->number_of_nodes(); i++ ) { + Node *n = _b->get_node(i); if( n->jvms() ) { // Build an OopMap here? JVMState *jvms = n->jvms(); @@ -447,8 +447,8 @@ static void do_liveness(PhaseRegAlloc* regalloc, PhaseCFG* cfg, Block_List* work } // Now walk tmp_live up the block backwards, computing live - for( int k=b->_nodes.size()-1; k>=0; k-- ) { - Node *n = b->_nodes[k]; + for( int k=b->number_of_nodes()-1; k>=0; k-- ) { + Node *n = b->get_node(k); // KILL def'd bits int first = regalloc->get_reg_first(n); int second = regalloc->get_reg_second(n); @@ -544,12 +544,12 @@ static void do_liveness(PhaseRegAlloc* regalloc, PhaseCFG* cfg, Block_List* work for (i = 1; i < cfg->number_of_blocks(); i++) { Block* block = cfg->get_block(i); uint j; - for (j = 1; j < block->_nodes.size(); j++) { - if (block->_nodes[j]->jvms() && (*safehash)[block->_nodes[j]] == NULL) { + for (j = 1; j < block->number_of_nodes(); j++) { + if (block->get_node(j)->jvms() && (*safehash)[block->get_node(j)] == NULL) { break; } } - if (j < block->_nodes.size()) { + if (j < block->number_of_nodes()) { break; } } diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp index c2f8d40b202..a1a0e1c1fb7 100644 --- a/hotspot/src/share/vm/opto/chaitin.cpp +++ b/hotspot/src/share/vm/opto/chaitin.cpp @@ -301,7 +301,7 @@ int PhaseChaitin::clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& // Copy kill projections after the cloned node Node* kills = proj->clone(); kills->set_req(0, copy); - b->_nodes.insert(idx++, kills); + b->insert_node(kills, idx++); _cfg.map_node_to_block(kills, b); new_lrg(kills, max_lrg_id++); } @@ -682,11 +682,11 @@ void PhaseChaitin::de_ssa() { uint lr_counter = 1; for( uint i = 0; i < _cfg.number_of_blocks(); i++ ) { Block* block = _cfg.get_block(i); - uint cnt = block->_nodes.size(); + uint cnt = block->number_of_nodes(); // Handle all the normal Nodes in the block for( uint j = 0; j < cnt; j++ ) { - Node *n = block->_nodes[j]; + Node *n = block->get_node(j); // Pre-color to the zero live range, or pick virtual register const RegMask &rm = n->out_RegMask(); _lrg_map.map(n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0); @@ -710,8 +710,8 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) { Block* block = _cfg.get_block(i); // For all instructions - for (uint j = 1; j < block->_nodes.size(); j++) { - Node* n = block->_nodes[j]; + for (uint j = 1; j < block->number_of_nodes(); j++) { + Node* n = block->get_node(j); uint input_edge_start =1; // Skip control most nodes if (n->is_Mach()) { input_edge_start = n->as_Mach()->oper_input_base(); @@ -1604,7 +1604,7 @@ void PhaseChaitin::fixup_spills() { // For all instructions in block uint last_inst = block->end_idx(); for (uint j = 1; j <= last_inst; j++) { - Node* n = block->_nodes[j]; + Node* n = block->get_node(j); // Dead instruction??? assert( n->outcnt() != 0 ||// Nothing dead after post alloc @@ -1641,7 +1641,7 @@ void PhaseChaitin::fixup_spills() { assert( cisc->oper_input_base() == 2, "Only adding one edge"); cisc->ins_req(1,src); // Requires a memory edge } - block->_nodes.map(j,cisc); // Insert into basic block + block->map_node(cisc, j); // Insert into basic block n->subsume_by(cisc, C); // Correct graph // ++_used_cisc_instructions; @@ -1698,7 +1698,7 @@ Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derive // (where top() node is placed). base->init_req(0, _cfg.get_root_node()); Block *startb = _cfg.get_block_for_node(C->top()); - startb->_nodes.insert(startb->find_node(C->top()), base ); + startb->insert_node(base, startb->find_node(C->top())); _cfg.map_node_to_block(base, startb); assert(_lrg_map.live_range_id(base) == 0, "should not have LRG yet"); } @@ -1743,9 +1743,9 @@ Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derive // Search the current block for an existing base-Phi Block *b = _cfg.get_block_for_node(derived); for( i = 1; i <= b->end_idx(); i++ ) {// Search for matching Phi - Node *phi = b->_nodes[i]; + Node *phi = b->get_node(i); if( !phi->is_Phi() ) { // Found end of Phis with no match? - b->_nodes.insert( i, base ); // Must insert created Phi here as base + b->insert_node(base, i); // Must insert created Phi here as base _cfg.map_node_to_block(base, b); new_lrg(base,maxlrg++); break; @@ -1786,7 +1786,7 @@ bool PhaseChaitin::stretch_base_pointer_live_ranges(ResourceArea *a) { IndexSet liveout(_live->live(block)); for (uint j = block->end_idx() + 1; j > 1; j--) { - Node* n = block->_nodes[j - 1]; + Node* n = block->get_node(j - 1); // Pre-split compares of loop-phis. Loop-phis form a cycle we would // like to see in the same register. Compare uses the loop-phi and so @@ -1979,8 +1979,8 @@ void PhaseChaitin::dump(const Block *b) const { b->dump_head(&_cfg); // For all instructions - for( uint j = 0; j < b->_nodes.size(); j++ ) - dump(b->_nodes[j]); + for( uint j = 0; j < b->number_of_nodes(); j++ ) + dump(b->get_node(j)); // Print live-out info at end of block if( _live ) { tty->print("Liveout: "); @@ -2271,8 +2271,8 @@ void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const { int dump_once = 0; // For all instructions - for( uint j = 0; j < block->_nodes.size(); j++ ) { - Node *n = block->_nodes[j]; + for( uint j = 0; j < block->number_of_nodes(); j++ ) { + Node *n = block->get_node(j); if (_lrg_map.find_const(n) == lidx) { if (!dump_once++) { tty->cr(); diff --git a/hotspot/src/share/vm/opto/coalesce.cpp b/hotspot/src/share/vm/opto/coalesce.cpp index 66fd988c273..b32a1ef8e25 100644 --- a/hotspot/src/share/vm/opto/coalesce.cpp +++ b/hotspot/src/share/vm/opto/coalesce.cpp @@ -54,9 +54,9 @@ void PhaseCoalesce::dump() const { for( j=0; j_num_succs; j++ ) tty->print("B%d ",b->_succs[j]->_pre_order); tty->print(" IDom: B%d/#%d\n", b->_idom ? b->_idom->_pre_order : 0, b->_dom_depth); - uint cnt = b->_nodes.size(); + uint cnt = b->number_of_nodes(); for( j=0; j_nodes[j]; + Node *n = b->get_node(j); dump( n ); tty->print("\t%s\t",n->Name()); @@ -152,7 +152,7 @@ void PhaseAggressiveCoalesce::insert_copy_with_overlap( Block *b, Node *copy, ui // after the last use. Last use is really first-use on a backwards scan. uint i = b->end_idx()-1; while(1) { - Node *n = b->_nodes[i]; + Node *n = b->get_node(i); // Check for end of virtual copies; this is also the end of the // parallel renaming effort. if (n->_idx < _unique) { @@ -174,7 +174,7 @@ void PhaseAggressiveCoalesce::insert_copy_with_overlap( Block *b, Node *copy, ui // the last kill. Thus it is the first kill on a backwards scan. i = b->end_idx()-1; while (1) { - Node *n = b->_nodes[i]; + Node *n = b->get_node(i); // Check for end of virtual copies; this is also the end of the // parallel renaming effort. if (n->_idx < _unique) { @@ -200,13 +200,13 @@ void PhaseAggressiveCoalesce::insert_copy_with_overlap( Block *b, Node *copy, ui tmp ->set_req(idx,copy->in(idx)); copy->set_req(idx,tmp); // Save source in temp early, before source is killed - b->_nodes.insert(kill_src_idx,tmp); + b->insert_node(tmp, kill_src_idx); _phc._cfg.map_node_to_block(tmp, b); last_use_idx++; } // Insert just after last use - b->_nodes.insert(last_use_idx+1,copy); + b->insert_node(copy, last_use_idx + 1); } void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { @@ -237,8 +237,8 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { Block *b = _phc._cfg.get_block(i); uint cnt = b->num_preds(); // Number of inputs to the Phi - for( uint l = 1; l_nodes.size(); l++ ) { - Node *n = b->_nodes[l]; + for( uint l = 1; lnumber_of_nodes(); l++ ) { + Node *n = b->get_node(l); // Do not use removed-copies, use copied value instead uint ncnt = n->req(); @@ -260,7 +260,7 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { if (_phc._lrg_map.find(n) == _phc._lrg_map.find(def)) { n->replace_by(def); n->set_req(cidx,NULL); - b->_nodes.remove(l); + b->remove_node(l); l--; continue; } @@ -321,13 +321,13 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { m->as_Mach()->rematerialize()) { copy = m->clone(); // Insert the copy in the basic block, just before us - b->_nodes.insert(l++, copy); + b->insert_node(copy, l++); l += _phc.clone_projs(b, l, m, copy, _phc._lrg_map); } else { const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()]; copy = new (C) MachSpillCopyNode(m, *rm, *rm); // Insert the copy in the basic block, just before us - b->_nodes.insert(l++, copy); + b->insert_node(copy, l++); } // Insert the copy in the use-def chain n->set_req(idx, copy); @@ -376,7 +376,7 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { // Insert the copy in the use-def chain n->set_req(inpidx, copy ); // Insert the copy in the basic block, just before us - b->_nodes.insert( l++, copy ); + b->insert_node(copy, l++); // Extend ("register allocate") the names array for the copy. uint max_lrg_id = _phc._lrg_map.max_lrg_id(); _phc.new_lrg(copy, max_lrg_id); @@ -431,8 +431,8 @@ void PhaseAggressiveCoalesce::coalesce( Block *b ) { } // Visit all the Phis in successor block - for( uint k = 1; k_nodes.size(); k++ ) { - Node *n = bs->_nodes[k]; + for( uint k = 1; knumber_of_nodes(); k++ ) { + Node *n = bs->get_node(k); if( !n->is_Phi() ) break; combine_these_two( n, n->in(j) ); } @@ -442,7 +442,7 @@ void PhaseAggressiveCoalesce::coalesce( Block *b ) { // Check _this_ block for 2-address instructions and copies. uint cnt = b->end_idx(); for( i = 1; i_nodes[i]; + Node *n = b->get_node(i); uint idx; // 2-address instructions have a virtual Copy matching their input // to their output @@ -490,10 +490,10 @@ void PhaseConservativeCoalesce::union_helper( Node *lr1_node, Node *lr2_node, ui dst_copy->set_req( didx, src_def ); // Add copy to free list // _phc.free_spillcopy(b->_nodes[bindex]); - assert( b->_nodes[bindex] == dst_copy, "" ); + assert( b->get_node(bindex) == dst_copy, "" ); dst_copy->replace_by( dst_copy->in(didx) ); dst_copy->set_req( didx, NULL); - b->_nodes.remove(bindex); + b->remove_node(bindex); if( bindex < b->_ihrp_index ) b->_ihrp_index--; if( bindex < b->_fhrp_index ) b->_fhrp_index--; @@ -523,8 +523,8 @@ uint PhaseConservativeCoalesce::compute_separating_interferences(Node *dst_copy, bindex2 = b2->end_idx()-1; } // Get prior instruction - assert(bindex2 < b2->_nodes.size(), "index out of bounds"); - Node *x = b2->_nodes[bindex2]; + assert(bindex2 < b2->number_of_nodes(), "index out of bounds"); + Node *x = b2->get_node(bindex2); if( x == prev_copy ) { // Previous copy in copy chain? if( prev_copy == src_copy)// Found end of chain and all interferences break; // So break out of loop @@ -776,7 +776,7 @@ void PhaseConservativeCoalesce::coalesce( Block *b ) { for( uint i = 1; iend_idx(); i++ ) { // Check for actual copies on inputs. Coalesce a copy into its // input if use and copy's input are compatible. - Node *copy1 = b->_nodes[i]; + Node *copy1 = b->get_node(i); uint idx1 = copy1->is_Copy(); if( !idx1 ) continue; // Not a copy diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 39ebf9d0483..b426bcce1a2 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -2258,7 +2258,7 @@ void Compile::dump_asm(int *pcs, uint pc_limit) { if (block->is_connector() && !Verbose) { continue; } - n = block->_nodes[0]; + n = block->head(); if (pcs && n->_idx < pc_limit) { tty->print("%3.3x ", pcs[n->_idx]); } else { @@ -2273,12 +2273,12 @@ void Compile::dump_asm(int *pcs, uint pc_limit) { // For all instructions Node *delay = NULL; - for (uint j = 0; j < block->_nodes.size(); j++) { + for (uint j = 0; j < block->number_of_nodes(); j++) { if (VMThread::should_terminate()) { cut_short = true; break; } - n = block->_nodes[j]; + n = block->get_node(j); if (valid_bundle_info(n)) { Bundle* bundle = node_bundling(n); if (bundle->used_in_unconditional_delay()) { diff --git a/hotspot/src/share/vm/opto/domgraph.cpp b/hotspot/src/share/vm/opto/domgraph.cpp index 9a98aef28e9..5e1886c24f0 100644 --- a/hotspot/src/share/vm/opto/domgraph.cpp +++ b/hotspot/src/share/vm/opto/domgraph.cpp @@ -211,21 +211,21 @@ class Block_Stack { uint Block_Stack::most_frequent_successor( Block *b ) { uint freq_idx = 0; int eidx = b->end_idx(); - Node *n = b->_nodes[eidx]; + Node *n = b->get_node(eidx); int op = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : n->Opcode(); switch( op ) { case Op_CountedLoopEnd: case Op_If: { // Split frequency amongst children float prob = n->as_MachIf()->_prob; // Is succ[0] the TRUE branch or the FALSE branch? - if( b->_nodes[eidx+1]->Opcode() == Op_IfFalse ) + if( b->get_node(eidx+1)->Opcode() == Op_IfFalse ) prob = 1.0f - prob; freq_idx = prob < PROB_FAIR; // freq=1 for succ[0] < 0.5 prob break; } case Op_Catch: // Split frequency amongst children for( freq_idx = 0; freq_idx < b->_num_succs; freq_idx++ ) - if( b->_nodes[eidx+1+freq_idx]->as_CatchProj()->_con == CatchProjNode::fall_through_index ) + if( b->get_node(eidx+1+freq_idx)->as_CatchProj()->_con == CatchProjNode::fall_through_index ) break; // Handle case of no fall-thru (e.g., check-cast MUST throw an exception) if( freq_idx == b->_num_succs ) freq_idx = 0; diff --git a/hotspot/src/share/vm/opto/gcm.cpp b/hotspot/src/share/vm/opto/gcm.cpp index 3e95535b73e..7ba369513a0 100644 --- a/hotspot/src/share/vm/opto/gcm.cpp +++ b/hotspot/src/share/vm/opto/gcm.cpp @@ -102,12 +102,12 @@ void PhaseCFG::replace_block_proj_ctrl( Node *n ) { uint j = 0; if (pb->_num_succs != 1) { // More then 1 successor? // Search for successor - uint max = pb->_nodes.size(); + uint max = pb->number_of_nodes(); assert( max > 1, "" ); uint start = max - pb->_num_succs; // Find which output path belongs to projection for (j = start; j < max; j++) { - if( pb->_nodes[j] == in0 ) + if( pb->get_node(j) == in0 ) break; } assert( j < max, "must find" ); @@ -1027,8 +1027,8 @@ Block* PhaseCFG::hoist_to_cheaper_block(Block* LCA, Block* early, Node* self) { Block* least = LCA; double least_freq = least->_freq; uint target = get_latency_for_node(self); - uint start_latency = get_latency_for_node(LCA->_nodes[0]); - uint end_latency = get_latency_for_node(LCA->_nodes[LCA->end_idx()]); + uint start_latency = get_latency_for_node(LCA->head()); + uint end_latency = get_latency_for_node(LCA->get_node(LCA->end_idx())); bool in_latency = (target <= start_latency); const Block* root_block = get_block_for_node(_root); @@ -1049,9 +1049,9 @@ Block* PhaseCFG::hoist_to_cheaper_block(Block* LCA, Block* early, Node* self) { self->dump(); tty->print_cr("# B%d: start latency for [%4d]=%d, end latency for [%4d]=%d, freq=%g", LCA->_pre_order, - LCA->_nodes[0]->_idx, + LCA->head()->_idx, start_latency, - LCA->_nodes[LCA->end_idx()]->_idx, + LCA->get_node(LCA->end_idx())->_idx, end_latency, least_freq); } @@ -1074,14 +1074,14 @@ Block* PhaseCFG::hoist_to_cheaper_block(Block* LCA, Block* early, Node* self) { if (mach && LCA == root_block) break; - uint start_lat = get_latency_for_node(LCA->_nodes[0]); + uint start_lat = get_latency_for_node(LCA->head()); uint end_idx = LCA->end_idx(); - uint end_lat = get_latency_for_node(LCA->_nodes[end_idx]); + uint end_lat = get_latency_for_node(LCA->get_node(end_idx)); double LCA_freq = LCA->_freq; #ifndef PRODUCT if (trace_opto_pipelining()) { tty->print_cr("# B%d: start latency for [%4d]=%d, end latency for [%4d]=%d, freq=%g", - LCA->_pre_order, LCA->_nodes[0]->_idx, start_lat, end_idx, end_lat, LCA_freq); + LCA->_pre_order, LCA->head()->_idx, start_lat, end_idx, end_lat, LCA_freq); } #endif cand_cnt++; @@ -1726,7 +1726,7 @@ void CFGLoop::compute_freq() { // Determine the probability of reaching successor 'i' from the receiver block. float Block::succ_prob(uint i) { int eidx = end_idx(); - Node *n = _nodes[eidx]; // Get ending Node + Node *n = get_node(eidx); // Get ending Node int op = n->Opcode(); if (n->is_Mach()) { @@ -1761,7 +1761,7 @@ float Block::succ_prob(uint i) { float prob = n->as_MachIf()->_prob; assert(prob >= 0.0 && prob <= 1.0, "out of range probability"); // If succ[i] is the FALSE branch, invert path info - if( _nodes[i + eidx + 1]->Opcode() == Op_IfFalse ) { + if( get_node(i + eidx + 1)->Opcode() == Op_IfFalse ) { return 1.0f - prob; // not taken } else { return prob; // taken @@ -1773,7 +1773,7 @@ float Block::succ_prob(uint i) { return 1.0f/_num_succs; case Op_Catch: { - const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj(); + const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj(); if (ci->_con == CatchProjNode::fall_through_index) { // Fall-thru path gets the lion's share. return 1.0f - PROB_UNLIKELY_MAG(5)*_num_succs; @@ -1810,7 +1810,7 @@ float Block::succ_prob(uint i) { // Return the number of fall-through candidates for a block int Block::num_fall_throughs() { int eidx = end_idx(); - Node *n = _nodes[eidx]; // Get ending Node + Node *n = get_node(eidx); // Get ending Node int op = n->Opcode(); if (n->is_Mach()) { @@ -1834,7 +1834,7 @@ int Block::num_fall_throughs() { case Op_Catch: { for (uint i = 0; i < _num_succs; i++) { - const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj(); + const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj(); if (ci->_con == CatchProjNode::fall_through_index) { return 1; } @@ -1862,14 +1862,14 @@ int Block::num_fall_throughs() { // Return true if a specific successor could be fall-through target. bool Block::succ_fall_through(uint i) { int eidx = end_idx(); - Node *n = _nodes[eidx]; // Get ending Node + Node *n = get_node(eidx); // Get ending Node int op = n->Opcode(); if (n->is_Mach()) { if (n->is_MachNullCheck()) { // In theory, either side can fall-thru, for simplicity sake, // let's say only the false branch can now. - return _nodes[i + eidx + 1]->Opcode() == Op_IfFalse; + return get_node(i + eidx + 1)->Opcode() == Op_IfFalse; } op = n->as_Mach()->ideal_Opcode(); } @@ -1883,7 +1883,7 @@ bool Block::succ_fall_through(uint i) { return true; case Op_Catch: { - const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj(); + const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj(); return ci->_con == CatchProjNode::fall_through_index; } @@ -1907,7 +1907,7 @@ bool Block::succ_fall_through(uint i) { // Update the probability of a two-branch to be uncommon void Block::update_uncommon_branch(Block* ub) { int eidx = end_idx(); - Node *n = _nodes[eidx]; // Get ending Node + Node *n = get_node(eidx); // Get ending Node int op = n->as_Mach()->ideal_Opcode(); @@ -1923,7 +1923,7 @@ void Block::update_uncommon_branch(Block* ub) { // If ub is the true path, make the proability small, else // ub is the false path, and make the probability large - bool invert = (_nodes[s + eidx + 1]->Opcode() == Op_IfFalse); + bool invert = (get_node(s + eidx + 1)->Opcode() == Op_IfFalse); // Get existing probability float p = n->as_MachIf()->_prob; diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp index 06cecaddbdc..9f67a652eec 100644 --- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp +++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp @@ -639,8 +639,8 @@ void IdealGraphPrinter::walk_nodes(Node *start, bool edges, VectorSet* temp_set) // reachable but are in the CFG so add them here. for (uint i = 0; i < C->cfg()->number_of_blocks(); i++) { Block* block = C->cfg()->get_block(i); - for (uint s = 0; s < block->_nodes.size(); s++) { - nodeStack.push(block->_nodes[s]); + for (uint s = 0; s < block->number_of_nodes(); s++) { + nodeStack.push(block->get_node(s)); } } } @@ -713,9 +713,9 @@ void IdealGraphPrinter::print(Compile* compile, const char *name, Node *node, in tail(SUCCESSORS_ELEMENT); head(NODES_ELEMENT); - for (uint s = 0; s < block->_nodes.size(); s++) { + for (uint s = 0; s < block->number_of_nodes(); s++) { begin_elem(NODE_ELEMENT); - print_attr(NODE_ID_PROPERTY, get_node_id(block->_nodes[s])); + print_attr(NODE_ID_PROPERTY, get_node_id(block->get_node(s))); end_elem(); } tail(NODES_ELEMENT); diff --git a/hotspot/src/share/vm/opto/ifg.cpp b/hotspot/src/share/vm/opto/ifg.cpp index 4455cd4571f..db8dbea84d7 100644 --- a/hotspot/src/share/vm/opto/ifg.cpp +++ b/hotspot/src/share/vm/opto/ifg.cpp @@ -319,7 +319,7 @@ void PhaseChaitin::build_ifg_virtual( ) { // value is then removed from the live-ness set and it's inputs are // added to the live-ness set. for (uint j = block->end_idx() + 1; j > 1; j--) { - Node* n = block->_nodes[j - 1]; + Node* n = block->get_node(j - 1); // Get value being defined uint r = _lrg_map.live_range_id(n); @@ -456,7 +456,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { // Compute first nonphi node index uint first_inst; for (first_inst = 1; first_inst < last_inst; first_inst++) { - if (!block->_nodes[first_inst]->is_Phi()) { + if (!block->get_node(first_inst)->is_Phi()) { break; } } @@ -464,15 +464,15 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { // Spills could be inserted before CreateEx node which should be // first instruction in block after Phis. Move CreateEx up. for (uint insidx = first_inst; insidx < last_inst; insidx++) { - Node *ex = block->_nodes[insidx]; + Node *ex = block->get_node(insidx); if (ex->is_SpillCopy()) { continue; } if (insidx > first_inst && ex->is_Mach() && ex->as_Mach()->ideal_Opcode() == Op_CreateEx) { // If the CreateEx isn't above all the MachSpillCopies // then move it to the top. - block->_nodes.remove(insidx); - block->_nodes.insert(first_inst, ex); + block->remove_node(insidx); + block->insert_node(ex, first_inst); } // Stop once a CreateEx or any other node is found break; @@ -523,7 +523,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { // to the live-ness set. uint j; for (j = last_inst + 1; j > 1; j--) { - Node* n = block->_nodes[j - 1]; + Node* n = block->get_node(j - 1); // Get value being defined uint r = _lrg_map.live_range_id(n); @@ -541,7 +541,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { if( !n->is_Proj() || // Could also be a flags-projection of a dead ADD or such. (_lrg_map.live_range_id(def) && !liveout.member(_lrg_map.live_range_id(def)))) { - block->_nodes.remove(j - 1); + block->remove_node(j - 1); if (lrgs(r)._def == n) { lrgs(r)._def = 0; } @@ -605,7 +605,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { // (j - 1) is index for current instruction 'n' Node *m = n; for (uint i = j; i <= last_inst && m->is_SpillCopy(); ++i) { - m = block->_nodes[i]; + m = block->get_node(i); } if (m == single_use) { lrgs(r)._area = 0.0; @@ -772,20 +772,20 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { // Compute high pressure indice; avoid landing in the middle of projnodes j = hrp_index[0]; - if (j < block->_nodes.size() && j < block->end_idx() + 1) { - Node* cur = block->_nodes[j]; + if (j < block->number_of_nodes() && j < block->end_idx() + 1) { + Node* cur = block->get_node(j); while (cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch()) { j--; - cur = block->_nodes[j]; + cur = block->get_node(j); } } block->_ihrp_index = j; j = hrp_index[1]; - if (j < block->_nodes.size() && j < block->end_idx() + 1) { - Node* cur = block->_nodes[j]; + if (j < block->number_of_nodes() && j < block->end_idx() + 1) { + Node* cur = block->get_node(j); while (cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch()) { j--; - cur = block->_nodes[j]; + cur = block->get_node(j); } } block->_fhrp_index = j; diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp index 8d9daa54b86..2b28ee873bf 100644 --- a/hotspot/src/share/vm/opto/lcm.cpp +++ b/hotspot/src/share/vm/opto/lcm.cpp @@ -75,11 +75,11 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe // Get the successor block for if the test ptr is non-null Block* not_null_block; // this one goes with the proj Block* null_block; - if (_nodes[_nodes.size()-1] == proj) { + if (get_node(number_of_nodes()-1) == proj) { null_block = _succs[0]; not_null_block = _succs[1]; } else { - assert(_nodes[_nodes.size()-2] == proj, "proj is one or the other"); + assert(get_node(number_of_nodes()-2) == proj, "proj is one or the other"); not_null_block = _succs[0]; null_block = _succs[1]; } @@ -94,7 +94,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe { bool found_trap = false; for (uint i1 = 0; i1 < null_block->_nodes.size(); i1++) { - Node* nn = null_block->_nodes[i1]; + Node* nn = null_block->get_node(i1); if (nn->is_MachCall() && nn->as_MachCall()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point()) { const Type* trtype = nn->in(TypeFunc::Parms)->bottom_type(); @@ -282,7 +282,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe while( b != this ) { uint k; for( k = 1; k < b->_nodes.size(); k++ ) { - Node *n = b->_nodes[k]; + Node *n = b->get_node(k); if( n->needs_anti_dependence_check() && n->in(LoadNode::Memory) == mach->in(StoreNode::Memory) ) break; // Found anti-dependent load @@ -344,8 +344,8 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe cfg->map_node_to_block(best, this); // Move the control dependence - if (best->in(0) && best->in(0) == old_block->_nodes[0]) - best->set_req(0, _nodes[0]); + if (best->in(0) && best->in(0) == old_block->head()) + best->set_req(0, head()); // Check for flag-killing projections that also need to be hoisted // Should be DU safe because no edge updates. @@ -368,8 +368,8 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe // We need to flip the projections to keep the same semantics. if( proj->Opcode() == Op_IfTrue ) { // Swap order of projections in basic block to swap branch targets - Node *tmp1 = _nodes[end_idx()+1]; - Node *tmp2 = _nodes[end_idx()+2]; + Node *tmp1 = get_node(end_idx()+1); + Node *tmp2 = get_node(end_idx()+2); _nodes.map(end_idx()+1, tmp2); _nodes.map(end_idx()+2, tmp1); Node *tmp = new (C) Node(C->top()); // Use not NULL input @@ -624,7 +624,7 @@ uint Block::sched_call( Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_Lis int op = mcall->ideal_Opcode(); MachProjNode *proj = new (matcher.C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj ); cfg->map_node_to_block(proj, this); - _nodes.insert(node_cnt++, proj); + insert_node(proj, node_cnt++); // Select the right register save policy. const char * save_policy; @@ -685,7 +685,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & tty->print_cr("# --- schedule_local B%d, before: ---", _pre_order); for (uint i = 0;i < _nodes.size();i++) { tty->print("# "); - _nodes[i]->fast_dump(); + get_node(i)->fast_dump(); } tty->print_cr("#"); } @@ -699,11 +699,11 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & uint phi_cnt = 1; uint i; for( i = 1; iis_Phi() || // Found a PhiNode or ParmNode (n->is_Proj() && n->in(0) == head()) ) { // Move guy at 'phi_cnt' to the end; makes a hole at phi_cnt - _nodes.map(i,_nodes[phi_cnt]); + _nodes.map(i,get_node(phi_cnt)); _nodes.map(phi_cnt++,n); // swap Phi/Parm up front } else { // All others // Count block-local inputs to 'n' @@ -748,12 +748,12 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & } } for(uint i2=i; i2<_nodes.size(); i2++ ) // Trailing guys get zapped count - ready_cnt.at_put(_nodes[i2]->_idx, 0); + ready_cnt.at_put(get_node(i2)->_idx, 0); // All the prescheduled guys do not hold back internal nodes uint i3; for(i3 = 0; i3fast_outs(jmax); j < jmax; j++) { Node* m = n->fast_out(j); if (cfg->get_block_for_node(m) == this) { // Local-block user @@ -767,7 +767,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & // Make a worklist Node_List worklist; for(uint i4=i3; i4_idx) ) { // Zero ready count? if (m->is_iteratively_computed()) { // Push induction variable increments last to allow other uses @@ -789,12 +789,12 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & } // Warm up the 'next_call' heuristic bits - needed_for_next_call(_nodes[0], next_call, cfg); + needed_for_next_call(head(), next_call, cfg); #ifndef PRODUCT if (cfg->trace_opto_pipelining()) { for (uint j=0; j<_nodes.size(); j++) { - Node *n = _nodes[j]; + Node *n = get_node(j); int idx = n->_idx; tty->print("# ready cnt:%3d ", ready_cnt.at(idx)); tty->print("latency:%3d ", cfg->get_latency_for_node(n)); @@ -851,7 +851,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & MachProjNode *proj = new (matcher.C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); cfg->map_node_to_block(proj, this); - _nodes.insert(phi_cnt++, proj); + insert_node(proj, phi_cnt++); add_call_kills(proj, regs, matcher._c_reg_save_policy, false); } @@ -893,7 +893,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & tty->print_cr("# after schedule_local"); for (uint i = 0;i < _nodes.size();i++) { tty->print("# "); - _nodes[i]->fast_dump(); + get_node(i)->fast_dump(); } tty->cr(); } @@ -952,7 +952,7 @@ static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def // Check to see if the use_blk already has an identical phi inserted. // If it exists, it will be at the first position since all uses of a // def are processed together. - Node *phi = use_blk->_nodes[1]; + Node *phi = use_blk->get_node(1); if( phi->is_Phi() ) { fixup = phi; for (uint k = 1; k < use_blk->num_preds(); k++) { @@ -967,7 +967,7 @@ static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def // If an existing PhiNode was not found, make a new one. if (fixup == NULL) { Node *new_phi = PhiNode::make(use_blk->head(), def); - use_blk->_nodes.insert(1, new_phi); + use_blk->insert_node(new_phi, 1); cfg->map_node_to_block(new_phi, use_blk); for (uint k = 1; k < use_blk->num_preds(); k++) { new_phi->set_req(k, inputs[k]); @@ -977,7 +977,7 @@ static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def } else { // Found the use just below the Catch. Make it use the clone. - fixup = use_blk->_nodes[n_clone_idx]; + fixup = use_blk->get_node(n_clone_idx); } return fixup; @@ -997,11 +997,11 @@ static void catch_cleanup_intra_block(Node *use, Node *def, Block *blk, int beg, for( uint k = 0; k < blk->_num_succs; k++ ) { // Get clone in each successor block Block *sb = blk->_succs[k]; - Node *clone = sb->_nodes[offset_idx+1]; + Node *clone = sb->get_node(offset_idx+1); assert( clone->Opcode() == use->Opcode(), "" ); // Make use-clone reference the def-clone - catch_cleanup_fix_all_inputs(clone, def, sb->_nodes[n_clone_idx]); + catch_cleanup_fix_all_inputs(clone, def, sb->get_node(n_clone_idx)); } } @@ -1022,11 +1022,11 @@ void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { // End of region to clone uint end = end_idx(); - if( !_nodes[end]->is_Catch() ) return; + if( !get_node(end)->is_Catch() ) return; // Start of region to clone uint beg = end; - while(!_nodes[beg-1]->is_MachProj() || - !_nodes[beg-1]->in(0)->is_MachCall() ) { + while(!get_node(beg-1)->is_MachProj() || + !get_node(beg-1)->in(0)->is_MachCall() ) { beg--; assert(beg > 0,"Catch cleanup walking beyond block boundary"); } @@ -1041,8 +1041,8 @@ void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { for( uint j = end; j > beg; j-- ) { // It is safe here to clone a node with anti_dependence // since clones dominate on each path. - Node *clone = _nodes[j-1]->clone(); - sb->_nodes.insert( 1, clone ); + Node *clone = get_node(j-1)->clone(); + sb->insert_node(clone, 1); cfg->map_node_to_block(clone, sb); } } @@ -1051,7 +1051,7 @@ void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { // Fixup edges. Check the def-use info per cloned Node for(uint i2 = beg; i2 < end; i2++ ) { uint n_clone_idx = i2-beg+1; // Index of clone of n in each successor block - Node *n = _nodes[i2]; // Node that got cloned + Node *n = get_node(i2); // Node that got cloned // Need DU safe iterator because of edge manipulation in calls. Unique_Node_List *out = new Unique_Node_List(Thread::current()->resource_area()); for (DUIterator_Fast j1max, j1 = n->fast_outs(j1max); j1 < j1max; j1++) { @@ -1081,8 +1081,8 @@ void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { // Remove the now-dead cloned ops for(uint i3 = beg; i3 < end; i3++ ) { - _nodes[beg]->disconnect_inputs(NULL, C); - _nodes.remove(beg); + get_node(beg)->disconnect_inputs(NULL, C); + remove_node(beg); } // If the successor blocks have a CreateEx node, move it back to the top @@ -1091,20 +1091,20 @@ void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { uint new_cnt = end - beg; // Remove any newly created, but dead, nodes. for( uint j = new_cnt; j > 0; j-- ) { - Node *n = sb->_nodes[j]; + Node *n = sb->get_node(j); if (n->outcnt() == 0 && (!n->is_Proj() || n->as_Proj()->in(0)->outcnt() == 1) ){ n->disconnect_inputs(NULL, C); - sb->_nodes.remove(j); + sb->remove_node(j); new_cnt--; } } // If any newly created nodes remain, move the CreateEx node to the top if (new_cnt > 0) { - Node *cex = sb->_nodes[1+new_cnt]; + Node *cex = sb->get_node(1+new_cnt); if( cex->is_Mach() && cex->as_Mach()->ideal_Opcode() == Op_CreateEx ) { - sb->_nodes.remove(1+new_cnt); - sb->_nodes.insert(1,cex); + sb->remove_node(1+new_cnt); + sb->insert_node(cex, 1); } } } diff --git a/hotspot/src/share/vm/opto/live.cpp b/hotspot/src/share/vm/opto/live.cpp index ab7381b639d..280d22204c2 100644 --- a/hotspot/src/share/vm/opto/live.cpp +++ b/hotspot/src/share/vm/opto/live.cpp @@ -85,8 +85,8 @@ void PhaseLive::compute(uint maxlrg) { IndexSet* def = &_defs[block->_pre_order-1]; DEBUG_ONLY(IndexSet *def_outside = getfreeset();) uint i; - for (i = block->_nodes.size(); i > 1; i--) { - Node* n = block->_nodes[i-1]; + for (i = block->number_of_nodes(); i > 1; i--) { + Node* n = block->get_node(i-1); if (n->is_Phi()) { break; } @@ -112,7 +112,7 @@ void PhaseLive::compute(uint maxlrg) { #endif // Remove anything defined by Phis and the block start instruction for (uint k = i; k > 0; k--) { - uint r = _names[block->_nodes[k - 1]->_idx]; + uint r = _names[block->get_node(k - 1)->_idx]; def->insert(r); use->remove(r); } @@ -124,7 +124,7 @@ void PhaseLive::compute(uint maxlrg) { // PhiNode uses go in the live-out set of prior blocks. for (uint k = i; k > 0; k--) { - add_liveout(p, _names[block->_nodes[k-1]->in(l)->_idx], first_pass); + add_liveout(p, _names[block->get_node(k-1)->in(l)->_idx], first_pass); } } freeset(block); @@ -254,10 +254,10 @@ void PhaseLive::add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ) { void PhaseLive::dump( const Block *b ) const { tty->print("Block %d: ",b->_pre_order); tty->print("LiveOut: "); _live[b->_pre_order-1].dump(); - uint cnt = b->_nodes.size(); + uint cnt = b->number_of_nodes(); for( uint i=0; iprint("L%d/", _names[b->_nodes[i]->_idx] ); - b->_nodes[i]->dump(); + tty->print("L%d/", _names[b->get_node(i)->_idx] ); + b->get_node(i)->dump(); } tty->print("\n"); } @@ -269,7 +269,7 @@ void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const { for (uint i = 0; i < _cfg.number_of_blocks(); i++) { Block* block = _cfg.get_block(i); for (uint j = block->end_idx() + 1; j > 1; j--) { - Node* n = block->_nodes[j-1]; + Node* n = block->get_node(j-1); if (n->is_Phi()) { break; } diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index 0f1d31c07fe..6232c41f0b1 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -57,7 +57,7 @@ extern int emit_deopt_handler(CodeBuffer &cbuf); // Convert Nodes to instruction bits and pass off to the VM void Compile::Output() { // RootNode goes - assert( _cfg->get_root_block()->_nodes.size() == 0, "" ); + assert( _cfg->get_root_block()->number_of_nodes() == 0, "" ); // The number of new nodes (mostly MachNop) is proportional to // the number of java calls and inner loops which are aligned. @@ -70,11 +70,11 @@ void Compile::Output() { Block *entry = _cfg->get_block(1); Block *broot = _cfg->get_root_block(); - const StartNode *start = entry->_nodes[0]->as_Start(); + const StartNode *start = entry->head()->as_Start(); // Replace StartNode with prolog MachPrologNode *prolog = new (this) MachPrologNode(); - entry->_nodes.map( 0, prolog ); + entry->map_node(prolog, 0); _cfg->map_node_to_block(prolog, entry); _cfg->unmap_node_from_block(start); // start is no longer in any block @@ -144,8 +144,8 @@ void Compile::Output() { for (uint i = 0; i < _cfg->number_of_blocks(); i++) { tty->print("\nBB#%03d:\n", i); Block* block = _cfg->get_block(i); - for (uint j = 0; j < block->_nodes.size(); j++) { - Node* n = block->_nodes[j]; + for (uint j = 0; j < block->number_of_nodes(); j++) { + Node* n = block->get_node(j); OptoReg::Name reg = _regalloc->get_reg_first(n); tty->print(" %-6s ", reg >= 0 && reg < REG_COUNT ? Matcher::regName[reg] : ""); n->dump(); @@ -226,8 +226,8 @@ void Compile::Insert_zap_nodes() { // Insert call to zap runtime stub before every node with an oop map for( uint i=0; i<_cfg->number_of_blocks(); i++ ) { Block *b = _cfg->get_block(i); - for ( uint j = 0; j < b->_nodes.size(); ++j ) { - Node *n = b->_nodes[j]; + for ( uint j = 0; j < b->number_of_nodes(); ++j ) { + Node *n = b->get_node(j); // Determining if we should insert a zap-a-lot node in output. // We do that for all nodes that has oopmap info, except for calls @@ -256,7 +256,7 @@ void Compile::Insert_zap_nodes() { } if (insert) { Node *zap = call_zap_node(n->as_MachSafePoint(), i); - b->_nodes.insert( j, zap ); + b->insert_node(zap, j); _cfg->map_node_to_block(zap, b); ++j; } @@ -379,10 +379,10 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size DEBUG_ONLY( jmp_rule[i] = 0; ) // Sum all instruction sizes to compute block size - uint last_inst = block->_nodes.size(); + uint last_inst = block->number_of_nodes(); uint blk_size = 0; for (uint j = 0; j < last_inst; j++) { - Node* nj = block->_nodes[j]; + Node* nj = block->get_node(j); // Handle machine instruction nodes if (nj->is_Mach()) { MachNode *mach = nj->as_Mach(); @@ -477,18 +477,18 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size for (uint i = 0; i < nblocks; i++) { Block* block = _cfg->get_block(i); int idx = jmp_nidx[i]; - MachNode* mach = (idx == -1) ? NULL: block->_nodes[idx]->as_Mach(); + MachNode* mach = (idx == -1) ? NULL: block->get_node(idx)->as_Mach(); if (mach != NULL && mach->may_be_short_branch()) { #ifdef ASSERT assert(jmp_size[i] > 0 && mach->is_MachBranch(), "sanity"); int j; // Find the branch; ignore trailing NOPs. - for (j = block->_nodes.size()-1; j>=0; j--) { - Node* n = block->_nodes[j]; + for (j = block->number_of_nodes()-1; j>=0; j--) { + Node* n = block->get_node(j); if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) break; } - assert(j >= 0 && j == idx && block->_nodes[j] == (Node*)mach, "sanity"); + assert(j >= 0 && j == idx && block->get_node(j) == (Node*)mach, "sanity"); #endif int br_size = jmp_size[i]; int br_offs = blk_starts[i] + jmp_offset[i]; @@ -522,7 +522,7 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size diff -= nop_size; } adjust_block_start += diff; - block->_nodes.map(idx, replacement); + block->map_node(replacement, idx); mach->subsume_by(replacement, C); mach = replacement; progress = true; @@ -1088,8 +1088,8 @@ CodeBuffer* Compile::init_buffer(uint* blk_starts) { for (uint i = 0; i < _cfg->number_of_blocks(); i++) { Block* b = _cfg->get_block(i); - for (uint j = 0; j < b->_nodes.size(); j++) { - Node* n = b->_nodes[j]; + for (uint j = 0; j < b->number_of_nodes(); j++) { + Node* n = b->get_node(j); // If the node is a MachConstantNode evaluate the constant // value section. @@ -1247,14 +1247,14 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { // Define the label at the beginning of the basic block MacroAssembler(cb).bind(blk_labels[block->_pre_order]); - uint last_inst = block->_nodes.size(); + uint last_inst = block->number_of_nodes(); // Emit block normally, except for last instruction. // Emit means "dump code bits into code buffer". for (uint j = 0; j_nodes[j]; + Node* n = block->get_node(j); // See if delay slots are supported if (valid_bundle_info(n) && @@ -1308,7 +1308,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { assert((padding % nop_size) == 0, "padding is not a multiple of NOP size"); int nops_cnt = padding / nop_size; MachNode *nop = new (this) MachNopNode(nops_cnt); - block->_nodes.insert(j++, nop); + block->insert_node(nop, j++); last_inst++; _cfg->map_node_to_block(nop, block); nop->emit(*cb, _regalloc); @@ -1394,7 +1394,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { // Insert padding between avoid_back_to_back branches. if (needs_padding && replacement->avoid_back_to_back()) { MachNode *nop = new (this) MachNopNode(); - block->_nodes.insert(j++, nop); + block->insert_node(nop, j++); _cfg->map_node_to_block(nop, block); last_inst++; nop->emit(*cb, _regalloc); @@ -1407,7 +1407,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { jmp_size[i] = new_size; jmp_rule[i] = mach->rule(); #endif - block->_nodes.map(j, replacement); + block->map_node(replacement, j); mach->subsume_by(replacement, C); n = replacement; mach = replacement; @@ -1438,7 +1438,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { count++; uint i4; for (i4 = 0; i4 < last_inst; ++i4) { - if (block->_nodes[i4] == oop_store) { + if (block->get_node(i4) == oop_store) { break; } } @@ -1548,7 +1548,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { int padding = nb->alignment_padding(current_offset); if( padding > 0 ) { MachNode *nop = new (this) MachNopNode(padding / nop_size); - block->_nodes.insert(block->_nodes.size(), nop); + block->insert_node(nop, block->number_of_nodes()); _cfg->map_node_to_block(nop, block); nop->emit(*cb, _regalloc); current_offset = cb->insts_size(); @@ -1655,8 +1655,8 @@ void Compile::FillExceptionTables(uint cnt, uint *call_returns, uint *inct_start int j; // Find the branch; ignore trailing NOPs. - for (j = block->_nodes.size() - 1; j >= 0; j--) { - n = block->_nodes[j]; + for (j = block->number_of_nodes() - 1; j >= 0; j--) { + n = block->get_node(j); if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) { break; } @@ -1675,8 +1675,8 @@ void Compile::FillExceptionTables(uint cnt, uint *call_returns, uint *inct_start uint call_return = call_returns[block->_pre_order]; #ifdef ASSERT assert( call_return > 0, "no call seen for this basic block" ); - while (block->_nodes[--j]->is_MachProj()) ; - assert(block->_nodes[j]->is_MachCall(), "CatchProj must follow call"); + while (block->get_node(--j)->is_MachProj()) ; + assert(block->get_node(j)->is_MachCall(), "CatchProj must follow call"); #endif // last instruction is a CatchNode, find it's CatchProjNodes int nof_succs = block->_num_succs; @@ -1782,7 +1782,7 @@ Scheduling::Scheduling(Arena *arena, Compile &compile) // Get the last node Block* block = _cfg->get_block(_cfg->number_of_blocks() - 1); - _next_node = block->_nodes[block->_nodes.size() - 1]; + _next_node = block->get_node(block->number_of_nodes() - 1); } #ifndef PRODUCT @@ -1875,7 +1875,7 @@ void Scheduling::ComputeLocalLatenciesForward(const Block *bb) { // Used to allow latency 0 to force an instruction to the beginning // of the bb uint latency = 1; - Node *use = bb->_nodes[j]; + Node *use = bb->get_node(j); uint nlen = use->len(); // Walk over all the inputs @@ -2286,7 +2286,7 @@ void Scheduling::AddNodeToBundle(Node *n, const Block *bb) { (OptoReg::is_valid(_regalloc->get_reg_first(n)) || op != Op_BoxLock)) ) { // Push any trailing projections - if( bb->_nodes[bb->_nodes.size()-1] != n ) { + if( bb->get_node(bb->number_of_nodes()-1) != n ) { for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { Node *foi = n->fast_out(i); if( foi->is_Proj() ) @@ -2329,21 +2329,21 @@ void Scheduling::ComputeUseCount(const Block *bb) { _unconditional_delay_slot = NULL; #ifdef ASSERT - for( uint i=0; i < bb->_nodes.size(); i++ ) - assert( _uses[bb->_nodes[i]->_idx] == 0, "_use array not clean" ); + for( uint i=0; i < bb->number_of_nodes(); i++ ) + assert( _uses[bb->get_node(i)->_idx] == 0, "_use array not clean" ); #endif // Force the _uses count to never go to zero for unscheduable pieces // of the block for( uint k = 0; k < _bb_start; k++ ) - _uses[bb->_nodes[k]->_idx] = 1; - for( uint l = _bb_end; l < bb->_nodes.size(); l++ ) - _uses[bb->_nodes[l]->_idx] = 1; + _uses[bb->get_node(k)->_idx] = 1; + for( uint l = _bb_end; l < bb->number_of_nodes(); l++ ) + _uses[bb->get_node(l)->_idx] = 1; // Iterate backwards over the instructions in the block. Don't count the // branch projections at end or the block header instructions. for( uint j = _bb_end-1; j >= _bb_start; j-- ) { - Node *n = bb->_nodes[j]; + Node *n = bb->get_node(j); if( n->is_Proj() ) continue; // Projections handled another way // Account for all uses @@ -2398,8 +2398,8 @@ void Scheduling::DoScheduling() { #ifndef PRODUCT if (_cfg->C->trace_opto_output()) { tty->print("# Schedule BB#%03d (initial)\n", i); - for (uint j = 0; j < bb->_nodes.size(); j++) { - bb->_nodes[j]->dump(); + for (uint j = 0; j < bb->number_of_nodes(); j++) { + bb->get_node(j)->dump(); } } #endif @@ -2426,10 +2426,10 @@ void Scheduling::DoScheduling() { } // Leave untouched the starting instruction, any Phis, a CreateEx node - // or Top. bb->_nodes[_bb_start] is the first schedulable instruction. - _bb_end = bb->_nodes.size()-1; + // or Top. bb->get_node(_bb_start) is the first schedulable instruction. + _bb_end = bb->number_of_nodes()-1; for( _bb_start=1; _bb_start <= _bb_end; _bb_start++ ) { - Node *n = bb->_nodes[_bb_start]; + Node *n = bb->get_node(_bb_start); // Things not matched, like Phinodes and ProjNodes don't get scheduled. // Also, MachIdealNodes do not get scheduled if( !n->is_Mach() ) continue; // Skip non-machine nodes @@ -2449,19 +2449,19 @@ void Scheduling::DoScheduling() { // in the block), because they have delay slots we can fill. Calls all // have their delay slots filled in the template expansions, so we don't // bother scheduling them. - Node *last = bb->_nodes[_bb_end]; + Node *last = bb->get_node(_bb_end); // Ignore trailing NOPs. while (_bb_end > 0 && last->is_Mach() && last->as_Mach()->ideal_Opcode() == Op_Con) { - last = bb->_nodes[--_bb_end]; + last = bb->get_node(--_bb_end); } assert(!last->is_Mach() || last->as_Mach()->ideal_Opcode() != Op_Con, ""); if( last->is_Catch() || // Exclude unreachable path case when Halt node is in a separate block. (_bb_end > 1 && last->is_Mach() && last->as_Mach()->ideal_Opcode() == Op_Halt) ) { // There must be a prior call. Skip it. - while( !bb->_nodes[--_bb_end]->is_MachCall() ) { - assert( bb->_nodes[_bb_end]->is_MachProj(), "skipping projections after expected call" ); + while( !bb->get_node(--_bb_end)->is_MachCall() ) { + assert( bb->get_node(_bb_end)->is_MachProj(), "skipping projections after expected call" ); } } else if( last->is_MachNullCheck() ) { // Backup so the last null-checked memory instruction is @@ -2470,7 +2470,7 @@ void Scheduling::DoScheduling() { Node *mem = last->in(1); do { _bb_end--; - } while (mem != bb->_nodes[_bb_end]); + } while (mem != bb->get_node(_bb_end)); } else { // Set _bb_end to point after last schedulable inst. _bb_end++; @@ -2499,7 +2499,7 @@ void Scheduling::DoScheduling() { assert( _scheduled.size() == _bb_end - _bb_start, "wrong number of instructions" ); #ifdef ASSERT for( uint l = _bb_start; l < _bb_end; l++ ) { - Node *n = bb->_nodes[l]; + Node *n = bb->get_node(l); uint m; for( m = 0; m < _bb_end-_bb_start; m++ ) if( _scheduled[m] == n ) @@ -2510,14 +2510,14 @@ void Scheduling::DoScheduling() { // Now copy the instructions (in reverse order) back to the block for ( uint k = _bb_start; k < _bb_end; k++ ) - bb->_nodes.map(k, _scheduled[_bb_end-k-1]); + bb->map_node(_scheduled[_bb_end-k-1], k); #ifndef PRODUCT if (_cfg->C->trace_opto_output()) { tty->print("# Schedule BB#%03d (final)\n", i); uint current = 0; - for (uint j = 0; j < bb->_nodes.size(); j++) { - Node *n = bb->_nodes[j]; + for (uint j = 0; j < bb->number_of_nodes(); j++) { + Node *n = bb->get_node(j); if( valid_bundle_info(n) ) { Bundle *bundle = node_bundling(n); if (bundle->instr_count() > 0 || bundle->flags() > 0) { @@ -2579,8 +2579,8 @@ void Scheduling::verify_good_schedule( Block *b, const char *msg ) { // Walk over the block backwards. Check to make sure each DEF doesn't // kill a live value (other than the one it's supposed to). Add each // USE to the live set. - for( uint i = b->_nodes.size()-1; i >= _bb_start; i-- ) { - Node *n = b->_nodes[i]; + for( uint i = b->number_of_nodes()-1; i >= _bb_start; i-- ) { + Node *n = b->get_node(i); int n_op = n->Opcode(); if( n_op == Op_MachProj && n->ideal_reg() == MachProjNode::fat_proj ) { // Fat-proj kills a slew of registers @@ -2711,7 +2711,7 @@ void Scheduling::anti_do_use( Block *b, Node *use, OptoReg::Name use_reg ) { pinch->req() == 1 ) { // pinch not yet in block? pinch->del_req(0); // yank pointer to later-def, also set flag // Insert the pinch-point in the block just after the last use - b->_nodes.insert(b->find_node(use)+1,pinch); + b->insert_node(pinch, b->find_node(use) + 1); _bb_end++; // Increase size scheduled region in block } @@ -2763,10 +2763,10 @@ void Scheduling::ComputeRegisterAntidependencies(Block *b) { // it being in the current block. bool fat_proj_seen = false; uint last_safept = _bb_end-1; - Node* end_node = (_bb_end-1 >= _bb_start) ? b->_nodes[last_safept] : NULL; + Node* end_node = (_bb_end-1 >= _bb_start) ? b->get_node(last_safept) : NULL; Node* last_safept_node = end_node; for( uint i = _bb_end-1; i >= _bb_start; i-- ) { - Node *n = b->_nodes[i]; + Node *n = b->get_node(i); int is_def = n->outcnt(); // def if some uses prior to adding precedence edges if( n->is_MachProj() && n->ideal_reg() == MachProjNode::fat_proj ) { // Fat-proj kills a slew of registers @@ -2815,7 +2815,7 @@ void Scheduling::ComputeRegisterAntidependencies(Block *b) { // Do not allow defs of new derived values to float above GC // points unless the base is definitely available at the GC point. - Node *m = b->_nodes[i]; + Node *m = b->get_node(i); // Add precedence edge from following safepoint to use of derived pointer if( last_safept_node != end_node && @@ -2832,11 +2832,11 @@ void Scheduling::ComputeRegisterAntidependencies(Block *b) { if( n->jvms() ) { // Precedence edge from derived to safept // Check if last_safept_node was moved by pinch-point insertion in anti_do_use() - if( b->_nodes[last_safept] != last_safept_node ) { + if( b->get_node(last_safept) != last_safept_node ) { last_safept = b->find_node(last_safept_node); } for( uint j=last_safept; j > i; j-- ) { - Node *mach = b->_nodes[j]; + Node *mach = b->get_node(j); if( mach->is_Mach() && mach->as_Mach()->ideal_Opcode() == Op_AddP ) mach->add_prec( n ); } diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index a1d1527127e..71c8d8afcd8 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -1648,10 +1648,10 @@ void PhasePeephole::do_transform() { bool block_not_printed = true; // and each instruction within a block - uint end_index = block->_nodes.size(); + uint end_index = block->number_of_nodes(); // block->end_idx() not valid after PhaseRegAlloc for( uint instruction_index = 1; instruction_index < end_index; ++instruction_index ) { - Node *n = block->_nodes.at(instruction_index); + Node *n = block->get_node(instruction_index); if( n->is_Mach() ) { MachNode *m = n->as_Mach(); int deleted_count = 0; @@ -1673,7 +1673,7 @@ void PhasePeephole::do_transform() { } // Print instructions being deleted for( int i = (deleted_count - 1); i >= 0; --i ) { - block->_nodes.at(instruction_index-i)->as_Mach()->format(_regalloc); tty->cr(); + block->get_node(instruction_index-i)->as_Mach()->format(_regalloc); tty->cr(); } tty->print_cr("replaced with"); // Print new instruction @@ -1687,11 +1687,11 @@ void PhasePeephole::do_transform() { // the node index to live range mappings.) uint safe_instruction_index = (instruction_index - deleted_count); for( ; (instruction_index > safe_instruction_index); --instruction_index ) { - block->_nodes.remove( instruction_index ); + block->remove_node( instruction_index ); } // install new node after safe_instruction_index - block->_nodes.insert( safe_instruction_index + 1, m2 ); - end_index = block->_nodes.size() - 1; // Recompute new block size + block->insert_node(m2, safe_instruction_index + 1); + end_index = block->number_of_nodes() - 1; // Recompute new block size NOT_PRODUCT( inc_peepholes(); ) } } diff --git a/hotspot/src/share/vm/opto/postaloc.cpp b/hotspot/src/share/vm/opto/postaloc.cpp index fdb72dd42c6..76de2ed16a1 100644 --- a/hotspot/src/share/vm/opto/postaloc.cpp +++ b/hotspot/src/share/vm/opto/postaloc.cpp @@ -423,8 +423,8 @@ void PhaseChaitin::post_allocate_copy_removal() { // Count of Phis in block uint phi_dex; - for (phi_dex = 1; phi_dex < block->_nodes.size(); phi_dex++) { - Node* phi = block->_nodes[phi_dex]; + for (phi_dex = 1; phi_dex < block->number_of_nodes(); phi_dex++) { + Node* phi = block->get_node(phi_dex); if (!phi->is_Phi()) { break; } @@ -439,7 +439,7 @@ void PhaseChaitin::post_allocate_copy_removal() { Block* pb = _cfg.get_block_for_node(block->pred(j)); // Remove copies along phi edges for (uint k = 1; k < phi_dex; k++) { - elide_copy(block->_nodes[k], j, block, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false); + elide_copy(block->get_node(k), j, block, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false); } if (blk2value[pb->_pre_order]) { // Have a mapping on this edge? // See if this predecessor's mappings have been used by everybody @@ -510,7 +510,7 @@ void PhaseChaitin::post_allocate_copy_removal() { // For all Phi's for (j = 1; j < phi_dex; j++) { uint k; - Node *phi = block->_nodes[j]; + Node *phi = block->get_node(j); uint pidx = _lrg_map.live_range_id(phi); OptoReg::Name preg = lrgs(_lrg_map.live_range_id(phi)).reg(); @@ -522,7 +522,7 @@ void PhaseChaitin::post_allocate_copy_removal() { u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input } if (u != NodeSentinel) { // Junk Phi. Remove - block->_nodes.remove(j--); + block->remove_node(j--); phi_dex--; _cfg.unmap_node_from_block(phi); phi->replace_by(u); @@ -552,8 +552,8 @@ void PhaseChaitin::post_allocate_copy_removal() { } // For all remaining instructions - for (j = phi_dex; j < block->_nodes.size(); j++) { - Node* n = block->_nodes[j]; + for (j = phi_dex; j < block->number_of_nodes(); j++) { + Node* n = block->get_node(j); if(n->outcnt() == 0 && // Dead? n != C->top() && // (ignore TOP, it has no du info) diff --git a/hotspot/src/share/vm/opto/reg_split.cpp b/hotspot/src/share/vm/opto/reg_split.cpp index ac4f8e35824..2c4ad874ffe 100644 --- a/hotspot/src/share/vm/opto/reg_split.cpp +++ b/hotspot/src/share/vm/opto/reg_split.cpp @@ -112,17 +112,17 @@ Node *PhaseChaitin::get_spillcopy_wide( Node *def, Node *use, uint uidx ) { void PhaseChaitin::insert_proj( Block *b, uint i, Node *spill, uint maxlrg ) { // Skip intervening ProjNodes. Do not insert between a ProjNode and // its definer. - while( i < b->_nodes.size() && - (b->_nodes[i]->is_Proj() || - b->_nodes[i]->is_Phi() ) ) + while( i < b->number_of_nodes() && + (b->get_node(i)->is_Proj() || + b->get_node(i)->is_Phi() ) ) i++; // Do not insert between a call and his Catch - if( b->_nodes[i]->is_Catch() ) { + if( b->get_node(i)->is_Catch() ) { // Put the instruction at the top of the fall-thru block. // Find the fall-thru projection while( 1 ) { - const CatchProjNode *cp = b->_nodes[++i]->as_CatchProj(); + const CatchProjNode *cp = b->get_node(++i)->as_CatchProj(); if( cp->_con == CatchProjNode::fall_through_index ) break; } @@ -131,7 +131,7 @@ void PhaseChaitin::insert_proj( Block *b, uint i, Node *spill, uint maxlrg ) { i = 1; // Right at start of block } - b->_nodes.insert(i,spill); // Insert node in block + b->insert_node(spill, i); // Insert node in block _cfg.map_node_to_block(spill, b); // Update node->block mapping to reflect // Adjust the point where we go hi-pressure if( i <= b->_ihrp_index ) b->_ihrp_index++; @@ -160,9 +160,9 @@ uint PhaseChaitin::split_DEF( Node *def, Block *b, int loc, uint maxlrg, Node ** // (The implicit_null_check function ensures the use is also dominated // by the branch-not-taken block.) Node *be = b->end(); - if( be->is_MachNullCheck() && be->in(1) == def && def == b->_nodes[loc] ) { + if( be->is_MachNullCheck() && be->in(1) == def && def == b->get_node(loc)) { // Spill goes in the branch-not-taken block - b = b->_succs[b->_nodes[b->end_idx()+1]->Opcode() == Op_IfTrue]; + b = b->_succs[b->get_node(b->end_idx()+1)->Opcode() == Op_IfTrue]; loc = 0; // Just past the Region } assert( loc >= 0, "must insert past block head" ); @@ -450,7 +450,7 @@ bool PhaseChaitin::prompt_use( Block *b, uint lidx ) { // Scan block for 1st use. for( uint i = 1; i <= b->end_idx(); i++ ) { - Node *n = b->_nodes[i]; + Node *n = b->get_node(i); // Ignore PHI use, these can be up or down if (n->is_Phi()) { continue; @@ -647,7 +647,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { // check block for appropriate phinode & update edges for( insidx = 1; insidx <= b->end_idx(); insidx++ ) { - n1 = b->_nodes[insidx]; + n1 = b->get_node(insidx); // bail if this is not a phi phi = n1->is_Phi() ? n1->as_Phi() : NULL; if( phi == NULL ) { @@ -747,7 +747,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { //----------Walk Instructions in the Block and Split---------- // For all non-phi instructions in the block for( insidx = 1; insidx <= b->end_idx(); insidx++ ) { - Node *n = b->_nodes[insidx]; + Node *n = b->get_node(insidx); // Find the defining Node's live range index uint defidx = _lrg_map.find_id(n); uint cnt = n->req(); @@ -776,7 +776,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { assert(_lrg_map.find_id(n) == _lrg_map.find_id(u), "should be the same lrg"); n->replace_by(u); // Then replace with unique input n->disconnect_inputs(NULL, C); - b->_nodes.remove(insidx); + b->remove_node(insidx); insidx--; b->_ihrp_index--; b->_fhrp_index--; @@ -789,12 +789,12 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { (b->_reg_pressure < (uint)INTPRESSURE) || b->_ihrp_index > 4000000 || b->_ihrp_index >= b->end_idx() || - !b->_nodes[b->_ihrp_index]->is_Proj(), "" ); + !b->get_node(b->_ihrp_index)->is_Proj(), "" ); assert( insidx > b->_fhrp_index || (b->_freg_pressure < (uint)FLOATPRESSURE) || b->_fhrp_index > 4000000 || b->_fhrp_index >= b->end_idx() || - !b->_nodes[b->_fhrp_index]->is_Proj(), "" ); + !b->get_node(b->_fhrp_index)->is_Proj(), "" ); // ********** Handle Crossing HRP Boundry ********** if( (insidx == b->_ihrp_index) || (insidx == b->_fhrp_index) ) { @@ -819,7 +819,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { // Insert point is just past last use or def in the block int insert_point = insidx-1; while( insert_point > 0 ) { - Node *n = b->_nodes[insert_point]; + Node *n = b->get_node(insert_point); // Hit top of block? Quit going backwards if (n->is_Phi()) { break; @@ -865,7 +865,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { } } // end if LRG is UP } // end for all spilling live ranges - assert( b->_nodes[insidx] == n, "got insidx set incorrectly" ); + assert( b->get_node(insidx) == n, "got insidx set incorrectly" ); } // end if crossing HRP Boundry // If the LRG index is oob, then this is a new spillcopy, skip it. @@ -878,7 +878,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { if (copyidx && defidx == _lrg_map.live_range_id(n->in(copyidx))) { n->replace_by( n->in(copyidx) ); n->set_req( copyidx, NULL ); - b->_nodes.remove(insidx--); + b->remove_node(insidx--); b->_ihrp_index--; // Adjust the point where we go hi-pressure b->_fhrp_index--; continue; @@ -932,10 +932,10 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { // Rematerializable? Then clone def at use site instead // of store/load if( def->rematerialize() ) { - int old_size = b->_nodes.size(); + int old_size = b->number_of_nodes(); def = split_Rematerialize( def, b, insidx, maxlrg, splits, slidx, lrg2reach, Reachblock, true ); if( !def ) return 0; // Bail out - insidx += b->_nodes.size()-old_size; + insidx += b->number_of_nodes()-old_size; } MachNode *mach = n->is_Mach() ? n->as_Mach() : NULL; @@ -1332,8 +1332,8 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { // so look at the node before it. int insert = pred->end_idx(); while (insert >= 1 && - pred->_nodes[insert - 1]->is_SpillCopy() && - _lrg_map.find(pred->_nodes[insert - 1]) >= lrgs_before_phi_split) { + pred->get_node(insert - 1)->is_SpillCopy() && + _lrg_map.find(pred->get_node(insert - 1)) >= lrgs_before_phi_split) { insert--; } def = split_Rematerialize(def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false); @@ -1402,7 +1402,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { for (bidx = 0; bidx < _cfg.number_of_blocks(); bidx++) { b = _cfg.get_block(bidx); for (insidx = 0; insidx <= b->end_idx(); insidx++) { - Node *n = b->_nodes[insidx]; + Node *n = b->get_node(insidx); uint defidx = _lrg_map.find(n); assert(defidx < _lrg_map.max_lrg_id(), "Bad live range index in Split"); assert(defidx < maxlrg,"Bad live range index in Split"); From 670c3329966260d1c67d3968f4b0a06bc3b33929 Mon Sep 17 00:00:00 2001 From: Dmitry Markov Date: Mon, 26 Aug 2013 17:21:48 +0400 Subject: [PATCH 0102/1294] 8023474: First mousepress doesn't start editing in JTree Reviewed-by: alexp, anthony --- jdk/src/share/classes/java/awt/Component.java | 11 ++ .../javax/swing/plaf/basic/BasicTreeUI.java | 9 +- .../share/classes/sun/awt/AWTAccessor.java | 7 +- .../basic/BasicTreeUI/8023474/bug8023474.java | 174 ++++++++++++++++++ 4 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 jdk/test/javax/swing/plaf/basic/BasicTreeUI/8023474/bug8023474.java diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index c3307538f27..23a16f7db3b 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -972,6 +972,10 @@ public abstract class Component implements ImageObserver, MenuContainer, public AccessControlContext getAccessControlContext(Component comp) { return comp.getAccessControlContext(); } + + public void revalidateSynchronously(Component comp) { + comp.revalidateSynchronously(); + } }); } @@ -2977,6 +2981,13 @@ public abstract class Component implements ImageObserver, MenuContainer, * @since 1.7 */ public void revalidate() { + revalidateSynchronously(); + } + + /** + * Revalidates the component synchronously. + */ + final void revalidateSynchronously() { synchronized (getTreeLock()) { invalidate(); diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java index 0e7cd1768e7..b91deec481d 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,7 @@ import javax.swing.plaf.TreeUI; import javax.swing.tree.*; import javax.swing.text.Position; import javax.swing.plaf.basic.DragRecognitionSupport.BeforeDrag; +import sun.awt.AWTAccessor; import sun.swing.SwingUtilities2; import sun.swing.DefaultLookup; @@ -2165,11 +2166,7 @@ public class BasicTreeUI extends TreeUI nodeBounds.width, nodeBounds.height); editingPath = path; - if (editingComponent instanceof JComponent) { - ((JComponent)editingComponent).revalidate(); - } else { - editingComponent.validate(); - } + AWTAccessor.getComponentAccessor().revalidateSynchronously(editingComponent); editingComponent.repaint(); if(cellEditor.shouldSelectCell(event)) { stopEditingInCompleteEditing = false; diff --git a/jdk/src/share/classes/sun/awt/AWTAccessor.java b/jdk/src/share/classes/sun/awt/AWTAccessor.java index 781750b0f1c..2b7f73ccd31 100644 --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2013, 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 @@ -236,6 +236,11 @@ public final class AWTAccessor { */ AccessControlContext getAccessControlContext(Component comp); + /** + * Revalidates the component synchronously. + */ + void revalidateSynchronously(Component comp); + } /* diff --git a/jdk/test/javax/swing/plaf/basic/BasicTreeUI/8023474/bug8023474.java b/jdk/test/javax/swing/plaf/basic/BasicTreeUI/8023474/bug8023474.java new file mode 100644 index 00000000000..6802db66945 --- /dev/null +++ b/jdk/test/javax/swing/plaf/basic/BasicTreeUI/8023474/bug8023474.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2013, 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 8023474 + * @summary Tests that the first mouse press starts editing in JTree + * @author Dmitry Markov + * @run main bug8023474 + */ + +import sun.awt.SunToolkit; + +import javax.swing.*; +import javax.swing.event.CellEditorListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeCellEditor; +import javax.swing.tree.TreeCellRenderer; +import java.awt.*; +import java.awt.event.InputEvent; +import java.util.EventObject; + +public class bug8023474 { + private static JTree tree; + + public static void main(String[] args) throws Exception { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + + toolkit.realSync(); + + Point point = getRowPointToClick(1); + robot.mouseMove(point.x, point.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + toolkit.realSync(); + + Boolean result = (Boolean)tree.getCellEditor().getCellEditorValue(); + if (!result) { + throw new RuntimeException("Test Failed!"); + } + } + + private static void createAndShowGUI() { + try { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + } catch (Exception e) { + throw new RuntimeException(e); + } + + DefaultMutableTreeNode root = new DefaultMutableTreeNode("root"); + DefaultMutableTreeNode item = new DefaultMutableTreeNode("item"); + DefaultMutableTreeNode subItem = new DefaultMutableTreeNode("subItem"); + + root.add(item); + item.add(subItem); + + DefaultTreeModel model = new DefaultTreeModel(root); + tree = new JTree(model); + + tree.setCellEditor(new Editor()); + tree.setEditable(true); + tree.setRowHeight(30); + tree.setCellRenderer(new CheckboxCellRenderer()); + + JFrame frame = new JFrame("bug8023474"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(new JScrollPane(tree)); + frame.setSize(400, 300); + frame.setVisible(true); + } + + private static Point getRowPointToClick(final int row) throws Exception { + final Point[] result = new Point[1]; + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + Rectangle rect = tree.getRowBounds(row); + Point point = new Point(rect.x + 10, rect.y + rect.height / 2); + SwingUtilities.convertPointToScreen(point, tree); + result[0] = point; + } + }); + return result[0]; + } + + private static class Editor extends JPanel implements TreeCellEditor { + private JCheckBox checkbox; + + public Editor() { + setOpaque(false); + checkbox = new JCheckBox(); + add(checkbox); + } + + public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, + boolean expanded, boolean leaf, int row) { + checkbox.setText(value.toString()); + checkbox.setSelected(false); + return this; + } + + public Object getCellEditorValue() { + return checkbox.isSelected(); + } + + public boolean isCellEditable(EventObject anEvent) { + return true; + } + + public boolean shouldSelectCell(EventObject anEvent) { + return true; + } + + public boolean stopCellEditing() { + return true; + } + + public void cancelCellEditing() { + } + + public void addCellEditorListener(CellEditorListener l) { + } + + public void removeCellEditorListener(CellEditorListener l) { + } + } + + private static class CheckboxCellRenderer extends JPanel implements TreeCellRenderer { + private JCheckBox checkbox; + + public CheckboxCellRenderer() { + setOpaque(false); + checkbox = new JCheckBox(); + add(checkbox); + } + + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, + boolean leaf, int row, boolean hasFocus) { + checkbox.setText(value.toString()); + checkbox.setSelected(false); + return this; + } + } +} From 90f87346313723a6a2561267fd4b46beb66033f1 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Mon, 26 Aug 2013 17:37:25 +0400 Subject: [PATCH 0103/1294] 8022456: LogCompilation tool does not work with C1 output again Reviewed-by: kvn --- .../sun/hotspot/tools/compiler/CallSite.java | 6 +++-- .../sun/hotspot/tools/compiler/LogParser.java | 26 +++++++++---------- hotspot/src/share/vm/c1/c1_Compilation.cpp | 9 ++++--- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java index 4870dffec2e..c4a77c02aac 100644 --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java @@ -106,10 +106,12 @@ public class CallSite { " (" + getMethod().getBytes() + " bytes) " + getReason()); } } + stream.printf(" (end time: %6.4f", getTimeStamp()); if (getEndNodes() > 0) { - stream.printf(" (end time: %6.4f nodes: %d live: %d)", getTimeStamp(), getEndNodes(), getEndLiveNodes()); + stream.printf(" nodes: %d live: %d", getEndNodes(), getEndLiveNodes()); } - stream.println(""); + stream.println(")"); + if (getReceiver() != null) { emit(stream, indent + 4); // stream.println("type profile " + method.holder + " -> " + receiver + " (" + diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java index 80a00364cc3..de80e9a1043 100644 --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java @@ -207,7 +207,12 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants } String search(Attributes attr, String name) { - return search(attr, name, null); + String result = attr.getValue(name); + if (result != null) { + return result; + } else { + throw new InternalError("can't find " + name); + } } String search(Attributes attr, String name, String defaultValue) { @@ -215,13 +220,7 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants if (result != null) { return result; } - if (defaultValue != null) { - return defaultValue; - } - for (int i = 0; i < attr.getLength(); i++) { - System.out.println(attr.getQName(i) + " " + attr.getValue(attr.getQName(i))); - } - throw new InternalError("can't find " + name); + return defaultValue; } int indent = 0; @@ -268,17 +267,18 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants Phase p = new Phase(search(atts, "name"), Double.parseDouble(search(atts, "stamp")), Integer.parseInt(search(atts, "nodes", "0")), - Integer.parseInt(search(atts, "live"))); + Integer.parseInt(search(atts, "live", "0"))); phaseStack.push(p); } else if (qname.equals("phase_done")) { Phase p = phaseStack.pop(); - if (! p.getId().equals(search(atts, "name"))) { + String phaseName = search(atts, "name", null); + if (phaseName != null && !p.getId().equals(phaseName)) { System.out.println("phase: " + p.getId()); throw new InternalError("phase name mismatch"); } p.setEnd(Double.parseDouble(search(atts, "stamp"))); p.setEndNodes(Integer.parseInt(search(atts, "nodes", "0"))); - p.setEndLiveNodes(Integer.parseInt(search(atts, "live"))); + p.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0"))); compile.getPhases().add(p); } else if (qname.equals("task")) { compile = new Compilation(Integer.parseInt(search(atts, "compile_id", "-1"))); @@ -413,8 +413,8 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants } } else if (qname.equals("parse_done")) { CallSite call = scopes.pop(); - call.setEndNodes(Integer.parseInt(search(atts, "nodes", "1"))); - call.setEndLiveNodes(Integer.parseInt(search(atts, "live", "1"))); + call.setEndNodes(Integer.parseInt(search(atts, "nodes", "0"))); + call.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0"))); call.setTimeStamp(Double.parseDouble(search(atts, "stamp"))); scopes.push(call); } diff --git a/hotspot/src/share/vm/c1/c1_Compilation.cpp b/hotspot/src/share/vm/c1/c1_Compilation.cpp index a8effa4bccf..1cdcab542fa 100644 --- a/hotspot/src/share/vm/c1/c1_Compilation.cpp +++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp @@ -74,16 +74,19 @@ class PhaseTraceTime: public TraceTime { private: JavaThread* _thread; CompileLog* _log; + TimerName _timer; public: PhaseTraceTime(TimerName timer) - : TraceTime("", &timers[timer], CITime || CITimeEach, Verbose), _log(NULL) { + : TraceTime("", &timers[timer], CITime || CITimeEach, Verbose), + _log(NULL), _timer(timer) + { if (Compilation::current() != NULL) { _log = Compilation::current()->log(); } if (_log != NULL) { - _log->begin_head("phase name='%s'", timer_name[timer]); + _log->begin_head("phase name='%s'", timer_name[_timer]); _log->stamp(); _log->end_head(); } @@ -91,7 +94,7 @@ class PhaseTraceTime: public TraceTime { ~PhaseTraceTime() { if (_log != NULL) - _log->done("phase"); + _log->done("phase name='%s'", timer_name[_timer]); } }; From 4b7e40084cfa3944f8b62af67d558ae22cd1a2cf Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Mon, 26 Aug 2013 17:41:05 +0400 Subject: [PATCH 0104/1294] 8022595: JSR292: deadlock during class loading of MethodHandles, MethodHandleImpl & MethodHandleNatives Reviewed-by: kvn, coleenp, dholmes --- hotspot/src/share/vm/runtime/thread.cpp | 10 + .../jsr292/ConcurrentClassLoadingTest.java | 194 ++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100644 hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index bbb9a47c221..b5bf15351f9 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -3636,6 +3636,16 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { CompileBroker::compilation_init(); #endif + if (EnableInvokeDynamic) { + // Pre-initialize some JSR292 core classes to avoid deadlock during class loading. + // It is done after compilers are initialized, because otherwise compilations of + // signature polymorphic MH intrinsics can be missed + // (see SystemDictionary::find_method_handle_intrinsic). + initialize_class(vmSymbols::java_lang_invoke_MethodHandle(), CHECK_0); + initialize_class(vmSymbols::java_lang_invoke_MemberName(), CHECK_0); + initialize_class(vmSymbols::java_lang_invoke_MethodHandleNatives(), CHECK_0); + } + #if INCLUDE_MANAGEMENT Management::initialize(THREAD); #endif // INCLUDE_MANAGEMENT diff --git a/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java b/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java new file mode 100644 index 00000000000..35430c0274d --- /dev/null +++ b/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2013, 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 8022595 + * @summary JSR292: deadlock during class loading of MethodHandles, MethodHandleImpl & MethodHandleNatives + * + * @run main/othervm ConcurrentClassLoadingTest + */ +import java.util.*; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +public class ConcurrentClassLoadingTest { + int numThreads = 0; + long seed = 0; + CyclicBarrier l; + Random rand; + + public static void main(String[] args) throws Throwable { + ConcurrentClassLoadingTest test = new ConcurrentClassLoadingTest(); + test.parseArgs(args); + test.run(); + } + + void parseArgs(String[] args) { + int i = 0; + while (i < args.length) { + String flag = args[i]; + switch(flag) { + case "-seed": + seed = Long.parseLong(args[++i]); + break; + case "-numThreads": + numThreads = Integer.parseInt(args[++i]); + break; + default: + throw new Error("Unknown flag: " + flag); + } + ++i; + } + } + + void init() { + if (numThreads == 0) { + numThreads = Runtime.getRuntime().availableProcessors(); + } + + if (seed == 0) { + seed = (new Random()).nextLong(); + } + rand = new Random(seed); + + l = new CyclicBarrier(numThreads + 1); + + System.out.printf("Threads: %d\n", numThreads); + System.out.printf("Seed: %d\n", seed); + } + + final List loaders = new ArrayList<>(); + + void prepare() { + List c = new ArrayList<>(Arrays.asList(classNames)); + + // Split classes between loading threads + int count = (classNames.length / numThreads) + 1; + for (int t = 0; t < numThreads; t++) { + List sel = new ArrayList<>(); + + System.out.printf("Thread #%d:\n", t); + for (int i = 0; i < count; i++) { + if (c.size() == 0) break; + + int k = rand.nextInt(c.size()); + String elem = c.remove(k); + sel.add(elem); + System.out.printf("\t%s\n", elem); + } + loaders.add(new Loader(sel)); + } + + // Print diagnostic info when the test hangs + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + boolean alive = false; + for (Loader l : loaders) { + if (!l.isAlive()) continue; + + if (!alive) { + System.out.println("Some threads are still alive:"); + alive = true; + } + + System.out.println(l.getName()); + for (StackTraceElement elem : l.getStackTrace()) { + System.out.println("\t"+elem.toString()); + } + } + } + }); + } + + public void run() throws Throwable { + init(); + prepare(); + + for (Loader loader : loaders) { + loader.start(); + } + + l.await(); + + for (Loader loader : loaders) { + loader.join(); + } + } + + class Loader extends Thread { + List classes; + + public Loader(List classes) { + this.classes = classes; + setDaemon(true); + } + + @Override + public void run() { + try { + l.await(); + + for (String name : classes) { + Class.forName(name).getName(); + } + } catch (ClassNotFoundException | BrokenBarrierException | InterruptedException e) { + throw new Error(e); + } + } + } + + final static String[] classNames = { + "java.lang.invoke.AbstractValidatingLambdaMetafactory", + "java.lang.invoke.BoundMethodHandle", + "java.lang.invoke.CallSite", + "java.lang.invoke.ConstantCallSite", + "java.lang.invoke.DirectMethodHandle", + "java.lang.invoke.InnerClassLambdaMetafactory", + "java.lang.invoke.InvokeDynamic", + "java.lang.invoke.InvokeGeneric", + "java.lang.invoke.InvokerBytecodeGenerator", + "java.lang.invoke.Invokers", + "java.lang.invoke.LambdaConversionException", + "java.lang.invoke.LambdaForm", + "java.lang.invoke.LambdaMetafactory", + "java.lang.invoke.MagicLambdaImpl", + "java.lang.invoke.MemberName", + "java.lang.invoke.MethodHandle", + "java.lang.invoke.MethodHandleImpl", + "java.lang.invoke.MethodHandleInfo", + "java.lang.invoke.MethodHandleNatives", + "java.lang.invoke.MethodHandleProxies", + "java.lang.invoke.MethodHandles", + "java.lang.invoke.MethodHandleStatics", + "java.lang.invoke.MethodType", + "java.lang.invoke.MethodTypeForm", + "java.lang.invoke.MutableCallSite", + "java.lang.invoke.SerializedLambda", + "java.lang.invoke.SimpleMethodHandle", + "java.lang.invoke.SwitchPoint", + "java.lang.invoke.TypeConvertingMethodAdapter", + "java.lang.invoke.VolatileCallSite", + "java.lang.invoke.WrongMethodTypeException" + }; +} From 9f4ed448a0726a7cdc371e27e483619c570043c4 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 26 Aug 2013 17:42:03 +0400 Subject: [PATCH 0105/1294] 8023638: Add the regression test for 8006997 Add the relevant test and proofread the VM messages as well Reviewed-by: coleenp, mseledtsov, dcubed --- hotspot/src/share/vm/runtime/arguments.cpp | 4 +- hotspot/test/runtime/contended/Options.java | 103 ++++++++++++++++++++ 2 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 hotspot/test/runtime/contended/Options.java diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 38f38f1c856..1287e811496 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -2230,7 +2230,7 @@ bool Arguments::check_vm_args_consistency() { // among the distinct pages. if (ContendedPaddingWidth < 0 || ContendedPaddingWidth > 8192) { jio_fprintf(defaultStream::error_stream(), - "ContendedPaddingWidth=" INTX_FORMAT " must be the between %d and %d\n", + "ContendedPaddingWidth=" INTX_FORMAT " must be in between %d and %d\n", ContendedPaddingWidth, 0, 8192); status = false; } @@ -2239,7 +2239,7 @@ bool Arguments::check_vm_args_consistency() { // It is sufficient to check against the largest type size. if ((ContendedPaddingWidth % BytesPerLong) != 0) { jio_fprintf(defaultStream::error_stream(), - "ContendedPaddingWidth=" INTX_FORMAT " must be the multiple of %d\n", + "ContendedPaddingWidth=" INTX_FORMAT " must be a multiple of %d\n", ContendedPaddingWidth, BytesPerLong); status = false; } diff --git a/hotspot/test/runtime/contended/Options.java b/hotspot/test/runtime/contended/Options.java new file mode 100644 index 00000000000..589ec9b4131 --- /dev/null +++ b/hotspot/test/runtime/contended/Options.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.*; + +/* + * @test + * @bug 8006997 + * @summary ContendedPaddingWidth should be range-checked + * + * @library /testlibrary + * @run main Options + */ +public class Options { + + public static void main(String[] args) throws Exception { + ProcessBuilder pb; + OutputAnalyzer output; + + pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=-128", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("ContendedPaddingWidth"); + output.shouldContain("must be in between"); + output.shouldHaveExitValue(1); + + pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=-8", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("ContendedPaddingWidth"); + output.shouldContain("must be in between"); + output.shouldHaveExitValue(1); + + pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=-1", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("ContendedPaddingWidth"); + output.shouldContain("must be in between"); + output.shouldContain("must be a multiple of 8"); + output.shouldHaveExitValue(1); + + pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=0", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=1", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("ContendedPaddingWidth"); + output.shouldContain("must be a multiple of 8"); + output.shouldHaveExitValue(1); + + pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8184", "-version"); // 8192-8 = 8184 + output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8191", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("ContendedPaddingWidth"); + output.shouldContain("must be a multiple of 8"); + output.shouldHaveExitValue(1); + + pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8192", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8193", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("ContendedPaddingWidth"); + output.shouldContain("must be in between"); + output.shouldContain("must be a multiple of 8"); + output.shouldHaveExitValue(1); + + pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8200", "-version"); // 8192+8 = 8200 + output = new OutputAnalyzer(pb.start()); + output.shouldContain("ContendedPaddingWidth"); + output.shouldContain("must be in between"); + output.shouldHaveExitValue(1); + + } + +} + From 515a7df99604e34ab3dd68ef21d1d02cd6a92057 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Mon, 26 Aug 2013 16:12:20 +0200 Subject: [PATCH 0106/1294] 8016277: Crash in nmethod::is_compiled_by_c1() on x86 Method pointer for zombie methods may be invalid Reviewed-by: kvn, coleenp --- hotspot/src/share/vm/code/nmethod.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp index 9412feff709..9cc45d7452d 100644 --- a/hotspot/src/share/vm/code/nmethod.cpp +++ b/hotspot/src/share/vm/code/nmethod.cpp @@ -93,18 +93,21 @@ HS_DTRACE_PROBE_DECL6(hotspot, compiled__method__unload, #endif bool nmethod::is_compiled_by_c1() const { - if (compiler() == NULL || method() == NULL) return false; // can happen during debug printing - if (is_native_method()) return false; + if (compiler() == NULL) { + return false; + } return compiler()->is_c1(); } bool nmethod::is_compiled_by_c2() const { - if (compiler() == NULL || method() == NULL) return false; // can happen during debug printing - if (is_native_method()) return false; + if (compiler() == NULL) { + return false; + } return compiler()->is_c2(); } bool nmethod::is_compiled_by_shark() const { - if (is_native_method()) return false; - assert(compiler() != NULL, "must be"); + if (compiler() == NULL) { + return false; + } return compiler()->is_shark(); } @@ -1401,6 +1404,9 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) { // nmethods aren't scanned for GC. _oops_are_stale = true; #endif + // the Method may be reclaimed by class unloading now that the + // nmethod is in zombie state + set_method(NULL); } else { assert(state == not_entrant, "other cases may need to be handled differently"); } From 38560368c16cfb8b71d18ff2df1a6d18b82fcf3f Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Mon, 26 Aug 2013 11:35:25 -0400 Subject: [PATCH 0107/1294] 8012294: remove generic handling for default methods Reviewed-by: kamg, coleenp --- .../share/vm/classfile/classFileParser.cpp | 36 - .../src/share/vm/classfile/defaultMethods.cpp | 367 +---- .../share/vm/classfile/genericSignatures.cpp | 1279 ----------------- .../share/vm/classfile/genericSignatures.hpp | 467 ------ hotspot/src/share/vm/runtime/globals.hpp | 6 - 5 files changed, 10 insertions(+), 2145 deletions(-) delete mode 100644 hotspot/src/share/vm/classfile/genericSignatures.cpp delete mode 100644 hotspot/src/share/vm/classfile/genericSignatures.hpp diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 507bb477a88..0705c5f14d6 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -28,7 +28,6 @@ #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/defaultMethods.hpp" -#include "classfile/genericSignatures.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" @@ -3039,35 +3038,6 @@ AnnotationArray* ClassFileParser::assemble_annotations(u1* runtime_visible_annot return annotations; } - -#ifdef ASSERT -static void parseAndPrintGenericSignatures( - instanceKlassHandle this_klass, TRAPS) { - assert(ParseAllGenericSignatures == true, "Shouldn't call otherwise"); - ResourceMark rm; - - if (this_klass->generic_signature() != NULL) { - using namespace generic; - ClassDescriptor* spec = ClassDescriptor::parse_generic_signature(this_klass(), CHECK); - - tty->print_cr("Parsing %s", this_klass->generic_signature()->as_C_string()); - spec->print_on(tty); - - for (int i = 0; i < this_klass->methods()->length(); ++i) { - Method* m = this_klass->methods()->at(i); - MethodDescriptor* method_spec = MethodDescriptor::parse_generic_signature(m, spec); - Symbol* sig = m->generic_signature(); - if (sig == NULL) { - sig = m->signature(); - } - tty->print_cr("Parsing %s", sig->as_C_string()); - method_spec->print_on(tty); - } - } -} -#endif // def ASSERT - - instanceKlassHandle ClassFileParser::parse_super_class(int super_class_index, TRAPS) { instanceKlassHandle super_klass; @@ -4060,12 +4030,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, java_lang_Class::create_mirror(this_klass, protection_domain, CHECK_(nullHandle)); -#ifdef ASSERT - if (ParseAllGenericSignatures) { - parseAndPrintGenericSignatures(this_klass, CHECK_(nullHandle)); - } -#endif - // Generate any default methods - default methods are interface methods // that have a default implementation. This is new with Lambda project. if (has_default_methods && !access_flags.is_interface() && diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index 3ff2996b3ed..5f02750dc72 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -25,7 +25,6 @@ #include "precompiled.hpp" #include "classfile/bytecodeAssembler.hpp" #include "classfile/defaultMethods.hpp" -#include "classfile/genericSignatures.hpp" #include "classfile/symbolTable.hpp" #include "memory/allocation.hpp" #include "memory/metadataFactory.hpp" @@ -75,14 +74,6 @@ class PseudoScope : public ResourceObj { } }; -class ContextMark : public PseudoScopeMark { - private: - generic::Context::Mark _mark; - public: - ContextMark(const generic::Context::Mark& cm) : _mark(cm) {} - virtual void destroy() { _mark.destroy(); } -}; - #ifndef PRODUCT static void print_slot(outputStream* str, Symbol* name, Symbol* signature) { ResourceMark rm; @@ -503,38 +494,6 @@ Symbol* MethodFamily::generate_conflicts_message(GrowableArray* methods return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL); } -// A generic method family contains a set of all methods that implement a single -// language-level method. Because of erasure, these methods may have different -// signatures. As members of the set are collected while walking over the -// hierarchy, they are tagged with a qualification state. The qualification -// state for an erased method is set to disqualified if there exists a path -// from the root of hierarchy to the method that contains an interleaving -// language-equivalent method defined in an interface. -class GenericMethodFamily : public MethodFamily { - private: - - generic::MethodDescriptor* _descriptor; // language-level description - - public: - - GenericMethodFamily(generic::MethodDescriptor* canonical_desc) - : _descriptor(canonical_desc) {} - - generic::MethodDescriptor* descriptor() const { return _descriptor; } - - bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) { - return descriptor()->covariant_match(md, ctx); - } - -#ifndef PRODUCT - Symbol* get_generic_sig() const { - - generic::Context ctx(NULL); // empty, as _descriptor already canonicalized - TempNewSymbol sig = descriptor()->reify_signature(&ctx, Thread::current()); - return sig; - } -#endif // ndef PRODUCT -}; class StateRestorer; @@ -571,26 +530,6 @@ class StatefulMethodFamily : public ResourceObj { StateRestorer* record_method_and_dq_further(Method* mo); }; - -// StatefulGenericMethodFamily is a wrapper around GenericMethodFamily that maintains the -// qualification state during hierarchy visitation, and applies that state -// when adding members to the GenericMethodFamily. -class StatefulGenericMethodFamily : public StatefulMethodFamily { - - public: - StatefulGenericMethodFamily(generic::MethodDescriptor* md, generic::Context* ctx) - : StatefulMethodFamily(new GenericMethodFamily(md->canonicalize(ctx))) { - - } - GenericMethodFamily* get_method_family() { - return (GenericMethodFamily*)_method_family; - } - - bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) { - return get_method_family()->descriptor_matches(md, ctx); - } -}; - class StateRestorer : public PseudoScopeMark { private: StatefulMethodFamily* _method; @@ -616,39 +555,6 @@ StateRestorer* StatefulMethodFamily::record_method_and_dq_further(Method* mo) { return mark; } -class StatefulGenericMethodFamilies : public ResourceObj { - private: - GrowableArray _methods; - - public: - StatefulGenericMethodFamily* find_matching( - generic::MethodDescriptor* md, generic::Context* ctx) { - for (int i = 0; i < _methods.length(); ++i) { - StatefulGenericMethodFamily* existing = _methods.at(i); - if (existing->descriptor_matches(md, ctx)) { - return existing; - } - } - return NULL; - } - - StatefulGenericMethodFamily* find_matching_or_create( - generic::MethodDescriptor* md, generic::Context* ctx) { - StatefulGenericMethodFamily* method = find_matching(md, ctx); - if (method == NULL) { - method = new StatefulGenericMethodFamily(md, ctx); - _methods.append(method); - } - return method; - } - - void extract_families_into(GrowableArray* array) { - for (int i = 0; i < _methods.length(); ++i) { - array->append(_methods.at(i)->get_method_family()); - } - } -}; - // Represents a location corresponding to a vtable slot for methods that // neither the class nor any of it's ancestors provide an implementaion. // Default methods may be present to fill this slot. @@ -779,146 +685,11 @@ class FindMethodsByErasedSig : public HierarchyVisitor { }; -// Iterates over the type hierarchy looking for all methods with a specific -// method name. The result of this is a set of method families each of -// which is populated with a set of methods that implement the same -// language-level signature. -class FindMethodsByGenericSig : public HierarchyVisitor { - private: - // Context data - Thread* THREAD; - generic::DescriptorCache* _cache; - Symbol* _method_name; - generic::Context* _ctx; - StatefulGenericMethodFamilies _families; - public: - - FindMethodsByGenericSig(generic::DescriptorCache* cache, Symbol* name, - generic::Context* ctx, Thread* thread) : - _cache(cache), _method_name(name), _ctx(ctx), THREAD(thread) {} - - void get_discovered_families(GrowableArray* methods) { - _families.extract_families_into(methods); - } - - void* new_node_data(InstanceKlass* cls) { return new PseudoScope(); } - void free_node_data(void* node_data) { - PseudoScope::cast(node_data)->destroy(); - } - - bool visit() { - PseudoScope* scope = PseudoScope::cast(current_data()); - InstanceKlass* klass = current_class(); - InstanceKlass* sub = current_depth() > 0 ? class_at_depth(1) : NULL; - - ContextMark* cm = new ContextMark(_ctx->mark()); - scope->add_mark(cm); // will restore context when scope is freed - - _ctx->apply_type_arguments(sub, klass, THREAD); - - int start, end = 0; - start = klass->find_method_by_name(_method_name, &end); - if (start != -1) { - for (int i = start; i < end; ++i) { - Method* m = klass->methods()->at(i); - // This gets the method's parameter list with its generic type - // parameters resolved - generic::MethodDescriptor* md = _cache->descriptor_for(m, THREAD); - - // Find all methods on this hierarchy that match this method - // (name, signature). This class collects other families of this - // method name. - StatefulGenericMethodFamily* family = - _families.find_matching_or_create(md, _ctx); - - if (klass->is_interface()) { - // ??? - StateRestorer* restorer = family->record_method_and_dq_further(m); - scope->add_mark(restorer); - } else { - // This is the rule that methods in classes "win" (bad word) over - // methods in interfaces. This works because of single inheritance - family->set_target_if_empty(m); - } - } - } - return true; - } -}; - -#ifndef PRODUCT -static void print_generic_families( - GrowableArray* methods, Symbol* match) { - streamIndentor si(tty, 4); - if (methods->length() == 0) { - tty->indent(); - tty->print_cr("No Logical Method found"); - } - for (int i = 0; i < methods->length(); ++i) { - tty->indent(); - GenericMethodFamily* lm = methods->at(i); - if (lm->contains_signature(match)) { - tty->print_cr(""); - } else { - tty->print_cr(""); - } - lm->print_sig_on(tty, lm->get_generic_sig(), 1); - } -} -#endif // ndef PRODUCT static void create_overpasses( GrowableArray* slots, InstanceKlass* klass, TRAPS); -static void generate_generic_defaults( - InstanceKlass* klass, GrowableArray* empty_slots, - EmptyVtableSlot* slot, int current_slot_index, TRAPS) { - - if (slot->is_bound()) { -#ifndef PRODUCT - if (TraceDefaultMethods) { - streamIndentor si(tty, 4); - tty->indent().print_cr("Already bound to logical method:"); - GenericMethodFamily* lm = (GenericMethodFamily*)(slot->get_binding()); - lm->print_sig_on(tty, lm->get_generic_sig(), 1); - } -#endif // ndef PRODUCT - return; // covered by previous processing - } - - generic::DescriptorCache cache; - - generic::Context ctx(&cache); - FindMethodsByGenericSig visitor(&cache, slot->name(), &ctx, CHECK); - visitor.run(klass); - - GrowableArray discovered_families; - visitor.get_discovered_families(&discovered_families); - -#ifndef PRODUCT - if (TraceDefaultMethods) { - print_generic_families(&discovered_families, slot->signature()); - } -#endif // ndef PRODUCT - - // Find and populate any other slots that match the discovered families - for (int j = current_slot_index; j < empty_slots->length(); ++j) { - EmptyVtableSlot* open_slot = empty_slots->at(j); - - if (slot->name() == open_slot->name()) { - for (int k = 0; k < discovered_families.length(); ++k) { - GenericMethodFamily* lm = discovered_families.at(k); - - if (lm->contains_signature(open_slot->signature())) { - lm->determine_target(klass, CHECK); - open_slot->bind_family(lm); - } - } - } - } -} - static void generate_erased_defaults( InstanceKlass* klass, GrowableArray* empty_slots, EmptyVtableSlot* slot, TRAPS) { @@ -943,21 +714,14 @@ static void merge_in_new_methods(InstanceKlass* klass, // // First if finds any name/signature slots that need any implementation (either // because they are miranda or a superclass's implementation is an overpass -// itself). For each slot, iterate over the hierarchy, using generic signature -// information to partition any methods that match the name into method families -// where each family contains methods whose signatures are equivalent at the -// language level (i.e., their reified parameters match and return values are -// covariant). Check those sets to see if they contain a signature that matches -// the slot we're looking at (if we're lucky, there might be other empty slots -// that we can fill using the same analysis). +// itself). For each slot, iterate over the hierarchy, to see if they contain a +// signature that matches the slot we are looking at. // // For each slot filled, we generate an overpass method that either calls the // unique default method candidate using invokespecial, or throws an exception // (in the case of no default method candidates, or more than one valid -// candidate). These methods are then added to the class's method list. If -// the method set we're using contains methods (qualified or not) with a -// different runtime signature than the method we're creating, then we have to -// create bridges with those signatures too. +// candidate). These methods are then added to the class's method list. +// The JVM does not create bridges nor handle generic signatures here. void DefaultMethods::generate_default_methods( InstanceKlass* klass, GrowableArray* mirandas, TRAPS) { @@ -997,11 +761,7 @@ void DefaultMethods::generate_default_methods( } #endif // ndef PRODUCT - if (ParseGenericDefaults) { - generate_generic_defaults(klass, empty_slots, slot, i, CHECK); - } else { - generate_erased_defaults(klass, empty_slots, slot, CHECK); - } + generate_erased_defaults(klass, empty_slots, slot, CHECK); } #ifndef PRODUCT if (TraceDefaultMethods) { @@ -1019,13 +779,13 @@ void DefaultMethods::generate_default_methods( } /** - * Generic analysis was used upon interface '_target' and found a unique - * default method candidate with generic signature '_method_desc'. This + * Interface inheritance rules were used to find a unique default method + * candidate for the resolved class. This * method is only viable if it would also be in the set of default method * candidates if we ran a full analysis on the current class. * * The only reason that the method would not be in the set of candidates for - * the current class is if that there's another covariantly matching method + * the current class is if that there's another matching method * which is "more specific" than the found method -- i.e., one could find a * path in the interface hierarchy in which the matching method appears * before we get to '_target'. @@ -1110,48 +870,6 @@ class ErasedShadowChecker : public ShadowChecker { : ShadowChecker(thread, name, holder, target) {} }; -class GenericShadowChecker : public ShadowChecker { - private: - generic::DescriptorCache* _cache; - generic::MethodDescriptor* _method_desc; - - bool path_has_shadow() { - generic::Context ctx(_cache); - - for (int i = current_depth() - 1; i > 0; --i) { - InstanceKlass* ik = class_at_depth(i); - InstanceKlass* sub = class_at_depth(i + 1); - ctx.apply_type_arguments(sub, ik, THREAD); - - if (ik->is_interface()) { - int end; - int start = ik->find_method_by_name(_method_name, &end); - if (start != -1) { - for (int j = start; j < end; ++j) { - Method* mo = ik->methods()->at(j); - generic::MethodDescriptor* md = _cache->descriptor_for(mo, THREAD); - if (_method_desc->covariant_match(md, &ctx)) { - return true; - } - } - } - } - } - return false; - } - - public: - - GenericShadowChecker(generic::DescriptorCache* cache, Thread* thread, - Symbol* name, InstanceKlass* holder, generic::MethodDescriptor* desc, - InstanceKlass* target) - : ShadowChecker(thread, name, holder, target) { - _cache = cache; - _method_desc = desc; - } -}; - - // Find the unique qualified candidate from the perspective of the super_class // which is the resolved_klass, which must be an immediate superinterface @@ -1203,66 +921,6 @@ Method* find_erased_super_default(InstanceKlass* current_class, InstanceKlass* s } } -// super_class is assumed to be the direct super of current_class -Method* find_generic_super_default( InstanceKlass* current_class, - InstanceKlass* super_class, - Symbol* method_name, Symbol* sig, TRAPS) { - generic::DescriptorCache cache; - generic::Context ctx(&cache); - - // Prime the initial generic context for current -> super_class - ctx.apply_type_arguments(current_class, super_class, CHECK_NULL); - - FindMethodsByGenericSig visitor(&cache, method_name, &ctx, CHECK_NULL); - visitor.run(super_class); - - GrowableArray families; - visitor.get_discovered_families(&families); - -#ifndef PRODUCT - if (TraceDefaultMethods) { - print_generic_families(&families, sig); - } -#endif // ndef PRODUCT - - GenericMethodFamily* selected_family = NULL; - - for (int i = 0; i < families.length(); ++i) { - GenericMethodFamily* lm = families.at(i); - if (lm->contains_signature(sig)) { - lm->determine_target(current_class, CHECK_NULL); - selected_family = lm; - } - } - - if (selected_family->has_target()) { - Method* target = selected_family->get_selected_target(); - InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); - - // Verify that the identified method is valid from the context of - // the current class - GenericShadowChecker checker(&cache, THREAD, target->name(), - holder, selected_family->descriptor(), super_class); - checker.run(current_class); - - if (checker.found_shadow()) { -#ifndef PRODUCT - if (TraceDefaultMethods) { - tty->print_cr(" Only candidate found was shadowed."); - } -#endif // ndef PRODUCT - THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), - "Accessible default method not found", NULL); - } else { - return target; - } - } else { - assert(selected_family->throws_exception(), "must have target or throw"); - THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), - selected_family->get_exception_message()->as_C_string(), NULL); - } -} - // This is called during linktime when we find an invokespecial call that // refers to a direct superinterface. It indicates that we should find the // default method in the hierarchy of that superinterface, and if that method @@ -1296,13 +954,8 @@ Method* DefaultMethods::find_super_default( assert(super_class->is_interface(), "only call for default methods"); Method* target = NULL; - if (ParseGenericDefaults) { - target = find_generic_super_default(current_class, super_class, - method_name, sig, CHECK_NULL); - } else { - target = find_erased_super_default(current_class, super_class, - method_name, sig, CHECK_NULL); - } + target = find_erased_super_default(current_class, super_class, + method_name, sig, CHECK_NULL); #ifndef PRODUCT if (target != NULL) { diff --git a/hotspot/src/share/vm/classfile/genericSignatures.cpp b/hotspot/src/share/vm/classfile/genericSignatures.cpp deleted file mode 100644 index 3bbce2f8ce7..00000000000 --- a/hotspot/src/share/vm/classfile/genericSignatures.cpp +++ /dev/null @@ -1,1279 +0,0 @@ -/* - * Copyright (c) 2012, 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. - * - */ - -#include "precompiled.hpp" - -#include "classfile/genericSignatures.hpp" -#include "classfile/symbolTable.hpp" -#include "classfile/systemDictionary.hpp" -#include "memory/resourceArea.hpp" - -namespace generic { - -// Helper class for parsing the generic signature Symbol in klass and methods -class DescriptorStream : public ResourceObj { - private: - Symbol* _symbol; - int _offset; - int _mark; - const char* _parse_error; - - void set_parse_error(const char* error) { - assert(error != NULL, "Can't set NULL error string"); - _parse_error = error; - } - - public: - DescriptorStream(Symbol* sym) - : _symbol(sym), _offset(0), _mark(-1), _parse_error(NULL) {} - - const char* parse_error() const { - return _parse_error; - } - - bool at_end() { return _offset >= _symbol->utf8_length(); } - - char peek() { - if (at_end()) { - set_parse_error("Peeking past end of signature"); - return '\0'; - } else { - return _symbol->byte_at(_offset); - } - } - - char read() { - if (at_end()) { - set_parse_error("Reading past end of signature"); - return '\0'; - } else { - return _symbol->byte_at(_offset++); - } - } - - void read(char expected) { - char c = read(); - assert_char(c, expected, 0); - } - - void assert_char(char c, char expected, int pos = -1) { - if (c != expected) { - const char* fmt = "Parse error at %d: expected %c but got %c"; - size_t len = strlen(fmt) + 5; - char* buffer = NEW_RESOURCE_ARRAY(char, len); - jio_snprintf(buffer, len, fmt, _offset + pos, expected, c); - set_parse_error(buffer); - } - } - - void push(char c) { - assert(c == _symbol->byte_at(_offset - 1), "Pushing back wrong value"); - --_offset; - } - - void expect_end() { - if (!at_end()) { - set_parse_error("Unexpected data trailing signature"); - } - } - - bool has_mark() { return _mark != -1; } - - void set_mark() { - _mark = _offset; - } - - Identifier* identifier_from_mark() { - assert(has_mark(), "Mark should be set"); - if (!has_mark()) { - set_parse_error("Expected mark to be set"); - return NULL; - } else { - Identifier* id = new Identifier(_symbol, _mark, _offset - 1); - _mark = -1; - return id; - } - } -}; - - -#define CHECK_FOR_PARSE_ERROR() \ - if (STREAM->parse_error() != NULL) { \ - if (VerifyGenericSignatures) { \ - fatal(STREAM->parse_error()); \ - } \ - return NULL; \ - } (void)0 - -#define READ() STREAM->read(); CHECK_FOR_PARSE_ERROR() -#define PEEK() STREAM->peek(); CHECK_FOR_PARSE_ERROR() -#define PUSH(c) STREAM->push(c) -#define EXPECT(c) STREAM->read(c); CHECK_FOR_PARSE_ERROR() -#define EXPECTED(c, ch) STREAM->assert_char(c, ch); CHECK_FOR_PARSE_ERROR() -#define EXPECT_END() STREAM->expect_end(); CHECK_FOR_PARSE_ERROR() - -#define CHECK_STREAM STREAM); CHECK_FOR_PARSE_ERROR(); ((void)0 - -#ifndef PRODUCT -void Identifier::print_on(outputStream* str) const { - for (int i = _begin; i < _end; ++i) { - str->print("%c", (char)_sym->byte_at(i)); - } -} -#endif // ndef PRODUCT - -bool Identifier::equals(Identifier* other) { - if (_sym == other->_sym && _begin == other->_begin && _end == other->_end) { - return true; - } else if (_end - _begin != other->_end - other->_begin) { - return false; - } else { - size_t len = _end - _begin; - char* addr = ((char*)_sym->bytes()) + _begin; - char* oaddr = ((char*)other->_sym->bytes()) + other->_begin; - return strncmp(addr, oaddr, len) == 0; - } -} - -bool Identifier::equals(Symbol* sym) { - Identifier id(sym, 0, sym->utf8_length()); - return equals(&id); -} - -/** - * A formal type parameter may be found in the the enclosing class, but it could - * also come from an enclosing method or outer class, in the case of inner-outer - * classes or anonymous classes. For example: - * - * class Outer { - * class Inner { - * void m(T t, V v, W w); - * } - * } - * - * In this case, the type variables in m()'s signature are not all found in the - * immediate enclosing class (Inner). class Inner has only type parameter W, - * but it's outer_class field will reference Outer's descriptor which contains - * T & V (no outer_method in this case). - * - * If you have an anonymous class, it has both an enclosing method *and* an - * enclosing class where type parameters can be declared: - * - * class MOuter { - * void bar(V v) { - * Runnable r = new Runnable() { - * public void run() {} - * public void foo(T t, V v) { ... } - * }; - * } - * } - * - * In this case, foo will be a member of some class, Runnable$1, which has no - * formal parameters itself, but has an outer_method (bar()) which provides - * type parameter V, and an outer class MOuter with type parameter T. - * - * It is also possible that the outer class is itself an inner class to some - * other class (or an anonymous class with an enclosing method), so we need to - * follow the outer_class/outer_method chain to it's end when looking for a - * type parameter. - */ -TypeParameter* Descriptor::find_type_parameter(Identifier* id, int* depth) { - - int current_depth = 0; - - MethodDescriptor* outer_method = as_method_signature(); - ClassDescriptor* outer_class = as_class_signature(); - - if (outer_class == NULL) { // 'this' is a method signature; use the holder - outer_class = outer_method->outer_class(); - } - - while (outer_method != NULL || outer_class != NULL) { - if (outer_method != NULL) { - for (int i = 0; i < outer_method->type_parameters().length(); ++i) { - TypeParameter* p = outer_method->type_parameters().at(i); - if (p->identifier()->equals(id)) { - *depth = -1; // indicates this this is a method parameter - return p; - } - } - } - if (outer_class != NULL) { - for (int i = 0; i < outer_class->type_parameters().length(); ++i) { - TypeParameter* p = outer_class->type_parameters().at(i); - if (p->identifier()->equals(id)) { - *depth = current_depth; - return p; - } - } - outer_method = outer_class->outer_method(); - outer_class = outer_class->outer_class(); - ++current_depth; - } - } - - if (VerifyGenericSignatures) { - fatal("Could not resolve identifier"); - } - - return NULL; -} - -ClassDescriptor* ClassDescriptor::parse_generic_signature(Klass* klass, TRAPS) { - return parse_generic_signature(klass, NULL, CHECK_NULL); -} - -ClassDescriptor* ClassDescriptor::parse_generic_signature( - Klass* klass, Symbol* original_name, TRAPS) { - - InstanceKlass* ik = InstanceKlass::cast(klass); - Symbol* sym = ik->generic_signature(); - - ClassDescriptor* spec; - - if (sym == NULL || (spec = ClassDescriptor::parse_generic_signature(sym)) == NULL) { - spec = ClassDescriptor::placeholder(ik); - } - - u2 outer_index = get_outer_class_index(ik, CHECK_NULL); - if (outer_index != 0) { - if (original_name == NULL) { - original_name = ik->name(); - } - Handle class_loader = Handle(THREAD, ik->class_loader()); - Handle protection_domain = Handle(THREAD, ik->protection_domain()); - - Symbol* outer_name = ik->constants()->klass_name_at(outer_index); - Klass* outer = SystemDictionary::find( - outer_name, class_loader, protection_domain, CHECK_NULL); - if (outer == NULL && !THREAD->is_Compiler_thread()) { - if (outer_name == ik->super()->name()) { - outer = SystemDictionary::resolve_super_or_fail(original_name, outer_name, - class_loader, protection_domain, - false, CHECK_NULL); - } - else { - outer = SystemDictionary::resolve_or_fail(outer_name, class_loader, - protection_domain, false, CHECK_NULL); - } - } - - InstanceKlass* outer_ik; - ClassDescriptor* outer_spec = NULL; - if (outer == NULL) { - outer_spec = ClassDescriptor::placeholder(ik); - assert(false, "Outer class not loaded and not loadable from here"); - } else { - outer_ik = InstanceKlass::cast(outer); - outer_spec = parse_generic_signature(outer, original_name, CHECK_NULL); - } - spec->set_outer_class(outer_spec); - - u2 encl_method_idx = ik->enclosing_method_method_index(); - if (encl_method_idx != 0 && outer_ik != NULL) { - ConstantPool* cp = ik->constants(); - u2 name_index = cp->name_ref_index_at(encl_method_idx); - u2 sig_index = cp->signature_ref_index_at(encl_method_idx); - Symbol* name = cp->symbol_at(name_index); - Symbol* sig = cp->symbol_at(sig_index); - Method* m = outer_ik->find_method(name, sig); - if (m != NULL) { - Symbol* gsig = m->generic_signature(); - if (gsig != NULL) { - MethodDescriptor* gms = MethodDescriptor::parse_generic_signature(gsig, outer_spec); - spec->set_outer_method(gms); - } - } else if (VerifyGenericSignatures) { - ResourceMark rm; - stringStream ss; - ss.print("Could not find method %s %s in class %s", - name->as_C_string(), sig->as_C_string(), outer_name->as_C_string()); - fatal(ss.as_string()); - } - } - } - - spec->bind_variables_to_parameters(); - return spec; -} - -ClassDescriptor* ClassDescriptor::placeholder(InstanceKlass* klass) { - GrowableArray formals; - GrowableArray interfaces; - ClassType* super_type = NULL; - - Klass* super_klass = klass->super(); - if (super_klass != NULL) { - InstanceKlass* super = InstanceKlass::cast(super_klass); - super_type = ClassType::from_symbol(super->name()); - } - - for (int i = 0; i < klass->local_interfaces()->length(); ++i) { - InstanceKlass* iface = InstanceKlass::cast(klass->local_interfaces()->at(i)); - interfaces.append(ClassType::from_symbol(iface->name())); - } - return new ClassDescriptor(formals, super_type, interfaces); -} - -ClassDescriptor* ClassDescriptor::parse_generic_signature(Symbol* sym) { - - DescriptorStream ds(sym); - DescriptorStream* STREAM = &ds; - - GrowableArray parameters(8); - char c = READ(); - if (c == '<') { - c = READ(); - while (c != '>') { - PUSH(c); - TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM); - parameters.append(ftp); - c = READ(); - } - } else { - PUSH(c); - } - - EXPECT('L'); - ClassType* super = ClassType::parse_generic_signature(CHECK_STREAM); - - GrowableArray signatures(2); - while (!STREAM->at_end()) { - EXPECT('L'); - ClassType* iface = ClassType::parse_generic_signature(CHECK_STREAM); - signatures.append(iface); - } - - EXPECT_END(); - - return new ClassDescriptor(parameters, super, signatures); -} - -#ifndef PRODUCT -void ClassDescriptor::print_on(outputStream* str) const { - str->indent().print_cr("ClassDescriptor {"); - { - streamIndentor si(str); - if (_type_parameters.length() > 0) { - str->indent().print_cr("Formals {"); - { - streamIndentor si(str); - for (int i = 0; i < _type_parameters.length(); ++i) { - _type_parameters.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - } - if (_super != NULL) { - str->indent().print_cr("Superclass: "); - { - streamIndentor si(str); - _super->print_on(str); - } - } - if (_interfaces.length() > 0) { - str->indent().print_cr("SuperInterfaces: {"); - { - streamIndentor si(str); - for (int i = 0; i < _interfaces.length(); ++i) { - _interfaces.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - } - if (_outer_method != NULL) { - str->indent().print_cr("Outer Method: {"); - { - streamIndentor si(str); - _outer_method->print_on(str); - } - str->indent().print_cr("}"); - } - if (_outer_class != NULL) { - str->indent().print_cr("Outer Class: {"); - { - streamIndentor si(str); - _outer_class->print_on(str); - } - str->indent().print_cr("}"); - } - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -ClassType* ClassDescriptor::interface_desc(Symbol* sym) { - for (int i = 0; i < _interfaces.length(); ++i) { - if (_interfaces.at(i)->identifier()->equals(sym)) { - return _interfaces.at(i); - } - } - if (VerifyGenericSignatures) { - fatal("Did not find expected interface"); - } - return NULL; -} - -void ClassDescriptor::bind_variables_to_parameters() { - if (_outer_class != NULL) { - _outer_class->bind_variables_to_parameters(); - } - if (_outer_method != NULL) { - _outer_method->bind_variables_to_parameters(); - } - for (int i = 0; i < _type_parameters.length(); ++i) { - _type_parameters.at(i)->bind_variables_to_parameters(this, i); - } - if (_super != NULL) { - _super->bind_variables_to_parameters(this); - } - for (int i = 0; i < _interfaces.length(); ++i) { - _interfaces.at(i)->bind_variables_to_parameters(this); - } -} - -ClassDescriptor* ClassDescriptor::canonicalize(Context* ctx) { - - GrowableArray type_params(_type_parameters.length()); - for (int i = 0; i < _type_parameters.length(); ++i) { - type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0)); - } - - ClassDescriptor* outer = _outer_class == NULL ? NULL : - _outer_class->canonicalize(ctx); - - ClassType* super = _super == NULL ? NULL : _super->canonicalize(ctx, 0); - - GrowableArray interfaces(_interfaces.length()); - for (int i = 0; i < _interfaces.length(); ++i) { - interfaces.append(_interfaces.at(i)->canonicalize(ctx, 0)); - } - - MethodDescriptor* md = _outer_method == NULL ? NULL : - _outer_method->canonicalize(ctx); - - return new ClassDescriptor(type_params, super, interfaces, outer, md); -} - -u2 ClassDescriptor::get_outer_class_index(InstanceKlass* klass, TRAPS) { - int inner_index = InstanceKlass::inner_class_inner_class_info_offset; - int outer_index = InstanceKlass::inner_class_outer_class_info_offset; - int name_offset = InstanceKlass::inner_class_inner_name_offset; - int next_offset = InstanceKlass::inner_class_next_offset; - - if (klass->inner_classes() == NULL || klass->inner_classes()->length() == 0) { - // No inner class info => no declaring class - return 0; - } - - Array* i_icls = klass->inner_classes(); - ConstantPool* i_cp = klass->constants(); - int i_length = i_icls->length(); - - // Find inner_klass attribute - for (int i = 0; i + next_offset < i_length; i += next_offset) { - u2 ioff = i_icls->at(i + inner_index); - u2 ooff = i_icls->at(i + outer_index); - u2 noff = i_icls->at(i + name_offset); - if (ioff != 0) { - // Check to see if the name matches the class we're looking for - // before attempting to find the class. - if (i_cp->klass_name_at_matches(klass, ioff) && ooff != 0) { - return ooff; - } - } - } - - // It may be anonymous; try for that. - u2 encl_method_class_idx = klass->enclosing_method_class_index(); - if (encl_method_class_idx != 0) { - return encl_method_class_idx; - } - - return 0; -} - -MethodDescriptor* MethodDescriptor::parse_generic_signature(Method* m, ClassDescriptor* outer) { - Symbol* generic_sig = m->generic_signature(); - MethodDescriptor* md = NULL; - if (generic_sig == NULL || (md = parse_generic_signature(generic_sig, outer)) == NULL) { - md = parse_generic_signature(m->signature(), outer); - } - assert(md != NULL, "Could not parse method signature"); - md->bind_variables_to_parameters(); - return md; -} - -MethodDescriptor* MethodDescriptor::parse_generic_signature(Symbol* sym, ClassDescriptor* outer) { - - DescriptorStream ds(sym); - DescriptorStream* STREAM = &ds; - - GrowableArray params(8); - char c = READ(); - if (c == '<') { - c = READ(); - while (c != '>') { - PUSH(c); - TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM); - params.append(ftp); - c = READ(); - } - } else { - PUSH(c); - } - - EXPECT('('); - - GrowableArray parameters(8); - c = READ(); - while (c != ')') { - PUSH(c); - Type* arg = Type::parse_generic_signature(CHECK_STREAM); - parameters.append(arg); - c = READ(); - } - - Type* rt = Type::parse_generic_signature(CHECK_STREAM); - - GrowableArray throws; - while (!STREAM->at_end()) { - EXPECT('^'); - Type* spec = Type::parse_generic_signature(CHECK_STREAM); - throws.append(spec); - } - - return new MethodDescriptor(params, outer, parameters, rt, throws); -} - -void MethodDescriptor::bind_variables_to_parameters() { - for (int i = 0; i < _type_parameters.length(); ++i) { - _type_parameters.at(i)->bind_variables_to_parameters(this, i); - } - for (int i = 0; i < _parameters.length(); ++i) { - _parameters.at(i)->bind_variables_to_parameters(this); - } - _return_type->bind_variables_to_parameters(this); - for (int i = 0; i < _throws.length(); ++i) { - _throws.at(i)->bind_variables_to_parameters(this); - } -} - -bool MethodDescriptor::covariant_match(MethodDescriptor* other, Context* ctx) { - - if (_parameters.length() == other->_parameters.length()) { - for (int i = 0; i < _parameters.length(); ++i) { - if (!_parameters.at(i)->covariant_match(other->_parameters.at(i), ctx)) { - return false; - } - } - - if (_return_type->as_primitive() != NULL) { - return _return_type->covariant_match(other->_return_type, ctx); - } else { - // return type is a reference - return other->_return_type->as_class() != NULL || - other->_return_type->as_variable() != NULL || - other->_return_type->as_array() != NULL; - } - } else { - return false; - } -} - -MethodDescriptor* MethodDescriptor::canonicalize(Context* ctx) { - - GrowableArray type_params(_type_parameters.length()); - for (int i = 0; i < _type_parameters.length(); ++i) { - type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0)); - } - - ClassDescriptor* outer = _outer_class == NULL ? NULL : - _outer_class->canonicalize(ctx); - - GrowableArray params(_parameters.length()); - for (int i = 0; i < _parameters.length(); ++i) { - params.append(_parameters.at(i)->canonicalize(ctx, 0)); - } - - Type* rt = _return_type->canonicalize(ctx, 0); - - GrowableArray throws(_throws.length()); - for (int i = 0; i < _throws.length(); ++i) { - throws.append(_throws.at(i)->canonicalize(ctx, 0)); - } - - return new MethodDescriptor(type_params, outer, params, rt, throws); -} - -#ifndef PRODUCT -TempNewSymbol MethodDescriptor::reify_signature(Context* ctx, TRAPS) { - stringStream ss(256); - - ss.print("("); - for (int i = 0; i < _parameters.length(); ++i) { - _parameters.at(i)->reify_signature(&ss, ctx); - } - ss.print(")"); - _return_type->reify_signature(&ss, ctx); - return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD); -} - -void MethodDescriptor::print_on(outputStream* str) const { - str->indent().print_cr("MethodDescriptor {"); - { - streamIndentor si(str); - if (_type_parameters.length() > 0) { - str->indent().print_cr("Formals: {"); - { - streamIndentor si(str); - for (int i = 0; i < _type_parameters.length(); ++i) { - _type_parameters.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - } - str->indent().print_cr("Parameters: {"); - { - streamIndentor si(str); - for (int i = 0; i < _parameters.length(); ++i) { - _parameters.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - str->indent().print_cr("Return Type: "); - { - streamIndentor si(str); - _return_type->print_on(str); - } - - if (_throws.length() > 0) { - str->indent().print_cr("Throws: {"); - { - streamIndentor si(str); - for (int i = 0; i < _throws.length(); ++i) { - _throws.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - } - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -TypeParameter* TypeParameter::parse_generic_signature(DescriptorStream* STREAM) { - STREAM->set_mark(); - char c = READ(); - while (c != ':') { - c = READ(); - } - - Identifier* id = STREAM->identifier_from_mark(); - - ClassType* class_bound = NULL; - GrowableArray interface_bounds(8); - - c = READ(); - if (c != '>') { - if (c != ':') { - EXPECTED(c, 'L'); - class_bound = ClassType::parse_generic_signature(CHECK_STREAM); - c = READ(); - } - - while (c == ':') { - EXPECT('L'); - ClassType* fts = ClassType::parse_generic_signature(CHECK_STREAM); - interface_bounds.append(fts); - c = READ(); - } - } - PUSH(c); - - return new TypeParameter(id, class_bound, interface_bounds); -} - -void TypeParameter::bind_variables_to_parameters(Descriptor* sig, int position) { - if (_class_bound != NULL) { - _class_bound->bind_variables_to_parameters(sig); - } - for (int i = 0; i < _interface_bounds.length(); ++i) { - _interface_bounds.at(i)->bind_variables_to_parameters(sig); - } - _position = position; -} - -Type* TypeParameter::resolve( - Context* ctx, int inner_depth, int ctx_depth) { - - if (inner_depth == -1) { - // This indicates that the parameter is a method type parameter, which - // isn't resolveable using the class hierarchy context - return bound(); - } - - ClassType* provider = ctx->at_depth(ctx_depth); - if (provider != NULL) { - for (int i = 0; i < inner_depth && provider != NULL; ++i) { - provider = provider->outer_class(); - } - if (provider != NULL) { - TypeArgument* arg = provider->type_argument_at(_position); - if (arg != NULL) { - Type* value = arg->lower_bound(); - return value->canonicalize(ctx, ctx_depth + 1); - } - } - } - - return bound(); -} - -TypeParameter* TypeParameter::canonicalize(Context* ctx, int ctx_depth) { - ClassType* bound = _class_bound == NULL ? NULL : - _class_bound->canonicalize(ctx, ctx_depth); - - GrowableArray ifaces(_interface_bounds.length()); - for (int i = 0; i < _interface_bounds.length(); ++i) { - ifaces.append(_interface_bounds.at(i)->canonicalize(ctx, ctx_depth)); - } - - TypeParameter* ret = new TypeParameter(_identifier, bound, ifaces); - ret->_position = _position; - return ret; -} - -ClassType* TypeParameter::bound() { - if (_class_bound != NULL) { - return _class_bound; - } - - if (_interface_bounds.length() == 1) { - return _interface_bounds.at(0); - } - - return ClassType::java_lang_Object(); // TODO: investigate this case -} - -#ifndef PRODUCT -void TypeParameter::print_on(outputStream* str) const { - str->indent().print_cr("Formal: {"); - { - streamIndentor si(str); - - str->indent().print("Identifier: "); - _identifier->print_on(str); - str->print_cr(""); - if (_class_bound != NULL) { - str->indent().print_cr("Class Bound: "); - streamIndentor si(str); - _class_bound->print_on(str); - } - if (_interface_bounds.length() > 0) { - str->indent().print_cr("Interface Bounds: {"); - { - streamIndentor si(str); - for (int i = 0; i < _interface_bounds.length(); ++i) { - _interface_bounds.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - } - str->indent().print_cr("Ordinal Position: %d", _position); - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -Type* Type::parse_generic_signature(DescriptorStream* STREAM) { - char c = READ(); - switch (c) { - case 'L': - return ClassType::parse_generic_signature(CHECK_STREAM); - case 'T': - return TypeVariable::parse_generic_signature(CHECK_STREAM); - case '[': - return ArrayType::parse_generic_signature(CHECK_STREAM); - default: - return new PrimitiveType(c); - } -} - -Identifier* ClassType::parse_generic_signature_simple(GrowableArray* args, - bool* has_inner, DescriptorStream* STREAM) { - STREAM->set_mark(); - - char c = READ(); - while (c != ';' && c != '.' && c != '<') { c = READ(); } - Identifier* id = STREAM->identifier_from_mark(); - - if (c == '<') { - c = READ(); - while (c != '>') { - PUSH(c); - TypeArgument* arg = TypeArgument::parse_generic_signature(CHECK_STREAM); - args->append(arg); - c = READ(); - } - c = READ(); - } - - *has_inner = (c == '.'); - if (!(*has_inner)) { - EXPECTED(c, ';'); - } - - return id; -} - -ClassType* ClassType::parse_generic_signature(DescriptorStream* STREAM) { - return parse_generic_signature(NULL, CHECK_STREAM); -} - -ClassType* ClassType::parse_generic_signature(ClassType* outer, DescriptorStream* STREAM) { - GrowableArray args; - ClassType* gct = NULL; - bool has_inner = false; - - Identifier* id = parse_generic_signature_simple(&args, &has_inner, STREAM); - if (id != NULL) { - gct = new ClassType(id, args, outer); - - if (has_inner) { - gct = parse_generic_signature(gct, CHECK_STREAM); - } - } - return gct; -} - -ClassType* ClassType::from_symbol(Symbol* sym) { - assert(sym != NULL, "Must not be null"); - GrowableArray args; - Identifier* id = new Identifier(sym, 0, sym->utf8_length()); - return new ClassType(id, args, NULL); -} - -ClassType* ClassType::java_lang_Object() { - return from_symbol(vmSymbols::java_lang_Object()); -} - -void ClassType::bind_variables_to_parameters(Descriptor* sig) { - for (int i = 0; i < _type_arguments.length(); ++i) { - _type_arguments.at(i)->bind_variables_to_parameters(sig); - } - if (_outer_class != NULL) { - _outer_class->bind_variables_to_parameters(sig); - } -} - -TypeArgument* ClassType::type_argument_at(int i) { - if (i >= 0 && i < _type_arguments.length()) { - return _type_arguments.at(i); - } else { - return NULL; - } -} - -#ifndef PRODUCT -void ClassType::reify_signature(stringStream* ss, Context* ctx) { - ss->print("L"); - _identifier->print_on(ss); - ss->print(";"); -} - -void ClassType::print_on(outputStream* str) const { - str->indent().print_cr("Class {"); - { - streamIndentor si(str); - str->indent().print("Name: "); - _identifier->print_on(str); - str->print_cr(""); - if (_type_arguments.length() != 0) { - str->indent().print_cr("Type Arguments: {"); - { - streamIndentor si(str); - for (int j = 0; j < _type_arguments.length(); ++j) { - _type_arguments.at(j)->print_on(str); - } - } - str->indent().print_cr("}"); - } - if (_outer_class != NULL) { - str->indent().print_cr("Outer Class: "); - streamIndentor sir(str); - _outer_class->print_on(str); - } - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -bool ClassType::covariant_match(Type* other, Context* ctx) { - - if (other == this) { - return true; - } - - TypeVariable* variable = other->as_variable(); - if (variable != NULL) { - other = variable->resolve(ctx, 0); - } - - ClassType* outer = outer_class(); - ClassType* other_class = other->as_class(); - - if (other_class == NULL || - (outer == NULL) != (other_class->outer_class() == NULL)) { - return false; - } - - if (!_identifier->equals(other_class->_identifier)) { - return false; - } - - if (outer != NULL && !outer->covariant_match(other_class->outer_class(), ctx)) { - return false; - } - - return true; -} - -ClassType* ClassType::canonicalize(Context* ctx, int ctx_depth) { - - GrowableArray args(_type_arguments.length()); - for (int i = 0; i < _type_arguments.length(); ++i) { - args.append(_type_arguments.at(i)->canonicalize(ctx, ctx_depth)); - } - - ClassType* outer = _outer_class == NULL ? NULL : - _outer_class->canonicalize(ctx, ctx_depth); - - return new ClassType(_identifier, args, outer); -} - -TypeVariable* TypeVariable::parse_generic_signature(DescriptorStream* STREAM) { - STREAM->set_mark(); - char c = READ(); - while (c != ';') { - c = READ(); - } - Identifier* id = STREAM->identifier_from_mark(); - - return new TypeVariable(id); -} - -void TypeVariable::bind_variables_to_parameters(Descriptor* sig) { - _parameter = sig->find_type_parameter(_id, &_inner_depth); - if (VerifyGenericSignatures && _parameter == NULL) { - fatal("Could not find formal parameter"); - } -} - -Type* TypeVariable::resolve(Context* ctx, int ctx_depth) { - if (parameter() != NULL) { - return parameter()->resolve(ctx, inner_depth(), ctx_depth); - } else { - if (VerifyGenericSignatures) { - fatal("Type variable matches no parameter"); - } - return NULL; - } -} - -bool TypeVariable::covariant_match(Type* other, Context* ctx) { - - if (other == this) { - return true; - } - - Context my_context(NULL); // empty, results in erasure - Type* my_type = resolve(&my_context, 0); - if (my_type == NULL) { - return false; - } - - return my_type->covariant_match(other, ctx); -} - -Type* TypeVariable::canonicalize(Context* ctx, int ctx_depth) { - return resolve(ctx, ctx_depth); -} - -#ifndef PRODUCT -void TypeVariable::reify_signature(stringStream* ss, Context* ctx) { - Type* type = resolve(ctx, 0); - if (type != NULL) { - type->reify_signature(ss, ctx); - } -} - -void TypeVariable::print_on(outputStream* str) const { - str->indent().print_cr("Type Variable {"); - { - streamIndentor si(str); - str->indent().print("Name: "); - _id->print_on(str); - str->print_cr(""); - str->indent().print_cr("Inner depth: %d", _inner_depth); - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -ArrayType* ArrayType::parse_generic_signature(DescriptorStream* STREAM) { - Type* base = Type::parse_generic_signature(CHECK_STREAM); - return new ArrayType(base); -} - -void ArrayType::bind_variables_to_parameters(Descriptor* sig) { - assert(_base != NULL, "Invalid base"); - _base->bind_variables_to_parameters(sig); -} - -bool ArrayType::covariant_match(Type* other, Context* ctx) { - assert(_base != NULL, "Invalid base"); - - if (other == this) { - return true; - } - - ArrayType* other_array = other->as_array(); - return (other_array != NULL && _base->covariant_match(other_array->_base, ctx)); -} - -ArrayType* ArrayType::canonicalize(Context* ctx, int ctx_depth) { - assert(_base != NULL, "Invalid base"); - return new ArrayType(_base->canonicalize(ctx, ctx_depth)); -} - -#ifndef PRODUCT -void ArrayType::reify_signature(stringStream* ss, Context* ctx) { - assert(_base != NULL, "Invalid base"); - ss->print("["); - _base->reify_signature(ss, ctx); -} - -void ArrayType::print_on(outputStream* str) const { - str->indent().print_cr("Array {"); - { - streamIndentor si(str); - _base->print_on(str); - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -bool PrimitiveType::covariant_match(Type* other, Context* ctx) { - - PrimitiveType* other_prim = other->as_primitive(); - return (other_prim != NULL && _type == other_prim->_type); -} - -PrimitiveType* PrimitiveType::canonicalize(Context* ctx, int ctxd) { - return this; -} - -#ifndef PRODUCT -void PrimitiveType::reify_signature(stringStream* ss, Context* ctx) { - ss->print("%c", _type); -} - -void PrimitiveType::print_on(outputStream* str) const { - str->indent().print_cr("Primitive: '%c'", _type); -} -#endif // ndef PRODUCT - -void PrimitiveType::bind_variables_to_parameters(Descriptor* sig) { -} - -TypeArgument* TypeArgument::parse_generic_signature(DescriptorStream* STREAM) { - char c = READ(); - Type* type = NULL; - - switch (c) { - case '*': - return new TypeArgument(ClassType::java_lang_Object(), NULL); - break; - default: - PUSH(c); - // fall-through - case '+': - case '-': - type = Type::parse_generic_signature(CHECK_STREAM); - if (c == '+') { - return new TypeArgument(type, NULL); - } else if (c == '-') { - return new TypeArgument(ClassType::java_lang_Object(), type); - } else { - return new TypeArgument(type, type); - } - } -} - -void TypeArgument::bind_variables_to_parameters(Descriptor* sig) { - assert(_lower_bound != NULL, "Invalid lower bound"); - _lower_bound->bind_variables_to_parameters(sig); - if (_upper_bound != NULL && _upper_bound != _lower_bound) { - _upper_bound->bind_variables_to_parameters(sig); - } -} - -bool TypeArgument::covariant_match(TypeArgument* other, Context* ctx) { - assert(_lower_bound != NULL, "Invalid lower bound"); - - if (other == this) { - return true; - } - - if (!_lower_bound->covariant_match(other->lower_bound(), ctx)) { - return false; - } - return true; -} - -TypeArgument* TypeArgument::canonicalize(Context* ctx, int ctx_depth) { - assert(_lower_bound != NULL, "Invalid lower bound"); - Type* lower = _lower_bound->canonicalize(ctx, ctx_depth); - Type* upper = NULL; - - if (_upper_bound == _lower_bound) { - upper = lower; - } else if (_upper_bound != NULL) { - upper = _upper_bound->canonicalize(ctx, ctx_depth); - } - - return new TypeArgument(lower, upper); -} - -#ifndef PRODUCT -void TypeArgument::print_on(outputStream* str) const { - str->indent().print_cr("TypeArgument {"); - { - streamIndentor si(str); - if (_lower_bound != NULL) { - str->indent().print("Lower bound: "); - _lower_bound->print_on(str); - } - if (_upper_bound != NULL) { - str->indent().print("Upper bound: "); - _upper_bound->print_on(str); - } - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -void Context::Mark::destroy() { - if (is_active()) { - _context->reset_to_mark(_marked_size); - } - deactivate(); -} - -void Context::apply_type_arguments( - InstanceKlass* current, InstanceKlass* super, TRAPS) { - assert(_cache != NULL, "Cannot use an empty context"); - ClassType* spec = NULL; - if (current != NULL) { - ClassDescriptor* descriptor = _cache->descriptor_for(current, CHECK); - if (super == current->super()) { - spec = descriptor->super(); - } else { - spec = descriptor->interface_desc(super->name()); - } - if (spec != NULL) { - _type_arguments.push(spec); - } - } -} - -void Context::reset_to_mark(int size) { - _type_arguments.trunc_to(size); -} - -ClassType* Context::at_depth(int i) const { - if (i < _type_arguments.length()) { - return _type_arguments.at(_type_arguments.length() - 1 - i); - } - return NULL; -} - -#ifndef PRODUCT -void Context::print_on(outputStream* str) const { - str->indent().print_cr("Context {"); - for (int i = 0; i < _type_arguments.length(); ++i) { - streamIndentor si(str); - str->indent().print("leval %d: ", i); - ClassType* ct = at_depth(i); - if (ct == NULL) { - str->print_cr(""); - continue; - } else { - str->print_cr("{"); - } - - for (int j = 0; j < ct->type_arguments_length(); ++j) { - streamIndentor si(str); - TypeArgument* ta = ct->type_argument_at(j); - Type* bound = ta->lower_bound(); - bound->print_on(str); - } - str->indent().print_cr("}"); - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -ClassDescriptor* DescriptorCache::descriptor_for(InstanceKlass* ik, TRAPS) { - - ClassDescriptor** existing = _class_descriptors.get(ik); - if (existing == NULL) { - ClassDescriptor* cd = ClassDescriptor::parse_generic_signature(ik, CHECK_NULL); - _class_descriptors.put(ik, cd); - return cd; - } else { - return *existing; - } -} - -MethodDescriptor* DescriptorCache::descriptor_for( - Method* mh, ClassDescriptor* cd, TRAPS) { - assert(mh != NULL && cd != NULL, "Should not be NULL"); - MethodDescriptor** existing = _method_descriptors.get(mh); - if (existing == NULL) { - MethodDescriptor* md = MethodDescriptor::parse_generic_signature(mh, cd); - _method_descriptors.put(mh, md); - return md; - } else { - return *existing; - } -} -MethodDescriptor* DescriptorCache::descriptor_for(Method* mh, TRAPS) { - ClassDescriptor* cd = descriptor_for( - InstanceKlass::cast(mh->method_holder()), CHECK_NULL); - return descriptor_for(mh, cd, THREAD); -} - -} // namespace generic diff --git a/hotspot/src/share/vm/classfile/genericSignatures.hpp b/hotspot/src/share/vm/classfile/genericSignatures.hpp deleted file mode 100644 index 07eb4759357..00000000000 --- a/hotspot/src/share/vm/classfile/genericSignatures.hpp +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright (c) 2012, 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. - * - */ - -#ifndef SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP -#define SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP - -#include "classfile/symbolTable.hpp" -#include "memory/allocation.hpp" -#include "runtime/signature.hpp" -#include "utilities/growableArray.hpp" -#include "utilities/resourceHash.hpp" - -class stringStream; - -namespace generic { - -class Identifier; -class ClassDescriptor; -class MethodDescriptor; - -class TypeParameter; // a formal type parameter declared in generic signatures -class TypeArgument; // The "type value" passed to fill parameters in supertypes -class TypeVariable; // A usage of a type parameter as a value -/** - * Example: - * - * class Foo extends Bar { int m(V v) {} } - * ^^^^^^ ^^^^^^ ^^ - * type parameters type argument type variable - * - * Note that a type variable could be passed as an argument too: - * class Foo extends Bar { int m(V v) {} } - * ^^^ - * type argument's value is a type variable - */ - - -class Type; -class ClassType; -class ArrayType; -class PrimitiveType; -class Context; -class DescriptorCache; - -class DescriptorStream; - -class Identifier : public ResourceObj { - private: - Symbol* _sym; - int _begin; - int _end; - - public: - Identifier(Symbol* sym, int begin, int end) : - _sym(sym), _begin(begin), _end(end) {} - - bool equals(Identifier* other); - bool equals(Symbol* sym); - -#ifndef PRODUCT - void print_on(outputStream* str) const; -#endif // ndef PRODUCT -}; - -class Descriptor : public ResourceObj { - protected: - GrowableArray _type_parameters; - ClassDescriptor* _outer_class; - - Descriptor(GrowableArray& params, - ClassDescriptor* outer) - : _type_parameters(params), _outer_class(outer) {} - - public: - - ClassDescriptor* outer_class() { return _outer_class; } - void set_outer_class(ClassDescriptor* sig) { _outer_class = sig; } - - virtual ClassDescriptor* as_class_signature() { return NULL; } - virtual MethodDescriptor* as_method_signature() { return NULL; } - - bool is_class_signature() { return as_class_signature() != NULL; } - bool is_method_signature() { return as_method_signature() != NULL; } - - GrowableArray& type_parameters() { - return _type_parameters; - } - - TypeParameter* find_type_parameter(Identifier* id, int* param_depth); - - virtual void bind_variables_to_parameters() = 0; - -#ifndef PRODUCT - virtual void print_on(outputStream* str) const = 0; -#endif -}; - -class ClassDescriptor : public Descriptor { - private: - ClassType* _super; - GrowableArray _interfaces; - MethodDescriptor* _outer_method; - - ClassDescriptor(GrowableArray& ftp, ClassType* scs, - GrowableArray& sis, ClassDescriptor* outer_class = NULL, - MethodDescriptor* outer_method = NULL) - : Descriptor(ftp, outer_class), _super(scs), _interfaces(sis), - _outer_method(outer_method) {} - - static u2 get_outer_class_index(InstanceKlass* k, TRAPS); - static ClassDescriptor* parse_generic_signature(Klass* k, Symbol* original_name, TRAPS); - - public: - - virtual ClassDescriptor* as_class_signature() { return this; } - - MethodDescriptor* outer_method() { return _outer_method; } - void set_outer_method(MethodDescriptor* m) { _outer_method = m; } - - ClassType* super() { return _super; } - ClassType* interface_desc(Symbol* sym); - - static ClassDescriptor* parse_generic_signature(Klass* k, TRAPS); - static ClassDescriptor* parse_generic_signature(Symbol* sym); - - // For use in superclass chains in positions where this is no generic info - static ClassDescriptor* placeholder(InstanceKlass* klass); - -#ifndef PRODUCT - void print_on(outputStream* str) const; -#endif - - ClassDescriptor* canonicalize(Context* ctx); - - // Linking sets the position index in any contained TypeVariable type - // to correspond to the location of that identifier in the formal type - // parameters. - void bind_variables_to_parameters(); -}; - -class MethodDescriptor : public Descriptor { - private: - GrowableArray _parameters; - Type* _return_type; - GrowableArray _throws; - - MethodDescriptor(GrowableArray& ftp, ClassDescriptor* outer, - GrowableArray& sigs, Type* rt, GrowableArray& throws) - : Descriptor(ftp, outer), _parameters(sigs), _return_type(rt), - _throws(throws) {} - - public: - - static MethodDescriptor* parse_generic_signature(Method* m, ClassDescriptor* outer); - static MethodDescriptor* parse_generic_signature(Symbol* sym, ClassDescriptor* outer); - - MethodDescriptor* as_method_signature() { return this; } - - // Performs generic analysis on the method parameters to determine - // if both methods refer to the same argument types. - bool covariant_match(MethodDescriptor* other, Context* ctx); - - // Returns a new method descriptor with all generic variables - // removed and replaced with whatever is indicated using the Context. - MethodDescriptor* canonicalize(Context* ctx); - - void bind_variables_to_parameters(); - -#ifndef PRODUCT - TempNewSymbol reify_signature(Context* ctx, TRAPS); - void print_on(outputStream* str) const; -#endif -}; - -class TypeParameter : public ResourceObj { - private: - Identifier* _identifier; - ClassType* _class_bound; - GrowableArray _interface_bounds; - - // The position is the ordinal location of the parameter within the - // formal parameter list (excluding outer classes). It is only set for - // formal type parameters that are associated with a class -- method - // type parameters are left as -1. When resolving a generic variable to - // find the actual type, this index is used to access the generic type - // argument in the provided context object. - int _position; // Assigned during variable linking - - TypeParameter(Identifier* id, ClassType* class_bound, - GrowableArray& interface_bounds) : - _identifier(id), _class_bound(class_bound), - _interface_bounds(interface_bounds), _position(-1) {} - - public: - static TypeParameter* parse_generic_signature(DescriptorStream* str); - - ClassType* bound(); - int position() { return _position; } - - void bind_variables_to_parameters(Descriptor* sig, int position); - Identifier* identifier() { return _identifier; } - - Type* resolve(Context* ctx, int inner_depth, int ctx_depth); - TypeParameter* canonicalize(Context* ctx, int ctx_depth); - -#ifndef PRODUCT - void print_on(outputStream* str) const; -#endif -}; - -class Type : public ResourceObj { - public: - static Type* parse_generic_signature(DescriptorStream* str); - - virtual ClassType* as_class() { return NULL; } - virtual TypeVariable* as_variable() { return NULL; } - virtual ArrayType* as_array() { return NULL; } - virtual PrimitiveType* as_primitive() { return NULL; } - - virtual bool covariant_match(Type* gt, Context* ctx) = 0; - virtual Type* canonicalize(Context* ctx, int ctx_depth) = 0; - - virtual void bind_variables_to_parameters(Descriptor* sig) = 0; - -#ifndef PRODUCT - virtual void reify_signature(stringStream* ss, Context* ctx) = 0; - virtual void print_on(outputStream* str) const = 0; -#endif -}; - -class ClassType : public Type { - friend class ClassDescriptor; - protected: - Identifier* _identifier; - GrowableArray _type_arguments; - ClassType* _outer_class; - - ClassType(Identifier* identifier, - GrowableArray& args, - ClassType* outer) - : _identifier(identifier), _type_arguments(args), _outer_class(outer) {} - - // Returns true if there are inner classes to read - static Identifier* parse_generic_signature_simple( - GrowableArray* args, - bool* has_inner, DescriptorStream* str); - - static ClassType* parse_generic_signature(ClassType* outer, - DescriptorStream* str); - static ClassType* from_symbol(Symbol* sym); - - public: - ClassType* as_class() { return this; } - - static ClassType* parse_generic_signature(DescriptorStream* str); - static ClassType* java_lang_Object(); - - Identifier* identifier() { return _identifier; } - int type_arguments_length() { return _type_arguments.length(); } - TypeArgument* type_argument_at(int i); - - virtual ClassType* outer_class() { return _outer_class; } - - bool covariant_match(Type* gt, Context* ctx); - ClassType* canonicalize(Context* ctx, int context_depth); - - void bind_variables_to_parameters(Descriptor* sig); - -#ifndef PRODUCT - void reify_signature(stringStream* ss, Context* ctx); - void print_on(outputStream* str) const; -#endif -}; - -class TypeVariable : public Type { - private: - Identifier* _id; - TypeParameter* _parameter; // assigned during linking - - // how many steps "out" from inner classes, -1 if method - int _inner_depth; - - TypeVariable(Identifier* id) - : _id(id), _parameter(NULL), _inner_depth(0) {} - - public: - TypeVariable* as_variable() { return this; } - - static TypeVariable* parse_generic_signature(DescriptorStream* str); - - Identifier* identifier() { return _id; } - TypeParameter* parameter() { return _parameter; } - int inner_depth() { return _inner_depth; } - - void bind_variables_to_parameters(Descriptor* sig); - - Type* resolve(Context* ctx, int ctx_depth); - bool covariant_match(Type* gt, Context* ctx); - Type* canonicalize(Context* ctx, int ctx_depth); - -#ifndef PRODUCT - void reify_signature(stringStream* ss, Context* ctx); - void print_on(outputStream* str) const; -#endif -}; - -class ArrayType : public Type { - private: - Type* _base; - - ArrayType(Type* base) : _base(base) {} - - public: - ArrayType* as_array() { return this; } - - static ArrayType* parse_generic_signature(DescriptorStream* str); - - bool covariant_match(Type* gt, Context* ctx); - ArrayType* canonicalize(Context* ctx, int ctx_depth); - - void bind_variables_to_parameters(Descriptor* sig); - -#ifndef PRODUCT - void reify_signature(stringStream* ss, Context* ctx); - void print_on(outputStream* str) const; -#endif -}; - -class PrimitiveType : public Type { - friend class Type; - private: - char _type; // includes V for void - - PrimitiveType(char& type) : _type(type) {} - - public: - PrimitiveType* as_primitive() { return this; } - - bool covariant_match(Type* gt, Context* ctx); - PrimitiveType* canonicalize(Context* ctx, int ctx_depth); - - void bind_variables_to_parameters(Descriptor* sig); - -#ifndef PRODUCT - void reify_signature(stringStream* ss, Context* ctx); - void print_on(outputStream* str) const; -#endif -}; - -class TypeArgument : public ResourceObj { - private: - Type* _lower_bound; - Type* _upper_bound; // may be null or == _lower_bound - - TypeArgument(Type* lower_bound, Type* upper_bound) - : _lower_bound(lower_bound), _upper_bound(upper_bound) {} - - public: - - static TypeArgument* parse_generic_signature(DescriptorStream* str); - - Type* lower_bound() { return _lower_bound; } - Type* upper_bound() { return _upper_bound; } - - void bind_variables_to_parameters(Descriptor* sig); - TypeArgument* canonicalize(Context* ctx, int ctx_depth); - - bool covariant_match(TypeArgument* a, Context* ctx); - -#ifndef PRODUCT - void print_on(outputStream* str) const; -#endif -}; - - -class Context : public ResourceObj { - private: - DescriptorCache* _cache; - GrowableArray _type_arguments; - - void reset_to_mark(int size); - - public: - // When this object goes out of scope or 'destroy' is - // called, then the application of the type to the - // context is wound-back (unless it's been deactivated). - class Mark : public StackObj { - private: - mutable Context* _context; - int _marked_size; - - bool is_active() const { return _context != NULL; } - void deactivate() const { _context = NULL; } - - public: - Mark() : _context(NULL), _marked_size(0) {} - Mark(Context* ctx, int sz) : _context(ctx), _marked_size(sz) {} - Mark(const Mark& m) : _context(m._context), _marked_size(m._marked_size) { - m.deactivate(); // Ownership is transferred - } - - Mark& operator=(const Mark& cm) { - destroy(); - _context = cm._context; - _marked_size = cm._marked_size; - cm.deactivate(); - return *this; - } - - void destroy(); - ~Mark() { destroy(); } - }; - - Context(DescriptorCache* cache) : _cache(cache) {} - - Mark mark() { return Mark(this, _type_arguments.length()); } - void apply_type_arguments(InstanceKlass* current, InstanceKlass* super,TRAPS); - - ClassType* at_depth(int i) const; - -#ifndef PRODUCT - void print_on(outputStream* str) const; -#endif -}; - -/** - * Contains a cache of descriptors for classes and methods so they can be - * looked-up instead of reparsing each time they are needed. - */ -class DescriptorCache : public ResourceObj { - private: - ResourceHashtable _class_descriptors; - ResourceHashtable _method_descriptors; - - public: - ClassDescriptor* descriptor_for(InstanceKlass* ikh, TRAPS); - - MethodDescriptor* descriptor_for(Method* mh, ClassDescriptor* cd, TRAPS); - // Class descriptor derived from method holder - MethodDescriptor* descriptor_for(Method* mh, TRAPS); -}; - -} // namespace generic - -#endif // SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP - diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 9b67389af47..1b17ae4ead7 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -3682,15 +3682,9 @@ class CommandLineFlags { develop(bool, TraceDefaultMethods, false, \ "Trace the default method processing steps") \ \ - develop(bool, ParseAllGenericSignatures, false, \ - "Parse all generic signatures while classloading") \ - \ develop(bool, VerifyGenericSignatures, false, \ "Abort VM on erroneous or inconsistent generic signatures") \ \ - product(bool, ParseGenericDefaults, false, \ - "Parse generic signatures for default method handling") \ - \ product(bool, UseVMInterruptibleIO, false, \ "(Unstable, Solaris-specific) Thread interrupt before or with " \ "EINTR for I/O operations results in OS_INTRPT. The default value"\ From 033640bd2c8c8a26fd77b4cae307e0a4e42eab3e Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Mon, 26 Aug 2013 13:32:14 -0400 Subject: [PATCH 0108/1294] 8023477: Invalid CP index when reading ConstantPool Need to check for 0 case for InstanceKlass::_generic_signature_index. Reviewed-by: sspitsyn, sla --- .../classes/sun/jvm/hotspot/oops/InstanceKlass.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java index 1cc2c8d910a..01104f59515 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java @@ -354,9 +354,16 @@ public class InstanceKlass extends Klass { public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; } public long getVtableLen() { return vtableLen.getValue(this); } public long getItableLen() { return itableLen.getValue(this); } - public Symbol getGenericSignature() { return getConstants().getSymbolAt(genericSignatureIndex.getValue(this)); } public long majorVersion() { return majorVersion.getValue(this); } public long minorVersion() { return minorVersion.getValue(this); } + public Symbol getGenericSignature() { + long index = genericSignatureIndex.getValue(this); + if (index != 0) { + return getConstants().getSymbolAt(index); + } else { + return null; + } + } // "size helper" == instance size in words public long getSizeHelper() { From 4415ae47cddaa0f314c23a8beff2c99224edfe1f Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Mon, 26 Aug 2013 14:11:26 -0700 Subject: [PATCH 0109/1294] 8020675: invalid jar file in the bootclasspath could lead to jvm fatal error Removed offending EXCEPTION_MARK calls and code cleanup Reviewed-by: dholmes, iklam, coleenp, mseledtsov --- .../src/share/vm/classfile/classLoader.cpp | 66 +++++++++++-------- .../src/share/vm/classfile/classLoader.hpp | 20 +++--- .../runtime/LoadClass/LoadClassNegative.java | 51 ++++++++++++++ .../test/runtime/LoadClass/TestForName.java | 33 ++++++++++ hotspot/test/runtime/LoadClass/dummy.jar | 0 5 files changed, 135 insertions(+), 35 deletions(-) create mode 100644 hotspot/test/runtime/LoadClass/LoadClassNegative.java create mode 100644 hotspot/test/runtime/LoadClass/TestForName.java create mode 100644 hotspot/test/runtime/LoadClass/dummy.jar diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp index 32a4da05bb5..35055b4cb41 100644 --- a/hotspot/src/share/vm/classfile/classLoader.cpp +++ b/hotspot/src/share/vm/classfile/classLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -197,7 +197,7 @@ ClassPathDirEntry::ClassPathDirEntry(char* dir) : ClassPathEntry() { } -ClassFileStream* ClassPathDirEntry::open_stream(const char* name) { +ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) { // construct full path name char path[JVM_MAXPATHLEN]; if (jio_snprintf(path, sizeof(path), "%s%s%s", _dir, os::file_separator(), name) == -1) { @@ -240,7 +240,7 @@ ClassPathZipEntry::~ClassPathZipEntry() { FREE_C_HEAP_ARRAY(char, _zip_name, mtClass); } -ClassFileStream* ClassPathZipEntry::open_stream(const char* name) { +ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) { // enable call to C land JavaThread* thread = JavaThread::current(); ThreadToNativeFromVM ttn(thread); @@ -284,24 +284,24 @@ void ClassPathZipEntry::contents_do(void f(const char* name, void* context), voi } } -LazyClassPathEntry::LazyClassPathEntry(char* path, struct stat st) : ClassPathEntry() { +LazyClassPathEntry::LazyClassPathEntry(char* path, const struct stat* st) : ClassPathEntry() { _path = strdup(path); - _st = st; + _st = *st; _meta_index = NULL; _resolved_entry = NULL; + _has_error = false; } bool LazyClassPathEntry::is_jar_file() { return ((_st.st_mode & S_IFREG) == S_IFREG); } -ClassPathEntry* LazyClassPathEntry::resolve_entry() { +ClassPathEntry* LazyClassPathEntry::resolve_entry(TRAPS) { if (_resolved_entry != NULL) { return (ClassPathEntry*) _resolved_entry; } ClassPathEntry* new_entry = NULL; - ClassLoader::create_class_path_entry(_path, _st, &new_entry, false); - assert(new_entry != NULL, "earlier code should have caught this"); + new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, CHECK_NULL); { ThreadCritical tc; if (_resolved_entry == NULL) { @@ -314,12 +314,21 @@ ClassPathEntry* LazyClassPathEntry::resolve_entry() { return (ClassPathEntry*) _resolved_entry; } -ClassFileStream* LazyClassPathEntry::open_stream(const char* name) { +ClassFileStream* LazyClassPathEntry::open_stream(const char* name, TRAPS) { if (_meta_index != NULL && !_meta_index->may_contain(name)) { return NULL; } - return resolve_entry()->open_stream(name); + if (_has_error) { + return NULL; + } + ClassPathEntry* cpe = resolve_entry(THREAD); + if (cpe == NULL) { + _has_error = true; + return NULL; + } else { + return cpe->open_stream(name, THREAD); + } } bool LazyClassPathEntry::is_lazy() { @@ -465,20 +474,19 @@ void ClassLoader::setup_bootstrap_search_path() { } } -void ClassLoader::create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy) { +ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st, bool lazy, TRAPS) { JavaThread* thread = JavaThread::current(); if (lazy) { - *new_entry = new LazyClassPathEntry(path, st); - return; + return new LazyClassPathEntry(path, st); } - if ((st.st_mode & S_IFREG) == S_IFREG) { + ClassPathEntry* new_entry = NULL; + if ((st->st_mode & S_IFREG) == S_IFREG) { // Regular file, should be a zip file // Canonicalized filename char canonical_path[JVM_MAXPATHLEN]; if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) { // This matches the classic VM - EXCEPTION_MARK; - THROW_MSG(vmSymbols::java_io_IOException(), "Bad pathname"); + THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL); } char* error_msg = NULL; jzfile* zip; @@ -489,7 +497,7 @@ void ClassLoader::create_class_path_entry(char *path, struct stat st, ClassPathE zip = (*ZipOpen)(canonical_path, &error_msg); } if (zip != NULL && error_msg == NULL) { - *new_entry = new ClassPathZipEntry(zip, path); + new_entry = new ClassPathZipEntry(zip, path); if (TraceClassLoading) { tty->print_cr("[Opened %s]", path); } @@ -504,16 +512,16 @@ void ClassLoader::create_class_path_entry(char *path, struct stat st, ClassPathE msg = NEW_RESOURCE_ARRAY(char, len); ; jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path); } - EXCEPTION_MARK; - THROW_MSG(vmSymbols::java_lang_ClassNotFoundException(), msg); + THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL); } } else { // Directory - *new_entry = new ClassPathDirEntry(path); + new_entry = new ClassPathDirEntry(path); if (TraceClassLoading) { tty->print_cr("[Path %s]", path); } } + return new_entry; } @@ -572,13 +580,14 @@ void ClassLoader::add_to_list(ClassPathEntry *new_entry) { } } -void ClassLoader::update_class_path_entry_list(const char *path, +void ClassLoader::update_class_path_entry_list(char *path, bool check_for_duplicates) { struct stat st; - if (os::stat((char *)path, &st) == 0) { + if (os::stat(path, &st) == 0) { // File or directory found ClassPathEntry* new_entry = NULL; - create_class_path_entry((char *)path, st, &new_entry, LazyBootClassLoader); + Thread* THREAD = Thread::current(); + new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, CHECK); // The kernel VM adds dynamically to the end of the classloader path and // doesn't reorder the bootclasspath which would break java.lang.Package // (see PackageInfo). @@ -897,7 +906,7 @@ instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) { PerfClassTraceTime::CLASS_LOAD); ClassPathEntry* e = _first_entry; while (e != NULL) { - stream = e->open_stream(name); + stream = e->open_stream(name, CHECK_NULL); if (stream != NULL) { break; } @@ -1257,11 +1266,16 @@ bool ClassPathZipEntry::is_rt_jar12() { } void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) { - resolve_entry()->compile_the_world(loader, CHECK); + ClassPathEntry* cpe = resolve_entry(THREAD); + if (cpe != NULL) { + cpe->compile_the_world(loader, CHECK); + } } bool LazyClassPathEntry::is_rt_jar() { - return resolve_entry()->is_rt_jar(); + Thread* THREAD = Thread::current(); + ClassPathEntry* cpe = resolve_entry(THREAD); + return (cpe != NULL) ? cpe->is_jar_file() : false; } void ClassLoader::compile_the_world() { diff --git a/hotspot/src/share/vm/classfile/classLoader.hpp b/hotspot/src/share/vm/classfile/classLoader.hpp index 786914cad22..e03cfad1b57 100644 --- a/hotspot/src/share/vm/classfile/classLoader.hpp +++ b/hotspot/src/share/vm/classfile/classLoader.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ class ClassPathEntry: public CHeapObj { ClassPathEntry(); // Attempt to locate file_name through this class path entry. // Returns a class file parsing stream if successfull. - virtual ClassFileStream* open_stream(const char* name) = 0; + virtual ClassFileStream* open_stream(const char* name, TRAPS) = 0; // Debugging NOT_PRODUCT(virtual void compile_the_world(Handle loader, TRAPS) = 0;) NOT_PRODUCT(virtual bool is_rt_jar() = 0;) @@ -77,7 +77,7 @@ class ClassPathDirEntry: public ClassPathEntry { bool is_jar_file() { return false; } const char* name() { return _dir; } ClassPathDirEntry(char* dir); - ClassFileStream* open_stream(const char* name); + ClassFileStream* open_stream(const char* name, TRAPS); // Debugging NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);) NOT_PRODUCT(bool is_rt_jar();) @@ -107,7 +107,7 @@ class ClassPathZipEntry: public ClassPathEntry { const char* name() { return _zip_name; } ClassPathZipEntry(jzfile* zip, const char* zip_name); ~ClassPathZipEntry(); - ClassFileStream* open_stream(const char* name); + ClassFileStream* open_stream(const char* name, TRAPS); void contents_do(void f(const char* name, void* context), void* context); // Debugging NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);) @@ -125,13 +125,14 @@ class LazyClassPathEntry: public ClassPathEntry { char* _path; // dir or file struct stat _st; MetaIndex* _meta_index; + bool _has_error; volatile ClassPathEntry* _resolved_entry; - ClassPathEntry* resolve_entry(); + ClassPathEntry* resolve_entry(TRAPS); public: bool is_jar_file(); const char* name() { return _path; } - LazyClassPathEntry(char* path, struct stat st); - ClassFileStream* open_stream(const char* name); + LazyClassPathEntry(char* path, const struct stat* st); + ClassFileStream* open_stream(const char* name, TRAPS); void set_meta_index(MetaIndex* meta_index) { _meta_index = meta_index; } virtual bool is_lazy(); // Debugging @@ -207,14 +208,15 @@ class ClassLoader: AllStatic { static void setup_meta_index(); static void setup_bootstrap_search_path(); static void load_zip_library(); - static void create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy); + static ClassPathEntry* create_class_path_entry(char *path, const struct stat* st, + bool lazy, TRAPS); // Canonicalizes path names, so strcmp will work properly. This is mainly // to avoid confusing the zip library static bool get_canonical_path(char* orig, char* out, int len); public: // Used by the kernel jvm. - static void update_class_path_entry_list(const char *path, + static void update_class_path_entry_list(char *path, bool check_for_duplicates); static void print_bootclasspath(); diff --git a/hotspot/test/runtime/LoadClass/LoadClassNegative.java b/hotspot/test/runtime/LoadClass/LoadClassNegative.java new file mode 100644 index 00000000000..9955bca00eb --- /dev/null +++ b/hotspot/test/runtime/LoadClass/LoadClassNegative.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013, 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 + * @key regression + * @bug 8020675 + * @summary make sure there is no fatal error if a class is loaded from an invalid jar file which is in the bootclasspath + * @library /testlibrary + * @build TestForName + * @build LoadClassNegative + * @run main LoadClassNegative + */ + +import java.io.File; +import com.oracle.java.testlibrary.*; + +public class LoadClassNegative { + + public static void main(String args[]) throws Exception { + String bootCP = "-Xbootclasspath/a:" + System.getProperty("test.src") + + File.separator + "dummy.jar"; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + bootCP, + "TestForName"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("ClassNotFoundException"); + output.shouldHaveExitValue(0); + } +} diff --git a/hotspot/test/runtime/LoadClass/TestForName.java b/hotspot/test/runtime/LoadClass/TestForName.java new file mode 100644 index 00000000000..429d8691cf2 --- /dev/null +++ b/hotspot/test/runtime/LoadClass/TestForName.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class TestForName { + public static void main(String[] args) { + try { + Class cls = Class.forName("xxx"); + System.out.println("Class = " + cls.getName()); + } catch (ClassNotFoundException cnfe) { + cnfe.printStackTrace(); + } + } +} diff --git a/hotspot/test/runtime/LoadClass/dummy.jar b/hotspot/test/runtime/LoadClass/dummy.jar new file mode 100644 index 00000000000..e69de29bb2d From 63e8e6745118cc246344932c0cc1f84afa72a90d Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Mon, 26 Aug 2013 21:59:50 -0700 Subject: [PATCH 0110/1294] 8020622: create.bat on Windows failed to create project file for Visual Studio 2012 Treat VS2012 the same as VS2010. Reviewed-by: dcubed, kamg, minqi --- hotspot/make/windows/create.bat | 7 +++++++ hotspot/make/windows/makefiles/rules.make | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/hotspot/make/windows/create.bat b/hotspot/make/windows/create.bat index 6e72fa9c9e9..a9a8acea6d2 100644 --- a/hotspot/make/windows/create.bat +++ b/hotspot/make/windows/create.bat @@ -82,6 +82,7 @@ for /F %%i in ('sh %HotSpotWorkSpace%/make/windows/get_msc_ver.sh') do set %%i echo ************************************************************** set ProjectFile=%HotSpotBuildSpace%\jvm.vcproj +echo MSC_VER = "%MSC_VER%" if "%MSC_VER%" == "1200" ( set ProjectFile=%HotSpotBuildSpace%\jvm.dsp echo Will generate VC6 project {unsupported} @@ -96,11 +97,17 @@ if "%MSC_VER%" == "1600" ( echo Will generate VC10 {Visual Studio 2010} set ProjectFile=%HotSpotBuildSpace%\jvm.vcxproj ) else ( +if "%MSC_VER%" == "1700" ( +echo Will generate VC10 {compatible with Visual Studio 2012} +echo After opening in VS 2012, click "Update" when prompted. +set ProjectFile=%HotSpotBuildSpace%\jvm.vcxproj +) else ( echo Will generate VC7 project {Visual Studio 2003 .NET} ) ) ) ) +) echo %ProjectFile% echo ************************************************************** diff --git a/hotspot/make/windows/makefiles/rules.make b/hotspot/make/windows/makefiles/rules.make index 693c1926526..d728263171b 100644 --- a/hotspot/make/windows/makefiles/rules.make +++ b/hotspot/make/windows/makefiles/rules.make @@ -69,6 +69,13 @@ VcVersion=VC9 VcVersion=VC10 ProjectFile=jvm.vcxproj +!elseif "$(MSC_VER)" == "1700" +# This is VS2012, but it loads VS10 projects just fine (and will +# upgrade them automatically to VS2012 format). + +VcVersion=VC10 +ProjectFile=jvm.vcxproj + !else VcVersion=VC7 From 6018c4e07f0fb0a1ec8ff6a8c878aabcff9a2779 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 27 Aug 2013 12:53:46 +0400 Subject: [PATCH 0111/1294] 7195179: ClassCastException for null values in JComboBox Reviewed-by: alexsch --- .../swing/plaf/basic/BasicComboBoxUI.java | 12 +-- .../swing/JComboBox/7195179/Test7195179.java | 84 +++++++++++++++++++ 2 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 jdk/test/javax/swing/JComboBox/7195179/Test7195179.java diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java index 331c5674ad3..eec48001160 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java @@ -971,14 +971,16 @@ public class BasicComboBoxUI extends ComboBoxUI { // cells, if not, this needs to loop through all. value = comboBox.getModel().getElementAt(0); } - if (value == null) { - value = " "; - } else if (value instanceof String && "".equals(value)) { - value = " "; - } Component component = renderer. getListCellRendererComponent(listBox, value, -1, false, false); + if (component instanceof JLabel) { + JLabel label = (JLabel) component; + String text = label.getText(); + if ((text == null) || text.isEmpty()) { + label.setText(" "); + } + } if (component instanceof JComponent) { component.setFont(comboBox.getFont()); } diff --git a/jdk/test/javax/swing/JComboBox/7195179/Test7195179.java b/jdk/test/javax/swing/JComboBox/7195179/Test7195179.java new file mode 100644 index 00000000000..f22084a87bc --- /dev/null +++ b/jdk/test/javax/swing/JComboBox/7195179/Test7195179.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Component; +import javax.swing.GroupLayout; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; +import javax.swing.plaf.basic.BasicComboBoxRenderer; + +import static javax.swing.SwingUtilities.invokeAndWait; + +/* + * @test + * @bug 7195179 + * @summary Tests that combobox works with generified renderers + * @author Sergey Malenkov + */ + +public class Test7195179 { + public static void main(String[] args) throws Exception { + invokeAndWait(new Runnable() { + @Override + public void run() { + Integer[] items = {null, 1, 2, 3}; + JComboBox combo = new JComboBox<>(items); + JLabel label = new JLabel("choose:"); + JPanel panel = new JPanel(); + GroupLayout layout = new GroupLayout(panel); + panel.setLayout(layout); + label.setLabelFor(combo); + combo.setSelectedIndex(0); + combo.setRenderer(new ListCellRenderer() { + private final BasicComboBoxRenderer renderer = new BasicComboBoxRenderer(); + + @Override + public Component getListCellRendererComponent(JList list, Integer value, int index, boolean isSelected, boolean cellHasFocus) { + return this.renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + } + }); + layout.setAutoCreateContainerGaps(true); + layout.setAutoCreateGaps(true); + layout.setHorizontalGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup().addComponent(label)) + .addGroup(layout.createParallelGroup().addComponent(combo))); + layout.setVerticalGroup(layout + .createSequentialGroup() + .addGroup(layout + .createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(label) + .addComponent(combo))); + + JFrame frame = new JFrame(getClass().getSimpleName()); + frame.add(panel); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.pack(); + frame.setVisible(true); + } + }); + } +} From 6dd078f94a61459f72cf552e10149fffbfb16f69 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 27 Aug 2013 13:13:32 +0400 Subject: [PATCH 0112/1294] 8021379: JFileChooser Create New Folder button enabled in write proteced directory Reviewed-by: alexsch --- jdk/src/share/classes/sun/swing/FilePane.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/sun/swing/FilePane.java b/jdk/src/share/classes/sun/swing/FilePane.java index 8dbaab55c3e..44aedab3d28 100644 --- a/jdk/src/share/classes/sun/swing/FilePane.java +++ b/jdk/src/share/classes/sun/swing/FilePane.java @@ -1980,18 +1980,18 @@ public class FilePane extends JPanel implements PropertyChangeListener { } if (f instanceof ShellFolder) { - return ((ShellFolder) f).isFileSystem(); + return f.canWrite(); } else { if (usesShellFolder(getFileChooser())) { try { - return ShellFolder.getShellFolder(f).isFileSystem(); + return ShellFolder.getShellFolder(f).canWrite(); } catch (FileNotFoundException ex) { // File doesn't exist return false; } } else { // Ordinary file - return true; + return f.canWrite(); } } } From e304fd35a02ddabc68318191f73071f63da8ef20 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 27 Aug 2013 13:37:38 +0400 Subject: [PATCH 0113/1294] 8022398: javax/swing/JFileChooser/8013442/Test8013442.java fails Reviewed-by: alexsch --- .../com/apple/laf/AquaFileChooserUI.java | 62 +---------- .../java/swing/plaf/gtk/GTKFileChooserUI.java | 69 +----------- .../swing/plaf/motif/MotifFileChooserUI.java | 68 +----------- .../plaf/windows/WindowsFileChooserUI.java | 67 +---------- .../swing/plaf/metal/MetalFileChooserUI.java | 66 +---------- .../swing/AbstractFilterComboBoxModel.java | 104 ++++++++++++++++++ .../plaf/synth/SynthFileChooserUIImpl.java | 67 +---------- 7 files changed, 125 insertions(+), 378 deletions(-) create mode 100644 jdk/src/share/classes/sun/swing/AbstractFilterComboBoxModel.java diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java b/jdk/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java index b7598f99d6d..be4b5b72a32 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java @@ -42,6 +42,7 @@ import javax.swing.filechooser.*; import javax.swing.plaf.*; import javax.swing.table.*; +import sun.swing.AbstractFilterComboBoxModel; import sun.swing.SwingUtilities2; public class AquaFileChooserUI extends FileChooserUI { @@ -1266,64 +1267,9 @@ public class AquaFileChooserUI extends FileChooserUI { /** * Data model for a type-face selection combo-box. */ - protected class FilterComboBoxModel extends DefaultListModel implements ComboBoxModel, PropertyChangeListener { - int selectedIndex = -1; - - protected FilterComboBoxModel() { - super(); - final FileFilter filters[] = getFileChooser().getChoosableFileFilters(); - for (int i = 0; i < filters.length; i++) { - this.add(i, filters[i]); - } - } - - public void propertyChange(final PropertyChangeEvent e) { - final String prop = e.getPropertyName(); - if (prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - this.clear(); - final FileFilter filters[] = (FileFilter[])e.getNewValue(); - - for (int i = 0; i < filters.length; i++) { - this.add(i, filters[i]); - } - - fireContentsChanged(this, -1, -1); - } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) { - final FileFilter currentFilter = (FileFilter)e.getNewValue(); - FileFilter filters[] = getFileChooser().getChoosableFileFilters(); - - boolean found = false; - if (currentFilter != null) { - for (final FileFilter element : filters) { - if (element == currentFilter) { - found = true; - } - } - if (found == false) { - getFileChooser().addChoosableFileFilter(currentFilter); - } - } - - filters = getFileChooser().getChoosableFileFilters(); - setSelectedItem(e.getNewValue()); - } - } - - public void setSelectedItem(final Object filter) { - if (filter != null) { - selectedIndex = this.indexOf(filter); - fireContentsChanged(this, -1, -1); - } - } - - public Object getSelectedItem() { - final Object returnValue = null; - - if (this.size() > 0) { - if ((selectedIndex != -1) && (selectedIndex < size())) { return this.get(selectedIndex); } - } - - return returnValue; + protected class FilterComboBoxModel extends AbstractFilterComboBoxModel { + protected JFileChooser getFileChooser() { + return AquaFileChooserUI.this.getFileChooser(); } } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java index 0cff673711c..df2b7f7cc23 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java @@ -41,6 +41,7 @@ import javax.swing.plaf.basic.BasicDirectoryModel; import javax.swing.table.*; import javax.accessibility.*; +import sun.swing.AbstractFilterComboBoxModel; import sun.swing.SwingUtilities2; import sun.swing.plaf.synth.*; @@ -1328,71 +1329,9 @@ class GTKFileChooserUI extends SynthFileChooserUI { /** * Data model for filter combo-box. */ - protected class FilterComboBoxModel extends AbstractListModel - implements ComboBoxModel, PropertyChangeListener { - protected FileFilter[] filters; - - protected FilterComboBoxModel() { - super(); - filters = getFileChooser().getChoosableFileFilters(); - } - - public void propertyChange(PropertyChangeEvent e) { - String prop = e.getPropertyName(); - if (prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - filters = (FileFilter[]) e.getNewValue(); - fireContentsChanged(this, -1, -1); - } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) { - fireContentsChanged(this, -1, -1); - } - } - - public void setSelectedItem(Object filter) { - if (filter != null) { - getFileChooser().setFileFilter((FileFilter) filter); - fireContentsChanged(this, -1, -1); - } - } - - public Object getSelectedItem() { - // Ensure that the current filter is in the list. - // NOTE: we shouldnt' have to do this, since JFileChooser adds - // the filter to the choosable filters list when the filter - // is set. Lets be paranoid just in case someone overrides - // setFileFilter in JFileChooser. - FileFilter currentFilter = getFileChooser().getFileFilter(); - boolean found = false; - if (currentFilter != null) { - for (FileFilter filter : filters) { - if (filter == currentFilter) { - found = true; - } - } - if (found == false) { - getFileChooser().addChoosableFileFilter(currentFilter); - } - } - return getFileChooser().getFileFilter(); - } - - public int getSize() { - if (filters != null) { - return filters.length; - } else { - return 0; - } - } - - public Object getElementAt(int index) { - if (index > getSize() - 1) { - // This shouldn't happen. Try to recover gracefully. - return getFileChooser().getFileFilter(); - } - if (filters != null) { - return filters[index]; - } else { - return null; - } + protected class FilterComboBoxModel extends AbstractFilterComboBoxModel { + protected JFileChooser getFileChooser() { + return GTKFileChooserUI.this.getFileChooser(); } } } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java index 048e76647c4..b821a56abc1 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java @@ -38,6 +38,7 @@ import java.io.File; import java.io.IOException; import java.util.*; import sun.awt.shell.ShellFolder; +import sun.swing.AbstractFilterComboBoxModel; import sun.swing.SwingUtilities2; /** @@ -777,70 +778,9 @@ public class MotifFileChooserUI extends BasicFileChooserUI { /** * Data model for a type-face selection combo-box. */ - protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, - PropertyChangeListener { - protected FileFilter[] filters; - protected FilterComboBoxModel() { - super(); - filters = getFileChooser().getChoosableFileFilters(); - } - - public void propertyChange(PropertyChangeEvent e) { - String prop = e.getPropertyName(); - if(prop.equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY)) { - filters = (FileFilter[]) e.getNewValue(); - fireContentsChanged(this, -1, -1); - } else if (prop.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) { - fireContentsChanged(this, -1, -1); - } - } - - public void setSelectedItem(Object filter) { - if(filter != null) { - getFileChooser().setFileFilter((FileFilter) filter); - fireContentsChanged(this, -1, -1); - } - } - - public Object getSelectedItem() { - // Ensure that the current filter is in the list. - // NOTE: we shouldnt' have to do this, since JFileChooser adds - // the filter to the choosable filters list when the filter - // is set. Lets be paranoid just in case someone overrides - // setFileFilter in JFileChooser. - FileFilter currentFilter = getFileChooser().getFileFilter(); - boolean found = false; - if(currentFilter != null) { - for (FileFilter filter : filters) { - if (filter == currentFilter) { - found = true; - } - } - if (!found) { - getFileChooser().addChoosableFileFilter(currentFilter); - } - } - return getFileChooser().getFileFilter(); - } - - public int getSize() { - if(filters != null) { - return filters.length; - } else { - return 0; - } - } - - public FileFilter getElementAt(int index) { - if(index > getSize() - 1) { - // This shouldn't happen. Try to recover gracefully. - return getFileChooser().getFileFilter(); - } - if(filters != null) { - return filters[index]; - } else { - return null; - } + protected class FilterComboBoxModel extends AbstractFilterComboBoxModel { + protected JFileChooser getFileChooser() { + return MotifFileChooserUI.this.getFileChooser(); } } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java index 2e1168199c9..8d40da00013 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java @@ -1193,70 +1193,9 @@ public class WindowsFileChooserUI extends BasicFileChooserUI { /** * Data model for a type-face selection combo-box. */ - protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, - PropertyChangeListener { - protected FileFilter[] filters; - protected FilterComboBoxModel() { - super(); - filters = getFileChooser().getChoosableFileFilters(); - } - - public void propertyChange(PropertyChangeEvent e) { - String prop = e.getPropertyName(); - if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - filters = (FileFilter[]) e.getNewValue(); - fireContentsChanged(this, -1, -1); - } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) { - fireContentsChanged(this, -1, -1); - } - } - - public void setSelectedItem(Object filter) { - if(filter != null) { - getFileChooser().setFileFilter((FileFilter) filter); - fireContentsChanged(this, -1, -1); - } - } - - public Object getSelectedItem() { - // Ensure that the current filter is in the list. - // NOTE: we shouldnt' have to do this, since JFileChooser adds - // the filter to the choosable filters list when the filter - // is set. Lets be paranoid just in case someone overrides - // setFileFilter in JFileChooser. - FileFilter currentFilter = getFileChooser().getFileFilter(); - boolean found = false; - if(currentFilter != null) { - for (FileFilter filter : filters) { - if (filter == currentFilter) { - found = true; - } - } - if(found == false) { - getFileChooser().addChoosableFileFilter(currentFilter); - } - } - return getFileChooser().getFileFilter(); - } - - public int getSize() { - if(filters != null) { - return filters.length; - } else { - return 0; - } - } - - public FileFilter getElementAt(int index) { - if(index > getSize() - 1) { - // This shouldn't happen. Try to recover gracefully. - return getFileChooser().getFileFilter(); - } - if(filters != null) { - return filters[index]; - } else { - return null; - } + protected class FilterComboBoxModel extends AbstractFilterComboBoxModel { + protected JFileChooser getFileChooser() { + return WindowsFileChooserUI.this.getFileChooser(); } } diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java index 27c519502cf..07a57f00369 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java @@ -1067,69 +1067,9 @@ public class MetalFileChooserUI extends BasicFileChooserUI { /** * Data model for a type-face selection combo-box. */ - protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener { - protected FileFilter[] filters; - protected FilterComboBoxModel() { - super(); - filters = getFileChooser().getChoosableFileFilters(); - } - - public void propertyChange(PropertyChangeEvent e) { - String prop = e.getPropertyName(); - if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - filters = (FileFilter[]) e.getNewValue(); - fireContentsChanged(this, -1, -1); - } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) { - fireContentsChanged(this, -1, -1); - } - } - - public void setSelectedItem(Object filter) { - if(filter != null) { - getFileChooser().setFileFilter((FileFilter) filter); - fireContentsChanged(this, -1, -1); - } - } - - public Object getSelectedItem() { - // Ensure that the current filter is in the list. - // NOTE: we shouldnt' have to do this, since JFileChooser adds - // the filter to the choosable filters list when the filter - // is set. Lets be paranoid just in case someone overrides - // setFileFilter in JFileChooser. - FileFilter currentFilter = getFileChooser().getFileFilter(); - boolean found = false; - if(currentFilter != null) { - for (FileFilter filter : filters) { - if (filter == currentFilter) { - found = true; - } - } - if(found == false) { - getFileChooser().addChoosableFileFilter(currentFilter); - } - } - return getFileChooser().getFileFilter(); - } - - public int getSize() { - if(filters != null) { - return filters.length; - } else { - return 0; - } - } - - public Object getElementAt(int index) { - if(index > getSize() - 1) { - // This shouldn't happen. Try to recover gracefully. - return getFileChooser().getFileFilter(); - } - if(filters != null) { - return filters[index]; - } else { - return null; - } + protected class FilterComboBoxModel extends AbstractFilterComboBoxModel { + protected JFileChooser getFileChooser() { + return MetalFileChooserUI.this.getFileChooser(); } } diff --git a/jdk/src/share/classes/sun/swing/AbstractFilterComboBoxModel.java b/jdk/src/share/classes/sun/swing/AbstractFilterComboBoxModel.java new file mode 100644 index 00000000000..355d3ca89db --- /dev/null +++ b/jdk/src/share/classes/sun/swing/AbstractFilterComboBoxModel.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.swing; + +import javax.swing.AbstractListModel; +import javax.swing.ComboBoxModel; +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileFilter; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * Data model for a type-face selection combo-box. + */ +public abstract class AbstractFilterComboBoxModel + extends AbstractListModel + implements ComboBoxModel, PropertyChangeListener { + + protected FileFilter[] filters; + + protected AbstractFilterComboBoxModel() { + this.filters = getFileChooser().getChoosableFileFilters(); + } + + protected abstract JFileChooser getFileChooser(); + + @Override + public void propertyChange(PropertyChangeEvent event) { + String property = event.getPropertyName(); + if (property == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { + this.filters = (FileFilter[]) event.getNewValue(); + fireContentsChanged(this, -1, -1); + } else if (property == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) { + fireContentsChanged(this, -1, -1); + } + } + + @Override + public void setSelectedItem(Object filter) { + if (filter != null) { + getFileChooser().setFileFilter((FileFilter) filter); + fireContentsChanged(this, -1, -1); + } + } + + @Override + public Object getSelectedItem() { + // Ensure that the current filter is in the list. + // NOTE: we should not have to do this, since JFileChooser adds + // the filter to the choosable filters list when the filter + // is set. Lets be paranoid just in case someone overrides + // setFileFilter in JFileChooser. + FileFilter currentFilter = getFileChooser().getFileFilter(); + if (currentFilter != null) { + for (FileFilter filter : this.filters) { + if (filter == currentFilter) { + return currentFilter; + } + } + getFileChooser().addChoosableFileFilter(currentFilter); + } + return currentFilter; + } + + @Override + public int getSize() { + return (this.filters != null) + ? filters.length + : 0; + } + + @Override + public FileFilter getElementAt(int index) { + if (index >= getSize()) { + // This shouldn't happen. Try to recover gracefully. + return getFileChooser().getFileFilter(); + } + return (this.filters != null) + ? filters[index] + : null; + } +} diff --git a/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java b/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java index d8e023647b2..bd7c9b4371e 100644 --- a/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java +++ b/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java @@ -923,70 +923,9 @@ public class SynthFileChooserUIImpl extends SynthFileChooserUI { /** * Data model for a type-face selection combo-box. */ - protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, - PropertyChangeListener { - protected FileFilter[] filters; - protected FilterComboBoxModel() { - super(); - filters = getFileChooser().getChoosableFileFilters(); - } - - public void propertyChange(PropertyChangeEvent e) { - String prop = e.getPropertyName(); - if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - filters = (FileFilter[]) e.getNewValue(); - fireContentsChanged(this, -1, -1); - } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) { - fireContentsChanged(this, -1, -1); - } - } - - public void setSelectedItem(Object filter) { - if(filter != null) { - getFileChooser().setFileFilter((FileFilter) filter); - fireContentsChanged(this, -1, -1); - } - } - - public Object getSelectedItem() { - // Ensure that the current filter is in the list. - // NOTE: we shouldnt' have to do this, since JFileChooser adds - // the filter to the choosable filters list when the filter - // is set. Lets be paranoid just in case someone overrides - // setFileFilter in JFileChooser. - FileFilter currentFilter = getFileChooser().getFileFilter(); - boolean found = false; - if(currentFilter != null) { - for (FileFilter filter : filters) { - if (filter == currentFilter) { - found = true; - } - } - if(found == false) { - getFileChooser().addChoosableFileFilter(currentFilter); - } - } - return getFileChooser().getFileFilter(); - } - - public int getSize() { - if(filters != null) { - return filters.length; - } else { - return 0; - } - } - - public FileFilter getElementAt(int index) { - if(index > getSize() - 1) { - // This shouldn't happen. Try to recover gracefully. - return getFileChooser().getFileFilter(); - } - if(filters != null) { - return filters[index]; - } else { - return null; - } + protected class FilterComboBoxModel extends AbstractFilterComboBoxModel { + protected JFileChooser getFileChooser() { + return SynthFileChooserUIImpl.this.getFileChooser(); } } From c678f0173a0e5ff6036369446aba82f96fdb0b3a Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Wed, 28 Aug 2013 11:22:43 +0200 Subject: [PATCH 0114/1294] 8023597: Optimize G1 barriers code for unsafe load_store Avoid loading old values in G1 pre-barriers for inlined unsafe load_store nodes. Reviewed-by: kvn, tonyp --- hotspot/src/share/vm/opto/graphKit.cpp | 21 ++++++++++ hotspot/src/share/vm/opto/graphKit.hpp | 4 ++ hotspot/src/share/vm/opto/library_call.cpp | 49 +++++++++++++++++----- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 2f435db6516..18772dfd0a8 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -1501,6 +1501,25 @@ void GraphKit::pre_barrier(bool do_load, } } +bool GraphKit::can_move_pre_barrier() const { + BarrierSet* bs = Universe::heap()->barrier_set(); + switch (bs->kind()) { + case BarrierSet::G1SATBCT: + case BarrierSet::G1SATBCTLogging: + return true; // Can move it if no safepoint + + case BarrierSet::CardTableModRef: + case BarrierSet::CardTableExtension: + case BarrierSet::ModRef: + return true; // There is no pre-barrier + + case BarrierSet::Other: + default : + ShouldNotReachHere(); + } + return false; +} + void GraphKit::post_barrier(Node* ctl, Node* store, Node* obj, @@ -3551,6 +3570,8 @@ void GraphKit::g1_write_barrier_pre(bool do_load, } else { // In this case both val_type and alias_idx are unused. assert(pre_val != NULL, "must be loaded already"); + // Nothing to be done if pre_val is null. + if (pre_val->bottom_type() == TypePtr::NULL_PTR) return; assert(pre_val->bottom_type()->basic_type() == T_OBJECT, "or we shouldn't be here"); } assert(bt == T_OBJECT, "or we shouldn't be here"); diff --git a/hotspot/src/share/vm/opto/graphKit.hpp b/hotspot/src/share/vm/opto/graphKit.hpp index 4d7d96178ae..e9d102cb6c5 100644 --- a/hotspot/src/share/vm/opto/graphKit.hpp +++ b/hotspot/src/share/vm/opto/graphKit.hpp @@ -695,6 +695,10 @@ class GraphKit : public Phase { void write_barrier_post(Node *store, Node* obj, Node* adr, uint adr_idx, Node* val, bool use_precise); + // Allow reordering of pre-barrier with oop store and/or post-barrier. + // Used for load_store operations which loads old value. + bool can_move_pre_barrier() const; + // G1 pre/post barriers void g1_write_barrier_pre(bool do_load, Node* obj, diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 22deebb5a83..60525d73ef7 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -2756,10 +2756,28 @@ bool LibraryCallKit::inline_unsafe_load_store(BasicType type, LoadStoreKind kind newval = _gvn.makecon(TypePtr::NULL_PTR); // Reference stores need a store barrier. - pre_barrier(true /* do_load*/, - control(), base, adr, alias_idx, newval, value_type->make_oopptr(), - NULL /* pre_val*/, - T_OBJECT); + if (kind == LS_xchg) { + // If pre-barrier must execute before the oop store, old value will require do_load here. + if (!can_move_pre_barrier()) { + pre_barrier(true /* do_load*/, + control(), base, adr, alias_idx, newval, value_type->make_oopptr(), + NULL /* pre_val*/, + T_OBJECT); + } // Else move pre_barrier to use load_store value, see below. + } else if (kind == LS_cmpxchg) { + // Same as for newval above: + if (_gvn.type(oldval) == TypePtr::NULL_PTR) { + oldval = _gvn.makecon(TypePtr::NULL_PTR); + } + // The only known value which might get overwritten is oldval. + pre_barrier(false /* do_load */, + control(), NULL, NULL, max_juint, NULL, NULL, + oldval /* pre_val */, + T_OBJECT); + } else { + ShouldNotReachHere(); + } + #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { Node *newval_enc = _gvn.transform(new (C) EncodePNode(newval, newval->bottom_type()->make_narrowoop())); @@ -2795,16 +2813,27 @@ bool LibraryCallKit::inline_unsafe_load_store(BasicType type, LoadStoreKind kind Node* proj = _gvn.transform(new (C) SCMemProjNode(load_store)); set_memory(proj, alias_idx); + if (type == T_OBJECT && kind == LS_xchg) { +#ifdef _LP64 + if (adr->bottom_type()->is_ptr_to_narrowoop()) { + load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type())); + } +#endif + if (can_move_pre_barrier()) { + // Don't need to load pre_val. The old value is returned by load_store. + // The pre_barrier can execute after the xchg as long as no safepoint + // gets inserted between them. + pre_barrier(false /* do_load */, + control(), NULL, NULL, max_juint, NULL, NULL, + load_store /* pre_val */, + T_OBJECT); + } + } + // Add the trailing membar surrounding the access insert_mem_bar(Op_MemBarCPUOrder); insert_mem_bar(Op_MemBarAcquire); -#ifdef _LP64 - if (type == T_OBJECT && adr->bottom_type()->is_ptr_to_narrowoop() && kind == LS_xchg) { - load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type())); - } -#endif - assert(type2size[load_store->bottom_type()->basic_type()] == type2size[rtype], "result type should match"); set_result(load_store); return true; From c0f4055c780a9715d8b76619fdd59cc71409f923 Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Wed, 28 Aug 2013 08:15:01 -0400 Subject: [PATCH 0115/1294] 8020489: VM crash when non-existent interface called by invokespecial Reviewed-by: kamg, coleenp --- .../src/share/vm/classfile/defaultMethods.cpp | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index 5f02750dc72..b59fe66e062 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -870,7 +870,6 @@ class ErasedShadowChecker : public ShadowChecker { : ShadowChecker(thread, name, holder, target) {} }; - // Find the unique qualified candidate from the perspective of the super_class // which is the resolved_klass, which must be an immediate superinterface // of klass @@ -884,43 +883,48 @@ Method* find_erased_super_default(InstanceKlass* current_class, InstanceKlass* s if (family != NULL) { family->determine_target(current_class, CHECK_NULL); // get target from current_class - } - if (family->has_target()) { - Method* target = family->get_selected_target(); - InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); + if (family->has_target()) { + Method* target = family->get_selected_target(); + InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); - // Verify that the identified method is valid from the context of - // the current class, which is the caller class for invokespecial - // link resolution, i.e. ensure there it is not shadowed. - // You can use invokespecial to disambiguate interface methods, but - // you can not use it to skip over an interface method that would shadow it. - ErasedShadowChecker checker(THREAD, target->name(), holder, super_class); - checker.run(current_class); + // Verify that the identified method is valid from the context of + // the current class, which is the caller class for invokespecial + // link resolution, i.e. ensure there it is not shadowed. + // You can use invokespecial to disambiguate interface methods, but + // you can not use it to skip over an interface method that would shadow it. + ErasedShadowChecker checker(THREAD, target->name(), holder, super_class); + checker.run(current_class); - if (checker.found_shadow()) { + if (checker.found_shadow()) { #ifndef PRODUCT - if (TraceDefaultMethods) { - tty->print_cr(" Only candidate found was shadowed."); - } + if (TraceDefaultMethods) { + tty->print_cr(" Only candidate found was shadowed."); + } #endif // ndef PRODUCT - THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), - "Accessible default method not found", NULL); + THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), + "Accessible default method not found", NULL); + } else { +#ifndef PRODUCT + if (TraceDefaultMethods) { + family->print_sig_on(tty, target->signature(), 1); + } +#endif // ndef PRODUCT + return target; + } } else { -#ifndef PRODUCT - if (TraceDefaultMethods) { - family->print_sig_on(tty, target->signature(), 1); - } -#endif // ndef PRODUCT - return target; - } + assert(family->throws_exception(), "must have target or throw"); + THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), + family->get_exception_message()->as_C_string(), NULL); + } } else { - assert(family->throws_exception(), "must have target or throw"); - THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), - family->get_exception_message()->as_C_string(), NULL); + // no method found + ResourceMark rm(THREAD); + THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), + Method::name_and_sig_as_C_string(current_class, + method_name, sig), NULL); } } - // This is called during linktime when we find an invokespecial call that // refers to a direct superinterface. It indicates that we should find the // default method in the hierarchy of that superinterface, and if that method From 25d12a300b5b498cfb9f7b388ac668caa1634dfa Mon Sep 17 00:00:00 2001 From: Pete Brunet Date: Wed, 28 Aug 2013 17:25:35 +0400 Subject: [PATCH 0116/1294] 8011955: Lunar screen reader crashes intermittently in WindowsAccessBridge-32.DLL 6995891: JAWS will occasionally stop speaking focused objects as user TABs -> problem with message queue 8014738: Combobox menu items are not announced with JAWS 8011938: Java Ferret example corrupts JCombobox of the running application 8012011: JAB 2.0.2 incompletely shows kbd accelerator in menus 8022966: Java Access Bridge no longer usable with screen magnifiers Reviewed-by: raginip, tbell, erikj, art --- jdk/make/bridge/AccessBridgeJava/Makefile | 6 ++--- jdk/makefiles/CompileJavaClasses.gmk | 1 + jdk/makefiles/GensrcMisc.gmk | 28 ++++++++++++++++------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/jdk/make/bridge/AccessBridgeJava/Makefile b/jdk/make/bridge/AccessBridgeJava/Makefile index c5bebd02cea..e143f987e0a 100644 --- a/jdk/make/bridge/AccessBridgeJava/Makefile +++ b/jdk/make/bridge/AccessBridgeJava/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ endif # # Java files to compile. # -FILES_java = com/sun/java/accessibility/AccessBridge.java +FILES_java = com/sun/java/accessibility/AccessBridgeLoader.java com/sun/java/accessibility/AccessBridge.java # # Location for the newly built classfiles. @@ -68,7 +68,7 @@ FILES_class = $(FILES_java:%.java=$(CLASSDESTDIR)/%.class) build: prebuild prebuild: - $(CP) $(CLOSED_PLATFORM_SRC)/classes/com/sun/java/accessibility/$(ABPLATFORM)/AccessBridge.java \ + $(CP) $(CLOSED_PLATFORM_SRC)/classes/com/sun/java/accessibility/$(ABPLATFORM)/AccessBridgeLoader.java \ $(CLOSED_PLATFORM_SRC)/classes/com/sun/java/accessibility all : build $(JARFILE) diff --git a/jdk/makefiles/CompileJavaClasses.gmk b/jdk/makefiles/CompileJavaClasses.gmk index 0b3e70dd914..a015846e39f 100644 --- a/jdk/makefiles/CompileJavaClasses.gmk +++ b/jdk/makefiles/CompileJavaClasses.gmk @@ -62,6 +62,7 @@ ifndef OPENJDK # AccessBridge is compiled separately below. EXFILES += AccessBridge.java \ + AccessBridgeLoader.java \ com/sun/java/accessibility/util/java/awt/ChoiceTranslator.java # This seems to never be built EXCLUDES += com/sun/java/accessibility/extensions diff --git a/jdk/makefiles/GensrcMisc.gmk b/jdk/makefiles/GensrcMisc.gmk index 812b2cee6c7..c879de348cb 100644 --- a/jdk/makefiles/GensrcMisc.gmk +++ b/jdk/makefiles/GensrcMisc.gmk @@ -200,26 +200,38 @@ ifeq ($(OPENJDK_TARGET_OS), windows) AB_SRC_DIR := $(JDK_TOPDIR)/src/closed/windows/classes/com/sun/java/accessibility ifeq ($(OPENJDK_TARGET_CPU_BITS), 32) + $(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridgeLoader.java: \ + $(AB_SRC_DIR)/32bit/AccessBridgeLoader.java + $(install-file) + $(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridge.java: \ - $(AB_SRC_DIR)/32bit/AccessBridge.java + $(AB_SRC_DIR)/AccessBridge.java + $(install-file) + + $(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridgeLoader.java: \ + $(AB_SRC_DIR)/legacy/AccessBridgeLoader.java $(install-file) $(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridge.java: \ - $(AB_SRC_DIR)/legacy/AccessBridge.java + $(AB_SRC_DIR)/AccessBridge.java $(install-file) - GENSRC_MISC += $(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridge.java \ - $(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridge.java + GENSRC_MISC += $(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridgeLoader.java \ + $(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridgeLoader.java \ + $(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridge.java \ + $(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridge.java else - $(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridge.java: \ - $(AB_SRC_DIR)/64bit/AccessBridge.java + $(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridgeLoader.java: \ + $(AB_SRC_DIR)/64bit/AccessBridgeLoader.java $(install-file) - GENSRC_MISC += $(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridge.java + GENSRC_MISC += $(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridgeLoader.java \ + $(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridge.java endif + endif endif -########################################################################################## \ No newline at end of file +########################################################################################## From 0628977a7ad4ef0144b3d1fe548b9b0b357fa87f Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 28 Aug 2013 17:32:25 +0400 Subject: [PATCH 0117/1294] 6968363: ClassCastException while entering HINDI characters with CustomDocument Reviewed-by: alexsch --- .../javax/swing/text/AbstractDocument.java | 22 +- .../javax/swing/text/DefaultCaret.java | 9 +- .../javax/swing/text/GlyphPainter2.java | 8 +- .../javax/swing/text/ParagraphView.java | 13 +- .../AbstractDocument/6968363/Test6968363.java | 241 ++++++++++++++++++ 5 files changed, 262 insertions(+), 31 deletions(-) create mode 100644 jdk/test/javax/swing/text/AbstractDocument/6968363/Test6968363.java diff --git a/jdk/src/share/classes/javax/swing/text/AbstractDocument.java b/jdk/src/share/classes/javax/swing/text/AbstractDocument.java index bf40cad6859..d9eefe375c5 100644 --- a/jdk/src/share/classes/javax/swing/text/AbstractDocument.java +++ b/jdk/src/share/classes/javax/swing/text/AbstractDocument.java @@ -934,16 +934,18 @@ public abstract class AbstractDocument implements Document, Serializable { * Returns true if the text in the range p0 to * p1 is left to right. */ - boolean isLeftToRight(int p0, int p1) { - if(!getProperty(I18NProperty).equals(Boolean.TRUE)) { - return true; - } - Element bidiRoot = getBidiRootElement(); - int index = bidiRoot.getElementIndex(p0); - Element bidiElem = bidiRoot.getElement(index); - if(bidiElem.getEndOffset() >= p1) { - AttributeSet bidiAttrs = bidiElem.getAttributes(); - return ((StyleConstants.getBidiLevel(bidiAttrs) % 2) == 0); + static boolean isLeftToRight(Document doc, int p0, int p1) { + if (Boolean.TRUE.equals(doc.getProperty(I18NProperty))) { + if (doc instanceof AbstractDocument) { + AbstractDocument adoc = (AbstractDocument) doc; + Element bidiRoot = adoc.getBidiRootElement(); + int index = bidiRoot.getElementIndex(p0); + Element bidiElem = bidiRoot.getElement(index); + if (bidiElem.getEndOffset() >= p1) { + AttributeSet bidiAttrs = bidiElem.getAttributes(); + return ((StyleConstants.getBidiLevel(bidiAttrs) % 2) == 0); + } + } } return true; } diff --git a/jdk/src/share/classes/javax/swing/text/DefaultCaret.java b/jdk/src/share/classes/javax/swing/text/DefaultCaret.java index 40a4af016ec..7a1a3ab4c53 100644 --- a/jdk/src/share/classes/javax/swing/text/DefaultCaret.java +++ b/jdk/src/share/classes/javax/swing/text/DefaultCaret.java @@ -1211,12 +1211,9 @@ public class DefaultCaret extends Rectangle implements Caret, FocusListener, Mou boolean isPositionLTR(int position, Position.Bias bias) { Document doc = component.getDocument(); - if(doc instanceof AbstractDocument ) { - if(bias == Position.Bias.Backward && --position < 0) - position = 0; - return ((AbstractDocument)doc).isLeftToRight(position, position); - } - return true; + if(bias == Position.Bias.Backward && --position < 0) + position = 0; + return AbstractDocument.isLeftToRight(doc, position, position); } Position.Bias guessBiasForOffset(int offset, Position.Bias lastBias, diff --git a/jdk/src/share/classes/javax/swing/text/GlyphPainter2.java b/jdk/src/share/classes/javax/swing/text/GlyphPainter2.java index 8b27ec93e4d..dca62085a5b 100644 --- a/jdk/src/share/classes/javax/swing/text/GlyphPainter2.java +++ b/jdk/src/share/classes/javax/swing/text/GlyphPainter2.java @@ -239,10 +239,10 @@ class GlyphPainter2 extends GlyphView.GlyphPainter { Position.Bias[] biasRet) throws BadLocationException { + Document doc = v.getDocument(); int startOffset = v.getStartOffset(); int endOffset = v.getEndOffset(); Segment text; - AbstractDocument doc; boolean viewIsLeftToRight; TextHitInfo currentHit, nextHit; @@ -252,8 +252,7 @@ class GlyphPainter2 extends GlyphView.GlyphPainter { case View.SOUTH: break; case View.EAST: - doc = (AbstractDocument)v.getDocument(); - viewIsLeftToRight = doc.isLeftToRight(startOffset, endOffset); + viewIsLeftToRight = AbstractDocument.isLeftToRight(doc, startOffset, endOffset); if(startOffset == doc.getLength()) { if(pos == -1) { @@ -313,8 +312,7 @@ class GlyphPainter2 extends GlyphView.GlyphPainter { } return pos; case View.WEST: - doc = (AbstractDocument)v.getDocument(); - viewIsLeftToRight = doc.isLeftToRight(startOffset, endOffset); + viewIsLeftToRight = AbstractDocument.isLeftToRight(doc, startOffset, endOffset); if(startOffset == doc.getLength()) { if(pos == -1) { diff --git a/jdk/src/share/classes/javax/swing/text/ParagraphView.java b/jdk/src/share/classes/javax/swing/text/ParagraphView.java index b88dd8731bb..396e153e520 100644 --- a/jdk/src/share/classes/javax/swing/text/ParagraphView.java +++ b/jdk/src/share/classes/javax/swing/text/ParagraphView.java @@ -267,8 +267,6 @@ public class ParagraphView extends FlowView implements TabExpander { throws BadLocationException { JTextComponent text = (JTextComponent)getContainer(); Document doc = getDocument(); - AbstractDocument aDoc = (doc instanceof AbstractDocument) ? - (AbstractDocument)doc : null; View row = getView(rowIndex); int lastPos = -1; // This could be made better to check backward positions too. @@ -276,8 +274,7 @@ public class ParagraphView extends FlowView implements TabExpander { for(int vc = 0, numViews = row.getViewCount(); vc < numViews; vc++) { View v = row.getView(vc); int start = v.getStartOffset(); - boolean ltr = (aDoc != null) ? aDoc.isLeftToRight - (start, start + 1) : true; + boolean ltr = AbstractDocument.isLeftToRight(doc, start, start + 1); if(ltr) { lastPos = start; for(int end = v.getEndOffset(); lastPos < end; lastPos++) { @@ -338,12 +335,8 @@ public class ParagraphView extends FlowView implements TabExpander { protected boolean flipEastAndWestAtEnds(int position, Position.Bias bias) { Document doc = getDocument(); - if(doc instanceof AbstractDocument && - !((AbstractDocument)doc).isLeftToRight(getStartOffset(), - getStartOffset() + 1)) { - return true; - } - return false; + position = getStartOffset(); + return !AbstractDocument.isLeftToRight(doc, position, position + 1); } // --- FlowView methods --------------------------------------------- diff --git a/jdk/test/javax/swing/text/AbstractDocument/6968363/Test6968363.java b/jdk/test/javax/swing/text/AbstractDocument/6968363/Test6968363.java new file mode 100644 index 00000000000..624a2522356 --- /dev/null +++ b/jdk/test/javax/swing/text/AbstractDocument/6968363/Test6968363.java @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import sun.awt.SunToolkit; + +import java.awt.Robot; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JTextField; +import javax.swing.event.DocumentListener; +import javax.swing.event.UndoableEditListener; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.Element; +import javax.swing.text.PlainDocument; +import javax.swing.text.Position; +import javax.swing.text.Segment; + +import static java.awt.BorderLayout.NORTH; +import static java.awt.BorderLayout.SOUTH; +import static java.awt.Toolkit.getDefaultToolkit; +import static java.awt.event.KeyEvent.VK_LEFT; +import static javax.swing.SwingUtilities.invokeAndWait; + +/* + * @test + * @bug 6968363 + * @summary Ensures that a custom document may not extend AbstractDocument + * @author Sergey Malenkov + */ +public class Test6968363 implements Runnable, Thread.UncaughtExceptionHandler { + private JFrame frame; + + public static void main(String[] args) throws Exception { + SunToolkit toolkit = (SunToolkit) getDefaultToolkit(); + Runnable task = new Test6968363(); + invokeAndWait(task); + toolkit.realSync(100); + new Robot().keyPress(VK_LEFT); + toolkit.realSync(100); + invokeAndWait(task); + } + + @Override + public void uncaughtException(Thread thread, Throwable throwable) { + throwable.printStackTrace(); + System.exit(1); + } + + @Override + public void run() { + if (this.frame == null) { + Thread.setDefaultUncaughtExceptionHandler(this); + this.frame = new JFrame(getClass().getSimpleName()); + this.frame.add(NORTH, new JLabel("Copy Paste a HINDI text into the field below")); + this.frame.add(SOUTH, new JTextField(new MyDocument(), "\u0938", 10)); + this.frame.pack(); + this.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + this.frame.setLocationRelativeTo(null); + this.frame.setVisible(true); + } else { + this.frame.dispose(); + this.frame = null; + } + } + + private static class MyDocument implements Document { + private final Document document = new PlainDocument(); + + @Override + public int getLength() { + return this.document.getLength(); + } + + @Override + public void addDocumentListener(DocumentListener listener) { + this.document.addDocumentListener(listener); + } + + @Override + public void removeDocumentListener(DocumentListener listener) { + this.document.removeDocumentListener(listener); + } + + @Override + public void addUndoableEditListener(UndoableEditListener listener) { + this.document.addUndoableEditListener(listener); + } + + @Override + public void removeUndoableEditListener(UndoableEditListener listener) { + this.document.removeUndoableEditListener(listener); + } + + @Override + public Object getProperty(Object key) { + return this.document.getProperty(key); + } + + @Override + public void putProperty(Object key, Object value) { + this.document.putProperty(key, value); + } + + @Override + public void remove(int offset, int length) throws BadLocationException { + this.document.remove(offset, length); + } + + @Override + public void insertString(int offset, String string, AttributeSet set) throws BadLocationException { + for (int i = 0; i < string.length(); i++) { + System.out.println("i: " + i + "; ch: " + Integer.toHexString(string.charAt(i))); + } + this.document.insertString(offset, string, set); + } + + @Override + public String getText(int offset, int length) throws BadLocationException { + return this.document.getText(offset, length); + } + + @Override + public void getText(int offset, int length, Segment segment) throws BadLocationException { + this.document.getText(offset, length, segment); + } + + @Override + public Position getStartPosition() { + return this.document.getStartPosition(); + } + + @Override + public Position getEndPosition() { + return this.document.getEndPosition(); + } + + @Override + public Position createPosition(int offset) throws BadLocationException { + return this.document.createPosition(offset); + } + + @Override + public Element[] getRootElements() { + Element[] elements = this.document.getRootElements(); + Element[] wrappers = new Element[elements.length]; + for (int i = 0; i < elements.length; i++) { + wrappers[i] = new MyElement(elements[i]); + } + return wrappers; + } + + @Override + public Element getDefaultRootElement() { + return new MyElement(this.document.getDefaultRootElement()); + } + + @Override + public void render(Runnable task) { + this.document.render(task); + } + + private class MyElement implements Element { + private final Element element; + + private MyElement(Element element) { + this.element = element; + } + + @Override + public Document getDocument() { + return MyDocument.this; + } + + @Override + public Element getParentElement() { + return new MyElement(this.element.getParentElement()); + } + + @Override + public String getName() { + return this.element.getName(); + } + + @Override + public AttributeSet getAttributes() { + return this.element.getAttributes(); + } + + @Override + public int getStartOffset() { + return this.element.getStartOffset(); + } + + @Override + public int getEndOffset() { + return this.element.getEndOffset(); + } + + @Override + public int getElementIndex(int offset) { + return this.element.getElementIndex(offset); + } + + @Override + public int getElementCount() { + return this.element.getElementCount(); + } + + @Override + public Element getElement(int index) { + return new MyElement(this.element.getElement(index)); + } + + @Override + public boolean isLeaf() { + return this.element.isLeaf(); + } + } + } +} From 026aac8993a3a6ceb087ae24d177a0b8bfa70949 Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Thu, 29 Aug 2013 11:05:55 +0200 Subject: [PATCH 0118/1294] 8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X Reviewed-by: dholmes, rbackman --- hotspot/src/os/posix/vm/os_posix.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/hotspot/src/os/posix/vm/os_posix.cpp b/hotspot/src/os/posix/vm/os_posix.cpp index bf6a1fafacd..01ba41b077f 100644 --- a/hotspot/src/os/posix/vm/os_posix.cpp +++ b/hotspot/src/os/posix/vm/os_posix.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,8 @@ #include #include #include +#include +#include // Check core dump limit and report possible place where core can be found @@ -271,11 +273,17 @@ os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { * The callback is supposed to provide the method that should be protected. */ bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { + sigset_t saved_sig_mask; + assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); assert(!WatcherThread::watcher_thread()->has_crash_protection(), "crash_protection already set?"); - if (sigsetjmp(_jmpbuf, 1) == 0) { + // we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask + // since on at least some systems (OS X) siglongjmp will restore the mask + // for the process, not the thread + pthread_sigmask(0, NULL, &saved_sig_mask); + if (sigsetjmp(_jmpbuf, 0) == 0) { // make sure we can see in the signal handler that we have crash protection // installed WatcherThread::watcher_thread()->set_crash_protection(this); @@ -285,6 +293,7 @@ bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { return true; } // this happens when we siglongjmp() back + pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL); WatcherThread::watcher_thread()->set_crash_protection(NULL); return false; } From 81cd0a873837c1a1c5899ed5727347cdf05d6b7d Mon Sep 17 00:00:00 2001 From: Shanliang Jiang Date: Wed, 18 Sep 2013 08:51:23 +0200 Subject: [PATCH 0119/1294] 8023954: MBean*Info.equals: throw NPE Reviewed-by: dfuchs, dholmes --- .../javax/management/MBeanAttributeInfo.java | 8 +- .../management/MBeanConstructorInfo.java | 6 +- .../javax/management/MBeanFeatureInfo.java | 7 +- .../management/MBeanNotificationInfo.java | 7 +- .../javax/management/MBeanOperationInfo.java | 8 +- .../javax/management/MBeanParameterInfo.java | 9 +- .../MBeanInfo/MBeanInfoEqualsNPETest.java | 216 ++++++++++++++++++ 7 files changed, 240 insertions(+), 21 deletions(-) create mode 100644 jdk/test/javax/management/MBeanInfo/MBeanInfoEqualsNPETest.java diff --git a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java index a70fb3a3571..7a3adaa5ad8 100644 --- a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java @@ -286,10 +286,10 @@ public class MBeanAttributeInfo extends MBeanFeatureInfo implements Cloneable { if (!(o instanceof MBeanAttributeInfo)) return false; MBeanAttributeInfo p = (MBeanAttributeInfo) o; - return (p.getName().equals(getName()) && - p.getType().equals(getType()) && - p.getDescription().equals(getDescription()) && - p.getDescriptor().equals(getDescriptor()) && + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getType(), getType()) && + Objects.equals(p.getDescription(), getDescription()) && + Objects.equals(p.getDescriptor(), getDescriptor()) && p.isReadable() == isReadable() && p.isWritable() == isWritable() && p.isIs() == isIs()); diff --git a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java index ad2176367d2..d02ffce3a8d 100644 --- a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java @@ -191,10 +191,10 @@ public class MBeanConstructorInfo extends MBeanFeatureInfo implements Cloneable if (!(o instanceof MBeanConstructorInfo)) return false; MBeanConstructorInfo p = (MBeanConstructorInfo) o; - return (p.getName().equals(getName()) && - p.getDescription().equals(getDescription()) && + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getDescription(), getDescription()) && Arrays.equals(p.fastGetSignature(), fastGetSignature()) && - p.getDescriptor().equals(getDescriptor())); + Objects.equals(p.getDescriptor(), getDescriptor())); } /* Unlike attributes and operations, it's quite likely we'll have diff --git a/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java b/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java index a2349a8c69f..ec8e8b622b8 100644 --- a/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java @@ -30,6 +30,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.io.StreamCorruptedException; +import java.util.Objects; /** *

    Provides general information for an MBean descriptor object. @@ -147,9 +148,9 @@ public class MBeanFeatureInfo implements Serializable, DescriptorRead { if (!(o instanceof MBeanFeatureInfo)) return false; MBeanFeatureInfo p = (MBeanFeatureInfo) o; - return (p.getName().equals(getName()) && - p.getDescription().equals(getDescription()) && - p.getDescriptor().equals(getDescriptor())); + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getDescription(), getDescription()) && + Objects.equals(p.getDescriptor(), getDescriptor())); } public int hashCode() { diff --git a/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java b/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java index b4bbbe80292..ad1c74f83d5 100644 --- a/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java @@ -26,6 +26,7 @@ package javax.management; import java.util.Arrays; +import java.util.Objects; /** *

    The MBeanNotificationInfo class is used to describe the @@ -191,9 +192,9 @@ public class MBeanNotificationInfo extends MBeanFeatureInfo implements Cloneable if (!(o instanceof MBeanNotificationInfo)) return false; MBeanNotificationInfo p = (MBeanNotificationInfo) o; - return (p.getName().equals(getName()) && - p.getDescription().equals(getDescription()) && - p.getDescriptor().equals(getDescriptor()) && + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getDescription(), getDescription()) && + Objects.equals(p.getDescriptor(), getDescriptor()) && Arrays.equals(p.fastGetNotifTypes(), fastGetNotifTypes())); } diff --git a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java index 8effa04f8d8..1be6d8f563a 100644 --- a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java @@ -294,12 +294,12 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable { if (!(o instanceof MBeanOperationInfo)) return false; MBeanOperationInfo p = (MBeanOperationInfo) o; - return (p.getName().equals(getName()) && - p.getReturnType().equals(getReturnType()) && - p.getDescription().equals(getDescription()) && + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getReturnType(), getReturnType()) && + Objects.equals(p.getDescription(), getDescription()) && p.getImpact() == getImpact() && Arrays.equals(p.fastGetSignature(), fastGetSignature()) && - p.getDescriptor().equals(getDescriptor())); + Objects.equals(p.getDescriptor(), getDescriptor())); } /* We do not include everything in the hashcode. We assume that diff --git a/jdk/src/share/classes/javax/management/MBeanParameterInfo.java b/jdk/src/share/classes/javax/management/MBeanParameterInfo.java index df3d59087df..81f2eff840d 100644 --- a/jdk/src/share/classes/javax/management/MBeanParameterInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanParameterInfo.java @@ -27,6 +27,7 @@ package javax.management; import java.util.Objects; + /** * Describes an argument of an operation exposed by an MBean. * Instances of this class are immutable. Subclasses may be mutable @@ -137,10 +138,10 @@ public class MBeanParameterInfo extends MBeanFeatureInfo implements Cloneable { if (!(o instanceof MBeanParameterInfo)) return false; MBeanParameterInfo p = (MBeanParameterInfo) o; - return (p.getName().equals(getName()) && - p.getType().equals(getType()) && - p.getDescription().equals(getDescription()) && - p.getDescriptor().equals(getDescriptor())); + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getType(), getType()) && + Objects.equals(p.getDescription(), getDescription()) && + Objects.equals(p.getDescriptor(), getDescriptor())); } public int hashCode() { diff --git a/jdk/test/javax/management/MBeanInfo/MBeanInfoEqualsNPETest.java b/jdk/test/javax/management/MBeanInfo/MBeanInfoEqualsNPETest.java new file mode 100644 index 00000000000..440878c37f3 --- /dev/null +++ b/jdk/test/javax/management/MBeanInfo/MBeanInfoEqualsNPETest.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanFeatureInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; +import javax.management.modelmbean.DescriptorSupport; +import javax.management.openmbean.SimpleType; + +/* + * @test + * @bug 8023954 + * @summary Test that MBean*Info.equals do not throw NPE + * @author Shanliang JIANG + * @run clean MBeanInfoEqualsNPETest + * @run build MBeanInfoEqualsNPETest + * @run main MBeanInfoEqualsNPETest + */ +public class MBeanInfoEqualsNPETest { + private static int failed = 0; + + public static void main(String[] args) throws Exception { + System.out.println("---MBeanInfoEqualsNPETest-main ..."); + + // ---- + System.out.println("\n---Testing on MBeanAttributeInfo..."); + MBeanAttributeInfo mbeanAttributeInfo0 = new MBeanAttributeInfo( + "name", SimpleType.INTEGER.getClassName(), "description", true, true, false); + MBeanAttributeInfo mbeanAttributeInfo = new MBeanAttributeInfo( + null, SimpleType.INTEGER.getClassName(), "description", true, true, false); + test(mbeanAttributeInfo0, mbeanAttributeInfo, "class name"); + + mbeanAttributeInfo = new MBeanAttributeInfo( + "name", null, "description", true, true, false); + test(mbeanAttributeInfo0, mbeanAttributeInfo, "type"); + + mbeanAttributeInfo = new MBeanAttributeInfo( + "name", SimpleType.INTEGER.getClassName(), null, true, true, false); + test(mbeanAttributeInfo0, mbeanAttributeInfo, "description"); + + // ---- + System.out.println("\n---Testing on MBeanConstructorInfo..."); + MBeanConstructorInfo mbeanConstructorInfo0 = new MBeanConstructorInfo( + "", "", new MBeanParameterInfo[]{}, new DescriptorSupport()); + MBeanConstructorInfo mbeanConstructorInfo = new MBeanConstructorInfo( + null, "", new MBeanParameterInfo[]{}, new DescriptorSupport()); + test(mbeanConstructorInfo0, mbeanConstructorInfo, "name"); + + mbeanConstructorInfo = new MBeanConstructorInfo( + "", null, new MBeanParameterInfo[]{}, new DescriptorSupport()); + test(mbeanConstructorInfo0, mbeanConstructorInfo, "description"); + + mbeanConstructorInfo = new MBeanConstructorInfo( + "", "", null, new DescriptorSupport()); + test(mbeanConstructorInfo0, mbeanConstructorInfo, "MBeanParameterInfo"); + + mbeanConstructorInfo = new MBeanConstructorInfo( + "", "", new MBeanParameterInfo[]{}, null); + test(mbeanConstructorInfo0, mbeanConstructorInfo, "descriptor"); + + // ---- + System.out.println("\n---Testing on MBeanOperationInfo..."); + MBeanOperationInfo mbeanOperationInfo0 = new MBeanOperationInfo( + "name", "description", new MBeanParameterInfo[]{}, "type", + MBeanOperationInfo.UNKNOWN, new DescriptorSupport()); + + MBeanOperationInfo mbeanOperationInfo = new MBeanOperationInfo( + null, "description", new MBeanParameterInfo[]{}, "type", + MBeanOperationInfo.UNKNOWN, new DescriptorSupport()); + test(mbeanOperationInfo0, mbeanOperationInfo, "name"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", null, new MBeanParameterInfo[]{}, "type", + MBeanOperationInfo.UNKNOWN, new DescriptorSupport()); + test(mbeanOperationInfo0, mbeanOperationInfo, "description"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", "description", null, "type", 1, new DescriptorSupport()); + test(mbeanOperationInfo0, mbeanOperationInfo, "MBeanParameterInfo"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", "description", new MBeanParameterInfo[]{}, null, + MBeanOperationInfo.UNKNOWN, new DescriptorSupport()); + test(mbeanOperationInfo0, mbeanOperationInfo, "type"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", "description", new MBeanParameterInfo[]{}, null, + MBeanOperationInfo.UNKNOWN, null); + test(mbeanOperationInfo0, mbeanOperationInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on MBeanParameterInfo..."); + MBeanParameterInfo mbeanParameterInfo0 = new MBeanParameterInfo( + "name", "type", "description", new DescriptorSupport()); + MBeanParameterInfo mbeanParameterInfo = new MBeanParameterInfo( + null, "type", "description", new DescriptorSupport()); + test(mbeanParameterInfo0, mbeanParameterInfo, "name"); + + mbeanParameterInfo = new MBeanParameterInfo( + "name", null, "description", new DescriptorSupport()); + test(mbeanParameterInfo0, mbeanParameterInfo, "type"); + + mbeanParameterInfo = new MBeanParameterInfo( + "name", "type", null, new DescriptorSupport()); + test(mbeanParameterInfo0, mbeanParameterInfo, "description"); + + mbeanParameterInfo = new MBeanParameterInfo( + "name", "type", "description", null); + test(mbeanParameterInfo0, mbeanParameterInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on MBeanFeatureInfo ..."); + MBeanFeatureInfo mbeanFeatureInfo0 = new MBeanFeatureInfo( + "name", "description", new DescriptorSupport()); + MBeanFeatureInfo mbeanFeatureInfo = new MBeanFeatureInfo( + null, "description", new DescriptorSupport()); + test(mbeanFeatureInfo0, mbeanFeatureInfo, "name"); + + mbeanFeatureInfo = new MBeanFeatureInfo( + "name", null, new DescriptorSupport()); + test(mbeanParameterInfo0, mbeanParameterInfo, "description"); + + mbeanFeatureInfo = new MBeanFeatureInfo( + "name", "description", null); + test(mbeanParameterInfo0, mbeanParameterInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on MBeanInfo..."); + String className = "toto"; + String description = "titi"; + MBeanAttributeInfo[] attrInfos = new MBeanAttributeInfo[]{}; + MBeanConstructorInfo[] constrInfos = new MBeanConstructorInfo[]{}; + MBeanOperationInfo[] operaInfos = new MBeanOperationInfo[]{}; + MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{}; + + MBeanInfo minfo0 = new MBeanInfo("toto", description, attrInfos, constrInfos, operaInfos, notifInfos); + MBeanInfo minfo = new MBeanInfo(null, description, attrInfos, constrInfos, operaInfos, notifInfos); + test(minfo0, minfo, "class name"); + + minfo = new MBeanInfo(className, null, attrInfos, constrInfos, operaInfos, notifInfos); + test(minfo0, minfo, "description"); + + minfo = new MBeanInfo(className, description, null, constrInfos, operaInfos, notifInfos); + test(minfo0, minfo, "attrInfos"); + + minfo = new MBeanInfo(className, description, attrInfos, null, operaInfos, notifInfos); + test(minfo0, minfo, "constrInfos"); + + minfo = new MBeanInfo(className, description, attrInfos, constrInfos, null, notifInfos); + test(minfo0, minfo, "operaInfos"); + + minfo = new MBeanInfo(className, description, attrInfos, constrInfos, operaInfos, null); + test(minfo0, minfo, "notifInfos"); + + if (failed > 0) { + throw new RuntimeException("Test failed: "+failed); + } else { + System.out.println("---Test: PASSED"); + } + } + + private static void test(Object obj1, Object obj2, String param) { + try { + obj1.equals(obj2); + System.out.println("OK-1: "+obj1.getClass().getSimpleName()+".equals worked with a null paramer: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-1!!! "+obj1.getClass().getSimpleName()+".equals got NPE with a null paramer: "+param); + npe.printStackTrace(); + failed++; + } + + try { + obj2.equals(obj1); + System.out.println("OK-2: "+obj2.getClass().getSimpleName()+".equals worked with a null paramer: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-2!!! "+obj2.getClass().getSimpleName()+".equals got NPE with a null paramer: "+param); + npe.printStackTrace(); + failed++; + } + + try { + obj1.equals(null); + obj2.equals(null); + + System.out.println("OK-3: "+obj1.getClass().getSimpleName()+".equals worked with a null field."); + } catch (NullPointerException npe) { + System.out.println("--->KO-3!!! "+obj1.getClass().getSimpleName()+".equals got NPE with a null field."); + npe.printStackTrace(); + failed++; + } + } +} From 5ae304e238a2e80ff895f8118edd4e6e9394a612 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 18 Sep 2013 18:22:49 +0800 Subject: [PATCH 0120/1294] 8012615: Realm.getRealmsList returns realms list in wrong Reviewed-by: valeriep, xuelei --- .../classes/sun/security/krb5/Config.java | 34 +- .../classes/sun/security/krb5/Realm.java | 525 +++++------------- .../krb5/internal/CredentialsUtil.java | 20 +- jdk/test/sun/security/krb5/ParseCAPaths.java | 85 ++- jdk/test/sun/security/krb5/krb5-capaths.conf | 81 +-- 5 files changed, 264 insertions(+), 481 deletions(-) diff --git a/jdk/src/share/classes/sun/security/krb5/Config.java b/jdk/src/share/classes/sun/security/krb5/Config.java index 5771886023c..c2640adbcda 100644 --- a/jdk/src/share/classes/sun/security/krb5/Config.java +++ b/jdk/src/share/classes/sun/security/krb5/Config.java @@ -225,19 +225,19 @@ public class Config { * and has no sub-key at all (given "forwardable" is defined, otherwise, * this method has no knowledge if it's a value name or a section name), */ - @SuppressWarnings("unchecked") public String get(String... keys) { - Vector v = get0(keys); + Vector v = getString0(keys); if (v == null) return null; return v.lastElement(); } /** * Gets all values for the specified keys. - * @see #get(java.lang.String[]) + * @throws IllegalArgumentException if any of the keys is illegal + * (See {@link #get}) */ public String getAll(String... keys) { - Vector v = get0(keys); + Vector v = getString0(keys); if (v == null) return null; StringBuilder sb = new StringBuilder(); boolean first = true; @@ -252,17 +252,37 @@ public class Config { return sb.toString(); } - // Internal method. Returns the vector of strings for keys. + /** + * Returns true if keys exists, can be either final string(s) or sub-stanza + * @throws IllegalArgumentException if any of the keys is illegal + * (See {@link #get}) + */ + public boolean exists(String... keys) { + return get0(keys) != null; + } + + // Returns final string value(s) for given keys. + @SuppressWarnings("unchecked") + private Vector getString0(String... keys) { + try { + return (Vector)get0(keys); + } catch (ClassCastException cce) { + throw new IllegalArgumentException(cce); + } + } + + // Internal method. Returns the value for keys, which can be a sub-stanza + // or final string value(s). // The only method (except for toString) that reads stanzaTable directly. @SuppressWarnings("unchecked") - private Vector get0(String... keys) { + private Object get0(String... keys) { Object current = stanzaTable; try { for (String key: keys) { current = ((Hashtable)current).get(key); if (current == null) return null; } - return (Vector)current; + return current; } catch (ClassCastException cce) { throw new IllegalArgumentException(cce); } diff --git a/jdk/src/share/classes/sun/security/krb5/Realm.java b/jdk/src/share/classes/sun/security/krb5/Realm.java index bc7705c4f0e..27bedc3ecf8 100644 --- a/jdk/src/share/classes/sun/security/krb5/Realm.java +++ b/jdk/src/share/classes/sun/security/krb5/Realm.java @@ -34,10 +34,8 @@ package sun.security.krb5; import sun.security.krb5.internal.Krb5; import sun.security.util.*; import java.io.IOException; -import java.util.StringTokenizer; -import java.util.Vector; -import java.util.Stack; -import java.util.EmptyStackException; +import java.util.*; + import sun.security.krb5.internal.util.KerberosString; /** @@ -50,7 +48,6 @@ import sun.security.krb5.internal.util.KerberosString; */ public class Realm implements Cloneable { private final String realm; // not null nor empty - private static boolean DEBUG = Krb5.DEBUG; public Realm(String name) throws RealmException { realm = parseRealm(name); @@ -233,90 +230,53 @@ public class Realm implements Cloneable { } } - /* - * First leg of realms parsing. Used by getRealmsList. - */ - private static String[] doInitialParse(String cRealm, String sRealm) - throws KrbException { - if (cRealm == null || sRealm == null){ - throw new KrbException(Krb5.API_INVALID_ARG); - } - if (DEBUG) { - System.out.println(">>> Realm doInitialParse: cRealm=[" - + cRealm + "], sRealm=[" +sRealm + "]"); - } - if (cRealm.equals(sRealm)) { - String[] retList = null; - retList = new String[1]; - retList[0] = new String(cRealm); - - if (DEBUG) { - System.out.println(">>> Realm doInitialParse: " - + retList[0]); - } - return retList; - } - return null; - } - /** * Returns an array of realms that may be traversed to obtain * a TGT from the initiating realm cRealm to the target realm * sRealm. *
    - * There may be an arbitrary number of intermediate realms - * between cRealm and sRealm. The realms may be organized - * organized hierarchically, or the paths between them may be - * specified in the [capaths] stanza of the caller's - * Kerberos configuration file. The configuration file is consulted - * first. Then a hirarchical organization is assumed if no realms - * are found in the configuration file. + * This method would read [capaths] to create a path, or generate a + * hierarchical path if [capaths] does not contain a sub-stanza for cRealm + * or the sub-stanza does not contain a tag for sRealm. *
    - * The returned list, if not null, contains cRealm as the first - * entry. sRealm is not included unless it is mistakenly listed - * in the configuration file as an intermediary realm. + * The returned list would never be null, and it always contains + * cRealm as the head entry. sRealm is not included as the tail. * - * @param cRealm the initiating realm - * @param sRealm the target realm - * @returns array of realms - * @thows KrbException + * @param cRealm the initiating realm, not null + * @param sRealm the target realm, not null, not equals to cRealm + * @returns array of realms including at least cRealm as the first + * element */ - public static String[] getRealmsList(String cRealm, String sRealm) - throws KrbException { - String[] retList = doInitialParse(cRealm, sRealm); - if (retList != null && retList.length != 0) { - return retList; - } - /* - * Try [capaths]. - */ - retList = parseCapaths(cRealm, sRealm); - if (retList != null && retList.length != 0) { - return retList; - } - /* - * Now assume the realms are organized hierarchically. - */ - retList = parseHierarchy(cRealm, sRealm); - return retList; + public static String[] getRealmsList(String cRealm, String sRealm) { + try { + // Try [capaths] + return parseCapaths(cRealm, sRealm); + } catch (KrbException ke) { + // Now assume the realms are organized hierarchically. + return parseHierarchy(cRealm, sRealm); } + } /** - * Parses the [capaths] stanza of the configuration file - * for a list of realms to traverse - * to obtain credentials from the initiating realm cRealm to - * the target realm sRealm. - * @param cRealm the initiating realm - * @param sRealm the target realm - * @returns array of realms - * @ throws KrbException - */ - - /* - * parseCapaths works for a capaths organized such that - * for a given client realm C there is a tag C that - * contains subtags Ci ... Cn that completely define intermediate - * realms from C to target T. For example: + * Parses the [capaths] stanza of the configuration file for a + * list of realms to traverse to obtain credentials from the + * initiating realm cRealm to the target realm sRealm. + * + * For a given client realm C there is a tag C in [capaths] whose + * subtag S has a value which is a (possibly partial) path from C + * to S. When the path is partial, it contains only the tail of the + * full path. Values of other subtags will be used to build the full + * path. The value "." means a direct path from C to S. If realm S + * does not appear as a subtag, there is no path defined here. + * + * The implementation ignores all values which equals to C or S, or + * a "." in multiple values, or any duplicated realm names. + * + * When a path value has more than two realms, they can be specified + * with multiple key-value pairs each having a single value, but the + * order must not change. + * + * For example: * * [capaths] * TIVOLI.COM = { @@ -325,357 +285,130 @@ public class Realm implements Cloneable { * LDAPCENTRAL.NET = . * } * - * The tag TIVOLI.COM contains subtags IBM.COM, IBM_LDAPCENTRAL.COM - * and LDAPCENTRAL.NET that completely define the path from TIVOLI.COM - * to IBM.COM (TIVOLI.COM->LADAPCENTRAL.NET->IBM_LDAPCENTRAL.COM->IBM - * or TIVOLI.COM->MOONLITE.ORG->IBM.COM). + * TIVOLI.COM has a direct path to LDAPCENTRAL.NET, which has a direct + * path to IBM_LDAPCENTRAL.COM. It also has a partial path to IBM.COM + * being "IBM_LDAPCENTRAL.COM MOONLITE.ORG". Merging these info together, + * a full path from TIVOLI.COM to IBM.COM will be * - * A direct path is assumed for an intermediary whose entry is not - * "closed" by a "." In the above example, TIVOLI.COM is assumed - * to have a direct path to MOONLITE.ORG and MOONLITE.COM - * in turn to IBM.COM. + * TIVOLI.COM -> LDAPCENTRAL.NET -> IBM_LDAPCENTRAL.COM + * -> IBM_LDAPCENTRAL.COM -> MOONLITE.ORG + * + * Please note the sRealm IBM.COM does not appear in the path. + * + * @param cRealm the initiating realm + * @param sRealm the target realm, not the same as cRealm + * @returns array of realms including at least cRealm as the first + * element + * @throws KrbException if the config does not contain a sub-stanza + * for cRealm in [capaths] or the sub-stanza does not contain + * sRealm as a tag */ + private static String[] parseCapaths(String cRealm, String sRealm) + throws KrbException { - private static String[] parseCapaths(String cRealm, String sRealm) throws KrbException { - String[] retList = null; + // This line could throw a KrbException + Config cfg = Config.getInstance(); - Config cfg = null; - try { - cfg = Config.getInstance(); - } catch (Exception exc) { - if (DEBUG) { - System.out.println ("Configuration information can not be " + - "obtained " + exc.getMessage()); - } - return null; + if (!cfg.exists("capaths", cRealm, sRealm)) { + throw new KrbException("No conf"); } - String intermediaries = cfg.getAll("capaths", cRealm, sRealm); + LinkedList path = new LinkedList<>(); - if (intermediaries == null) { - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: no cfg entry"); - } - return null; - } - - String tempTarget = null, tempRealm = null; - Stack iStack = new Stack<>(); - - /* - * The half-established reversed-path, starting from the final target - * (sRealm), each item can be connected to by the next one. - * Might contains wrong item, if found, a bad track is performed - */ - Vector tempList = new Vector<>(8, 8); - tempList.add(sRealm); - - int count = 0; // For debug only - tempTarget = sRealm; - - out: do { - if (DEBUG) { - count++; - System.out.println(">>> Realm parseCapaths: loop " + - count + ": target=" + tempTarget); - } - - if (intermediaries != null && - !intermediaries.equals(".") && - !intermediaries.equals(cRealm)) { - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: loop " + - count + ": intermediaries=[" + - intermediaries + "]"); - } - - /* - * We have one or more space-separated intermediary realms. - * Stack them. A null is always added between intermedies of - * different targets. When this null is popped, it means none - * of the intermedies for this target is useful (because of - * infinite loop), the target is then removed from the partial - * tempList, and the next possible intermediary is tried. - */ - iStack.push(null); - String[] ints = intermediaries.split("\\s+"); - for (int i = ints.length-1; i>=0; i--) - { - tempRealm = ints[i]; - if (tempRealm.equals(PrincipalName.REALM_COMPONENT_SEPARATOR_STR)) { - break out; - } - if (!tempList.contains(tempRealm)) { - iStack.push(tempRealm); - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: loop " + - count + - ": pushed realm on to stack: " + - tempRealm); - } - } else if (DEBUG) { - System.out.println(">>> Realm parseCapaths: loop " + - count + - ": ignoring realm: [" + - tempRealm + "]"); - } - } - } else { - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: loop " + - count + - ": no intermediaries"); - } + String head = sRealm; + while (true) { + String value = cfg.getAll("capaths", cRealm, head); + if (value == null) { break; } - - /* - * Get next intermediary realm from the stack - */ - - try { - while ((tempTarget = iStack.pop()) == null) { - tempList.removeElementAt(tempList.size()-1); - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: backtrack, remove tail"); - } + String[] more = value.split("\\s+"); + boolean changed = false; + for (int i=more.length-1; i>=0; i--) { + if (path.contains(more[i]) + || more[i].equals(".") + || more[i].equals(cRealm) + || more[i].equals(sRealm) + || more[i].equals(head)) { + // Ignore invalid values + continue; } - } catch (EmptyStackException exc) { - tempTarget = null; + changed = true; + path.addFirst(more[i]); } - - if (tempTarget == null) { - /* - * No more intermediaries. We're done. - */ - break; - } - - tempList.add(tempTarget); - - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: loop " + count + - ": added intermediary to list: " + - tempTarget); - } - - intermediaries = cfg.getAll("capaths", cRealm, tempTarget); - - } while (true); - - if (tempList.isEmpty()) { - return null; + if (!changed) break; + head = path.getFirst(); } - - // From (SREALM, T1, T2) to (CREALM, T2, T1) - retList = new String[tempList.size()]; - retList[0] = cRealm; - for (int i=1; i>> Realm parseCapaths [" + i + - "]=" + retList[i]); - } - } - - return retList; - } + path.addFirst(cRealm); + return path.toArray(new String[path.size()]); + } /** * Build a list of realm that can be traversed * to obtain credentials from the initiating realm cRealm * for a service in the target realm sRealm. * @param cRealm the initiating realm - * @param sRealm the target realm - * @returns array of realms - * @throws KrbException + * @param sRealm the target realm, not the same as cRealm + * @returns array of realms including cRealm as the first element */ - private static String[] parseHierarchy(String cRealm, String sRealm) - throws KrbException - { - String[] retList = null; + private static String[] parseHierarchy(String cRealm, String sRealm) { - // Parse the components and determine common part, if any. + String[] cComponents = cRealm.split("\\."); + String[] sComponents = sRealm.split("\\."); - String[] cComponents = null; - String[] sComponents = null; + int cPos = cComponents.length; + int sPos = sComponents.length; - StringTokenizer strTok = - new StringTokenizer(cRealm, - PrincipalName.REALM_COMPONENT_SEPARATOR_STR); - - // Parse cRealm - - int cCount = strTok.countTokens(); - cComponents = new String[cCount]; - - for (cCount = 0; strTok.hasMoreTokens(); cCount++) { - cComponents[cCount] = strTok.nextToken(); + boolean hasCommon = false; + for (sPos--, cPos--; sPos >=0 && cPos >= 0 && + sComponents[sPos].equals(cComponents[cPos]); + sPos--, cPos--) { + hasCommon = true; } - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy: cRealm has " + - cCount + " components:"); - int j = 0; - while (j < cCount) { - System.out.println(">>> Realm parseHierarchy: " + - "cComponents["+j+"]=" + cComponents[j++]); - } + // For those with common components: + // length pos + // SITES1.SALES.EXAMPLE.COM 4 1 + // EVERYWHERE.EXAMPLE.COM 3 0 + + // For those without common components: + // length pos + // DEVEL.EXAMPLE.COM 3 2 + // PROD.EXAMPLE.ORG 3 2 + + LinkedList path = new LinkedList<>(); + + // Un-common ones for client side + for (int i=0; i<=cPos; i++) { + path.addLast(subStringFrom(cComponents, i)); } - // Parse sRealm - - strTok = new StringTokenizer(sRealm, - PrincipalName.REALM_COMPONENT_SEPARATOR_STR); - - int sCount = strTok.countTokens(); - sComponents = new String[sCount]; - - for (sCount = 0; strTok.hasMoreTokens(); sCount++) { - sComponents[sCount] = strTok.nextToken(); + // Common one + if (hasCommon) { + path.addLast(subStringFrom(cComponents, cPos+1)); } - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy: sRealm has " + - sCount + " components:"); - int j = 0; - while (j < sCount) { - System.out.println(">>> Realm parseHierarchy: sComponents["+j+ - "]=" + sComponents[j++]); - } + // Un-common ones for server side + for (int i=sPos; i>=0; i--) { + path.addLast(subStringFrom(sComponents, i)); } - // Determine common components, if any. + // Remove sRealm from path. Note that it might be added at last loop + // or as a common component, if sRealm is a parent of cRealm + path.removeLast(); - int commonComponents = 0; - - //while (sCount > 0 && cCount > 0 && - // sComponents[--sCount].equals(cComponents[--cCount])) - - for (sCount--, cCount--; sCount >=0 && cCount >= 0 && - sComponents[sCount].equals(cComponents[cCount]); - sCount--, cCount--) { - commonComponents++; - } - - int cCommonStart = -1; - int sCommonStart = -1; - - int links = 0; - - if (commonComponents > 0) { - sCommonStart = sCount+1; - cCommonStart = cCount+1; - - // components from common to ancestors - links += sCommonStart; - links += cCommonStart; - } else { - links++; - } - - if (DEBUG) { - if (commonComponents > 0) { - System.out.println(">>> Realm parseHierarchy: " + - commonComponents + " common component" + - (commonComponents > 1 ? "s" : " ")); - - System.out.println(">>> Realm parseHierarchy: common part " - + - "in cRealm (starts at index " + - cCommonStart + ")"); - System.out.println(">>> Realm parseHierarchy: common part in sRealm (starts at index " + - sCommonStart + ")"); - - - String commonPart = substring(cRealm, cCommonStart); - System.out.println(">>> Realm parseHierarchy: common part in cRealm=" + - commonPart); - - commonPart = substring(sRealm, sCommonStart); - System.out.println(">>> Realm parseHierarchy: common part in sRealm=" + - commonPart); - - } else - System.out.println(">>> Realm parseHierarchy: no common part"); - } - - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy: total links=" + links); - } - - retList = new String[links]; - - retList[0] = new String(cRealm); - - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy A: retList[0]=" + - retList[0]); - } - - // For an initiator realm A.B.C.D.COM, - // build a list krbtgt/B.C.D.COM@A.B.C.D.COM up to the common part, - // ie the issuer realm is the immediate descendant - // of the target realm. - - String cTemp = null, sTemp = null; - int i; - for (i = 1, cCount = 0; i < links && cCount < cCommonStart; cCount++) { - sTemp = substring(cRealm, cCount+1); - //cTemp = substring(cRealm, cCount); - retList[i++] = new String(sTemp); - - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy B: retList[" + - (i-1) +"]="+retList[i-1]); - } - } - - - for (sCount = sCommonStart; i < links && sCount - 1 > 0; sCount--) { - sTemp = substring(sRealm, sCount-1); - //cTemp = substring(sRealm, sCount); - retList[i++] = new String(sTemp); - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy D: retList[" + - (i-1) +"]="+retList[i-1]); - } - } - - return retList; + return path.toArray(new String[path.size()]); } - private static String substring(String realm, int componentIndex) - { - int i = 0 , j = 0, len = realm.length(); - - while(i < len && j != componentIndex) { - if (realm.charAt(i++) != PrincipalName.REALM_COMPONENT_SEPARATOR) - continue; - j++; + /** + * Creates a realm name using components from the given postion. + * For example, subStringFrom({"A", "B", "C"}, 1) is "B.C". + */ + private static String subStringFrom(String[] components, int from) { + StringBuilder sb = new StringBuilder(); + for (int i=from; i>> Credentials acquireServiceCreds: no realms list"); - } - return null; - } - int i = 0, k = 0; Credentials cTgt = null, newTgt = null, theTgt = null; PrincipalName tempService = null; @@ -206,16 +198,14 @@ public class CredentialsUtil { if (newTgt == null) { if (DEBUG) { System.out.println(">>> Credentials acquireServiceCreds: " - + "no tgt; searching backwards"); + + "no tgt; searching thru capath"); } /* - * No tgt found. Try to get one for a - * realm as close to the target as possible. - * That means traversing the realms list backwards. + * No tgt found. Let's go thru the realms list one by one. */ - for (newTgt = null, k = realms.length - 1; - newTgt == null && k > i; k--) { + for (newTgt = null, k = i+1; + newTgt == null && k < realms.length; k++) { tempService = PrincipalName.tgsService(realms[k], realms[i]); if (DEBUG) { System.out.println( diff --git a/jdk/test/sun/security/krb5/ParseCAPaths.java b/jdk/test/sun/security/krb5/ParseCAPaths.java index f8c30bd7b7d..18b43470842 100644 --- a/jdk/test/sun/security/krb5/ParseCAPaths.java +++ b/jdk/test/sun/security/krb5/ParseCAPaths.java @@ -22,7 +22,7 @@ */ /* * @test - * @bug 6789935 + * @bug 6789935 8012615 * @run main/othervm ParseCAPaths * @summary cross-realm capath search error */ @@ -35,37 +35,75 @@ public class ParseCAPaths { public static void main(String[] args) throws Exception { System.setProperty("java.security.krb5.conf", System.getProperty("test.src", ".") +"/krb5-capaths.conf"); - //System.setProperty("sun.security.krb5.debug", "true"); - // Standard example + // MIT check("ANL.GOV", "TEST.ANL.GOV", "ANL.GOV"); check("ANL.GOV", "ES.NET", "ANL.GOV"); check("ANL.GOV", "PNL.GOV", "ANL.GOV", "ES.NET"); check("ANL.GOV", "NERSC.GOV", "ANL.GOV", "ES.NET"); + check("NERSC.GOV", "TEST.ANL.GOV", "NERSC.GOV", "ES.NET", "ANL.GOV"); + + // RedHat + // 3.6.2.1. Configuring a Shared Hierarchy of Names + check("AA.EXAMPLE.COM", "BB.EXAMPLE.COM", + "AA.EXAMPLE.COM", "EXAMPLE.COM"); + check("SITE1.SALES.EXAMPLE.COM", "EVERYWHERE.EXAMPLE.COM", + "SITE1.SALES.EXAMPLE.COM", "SALES.EXAMPLE.COM", + "EXAMPLE.COM"); + check("DEVEL.EXAMPLE.COM", "PROD.EXAMPLE.ORG", + "DEVEL.EXAMPLE.COM", "EXAMPLE.COM", "COM", + "ORG", "EXAMPLE.ORG"); + // 3.6.2.2. Configuring Paths in krb5.conf + check("A.EXAMPLE.COM", "B.EXAMPLE.COM", "A.EXAMPLE.COM"); + check("A.EXAMPLE.COM", "C.EXAMPLE.COM", + "A.EXAMPLE.COM", "B.EXAMPLE.COM"); + check("A.EXAMPLE.COM", "D.EXAMPLE.COM", + "A.EXAMPLE.COM", "B.EXAMPLE.COM", "C.EXAMPLE.COM"); + + // The original JDK example + check("TIVOLI.COM", "IBM.COM", "TIVOLI.COM", "LDAPCENTRAL.NET", + "IBM_LDAPCENTRAL.COM", "MOONLITE.ORG"); + // Hierachical - check("N1.N.COM", "N2.N.COM", "N1.N.COM", "N.COM"); // 2 common - check("N1.N.COM", "N2.N3.COM", "N1.N.COM", "N.COM", // 1 common + check("N1.N.COM", "N2.N.COM", "N1.N.COM", "N.COM"); + check("N1.N.COM", "N2.N3.COM", "N1.N.COM", "N.COM", "COM", "N3.COM"); - check("N1.COM", "N2.COM", "N1.COM", "COM"); // 1 common - check("N1", "N2", "N1"); // 0 common - // Extra garbages - check("A1.COM", "A4.COM", "A1.COM", "A2.COM"); + check("N1.COM", "N2.COM", "N1.COM", "COM"); + check("N1", "N2", "N1"); + check("N1.COM", "N2.ORG", "N1.COM", "COM", "ORG"); + check("N1.N.COM", "N.COM", "N1.N.COM"); + check("X.N1.N.COM", "N.COM", "X.N1.N.COM", "N1.N.COM"); + check("N.COM", "N1.N.COM", "N.COM"); + check("N.COM", "X.N1.N.COM", "N.COM", "N1.N.COM"); + check("A.B.C", "D.E.F", "A.B.C", "B.C", "C", "F", "E.F"); + + // Full path + check("A1.COM", "A2.COM", "A1.COM"); + check("A1.COM", "A3.COM", "A1.COM", "A2.COM"); + check("A1.COM", "A4.COM", "A1.COM", "A2.COM", "A3.COM"); + + // Shortest path + check("B1.COM", "B2.COM", "B1.COM"); check("B1.COM", "B3.COM", "B1.COM", "B2.COM"); + check("B1.COM", "B4.COM", "B1.COM", "B2.COM", "B3.COM"); + // Missing is "." + check("C1.COM", "C2.COM", "C1.COM", "COM"); check("C1.COM", "C3.COM", "C1.COM", "C2.COM"); - // Multiple path - check("D1.COM", "D4.COM", "D1.COM", "D2.COM"); - check("E1.COM", "E4.COM", "E1.COM", "E2.COM"); - check("F1.COM", "F4.COM", "F1.COM", "F9.COM"); - // Infinite loop - check("G1.COM", "G3.COM", "G1.COM", "COM"); - check("H1.COM", "H3.COM", "H1.COM"); + + // cRealm = . + check("D1.COM", "D2.COM", "D1.COM"); + + // Bad cases + check("E1.COM", "E2.COM", "E1.COM"); + check("E1.COM", "E3.COM", "E1.COM", "E4.COM"); + check("G1.COM", "G3.COM", "G1.COM", "G2.COM"); check("I1.COM", "I4.COM", "I1.COM", "I5.COM"); - // J2=J1 is the same as J2=. - check("J1.COM", "J2.COM", "J1.COM"); + // 7019384 check("A9.PRAGUE.XXX.CZ", "SERVIS.XXX.CZ", "A9.PRAGUE.XXX.CZ", "PRAGUE.XXX.CZ", "ROOT.XXX.CZ"); + if (failed != null) { throw failed; } @@ -75,6 +113,7 @@ public class ParseCAPaths { try { check2(from, to, paths); } catch (Exception e) { + System.out.println(" " + e.getMessage()); failed = e; } } @@ -84,18 +123,14 @@ public class ParseCAPaths { System.out.println(from + " -> " + to); System.out.println(" expected: " + Arrays.toString(paths)); String[] result = Realm.getRealmsList(from, to); - System.out.println(" result: " + Arrays.toString(result)); - if (result == null) { - if (paths.length == 0) { - // OK - } else { - throw new Exception("Shouldn't have a valid path."); - } + if (result == null || result.length == 0) { + throw new Exception("There is always a valid path."); } else if(result.length != paths.length) { throw new Exception("Length of path not correct"); } else { for (int i=0; i Date: Wed, 18 Sep 2013 14:10:24 +0100 Subject: [PATCH 0121/1294] 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx) Co-authored-by: Norman Maurer Reviewed-by: alanb, coffeys --- .../sun/nio/ch/DevPollArrayWrapper.java | 7 +++++-- .../classes/sun/nio/ch/EPollArrayWrapper.java | 18 +++++++++++++++--- .../classes/sun/nio/ch/EventPortWrapper.java | 12 +++++++++--- .../nio/channels/Selector/LotsOfChannels.java | 5 +++-- .../nio/channels/Selector/SelectorLimit.java | 3 ++- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java index df30e2924f2..6eeee2a7532 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java +++ b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java @@ -26,9 +26,11 @@ package sun.nio.ch; import java.io.IOException; +import java.security.AccessController; import java.util.BitSet; import java.util.Map; import java.util.HashMap; +import sun.security.action.GetIntegerAction; /** @@ -78,10 +80,11 @@ class DevPollArrayWrapper { static final int NUM_POLLFDS = Math.min(OPEN_MAX-1, 8192); // Initial size of arrays for fd registration changes - private final int INITIAL_PENDING_UPDATE_SIZE = 64; + private static final int INITIAL_PENDING_UPDATE_SIZE = 64; // maximum size of updatesLow - private final int MAX_UPDATE_ARRAY_SIZE = Math.min(OPEN_MAX, 64*1024); + private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged( + new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024))); // The pollfd array for results from devpoll driver private final AllocatedNativeObject pollArray; diff --git a/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java index a73d3c2dff1..f64feb24c75 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java +++ b/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java @@ -26,9 +26,11 @@ package sun.nio.ch; import java.io.IOException; +import java.security.AccessController; import java.util.BitSet; import java.util.HashMap; import java.util.Map; +import sun.security.action.GetIntegerAction; /** * Manipulates a native array of epoll_event structs on Linux: @@ -78,8 +80,8 @@ class EPollArrayWrapper { private static final int INITIAL_PENDING_UPDATE_SIZE = 64; // maximum size of updatesLow - private static final int MAX_UPDATE_ARRAY_SIZE = Math.min(OPEN_MAX, 64*1024); - + private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged( + new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024))); // The fd of the epoll driver private final int epfd; @@ -163,6 +165,16 @@ class EPollArrayWrapper { return pollArray.getInt(offset); } + /** + * Returns {@code true} if updates for the given key (file + * descriptor) are killed. + */ + private boolean isEventsHighKilled(Integer key) { + assert key >= MAX_UPDATE_ARRAY_SIZE; + Byte value = eventsHigh.get(key); + return (value != null && value == KILLED); + } + /** * Sets the pending update events for the given file descriptor. This * method has no effect if the update events is already set to KILLED, @@ -175,7 +187,7 @@ class EPollArrayWrapper { } } else { Integer key = Integer.valueOf(fd); - if ((eventsHigh.get(key) != KILLED) || force) { + if (!isEventsHighKilled(key) || force) { eventsHigh.put(key, Byte.valueOf(events)); } } diff --git a/jdk/src/solaris/classes/sun/nio/ch/EventPortWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/EventPortWrapper.java index bec37360642..d9383eb7ed0 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/EventPortWrapper.java +++ b/jdk/src/solaris/classes/sun/nio/ch/EventPortWrapper.java @@ -25,9 +25,14 @@ package sun.nio.ch; -import sun.misc.Unsafe; import java.io.IOException; -import java.util.*; +import java.security.AccessController; +import java.util.BitSet; +import java.util.HashMap; +import java.util.Map; + +import sun.misc.Unsafe; +import sun.security.action.GetIntegerAction; import static sun.nio.ch.SolarisEventPort.*; /** @@ -49,7 +54,8 @@ class EventPortWrapper { private final int INITIAL_PENDING_UPDATE_SIZE = 256; // maximum size of updateArray - private final int MAX_UPDATE_ARRAY_SIZE = Math.min(OPEN_MAX, 64*1024); + private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged( + new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024))); // special update status to indicate that it should be ignored private static final byte IGNORE = -1; diff --git a/jdk/test/java/nio/channels/Selector/LotsOfChannels.java b/jdk/test/java/nio/channels/Selector/LotsOfChannels.java index d88655d807f..2db6366a7fd 100644 --- a/jdk/test/java/nio/channels/Selector/LotsOfChannels.java +++ b/jdk/test/java/nio/channels/Selector/LotsOfChannels.java @@ -22,9 +22,10 @@ */ /* @test - * @bug 4503092 + * @bug 4503092 8024883 * @summary Tests that Windows Selector can use more than 63 channels - * @run main/timeout=300 LotsOfChannels + * @run main LotsOfChannels + * @run main/othervm -Dsun.nio.ch.maxUpdateArraySize=64 LotsOfChannels * @author kladko */ diff --git a/jdk/test/java/nio/channels/Selector/SelectorLimit.java b/jdk/test/java/nio/channels/Selector/SelectorLimit.java index 27589e24665..69963db8e04 100644 --- a/jdk/test/java/nio/channels/Selector/SelectorLimit.java +++ b/jdk/test/java/nio/channels/Selector/SelectorLimit.java @@ -22,12 +22,13 @@ */ /* @test - * @bug 4777504 + * @bug 4777504 8024883 * @summary Ensure that a Selector can return at least 100 selected keys * @author Mark Reinhold * @library .. * @build SelectorLimit * @run main/othervm SelectorLimit + * @run main/othervm -Dsun.nio.ch.maxUpdateArraySize=128 SelectorLimit */ import java.io.*; From ac8db73a7c956bdcc3749a0262a2af5ffbe60d3a Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 18 Sep 2013 21:37:45 +0800 Subject: [PATCH 0122/1294] 8011402: Move blacklisting certificate logic from hard code to data Reviewed-by: erikj, mullan --- jdk/make/java/security/Makefile | 25 +- jdk/makefiles/CopyFiles.gmk | 19 + .../java/security/cert/Certificate.java | 19 +- .../security/util/UntrustedCertificates.java | 907 ++---------------- .../sun/security/x509/X509CertImpl.java | 42 + .../security/BlacklistedCertsConverter.java | 89 ++ jdk/src/share/lib/security/blacklisted.certs | 19 + .../share/lib/security/blacklisted.certs.pem | 721 ++++++++++++++ .../lib/security/CheckBlacklistedCerts.java | 131 +++ 9 files changed, 1118 insertions(+), 854 deletions(-) create mode 100644 jdk/src/share/lib/security/BlacklistedCertsConverter.java create mode 100644 jdk/src/share/lib/security/blacklisted.certs create mode 100644 jdk/src/share/lib/security/blacklisted.certs.pem create mode 100644 jdk/test/lib/security/CheckBlacklistedCerts.java diff --git a/jdk/make/java/security/Makefile b/jdk/make/java/security/Makefile index bbb0ca4f757..05b6b8a5664 100644 --- a/jdk/make/java/security/Makefile +++ b/jdk/make/java/security/Makefile @@ -70,9 +70,13 @@ POLICY_BUILD = $(LIBDIR)/security/java.policy CACERTS_SRC = $(CACERTS_FILE) CACERTS_BUILD = $(LIBDIR)/security/cacerts +BLACKLISTED_CERTS_SRC = $(TOPDIR)/src/share/lib/security/blacklisted.certs +BLACKLISTED_CERTS_BUILD = $(LIBDIR)/security/blacklisted.certs + ifndef OPENJDK BLACKLIST_SRC = $(CLOSED_SHARE_SRC)/lib/security/blacklist BLACKLIST_BUILD = $(LIBDIR)/security/blacklist + BLACKLISTED_CERTS_SRC += $(wildcard $(CLOSED_SHARE_SRC)/lib/security/blacklisted.certs) TRUSTEDLIBS_SRC = $(CLOSED_SHARE_SRC)/lib/security/trusted.libraries TRUSTEDLIBS_BUILD = $(LIBDIR)/security/trusted.libraries endif @@ -85,9 +89,9 @@ FILES_class = $(FILES_java:%.java=$(CLASSBINDIR)/%.class) include $(BUILDDIR)/common/Rules.gmk ifdef OPENJDK -build: properties policy cacerts +build: properties policy cacerts blacklisted-certs else -build: properties policy cacerts blacklist trustedlibs +build: properties policy cacerts blacklist blacklisted-certs trustedlibs endif install: all @@ -100,6 +104,8 @@ cacerts: classes $(CACERTS_BUILD) blacklist: classes $(BLACKLIST_BUILD) +blacklisted-certs: classes $(BLACKLISTED_CERTS_BUILD) + trustedlibs: classes $(TRUSTEDLIBS_BUILD) $(PROPS_BUILD): $(PROPS_SRC) @@ -114,12 +120,25 @@ $(CACERTS_BUILD): $(CACERTS_SRC) $(BLACKLIST_BUILD): $(BLACKLIST_SRC) $(install-file) +$(BLACKLISTED_CERTS_BUILD): $(BLACKLISTED_CERTS_SRC) + $(MKDIR) -p $(@D) + $(CAT) $^ | $(SED) '/^$$/d' | $(SORT) | $(UNIQ) > $@.tmp + $(GREP) -i Algorithm $@.tmp > $@ + if [ `$(SED) -n -e "$$=" $@` != 1 ]; then \ + $(ECHO) "Different algorithms defined in $^"; \ + $(RM) $@ $@.tmp; \ + false; \ + fi + $(GREP) -iv Algorithm $@.tmp >> $@ + $(RM) $@.tmp + $(TRUSTEDLIBS_BUILD): $(TRUSTEDLIBS_SRC) $(install-file) clean clobber:: .delete.classlist $(RM) -r $(CLASSBINDIR)/java/security - $(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD) $(TRUSTEDLIBS_BUILD) + $(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD) \ + $(BLACKLISTED_CERTS_BUILD) $(TRUSTEDLIBS_BUILD) # Additional Rule for building sun.security.util $(CLASSBINDIR)/%.class: $(SHARE_SRC)/sun/%.java diff --git a/jdk/makefiles/CopyFiles.gmk b/jdk/makefiles/CopyFiles.gmk index 2b3cbf2e200..abdf3546a18 100644 --- a/jdk/makefiles/CopyFiles.gmk +++ b/jdk/makefiles/CopyFiles.gmk @@ -382,11 +382,16 @@ COPY_FILES += $(CACERTS_DST) ########################################################################################## +BLACKLISTED_CERTS_SRC := $(JDK_TOPDIR)/src/share/lib/security/blacklisted.certs +BLACKLISTED_CERTS_DST := $(JDK_OUTPUTDIR)/lib/security/blacklisted.certs + ifndef OPENJDK BLACKLIST_SRC := $(JDK_TOPDIR)/src/closed/share/lib/security/blacklist BLACKLIST_DST := $(JDK_OUTPUTDIR)/lib/security/blacklist +BLACKLISTED_CERTS_SRC += $(wildcard $(JDK_TOPDIR)/src/closed/share/lib/security/blacklisted.certs) + TRUSTEDLIBS_SRC := $(JDK_TOPDIR)/src/closed/share/lib/security/trusted.libraries TRUSTEDLIBS_DST := $(JDK_OUTPUTDIR)/lib/security/trusted.libraries @@ -402,6 +407,20 @@ COPY_FILES += $(TRUSTEDLIBS_DST) endif +$(BLACKLISTED_CERTS_DST): $(BLACKLISTED_CERTS_SRC) + $(MKDIR) -p $(@D) + $(CAT) $^ | $(SED) '/^$$/d' | $(SORT) | $(UNIQ) > $@.tmp + $(GREP) -i Algorithm $@.tmp > $@ + if [ `$(SED) -n -e "$$=" $@` != 1 ]; then \ + $(ECHO) "Different algorithms defined in $^"; \ + $(RM) $@ $@.tmp; \ + false; \ + fi + $(GREP) -iv Algorithm $@.tmp >> $@ + $(RM) $@.tmp + +COPY_FILES += $(BLACKLISTED_CERTS_DST) + ########################################################################################## ifndef OPENJDK diff --git a/jdk/src/share/classes/java/security/cert/Certificate.java b/jdk/src/share/classes/java/security/cert/Certificate.java index 638a02e6f80..10544983d2c 100644 --- a/jdk/src/share/classes/java/security/cert/Certificate.java +++ b/jdk/src/share/classes/java/security/cert/Certificate.java @@ -66,6 +66,9 @@ public abstract class Certificate implements java.io.Serializable { // the certificate type private final String type; + /** Cache the hash code for the certiticate */ + private int hash = -1; // Default to -1 + /** * Creates a certificate of the specified type. * @@ -123,16 +126,16 @@ public abstract class Certificate implements java.io.Serializable { * @return the hashcode value. */ public int hashCode() { - int retval = 0; - try { - byte[] certData = X509CertImpl.getEncodedInternal(this); - for (int i = 1; i < certData.length; i++) { - retval += certData[i] * i; + int h = hash; + if (h == -1) { + try { + h = Arrays.hashCode(X509CertImpl.getEncodedInternal(this)); + } catch (CertificateException e) { + h = 0; } - return retval; - } catch (CertificateException e) { - return retval; + hash = h; } + return h; } /** diff --git a/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java b/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java index 73495df5bcc..e14229b3c9d 100644 --- a/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java +++ b/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java @@ -24,13 +24,15 @@ */ package sun.security.util; -import java.io.IOException; -import java.io.ByteArrayInputStream; +import java.io.*; +import java.security.AccessController; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivilegedAction; import java.security.cert.X509Certificate; -import java.security.cert.CertificateFactory; import java.security.cert.CertificateException; -import java.util.Set; -import java.util.HashSet; +import java.util.*; +import sun.security.x509.X509CertImpl; /** * A utility class to check if a certificate is untrusted. This is an internal @@ -42,8 +44,50 @@ import java.util.HashSet; */ public final class UntrustedCertificates { - private final static Set untrustedCerts = new HashSet<>(); + private static final Debug debug = Debug.getInstance("certpath"); + private static final String ALGORITHM_KEY = "Algorithm"; + private static final Properties props = new Properties(); + private static final String algorithm; + + static { + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Void run() { + File f = new File(System.getProperty("java.home"), + "lib/security/blacklisted.certs"); + try (FileInputStream fin = new FileInputStream(f)) { + props.load(fin); + // It's said that the fingerprint could contain colons + for (Map.Entry e: props.entrySet()) { + e.setValue(stripColons(e.getValue())); + } + } catch (IOException fnfe) { + if (debug != null) { + debug.println("Error parsing blacklisted.certs"); + } + } + return null; + } + }); + algorithm = props.getProperty(ALGORITHM_KEY); + } + + private static String stripColons(Object input) { + String s = (String)input; + char[] letters = s.toCharArray(); + int pos = 0; + for (int i = 0; i < letters.length; i++) { + if (letters[i] != ':') { + if (i != pos) { + letters[pos] = letters[i]; + } + pos++; + } + } + if (pos == letters.length) return s; + else return new String(letters, 0, pos); + } /** * Checks if a certificate is untrusted. * @@ -51,844 +95,21 @@ public final class UntrustedCertificates { * @return true if the certificate is untrusted. */ public static boolean isUntrusted(X509Certificate cert) { - return untrustedCerts.contains(cert); - } - - private static void add(String alias, String pemCert) { - // generate certificate from PEM certificate - try (ByteArrayInputStream is = - new ByteArrayInputStream(pemCert.getBytes())) { - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - X509Certificate cert = (X509Certificate)cf.generateCertificate(is); - - if (!untrustedCerts.add(cert)) { - throw new RuntimeException("Duplicate untrusted certificate: " + - cert.getSubjectX500Principal()); - } - } catch (CertificateException | IOException e) { - throw new RuntimeException( - "Incorrect untrusted certificate: " + alias, e); + if (algorithm == null) { + return false; } + String key; + if (cert instanceof X509CertImpl) { + key = ((X509CertImpl)cert).getFingerprint(algorithm); + } else { + try { + key = new X509CertImpl(cert.getEncoded()).getFingerprint(algorithm); + } catch (CertificateException cee) { + return false; + } + } + return props.containsKey(key); } - static { - // ----------------------------------------------------------------- - // Compromised CAs of Digicert Malaysia - // - // Reported by Digicert in its announcement on November 05, 2011. - // - - // Digicert Malaysia intermediate, cross-signed by CyberTrust - // - // Subject: CN=Digisign Server ID (Enrich), - // OU=457608-K, - // O=Digicert Sdn. Bhd., - // C=MY - // Issuer: CN=GTE CyberTrust Global Root, - // OU=GTE CyberTrust Solutions, Inc., - // O=GTE Corporation, - // C=US - // Serial: 120001705 (07:27:14:a9) - add("digicert-server-cross-to-cybertrust-4C0E636A", - "-----BEGIN CERTIFICATE-----\n" + - "MIIDyzCCAzSgAwIBAgIEBycUqTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV\n" + - "UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU\n" + - "cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds\n" + - "b2JhbCBSb290MB4XDTA3MDcxNzE1MTc0OFoXDTEyMDcxNzE1MTY1NFowYzELMAkG\n" + - "A1UEBhMCTVkxGzAZBgNVBAoTEkRpZ2ljZXJ0IFNkbi4gQmhkLjERMA8GA1UECxMI\n" + - "NDU3NjA4LUsxJDAiBgNVBAMTG0RpZ2lzaWduIFNlcnZlciBJRCAoRW5yaWNoKTCB\n" + - "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArahkS02Hx4RZufuQRqCmicDx/tXa\n" + - "VII3DZkrRSYK6Fawf8qo9I5HhAGCKeOzarWR8/uVhbxyqGToCkCcxfRxrnt7agfq\n" + - "kBRPjYmvlKuyBtQCanuYH1m5Os1U+iDfsioK6bjdaZDAKdNO0JftZszFGUkGf/pe\n" + - "LHx7hRsyQt97lSUCAwEAAaOCAXgwggF0MBIGA1UdEwEB/wQIMAYBAf8CAQAwXAYD\n" + - "VR0gBFUwUzBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcCARYtaHR0cDovL2N5YmVy\n" + - "dHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnkuY2ZtMAcGBWCDSgEBMA4GA1Ud\n" + - "DwEB/wQEAwIB5jCBiQYDVR0jBIGBMH+heaR3MHUxCzAJBgNVBAYTAlVTMRgwFgYD\n" + - "VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv\n" + - "bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv\n" + - "b3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cucHVibGljLXRydXN0\n" + - "LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYDVR0OBBYEFMYWk04WF+wW\n" + - "royUdvOGbcV0boR3MA0GCSqGSIb3DQEBBQUAA4GBAHYAe6Z4K2Ydjl42xqSOBfIj\n" + - "knyTZ9P0wAp9iy3Z6tVvGvPhSilaIoRNUC9LDPL/hcJ7VdREgr5trGeOvLQfkpxR\n" + - "gBoU9m6rYYgLrRx/90tQUdZlG6ZHcRVesHHzNRTyN71jyNXwk1o0X9g96F33xR7A\n" + - "5c8fhiSpPAdmzcHSNmNZ\n" + - "-----END CERTIFICATE-----"); - - // Digicert Malaysia intermediate, cross-signed by Entrust - // - // Subject: CN=Digisign Server ID - (Enrich), - // OU=457608-K, - // O=Digicert Sdn. Bhd., - // C=MY - // Issuer: CN=Entrust.net Certification Authority (2048) - // OU=(c) 1999 Entrust.net Limited, - // OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), - // O=Entrust.net - // Serial: 1184644297 (4c:0e:63:6a) - add("digicert-server-cross-to-entrust-ca-4C0E636A", - "-----BEGIN CERTIFICATE-----\n" + - "MIIEzjCCA7agAwIBAgIETA5jajANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML\n" + - "RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp\n" + - "bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5\n" + - "IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp\n" + - "ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw0xMDA3MTYxNzIzMzdaFw0xNTA3\n" + - "MTYxNzUzMzdaMGUxCzAJBgNVBAYTAk1ZMRswGQYDVQQKExJEaWdpY2VydCBTZG4u\n" + - "IEJoZC4xETAPBgNVBAsTCDQ1NzYwOC1LMSYwJAYDVQQDEx1EaWdpc2lnbiBTZXJ2\n" + - "ZXIgSUQgLSAoRW5yaWNoKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n" + - "AMWJ5PQNBkCSWccaszXRDkwqM/n4r8qef+65p21g9FTob9Wb8xtjMQRoctE0Foy0\n" + - "FyyX3nPF2JAVoBor9cuzSIZE8B2ITM5BQhrv9Qze/kDaOSD3BlU6ap1GwdJvpbLI\n" + - "Vz4po5zg6YV3ZuiYpyR+vsBZIOVEb7ZX2L7OwmV3WMZhQdF0BMh/SULFcqlyFu6M\n" + - "3RJdtErU0a9Qt9iqdXZorT5dqjBtYairEFs+E78z4K9EnTgiW+9ML6ZxJhUmyiiM\n" + - "2fqOjqmiFDXimySItPR/hZ2DTwehthSQNsQ0HI0mYW0Tb3i+6I8nx0uElqOGaAwj\n" + - "vgvsjJQAqQSKE5D334VsDLECAwEAAaOCATQwggEwMA4GA1UdDwEB/wQEAwIBBjAS\n" + - "BgNVHRMBAf8ECDAGAQH/AgEAMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggrBgEFBQcD\n" + - "AgYIKwYBBQUHAwQwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8v\n" + - "b2NzcC5lbnRydXN0Lm5ldDBEBgNVHSAEPTA7MDkGBWCDSgEBMDAwLgYIKwYBBQUH\n" + - "AgEWImh0dHA6Ly93d3cuZGlnaWNlcnQuY29tLm15L2Nwcy5odG0wMgYDVR0fBCsw\n" + - "KTAnoCWgI4YhaHR0cDovL2NybC5lbnRydXN0Lm5ldC8yMDQ4Y2EuY3JsMBEGA1Ud\n" + - "DgQKBAhMTswlKAMpgTAfBgNVHSMEGDAWgBRV5IHREYC+2Im5CKMx+aEkCRa5cDAN\n" + - "BgkqhkiG9w0BAQUFAAOCAQEAl0zvSjpJrHL8MCBrtClbp8WVBJD5MtXChWreA6E3\n" + - "+YkAsFqsVX7bQzX/yQH4Ub7MJsrIaqTEVD4mHucMo82XZ5TdpkLrXM2POXlrM3kh\n" + - "Bnn6gkQVmczBtznTRmJ8snDrb84gqj4Zt+l0gpy0pUtNYQA35IfS8hQ6ZHy4qXth\n" + - "4JMi59WfPkfmNnagU9gAAzoPtTP+lsrT0oI6Lt3XSOHkp2nMHOmZSufKcEXXCwcO\n" + - "mnUb0C+Sb/akB8O9HEumhLZ9qJqp0qcp8QtXaR6XVybsK0Os1EWDBQDp4/BGQAf6\n" + - "6rFRc5Mcpd1TETfIKqcVJx20qsx/qjEw/LhFn0gJ7RDixQ==\n" + - "-----END CERTIFICATE-----"); - - - // ----------------------------------------------------------------- - // - // No longer used certificates - // - - // Subject: CN=Java Media APIs, - // OU=Java Signed Extensions, - // OU=Corporate Object Signing, - // O=Sun Microsystems Inc - // Issuer: CN=Object Signing CA, - // OU=Class 2 OnSite Subscriber CA, - // OU=VeriSign Trust Network, - // O=Sun Microsystems Inc - // Serial: 6a:8b:99:91:37:59:4f:89:53:e2:97:18:9f:19:1e:4e - add("java-media-pretrusted-9F191E4E", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFdzCCBF+gAwIBAgIQaouZkTdZT4lT4pcYnxkeTjANBgkqhkiG9w0BAQUFADCB\n" + - "gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT\n" + - "aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj\n" + - "cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDUxMjAw\n" + - "MDAwMFoXDTEyMDUxMTIzNTk1OVowfTEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt\n" + - "cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE\n" + - "CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEYMBYGA1UEAxQPSmF2YSBNZWRpYSBB\n" + - "UElzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl5blzoKTVE8y4Hpz\n" + - "q6E15RZz1bF5HnYEyYqgHkZXnAKedmYCoMzm1XK8s+gQWShLEvGEAvs5yqarx9gE\n" + - "nnC21N28aEZgIJMa2/arKxCUkS4pxdGPYGexL9UzSRkUpoBShCZKEGdmX7gfJE2K\n" + - "/sd9MFvGV5/yZtWXrADzvm0Kd/9mg1KRv1gfrZIq0TJbupoXPYYqb73AkI9eT2ZD\n" + - "q9MdwD4E5+oojsDFXt8GU/D00fUhtXpYwuplU7D667WHYdJhIah0ST6JywyqcLXG\n" + - "XSuFTXOgITT2idSHluZVmx3dqJ72u9kPkO4JdJTMDfaK8zgNLaRkiU8Qcj+qhLYH\n" + - "ytaqcwIDAQABo4IB6jCCAeYwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCB4AwfwYD\n" + - "VR0fBHgwdjB0oHKgcIZuaHR0cDovL29uc2l0ZWNybC52ZXJpc2lnbi5jb20vU3Vu\n" + - "TWljcm9zeXN0ZW1zSW5jQ29ycG9yYXRlT2JqZWN0U2lnbmluZ0phdmFTaWduZWRF\n" + - "eHRlbnNpb25zQ2xhc3NCL0xhdGVzdENSTC5jcmwwHwYDVR0jBBgwFoAUs0crgn5T\n" + - "tHPKuLsZt76BTQeVx+0wHQYDVR0OBBYEFKS32mVx0gNWTeS4ProHEaeSpvvIMDsG\n" + - "CCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL29uc2l0ZS1vY3NwLnZl\n" + - "cmlzaWduLmNvbTCBtQYDVR0gBIGtMIGqMDkGC2CGSAGG+EUBBxcCMCowKAYIKwYB\n" + - "BQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwbQYLYIZIAYb3AIN9\n" + - "nD8wXjAnBggrBgEFBQcCARYbaHR0cHM6Ly93d3cuc3VuLmNvbS9wa2kvY3BzMDMG\n" + - "CCsGAQUFBwICMCcaJVZhbGlkYXRlZCBGb3IgU3VuIEJ1c2luZXNzIE9wZXJhdGlv\n" + - "bnMwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQEFBQADggEBAAe6BO4W\n" + - "3TSNWfezyelJs6kE3HfulT6Bdyz4UUoh9ykXcV8nRwT+kh25I5MdyG2GfkJoADPR\n" + - "VhC5DYo13UFpIsTNVjq+hGYe2hML93bN7ad9SxCCyjHUo3yMz2qgBbHZI3VA9ZHA\n" + - "aWM4Tx0saMwbcnVvlbuGh+PXvStfypJqYT6lzcdFfjNVX4FI/QQNGhBswMY51tC8\n" + - "GTBCL2qhJon0gSCU4zaawDOf7+XxJWirLamYL1Aal1/h2z2sFrvA/1ftxtU3kZ6I\n" + - "7De8DyoHeZg7pYGdrj7g+lPhCga/WvEhN152I+aP08YbFcJHYmK05ngl/Ye4c6Bd\n" + - "cdrdfbw6QzEUIYY=\n" + - "-----END CERTIFICATE-----"); - - // Subject: CN=JavaFX 1.0 Runtime, - // OU=Java Signed Extensions, - // OU=Corporate Object Signing, - // O=Sun Microsystems Inc - // Issuer: CN=Object Signing CA, - // OU=Class 2 OnSite Subscriber CA, - // OU=VeriSign Trust Network, - // O=Sun Microsystems Inc - // Serial: 55:c0:e6:44:59:59:79:9e:d9:26:f1:b0:4a:1e:f0:27 - add("java-fx10-pretrusted-4A1EF027", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFezCCBGOgAwIBAgIQVcDmRFlZeZ7ZJvGwSh7wJzANBgkqhkiG9w0BAQUFADCB\n" + - "gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT\n" + - "aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj\n" + - "cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA4MTAwOTAw\n" + - "MDAwMFoXDTExMTAwOTIzNTk1OVowgYAxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl\n" + - "bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxHzAdBgNV\n" + - "BAsUFkphdmEgU2lnbmVkIEV4dGVuc2lvbnMxGzAZBgNVBAMUEkphdmFGWCAxLjAg\n" + - "UnVudGltZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM+WDc6+bu+4\n" + - "tmAcS/lBtUc02WOt9QZpVsXg9cG2pu/8bUtmDELa8iiYBVFpIs8DU58HLrGQtCUY\n" + - "SIAGOVPsOJoN29UKCDWfY9j5JeVhfhMGqk9DwrWhzgsjy4cpZ1pIp+k/fJ8zT8Ul\n" + - "aYLpow1vg3UNddsmwz02tN7cOrMw9WYIG4CRYnY1OrtJSfe2pYzheC4zyvR+aiVl\n" + - "nang2OtqikSQsNFOFHsLOJFxngy9LrO8evDSu25VTKI6zlWU6/bMeqtztJPN0VOn\n" + - "NyUrJZvkxZ207Jg0T693BGSxNC1n+ihztXogql8950M/pEuUbDjylv5FFvlp6DSB\n" + - "dDT2MkutmyMCAwEAAaOCAeowggHmMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeA\n" + - "MH8GA1UdHwR4MHYwdKByoHCGbmh0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29t\n" + - "L1N1bk1pY3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdKYXZhU2ln\n" + - "bmVkRXh0ZW5zaW9uc0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaAFLNH\n" + - "K4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBTjgufVi3XJ3gx1ewsA6Rr7BR4Z\n" + - "zjA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUtb2Nz\n" + - "cC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAqMCgG\n" + - "CCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CGSAGG\n" + - "9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtpL2Nw\n" + - "czAzBggrBgEFBQcCAjAnGiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBPcGVy\n" + - "YXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IBAQAB\n" + - "YVJTTVe7rzyTO4jc3zajErOT/COkdQTfNo0eIX1QbNynFieJvwY/jRzUZwjktIFR\n" + - "2p4JtbpHGAtKtjOAOTieQ8xdDOoC1djzpE7/AbMvuvlTavtUKT+F7tPdhfXgWXJV\n" + - "6Wbt8jryKyk3zZGiEhauIwZUkfjRkEtffEmZWLUd8c8rURJjfC/XHH2oyurscoxc\n" + - "CjX29c9ynxSiS/VvQp1an0HvErGh69N48wj7cj8mtZ1yHzd2XCzSSR1OfTPfk0Pt\n" + - "yg51p7yJaFiH21PTZegEL6zyVNOYBTKwwIi2OzpwYalD3uvK6e3OKDrfFCOxu17u\n" + - "4PveESbrdyrmvLe7IVez\n" + - "-----END CERTIFICATE-----"); - - // Subject: CN=JavaFX Runtime, - // OU=Java Signed Extensions, - // OU=Corporate Object Signing, - // O=Sun Microsystems Inc - // Issuer: CN=Object Signing CA, - // OU=Class 2 OnSite Subscriber CA, - // OU=VeriSign Trust Network, - // O=Sun Microsystems Inc - // Serial: 47:f4:55:f1:da:4a:5e:f9:e3:f7:a8:03:62:17:c0:ff - add("javafx-runtime-pretrusted-6217C0FF", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFdjCCBF6gAwIBAgIQR/RV8dpKXvnj96gDYhfA/zANBgkqhkiG9w0BAQUFADCB\n" + - "gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT\n" + - "aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj\n" + - "cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDEyOTAw\n" + - "MDAwMFoXDTEyMDEyOTIzNTk1OVowfDEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt\n" + - "cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE\n" + - "CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEXMBUGA1UEAxQOSmF2YUZYIFJ1bnRp\n" + - "bWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCIzd0fAk8mI9ONc6RJ\n" + - "aGieioK2FLdXEwj8zL3vdGDVmBwyR1zwYkaOIFFgF9IW/8qc4iAYA5sGUY+0g8q3\n" + - "5DuYAxfTzBB5KdaYvbuq6GGnoHIWmTirXY+1friFp8lyXSvtuEaGB1VHaBoZchEg\n" + - "k+UgeVDA43dHwcT1Ov3DePczJRUes8T/QHzLX+BxUDG43vjyncCEO/AjqLZxXEz2\n" + - "xrNbKLcH3lGMJK7hdbfssUfF5BjC38Hn71HauYlA43b2no+2y0Sjulwzez2YPbDC\n" + - "0GLR3TnKtA8dqOrnl5t3DniDbfOBNtBE3VOydJO0XW57Ng1HRXD023nm9ECPY2xp\n" + - "0N/pAgMBAAGjggHqMIIB5jAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDB/BgNV\n" + - "HR8EeDB2MHSgcqBwhm5odHRwOi8vb25zaXRlY3JsLnZlcmlzaWduLmNvbS9TdW5N\n" + - "aWNyb3N5c3RlbXNJbmNDb3Jwb3JhdGVPYmplY3RTaWduaW5nSmF2YVNpZ25lZEV4\n" + - "dGVuc2lvbnNDbGFzc0IvTGF0ZXN0Q1JMLmNybDAfBgNVHSMEGDAWgBSzRyuCflO0\n" + - "c8q4uxm3voFNB5XH7TAdBgNVHQ4EFgQUvOdd0cKPj+Yik/iOBwTdphh5A+gwOwYI\n" + - "KwYBBQUHAQEELzAtMCsGCCsGAQUFBzABhh9odHRwOi8vb25zaXRlLW9jc3AudmVy\n" + - "aXNpZ24uY29tMIG1BgNVHSAEga0wgaowOQYLYIZIAYb4RQEHFwIwKjAoBggrBgEF\n" + - "BQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTBtBgtghkgBhvcAg32c\n" + - "PzBeMCcGCCsGAQUFBwIBFhtodHRwczovL3d3dy5zdW4uY29tL3BraS9jcHMwMwYI\n" + - "KwYBBQUHAgIwJxolVmFsaWRhdGVkIEZvciBTdW4gQnVzaW5lc3MgT3BlcmF0aW9u\n" + - "czATBgNVHSUEDDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQUFAAOCAQEAbGcf2NjL\n" + - "AI93HG6ny2BbepaZA1a8xa/R6uUc7xV+Qw6MgLwFD4Q4i6LWUztQDvg9l68MM2/i\n" + - "Y9LEi1KM4lcNbK5+D+t9x98wXBiuojXhVdp5ZmC03EyEBbriopdBsmXVLDSu/Y3+\n" + - "zowOO5xwpMK3dbgsSDs2Vt0UosD3FTcRaD3GNfOhXMp+o1grHNiXF9YgkmdQbPPZ\n" + - "DQ2KBhFPCRJXBGvyKOqno/DTg0sQ3crGH/C4/4t7mnQXWldZotmJUZ0ONc9oD+Q1\n" + - "JAaguUKqIwn9yZ093ie+JWHbYNid9IIIPXYgtRxmf9a376WBhqhu56uJftBJ7x9g\n" + - "eQ7Lot6CSWCiFw==\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised Solaris INTERNAL DEVELOPMENT USE ONLY certificate - // - - // Subject: CN=Solaris INTERNAL DEVELOPMENT USE ONLY, - // OU=Solaris Cryptographic Framework, - // OU=Corporate Object Signing, - // O=Sun Microsystems Inc - // Issuer: CN=Object Signing CA, - // OU=Class 2 OnSite Subscriber CA, - // OU=VeriSign Trust Network, - // O=Sun Microsystems Inc - // Serial: 77:29:77:52:6a:19:7b:9a:a6:a2:c7:99:a0:e1:cd:8c - add("solaris-internal-dev-A0E1CD8C", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFHjCCBAagAwIBAgIQdyl3UmoZe5qmoseZoOHNjDANBgkqhkiG9w0BAQUFADCB\n" + - "gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT\n" + - "aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj\n" + - "cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA3MDEwNDAw\n" + - "MDAwMFoXDTEwMDEwMzIzNTk1OVowgZwxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl\n" + - "bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxKDAmBgNV\n" + - "BAsUH1NvbGFyaXMgQ3J5cHRvZ3JhcGhpYyBGcmFtZXdvcmsxLjAsBgNVBAMUJVNv\n" + - "bGFyaXMgSU5URVJOQUwgREVWRUxPUE1FTlQgVVNFIE9OTFkwgZ8wDQYJKoZIhvcN\n" + - "AQEBBQADgY0AMIGJAoGBALbNU4hf3mD5ArDI9pjgioAyvV3bjMPRQdCZniIeGJBp\n" + - "odFlSEH+Mh64W1DsY8coeZ7FvvGJkx9IpTMJW9k8w1oJK9UNqHyAQfaYjQyXi3xQ\n" + - "LJp62EvYdGfDlwOZejEcR/MbzZG+GOPMMvQj5+xyFDvLXNGfQNTnxw2qnBgCJXjj\n" + - "AgMBAAGjggH1MIIB8TAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDCBiQYDVR0f\n" + - "BIGBMH8wfaB7oHmGd2h0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29tL1N1bk1p\n" + - "Y3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdTb2xhcmlzQ3J5cHRv\n" + - "Z3JhcGhpY0ZyYW1ld29ya0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaA\n" + - "FLNHK4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBRpfiGYkehTnsIzuN2H6AFb\n" + - "VCZG8jA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUt\n" + - "b2NzcC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAq\n" + - "MCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CG\n" + - "SAGG9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtp\n" + - "L2NwczAzBggrBgEFBQcCAjAnFiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBP\n" + - "cGVyYXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IB\n" + - "AQCG5soy3LFHTFbA8/5SzDRhQoJkHUnOP0t3b6nvX6vZYRp649fje7TQOPRm1pFd\n" + - "CZ17J+tggdZwgzTqY4aYpJ00jZaK6pV37q/vgFC/ia6jDs8Q+ly9cEcadBZ5loYg\n" + - "cmxp9p57W2MNWx8VA8oFdNtKfF0jUNXbLNtvwGHmgR6YcwLrGN1b6/9Lt9bO3ODl\n" + - "FO+ZDwkfQz5ClUVrTx2dGBvKRYFqSG5S8JAfsgYhPvcacUQkA7ExyKvfRXLWVrce\n" + - "ZiPpcElbx+819H2sAPvVvparVeAruZGMAtejHZp9NFoowKen5drJp9VxePS4eM49\n" + - "3DepB6lKRrNRw66LNQol4ZBz\n" + - "-----END CERTIFICATE-----"); - - - // ----------------------------------------------------------------- - // Compromised CAs of DigiNotar - // - // Reported by Fox-IT in its interim report on September 5, 2011, - // "DigiNotar Certificate Authority breach 'Operation Black Tulip'". - // - - // - // Compromised DigiNotar Cyber CA - // - - // DigiNotar intermediate, cross-signed by CyberTrust - // - // Subject: EMAILADDRESS=info@diginotar.nl, CN=DigiNotar Cyber CA, - // O=DigiNotar, C=NL - // Issuer: CN=GTE CyberTrust Global Root, - // OU=GTE CyberTrust Solutions, Inc., - // O=GTE Corporation, - // C=US - // Serial: 120000525 (07:27:10:0D) - add("info-at-diginotar-cyber-ca-cross-to-gte-cybertrust-0727100D", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFWjCCBMOgAwIBAgIEBycQDTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV\n" + - "UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU\n" + - "cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds\n" + - "b2JhbCBSb290MB4XDTA2MTAwNDEwNTQxMVoXDTExMTAwNDEwNTMxMVowYDELMAkG\n" + - "A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy\n" + - "IEN5YmVyIENBMSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIw\n" + - "DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANLOFQotqF6EZ639vu9Gx8i5z3P8\n" + - "9DS5+SxD52ATPXrjss87Z2yQrcC5P4RS8DVC3HTcKDu9UrSnrHJFF8bwieu0qiXy\n" + - "XUte0dmHutZ9fPXOMp8QM8WxSrtekTHC0OlBwpFkfglBO9uLCDdqqspS3rU5HsCI\n" + - "A6U/i5kTYUO1m4Kz7iBvz6FEouova0CfjytXraFTwoUiaZ2gP1HfC0GRDaXhqKpc\n" + - "SQhdvd5wQbEPyWNr0380dAIvNFp4dRxoeoFnivPaQPBgY/SSINcDpj2jHmfEhBtB\n" + - "pcmM5r3qSLYFFgizNxJa92E89zhvLpfgb1Y4VNMota0Ubi5LZLUnZbd1JQm2Bz2V\n" + - "VgIKgmCyc0XgMyZRdJq51FAc9k1bW1JSE1qmf6cO4ehBVGeYjIfVydNsy9NUkgYJ\n" + - "NEH3gW8/nsl8dVWw58Gzd+jDxAA1lUBwEEoF3iW7n1mlZLxHYL9g43aLE1Xd4XR6\n" + - "uc8kpmp/3mQiRFhogmoQ+T3lPhu5vfwi9GAEibtVbShV+t6OjRshFNc3izR7Tfay\n" + - "shDPM7F9HGKZSMsrbHaWVb8ZDR0fu2WqG46ZtcYokOWCLXhQIJr9eS8kf/CJKWn0\n" + - "fc1zvrPtTsHR7VJej/e4142HrbLZG1ES/1az4a80fVykeIgQnp0DxqWqoiRR90kU\n" + - "xbHuWUOV36toKDA/AgMBAAGjggGGMIIBgjASBgNVHRMBAf8ECDAGAQH/AgEBMFMG\n" + - "A1UdIARMMEowSAYJKwYBBAGxPgEAMDswOQYIKwYBBQUHAgEWLWh0dHA6Ly93d3cu\n" + - "cHVibGljLXRydXN0LmNvbS9DUFMvT21uaVJvb3QuaHRtbDAOBgNVHQ8BAf8EBAMC\n" + - "AQYwgaAGA1UdIwSBmDCBlYAUpgwdn2H/Bxe1vzhG20Mw1Y6wUgaheaR3MHUxCzAJ\n" + - "BgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdU\n" + - "RSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVy\n" + - "VHJ1c3QgR2xvYmFsIFJvb3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93\n" + - "d3cucHVibGljLXRydXN0LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYD\n" + - "VR0OBBYEFKv5aN/PSjfXe0WMX3LeQETDZbvCMA0GCSqGSIb3DQEBBQUAA4GBAI9o\n" + - "a6VbB7pEZg4cqFwwezPkCiYE/O+eGjjWLqEf0JlHwnVkJP2eOyh2uSYoYZEMbSz4\n" + - "BJ98UAHV42mv7xXSRZskCSpmBU8lgcpdvqrBWSeuM46C9990sFWzjvjnN8huqlZE\n" + - "9r1TgSOWPbT6MopTZkQloiXGpjwljPDgKAYityZB\n" + - "-----END CERTIFICATE-----"); - - // DigiNotar intermediate, cross-signed by CyberTrust - // - // Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL - // Issuer: CN=GTE CyberTrust Global Root, - // OU=GTE CyberTrust Solutions, Inc., - // O=GTE Corporation, - // C=US - // Serial: 120000505 (07:27:0F:F9) - add("diginotar-cyber-ca-cross-to-gte-cybertrust-07270FF9", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFODCCBKGgAwIBAgIEBycP+TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV\n" + - "UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU\n" + - "cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds\n" + - "b2JhbCBSb290MB4XDTA2MDkyMDA5NDUzMloXDTEzMDkyMDA5NDQwNlowPjELMAkG\n" + - "A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy\n" + - "IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o\n" + - "XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S\n" + - "tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7\n" + - "24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp\n" + - "naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj\n" + - "9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu\n" + - "LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU\n" + - "Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk\n" + - "vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6\n" + - "3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt\n" + - "eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4\n" + - "iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB\n" + - "/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC\n" + - "ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s\n" + - "MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV\n" + - "jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv\n" + - "bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD\n" + - "VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6\n" + - "oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw\n" + - "MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI\n" + - "hvcNAQEFBQADgYEACcpiD427SuDUejUrBi3RKGG2rAH7g0m8rtQvLYauGYOl1h0T\n" + - "4he+/jJ06XoUOMqUXvcpAWlxG5Ea/aO7qh3Ke+IW/aGjDvMMX7LhIDGUK16Sdu36\n" + - "6bUjpr8KOwOpb1JgVM1f6bcvfKIn/UGDdbYN+3gm87FF6TKVKho1IZXFonU=\n" + - "-----END CERTIFICATE-----"); - - // DigiNotar intermediate, cross-signed by CyberTrust - // - // Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL - // Issuer: CN=GTE CyberTrust Global Root, - // OU=GTE CyberTrust Solutions, Inc., - // O=GTE Corporation, - // C=US - // Serial: 120000515 (07:27:10:03) - add("diginotar-cyber-ca-cross-to-gte-cybertrust-07271003", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFODCCBKGgAwIBAgIEBycQAzANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV\n" + - "UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU\n" + - "cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds\n" + - "b2JhbCBSb290MB4XDTA2MDkyNzEwNTMzMloXDTExMDkyNzEwNTIzMFowPjELMAkG\n" + - "A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy\n" + - "IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o\n" + - "XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S\n" + - "tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7\n" + - "24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp\n" + - "naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj\n" + - "9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu\n" + - "LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU\n" + - "Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk\n" + - "vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6\n" + - "3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt\n" + - "eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4\n" + - "iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB\n" + - "/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC\n" + - "ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s\n" + - "MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV\n" + - "jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv\n" + - "bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD\n" + - "VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6\n" + - "oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw\n" + - "MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI\n" + - "hvcNAQEFBQADgYEAWcyGZhizJlRP1jjNupZey+yZG6oMDW4Z11boriMHbYPCndBE\n" + - "bVh07zmPbZsihOw9w/vm5KbVX5CgxUv4Rhzh/20Faixf3P3bpWg0qgzHVVusNVR/\n" + - "P50aKkpdK3hp+QLl56e+lWOddSAINIpmcuyDI1hyuzB+GJEASm9tNU/6rs8=\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised DigiNotar Root CA - // - - // DigiNotar intermediate, cross-signed by Entrust - // - // Subject: EMAILADDRESS=info@diginotar.nl, - // CN=DigiNotar Root CA, - // O=DigiNotar, C=NL - // Issuer: CN=Entrust.net Secure Server Certification Authority - // OU=(c) 1999 Entrust.net Limited, - // OU=www.entrust.net/CPS incorp. by ref. (limits liab.), - // O=Entrust.net, - // C=US, - // Serial: 1184644297 (46:9C:3C:C9) - add("info-at-diginotar-root-ca-cross-to-entrust-secure-server-469C3CC9", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFSDCCBLGgAwIBAgIERpw8yTANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" + - "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" + - "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" + - "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" + - "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA0\n" + - "MjYwNTAwMDBaFw0xMzA4MTQyMDEyMzZaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK\n" + - "EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI\n" + - "hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP\n" + - "ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt\n" + - "OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx\n" + - "hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7\n" + - "gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D\n" + - "IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T\n" + - "BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs\n" + - "Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8\n" + - "5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf\n" + - "DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX\n" + - "9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e\n" + - "7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj\n" + - "ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB\n" + - "BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF\n" + - "BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD\n" + - "VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy\n" + - "bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G\n" + - "A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob\n" + - "BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAI979rBep8tu3TeLunapgsZ0jtXp\n" + - "GDFjKWSk87dj1jCyYi+q/GyDyZ6ZQZNRP0sF+6twscq05lClWNy3TROMp7QeuoLO\n" + - "G7Utw3OJaswUtp4YglANMRTHEe3g9ltifUXRH5tSuy7u6yi4LD4WTm5ULP6r/g6l\n" + - "0CnjXYb0+b1Fmz6U\n" + - "-----END CERTIFICATE-----"); - - // DigiNotar intermediate, cross-signed by Entrust - // - // Subject: EMAILADDRESS=info@diginotar.nl, - // CN=DigiNotar Root CA, - // O=DigiNotar, C=NL - // Issuer: CN=Entrust.net Secure Server Certification Authority - // OU=(c) 1999 Entrust.net Limited, - // OU=www.entrust.net/CPS incorp. by ref. (limits liab.), - // O=Entrust.net, - // C=US, - // Serial: 1184640175 (46:9C:2C:AF) - add("info-at-diginotar-root-ca-cross-to-entrust-secure-server-469C2CAF", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFSDCCBLGgAwIBAgIERpwsrzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" + - "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" + - "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" + - "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" + - "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3\n" + - "MjYxNTU3MzlaFw0xMzA4MjYxNjI3MzlaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK\n" + - "EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI\n" + - "hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP\n" + - "ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt\n" + - "OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx\n" + - "hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7\n" + - "gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D\n" + - "IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T\n" + - "BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs\n" + - "Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8\n" + - "5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf\n" + - "DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX\n" + - "9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e\n" + - "7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj\n" + - "ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB\n" + - "BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF\n" + - "BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD\n" + - "VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy\n" + - "bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G\n" + - "A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob\n" + - "BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAEa6RcDNcEIGUlkDJUY/pWTds4zh\n" + - "xbVkp3wSmpwPFhx5fxTyF4HD2L60jl3aqjTB7gPpsL2Pk5QZlNsi3t4UkCV70UOd\n" + - "ueJRN3o/LOtk4+bjXY2lC0qTHbN80VMLqPjmaf9ghSA9hwhskdtMgRsgfd90q5QP\n" + - "ZFdYf+hthc3m6IcJ\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised DigiNotar PKIoverheid CA Organisatie - G2 - // - - // DigiNotar intermediate, cross-signed by the Dutch government - // - // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2, - // O=DigiNotar B.V., - // C=NL - // Issuer: CN=Staat der Nederlanden Organisatie CA - G2, - // O=Staat der Nederlanden, - // C=NL - // Serial: 20001983 (01:31:34:bf) - add("diginotar-pkioverheid-organisatie-cross-to-nederlanden-013134BF", - "-----BEGIN CERTIFICATE-----\n" + - "MIIGnDCCBISgAwIBAgIEATE0vzANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJO\n" + - "TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMTIwMAYDVQQDDClTdGFh\n" + - "dCBkZXIgTmVkZXJsYW5kZW4gT3JnYW5pc2F0aWUgQ0EgLSBHMjAeFw0xMDA1MTIw\n" + - "ODUxMzhaFw0yMDAzMjMwOTUwMDRaMFoxCzAJBgNVBAYTAk5MMRcwFQYDVQQKDA5E\n" + - "aWdpTm90YXIgQi5WLjEyMDAGA1UEAwwpRGlnaU5vdGFyIFBLSW92ZXJoZWlkIENB\n" + - "IE9yZ2FuaXNhdGllIC0gRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\n" + - "AQCxExkPJ+Zs1FWGS9DsiYpFkXisR71HK+T8RetPtCZzWzfTw3/2497Xo/gtaMUI\n" + - "PkuU1uSHJTZrhLUYdPMoWHMvm2rPvAQe9t7dr/xLqvXbZmIlASWC3vKXWhBu3V2p\n" + - "IrEEqSNzOvhxrR3PhETrR9Gvbch8KKvH8jd6dF9fxQIUiqNa4xtsAeNdjtlo1vQJ\n" + - "GzLckbUs9SDrjANtJkm4k8SFXdjSm69WaswFM8ygQp40VUSca6DUEtArVM23iQ3l\n" + - "9uvo+4UBM096a/GdcjOWDveyhKWlJ8Qn8VFzKXe6Z27+TNy04qGhgS85SY1DOBPO\n" + - "0KVcwoc6AGdlQiPxNlkKHaNRyLyjlCox3+M88p0aPASw77EKMBNzttfzo0wBdRSF\n" + - "eMDXijlYhVD6LubFvs+LP6+PNtQlCS3SD6xyk/K/i9RQs/kVUJuZ9RTZ+4uRozIm\n" + - "JqD43ztggYaDeVsr6xM9KTrBbd29no6H1kquNJcF7hSm9tw4fkrpJFQHPZdoN0Zr\n" + - "DceoIa8TVOQJavFNRgrJXfubT73e+7dUy7g4nKc5+2otwHuNq6WnV+xKkoozxeEg\n" + - "XHPYkJIrgNUPhhhpfDlPhIa890xb89W0yqDC8DciynlSH1PmqvOQsDvd8ij9rOvF\n" + - "BiSgydQvD1j9tZ7sD8+yWdCiBHo4aq5y+73wJWKUCacFCwIDAQABo4IBYTCCAV0w\n" + - "SAYDVR0gBEEwPzA9BgRVHSAAMDUwMwYIKwYBBQUHAgEWJ2h0dHA6Ly93d3cuZGln\n" + - "aW5vdGFyLm5sL2Nwcy9wa2lvdmVyaGVpZDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud\n" + - "DwEB/wQEAwIBBjCBhQYDVR0jBH4wfIAUORCLSZJc22ESIM1JnRqO2pxnQLmhXqRc\n" + - "MFoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4x\n" + - "KzApBgNVBAMMIlN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENBIC0gRzKCBACY\n" + - "lvQwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NybC5wa2lvdmVyaGVpZC5ubC9E\n" + - "b21PcmdhbmlzYXRpZUxhdGVzdENSTC1HMi5jcmwwHQYDVR0OBBYEFLxdlDvZq3sD\n" + - "JXNhwtst7vyrj2WhMA0GCSqGSIb3DQEBCwUAA4ICAQCP/C1Mt9kt1R+978v0t2gX\n" + - "dZ1O1ffdnPEqJu2forYcA9VTs+wIzzTi48P0tRYvyMO+19NzqwA2+RpKftZj6V5G\n" + - "uqW2jhW3oyrYQx3vXcgfgYWzi/f/PPTZ9EYIP5y8HaDZqEzNJVJOCrEg9x/pQ9lU\n" + - "RoETmsBedGwqmDLq/He7DaWiMZgifnx859qkrey3LhoZcfhIUNpDjyyE3cFAJ+O1\n" + - "8BVOltT4XOOGKUYr1zsH6zh/yIZXl9PvKjPEF1DVZGlrK2tFXl0vF8paTs/D1zk8\n" + - "9TufRrmb5w5Jl53W1eMbD+qPAU6aE5RZCgIHSEsaYKt/T+0L2FUNaG9VnGllFULs\n" + - "wNzdbKzDFs4LHVabpMTE0i7gD+JEJytQaaTcYuiKISlCbMwAOpZ2m+9AwKRed4Qy\n" + - "bCYqOWauXeO5ubIsaB8empADOfCqs6TMSYsYNOk3yXspx4R8b0QVL+xhWQTJRcui\n" + - "1lKifH8pktZKxYtCqNT+6tjHhyMY5J16fXNAUpigrm7jBT8FD+Clxm1N7YM3iJzH\n" + - "89xCmmq21yFJNnfy7xhPxXDZnunetyuL9Lx+KN8NQMmFXK6dxTH/0FwOtah+8Okv\n" + - "uq+IruW10Vilr5xxpykBkINpN4IFuvwJwQhujHg7wzMCgD9EhQgd31VWCK0shS1d\n" + - "sQPhrqp0xaTzTro3mHuCuQ==\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised DigiNotar PKIoverheid CA Overheid en Bedrijven - // - - // DigiNotar intermediate, cross-signed by the Dutch government - // - // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven, - // O=DigiNotar B.V., - // C=NL - // Issuer: CN=Staat der Nederlanden Overheid CA - // O=Staat der Nederlanden, - // C=NL - // Serial: 20015536 (01:31:69:b0) - add("diginotar-pkioverheid-overheid-enb-cross-to-nederlanden-013169B0", - "-----BEGIN CERTIFICATE-----\n" + - "MIIEiDCCA3CgAwIBAgIEATFpsDANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO\n" + - "TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh\n" + - "dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDcwNzA1MDg0MjA3WhcN\n" + - "MTUwNzI3MDgzOTQ2WjBfMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy\n" + - "IEIuVi4xNzA1BgNVBAMTLkRpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp\n" + - "ZCBlbiBCZWRyaWp2ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDc\n" + - "vdKnTmoKuzuiheF/AK2+tDBomAfNoHrElM9x+Yo35FPrV3bMi+Zs/u6HVcg+uwQ5\n" + - "AKeAeKxbT370vbhUuHE7BzFJOZNUfCA7eSuPu2GQfbGs5h+QLp1FAalkLU3DL7nn\n" + - "UNVOKlyrdnY3Rtd57EKZ96LspIlw3Dgrh6aqJOadkiQbvvb91C8ZF3rmMgeUVAVT\n" + - "Q+lsvK9Hy7zL/b07RBKB8WtLu+20z6slTxjSzAL8o0+1QjPLWc0J3NNQ/aB2jKx+\n" + - "ZopC9q0ckvO2+xRG603XLzDgbe5bNr5EdLcgBVeFTegAGaL2DOauocBC36esgl3H\n" + - "aLcY5olLmmv6znn58yynAgMBAAGjggFQMIIBTDBIBgNVHSAEQTA/MD0GBFUdIAAw\n" + - "NTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5kaWdpbm90YXIubmwvY3BzL3BraW92\n" + - "ZXJoZWlkMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMIGABgNVHSME\n" + - "eTB3gBQLhtYPd6NosftkCcOIblwEHFfpPaFZpFcwVTELMAkGA1UEBhMCTkwxHjAc\n" + - "BgNVBAoTFVN0YWF0IGRlciBOZWRlcmxhbmRlbjEmMCQGA1UEAxMdU3RhYXQgZGVy\n" + - "IE5lZGVybGFuZGVuIFJvb3QgQ0GCBACYmnkwPQYDVR0fBDYwNDAyoDCgLoYsaHR0\n" + - "cDovL2NybC5wa2lvdmVyaGVpZC5ubC9Eb21PdkxhdGVzdENSTC5jcmwwHQYDVR0O\n" + - "BBYEFEwIyY128ZjHPt881y91DbF2eZfMMA0GCSqGSIb3DQEBBQUAA4IBAQAMlIca\n" + - "v03jheLu19hjeQ5Q38aEW9K72fUxCho1l3TfFPoqDz7toOMI9tVOW6+mriXiRWsi\n" + - "D7dUKH6S3o0UbNEc5W50BJy37zRERd/Jgx0ZH8Apad+J1T/CsFNt5U4X5HNhIxMm\n" + - "cUP9TFnLw98iqiEr2b+VERqKpOKrp11Lbyn1UtHk0hWxi/7wA8+nfemZhzizDXMU\n" + - "5HIs4c71rQZIZPrTKbmi2Lv01QulQERDjqC/zlqlUkxk0xcxYczopIro5Ij76eUv\n" + - "BjMzm5RmZrGrUDqhCYF0U1onuabSJc/Tw6f/ltAv6uAejVLpGBwgCkegllYOQJBR\n" + - "RKwa/fHuhR/3Qlpl\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised DigiNotar PKIoverheid CA Overheid - // - - // DigiNotar intermediate, cross-signed by the Dutch government - // - // Subject: CN=DigiNotar PKIoverheid CA Overheid - // O=DigiNotar B.V., - // C=NL - // Issuer: CN=Staat der Nederlanden Overheid CA - // O=Staat der Nederlanden, - // C=NL - // Serial: 20006006 (01:31:44:76) - add("diginotar-pkioverheid-overheid-cross-to-nederlanden-01314476", - "-----BEGIN CERTIFICATE-----\n" + - "MIIEezCCA2OgAwIBAgIEATFEdjANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO\n" + - "TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh\n" + - "dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDQwNjI0MDgxOTMyWhcN\n" + - "MTAwNjIzMDgxNzM2WjBSMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy\n" + - "IEIuVi4xKjAoBgNVBAMTIURpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp\n" + - "ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANSlrubta5tlOjVCi/gb\n" + - "yLCvRqfBjxG8H594VcKHu0WAYc99SPZF9cycj5mw2GyfQvy/WIrGrL4iyNq1gSqR\n" + - "0QA/mTXKZIaPqzpDhdm+VvrKkmjrbZfaQxgMSs3ChtBsjcP9Lc0X1zXZ4Q8nBe3k\n" + - "BTp+zehINfmbjoEgXLxsMR5RQ6GxzKjuC04PQpbJQgTIakglKaqYcDDZbEscWgPV\n" + - "Hgj/2aoHlj6leW/ThHZ+O41jUguEmBLZA3mu3HrCfrHntb5dPt0ihzSx7GtD/SaX\n" + - "5HBLxnP189YuqMk5iRA95CtiSdKauvon/xRKRLNgG6XAz0ctSoY7xLDdiBVU5kJd\n" + - "FScCAwEAAaOCAVAwggFMMEgGA1UdIARBMD8wPQYEVR0gADA1MDMGCCsGAQUFBwIB\n" + - "FidodHRwOi8vd3d3LmRpZ2lub3Rhci5ubC9jcHMvcGtpb3ZlcmhlaWQwDwYDVR0T\n" + - "AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgYAGA1UdIwR5MHeAFAuG1g93o2ix\n" + - "+2QJw4huXAQcV+k9oVmkVzBVMQswCQYDVQQGEwJOTDEeMBwGA1UEChMVU3RhYXQg\n" + - "ZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g\n" + - "Um9vdCBDQYIEAJiaeTA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnBraW92\n" + - "ZXJoZWlkLm5sL0RvbU92TGF0ZXN0Q1JMLmNybDAdBgNVHQ4EFgQUvRaYQh2+kdE9\n" + - "wpcl4CjXWOC1f+IwDQYJKoZIhvcNAQEFBQADggEBAGhQsCWLiaN2EOhPAW+JQP6o\n" + - "XBOrLv5w6joahzBFVn1BiefzmlMKjibqKYxURRvMAsMkh82/MfL8V0w6ugxl81lu\n" + - "i42dcxl9cKSVXKMw4bbBzJ2VQI5HTIABwefeNuy/eX6idVwYdt3ajAH7fUA8Q9Cq\n" + - "vr6H8B+8mwoEqTVTEVlCSsC/EXsokYEUr06PPzRudKjDmijgj7zFaIioZNc8hk7g\n" + - "ufEgrs/tmcNGylrwRHgCXjCRBt2NHlZ08l7A1AGU8HcHlSbG9Un/2q9kVHUkps0D\n" + - "gtUaEK+x6jpAu/R8Ojezu/+ZEcwwjI/KOhG+84+ejFmtyEkrUdsAdEdLf/2dKsw=\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised DigiNotar Services 1024 CA - // - - // DigiNotar intermediate, cross-signed by the Entrust - // - // Subject: EMAILADDRESS=info@diginotar.nl, - // CN=DigiNotar Services 1024 CA - // O=DigiNotar, C=NL - // Issuer: CN=Entrust.net Secure Server Certification Authority, - // OU=(c) 1999 Entrust.net Limited, - // OU=www.entrust.net/CPS incorp. by ref. (limits liab.), - // O=Entrust.net, - // C=US - // Serial: 1184640176 (46:9c:2c:b0) - add("diginotar-services-1024-ca-cross-to-entrust-469C2CB0", - "-----BEGIN CERTIFICATE-----\n" + - "MIIDzTCCAzagAwIBAgIERpwssDANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" + - "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" + - "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" + - "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" + - "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3\n" + - "MjYxNTU5MDBaFw0xMzA4MjYxNjI5MDBaMGgxCzAJBgNVBAYTAk5MMRIwEAYDVQQK\n" + - "EwlEaWdpTm90YXIxIzAhBgNVBAMTGkRpZ2lOb3RhciBTZXJ2aWNlcyAxMDI0IENB\n" + - "MSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCBnzANBgkqhkiG9w0B\n" + - "AQEFAAOBjQAwgYkCgYEA2ptNXTz50eKLxsYIIMXZHkjsZlhneWIrQWP0iY1o2q+4\n" + - "lDaLGSSkoJPSmQ+yrS01Tc0vauH5mxkrvAQafi09UmTN8T5nD4ku6PJPrqYIoYX+\n" + - "oakJ5sarPkP8r3oDkdqmOaZh7phPGKjTs69mgumfvN1y+QYEvRLZGCTnq5NTi1kC\n" + - "AwEAAaOCASYwggEiMBIGA1UdEwEB/wQIMAYBAf8CAQAwJwYDVR0lBCAwHgYIKwYB\n" + - "BQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDBDARBgNVHSAECjAIMAYGBFUdIAAwMwYI\n" + - "KwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5l\n" + - "dDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1c3QubmV0L3NlcnZl\n" + - "cjEuY3JsMB0GA1UdDgQWBBT+3JRJDG/vXH/G8RKZTxZJrfuCZTALBgNVHQ8EBAMC\n" + - "AQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0BowGQYJKoZIhvZ9B0EA\n" + - "BAwwChsEVjcuMQMCAIEwDQYJKoZIhvcNAQEFBQADgYEAY3RqN6k/lpxmyFisCcnv\n" + - "9WWUf6MCxDgxvV0jh+zUVrLJsm7kBQb87PX6iHBZ1O7m3bV6oKNgLwIMq94SXa/w\n" + - "NUuqikeRGvWFLELHHe+VQ7NeuJWTpdrFKKqtci0xrZlrbP+MISevrZqRK8fdWMNu\n" + - "B8WfedLHjFW/TMcnXlEWKz4=\n" + - "-----END CERTIFICATE-----"); - - // - // Revoked DigiCert code signing certificates used to sign malware - // - - // Subject: CN=Buster Paper Comercial Ltda, - // O=Buster Paper Comercial Ltda, - // L=S?o Jos? Dos Campos, - // ST=S?o Paulo, - // C=BR - // Issuer: CN=DigiCert Assured ID Code Signing CA-1, - // OU=www.digicert.com, - // O=DigiCert Inc, - // C=US - // Serial: 07:b4:4c:db:ff:fb:78:de:05:f4:26:16:72:a6:73:12 - add("buster-paper-comercial-ltda-72A67312", - "-----BEGIN CERTIFICATE-----\n" + - "MIIGwzCCBaugAwIBAgIQB7RM2//7eN4F9CYWcqZzEjANBgkqhkiG9w0BAQUFADBv\n" + - "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" + - "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" + - "ZGUgU2lnbmluZyBDQS0xMB4XDTEzMDExNzAwMDAwMFoXDTE0MDEyMjEyMDAwMFow\n" + - "gY4xCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMR4wHAYDVQQHDBVT\n" + - "w6NvIEpvc8OpIERvcyBDYW1wb3MxJDAiBgNVBAoTG0J1c3RlciBQYXBlciBDb21l\n" + - "cmNpYWwgTHRkYTEkMCIGA1UEAxMbQnVzdGVyIFBhcGVyIENvbWVyY2lhbCBMdGRh\n" + - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzO0l6jWIpEfO2oUpVHpL\n" + - "HETj5lzivNb0S9jKHgGJax917czh81PnGTxwxFXd6gLJuy/XFHvmiSi8g8jzlymn\n" + - "2Ji5zQ3CPaz7nomJokSUDlMVJ2qYWtctw4jrdjuI4qtn+koXXUFkWjkf8h8251I4\n" + - "tUs7S49HE2Go5owCYP3byajj7fsFAYR/Xb7TdVtndkZsUB/YgOjHovyACjouaNCi\n" + - "mDiRyQ6zLLjZGiyeD65Yiseuhp5b8/BL5h1p7w76QYMYMVQNAdtDKut2R8MBpuWf\n" + - "Ny7Eoi0x/gm1p9X5Rcl5aN7K0G4UtTAJKbkuUfXddsyFoM0Nx8uo8SgNQ8Y/X5Jx\n" + - "BwIDAQABo4IDOTCCAzUwHwYDVR0jBBgwFoAUe2jOKarAF75JeuHlP9an90WPNTIw\n" + - "HQYDVR0OBBYEFFLZ3n5nt/Eer7n1bvtOqMb1qKO5MA4GA1UdDwEB/wQEAwIHgDAT\n" + - "BgNVHSUEDDAKBggrBgEFBQcDAzBzBgNVHR8EbDBqMDOgMaAvhi1odHRwOi8vY3Js\n" + - "My5kaWdpY2VydC5jb20vYXNzdXJlZC1jcy0yMDExYS5jcmwwM6AxoC+GLWh0dHA6\n" + - "Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9hc3N1cmVkLWNzLTIwMTFhLmNybDCCAcQGA1Ud\n" + - "IASCAbswggG3MIIBswYJYIZIAYb9bAMBMIIBpDA6BggrBgEFBQcCARYuaHR0cDov\n" + - "L3d3dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsG\n" + - "AQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABD\n" + - "AGUAcgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABh\n" + - "AGMAYwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQBy\n" + - "AHQAIABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBn\n" + - "ACAAUABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABs\n" + - "AGkAbQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABp\n" + - "AG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBl\n" + - "AGYAZQByAGUAbgBjAGUALjCBggYIKwYBBQUHAQEEdjB0MCQGCCsGAQUFBzABhhho\n" + - "dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTAYIKwYBBQUHMAKGQGh0dHA6Ly9jYWNl\n" + - "cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENvZGVTaWduaW5nQ0Et\n" + - "MS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAPTTQvpOIikXI\n" + - "hTLnNbajaFRR5GhQpTzUNgBfF9VYSlNw/wMjpGsrh5RxaJCip52jbehmTgjMRhft\n" + - "jRYyml44PAVsCcR9uEoDpCZYpI1fHI1R+F8jd1C9rqprbSwwOG4xlg4SmvTHYs6e\n" + - "gBItQ/1p9XY+Sf4Wv1qOuOFL1qvV/5VyR2zdlOQCmKCeMgxt6a/tHLBDiAA67D44\n" + - "/vfdoNJl0CU2It0PO60jdCPFNWIRcxL+OSDqAoePeUC7xQ+JsTEIxuUE8+d6w6fc\n" + - "BV2mYb1flh22t46GLjh4gyo7xw3aL6L0L0jzlTT6IcEw6NIbaPbIKj/npQnHobYj\n" + - "XMuKLxbh7g==\n" + - "-----END CERTIFICATE-----"); - - // Subject: CN=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, - // O=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, - // L=S?o Paulo, - // ST=S?o Paulo, - // C=BR - // Issuer: CN=DigiCert Assured ID Code Signing CA-1, - // OU=www.digicert.com, - // O=DigiCert Inc, - // C=US - // Serial: 0a:38:9b:95:ee:73:6d:d1:3b:c0:ed:74:3f:d7:4d:2f - add("buster-assistencia-tecnica-electronica-ltda-3FD74D2F", - "-----BEGIN CERTIFICATE-----\n" + - "MIIG4DCCBcigAwIBAgIQCjible5zbdE7wO10P9dNLzANBgkqhkiG9w0BAQUFADBv\n" + - "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" + - "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" + - "ZGUgU2lnbmluZyBDQS0xMB4XDTEyMTEwOTAwMDAwMFoXDTEzMTExNDEyMDAwMFow\n" + - "gasxCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMRMwEQYDVQQHDApT\n" + - "w6NvIFBhdWxvMTgwNgYDVQQKEy9CVVNURVIgQVNTSVNURU5DSUEgVEVDTklDQSBF\n" + - "TEVUUk9OSUNBIExUREEgLSBNRTE4MDYGA1UEAxMvQlVTVEVSIEFTU0lTVEVOQ0lB\n" + - "IFRFQ05JQ0EgRUxFVFJPTklDQSBMVERBIC0gTUUwggEiMA0GCSqGSIb3DQEBAQUA\n" + - "A4IBDwAwggEKAoIBAQDAqNeEs5/B2CTXGjTOkUIdu6jV6qulOZwdw4sefHWYj1UR\n" + - "4z6zPk9kjpUgbnb402RFq88QtfInwddZ/wXn9OxMtDd/3TnC7HrhNS7ga79ZFL2V\n" + - "JnmzKHum2Yvh0q82QEJ9tHBR2X9VdKpUIH08Zs3k6cWWM1H0YX0cxA/HohhesQJW\n" + - "kwJ3urOIJiH/HeByDk8a1NS8safcCxk5vxvW4WvCg43iT09LeHY5Aa8abKw8lqVb\n" + - "0tD5ZSIjdmdj3TT1U37iAHLLRM2DXbxfdbhouUX1c5U1ZHAMA67HwjKiseOiDaHj\n" + - "NUGbC37C+cgbc9VVM/cURD8WvS0Kj6fQv7F2QtJDAgMBAAGjggM5MIIDNTAfBgNV\n" + - "HSMEGDAWgBR7aM4pqsAXvkl64eU/1qf3RY81MjAdBgNVHQ4EFgQU88EXKAyDsh30\n" + - "o9+Gu9a4xUy+FSMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD\n" + - "MHMGA1UdHwRsMGowM6AxoC+GLWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9hc3N1\n" + - "cmVkLWNzLTIwMTFhLmNybDAzoDGgL4YtaHR0cDovL2NybDQuZGlnaWNlcnQuY29t\n" + - "L2Fzc3VyZWQtY3MtMjAxMWEuY3JsMIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgB\n" + - "hv1sAwEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9z\n" + - "c2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4A\n" + - "eQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQA\n" + - "ZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUA\n" + - "IABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAA\n" + - "YQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcA\n" + - "cgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIA\n" + - "aQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQA\n" + - "ZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMIGC\n" + - "BggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0\n" + - "LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp\n" + - "Z2lDZXJ0QXNzdXJlZElEQ29kZVNpZ25pbmdDQS0xLmNydDAMBgNVHRMBAf8EAjAA\n" + - "MA0GCSqGSIb3DQEBBQUAA4IBAQAei1QmiXepje8OIfo/WonD4MIXgpPr2dfRaquQ\n" + - "A8q63OpTRSveyqdQDCSPpDRF/nvO1Y30yksZvIH1tNBsW5LBdxAKN3lFdBlqBwtE\n" + - "Q3jHc0KVVYRJ0FBaGE/PJHmRajscdAhYIcMPhTga0u0tDK+wOHEq3993dfl6yHjA\n" + - "XHU2iW5pnk75ZoE39zALD5eKXT8ZXrET5c3XUFJKWA+XuGmdmyzqo0Au49PanBv9\n" + - "UlZnabYfqoMArqMS0tGSX4cGgi9/2E+pHG9BX4sFW+ZDumroOA2pxyMWEKjxePEL\n" + - "zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" + - "-----END CERTIFICATE-----"); - - // - // Revoked code signing certificate w/ a stolen key issued by GoDaddy - // used to sign malware - // - - // Subject: CN=CLEARESULT CONSULTING INC., OU=Corporate IT, - // O=CLEARESULT CONSULTING INC., L=Austin, ST=TX, C=US - // Issuer: SERIALNUMBER=07969287, - // CN=Go Daddy Secure Certification Authority, - // OU=http://certificates.godaddy.com/repository, - // O="GoDaddy.com, Inc.", - // L=Scottsdale, - // ST=Arizona, - // C=US - // Serial: 2b:73:43:2a:a8:4f:44 - add("clearesult-consulting-inc-2AA84F44", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFYjCCBEqgAwIBAgIHK3NDKqhPRDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE\n" + - "BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY\n" + - "BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm\n" + - "aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5\n" + - "IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky\n" + - "ODcwHhcNMTIwMjE1MjEwOTA2WhcNMTQwMjE1MjEwOTA2WjCBjDELMAkGA1UEBgwC\n" + - "VVMxCzAJBgNVBAgMAlRYMQ8wDQYDVQQHDAZBdXN0aW4xIzAhBgNVBAoMGkNMRUFS\n" + - "RVNVTFQgQ09OU1VMVElORyBJTkMuMRUwEwYDVQQLDAxDb3Jwb3JhdGUgSVQxIzAh\n" + - "BgNVBAMMGkNMRUFSRVNVTFQgQ09OU1VMVElORyBJTkMuMIIBIjANBgkqhkiG9w0B\n" + - "AQEFAAOCAQ8AMIIBCgKCAQEAtIOjCKeAicull+7ZIzt0/4ya3IeXUFlfypqKMLkU\n" + - "IbKjn0P5uMj6VE3rlbZr44RCegxvdnR6umBh1c0ZXoN3o+yc0JKcKcLiApmJJ277\n" + - "p7IbLwYDhBXRQNoIJm187IOMRPIxsKN4hL91txn9jGBmW+9zKlJlNhR5R7vjwU2E\n" + - "jrH/6oqsc9EM2yYpfjlNv6+3jSwAYZCkSWr+27PQOV+YHKmIxtJjX0upFz5FdIrV\n" + - "9CCX+L2Kji1THOkSgG4QTbYxmEcHqGViWz8hXLeNXjcbEsPuIiAu3hknxRHfUTE/\n" + - "U0Lh0Ug1e3LrJu+WnxM2SmUY4krsZ22c0yWUW9hzWITIjQIDAQABo4IBhzCCAYMw\n" + - "DwYDVR0TAQH/BAUwAwEBADATBgNVHSUEDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8E\n" + - "BAMCB4AwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9n\n" + - "ZHM1LTE2LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcCMDkwNwYIKwYBBQUH\n" + - "AgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8w\n" + - "gYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRk\n" + - "eS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHku\n" + - "Y29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9\n" + - "rGEyk2xF1uLuhV+auud2mWjM5zAdBgNVHQ4EFgQUDtdeKqeN2QkcbEp1HovFieNB\n" + - "XiowDQYJKoZIhvcNAQEFBQADggEBAD74Agw5tvi2aBl4/f/s7/VE/BClzDsKMb9K\n" + - "v9qpeC45ZA/jelxV11HKbQnVF194gDb7D2H9OsAsRUy8HVKbXEcc/8dKvwOqb+BC\n" + - "2i/EmfjLgmCfezNFtLq8xcPxF3zIRc44vPrK0z4YZsaHdH+yTEJ51p5EMdTqaLaP\n" + - "4n5m8LX3RfqlQB9dYFe6dUoYZjKm9d/pIRww3VqfOzjl42Edi1w6dWmBVMx1NZuR\n" + - "DBabJH1vJ9Gd+KwxMCmBZ6pQPl28JDimhJhI2LNqU349uADQVV0HJosddN/ARyyI\n" + - "LSIQO7BnNVKVG9Iujf33bvPNeg0qNz5qw+rKKq97Pqeum+L5oKU=\n" + - "-----END CERTIFICATE-----"); - } + private UntrustedCertificates() {} } diff --git a/jdk/src/share/classes/sun/security/x509/X509CertImpl.java b/jdk/src/share/classes/sun/security/x509/X509CertImpl.java index bd59b62811a..b96674e2e1d 100644 --- a/jdk/src/share/classes/sun/security/x509/X509CertImpl.java +++ b/jdk/src/share/classes/sun/security/x509/X509CertImpl.java @@ -37,6 +37,7 @@ import java.security.*; import java.security.cert.*; import java.security.cert.Certificate; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import javax.security.auth.x500.X500Principal; @@ -1913,4 +1914,45 @@ public class X509CertImpl extends X509Certificate implements DerEncoder { } return false; } + + private ConcurrentHashMap fingerprints = + new ConcurrentHashMap<>(2); + + public String getFingerprint(String algorithm) { + return fingerprints.computeIfAbsent(algorithm, + x -> getCertificateFingerPrint(x)); + } + + /** + * Gets the requested finger print of the certificate. The result + * only contains 0-9 and A-F. No small case, no colon. + */ + private String getCertificateFingerPrint(String mdAlg) { + String fingerPrint = ""; + try { + byte[] encCertInfo = getEncoded(); + MessageDigest md = MessageDigest.getInstance(mdAlg); + byte[] digest = md.digest(encCertInfo); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < digest.length; i++) { + byte2hex(digest[i], buf); + } + fingerPrint = buf.toString(); + } catch (NoSuchAlgorithmException | CertificateEncodingException e) { + // ignored + } + return fingerPrint; + } + + /** + * Converts a byte to hex digit and writes to the supplied buffer + */ + private static void byte2hex(byte b, StringBuffer buf) { + char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + int high = ((b & 0xf0) >> 4); + int low = (b & 0x0f); + buf.append(hexChars[high]); + buf.append(hexChars[low]); + } } diff --git a/jdk/src/share/lib/security/BlacklistedCertsConverter.java b/jdk/src/share/lib/security/BlacklistedCertsConverter.java new file mode 100644 index 00000000000..65a88f00a2e --- /dev/null +++ b/jdk/src/share/lib/security/BlacklistedCertsConverter.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Collection; + +/** + * This is the tool to convert blacklisted.certs.pem to blacklisted.certs. + * Every time a new blacklisted certs is added, please append the PEM format + * to the end of blacklisted.certs.pem (with proper comments) and then use + * this tool to generate an updated blacklisted.certs. Make sure to include + * changes to both in a changeset. + */ +public class BlacklistedCertsConverter { + public static void main(String[] args) throws Exception { + if (args.length == 0) { + System.out.println("Usage: java BlacklistedCertsConverter SHA-256" + + " < blacklisted.certs.pem > blacklisted.certs"); + System.exit(1); + } + String mdAlg = args[0]; + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Collection certs + = cf.generateCertificates(System.in); + System.out.println("Algorithm=" + mdAlg); + for (Certificate cert: certs) { + System.out.println( + getCertificateFingerPrint(mdAlg, (X509Certificate)cert)); + } + } + + /** + * Converts a byte to hex digit and writes to the supplied buffer + */ + private static void byte2hex(byte b, StringBuffer buf) { + char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + int high = ((b & 0xf0) >> 4); + int low = (b & 0x0f); + buf.append(hexChars[high]); + buf.append(hexChars[low]); + } + + /** + * Gets the requested finger print of the certificate. + */ + private static String getCertificateFingerPrint(String mdAlg, + X509Certificate cert) { + String fingerPrint = ""; + try { + byte[] encCertInfo = cert.getEncoded(); + MessageDigest md = MessageDigest.getInstance(mdAlg); + byte[] digest = md.digest(encCertInfo); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < digest.length; i++) { + byte2hex(digest[i], buf); + } + fingerPrint = buf.toString(); + } catch (NoSuchAlgorithmException | CertificateEncodingException e) { + // ignored + } + return fingerPrint; + } +} diff --git a/jdk/src/share/lib/security/blacklisted.certs b/jdk/src/share/lib/security/blacklisted.certs new file mode 100644 index 00000000000..cb1e4d59e38 --- /dev/null +++ b/jdk/src/share/lib/security/blacklisted.certs @@ -0,0 +1,19 @@ +Algorithm=SHA-256 +76A45A496031E4DD2D7ED23E8F6FF97DBDEA980BAAC8B0BA94D7EDB551348645 +4CBBF8256BC9888A8007B2F386940A2E394378B0D903CBB3863C5A6394B889CE +D24566BF315F4E597D6E381C87119FB4198F5E9E2607F5F4AB362EF7E2E7672F +14E6D2764A4B06701C6CBC376A253775F79C782FBCB6C0EE6F99DE4BA1024ADD +D3A936E1A7775A45217C8296A1F22AC5631DCDEC45594099E78EEEBBEDCBA967 +5E83124D68D24E8E177E306DF643D5EA99C5A94D6FC34B072F7544A1CABB7C7B +9ED8F9B0E8E42A1656B8E1DD18F42BA42DC06FE52686173BA2FC70E756F207DC +FDEDB5BDFCB67411513A61AEE5CB5B5D7C52AF06028EFC996CC1B05B1D6CEA2B +A686FEE577C88AB664D0787ECDFFF035F4806F3DE418DC9E4D516324FFF02083 +4FEE0163686ECBD65DB968E7494F55D84B25486D438E9DE558D629D28CD4D176 +8A1BD21661C60015065212CC98B1ABB50DFD14C872A208E66BAE890F25C448AF +B8686723E415534BC0DBD16326F9486F85B0B0799BF6639334E61DAAE67F36CD +3946901F46B0071E90D78279E82FABABCA177231A704BE72C5B0E8918566EA66 +31C8FD37DB9B56E708B03D1F01848B068C6DA66F36FB5D82C008C6040FA3E133 +450F1B421BB05C8609854884559C323319619E8B06B001EA2DCBB74A23AA3BE2 +FC02FD48DB92D4DCE6F11679D38354CF750CFC7F584A520EB90BDE80E241F2BD +DF21016B00FC54F9FE3BC8B039911BB216E9162FAD2FD14D990AB96E951B49BE +F5B6F88F75D391A4B1EB336F9E201239FB6B1377DB8CFA7B84736216E5AFFFD7 diff --git a/jdk/src/share/lib/security/blacklisted.certs.pem b/jdk/src/share/lib/security/blacklisted.certs.pem new file mode 100644 index 00000000000..f44a6985352 --- /dev/null +++ b/jdk/src/share/lib/security/blacklisted.certs.pem @@ -0,0 +1,721 @@ +// Subject: CN=Digisign Server ID (Enrich), +// OU=457608-K, +// O=Digicert Sdn. Bhd., +// C=MY +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120001705 (07:27:14:a9) +-----BEGIN CERTIFICATE----- +MIIDyzCCAzSgAwIBAgIEBycUqTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA3MDcxNzE1MTc0OFoXDTEyMDcxNzE1MTY1NFowYzELMAkG +A1UEBhMCTVkxGzAZBgNVBAoTEkRpZ2ljZXJ0IFNkbi4gQmhkLjERMA8GA1UECxMI +NDU3NjA4LUsxJDAiBgNVBAMTG0RpZ2lzaWduIFNlcnZlciBJRCAoRW5yaWNoKTCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArahkS02Hx4RZufuQRqCmicDx/tXa +VII3DZkrRSYK6Fawf8qo9I5HhAGCKeOzarWR8/uVhbxyqGToCkCcxfRxrnt7agfq +kBRPjYmvlKuyBtQCanuYH1m5Os1U+iDfsioK6bjdaZDAKdNO0JftZszFGUkGf/pe +LHx7hRsyQt97lSUCAwEAAaOCAXgwggF0MBIGA1UdEwEB/wQIMAYBAf8CAQAwXAYD +VR0gBFUwUzBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcCARYtaHR0cDovL2N5YmVy +dHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnkuY2ZtMAcGBWCDSgEBMA4GA1Ud +DwEB/wQEAwIB5jCBiQYDVR0jBIGBMH+heaR3MHUxCzAJBgNVBAYTAlVTMRgwFgYD +VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv +bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv +b3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cucHVibGljLXRydXN0 +LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYDVR0OBBYEFMYWk04WF+wW +royUdvOGbcV0boR3MA0GCSqGSIb3DQEBBQUAA4GBAHYAe6Z4K2Ydjl42xqSOBfIj +knyTZ9P0wAp9iy3Z6tVvGvPhSilaIoRNUC9LDPL/hcJ7VdREgr5trGeOvLQfkpxR +gBoU9m6rYYgLrRx/90tQUdZlG6ZHcRVesHHzNRTyN71jyNXwk1o0X9g96F33xR7A +5c8fhiSpPAdmzcHSNmNZ +-----END CERTIFICATE----- + +// Subject: CN=Digisign Server ID - (Enrich), +// OU=457608-K, +// O=Digicert Sdn. Bhd., +// C=MY +// Issuer: CN=Entrust.net Certification Authority (2048) +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), +// O=Entrust.net +// Serial: 1184644297 (4c:0e:63:6a) +-----BEGIN CERTIFICATE----- +MIIEzjCCA7agAwIBAgIETA5jajANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw0xMDA3MTYxNzIzMzdaFw0xNTA3 +MTYxNzUzMzdaMGUxCzAJBgNVBAYTAk1ZMRswGQYDVQQKExJEaWdpY2VydCBTZG4u +IEJoZC4xETAPBgNVBAsTCDQ1NzYwOC1LMSYwJAYDVQQDEx1EaWdpc2lnbiBTZXJ2 +ZXIgSUQgLSAoRW5yaWNoKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AMWJ5PQNBkCSWccaszXRDkwqM/n4r8qef+65p21g9FTob9Wb8xtjMQRoctE0Foy0 +FyyX3nPF2JAVoBor9cuzSIZE8B2ITM5BQhrv9Qze/kDaOSD3BlU6ap1GwdJvpbLI +Vz4po5zg6YV3ZuiYpyR+vsBZIOVEb7ZX2L7OwmV3WMZhQdF0BMh/SULFcqlyFu6M +3RJdtErU0a9Qt9iqdXZorT5dqjBtYairEFs+E78z4K9EnTgiW+9ML6ZxJhUmyiiM +2fqOjqmiFDXimySItPR/hZ2DTwehthSQNsQ0HI0mYW0Tb3i+6I8nx0uElqOGaAwj +vgvsjJQAqQSKE5D334VsDLECAwEAAaOCATQwggEwMA4GA1UdDwEB/wQEAwIBBjAS +BgNVHRMBAf8ECDAGAQH/AgEAMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggrBgEFBQcD +AgYIKwYBBQUHAwQwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8v +b2NzcC5lbnRydXN0Lm5ldDBEBgNVHSAEPTA7MDkGBWCDSgEBMDAwLgYIKwYBBQUH +AgEWImh0dHA6Ly93d3cuZGlnaWNlcnQuY29tLm15L2Nwcy5odG0wMgYDVR0fBCsw +KTAnoCWgI4YhaHR0cDovL2NybC5lbnRydXN0Lm5ldC8yMDQ4Y2EuY3JsMBEGA1Ud +DgQKBAhMTswlKAMpgTAfBgNVHSMEGDAWgBRV5IHREYC+2Im5CKMx+aEkCRa5cDAN +BgkqhkiG9w0BAQUFAAOCAQEAl0zvSjpJrHL8MCBrtClbp8WVBJD5MtXChWreA6E3 ++YkAsFqsVX7bQzX/yQH4Ub7MJsrIaqTEVD4mHucMo82XZ5TdpkLrXM2POXlrM3kh +Bnn6gkQVmczBtznTRmJ8snDrb84gqj4Zt+l0gpy0pUtNYQA35IfS8hQ6ZHy4qXth +4JMi59WfPkfmNnagU9gAAzoPtTP+lsrT0oI6Lt3XSOHkp2nMHOmZSufKcEXXCwcO +mnUb0C+Sb/akB8O9HEumhLZ9qJqp0qcp8QtXaR6XVybsK0Os1EWDBQDp4/BGQAf6 +6rFRc5Mcpd1TETfIKqcVJx20qsx/qjEw/LhFn0gJ7RDixQ== +-----END CERTIFICATE----- + +// Subject: CN=Java Media APIs, +// OU=Java Signed Extensions, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 6a:8b:99:91:37:59:4f:89:53:e2:97:18:9f:19:1e:4e +-----BEGIN CERTIFICATE----- +MIIFdzCCBF+gAwIBAgIQaouZkTdZT4lT4pcYnxkeTjANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDUxMjAw +MDAwMFoXDTEyMDUxMTIzNTk1OVowfTEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt +cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE +CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEYMBYGA1UEAxQPSmF2YSBNZWRpYSBB +UElzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl5blzoKTVE8y4Hpz +q6E15RZz1bF5HnYEyYqgHkZXnAKedmYCoMzm1XK8s+gQWShLEvGEAvs5yqarx9gE +nnC21N28aEZgIJMa2/arKxCUkS4pxdGPYGexL9UzSRkUpoBShCZKEGdmX7gfJE2K +/sd9MFvGV5/yZtWXrADzvm0Kd/9mg1KRv1gfrZIq0TJbupoXPYYqb73AkI9eT2ZD +q9MdwD4E5+oojsDFXt8GU/D00fUhtXpYwuplU7D667WHYdJhIah0ST6JywyqcLXG +XSuFTXOgITT2idSHluZVmx3dqJ72u9kPkO4JdJTMDfaK8zgNLaRkiU8Qcj+qhLYH +ytaqcwIDAQABo4IB6jCCAeYwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCB4AwfwYD +VR0fBHgwdjB0oHKgcIZuaHR0cDovL29uc2l0ZWNybC52ZXJpc2lnbi5jb20vU3Vu +TWljcm9zeXN0ZW1zSW5jQ29ycG9yYXRlT2JqZWN0U2lnbmluZ0phdmFTaWduZWRF +eHRlbnNpb25zQ2xhc3NCL0xhdGVzdENSTC5jcmwwHwYDVR0jBBgwFoAUs0crgn5T +tHPKuLsZt76BTQeVx+0wHQYDVR0OBBYEFKS32mVx0gNWTeS4ProHEaeSpvvIMDsG +CCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL29uc2l0ZS1vY3NwLnZl +cmlzaWduLmNvbTCBtQYDVR0gBIGtMIGqMDkGC2CGSAGG+EUBBxcCMCowKAYIKwYB +BQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwbQYLYIZIAYb3AIN9 +nD8wXjAnBggrBgEFBQcCARYbaHR0cHM6Ly93d3cuc3VuLmNvbS9wa2kvY3BzMDMG +CCsGAQUFBwICMCcaJVZhbGlkYXRlZCBGb3IgU3VuIEJ1c2luZXNzIE9wZXJhdGlv +bnMwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQEFBQADggEBAAe6BO4W +3TSNWfezyelJs6kE3HfulT6Bdyz4UUoh9ykXcV8nRwT+kh25I5MdyG2GfkJoADPR +VhC5DYo13UFpIsTNVjq+hGYe2hML93bN7ad9SxCCyjHUo3yMz2qgBbHZI3VA9ZHA +aWM4Tx0saMwbcnVvlbuGh+PXvStfypJqYT6lzcdFfjNVX4FI/QQNGhBswMY51tC8 +GTBCL2qhJon0gSCU4zaawDOf7+XxJWirLamYL1Aal1/h2z2sFrvA/1ftxtU3kZ6I +7De8DyoHeZg7pYGdrj7g+lPhCga/WvEhN152I+aP08YbFcJHYmK05ngl/Ye4c6Bd +cdrdfbw6QzEUIYY= +-----END CERTIFICATE----- + +// Subject: CN=JavaFX 1.0 Runtime, +// OU=Java Signed Extensions, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 55:c0:e6:44:59:59:79:9e:d9:26:f1:b0:4a:1e:f0:27 +-----BEGIN CERTIFICATE----- +MIIFezCCBGOgAwIBAgIQVcDmRFlZeZ7ZJvGwSh7wJzANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA4MTAwOTAw +MDAwMFoXDTExMTAwOTIzNTk1OVowgYAxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl +bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxHzAdBgNV +BAsUFkphdmEgU2lnbmVkIEV4dGVuc2lvbnMxGzAZBgNVBAMUEkphdmFGWCAxLjAg +UnVudGltZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM+WDc6+bu+4 +tmAcS/lBtUc02WOt9QZpVsXg9cG2pu/8bUtmDELa8iiYBVFpIs8DU58HLrGQtCUY +SIAGOVPsOJoN29UKCDWfY9j5JeVhfhMGqk9DwrWhzgsjy4cpZ1pIp+k/fJ8zT8Ul +aYLpow1vg3UNddsmwz02tN7cOrMw9WYIG4CRYnY1OrtJSfe2pYzheC4zyvR+aiVl +nang2OtqikSQsNFOFHsLOJFxngy9LrO8evDSu25VTKI6zlWU6/bMeqtztJPN0VOn +NyUrJZvkxZ207Jg0T693BGSxNC1n+ihztXogql8950M/pEuUbDjylv5FFvlp6DSB +dDT2MkutmyMCAwEAAaOCAeowggHmMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeA +MH8GA1UdHwR4MHYwdKByoHCGbmh0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29t +L1N1bk1pY3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdKYXZhU2ln +bmVkRXh0ZW5zaW9uc0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaAFLNH +K4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBTjgufVi3XJ3gx1ewsA6Rr7BR4Z +zjA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUtb2Nz +cC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAqMCgG +CCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CGSAGG +9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtpL2Nw +czAzBggrBgEFBQcCAjAnGiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBPcGVy +YXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IBAQAB +YVJTTVe7rzyTO4jc3zajErOT/COkdQTfNo0eIX1QbNynFieJvwY/jRzUZwjktIFR +2p4JtbpHGAtKtjOAOTieQ8xdDOoC1djzpE7/AbMvuvlTavtUKT+F7tPdhfXgWXJV +6Wbt8jryKyk3zZGiEhauIwZUkfjRkEtffEmZWLUd8c8rURJjfC/XHH2oyurscoxc +CjX29c9ynxSiS/VvQp1an0HvErGh69N48wj7cj8mtZ1yHzd2XCzSSR1OfTPfk0Pt +yg51p7yJaFiH21PTZegEL6zyVNOYBTKwwIi2OzpwYalD3uvK6e3OKDrfFCOxu17u +4PveESbrdyrmvLe7IVez +-----END CERTIFICATE----- + +// Subject: CN=JavaFX Runtime, +// OU=Java Signed Extensions, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 47:f4:55:f1:da:4a:5e:f9:e3:f7:a8:03:62:17:c0:ff +-----BEGIN CERTIFICATE----- +MIIFdjCCBF6gAwIBAgIQR/RV8dpKXvnj96gDYhfA/zANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDEyOTAw +MDAwMFoXDTEyMDEyOTIzNTk1OVowfDEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt +cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE +CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEXMBUGA1UEAxQOSmF2YUZYIFJ1bnRp +bWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCIzd0fAk8mI9ONc6RJ +aGieioK2FLdXEwj8zL3vdGDVmBwyR1zwYkaOIFFgF9IW/8qc4iAYA5sGUY+0g8q3 +5DuYAxfTzBB5KdaYvbuq6GGnoHIWmTirXY+1friFp8lyXSvtuEaGB1VHaBoZchEg +k+UgeVDA43dHwcT1Ov3DePczJRUes8T/QHzLX+BxUDG43vjyncCEO/AjqLZxXEz2 +xrNbKLcH3lGMJK7hdbfssUfF5BjC38Hn71HauYlA43b2no+2y0Sjulwzez2YPbDC +0GLR3TnKtA8dqOrnl5t3DniDbfOBNtBE3VOydJO0XW57Ng1HRXD023nm9ECPY2xp +0N/pAgMBAAGjggHqMIIB5jAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDB/BgNV +HR8EeDB2MHSgcqBwhm5odHRwOi8vb25zaXRlY3JsLnZlcmlzaWduLmNvbS9TdW5N +aWNyb3N5c3RlbXNJbmNDb3Jwb3JhdGVPYmplY3RTaWduaW5nSmF2YVNpZ25lZEV4 +dGVuc2lvbnNDbGFzc0IvTGF0ZXN0Q1JMLmNybDAfBgNVHSMEGDAWgBSzRyuCflO0 +c8q4uxm3voFNB5XH7TAdBgNVHQ4EFgQUvOdd0cKPj+Yik/iOBwTdphh5A+gwOwYI +KwYBBQUHAQEELzAtMCsGCCsGAQUFBzABhh9odHRwOi8vb25zaXRlLW9jc3AudmVy +aXNpZ24uY29tMIG1BgNVHSAEga0wgaowOQYLYIZIAYb4RQEHFwIwKjAoBggrBgEF +BQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTBtBgtghkgBhvcAg32c +PzBeMCcGCCsGAQUFBwIBFhtodHRwczovL3d3dy5zdW4uY29tL3BraS9jcHMwMwYI +KwYBBQUHAgIwJxolVmFsaWRhdGVkIEZvciBTdW4gQnVzaW5lc3MgT3BlcmF0aW9u +czATBgNVHSUEDDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQUFAAOCAQEAbGcf2NjL +AI93HG6ny2BbepaZA1a8xa/R6uUc7xV+Qw6MgLwFD4Q4i6LWUztQDvg9l68MM2/i +Y9LEi1KM4lcNbK5+D+t9x98wXBiuojXhVdp5ZmC03EyEBbriopdBsmXVLDSu/Y3+ +zowOO5xwpMK3dbgsSDs2Vt0UosD3FTcRaD3GNfOhXMp+o1grHNiXF9YgkmdQbPPZ +DQ2KBhFPCRJXBGvyKOqno/DTg0sQ3crGH/C4/4t7mnQXWldZotmJUZ0ONc9oD+Q1 +JAaguUKqIwn9yZ093ie+JWHbYNid9IIIPXYgtRxmf9a376WBhqhu56uJftBJ7x9g +eQ7Lot6CSWCiFw== +-----END CERTIFICATE----- + +// Subject: CN=Solaris INTERNAL DEVELOPMENT USE ONLY, +// OU=Solaris Cryptographic Framework, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 77:29:77:52:6a:19:7b:9a:a6:a2:c7:99:a0:e1:cd:8c +-----BEGIN CERTIFICATE----- +MIIFHjCCBAagAwIBAgIQdyl3UmoZe5qmoseZoOHNjDANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA3MDEwNDAw +MDAwMFoXDTEwMDEwMzIzNTk1OVowgZwxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl +bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxKDAmBgNV +BAsUH1NvbGFyaXMgQ3J5cHRvZ3JhcGhpYyBGcmFtZXdvcmsxLjAsBgNVBAMUJVNv +bGFyaXMgSU5URVJOQUwgREVWRUxPUE1FTlQgVVNFIE9OTFkwgZ8wDQYJKoZIhvcN +AQEBBQADgY0AMIGJAoGBALbNU4hf3mD5ArDI9pjgioAyvV3bjMPRQdCZniIeGJBp +odFlSEH+Mh64W1DsY8coeZ7FvvGJkx9IpTMJW9k8w1oJK9UNqHyAQfaYjQyXi3xQ +LJp62EvYdGfDlwOZejEcR/MbzZG+GOPMMvQj5+xyFDvLXNGfQNTnxw2qnBgCJXjj +AgMBAAGjggH1MIIB8TAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDCBiQYDVR0f +BIGBMH8wfaB7oHmGd2h0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29tL1N1bk1p +Y3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdTb2xhcmlzQ3J5cHRv +Z3JhcGhpY0ZyYW1ld29ya0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaA +FLNHK4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBRpfiGYkehTnsIzuN2H6AFb +VCZG8jA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUt +b2NzcC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAq +MCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CG +SAGG9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtp +L2NwczAzBggrBgEFBQcCAjAnFiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBP +cGVyYXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IB +AQCG5soy3LFHTFbA8/5SzDRhQoJkHUnOP0t3b6nvX6vZYRp649fje7TQOPRm1pFd +CZ17J+tggdZwgzTqY4aYpJ00jZaK6pV37q/vgFC/ia6jDs8Q+ly9cEcadBZ5loYg +cmxp9p57W2MNWx8VA8oFdNtKfF0jUNXbLNtvwGHmgR6YcwLrGN1b6/9Lt9bO3ODl +FO+ZDwkfQz5ClUVrTx2dGBvKRYFqSG5S8JAfsgYhPvcacUQkA7ExyKvfRXLWVrce +ZiPpcElbx+819H2sAPvVvparVeAruZGMAtejHZp9NFoowKen5drJp9VxePS4eM49 +3DepB6lKRrNRw66LNQol4ZBz +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, CN=DigiNotar Cyber CA, +// O=DigiNotar, C=NL +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120000525 (07:27:10:0D) +-----BEGIN CERTIFICATE----- +MIIFWjCCBMOgAwIBAgIEBycQDTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA2MTAwNDEwNTQxMVoXDTExMTAwNDEwNTMxMVowYDELMAkG +A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy +IEN5YmVyIENBMSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANLOFQotqF6EZ639vu9Gx8i5z3P8 +9DS5+SxD52ATPXrjss87Z2yQrcC5P4RS8DVC3HTcKDu9UrSnrHJFF8bwieu0qiXy +XUte0dmHutZ9fPXOMp8QM8WxSrtekTHC0OlBwpFkfglBO9uLCDdqqspS3rU5HsCI +A6U/i5kTYUO1m4Kz7iBvz6FEouova0CfjytXraFTwoUiaZ2gP1HfC0GRDaXhqKpc +SQhdvd5wQbEPyWNr0380dAIvNFp4dRxoeoFnivPaQPBgY/SSINcDpj2jHmfEhBtB +pcmM5r3qSLYFFgizNxJa92E89zhvLpfgb1Y4VNMota0Ubi5LZLUnZbd1JQm2Bz2V +VgIKgmCyc0XgMyZRdJq51FAc9k1bW1JSE1qmf6cO4ehBVGeYjIfVydNsy9NUkgYJ +NEH3gW8/nsl8dVWw58Gzd+jDxAA1lUBwEEoF3iW7n1mlZLxHYL9g43aLE1Xd4XR6 +uc8kpmp/3mQiRFhogmoQ+T3lPhu5vfwi9GAEibtVbShV+t6OjRshFNc3izR7Tfay +shDPM7F9HGKZSMsrbHaWVb8ZDR0fu2WqG46ZtcYokOWCLXhQIJr9eS8kf/CJKWn0 +fc1zvrPtTsHR7VJej/e4142HrbLZG1ES/1az4a80fVykeIgQnp0DxqWqoiRR90kU +xbHuWUOV36toKDA/AgMBAAGjggGGMIIBgjASBgNVHRMBAf8ECDAGAQH/AgEBMFMG +A1UdIARMMEowSAYJKwYBBAGxPgEAMDswOQYIKwYBBQUHAgEWLWh0dHA6Ly93d3cu +cHVibGljLXRydXN0LmNvbS9DUFMvT21uaVJvb3QuaHRtbDAOBgNVHQ8BAf8EBAMC +AQYwgaAGA1UdIwSBmDCBlYAUpgwdn2H/Bxe1vzhG20Mw1Y6wUgaheaR3MHUxCzAJ +BgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdU +RSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVy +VHJ1c3QgR2xvYmFsIFJvb3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93 +d3cucHVibGljLXRydXN0LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYD +VR0OBBYEFKv5aN/PSjfXe0WMX3LeQETDZbvCMA0GCSqGSIb3DQEBBQUAA4GBAI9o +a6VbB7pEZg4cqFwwezPkCiYE/O+eGjjWLqEf0JlHwnVkJP2eOyh2uSYoYZEMbSz4 +BJ98UAHV42mv7xXSRZskCSpmBU8lgcpdvqrBWSeuM46C9990sFWzjvjnN8huqlZE +9r1TgSOWPbT6MopTZkQloiXGpjwljPDgKAYityZB +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120000505 (07:27:0F:F9) +-----BEGIN CERTIFICATE----- +MIIFODCCBKGgAwIBAgIEBycP+TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA2MDkyMDA5NDUzMloXDTEzMDkyMDA5NDQwNlowPjELMAkG +A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy +IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o +XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S +tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7 +24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp +naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj +9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu +LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU +Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk +vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6 +3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt +eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4 +iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB +/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC +ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s +MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV +jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv +bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD +VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6 +oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw +MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI +hvcNAQEFBQADgYEACcpiD427SuDUejUrBi3RKGG2rAH7g0m8rtQvLYauGYOl1h0T +4he+/jJ06XoUOMqUXvcpAWlxG5Ea/aO7qh3Ke+IW/aGjDvMMX7LhIDGUK16Sdu36 +6bUjpr8KOwOpb1JgVM1f6bcvfKIn/UGDdbYN+3gm87FF6TKVKho1IZXFonU= +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120000515 (07:27:10:03) +-----BEGIN CERTIFICATE----- +MIIFODCCBKGgAwIBAgIEBycQAzANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA2MDkyNzEwNTMzMloXDTExMDkyNzEwNTIzMFowPjELMAkG +A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy +IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o +XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S +tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7 +24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp +naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj +9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu +LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU +Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk +vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6 +3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt +eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4 +iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB +/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC +ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s +MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV +jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv +bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD +VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6 +oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw +MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI +hvcNAQEFBQADgYEAWcyGZhizJlRP1jjNupZey+yZG6oMDW4Z11boriMHbYPCndBE +bVh07zmPbZsihOw9w/vm5KbVX5CgxUv4Rhzh/20Faixf3P3bpWg0qgzHVVusNVR/ +P50aKkpdK3hp+QLl56e+lWOddSAINIpmcuyDI1hyuzB+GJEASm9tNU/6rs8= +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, +// CN=DigiNotar Root CA, +// O=DigiNotar, C=NL +// Issuer: CN=Entrust.net Secure Server Certification Authority +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), +// O=Entrust.net, +// C=US, +// Serial: 1184644297 (46:9C:3C:C9) +-----BEGIN CERTIFICATE----- +MIIFSDCCBLGgAwIBAgIERpw8yTANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA0 +MjYwNTAwMDBaFw0xMzA4MTQyMDEyMzZaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK +EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI +hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt +OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx +hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7 +gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D +IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T +BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs +Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8 +5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf +DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX +9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e +7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj +ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB +BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF +BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD +VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy +bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G +A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob +BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAI979rBep8tu3TeLunapgsZ0jtXp +GDFjKWSk87dj1jCyYi+q/GyDyZ6ZQZNRP0sF+6twscq05lClWNy3TROMp7QeuoLO +G7Utw3OJaswUtp4YglANMRTHEe3g9ltifUXRH5tSuy7u6yi4LD4WTm5ULP6r/g6l +0CnjXYb0+b1Fmz6U +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, +// CN=DigiNotar Root CA, +// O=DigiNotar, C=NL +// Issuer: CN=Entrust.net Secure Server Certification Authority +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), +// O=Entrust.net, +// C=US, +// Serial: 1184640175 (46:9C:2C:AF) +-----BEGIN CERTIFICATE----- +MIIFSDCCBLGgAwIBAgIERpwsrzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3 +MjYxNTU3MzlaFw0xMzA4MjYxNjI3MzlaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK +EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI +hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt +OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx +hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7 +gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D +IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T +BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs +Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8 +5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf +DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX +9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e +7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj +ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB +BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF +BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD +VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy +bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G +A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob +BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAEa6RcDNcEIGUlkDJUY/pWTds4zh +xbVkp3wSmpwPFhx5fxTyF4HD2L60jl3aqjTB7gPpsL2Pk5QZlNsi3t4UkCV70UOd +ueJRN3o/LOtk4+bjXY2lC0qTHbN80VMLqPjmaf9ghSA9hwhskdtMgRsgfd90q5QP +ZFdYf+hthc3m6IcJ +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2, +// O=DigiNotar B.V., +// C=NL +// Issuer: CN=Staat der Nederlanden Organisatie CA - G2, +// O=Staat der Nederlanden, +// C=NL +// Serial: 20001983 (01:31:34:bf) +-----BEGIN CERTIFICATE----- +MIIGnDCCBISgAwIBAgIEATE0vzANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMTIwMAYDVQQDDClTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gT3JnYW5pc2F0aWUgQ0EgLSBHMjAeFw0xMDA1MTIw +ODUxMzhaFw0yMDAzMjMwOTUwMDRaMFoxCzAJBgNVBAYTAk5MMRcwFQYDVQQKDA5E +aWdpTm90YXIgQi5WLjEyMDAGA1UEAwwpRGlnaU5vdGFyIFBLSW92ZXJoZWlkIENB +IE9yZ2FuaXNhdGllIC0gRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCxExkPJ+Zs1FWGS9DsiYpFkXisR71HK+T8RetPtCZzWzfTw3/2497Xo/gtaMUI +PkuU1uSHJTZrhLUYdPMoWHMvm2rPvAQe9t7dr/xLqvXbZmIlASWC3vKXWhBu3V2p +IrEEqSNzOvhxrR3PhETrR9Gvbch8KKvH8jd6dF9fxQIUiqNa4xtsAeNdjtlo1vQJ +GzLckbUs9SDrjANtJkm4k8SFXdjSm69WaswFM8ygQp40VUSca6DUEtArVM23iQ3l +9uvo+4UBM096a/GdcjOWDveyhKWlJ8Qn8VFzKXe6Z27+TNy04qGhgS85SY1DOBPO +0KVcwoc6AGdlQiPxNlkKHaNRyLyjlCox3+M88p0aPASw77EKMBNzttfzo0wBdRSF +eMDXijlYhVD6LubFvs+LP6+PNtQlCS3SD6xyk/K/i9RQs/kVUJuZ9RTZ+4uRozIm +JqD43ztggYaDeVsr6xM9KTrBbd29no6H1kquNJcF7hSm9tw4fkrpJFQHPZdoN0Zr +DceoIa8TVOQJavFNRgrJXfubT73e+7dUy7g4nKc5+2otwHuNq6WnV+xKkoozxeEg +XHPYkJIrgNUPhhhpfDlPhIa890xb89W0yqDC8DciynlSH1PmqvOQsDvd8ij9rOvF +BiSgydQvD1j9tZ7sD8+yWdCiBHo4aq5y+73wJWKUCacFCwIDAQABo4IBYTCCAV0w +SAYDVR0gBEEwPzA9BgRVHSAAMDUwMwYIKwYBBQUHAgEWJ2h0dHA6Ly93d3cuZGln +aW5vdGFyLm5sL2Nwcy9wa2lvdmVyaGVpZDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjCBhQYDVR0jBH4wfIAUORCLSZJc22ESIM1JnRqO2pxnQLmhXqRc +MFoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4x +KzApBgNVBAMMIlN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENBIC0gRzKCBACY +lvQwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NybC5wa2lvdmVyaGVpZC5ubC9E +b21PcmdhbmlzYXRpZUxhdGVzdENSTC1HMi5jcmwwHQYDVR0OBBYEFLxdlDvZq3sD +JXNhwtst7vyrj2WhMA0GCSqGSIb3DQEBCwUAA4ICAQCP/C1Mt9kt1R+978v0t2gX +dZ1O1ffdnPEqJu2forYcA9VTs+wIzzTi48P0tRYvyMO+19NzqwA2+RpKftZj6V5G +uqW2jhW3oyrYQx3vXcgfgYWzi/f/PPTZ9EYIP5y8HaDZqEzNJVJOCrEg9x/pQ9lU +RoETmsBedGwqmDLq/He7DaWiMZgifnx859qkrey3LhoZcfhIUNpDjyyE3cFAJ+O1 +8BVOltT4XOOGKUYr1zsH6zh/yIZXl9PvKjPEF1DVZGlrK2tFXl0vF8paTs/D1zk8 +9TufRrmb5w5Jl53W1eMbD+qPAU6aE5RZCgIHSEsaYKt/T+0L2FUNaG9VnGllFULs +wNzdbKzDFs4LHVabpMTE0i7gD+JEJytQaaTcYuiKISlCbMwAOpZ2m+9AwKRed4Qy +bCYqOWauXeO5ubIsaB8empADOfCqs6TMSYsYNOk3yXspx4R8b0QVL+xhWQTJRcui +1lKifH8pktZKxYtCqNT+6tjHhyMY5J16fXNAUpigrm7jBT8FD+Clxm1N7YM3iJzH +89xCmmq21yFJNnfy7xhPxXDZnunetyuL9Lx+KN8NQMmFXK6dxTH/0FwOtah+8Okv +uq+IruW10Vilr5xxpykBkINpN4IFuvwJwQhujHg7wzMCgD9EhQgd31VWCK0shS1d +sQPhrqp0xaTzTro3mHuCuQ== +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven, +// O=DigiNotar B.V., +// C=NL +// Issuer: CN=Staat der Nederlanden Overheid CA +// O=Staat der Nederlanden, +// C=NL +// Serial: 20015536 (01:31:69:b0) +-----BEGIN CERTIFICATE----- +MIIEiDCCA3CgAwIBAgIEATFpsDANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO +TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDcwNzA1MDg0MjA3WhcN +MTUwNzI3MDgzOTQ2WjBfMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy +IEIuVi4xNzA1BgNVBAMTLkRpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp +ZCBlbiBCZWRyaWp2ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDc +vdKnTmoKuzuiheF/AK2+tDBomAfNoHrElM9x+Yo35FPrV3bMi+Zs/u6HVcg+uwQ5 +AKeAeKxbT370vbhUuHE7BzFJOZNUfCA7eSuPu2GQfbGs5h+QLp1FAalkLU3DL7nn +UNVOKlyrdnY3Rtd57EKZ96LspIlw3Dgrh6aqJOadkiQbvvb91C8ZF3rmMgeUVAVT +Q+lsvK9Hy7zL/b07RBKB8WtLu+20z6slTxjSzAL8o0+1QjPLWc0J3NNQ/aB2jKx+ +ZopC9q0ckvO2+xRG603XLzDgbe5bNr5EdLcgBVeFTegAGaL2DOauocBC36esgl3H +aLcY5olLmmv6znn58yynAgMBAAGjggFQMIIBTDBIBgNVHSAEQTA/MD0GBFUdIAAw +NTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5kaWdpbm90YXIubmwvY3BzL3BraW92 +ZXJoZWlkMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMIGABgNVHSME +eTB3gBQLhtYPd6NosftkCcOIblwEHFfpPaFZpFcwVTELMAkGA1UEBhMCTkwxHjAc +BgNVBAoTFVN0YWF0IGRlciBOZWRlcmxhbmRlbjEmMCQGA1UEAxMdU3RhYXQgZGVy +IE5lZGVybGFuZGVuIFJvb3QgQ0GCBACYmnkwPQYDVR0fBDYwNDAyoDCgLoYsaHR0 +cDovL2NybC5wa2lvdmVyaGVpZC5ubC9Eb21PdkxhdGVzdENSTC5jcmwwHQYDVR0O +BBYEFEwIyY128ZjHPt881y91DbF2eZfMMA0GCSqGSIb3DQEBBQUAA4IBAQAMlIca +v03jheLu19hjeQ5Q38aEW9K72fUxCho1l3TfFPoqDz7toOMI9tVOW6+mriXiRWsi +D7dUKH6S3o0UbNEc5W50BJy37zRERd/Jgx0ZH8Apad+J1T/CsFNt5U4X5HNhIxMm +cUP9TFnLw98iqiEr2b+VERqKpOKrp11Lbyn1UtHk0hWxi/7wA8+nfemZhzizDXMU +5HIs4c71rQZIZPrTKbmi2Lv01QulQERDjqC/zlqlUkxk0xcxYczopIro5Ij76eUv +BjMzm5RmZrGrUDqhCYF0U1onuabSJc/Tw6f/ltAv6uAejVLpGBwgCkegllYOQJBR +RKwa/fHuhR/3Qlpl +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar PKIoverheid CA Overheid +// O=DigiNotar B.V., +// C=NL +// Issuer: CN=Staat der Nederlanden Overheid CA +// O=Staat der Nederlanden, +// C=NL +// Serial: 20006006 (01:31:44:76) +-----BEGIN CERTIFICATE----- +MIIEezCCA2OgAwIBAgIEATFEdjANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO +TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDQwNjI0MDgxOTMyWhcN +MTAwNjIzMDgxNzM2WjBSMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy +IEIuVi4xKjAoBgNVBAMTIURpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp +ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANSlrubta5tlOjVCi/gb +yLCvRqfBjxG8H594VcKHu0WAYc99SPZF9cycj5mw2GyfQvy/WIrGrL4iyNq1gSqR +0QA/mTXKZIaPqzpDhdm+VvrKkmjrbZfaQxgMSs3ChtBsjcP9Lc0X1zXZ4Q8nBe3k +BTp+zehINfmbjoEgXLxsMR5RQ6GxzKjuC04PQpbJQgTIakglKaqYcDDZbEscWgPV +Hgj/2aoHlj6leW/ThHZ+O41jUguEmBLZA3mu3HrCfrHntb5dPt0ihzSx7GtD/SaX +5HBLxnP189YuqMk5iRA95CtiSdKauvon/xRKRLNgG6XAz0ctSoY7xLDdiBVU5kJd +FScCAwEAAaOCAVAwggFMMEgGA1UdIARBMD8wPQYEVR0gADA1MDMGCCsGAQUFBwIB +FidodHRwOi8vd3d3LmRpZ2lub3Rhci5ubC9jcHMvcGtpb3ZlcmhlaWQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgYAGA1UdIwR5MHeAFAuG1g93o2ix ++2QJw4huXAQcV+k9oVmkVzBVMQswCQYDVQQGEwJOTDEeMBwGA1UEChMVU3RhYXQg +ZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQYIEAJiaeTA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnBraW92 +ZXJoZWlkLm5sL0RvbU92TGF0ZXN0Q1JMLmNybDAdBgNVHQ4EFgQUvRaYQh2+kdE9 +wpcl4CjXWOC1f+IwDQYJKoZIhvcNAQEFBQADggEBAGhQsCWLiaN2EOhPAW+JQP6o +XBOrLv5w6joahzBFVn1BiefzmlMKjibqKYxURRvMAsMkh82/MfL8V0w6ugxl81lu +i42dcxl9cKSVXKMw4bbBzJ2VQI5HTIABwefeNuy/eX6idVwYdt3ajAH7fUA8Q9Cq +vr6H8B+8mwoEqTVTEVlCSsC/EXsokYEUr06PPzRudKjDmijgj7zFaIioZNc8hk7g +ufEgrs/tmcNGylrwRHgCXjCRBt2NHlZ08l7A1AGU8HcHlSbG9Un/2q9kVHUkps0D +gtUaEK+x6jpAu/R8Ojezu/+ZEcwwjI/KOhG+84+ejFmtyEkrUdsAdEdLf/2dKsw= +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, +// CN=DigiNotar Services 1024 CA +// O=DigiNotar, C=NL +// Issuer: CN=Entrust.net Secure Server Certification Authority, +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), +// O=Entrust.net, +// C=US +// Serial: 1184640176 (46:9c:2c:b0) +-----BEGIN CERTIFICATE----- +MIIDzTCCAzagAwIBAgIERpwssDANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3 +MjYxNTU5MDBaFw0xMzA4MjYxNjI5MDBaMGgxCzAJBgNVBAYTAk5MMRIwEAYDVQQK +EwlEaWdpTm90YXIxIzAhBgNVBAMTGkRpZ2lOb3RhciBTZXJ2aWNlcyAxMDI0IENB +MSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEA2ptNXTz50eKLxsYIIMXZHkjsZlhneWIrQWP0iY1o2q+4 +lDaLGSSkoJPSmQ+yrS01Tc0vauH5mxkrvAQafi09UmTN8T5nD4ku6PJPrqYIoYX+ +oakJ5sarPkP8r3oDkdqmOaZh7phPGKjTs69mgumfvN1y+QYEvRLZGCTnq5NTi1kC +AwEAAaOCASYwggEiMBIGA1UdEwEB/wQIMAYBAf8CAQAwJwYDVR0lBCAwHgYIKwYB +BQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDBDARBgNVHSAECjAIMAYGBFUdIAAwMwYI +KwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5l +dDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1c3QubmV0L3NlcnZl +cjEuY3JsMB0GA1UdDgQWBBT+3JRJDG/vXH/G8RKZTxZJrfuCZTALBgNVHQ8EBAMC +AQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0BowGQYJKoZIhvZ9B0EA +BAwwChsEVjcuMQMCAIEwDQYJKoZIhvcNAQEFBQADgYEAY3RqN6k/lpxmyFisCcnv +9WWUf6MCxDgxvV0jh+zUVrLJsm7kBQb87PX6iHBZ1O7m3bV6oKNgLwIMq94SXa/w +NUuqikeRGvWFLELHHe+VQ7NeuJWTpdrFKKqtci0xrZlrbP+MISevrZqRK8fdWMNu +B8WfedLHjFW/TMcnXlEWKz4= +-----END CERTIFICATE----- + +// Subject: CN=Buster Paper Comercial Ltda, +// O=Buster Paper Comercial Ltda, +// L=S?o Jos? Dos Campos, +// ST=S?o Paulo, +// C=BR +// Issuer: CN=DigiCert Assured ID Code Signing CA-1, +// OU=www.digicert.com, +// O=DigiCert Inc, +// C=US +// Serial: 07:b4:4c:db:ff:fb:78:de:05:f4:26:16:72:a6:73:12 +-----BEGIN CERTIFICATE----- +MIIGwzCCBaugAwIBAgIQB7RM2//7eN4F9CYWcqZzEjANBgkqhkiG9w0BAQUFADBv +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv +ZGUgU2lnbmluZyBDQS0xMB4XDTEzMDExNzAwMDAwMFoXDTE0MDEyMjEyMDAwMFow +gY4xCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMR4wHAYDVQQHDBVT +w6NvIEpvc8OpIERvcyBDYW1wb3MxJDAiBgNVBAoTG0J1c3RlciBQYXBlciBDb21l +cmNpYWwgTHRkYTEkMCIGA1UEAxMbQnVzdGVyIFBhcGVyIENvbWVyY2lhbCBMdGRh +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzO0l6jWIpEfO2oUpVHpL +HETj5lzivNb0S9jKHgGJax917czh81PnGTxwxFXd6gLJuy/XFHvmiSi8g8jzlymn +2Ji5zQ3CPaz7nomJokSUDlMVJ2qYWtctw4jrdjuI4qtn+koXXUFkWjkf8h8251I4 +tUs7S49HE2Go5owCYP3byajj7fsFAYR/Xb7TdVtndkZsUB/YgOjHovyACjouaNCi +mDiRyQ6zLLjZGiyeD65Yiseuhp5b8/BL5h1p7w76QYMYMVQNAdtDKut2R8MBpuWf +Ny7Eoi0x/gm1p9X5Rcl5aN7K0G4UtTAJKbkuUfXddsyFoM0Nx8uo8SgNQ8Y/X5Jx +BwIDAQABo4IDOTCCAzUwHwYDVR0jBBgwFoAUe2jOKarAF75JeuHlP9an90WPNTIw +HQYDVR0OBBYEFFLZ3n5nt/Eer7n1bvtOqMb1qKO5MA4GA1UdDwEB/wQEAwIHgDAT +BgNVHSUEDDAKBggrBgEFBQcDAzBzBgNVHR8EbDBqMDOgMaAvhi1odHRwOi8vY3Js +My5kaWdpY2VydC5jb20vYXNzdXJlZC1jcy0yMDExYS5jcmwwM6AxoC+GLWh0dHA6 +Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9hc3N1cmVkLWNzLTIwMTFhLmNybDCCAcQGA1Ud +IASCAbswggG3MIIBswYJYIZIAYb9bAMBMIIBpDA6BggrBgEFBQcCARYuaHR0cDov +L3d3dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsG +AQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABD +AGUAcgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABh +AGMAYwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQBy +AHQAIABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBn +ACAAUABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABs +AGkAbQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABp +AG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBl +AGYAZQByAGUAbgBjAGUALjCBggYIKwYBBQUHAQEEdjB0MCQGCCsGAQUFBzABhhho +dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTAYIKwYBBQUHMAKGQGh0dHA6Ly9jYWNl +cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENvZGVTaWduaW5nQ0Et +MS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAPTTQvpOIikXI +hTLnNbajaFRR5GhQpTzUNgBfF9VYSlNw/wMjpGsrh5RxaJCip52jbehmTgjMRhft +jRYyml44PAVsCcR9uEoDpCZYpI1fHI1R+F8jd1C9rqprbSwwOG4xlg4SmvTHYs6e +gBItQ/1p9XY+Sf4Wv1qOuOFL1qvV/5VyR2zdlOQCmKCeMgxt6a/tHLBDiAA67D44 +/vfdoNJl0CU2It0PO60jdCPFNWIRcxL+OSDqAoePeUC7xQ+JsTEIxuUE8+d6w6fc +BV2mYb1flh22t46GLjh4gyo7xw3aL6L0L0jzlTT6IcEw6NIbaPbIKj/npQnHobYj +XMuKLxbh7g== +-----END CERTIFICATE----- + +// Subject: CN=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, +// O=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, +// L=S?o Paulo, +// ST=S?o Paulo, +// C=BR +// Issuer: CN=DigiCert Assured ID Code Signing CA-1, +// OU=www.digicert.com, +// O=DigiCert Inc, +// C=US +// Serial: 0a:38:9b:95:ee:73:6d:d1:3b:c0:ed:74:3f:d7:4d:2f +-----BEGIN CERTIFICATE----- +MIIG4DCCBcigAwIBAgIQCjible5zbdE7wO10P9dNLzANBgkqhkiG9w0BAQUFADBv +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv +ZGUgU2lnbmluZyBDQS0xMB4XDTEyMTEwOTAwMDAwMFoXDTEzMTExNDEyMDAwMFow +gasxCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMRMwEQYDVQQHDApT +w6NvIFBhdWxvMTgwNgYDVQQKEy9CVVNURVIgQVNTSVNURU5DSUEgVEVDTklDQSBF +TEVUUk9OSUNBIExUREEgLSBNRTE4MDYGA1UEAxMvQlVTVEVSIEFTU0lTVEVOQ0lB +IFRFQ05JQ0EgRUxFVFJPTklDQSBMVERBIC0gTUUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDAqNeEs5/B2CTXGjTOkUIdu6jV6qulOZwdw4sefHWYj1UR +4z6zPk9kjpUgbnb402RFq88QtfInwddZ/wXn9OxMtDd/3TnC7HrhNS7ga79ZFL2V +JnmzKHum2Yvh0q82QEJ9tHBR2X9VdKpUIH08Zs3k6cWWM1H0YX0cxA/HohhesQJW +kwJ3urOIJiH/HeByDk8a1NS8safcCxk5vxvW4WvCg43iT09LeHY5Aa8abKw8lqVb +0tD5ZSIjdmdj3TT1U37iAHLLRM2DXbxfdbhouUX1c5U1ZHAMA67HwjKiseOiDaHj +NUGbC37C+cgbc9VVM/cURD8WvS0Kj6fQv7F2QtJDAgMBAAGjggM5MIIDNTAfBgNV +HSMEGDAWgBR7aM4pqsAXvkl64eU/1qf3RY81MjAdBgNVHQ4EFgQU88EXKAyDsh30 +o9+Gu9a4xUy+FSMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD +MHMGA1UdHwRsMGowM6AxoC+GLWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9hc3N1 +cmVkLWNzLTIwMTFhLmNybDAzoDGgL4YtaHR0cDovL2NybDQuZGlnaWNlcnQuY29t +L2Fzc3VyZWQtY3MtMjAxMWEuY3JsMIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgB +hv1sAwEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9z +c2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4A +eQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQA +ZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUA +IABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAA +YQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcA +cgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIA +aQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQA +ZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMIGC +BggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0 +LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp +Z2lDZXJ0QXNzdXJlZElEQ29kZVNpZ25pbmdDQS0xLmNydDAMBgNVHRMBAf8EAjAA +MA0GCSqGSIb3DQEBBQUAA4IBAQAei1QmiXepje8OIfo/WonD4MIXgpPr2dfRaquQ +A8q63OpTRSveyqdQDCSPpDRF/nvO1Y30yksZvIH1tNBsW5LBdxAKN3lFdBlqBwtE +Q3jHc0KVVYRJ0FBaGE/PJHmRajscdAhYIcMPhTga0u0tDK+wOHEq3993dfl6yHjA +XHU2iW5pnk75ZoE39zALD5eKXT8ZXrET5c3XUFJKWA+XuGmdmyzqo0Au49PanBv9 +UlZnabYfqoMArqMS0tGSX4cGgi9/2E+pHG9BX4sFW+ZDumroOA2pxyMWEKjxePEL +zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc +-----END CERTIFICATE----- + +// Subject: CN=CLEARESULT CONSULTING INC., OU=Corporate IT, +// O=CLEARESULT CONSULTING INC., L=Austin, ST=TX, C=US +// Issuer: SERIALNUMBER=07969287, +// CN=Go Daddy Secure Certification Authority, +// OU=http://certificates.godaddy.com/repository, +// O="GoDaddy.com, Inc.", +// L=Scottsdale, +// ST=Arizona, +// C=US +// Serial: 2b:73:43:2a:a8:4f:44 +-----BEGIN CERTIFICATE----- +MIIFYjCCBEqgAwIBAgIHK3NDKqhPRDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE +BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY +BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm +aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5 +IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky +ODcwHhcNMTIwMjE1MjEwOTA2WhcNMTQwMjE1MjEwOTA2WjCBjDELMAkGA1UEBgwC +VVMxCzAJBgNVBAgMAlRYMQ8wDQYDVQQHDAZBdXN0aW4xIzAhBgNVBAoMGkNMRUFS +RVNVTFQgQ09OU1VMVElORyBJTkMuMRUwEwYDVQQLDAxDb3Jwb3JhdGUgSVQxIzAh +BgNVBAMMGkNMRUFSRVNVTFQgQ09OU1VMVElORyBJTkMuMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAtIOjCKeAicull+7ZIzt0/4ya3IeXUFlfypqKMLkU +IbKjn0P5uMj6VE3rlbZr44RCegxvdnR6umBh1c0ZXoN3o+yc0JKcKcLiApmJJ277 +p7IbLwYDhBXRQNoIJm187IOMRPIxsKN4hL91txn9jGBmW+9zKlJlNhR5R7vjwU2E +jrH/6oqsc9EM2yYpfjlNv6+3jSwAYZCkSWr+27PQOV+YHKmIxtJjX0upFz5FdIrV +9CCX+L2Kji1THOkSgG4QTbYxmEcHqGViWz8hXLeNXjcbEsPuIiAu3hknxRHfUTE/ +U0Lh0Ug1e3LrJu+WnxM2SmUY4krsZ22c0yWUW9hzWITIjQIDAQABo4IBhzCCAYMw +DwYDVR0TAQH/BAUwAwEBADATBgNVHSUEDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8E +BAMCB4AwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9n +ZHM1LTE2LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcCMDkwNwYIKwYBBQUH +AgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8w +gYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRk +eS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHku +Y29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9 +rGEyk2xF1uLuhV+auud2mWjM5zAdBgNVHQ4EFgQUDtdeKqeN2QkcbEp1HovFieNB +XiowDQYJKoZIhvcNAQEFBQADggEBAD74Agw5tvi2aBl4/f/s7/VE/BClzDsKMb9K +v9qpeC45ZA/jelxV11HKbQnVF194gDb7D2H9OsAsRUy8HVKbXEcc/8dKvwOqb+BC +2i/EmfjLgmCfezNFtLq8xcPxF3zIRc44vPrK0z4YZsaHdH+yTEJ51p5EMdTqaLaP +4n5m8LX3RfqlQB9dYFe6dUoYZjKm9d/pIRww3VqfOzjl42Edi1w6dWmBVMx1NZuR +DBabJH1vJ9Gd+KwxMCmBZ6pQPl28JDimhJhI2LNqU349uADQVV0HJosddN/ARyyI +LSIQO7BnNVKVG9Iujf33bvPNeg0qNz5qw+rKKq97Pqeum+L5oKU= +-----END CERTIFICATE----- diff --git a/jdk/test/lib/security/CheckBlacklistedCerts.java b/jdk/test/lib/security/CheckBlacklistedCerts.java new file mode 100644 index 00000000000..1f162b3e499 --- /dev/null +++ b/jdk/test/lib/security/CheckBlacklistedCerts.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013, 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 8011402 + * @summary Move blacklisting certificate logic from hard code to data + */ + +import sun.security.util.UntrustedCertificates; + +import java.io.*; +import java.security.KeyStore; +import java.security.cert.*; +import java.util.*; + +public class CheckBlacklistedCerts { + public static void main(String[] args) throws Exception { + + String home = System.getProperty("java.home"); + boolean failed = false; + + // Root CAs should always be trusted + File file = new File(home, "lib/security/cacerts"); + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + try (FileInputStream fis = new FileInputStream(file)) { + ks.load(new FileInputStream(file), null); + } + System.out.println("Check for cacerts: " + ks.size()); + for (String alias: Collections.list(ks.aliases())) { + X509Certificate cert = (X509Certificate)ks.getCertificate(alias); + if (UntrustedCertificates.isUntrusted(cert)) { + System.out.print(alias + " is untrusted"); + failed = true; + } + } + + // All certs in the pem files + Set blacklisted = new HashSet<>(); + + // Hopefully src comes with test, but it might be missing if doing + // a -testonly JPRT job. + File[] blacklists = { + new File(System.getProperty("test.src"), + "../../../src/share/lib/security/blacklisted.certs.pem"), + new File(System.getProperty("test.src"), + "../../../src/closed/share/lib/security/blacklisted.certs.pem") + }; + + // Is this an OPENJDK build? + if (!new File(home, "lib/security/local_policy.jar").exists()) { + blacklists = Arrays.copyOf(blacklists, 1); + } + + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + for (File blacklist: blacklists) { + System.out.print("Check for " + blacklist + ": "); + if (!blacklist.exists()) { + System.out.println("does not exist"); + } else { + try (FileInputStream fis = new FileInputStream(blacklist)) { + Collection certs + = cf.generateCertificates(fis); + System.out.println(certs.size()); + for (Certificate c: certs) { + blacklisted.add(c); + X509Certificate cert = ((X509Certificate)c); + if (!UntrustedCertificates.isUntrusted(cert)) { + System.out.println(cert.getSubjectDN() + " is trusted"); + failed = true; + } + } + } + } + } + + // Check the blacklisted.certs file itself + file = new File(home, "lib/security/blacklisted.certs"); + System.out.print("Check for " + file + ": "); + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(new FileInputStream(file)))) { + int acount = 0; + int ccount = 0; + while (true) { + String line = reader.readLine(); + if (line == null) break; + if (line.startsWith("Algorithm")) { + acount++; + } else if (!line.isEmpty() && !line.startsWith("#")) { + ccount++; + } + } + System.out.println(acount + " algs, " + ccount + " certs" ); + if (acount != 1) { + System.out.println("There are " + acount + " algorithms"); + failed = true; + } + if (ccount != blacklisted.size() + && !blacklisted.isEmpty()) { + System.out.println("Wrong blacklisted.certs size: " + + ccount + " fingerprints, " + + blacklisted.size() + " certs"); + failed = true; + } + } + + if (failed) { + throw new Exception("Failed"); + } + } +} From 8290ada96c02e38f2d718a9060eeb3a0acdeb3ac Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Wed, 18 Sep 2013 15:13:10 +0100 Subject: [PATCH 0123/1294] 8015762: TEST_BUG: java/nio/channels/DatagramChannel/AdaptDatagramSocket.java failing intermittently [win] Reviewed-by: chegar, alanb --- .../java/nio/channels/DatagramChannel/AdaptDatagramSocket.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java b/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java index 1763ef3a11e..dbeb491acfe 100644 --- a/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java +++ b/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java @@ -136,7 +136,7 @@ public class AdaptDatagramSocket { echoServer.getPort()); test(address, 0, false, false); test(address, 0, false, true); - test(address, 5000, false, false); + test(address, 15000, false, false); } try (TestServers.UdpDiscardServer discardServer = TestServers.UdpDiscardServer.startNewServer()) { From 100b98aafa33e503f453a52cd41be3cbf4548be4 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Thu, 19 Sep 2013 17:04:45 +0400 Subject: [PATCH 0124/1294] 8017248: Compiler Diacritics Issue Reviewed-by: naoto --- .../classes/sun/launcher/LauncherHelper.java | 15 ++++++++++++++- jdk/test/tools/launcher/8017248/ClassÁ.java | 5 +++++ jdk/test/tools/launcher/8017248/test.sh | 16 ++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 jdk/test/tools/launcher/8017248/ClassÁ.java create mode 100644 jdk/test/tools/launcher/8017248/test.sh diff --git a/jdk/src/share/classes/sun/launcher/LauncherHelper.java b/jdk/src/share/classes/sun/launcher/LauncherHelper.java index 5a6f40442ed..dc6a10bfac2 100644 --- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java +++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java @@ -51,6 +51,7 @@ import java.nio.charset.Charset; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; +import java.text.Normalizer; import java.util.ResourceBundle; import java.text.MessageFormat; import java.util.ArrayList; @@ -493,7 +494,19 @@ public enum LauncherHelper { try { mainClass = scloader.loadClass(cn); } catch (NoClassDefFoundError | ClassNotFoundException cnfe) { - abort(cnfe, "java.launcher.cls.error1", cn); + if (System.getProperty("os.name", "").contains("OS X") + && Normalizer.isNormalized(cn, Normalizer.Form.NFD)) { + try { + // On Mac OS X since all names with diacretic symbols are given as decomposed it + // is possible that main class name comes incorrectly from the command line + // and we have to re-compose it + mainClass = scloader.loadClass(Normalizer.normalize(cn, Normalizer.Form.NFC)); + } catch (NoClassDefFoundError | ClassNotFoundException cnfe1) { + abort(cnfe, "java.launcher.cls.error1", cn); + } + } else { + abort(cnfe, "java.launcher.cls.error1", cn); + } } // set to mainClass appClass = mainClass; diff --git a/jdk/test/tools/launcher/8017248/ClassÁ.java b/jdk/test/tools/launcher/8017248/ClassÁ.java new file mode 100644 index 00000000000..2e264990c74 --- /dev/null +++ b/jdk/test/tools/launcher/8017248/ClassÁ.java @@ -0,0 +1,5 @@ +public class ClassÁ { + public static void main(String args[]) { + System.out.println("Succes!"); + } +} diff --git a/jdk/test/tools/launcher/8017248/test.sh b/jdk/test/tools/launcher/8017248/test.sh new file mode 100644 index 00000000000..7a96f46c223 --- /dev/null +++ b/jdk/test/tools/launcher/8017248/test.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# @test test.sh +# @bug 8017248 +# @summary Compiler Diacritics Issue +# @run shell test.sh + +OSNAME=`uname -s` +if [ "$OSNAME" == "Darwin" ] +then + rm *.class + ${TESTJAVA}/bin/javac *.java + ${TESTJAVA}/bin/java `echo *.class | cut -d. -f1` +else + echo Test is specific to Mac OS X, skipping. + exit 0 +fi From c7759dc643ac3768e1e05733f82583eed29040d2 Mon Sep 17 00:00:00 2001 From: Peter Levart Date: Thu, 19 Sep 2013 16:14:13 +0200 Subject: [PATCH 0125/1294] 8011940: java.lang.Class.getAnnotations() always enters synchronized method Reviewed-by: jfranck, chegar, psandoz, shade --- jdk/src/share/classes/java/lang/Class.java | 113 +++++++--- ...tionsInheritanceOrderRedefinitionTest.java | 210 ++++++++++++++++++ 2 files changed, 286 insertions(+), 37 deletions(-) create mode 100644 jdk/test/java/lang/annotation/AnnotationsInheritanceOrderRedefinitionTest.java diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index f884f2efe03..a09aa2c86a4 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -48,6 +48,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Set; import java.util.Map; @@ -2370,11 +2371,14 @@ public final class Class implements java.io.Serializable, private static final long reflectionDataOffset; // offset of Class.annotationType instance field private static final long annotationTypeOffset; + // offset of Class.annotationData instance field + private static final long annotationDataOffset; static { Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches reflectionDataOffset = objectFieldOffset(fields, "reflectionData"); annotationTypeOffset = objectFieldOffset(fields, "annotationType"); + annotationDataOffset = objectFieldOffset(fields, "annotationData"); } private static long objectFieldOffset(Field[] fields, String fieldName) { @@ -2396,6 +2400,12 @@ public final class Class implements java.io.Serializable, AnnotationType newType) { return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType); } + + static boolean casAnnotationData(Class clazz, + AnnotationData oldData, + AnnotationData newData) { + return unsafe.compareAndSwapObject(clazz, annotationDataOffset, oldData, newData); + } } /** @@ -2406,7 +2416,7 @@ public final class Class implements java.io.Serializable, private static boolean useCaches = true; // reflection data that might get invalidated when JVM TI RedefineClasses() is called - static class ReflectionData { + private static class ReflectionData { volatile Field[] declaredFields; volatile Field[] publicFields; volatile Method[] declaredMethods; @@ -3253,8 +3263,7 @@ public final class Class implements java.io.Serializable, public A getAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); - initAnnotationsIfNecessary(); - return (A) annotations.get(annotationClass); + return (A) annotationData().annotations.get(annotationClass); } /** @@ -3275,16 +3284,14 @@ public final class Class implements java.io.Serializable, public A[] getAnnotationsByType(Class annotationClass) { Objects.requireNonNull(annotationClass); - initAnnotationsIfNecessary(); - return AnnotationSupport.getMultipleAnnotations(annotations, annotationClass); + return AnnotationSupport.getMultipleAnnotations(annotationData().annotations, annotationClass); } /** * @since 1.5 */ public Annotation[] getAnnotations() { - initAnnotationsIfNecessary(); - return AnnotationParser.toArray(annotations); + return AnnotationParser.toArray(annotationData().annotations); } /** @@ -3296,8 +3303,7 @@ public final class Class implements java.io.Serializable, public A getDeclaredAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); - initAnnotationsIfNecessary(); - return (A) declaredAnnotations.get(annotationClass); + return (A) annotationData().declaredAnnotations.get(annotationClass); } /** @@ -3308,52 +3314,85 @@ public final class Class implements java.io.Serializable, public A[] getDeclaredAnnotationsByType(Class annotationClass) { Objects.requireNonNull(annotationClass); - initAnnotationsIfNecessary(); - return AnnotationSupport.getMultipleAnnotations(declaredAnnotations, annotationClass); + return AnnotationSupport.getMultipleAnnotations(annotationData().declaredAnnotations, annotationClass); } /** * @since 1.5 */ public Annotation[] getDeclaredAnnotations() { - initAnnotationsIfNecessary(); - return AnnotationParser.toArray(declaredAnnotations); + return AnnotationParser.toArray(annotationData().declaredAnnotations); + } + + // annotation data that might get invalidated when JVM TI RedefineClasses() is called + private static class AnnotationData { + final Map, Annotation> annotations; + final Map, Annotation> declaredAnnotations; + + // Value of classRedefinedCount when we created this AnnotationData instance + final int redefinedCount; + + AnnotationData(Map, Annotation> annotations, + Map, Annotation> declaredAnnotations, + int redefinedCount) { + this.annotations = annotations; + this.declaredAnnotations = declaredAnnotations; + this.redefinedCount = redefinedCount; + } } // Annotations cache - private transient Map, Annotation> annotations; - private transient Map, Annotation> declaredAnnotations; - // Value of classRedefinedCount when we last cleared the cached annotations and declaredAnnotations fields - private transient int lastAnnotationsRedefinedCount = 0; + @SuppressWarnings("UnusedDeclaration") + private volatile transient AnnotationData annotationData; - // Clears cached values that might possibly have been obsoleted by - // a class redefinition. - private void clearAnnotationCachesOnClassRedefinition() { - if (lastAnnotationsRedefinedCount != classRedefinedCount) { - annotations = declaredAnnotations = null; - lastAnnotationsRedefinedCount = classRedefinedCount; + private AnnotationData annotationData() { + while (true) { // retry loop + AnnotationData annotationData = this.annotationData; + int classRedefinedCount = this.classRedefinedCount; + if (annotationData != null && + annotationData.redefinedCount == classRedefinedCount) { + return annotationData; + } + // null or stale annotationData -> optimistically create new instance + AnnotationData newAnnotationData = createAnnotationData(classRedefinedCount); + // try to install it + if (Atomic.casAnnotationData(this, annotationData, newAnnotationData)) { + // successfully installed new AnnotationData + return newAnnotationData; + } } } - private synchronized void initAnnotationsIfNecessary() { - clearAnnotationCachesOnClassRedefinition(); - if (annotations != null) - return; - declaredAnnotations = AnnotationParser.parseAnnotations( - getRawAnnotations(), getConstantPool(), this); + private AnnotationData createAnnotationData(int classRedefinedCount) { + Map, Annotation> declaredAnnotations = + AnnotationParser.parseAnnotations(getRawAnnotations(), getConstantPool(), this); Class superClass = getSuperclass(); - if (superClass == null) { + Map, Annotation> annotations = null; + if (superClass != null) { + Map, Annotation> superAnnotations = + superClass.annotationData().annotations; + for (Map.Entry, Annotation> e : superAnnotations.entrySet()) { + Class annotationClass = e.getKey(); + if (AnnotationType.getInstance(annotationClass).isInherited()) { + if (annotations == null) { // lazy construction + annotations = new LinkedHashMap<>((Math.max( + declaredAnnotations.size(), + Math.min(12, declaredAnnotations.size() + superAnnotations.size()) + ) * 4 + 2) / 3 + ); + } + annotations.put(annotationClass, e.getValue()); + } + } + } + if (annotations == null) { + // no inherited annotations -> share the Map with declaredAnnotations annotations = declaredAnnotations; } else { - annotations = new HashMap<>(); - superClass.initAnnotationsIfNecessary(); - for (Map.Entry, Annotation> e : superClass.annotations.entrySet()) { - Class annotationClass = e.getKey(); - if (AnnotationType.getInstance(annotationClass).isInherited()) - annotations.put(annotationClass, e.getValue()); - } + // at least one inherited annotation -> declared may override inherited annotations.putAll(declaredAnnotations); } + return new AnnotationData(annotations, declaredAnnotations, classRedefinedCount); } // Annotation types cache their internal (AnnotationType) form diff --git a/jdk/test/java/lang/annotation/AnnotationsInheritanceOrderRedefinitionTest.java b/jdk/test/java/lang/annotation/AnnotationsInheritanceOrderRedefinitionTest.java new file mode 100644 index 00000000000..909154a7c1e --- /dev/null +++ b/jdk/test/java/lang/annotation/AnnotationsInheritanceOrderRedefinitionTest.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2013, 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 8011940 + * @summary Test inheritance, order and class redefinition behaviour of RUNTIME + * class annotations + * @author plevart + */ + +import sun.reflect.annotation.AnnotationParser; + +import java.lang.annotation.Annotation; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.StringJoiner; + +public class AnnotationsInheritanceOrderRedefinitionTest { + + @Retention(RetentionPolicy.RUNTIME) + @Inherited + @interface Ann1 { + String value(); + } + + @Retention(RetentionPolicy.RUNTIME) + @Inherited + @interface Ann2 { + String value(); + } + + @Retention(RetentionPolicy.RUNTIME) + @Inherited + @interface Ann3 { + String value(); + } + + @Ann1("A") + @Ann2("A") + static class A {} + + @Ann3("B") + static class B extends A {} + + @Ann1("C") + @Ann3("C") + static class C extends B {} + + public static void main(String[] args) { + + StringBuilder msgs = new StringBuilder(); + boolean ok = true; + + ok &= annotationsEqual(msgs, A.class, true, + ann(Ann1.class, "A"), ann(Ann2.class, "A")); + ok &= annotationsEqual(msgs, A.class, false, + ann(Ann1.class, "A"), ann(Ann2.class, "A")); + ok &= annotationsEqual(msgs, B.class, true, + ann(Ann3.class, "B")); + ok &= annotationsEqual(msgs, B.class, false, + ann(Ann1.class, "A"), ann(Ann2.class, "A"), ann(Ann3.class, "B")); + ok &= annotationsEqual(msgs, C.class, true, + ann(Ann1.class, "C"), ann(Ann3.class, "C")); + ok &= annotationsEqual(msgs, C.class, false, + ann(Ann1.class, "C"), ann(Ann2.class, "A"), ann(Ann3.class, "C")); + + Annotation[] declaredAnnotatiosA = A.class.getDeclaredAnnotations(); + Annotation[] annotationsA = A.class.getAnnotations(); + Annotation[] declaredAnnotatiosB = B.class.getDeclaredAnnotations(); + Annotation[] annotationsB = B.class.getAnnotations(); + Annotation[] declaredAnnotatiosC = C.class.getDeclaredAnnotations(); + Annotation[] annotationsC = C.class.getAnnotations(); + + incrementClassRedefinedCount(A.class); + incrementClassRedefinedCount(B.class); + incrementClassRedefinedCount(C.class); + + ok &= annotationsEqualButNotSame(msgs, A.class, true, declaredAnnotatiosA); + ok &= annotationsEqualButNotSame(msgs, A.class, false, annotationsA); + ok &= annotationsEqualButNotSame(msgs, B.class, true, declaredAnnotatiosB); + ok &= annotationsEqualButNotSame(msgs, B.class, false, annotationsB); + ok &= annotationsEqualButNotSame(msgs, C.class, true, declaredAnnotatiosC); + ok &= annotationsEqualButNotSame(msgs, C.class, false, annotationsC); + + if (!ok) { + throw new RuntimeException("test failure\n" + msgs); + } + } + + // utility methods + + private static boolean annotationsEqualButNotSame(StringBuilder msgs, + Class declaringClass, boolean declaredOnly, Annotation[] oldAnns) { + if (!annotationsEqual(msgs, declaringClass, declaredOnly, oldAnns)) { + return false; + } + Annotation[] anns = declaredOnly + ? declaringClass.getDeclaredAnnotations() + : declaringClass.getAnnotations(); + List sameAnns = new ArrayList<>(); + for (int i = 0; i < anns.length; i++) { + if (anns[i] == oldAnns[i]) { + sameAnns.add(anns[i]); + } + } + if (!sameAnns.isEmpty()) { + msgs.append(declaredOnly ? "declared " : "").append("annotations for ") + .append(declaringClass.getSimpleName()) + .append(" not re-parsed after class redefinition: ") + .append(toSimpleString(sameAnns)).append("\n"); + return false; + } else { + return true; + } + } + + private static boolean annotationsEqual(StringBuilder msgs, + Class declaringClass, boolean declaredOnly, Annotation... expectedAnns) { + Annotation[] anns = declaredOnly + ? declaringClass.getDeclaredAnnotations() + : declaringClass.getAnnotations(); + if (!Arrays.equals(anns, expectedAnns)) { + msgs.append(declaredOnly ? "declared " : "").append("annotations for ") + .append(declaringClass.getSimpleName()).append(" are: ") + .append(toSimpleString(anns)).append(", expected: ") + .append(toSimpleString(expectedAnns)).append("\n"); + return false; + } else { + return true; + } + } + + private static Annotation ann(Class annotationType, + Object value) { + return AnnotationParser.annotationForMap(annotationType, + Collections.singletonMap("value", value)); + } + + private static String toSimpleString(List anns) { + return toSimpleString(anns.toArray(new Annotation[anns.size()])); + } + + private static String toSimpleString(Annotation[] anns) { + StringJoiner joiner = new StringJoiner(", "); + for (Annotation ann : anns) { + joiner.add(toSimpleString(ann)); + } + return joiner.toString(); + } + + private static String toSimpleString(Annotation ann) { + Class annotationType = ann.annotationType(); + Object value; + try { + value = annotationType.getDeclaredMethod("value").invoke(ann); + } catch (IllegalAccessException | InvocationTargetException + | NoSuchMethodException e) { + throw new RuntimeException(e); + } + return "@" + annotationType.getSimpleName() + "(" + value + ")"; + } + + private static final Field classRedefinedCountField; + + static { + try { + classRedefinedCountField = Class.class.getDeclaredField("classRedefinedCount"); + classRedefinedCountField.setAccessible(true); + } catch (NoSuchFieldException e) { + throw new Error(e); + } + } + + private static void incrementClassRedefinedCount(Class clazz) { + try { + classRedefinedCountField.set(clazz, + ((Integer) classRedefinedCountField.get(clazz)) + 1); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} From 6ea068de3a75428cfdf9b19b5f59b4537fd9c0a5 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Thu, 19 Sep 2013 10:06:30 -0700 Subject: [PATCH 0126/1294] 8023113: tools/jar/ChangeDir.java fails if /tmp/a exists Updated the test case Reviewed-by: alanb --- jdk/test/tools/jar/ChangeDir.java | 65 ++++++++++++++++--------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/jdk/test/tools/jar/ChangeDir.java b/jdk/test/tools/jar/ChangeDir.java index f811618af46..6f65fa8542e 100644 --- a/jdk/test/tools/jar/ChangeDir.java +++ b/jdk/test/tools/jar/ChangeDir.java @@ -23,13 +23,15 @@ /** * @test - * @bug 4806786 + * @bug 4806786 8023113 * @summary jar -C doesn't ignore multiple // in path */ import java.io.*; +import java.nio.file.*; import java.util.*; import java.util.jar.*; +import java.util.stream.Stream; import sun.tools.jar.Main; public class ChangeDir { @@ -37,13 +39,16 @@ public class ChangeDir { private final static String fileName = "hello.txt"; /** Remove dirs & files needed for test. */ - private static void cleanup(File dir) throws Throwable { - if (dir != null && dir.exists()) { - for (File ff : dir.listFiles()) { - check(ff.delete()); + private static void cleanup(Path dir) { + try { + if (Files.isDirectory(dir)) { + try (Stream s = Files.list(dir)) { + s.forEach( p -> cleanup(p)); + } } - check(dir.delete()); - check(new File(jarName).delete()); + Files.delete(dir); + } catch (IOException x) { + fail(x.toString()); } } @@ -62,19 +67,16 @@ public class ChangeDir { } static void doTest(String sep) throws Throwable { - File testDir = null; - JarFile jf = null; + Path topDir = Files.createTempDirectory("delete"); try { + Files.deleteIfExists(Paths.get(jarName)); + // Create a subdirectory "a/b" - File f = File.createTempFile("delete", ".me"); - String dirName = f.getParent(); - testDir = new File(dirName + sep + "a" + sep + "b"); - cleanup(testDir); - check(testDir.mkdirs()); + Path testDir = Files.createDirectories(topDir.resolve("a").resolve("b")); // Create file in that subdirectory - File testFile = new File(testDir, fileName); - check(testFile.createNewFile()); + Path testFile = testDir.resolve(fileName); + Files.createFile(testFile); // Create a jar file from that subdirectory, but with a // in the // path name. @@ -82,33 +84,32 @@ public class ChangeDir { argList.add("cf"); argList.add(jarName); argList.add("-C"); - argList.add(dirName + sep + "a" + sep + sep + "b"); // Note double 'sep' is intentional + argList.add(topDir.toString() + sep + "a" + sep + sep + "b"); // Note double 'sep' is intentional argList.add(fileName); - String jarArgs[] = new String[argList.size()]; - jarArgs = argList.toArray(jarArgs); Main jarTool = new Main(System.out, System.err, "jar"); - if (!jarTool.run(jarArgs)) { + if (!jarTool.run(argList.toArray(new String[argList.size()]))) { fail("Could not create jar file."); } // Check that the entry for hello.txt does *not* have a pathname. - jf = new JarFile(jarName); - for (Enumeration i = jf.entries(); i.hasMoreElements();) { - JarEntry je = i.nextElement(); - String name = je.getName(); - if (name.indexOf(fileName) != -1) { - if (name.indexOf(fileName) != 0) { - fail(String.format( - "Expected '%s' but got '%s'%n", fileName, name)); + try (JarFile jf = new JarFile(jarName)) { + for (Enumeration i = jf.entries(); i.hasMoreElements();) { + JarEntry je = i.nextElement(); + String name = je.getName(); + if (name.indexOf(fileName) != -1) { + if (name.indexOf(fileName) != 0) { + fail(String.format( + "Expected '%s' but got '%s'%n", fileName, name)); + } else { + pass(); + } } } } } finally { - if (jf != null) { - jf.close(); - } - cleanup(testDir); + cleanup(topDir); + Files.deleteIfExists(Paths.get(jarName)); } } From 3a559a7ea0774035bf3545735e49264f755da292 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Wed, 18 Sep 2013 10:49:34 -0700 Subject: [PATCH 0127/1294] 8025002: "".codePoints().sorted().iterator().hasNext() causes NegativeArraySizeException Reviewed-by: henryjen, alanb --- jdk/src/share/classes/java/lang/CharSequence.java | 2 +- jdk/test/java/lang/CharSequence/DefaultTest.java | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/lang/CharSequence.java b/jdk/src/share/classes/java/lang/CharSequence.java index ac80b22f066..a74a9d0d424 100644 --- a/jdk/src/share/classes/java/lang/CharSequence.java +++ b/jdk/src/share/classes/java/lang/CharSequence.java @@ -228,7 +228,7 @@ public interface CharSequence { Spliterators.spliteratorUnknownSize( new CodePointIterator(), Spliterator.ORDERED), - Spliterator.SUBSIZED | Spliterator.SIZED | Spliterator.ORDERED, + Spliterator.ORDERED, false); } } diff --git a/jdk/test/java/lang/CharSequence/DefaultTest.java b/jdk/test/java/lang/CharSequence/DefaultTest.java index dd51ce64122..856b980ff00 100644 --- a/jdk/test/java/lang/CharSequence/DefaultTest.java +++ b/jdk/test/java/lang/CharSequence/DefaultTest.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; import java.util.PrimitiveIterator; +import java.util.Spliterator; import java.util.stream.Collectors; import org.testng.annotations.Test; @@ -34,7 +35,7 @@ import static org.testng.Assert.*; /* * @test * @summary Unit test for CharSequence default methods - * @bug 8012665 + * @bug 8012665 8025002 * @run testng DefaultTest */ @@ -53,6 +54,12 @@ public class DefaultTest { assertEquals(list, Arrays.asList((int) 'a', (int) 'b', (int) 'c')); } + public void testCodePointsCharacteristics() { + Spliterator.OfInt s = "".codePoints().spliterator(); + assertFalse(s.hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED)); + assertTrue(s.hasCharacteristics(Spliterator.ORDERED)); + } + @Test(expectedExceptions = NoSuchElementException.class) public void testEmptyCodePoints() { PrimitiveIterator.OfInt s = "".codePoints().iterator(); From 0f59d418d8115e4106c8d81071995d5f4f4352d0 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Thu, 19 Sep 2013 20:41:54 -0700 Subject: [PATCH 0128/1294] 8024405: Spliterators.spliterator should support CONCURRENT characteristic Reviewed-by: martin --- .../share/classes/java/util/Spliterator.java | 2 +- .../share/classes/java/util/Spliterators.java | 78 +++++----- .../SpliteratorCharacteristics.java | 142 +++++++++++++++++- ...SpliteratorTraversingAndSplittingTest.java | 11 +- 4 files changed, 194 insertions(+), 39 deletions(-) diff --git a/jdk/src/share/classes/java/util/Spliterator.java b/jdk/src/share/classes/java/util/Spliterator.java index 542aec76cde..08d8f1522ca 100644 --- a/jdk/src/share/classes/java/util/Spliterator.java +++ b/jdk/src/share/classes/java/util/Spliterator.java @@ -539,7 +539,7 @@ public interface Spliterator { * Spliterator is expected to have a documented policy concerning the impact * of modifications during traversal. * - *

    A top-level Spliterator should not report {@code CONCURRENT} and + *

    A top-level Spliterator should not report both {@code CONCURRENT} and * {@code SIZED}, since the finite size, if known, may change if the source * is concurrently modified during traversal. Such a Spliterator is * inconsistent and no guarantees can be made about any computation using diff --git a/jdk/src/share/classes/java/util/Spliterators.java b/jdk/src/share/classes/java/util/Spliterators.java index afa2fd379cc..3f97a833a68 100644 --- a/jdk/src/share/classes/java/util/Spliterators.java +++ b/jdk/src/share/classes/java/util/Spliterators.java @@ -409,16 +409,16 @@ public final class Spliterators { * * @param Type of elements * @param c The collection - * @param additionalCharacteristics Additional spliterator characteristics - * of this spliterator's source or elements beyond {@code SIZED} and - * {@code SUBSIZED} which are are always reported + * @param characteristics Characteristics of this spliterator's source or + * elements. The characteristics {@code SIZED} and {@code SUBSIZED} + * are additionally reported unless {@code CONCURRENT} is supplied. * @return A spliterator from an iterator * @throws NullPointerException if the given collection is {@code null} */ public static Spliterator spliterator(Collection c, - int additionalCharacteristics) { + int characteristics) { return new IteratorSpliterator<>(Objects.requireNonNull(c), - additionalCharacteristics); + characteristics); } /** @@ -439,17 +439,17 @@ public final class Spliterators { * @param iterator The iterator for the source * @param size The number of elements in the source, to be reported as * initial {@code estimateSize} - * @param additionalCharacteristics Additional spliterator characteristics - * of this spliterator's source or elements beyond {@code SIZED} and - * {@code SUBSIZED} which are are always reported + * @param characteristics Characteristics of this spliterator's source or + * elements. The characteristics {@code SIZED} and {@code SUBSIZED} + * are additionally reported unless {@code CONCURRENT} is supplied. * @return A spliterator from an iterator * @throws NullPointerException if the given iterator is {@code null} */ public static Spliterator spliterator(Iterator iterator, long size, - int additionalCharacteristics) { + int characteristics) { return new IteratorSpliterator<>(Objects.requireNonNull(iterator), size, - additionalCharacteristics); + characteristics); } /** @@ -467,7 +467,7 @@ public final class Spliterators { * * @param Type of elements * @param iterator The iterator for the source - * @param characteristics Properties of this spliterator's source + * @param characteristics Characteristics of this spliterator's source * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are * ignored and are not reported.) * @return A spliterator from an iterator @@ -496,17 +496,17 @@ public final class Spliterators { * @param iterator The iterator for the source * @param size The number of elements in the source, to be reported as * initial {@code estimateSize}. - * @param additionalCharacteristics Additional spliterator characteristics - * of this spliterator's source or elements beyond {@code SIZED} and - * {@code SUBSIZED} which are are always reported + * @param characteristics Characteristics of this spliterator's source or + * elements. The characteristics {@code SIZED} and {@code SUBSIZED} + * are additionally reported unless {@code CONCURRENT} is supplied. * @return A spliterator from an iterator * @throws NullPointerException if the given iterator is {@code null} */ public static Spliterator.OfInt spliterator(PrimitiveIterator.OfInt iterator, long size, - int additionalCharacteristics) { + int characteristics) { return new IntIteratorSpliterator(Objects.requireNonNull(iterator), - size, additionalCharacteristics); + size, characteristics); } /** @@ -524,7 +524,7 @@ public final class Spliterators { * operated on after the spliterator is returned. * * @param iterator The iterator for the source - * @param characteristics Properties of this spliterator's source + * @param characteristics Characteristics of this spliterator's source * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are * ignored and are not reported.) * @return A spliterator from an iterator @@ -553,17 +553,17 @@ public final class Spliterators { * @param iterator The iterator for the source * @param size The number of elements in the source, to be reported as * initial {@code estimateSize}. - * @param additionalCharacteristics Additional spliterator characteristics - * of this spliterator's source or elements beyond {@code SIZED} and - * {@code SUBSIZED} which are are always reported + * @param characteristics Characteristics of this spliterator's source or + * elements. The characteristics {@code SIZED} and {@code SUBSIZED} + * are additionally reported unless {@code CONCURRENT} is supplied. * @return A spliterator from an iterator * @throws NullPointerException if the given iterator is {@code null} */ public static Spliterator.OfLong spliterator(PrimitiveIterator.OfLong iterator, long size, - int additionalCharacteristics) { + int characteristics) { return new LongIteratorSpliterator(Objects.requireNonNull(iterator), - size, additionalCharacteristics); + size, characteristics); } /** @@ -581,7 +581,7 @@ public final class Spliterators { * operated on after the spliterator is returned. * * @param iterator The iterator for the source - * @param characteristics Properties of this spliterator's source + * @param characteristics Characteristics of this spliterator's source * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are * ignored and are not reported.) * @return A spliterator from an iterator @@ -610,17 +610,17 @@ public final class Spliterators { * @param iterator The iterator for the source * @param size The number of elements in the source, to be reported as * initial {@code estimateSize} - * @param additionalCharacteristics Additional spliterator characteristics - * of this spliterator's source or elements beyond {@code SIZED} and - * {@code SUBSIZED} which are are always reported + * @param characteristics Characteristics of this spliterator's source or + * elements. The characteristics {@code SIZED} and {@code SUBSIZED} + * are additionally reported unless {@code CONCURRENT} is supplied. * @return A spliterator from an iterator * @throws NullPointerException if the given iterator is {@code null} */ public static Spliterator.OfDouble spliterator(PrimitiveIterator.OfDouble iterator, long size, - int additionalCharacteristics) { + int characteristics) { return new DoubleIteratorSpliterator(Objects.requireNonNull(iterator), - size, additionalCharacteristics); + size, characteristics); } /** @@ -638,7 +638,7 @@ public final class Spliterators { * operated on after the spliterator is returned. * * @param iterator The iterator for the source - * @param characteristics Properties of this spliterator's source + * @param characteristics Characteristics of this spliterator's source * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are * ignored and are not reported.) * @return A spliterator from an iterator @@ -1710,7 +1710,9 @@ public final class Spliterators { public IteratorSpliterator(Collection collection, int characteristics) { this.collection = collection; this.it = null; - this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED; + this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0 + ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED + : characteristics; } /** @@ -1727,7 +1729,9 @@ public final class Spliterators { this.collection = null; this.it = iterator; this.est = size; - this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED; + this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0 + ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED + : characteristics; } /** @@ -1857,7 +1861,9 @@ public final class Spliterators { public IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, long size, int characteristics) { this.it = iterator; this.est = size; - this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED; + this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0 + ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED + : characteristics; } /** @@ -1949,7 +1955,9 @@ public final class Spliterators { public LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics) { this.it = iterator; this.est = size; - this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED; + this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0 + ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED + : characteristics; } /** @@ -2041,7 +2049,9 @@ public final class Spliterators { public DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, long size, int characteristics) { this.it = iterator; this.est = size; - this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED; + this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0 + ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED + : characteristics; } /** diff --git a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java index 3c74ce29dc1..37fbcc769d0 100644 --- a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java +++ b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8020156 8020009 8022326 8012913 + * @bug 8020156 8020009 8022326 8012913 8024405 * @run testng SpliteratorCharacteristics */ @@ -36,21 +36,150 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; +import java.util.PrimitiveIterator; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; import java.util.Spliterator; +import java.util.Spliterators; import java.util.TreeMap; import java.util.TreeSet; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListSet; +import java.util.function.Supplier; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; import static org.testng.Assert.*; @Test public class SpliteratorCharacteristics { + public void testSpliteratorFromCollection() { + List l = Arrays.asList(1, 2, 3, 4); + + { + Spliterator s = Spliterators.spliterator(l, 0); + assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(l, Spliterator.CONCURRENT); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(l.iterator( ), 1, 0); + assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(l.iterator( ), 1, Spliterator.CONCURRENT); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize(l.iterator( ), 0); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize( + l.iterator(), Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + } + + public void testSpliteratorOfIntFromIterator() { + Supplier si = () -> IntStream.of(1, 2, 3, 4).iterator(); + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, 0); + assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize(si.get(), 0); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize( + si.get(), Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + } + + public void testSpliteratorOfLongFromIterator() { + Supplier si = () -> LongStream.of(1, 2, 3, 4).iterator(); + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, 0); + assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize(si.get(), 0); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize( + si.get(), Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + } + + public void testSpliteratorOfDoubleFromIterator() { + Supplier si = () -> DoubleStream.of(1, 2, 3, 4).iterator(); + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, 0); + assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize(si.get(), 0); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize( + si.get(), Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + } + + // + public void testHashMap() { assertMapCharacteristics(new HashMap<>(), Spliterator.SIZED | Spliterator.DISTINCT); @@ -199,10 +328,19 @@ public class SpliteratorCharacteristics { } void assertCharacteristics(Collection c, int expectedCharacteristics) { - assertTrue(c.spliterator().hasCharacteristics(expectedCharacteristics), + assertCharacteristics(c.spliterator(), expectedCharacteristics); + } + + void assertCharacteristics(Spliterator s, int expectedCharacteristics) { + assertTrue(s.hasCharacteristics(expectedCharacteristics), "Spliterator characteristics"); } + void assertHasNotCharacteristics(Spliterator s, int expectedCharacteristics) { + assertFalse(s.hasCharacteristics(expectedCharacteristics), + "Spliterator characteristics"); + } + void assertNullComparator(Collection c) { assertNull(c.spliterator().getComparator(), "Comparator of Spliterator of Collection"); diff --git a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java index a84cbbeaebe..69c7cf57436 100644 --- a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java +++ b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java @@ -1159,7 +1159,7 @@ public class SpliteratorTraversingAndSplittingTest { List dest = new ArrayList<>(); spliterator = supplier.get(); - assertSpliterator(spliterator); + assertRootSpliterator(spliterator); // verify splitting with forEach visit(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), false); @@ -1234,7 +1234,7 @@ public class SpliteratorTraversingAndSplittingTest { UnaryOperator> boxingAdapter) { Spliterator s = supplier.get(); boolean isOrdered = s.hasCharacteristics(Spliterator.ORDERED); - assertSpliterator(s); + assertRootSpliterator(s); List splits = new ArrayList<>(); Consumer c = boxingAdapter.apply(splits::add); @@ -1326,6 +1326,13 @@ public class SpliteratorTraversingAndSplittingTest { } } + private static void assertRootSpliterator(Spliterator s) { + assertFalse(s.hasCharacteristics(Spliterator.SIZED | Spliterator.CONCURRENT), + "Root spliterator should not be SIZED and CONCURRENT"); + + assertSpliterator(s); + } + private static void assertSpliterator(Spliterator s, int rootCharacteristics) { if ((rootCharacteristics & Spliterator.SUBSIZED) != 0) { assertTrue(s.hasCharacteristics(Spliterator.SUBSIZED), From 6de8695342b7af00f6079f6560e3e871da5b2e42 Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Fri, 20 Sep 2013 10:14:35 +0200 Subject: [PATCH 0129/1294] 8024985: com/sun/jdi/StepTest.java failed since jdk8b107 Reviewed-by: dcubed --- jdk/test/com/sun/jdi/ExceptionEvents.java | 4 ++++ jdk/test/com/sun/jdi/FilterNoMatch.java | 10 +++++++--- jdk/test/com/sun/jdi/JDIScaffold.java | 4 ++++ jdk/test/com/sun/jdi/PopAndStepTest.java | 4 ++++ jdk/test/com/sun/jdi/RepStep.java | 4 ++++ jdk/test/com/sun/jdi/TestScaffold.java | 7 ++++++- 6 files changed, 29 insertions(+), 4 deletions(-) diff --git a/jdk/test/com/sun/jdi/ExceptionEvents.java b/jdk/test/com/sun/jdi/ExceptionEvents.java index 88633b6fcde..42a532e4c44 100644 --- a/jdk/test/com/sun/jdi/ExceptionEvents.java +++ b/jdk/test/com/sun/jdi/ExceptionEvents.java @@ -417,8 +417,12 @@ public class ExceptionEvents extends TestScaffold { request = eventRequestManager().createExceptionRequest(exceptionClass, caught, uncaught); request.addClassExclusionFilter("java.*"); + request.addClassExclusionFilter("javax.*"); request.addClassExclusionFilter("sun.*"); request.addClassExclusionFilter("com.sun.*"); + request.addClassExclusionFilter("com.oracle.*"); + request.addClassExclusionFilter("oracle.*"); + request.addClassExclusionFilter("jdk.internal.*"); request.setSuspendPolicy(suspendPolicy); request.enable(); diff --git a/jdk/test/com/sun/jdi/FilterNoMatch.java b/jdk/test/com/sun/jdi/FilterNoMatch.java index 1feb8992f3a..3a8ecd2abdb 100644 --- a/jdk/test/com/sun/jdi/FilterNoMatch.java +++ b/jdk/test/com/sun/jdi/FilterNoMatch.java @@ -121,9 +121,13 @@ public class FilterNoMatch extends JDIScaffold { // We have to filter out all these so that they don't cause the // listener to be called. - request1.addClassExclusionFilter( "java.*"); - request1.addClassExclusionFilter( "com.*"); - request1.addClassExclusionFilter( "sun.*"); + request1.addClassExclusionFilter("java.*"); + request1.addClassExclusionFilter("javax.*"); + request1.addClassExclusionFilter("sun.*"); + request1.addClassExclusionFilter("com.sun.*"); + request1.addClassExclusionFilter("com.oracle.*"); + request1.addClassExclusionFilter("oracle.*"); + request1.addClassExclusionFilter("jdk.internal.*"); // We want our listener to be called if a pattern does not match. // So, here we want patterns that do not match HelloWorld. diff --git a/jdk/test/com/sun/jdi/JDIScaffold.java b/jdk/test/com/sun/jdi/JDIScaffold.java index e0a95dfbe09..0c60c0767dd 100644 --- a/jdk/test/com/sun/jdi/JDIScaffold.java +++ b/jdk/test/com/sun/jdi/JDIScaffold.java @@ -450,8 +450,12 @@ abstract public class JDIScaffold { requestManager.createStepRequest(thread, gran, depth); sr.addClassExclusionFilter("java.*"); + sr.addClassExclusionFilter("javax.*"); sr.addClassExclusionFilter("sun.*"); sr.addClassExclusionFilter("com.sun.*"); + sr.addClassExclusionFilter("com.oracle.*"); + sr.addClassExclusionFilter("oracle.*"); + sr.addClassExclusionFilter("jdk.internal.*"); sr.addCountFilter(1); sr.enable(); StepEvent retEvent = (StepEvent)waitForRequestedEvent(sr); diff --git a/jdk/test/com/sun/jdi/PopAndStepTest.java b/jdk/test/com/sun/jdi/PopAndStepTest.java index c5487fe787d..76dc0f5038c 100644 --- a/jdk/test/com/sun/jdi/PopAndStepTest.java +++ b/jdk/test/com/sun/jdi/PopAndStepTest.java @@ -130,8 +130,12 @@ public class PopAndStepTest extends TestScaffold { StepRequest srInto = erm.createStepRequest(mainThread, StepRequest.STEP_LINE, StepRequest.STEP_INTO); srInto.addClassExclusionFilter("java.*"); + srInto.addClassExclusionFilter("javax.*"); srInto.addClassExclusionFilter("sun.*"); srInto.addClassExclusionFilter("com.sun.*"); + srInto.addClassExclusionFilter("com.oracle.*"); + srInto.addClassExclusionFilter("oracle.*"); + srInto.addClassExclusionFilter("jdk.internal.*"); srInto.addCountFilter(1); srInto.enable(); // This fails mainThread.popFrames(frameFor("A")); diff --git a/jdk/test/com/sun/jdi/RepStep.java b/jdk/test/com/sun/jdi/RepStep.java index 665dfb79845..80ce449b304 100644 --- a/jdk/test/com/sun/jdi/RepStep.java +++ b/jdk/test/com/sun/jdi/RepStep.java @@ -75,8 +75,12 @@ public class RepStep { DEPTH); sr.addClassExclusionFilter("java.*"); + sr.addClassExclusionFilter("javax.*"); sr.addClassExclusionFilter("sun.*"); sr.addClassExclusionFilter("com.sun.*"); + sr.addClassExclusionFilter("com.oracle.*"); + sr.addClassExclusionFilter("oracle.*"); + sr.addClassExclusionFilter("jdk.internal.*"); sr.enable(); } diff --git a/jdk/test/com/sun/jdi/TestScaffold.java b/jdk/test/com/sun/jdi/TestScaffold.java index 61f8e053eaf..5dc5640f91f 100644 --- a/jdk/test/com/sun/jdi/TestScaffold.java +++ b/jdk/test/com/sun/jdi/TestScaffold.java @@ -746,8 +746,12 @@ abstract public class TestScaffold extends TargetAdapter { requestManager.createStepRequest(thread, gran, depth); sr.addClassExclusionFilter("java.*"); + sr.addClassExclusionFilter("javax.*"); sr.addClassExclusionFilter("sun.*"); sr.addClassExclusionFilter("com.sun.*"); + sr.addClassExclusionFilter("com.oracle.*"); + sr.addClassExclusionFilter("oracle.*"); + sr.addClassExclusionFilter("jdk.internal.*"); sr.addCountFilter(1); sr.enable(); StepEvent retEvent = (StepEvent)waitForRequestedEvent(sr); @@ -829,7 +833,8 @@ abstract public class TestScaffold extends TargetAdapter { Method method = findMethod(rt, methodName, methodSignature); if (method == null) { - throw new IllegalArgumentException("Bad method name/signature"); + throw new IllegalArgumentException("Bad method name/signature: " + + clsName + "." + methodName + ":" + methodSignature); } return resumeTo(method.location()); From a066da5d4d48d6f2eac8fe31f920a7a7f45fb1ce Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Fri, 20 Sep 2013 10:15:02 +0200 Subject: [PATCH 0130/1294] 8024416: TESTBUG: com/sun/jdi/MethodEntryExitEvents.java: method entry count mismatch Reviewed-by: dcubed --- jdk/test/com/sun/jdi/MethodEntryExitEvents.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/com/sun/jdi/MethodEntryExitEvents.java b/jdk/test/com/sun/jdi/MethodEntryExitEvents.java index a1c67cbfdd4..a14a63e3491 100644 --- a/jdk/test/com/sun/jdi/MethodEntryExitEvents.java +++ b/jdk/test/com/sun/jdi/MethodEntryExitEvents.java @@ -115,7 +115,7 @@ public class MethodEntryExitEvents extends TestScaffold { */ private String[] excludes = {"java.*", "javax.*", "sun.*", "com.sun.*", "com.oracle.*", - "oracle.*"}; + "oracle.*", "jdk.internal.*"}; MethodEntryExitEvents (String args[]) { super(args); From e5fa00ffb59d2297c73848997cd66cc519b4f10a Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Fri, 20 Sep 2013 17:56:54 +0400 Subject: [PATCH 0131/1294] 8025076: Fix for JDK-8017248 breaks jprt submission for non-unicode locales Reviewed-by: naoto, ksrini --- jdk/test/tools/launcher/8017248/ClassÁ.java | 5 -- jdk/test/tools/launcher/8017248/test.sh | 16 ----- jdk/test/tools/launcher/DiacriticTest.java | 76 +++++++++++++++++++++ 3 files changed, 76 insertions(+), 21 deletions(-) delete mode 100644 jdk/test/tools/launcher/8017248/ClassÁ.java delete mode 100644 jdk/test/tools/launcher/8017248/test.sh create mode 100644 jdk/test/tools/launcher/DiacriticTest.java diff --git a/jdk/test/tools/launcher/8017248/ClassÁ.java b/jdk/test/tools/launcher/8017248/ClassÁ.java deleted file mode 100644 index 2e264990c74..00000000000 --- a/jdk/test/tools/launcher/8017248/ClassÁ.java +++ /dev/null @@ -1,5 +0,0 @@ -public class ClassÁ { - public static void main(String args[]) { - System.out.println("Succes!"); - } -} diff --git a/jdk/test/tools/launcher/8017248/test.sh b/jdk/test/tools/launcher/8017248/test.sh deleted file mode 100644 index 7a96f46c223..00000000000 --- a/jdk/test/tools/launcher/8017248/test.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# @test test.sh -# @bug 8017248 -# @summary Compiler Diacritics Issue -# @run shell test.sh - -OSNAME=`uname -s` -if [ "$OSNAME" == "Darwin" ] -then - rm *.class - ${TESTJAVA}/bin/javac *.java - ${TESTJAVA}/bin/java `echo *.class | cut -d. -f1` -else - echo Test is specific to Mac OS X, skipping. - exit 0 -fi diff --git a/jdk/test/tools/launcher/DiacriticTest.java b/jdk/test/tools/launcher/DiacriticTest.java new file mode 100644 index 00000000000..44107bae42f --- /dev/null +++ b/jdk/test/tools/launcher/DiacriticTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013 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 8017248 + * @summary Compiler Diacritics Issue + * @run main DiacriticTest + */ + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; + +public class DiacriticTest extends TestHelper { + + // NFD-normalized form of the class name + static String NAME_NFD="ClassA\u0301"; + // NFC-normalized form of the same class name + static String NAME_NFC="Class\u00C1"; + + public static void main(String[] args) throws IOException { + if (!isMacOSX) { + System.out.println("This test is for Mac OS X only. Passing."); + return; + } + + File sourceFile = new File(NAME_NFC + ".java"); + String source = "public class " + NAME_NFC + " { " + + " public static void main(String args[]) {\n" + + " System.out.println(\"Success!\");\n" + + " }\n" + + "}\n"; + ArrayList content = new ArrayList<>(); + content.add(source); + createFile(sourceFile, content); + + HashMap env = new HashMap<>(); + env.put("LC_CTYPE", "UTF-8"); + + TestResult tr; + tr = doExec(env, javacCmd, NAME_NFD + ".java"); + System.out.println(tr.testOutput); + if (!tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("Compilation failed"); + } + tr = doExec(env, javaCmd, "-cp", ".", NAME_NFD); + System.out.println(tr.testOutput); + if (!tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("Test execution failed"); + } + } +} From fdef74ade2c76938a587ba4fe2ca713843a3d117 Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Fri, 20 Sep 2013 16:40:32 +0200 Subject: [PATCH 0132/1294] 7200277: [parfait] potential buffer overflow in npt/utf.c Reviewed-by: dsamersoff, dcubed --- jdk/src/share/npt/utf.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/npt/utf.c b/jdk/src/share/npt/utf.c index 9c88ca0583d..55ddd210d57 100644 --- a/jdk/src/share/npt/utf.c +++ b/jdk/src/share/npt/utf.c @@ -105,18 +105,24 @@ utf16ToUtf8m(struct UtfInst *ui, unsigned short *utf16, int len, jbyte *output, code = utf16[i]; if ( code >= 0x0001 && code <= 0x007F ) { + if ( outputLen + 1 >= outputMaxLen ) { + return -1; + } output[outputLen++] = code; } else if ( code == 0 || ( code >= 0x0080 && code <= 0x07FF ) ) { + if ( outputLen + 2 >= outputMaxLen ) { + return -1; + } output[outputLen++] = ((code>>6) & 0x1F) | 0xC0; output[outputLen++] = (code & 0x3F) | 0x80; } else if ( code >= 0x0800 && code <= 0xFFFF ) { + if ( outputLen + 3 >= outputMaxLen ) { + return -1; + } output[outputLen++] = ((code>>12) & 0x0F) | 0xE0; output[outputLen++] = ((code>>6) & 0x3F) | 0x80; output[outputLen++] = (code & 0x3F) | 0x80; } - if ( outputLen > outputMaxLen ) { - return -1; - } } output[outputLen] = 0; return outputLen; @@ -412,12 +418,15 @@ bytesToPrintable(struct UtfInst *ui, char *bytes, int len, char *output, int out unsigned byte; byte = bytes[i]; - if ( outputLen >= outputMaxLen ) { - return -1; - } if ( byte <= 0x7f && isprint(byte) && !iscntrl(byte) ) { + if ( outputLen + 1 >= outputMaxLen ) { + return -1; + } output[outputLen++] = (char)byte; } else { + if ( outputLen + 4 >= outputMaxLen ) { + return -1; + } (void)sprintf(output+outputLen,"\\x%02x",byte); outputLen += 4; } From 851fd0447ee2e0ee042d4025663d6f9b6ee69fa7 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Fri, 20 Sep 2013 11:07:06 -0700 Subject: [PATCH 0133/1294] 8024253: ThreadLocal random can use SecureRandom for the initial seed Co-authored-by: Peter Levart Co-authored-by: Guy Steele Reviewed-by: psandoz, chegar, alanb --- .../classes/java/util/SplittableRandom.java | 31 +++++++++-- .../util/concurrent/ThreadLocalRandom.java | 53 +++++++++++++++++-- .../ThreadLocalRandomTest.java | 2 + 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/java/util/SplittableRandom.java b/jdk/src/share/classes/java/util/SplittableRandom.java index 5a990f4d215..c3f5c0b4234 100644 --- a/jdk/src/share/classes/java/util/SplittableRandom.java +++ b/jdk/src/share/classes/java/util/SplittableRandom.java @@ -25,8 +25,7 @@ package java.util; -import java.security.SecureRandom; -import java.net.InetAddress; +import java.net.NetworkInterface; import java.util.concurrent.atomic.AtomicLong; import java.util.function.IntConsumer; import java.util.function.LongConsumer; @@ -242,12 +241,34 @@ public final class SplittableRandom { s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); return s; } - int hh = 0; // hashed host address + long h = 0L; try { - hh = InetAddress.getLocalHost().hashCode(); + Enumeration ifcs = + NetworkInterface.getNetworkInterfaces(); + boolean retry = false; // retry once if getHardwareAddress is null + while (ifcs.hasMoreElements()) { + NetworkInterface ifc = ifcs.nextElement(); + if (!ifc.isVirtual()) { // skip fake addresses + byte[] bs = ifc.getHardwareAddress(); + if (bs != null) { + int n = bs.length; + int m = Math.min(n >>> 1, 4); + for (int i = 0; i < m; ++i) + h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i]; + if (m < 4) + h = (h << 8) ^ bs[n-1-m]; + h = mix64(h); + break; + } + else if (!retry) + retry = true; + else + break; + } + } } catch (Exception ignore) { } - return (mix64((((long)hh) << 32) ^ System.currentTimeMillis()) ^ + return (h ^ mix64(System.currentTimeMillis()) ^ mix64(System.nanoTime())); } diff --git a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java index 297f88cd5a3..2cd2b0094bf 100644 --- a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java +++ b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java @@ -36,6 +36,8 @@ package java.util.concurrent; import java.io.ObjectStreamField; +import java.net.NetworkInterface; +import java.util.Enumeration; import java.util.Random; import java.util.Spliterator; import java.util.concurrent.atomic.AtomicInteger; @@ -71,7 +73,10 @@ import java.util.stream.StreamSupport; * *

    Instances of {@code ThreadLocalRandom} are not cryptographically * secure. Consider instead using {@link java.security.SecureRandom} - * in security-sensitive applications. + * in security-sensitive applications. Additionally, + * default-constructed instances do not use a cryptographically random + * seed unless the {@linkplain System#getProperty system property} + * {@code java.util.secureRandomSeed} is set to {@code true}. * * @since 1.7 * @author Doug Lea @@ -129,9 +134,49 @@ public class ThreadLocalRandom extends Random { /** * The next seed for default constructors. */ - private static final AtomicLong seeder = - new AtomicLong(mix64(System.currentTimeMillis()) ^ - mix64(System.nanoTime())); + private static final AtomicLong seeder = new AtomicLong(initialSeed()); + + private static long initialSeed() { + String pp = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction( + "java.util.secureRandomSeed")); + if (pp != null && pp.equalsIgnoreCase("true")) { + byte[] seedBytes = java.security.SecureRandom.getSeed(8); + long s = (long)(seedBytes[0]) & 0xffL; + for (int i = 1; i < 8; ++i) + s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); + return s; + } + long h = 0L; + try { + Enumeration ifcs = + NetworkInterface.getNetworkInterfaces(); + boolean retry = false; // retry once if getHardwareAddress is null + while (ifcs.hasMoreElements()) { + NetworkInterface ifc = ifcs.nextElement(); + if (!ifc.isVirtual()) { // skip fake addresses + byte[] bs = ifc.getHardwareAddress(); + if (bs != null) { + int n = bs.length; + int m = Math.min(n >>> 1, 4); + for (int i = 0; i < m; ++i) + h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i]; + if (m < 4) + h = (h << 8) ^ bs[n-1-m]; + h = mix64(h); + break; + } + else if (!retry) + retry = true; + else + break; + } + } + } catch (Exception ignore) { + } + return (h ^ mix64(System.currentTimeMillis()) ^ + mix64(System.nanoTime())); + } /** * The seed increment diff --git a/jdk/test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java b/jdk/test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java index e4e91f597bb..f159b67d348 100644 --- a/jdk/test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java +++ b/jdk/test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java @@ -33,7 +33,9 @@ import static org.testng.Assert.*; /** * @test + * @bug 8024253 * @run testng ThreadLocalRandomTest + * @run testng/othervm -Djava.util.secureRandomSeed=true ThreadLocalRandomTest * @summary test methods on ThreadLocalRandom */ @Test From ca9e74c63d031db3f4bba330411831d01013d020 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Fri, 20 Sep 2013 15:12:05 -0700 Subject: [PATCH 0134/1294] 8024331: j.u.Map.computeIfPresent() default/nondefault implementations don't throw NPE if the remappingFunction is null and the key is absent Explicitly check for null remappingFunction parameter. Reviewed-by: mduigou, forax, psandoz --- jdk/src/share/classes/java/util/HashMap.java | 2 + jdk/src/share/classes/java/util/Map.java | 4 ++ jdk/test/java/util/Map/Defaults.java | 61 +++++++++++++++++++- 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/util/HashMap.java b/jdk/src/share/classes/java/util/HashMap.java index a6a7d152b5f..16880663f24 100644 --- a/jdk/src/share/classes/java/util/HashMap.java +++ b/jdk/src/share/classes/java/util/HashMap.java @@ -1132,6 +1132,8 @@ public class HashMap extends AbstractMap public V computeIfPresent(K key, BiFunction remappingFunction) { + if (remappingFunction == null) + throw new NullPointerException(); Node e; V oldValue; int hash = hash(key); if ((e = getNode(hash, key)) != null && diff --git a/jdk/src/share/classes/java/util/Map.java b/jdk/src/share/classes/java/util/Map.java index 4340e6d9c8f..bf1ba8391c8 100644 --- a/jdk/src/share/classes/java/util/Map.java +++ b/jdk/src/share/classes/java/util/Map.java @@ -934,6 +934,7 @@ public interface Map { */ default V computeIfAbsent(K key, Function mappingFunction) { + Objects.requireNonNull(mappingFunction); V v, newValue; return ((v = get(key)) == null && (newValue = mappingFunction.apply(key)) != null && @@ -992,6 +993,7 @@ public interface Map { */ default V computeIfPresent(K key, BiFunction remappingFunction) { + Objects.requireNonNull(remappingFunction); V oldValue; while ((oldValue = get(key)) != null) { V newValue = remappingFunction.apply(key, oldValue); @@ -1068,6 +1070,7 @@ public interface Map { */ default V compute(K key, BiFunction remappingFunction) { + Objects.requireNonNull(remappingFunction); V oldValue = get(key); for (;;) { V newValue = remappingFunction.apply(key, oldValue); @@ -1174,6 +1177,7 @@ public interface Map { */ default V merge(K key, V value, BiFunction remappingFunction) { + Objects.requireNonNull(remappingFunction); V oldValue = get(key); for (;;) { if (oldValue != null) { diff --git a/jdk/test/java/util/Map/Defaults.java b/jdk/test/java/util/Map/Defaults.java index 82470019048..f14cd8aaa4b 100644 --- a/jdk/test/java/util/Map/Defaults.java +++ b/jdk/test/java/util/Map/Defaults.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8010122 8004518 + * @bug 8010122 8004518 8024331 * @summary Test Map default methods * @author Mike Duigou * @run testng Defaults @@ -288,6 +288,21 @@ public class Defaults { assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); } + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfAbsentNPEHashMap() { + Object value = new HashMap().computeIfAbsent(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfAbsentNPEHashtable() { + Object value = new Hashtable().computeIfAbsent(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfAbsentNPETreeMap() { + Object value = new TreeMap().computeIfAbsent(KEYS[1], null); + } + @Test(dataProvider = "Map rw=true keys=withNull values=withNull") public void testComputeIfPresentNulls(String description, Map map) { assertTrue(map.containsKey(null), description + ": null key absent"); @@ -328,6 +343,21 @@ public class Defaults { assertSame(map.get(EXTRA_KEY), null); } + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfPresentNPEHashMap() { + Object value = new HashMap().computeIfPresent(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfPresentNPEHashtable() { + Object value = new Hashtable().computeIfPresent(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfPresentNPETreeMap() { + Object value = new TreeMap().computeIfPresent(KEYS[1], null); + } + @Test(dataProvider = "Map rw=true keys=withNull values=withNull") public void testComputeNulls(String description, Map map) { assertTrue(map.containsKey(null), "null key absent"); @@ -414,6 +444,20 @@ public class Defaults { assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); } + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeNPEHashMap() { + Object value = new HashMap().compute(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeNPEHashtable() { + Object value = new Hashtable().compute(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeNPETreeMap() { + Object value = new TreeMap().compute(KEYS[1], null); + } @Test(dataProvider = "Map rw=true keys=withNull values=withNull") public void testMergeNulls(String description, Map map) { @@ -456,6 +500,21 @@ public class Defaults { assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); } + @Test(expectedExceptions = {NullPointerException.class}) + public void testMergeNPEHashMap() { + Object value = new HashMap().merge(KEYS[1], VALUES[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testMergeNPEHashtable() { + Object value = new Hashtable().merge(KEYS[1], VALUES[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testMergeNPETreeMap() { + Object value = new TreeMap().merge(KEYS[1], VALUES[1], null); + } + enum IntegerEnum { e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, From 57f84d86371845457d3b3c0b700c8cca120e30f4 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Fri, 20 Sep 2013 17:11:32 -0700 Subject: [PATCH 0135/1294] 8024341: j.u.regex.Pattern.splitAsStream() doesn't correspond to split() method if using an example from the spec Reviewed-by: alanb --- .../classes/java/util/regex/Pattern.java | 43 ++++++++++++++----- ...atternTest.java => PatternStreamTest.java} | 37 +++++++++++++++- 2 files changed, 68 insertions(+), 12 deletions(-) rename jdk/test/java/util/regex/{PatternTest.java => PatternStreamTest.java} (82%) diff --git a/jdk/src/share/classes/java/util/regex/Pattern.java b/jdk/src/share/classes/java/util/regex/Pattern.java index 1dc72c10cd3..81ea7145a78 100644 --- a/jdk/src/share/classes/java/util/regex/Pattern.java +++ b/jdk/src/share/classes/java/util/regex/Pattern.java @@ -5755,7 +5755,8 @@ NEXT: while (i <= last) { * input sequence that is terminated by another subsequence that matches * this pattern or is terminated by the end of the input sequence. The * substrings in the stream are in the order in which they occur in the - * input. + * input. Trailing empty strings will be discarded and not encountered in + * the stream. * *

    If this pattern does not match any subsequence of the input then * the resulting stream has just one element, namely the input sequence in @@ -5781,6 +5782,8 @@ NEXT: while (i <= last) { private int current; // null if the next element, if any, needs to obtained private String nextElement; + // > 0 if there are N next empty elements + private int emptyElementCount; MatcherIterator() { this.matcher = matcher(input); @@ -5790,26 +5793,46 @@ NEXT: while (i <= last) { if (!hasNext()) throw new NoSuchElementException(); - String n = nextElement; - nextElement = null; - return n; + if (emptyElementCount == 0) { + String n = nextElement; + nextElement = null; + return n; + } else { + emptyElementCount--; + return ""; + } } public boolean hasNext() { - if (nextElement != null) + if (nextElement != null || emptyElementCount > 0) return true; if (current == input.length()) return false; - if (matcher.find()) { + // Consume the next matching element + // Count sequence of matching empty elements + while (matcher.find()) { nextElement = input.subSequence(current, matcher.start()).toString(); current = matcher.end(); - } else { - nextElement = input.subSequence(current, input.length()).toString(); - current = input.length(); + if (!nextElement.isEmpty()) { + return true; + } else { + emptyElementCount++; + } + } + + // Consume last matching element + nextElement = input.subSequence(current, input.length()).toString(); + current = input.length(); + if (!nextElement.isEmpty()) { + return true; + } else { + // Ignore a terminal sequence of matching empty elements + emptyElementCount = 0; + nextElement = null; + return false; } - return true; } } return StreamSupport.stream(Spliterators.spliteratorUnknownSize( diff --git a/jdk/test/java/util/regex/PatternTest.java b/jdk/test/java/util/regex/PatternStreamTest.java similarity index 82% rename from jdk/test/java/util/regex/PatternTest.java rename to jdk/test/java/util/regex/PatternStreamTest.java index aab17319ae4..374b62378e9 100644 --- a/jdk/test/java/util/regex/PatternTest.java +++ b/jdk/test/java/util/regex/PatternStreamTest.java @@ -23,10 +23,11 @@ /** * @test + * @bug 8016846 8024341 * @summary Unit tests for wrapping classes should delegate to default methods * @library ../stream/bootlib * @build java.util.stream.OpTestCase - * @run testng/othervm PatternTest + * @run testng/othervm PatternStreamTest */ import org.testng.annotations.DataProvider; @@ -42,7 +43,7 @@ import java.util.stream.Stream; import java.util.stream.TestData; @Test -public class PatternTest extends OpTestCase { +public class PatternStreamTest extends OpTestCase { @DataProvider(name = "Stream") public static Object[][] makeStreamTestData() { @@ -132,6 +133,38 @@ public class PatternTest extends OpTestCase { expected.add("different"); expected.add("separators"); + + description = "Repeated separators within and at end"; + input = "boo:and:foo"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("b"); + expected.add(""); + expected.add(":and:f"); + + + description = "Many repeated separators within and at end"; + input = "booooo:and:fooooo"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("b"); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(":and:f"); + + description = "Many repeated separators before last match"; + input = "fooooo:"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("f"); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(":"); + data.add(new Object[] {description, input, pattern, expected}); return data.toArray(new Object[0][]); } From 06571ae86244a9690f8cf213a85edb651adcebcc Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Mon, 23 Sep 2013 04:05:42 +0100 Subject: [PATCH 0136/1294] 8023130: (process) ProcessBuilder#inheritIO does not work on Windows Reviewed-by: alanb, martin --- .../windows/native/java/lang/ProcessImpl_md.c | 6 +- jdk/test/java/lang/ProcessBuilder/Basic.java | 12 ++- .../ProcessBuilder/InheritIO/InheritIO.java | 47 +++++++++++ .../ProcessBuilder/InheritIO/InheritIO.sh | 81 +++++++++++++++++++ 4 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.java create mode 100644 jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.sh diff --git a/jdk/src/windows/native/java/lang/ProcessImpl_md.c b/jdk/src/windows/native/java/lang/ProcessImpl_md.c index 1806fb8193c..da7d00b081a 100644 --- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c +++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c @@ -308,7 +308,11 @@ static jlong processCreate( if (success) { PROCESS_INFORMATION pi; - DWORD processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT; + DWORD processFlag = CREATE_UNICODE_ENVIRONMENT; + + /* Suppress popping-up of a console window for non-console applications */ + if (GetConsoleWindow() == NULL) + processFlag |= CREATE_NO_WINDOW; si.dwFlags = STARTF_USESTDHANDLES; if (!CreateProcessW( diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java index ebccabdd9c4..5a55cb6f0f4 100644 --- a/jdk/test/java/lang/ProcessBuilder/Basic.java +++ b/jdk/test/java/lang/ProcessBuilder/Basic.java @@ -298,11 +298,15 @@ public class Basic { System.exit(5); System.err.print("standard error"); System.out.print("standard output"); - } else if (action.equals("testInheritIO")) { + } else if (action.equals("testInheritIO") + || action.equals("testRedirectInherit")) { List childArgs = new ArrayList(javaChildArgs); childArgs.add("testIO"); ProcessBuilder pb = new ProcessBuilder(childArgs); - pb.inheritIO(); + if (action.equals("testInheritIO")) + pb.inheritIO(); + else + redirectIO(pb, INHERIT, INHERIT, INHERIT); ProcessResults r = run(pb); if (! r.out().equals("")) System.exit(7); @@ -1019,10 +1023,10 @@ public class Basic { // Note that this requires __FOUR__ nested JVMs involved in one test, // if you count the harness JVM. //---------------------------------------------------------------- - { + for (String testName : new String[] { "testInheritIO", "testRedirectInherit" } ) { redirectIO(pb, PIPE, PIPE, PIPE); List command = pb.command(); - command.set(command.size() - 1, "testInheritIO"); + command.set(command.size() - 1, testName); Process p = pb.start(); new PrintStream(p.getOutputStream()).print("standard input"); p.getOutputStream().close(); diff --git a/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.java b/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.java new file mode 100644 index 00000000000..83bb23d840c --- /dev/null +++ b/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static java.lang.ProcessBuilder.Redirect.*; + +class InheritIO { + + public static class TestInheritIO { + public static void main(String args[]) throws Throwable { + int err = new ProcessBuilder(args).inheritIO().start().waitFor(); + System.err.print("exit value: " + err); + System.exit(err); + } + } + + public static class TestRedirectInherit { + public static void main(String args[]) throws Throwable { + int err = new ProcessBuilder(args) + .redirectInput(INHERIT) + .redirectOutput(INHERIT) + .redirectError(INHERIT) + .start().waitFor(); + System.err.print("exit value: " + err); + System.exit(err); + } + } +} diff --git a/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.sh b/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.sh new file mode 100644 index 00000000000..2b33a037296 --- /dev/null +++ b/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.sh @@ -0,0 +1,81 @@ +# +# Copyright (c) 2013, 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 8023130 +# @summary (process) ProcessBuilder#inheritIO does not work on Windows +# @run shell InheritIO.sh + +if [ "x${TESTSRC}" = "x" ]; then + echo "TESTSRC not set. Test cannot execute. Failed." + exit 1 +fi + +if [ "x${TESTJAVA}" = "x" ]; then + echo "TESTJAVA not set. Test cannot execute. Failed." + exit 1 +fi + + +JAVA="${TESTJAVA}/bin/java" +JAVAC="${TESTJAVA}/bin/javac" + +cp -f ${TESTSRC}/InheritIO.java . + +# compile the class ourselves, so this can run as a standalone test + +${JAVAC} InheritIO.java +RES="$?" +if [ ${RES} != 0 ]; then + echo 'FAIL: Cannot compile InheritIO.java' + exit ${RES} +fi + + +for TEST_NAME in TestInheritIO TestRedirectInherit +do + ${JAVA} ${TESTVMOPTS} -classpath . \ + 'InheritIO$'${TEST_NAME} printf message > stdout.txt 2> stderr.txt + + RES="$?" + if [ ${RES} != 0 ]; then + echo 'FAIL: InheritIO$'${TEST_NAME}' failed with '${RES} + exit ${RES} + fi + + OUT_EXPECTED='message' + OUT_RECEIVED=`cat stdout.txt` + if [ "x${OUT_RECEIVED}" != "x${OUT_EXPECTED}" ]; then + echo "FAIL: unexpected '${OUT_RECEIVED}' in stdout" + exit 1 + fi + + ERR_EXPECTED='exit value: 0' + ERR_RECEIVED=`cat stderr.txt` + if [ "x${ERR_RECEIVED}" != "x${ERR_EXPECTED}" ]; then + echo "FAIL: unexpected '${ERR_RECEIVED}' in stderr" + exit 1 + fi +done + +echo 'PASS: InheritIO works as expected' From ef64db06e24efd1f08aa5e3e5a327d3e38b5734b Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Thu, 29 Aug 2013 11:08:42 +0200 Subject: [PATCH 0137/1294] 8014659: NPG: performance counters for compressed klass space Reviewed-by: jmasa, sla --- .../sun/tools/jstat/resources/jstat_options | 96 +++++++++++++++++++ .../sun/tools/jstat/gcCapacityOutput1.awk | 8 +- jdk/test/sun/tools/jstat/gcCauseOutput1.awk | 8 +- .../sun/tools/jstat/gcMetaCapacityOutput1.awk | 8 +- jdk/test/sun/tools/jstat/gcOldOutput1.awk | 8 +- jdk/test/sun/tools/jstat/gcOutput1.awk | 8 +- jdk/test/sun/tools/jstat/lineCounts1.awk | 16 ++-- jdk/test/sun/tools/jstat/lineCounts2.awk | 8 +- jdk/test/sun/tools/jstat/lineCounts3.awk | 26 ++--- jdk/test/sun/tools/jstat/lineCounts4.awk | 30 +++--- jdk/test/sun/tools/jstat/timeStamp1.awk | 8 +- .../sun/tools/jstatd/jstatGcutilOutput1.awk | 16 ++-- 12 files changed, 168 insertions(+), 72 deletions(-) diff --git a/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options b/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options index bead54260fd..a629a3c6206 100644 --- a/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options +++ b/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options @@ -207,6 +207,22 @@ option gc { scale K format "0.0" } + column { + header "^CCSC^" /* Compressed Class Space Capacity - Current */ + data sun.gc.compressedclassspace.capacity + align center + width 6 + scale K + format "0.0" + } + column { + header "^CCSU^" /* Compressed Class Space Used */ + data sun.gc.compressedclassspace.used + align center + width 6 + scale K + format "0.0" + } column { header "^YGC^" /* Young Generation Collections */ data sun.gc.collector.0.invocations @@ -353,6 +369,30 @@ option gccapacity { width 8 format "0.0" } + column { + header "^CCSMN^" /* Compressed Class Space Capacity - Minimum */ + data sun.gc.compressedclassspace.minCapacity + scale K + align right + width 8 + format "0.0" + } + column { + header "^CCSMX^" /* Compressed Class Space Capacity - Maximum */ + data sun.gc.compressedclassspace.maxCapacity + scale K + align right + width 8 + format "0.0" + } + column { + header "^CCSC^" /* Compressed Class Space Capacity - Current */ + data sun.gc.compressedclassspace.capacity + scale K + align right + width 8 + format "0.0" + } column { header "^YGC^" /* Young Generation Collections */ data sun.gc.collector.0.invocations @@ -411,6 +451,14 @@ option gccause { scale raw format "0.00" } + column { + header "^CCS^" /* Compressed Class Space - Percent Used */ + data (1-((sun.gc.compressedclassspace.capacity - sun.gc.compressedclassspace.used)/sun.gc.compressedclassspace.capacity)) * 100 + align right + width 6 + scale raw + format "0.00" + } column { header "^YGC^" /* Young Generation Collections */ data sun.gc.collector.0.invocations @@ -661,6 +709,22 @@ option gcold { scale K format "0.0" } + column { + header "^CCSC^" /* Compressed Class Space Capacity - Current */ + data sun.gc.compressedclassspace.capacity + width 8 + align right + scale K + format "0.0" + } + column { + header "^CCSU^" /* Compressed Class Space Used */ + data sun.gc.compressedclassspace.used + width 8 + align right + scale K + format "0.0" + } column { header "^OC^" /* Old Space Capacity - Current */ data sun.gc.generation.1.space.0.capacity @@ -801,6 +865,30 @@ option gcmetacapacity { width 10 format "0.0" } + column { + header "^CCSMN^" /* Compressed Class Space Capacity - Minimum */ + data sun.gc.compressedclassspace.minCapacity + scale K + align right + width 10 + format "0.0" + } + column { + header "^CCSMX^" /* Compressed Class Space Capacity - Maximum */ + data sun.gc.compressedclassspace.maxCapacity + scale K + align right + width 10 + format "0.0" + } + column { + header "^CCSC^" /* Compressed Class Space Capacity - Current */ + data sun.gc.compressedclassspace.capacity + scale K + align right + width 10 + format "0.0" + } column { header "^YGC^" /* Young Generation Collections */ data sun.gc.collector.0.invocations @@ -875,6 +963,14 @@ option gcutil { scale raw format "0.00" } + column { + header "^CCS^" /* Compressed Class Space Space - Percent Used */ + data (1-((sun.gc.compressedclassspace.capacity - sun.gc.compressedclassspace.used)/sun.gc.compressedclassspace.capacity)) * 100 + align right + width 6 + scale raw + format "0.00" + } column { header "^YGC^" /* Young Generation Collections */ data sun.gc.collector.0.invocations diff --git a/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk b/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk index c59de5f0bdb..ab630d143b6 100644 --- a/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk @@ -3,19 +3,19 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC YGC FGC -# 2176.0 7232.0 2176.0 64.0 64.0 2048.0 6016.0 58304.0 6016.0 6016.0 8192.0 65536.0 8192.0 8192.0 0 +# NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC +# 4096.0 657408.0 8192.0 512.0 512.0 3072.0 6144.0 1312768.0 6144.0 6144.0 512.0 132096.0 5120.0 512.0 131072.0 512.0 1 0 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC YGC FGC $/ { +/^ NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/gcCauseOutput1.awk b/jdk/test/sun/tools/jstat/gcCauseOutput1.awk index 973d2c049e6..f6127e415f5 100644 --- a/jdk/test/sun/tools/jstat/gcCauseOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcCauseOutput1.awk @@ -3,15 +3,15 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O P YGC YGCT FGC FGCT GCT LGCC GCC -# 0.00 100.00 14.01 3.06 23.20 1 0.032 0 0.000 0.032 Allocation Failure No GC +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC +# 0.00 0.00 0.00 9.97 90.94 87.70 2 0.013 0 0.000 0.013 Allocation Failure No GC BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT LGCC GCC $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC $/ { headerlines++; } @@ -23,7 +23,7 @@ BEGIN { # or more letters and spaces. It also provides for the ".", "(", and ")" # characters to allow for the string "System.gc()". # -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[a-zA-Z]+[a-zA-Z \.\(\)]*[ ]*[a-zA-Z]+[a-zA-Z \.\(\)]*$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[a-zA-Z]+[a-zA-Z \.\(\)]*[ ]*[a-zA-Z]+[a-zA-Z \.\(\)]*$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/gcMetaCapacityOutput1.awk b/jdk/test/sun/tools/jstat/gcMetaCapacityOutput1.awk index c015dd69c94..12d9544542a 100644 --- a/jdk/test/sun/tools/jstat/gcMetaCapacityOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcMetaCapacityOutput1.awk @@ -3,18 +3,18 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# MCMN MCMX MC YGC FGC FGCT GCT -# 8192.0 65536.0 8192.0 8192.0 1 0 0.000 0.029 +# MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT +# 512.0 132096.0 5120.0 512.0 131072.0 512.0 1 0 0.000 0.004 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ MCMN MCMX MC YGC FGC FGCT GCT $/ { +/^ MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/gcOldOutput1.awk b/jdk/test/sun/tools/jstat/gcOldOutput1.awk index df7c6b582c5..c007f66b3be 100644 --- a/jdk/test/sun/tools/jstat/gcOldOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcOldOutput1.awk @@ -3,19 +3,19 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# MC MU OC OU YGC FGC FGCT GCT -# 8192.0 1877.3 6016.0 180.8 1 0 0.000 0.030 +# MC MU CCSC CCSU OC OU YGC FGC FGCT GCT +# 5120.0 4152.0 512.0 397.9 6144.0 200.0 1 0 0.000 0.005 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ MC MU OC OU YGC FGC FGCT GCT $/ { +/^ MC MU CCSC CCSU OC OU YGC FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/gcOutput1.awk b/jdk/test/sun/tools/jstat/gcOutput1.awk index 5ac5b2837a2..d1d90a281e2 100644 --- a/jdk/test/sun/tools/jstat/gcOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcOutput1.awk @@ -3,19 +3,19 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0C S1C S0U S1U EC EU OC OU MC MU YGC YGCT FGC FGCT GCT -# 64.0 64.0 0.0 0.0 2048.0 1711.2 6016.0 0.0 8192.0 1948.6 0 0.000 0 0.000 0.000 +# S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT +# 512.0 512.0 0.0 496.0 3072.0 615.5 6144.0 280.0 5120.0 4176.0 512.0 401.0 1 0.005 0 0.000 0.005 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0C S1C S0U S1U EC EU OC OU MC MU YGC YGCT FGC FGCT GCT $/ { +/^ S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/lineCounts1.awk b/jdk/test/sun/tools/jstat/lineCounts1.awk index 33b2f08cc61..b5cb1cdd0bd 100644 --- a/jdk/test/sun/tools/jstat/lineCounts1.awk +++ b/jdk/test/sun/tools/jstat/lineCounts1.awk @@ -3,22 +3,22 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 -# 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 70.89 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 70.89 1.24 27.84 1 0.044 0 0.000 0.044 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 93.76 28.80 1.82 77.74 68.02 1 0.005 0 0.000 0.005 +# 0.00 93.76 73.04 1.82 77.74 68.02 1 0.005 0 0.000 0.005 +# 0.00 93.76 73.04 1.82 77.74 68.02 1 0.005 0 0.000 0.005 +# 0.00 93.76 73.04 1.82 77.74 68.02 1 0.005 0 0.000 0.005 +# 0.00 93.76 75.00 1.82 77.74 68.02 1 0.005 0 0.000 0.005 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/lineCounts2.awk b/jdk/test/sun/tools/jstat/lineCounts2.awk index b1e80482241..1309d04f8cb 100644 --- a/jdk/test/sun/tools/jstat/lineCounts2.awk +++ b/jdk/test/sun/tools/jstat/lineCounts2.awk @@ -3,18 +3,18 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 93.76 28.40 1.82 77.74 68.02 1 0.005 0 0.000 0.005 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/lineCounts3.awk b/jdk/test/sun/tools/jstat/lineCounts3.awk index e7c362fbd8f..2d8d4bf1368 100644 --- a/jdk/test/sun/tools/jstat/lineCounts3.awk +++ b/jdk/test/sun/tools/jstat/lineCounts3.awk @@ -3,27 +3,27 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 99.99 66.81 1.24 26.55 1 0.028 0 0.000 0.028 -# 0.00 99.99 68.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 72.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 72.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 74.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 74.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 76.81 1.24 27.85 1 0.028 0 0.000 0.028 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 93.76 26.48 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 71.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 73.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 73.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 73.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 75.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 75.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 77.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 77.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 77.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/lineCounts4.awk b/jdk/test/sun/tools/jstat/lineCounts4.awk index af9487edb27..5ec4ac7e9bf 100644 --- a/jdk/test/sun/tools/jstat/lineCounts4.awk +++ b/jdk/test/sun/tools/jstat/lineCounts4.awk @@ -3,30 +3,30 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 99.99 66.81 1.24 26.55 1 0.028 0 0.000 0.028 -# 0.00 99.99 68.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 72.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 72.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 74.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 74.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 76.81 1.24 27.85 1 0.028 0 0.000 0.028 -# S0 S1 E O P YGC YGCT FGC FGCT GCT -# 0.00 99.99 76.81 1.24 27.85 1 0.028 0 0.000 0.028 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 96.88 66.55 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 71.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 73.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 73.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 73.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 75.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 75.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 77.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 77.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 77.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 96.88 79.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 BEGIN { headerlines=0; datalines=0; totallines=0 datalines2=0; } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { if (headerlines == 2) { datalines2++; } diff --git a/jdk/test/sun/tools/jstat/timeStamp1.awk b/jdk/test/sun/tools/jstat/timeStamp1.awk index 825101b3ac4..1d90a18f748 100644 --- a/jdk/test/sun/tools/jstat/timeStamp1.awk +++ b/jdk/test/sun/tools/jstat/timeStamp1.awk @@ -3,18 +3,18 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 +#Timestamp S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.3 0.00 100.00 68.74 1.95 77.73 68.02 1 0.004 0 0.000 0.004 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^Timestamp S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^Timestamp S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk b/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk index 33b2f08cc61..76b355e6707 100644 --- a/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk +++ b/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk @@ -3,22 +3,22 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 -# 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 70.89 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 70.89 1.24 27.84 1 0.044 0 0.000 0.044 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 100.00 56.99 7.81 95.03 87.56 1 0.009 0 0.000 0.009 +# 0.00 100.00 63.64 7.81 95.03 87.56 1 0.009 0 0.000 0.009 +# 0.00 100.00 64.68 7.81 95.03 87.56 1 0.009 0 0.000 0.009 +# 0.00 100.00 65.73 7.81 95.03 87.56 1 0.009 0 0.000 0.009 +# 0.00 100.00 67.22 7.81 95.03 87.56 1 0.009 0 0.000 0.009 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } From 1ff22f2ed9e6c76b61de103b4d7f37fdea0232e6 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Thu, 29 Aug 2013 10:33:13 -0400 Subject: [PATCH 0138/1294] 8016764: JVM does not prohibit invokespecial in c.f.v 51.0 that invokes default interface method in c.f.v 52.0 Check cfv before allowing invokespecial call to default method. Reviewed-by: kamg, acorn, dholmes --- hotspot/src/share/vm/classfile/verifier.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index 015b8093d21..68e634f3a15 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -2318,9 +2318,6 @@ void ClassVerifier::verify_invoke_instructions( types = 1 << JVM_CONSTANT_InvokeDynamic; break; case Bytecodes::_invokespecial: - types = (1 << JVM_CONSTANT_InterfaceMethodref) | - (1 << JVM_CONSTANT_Methodref); - break; case Bytecodes::_invokestatic: types = (_klass->major_version() < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) ? (1 << JVM_CONSTANT_Methodref) : From 02440bce3785074ed2948c7d1adec26e5241d8da Mon Sep 17 00:00:00 2001 From: Lois Foltan Date: Thu, 29 Aug 2013 13:44:07 -0400 Subject: [PATCH 0139/1294] 8022407: sun/misc/CopyMemory.java fails with SIGSEGV in Unsafe_SetByte+0x35 Lower optimization level for unsafe.cpp due to MacOS Xcode 4.6.2 compiler optimization issue. Reviewed-by: coleenp, twisti, dholmes --- hotspot/make/bsd/makefiles/gcc.make | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make index c2c96f9a18f..1cdff227a5a 100644 --- a/hotspot/make/bsd/makefiles/gcc.make +++ b/hotspot/make/bsd/makefiles/gcc.make @@ -139,6 +139,7 @@ ifeq ($(USE_CLANG), true) PCH_FLAG/loopTransform.o = $(PCH_FLAG/NO_PCH) PCH_FLAG/sharedRuntimeTrig.o = $(PCH_FLAG/NO_PCH) PCH_FLAG/sharedRuntimeTrans.o = $(PCH_FLAG/NO_PCH) + PCH_FLAG/unsafe.o = $(PCH_FLAG/NO_PCH) endif else # ($(USE_CLANG), true) @@ -306,6 +307,7 @@ OPT_CFLAGS/NOOPT=-O0 ifeq ($(USE_CLANG), true) ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 2), 1) OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT) + OPT_CFLAGS/unsafe.o += -01 endif else # 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation. From 98c327bc7d0cdb1147ee6d7dfaf36b24222c7c49 Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Thu, 29 Aug 2013 21:48:23 +0400 Subject: [PATCH 0140/1294] 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193 Don't re-evaluate stack bounds for main thread before install guard page Reviewed-by: coleenp, dholmes, dlong --- hotspot/src/os/linux/vm/os_linux.cpp | 119 +++++++++++------- hotspot/src/share/vm/runtime/os.cpp | 38 ------ hotspot/src/share/vm/runtime/os.hpp | 4 - .../InitialThreadOverflow/DoOverflow.java | 41 ++++++ .../runtime/InitialThreadOverflow/invoke.cxx | 70 +++++++++++ .../runtime/InitialThreadOverflow/testme.sh | 73 +++++++++++ 6 files changed, 256 insertions(+), 89 deletions(-) create mode 100644 hotspot/test/runtime/InitialThreadOverflow/DoOverflow.java create mode 100644 hotspot/test/runtime/InitialThreadOverflow/invoke.cxx create mode 100644 hotspot/test/runtime/InitialThreadOverflow/testme.sh diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 23d3457046d..bf89423c1ce 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -2943,6 +2943,53 @@ bool os::pd_uncommit_memory(char* addr, size_t size) { return res != (uintptr_t) MAP_FAILED; } +static +address get_stack_commited_bottom(address bottom, size_t size) { + address nbot = bottom; + address ntop = bottom + size; + + size_t page_sz = os::vm_page_size(); + unsigned pages = size / page_sz; + + unsigned char vec[1]; + unsigned imin = 1, imax = pages + 1, imid; + int mincore_return_value; + + while (imin < imax) { + imid = (imax + imin) / 2; + nbot = ntop - (imid * page_sz); + + // Use a trick with mincore to check whether the page is mapped or not. + // mincore sets vec to 1 if page resides in memory and to 0 if page + // is swapped output but if page we are asking for is unmapped + // it returns -1,ENOMEM + mincore_return_value = mincore(nbot, page_sz, vec); + + if (mincore_return_value == -1) { + // Page is not mapped go up + // to find first mapped page + if (errno != EAGAIN) { + assert(errno == ENOMEM, "Unexpected mincore errno"); + imax = imid; + } + } else { + // Page is mapped go down + // to find first not mapped page + imin = imid + 1; + } + } + + nbot = nbot + page_sz; + + // Adjust stack bottom one page up if last checked page is not mapped + if (mincore_return_value == -1) { + nbot = nbot + page_sz; + } + + return nbot; +} + + // Linux uses a growable mapping for the stack, and if the mapping for // the stack guard pages is not removed when we detach a thread the // stack cannot grow beyond the pages where the stack guard was @@ -2957,59 +3004,37 @@ bool os::pd_uncommit_memory(char* addr, size_t size) { // So, we need to know the extent of the stack mapping when // create_stack_guard_pages() is called. -// Find the bounds of the stack mapping. Return true for success. -// // We only need this for stacks that are growable: at the time of // writing thread stacks don't use growable mappings (i.e. those // creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this // only applies to the main thread. -static -bool get_stack_bounds(uintptr_t *bottom, uintptr_t *top) { - - char buf[128]; - int fd, sz; - - if ((fd = ::open("/proc/self/maps", O_RDONLY)) < 0) { - return false; - } - - const char kw[] = "[stack]"; - const int kwlen = sizeof(kw)-1; - - // Address part of /proc/self/maps couldn't be more than 128 bytes - while ((sz = os::get_line_chars(fd, buf, sizeof(buf))) > 0) { - if (sz > kwlen && ::memcmp(buf+sz-kwlen, kw, kwlen) == 0) { - // Extract addresses - if (sscanf(buf, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) { - uintptr_t sp = (uintptr_t) __builtin_frame_address(0); - if (sp >= *bottom && sp <= *top) { - ::close(fd); - return true; - } - } - } - } - - ::close(fd); - return false; -} - - // If the (growable) stack mapping already extends beyond the point // where we're going to put our guard pages, truncate the mapping at // that point by munmap()ping it. This ensures that when we later // munmap() the guard pages we don't leave a hole in the stack -// mapping. This only affects the main/initial thread, but guard -// against future OS changes +// mapping. This only affects the main/initial thread + bool os::pd_create_stack_guard_pages(char* addr, size_t size) { - uintptr_t stack_extent, stack_base; - bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true); - if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) { - assert(os::Linux::is_initial_thread(), - "growable stack in non-initial thread"); - if (stack_extent < (uintptr_t)addr) - ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent); + + if (os::Linux::is_initial_thread()) { + // As we manually grow stack up to bottom inside create_attached_thread(), + // it's likely that os::Linux::initial_thread_stack_bottom is mapped and + // we don't need to do anything special. + // Check it first, before calling heavy function. + uintptr_t stack_extent = (uintptr_t) os::Linux::initial_thread_stack_bottom(); + unsigned char vec[1]; + + if (mincore((address)stack_extent, os::vm_page_size(), vec) == -1) { + // Fallback to slow path on all errors, including EAGAIN + stack_extent = (uintptr_t) get_stack_commited_bottom( + os::Linux::initial_thread_stack_bottom(), + (size_t)addr - stack_extent); + } + + if (stack_extent < (uintptr_t)addr) { + ::munmap((void*)stack_extent, (uintptr_t)(addr - stack_extent)); + } } return os::commit_memory(addr, size, !ExecMem); @@ -3018,13 +3043,13 @@ bool os::pd_create_stack_guard_pages(char* addr, size_t size) { // If this is a growable mapping, remove the guard pages entirely by // munmap()ping them. If not, just call uncommit_memory(). This only // affects the main/initial thread, but guard against future OS changes +// It's safe to always unmap guard pages for initial thread because we +// always place it right after end of the mapped region + bool os::remove_stack_guard_pages(char* addr, size_t size) { uintptr_t stack_extent, stack_base; - bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true); - if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) { - assert(os::Linux::is_initial_thread(), - "growable stack in non-initial thread"); + if (os::Linux::is_initial_thread()) { return ::munmap(addr, size) == 0; } diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index a16c85785d3..501209e777f 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -1424,44 +1424,6 @@ bool os::is_server_class_machine() { return result; } -// Read file line by line, if line is longer than bsize, -// skip rest of line. -int os::get_line_chars(int fd, char* buf, const size_t bsize){ - size_t sz, i = 0; - - // read until EOF, EOL or buf is full - while ((sz = (int) read(fd, &buf[i], 1)) == 1 && i < (bsize-2) && buf[i] != '\n') { - ++i; - } - - if (buf[i] == '\n') { - // EOL reached so ignore EOL character and return - - buf[i] = 0; - return (int) i; - } - - buf[i+1] = 0; - - if (sz != 1) { - // EOF reached. if we read chars before EOF return them and - // return EOF on next call otherwise return EOF - - return (i == 0) ? -1 : (int) i; - } - - // line is longer than size of buf, skip to EOL - char ch; - while (read(fd, &ch, 1) == 1 && ch != '\n') { - // Do nothing - } - - // return initial part of line that fits in buf. - // If we reached EOF, it will be returned on next call. - - return (int) i; -} - void os::SuspendedThreadTask::run() { assert(Threads_lock->owned_by_self() || (_thread == VMThread::vm_thread()), "must have threads lock to call this"); internal_do_task(); diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index 38efad386f1..8f98c2013f6 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -725,10 +725,6 @@ class os: AllStatic { // Hook for os specific jvm options that we don't want to abort on seeing static bool obsolete_option(const JavaVMOption *option); - // Read file line by line. If line is longer than bsize, - // rest of line is skipped. Returns number of bytes read or -1 on EOF - static int get_line_chars(int fd, char *buf, const size_t bsize); - // Extensions #include "runtime/os_ext.hpp" diff --git a/hotspot/test/runtime/InitialThreadOverflow/DoOverflow.java b/hotspot/test/runtime/InitialThreadOverflow/DoOverflow.java new file mode 100644 index 00000000000..958285ca915 --- /dev/null +++ b/hotspot/test/runtime/InitialThreadOverflow/DoOverflow.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class DoOverflow { + + static int count; + + public void overflow() { + count+=1; + overflow(); + } + + public static void printIt() { + System.out.println("Going to overflow stack"); + try { + new DoOverflow().overflow(); + } catch(java.lang.StackOverflowError e) { + System.out.println("Overflow OK " + count); + } + } +} diff --git a/hotspot/test/runtime/InitialThreadOverflow/invoke.cxx b/hotspot/test/runtime/InitialThreadOverflow/invoke.cxx new file mode 100644 index 00000000000..55213c0f3bf --- /dev/null +++ b/hotspot/test/runtime/InitialThreadOverflow/invoke.cxx @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013, 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. + */ + +#include +#include + +#include + +JavaVM* jvm; + +void * +floobydust (void *p) { + JNIEnv *env; + + jvm->AttachCurrentThread((void**)&env, NULL); + + jclass class_id = env->FindClass ("DoOverflow"); + assert (class_id); + + jmethodID method_id = env->GetStaticMethodID(class_id, "printIt", "()V"); + assert (method_id); + + env->CallStaticVoidMethod(class_id, method_id, NULL); + + jvm->DetachCurrentThread(); +} + +int +main (int argc, const char** argv) { + JavaVMOption options[1]; + options[0].optionString = (char*) "-Xss320k"; + + JavaVMInitArgs vm_args; + vm_args.version = JNI_VERSION_1_2; + vm_args.ignoreUnrecognized = JNI_TRUE; + vm_args.options = options; + vm_args.nOptions = 1; + + JNIEnv* env; + jint result = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); + assert(result >= 0); + + pthread_t thr; + pthread_create(&thr, NULL, floobydust, NULL); + pthread_join(thr, NULL); + + floobydust(NULL); + + return 0; +} diff --git a/hotspot/test/runtime/InitialThreadOverflow/testme.sh b/hotspot/test/runtime/InitialThreadOverflow/testme.sh new file mode 100644 index 00000000000..015a6bd43b1 --- /dev/null +++ b/hotspot/test/runtime/InitialThreadOverflow/testme.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# Copyright (c) 2013 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 testme.sh +# @bug 8009062 +# @summary Poor performance of JNI AttachCurrentThread after fix for 7017193 +# @compile DoOverflow.java +# @run shell testme.sh + +set -x +if [ "${TESTSRC}" = "" ] +then + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" +fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh + +if [ "${VM_OS}" != "linux" ] +then + echo "Test only valid for Linux" + exit 0 +fi + +gcc_cmd=`which gcc` +if [ "x$gcc_cmd" == "x" ]; then + echo "WARNING: gcc not found. Cannot execute test." 2>&1 + exit 0; +fi + +CFLAGS="-m${VM_BITS}" + +LD_LIBRARY_PATH=.:${COMPILEJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH +export LD_LIBRARY_PATH + +cp ${TESTSRC}${FS}invoke.cxx . + +# Copy the result of our @compile action: +cp ${TESTCLASSES}${FS}DoOverflow.class . + +echo "Compilation flag: ${COMP_FLAG}" +# Note pthread may not be found thus invoke creation will fail to be created. +# Check to ensure you have a /usr/lib/libpthread.so if you don't please look +# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation. + +$gcc_cmd -DLINUX ${CFLAGS} -o invoke \ + -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \ + -L${COMPILEJAVA}/jre/lib/${VM_CPU}/${VM_TYPE} \ + -ljvm -lpthread invoke.cxx + +./invoke +exit $? From a92cdcd0107d4c8915680b14d4cc2b9fe14d8eb1 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Thu, 29 Aug 2013 22:44:19 +0400 Subject: [PATCH 0141/1294] 8023976: assert(!CompilationPolicy::can_be_compiled(this, comp_level)) failed: sanity check Reviewed-by: kvn, twisti --- hotspot/src/share/vm/oops/method.cpp | 19 +++++++++++++++++-- hotspot/src/share/vm/oops/method.hpp | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index 7082e72510e..b8e60a774f3 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -720,11 +720,22 @@ void Method::print_made_not_compilable(int comp_level, bool is_osr, bool report, } } +bool Method::is_always_compilable() const { + // Generated adapters must be compiled + if (is_method_handle_intrinsic() && is_synthetic()) { + assert(!is_not_c1_compilable(), "sanity check"); + assert(!is_not_c2_compilable(), "sanity check"); + return true; + } + + return false; +} + bool Method::is_not_compilable(int comp_level) const { if (number_of_breakpoints() > 0) return true; - if (is_method_handle_intrinsic()) - return !is_synthetic(); // the generated adapters must be compiled + if (is_always_compilable()) + return false; if (comp_level == CompLevel_any) return is_not_c1_compilable() || is_not_c2_compilable(); if (is_c1_compile(comp_level)) @@ -736,6 +747,10 @@ bool Method::is_not_compilable(int comp_level) const { // call this when compiler finds that this method is not compilable void Method::set_not_compilable(int comp_level, bool report, const char* reason) { + if (is_always_compilable()) { + // Don't mark a method which should be always compilable + return; + } print_made_not_compilable(comp_level, /*is_osr*/ false, report, reason); if (comp_level == CompLevel_all) { set_not_c1_compilable(); diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index 250d5c0d65f..faaf5105994 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -796,6 +796,7 @@ class Method : public Metadata { void set_not_osr_compilable_quietly(int comp_level = CompLevel_all) { set_not_osr_compilable(comp_level, false); } + bool is_always_compilable() const; private: void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason); From 1e581e11eaaa51a4631e6a97a960fea9c50dce20 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Thu, 3 Oct 2013 15:16:14 -0400 Subject: [PATCH 0142/1294] 8024427: Missing java.time.chrono serialization tests Add tests and cleanup existing serialization tests Reviewed-by: sherman --- .../java/time/temporal/ValueRange.java | 16 ++ .../time/tck/java/time/AbstractTCKTest.java | 35 +++- .../time/tck/java/time/TCKClock_Fixed.java | 6 - .../time/tck/java/time/TCKClock_Offset.java | 6 - .../time/tck/java/time/TCKClock_System.java | 8 - .../time/tck/java/time/TCKClock_Tick.java | 10 -- .../time/tck/java/time/chrono/CopticDate.java | 23 +++ .../time/chrono/TCKChronoZonedDateTime.java | 18 -- .../tck/java/time/chrono/TCKChronology.java | 17 -- .../time/chrono/TCKTestServiceLoader.java | 24 +-- .../TCKChronoLocalDateSerialization.java | 164 ++++++++++++++++++ ... TCKChronoLocalDateTimeSerialization.java} | 35 ++-- ... TCKChronoZonedDateTimeSerialization.java} | 46 ++--- .../serial/TCKChronologySerialization.java | 64 +++---- .../chrono/serial/TCKCopticSerialization.java | 82 +++++++++ .../chrono/serial/TCKEraSerialization.java | 135 ++++++++++++++ .../time/serial/TCKClockSerialization.java | 114 ++++++++++++ ...ion.java => TCKDurationSerialization.java} | 22 ++- ...tant.java => TCKInstantSerialization.java} | 4 +- ...te.java => TCKLocalDateSerialization.java} | 6 +- ...ava => TCKLocalDateTimeSerialization.java} | 6 +- ...me.java => TCKLocalTimeSerialization.java} | 4 +- ...Day.java => TCKMonthDaySerialization.java} | 9 +- ...va => TCKOffsetDateTimeSerialization.java} | 7 +- ...e.java => TCKOffsetTimeSerialization.java} | 4 +- ...eriod.java => TCKPeriodSerialization.java} | 5 +- ...th.java => TCKYearMonthSerialization.java} | 7 +- ...TCKYear.java => TCKYearSerialization.java} | 4 +- ...oneId.java => TCKZoneIdSerialization.java} | 4 +- ...t.java => TCKZoneOffsetSerialization.java} | 4 +- ...ava => TCKZonedDateTimeSerialization.java} | 5 +- .../java/time/temporal/TCKJulianFields.java | 17 +- .../serial/TCKChronoFieldSerialization.java | 145 ++++++++++++++++ .../serial/TCKChronoUnitSerialization.java | 122 +++++++++++++ .../serial/TCKJulianFieldsSerialization.java | 94 ++++++++++ .../serial/TCKValueRangeSerialization.java | 120 +++++++++++++ ...s.java => TCKWeekFieldsSerialization.java} | 4 +- .../time/zone/TCKZoneOffsetTransition.java | 2 - .../zone/TCKZoneOffsetTransitionRule.java | 3 - ...va => TCKFixedZoneRulesSerialization.java} | 4 +- ...oneOffsetTransitionRuleSerialization.java} | 34 +++- ...TCKZoneOffsetTransitionSerialization.java} | 26 ++- ...es.java => TCKZoneRulesSerialization.java} | 4 +- .../time/test/java/time/AbstractTest.java | 26 --- .../time/test/java/time/TestDuration.java | 28 --- .../time/temporal/TestDateTimeValueRange.java | 13 -- 46 files changed, 1208 insertions(+), 328 deletions(-) create mode 100644 jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateSerialization.java rename jdk/test/java/time/tck/java/time/chrono/serial/{TCKChronoLocalDateTime.java => TCKChronoLocalDateTimeSerialization.java} (78%) rename jdk/test/java/time/tck/java/time/chrono/serial/{TCKChronoLocalDate.java => TCKChronoZonedDateTimeSerialization.java} (77%) create mode 100644 jdk/test/java/time/tck/java/time/chrono/serial/TCKCopticSerialization.java create mode 100644 jdk/test/java/time/tck/java/time/chrono/serial/TCKEraSerialization.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKClockSerialization.java rename jdk/test/java/time/tck/java/time/serial/{TCKDuration.java => TCKDurationSerialization.java} (83%) rename jdk/test/java/time/tck/java/time/serial/{TCKInstant.java => TCKInstantSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKLocalDate.java => TCKLocalDateSerialization.java} (96%) rename jdk/test/java/time/tck/java/time/serial/{TCKLocalDateTime.java => TCKLocalDateTimeSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKLocalTime.java => TCKLocalTimeSerialization.java} (98%) rename jdk/test/java/time/tck/java/time/serial/{TCKMonthDay.java => TCKMonthDaySerialization.java} (96%) rename jdk/test/java/time/tck/java/time/serial/{TCKOffsetDateTime.java => TCKOffsetDateTimeSerialization.java} (96%) rename jdk/test/java/time/tck/java/time/serial/{TCKOffsetTime.java => TCKOffsetTimeSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKPeriod.java => TCKPeriodSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKYearMonth.java => TCKYearMonthSerialization.java} (96%) rename jdk/test/java/time/tck/java/time/serial/{TCKYear.java => TCKYearSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKZoneId.java => TCKZoneIdSerialization.java} (99%) rename jdk/test/java/time/tck/java/time/serial/{TCKZoneOffset.java => TCKZoneOffsetSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKZonedDateTime.java => TCKZonedDateTimeSerialization.java} (98%) create mode 100644 jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoFieldSerialization.java create mode 100644 jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoUnitSerialization.java create mode 100644 jdk/test/java/time/tck/java/time/temporal/serial/TCKJulianFieldsSerialization.java create mode 100644 jdk/test/java/time/tck/java/time/temporal/serial/TCKValueRangeSerialization.java rename jdk/test/java/time/tck/java/time/temporal/serial/{TCKWeekFields.java => TCKWeekFieldsSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/zone/serial/{TCKFixedZoneRules.java => TCKFixedZoneRulesSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/zone/serial/{TCKZoneOffsetTransitionRule.java => TCKZoneOffsetTransitionRuleSerialization.java} (77%) rename jdk/test/java/time/tck/java/time/zone/serial/{TCKZoneOffsetTransition.java => TCKZoneOffsetTransitionSerialization.java} (78%) rename jdk/test/java/time/tck/java/time/zone/serial/{TCKZoneRules.java => TCKZoneRulesSerialization.java} (98%) diff --git a/jdk/src/share/classes/java/time/temporal/ValueRange.java b/jdk/src/share/classes/java/time/temporal/ValueRange.java index e003f114adc..a48abafbf10 100644 --- a/jdk/src/share/classes/java/time/temporal/ValueRange.java +++ b/jdk/src/share/classes/java/time/temporal/ValueRange.java @@ -61,6 +61,7 @@ */ package java.time.temporal; +import java.io.InvalidObjectException; import java.io.Serializable; import java.time.DateTimeException; @@ -337,6 +338,21 @@ public final class ValueRange implements Serializable { } } + /** + * Return the ValueRange for the serialized values. + * The values are validated according to the constraints of the {@link #of} + * factory method. + * @return the ValueRange for the serialized fields + * @throws InvalidObjectException if the serialized object has invalid values + */ + private Object readResolve() throws InvalidObjectException { + try { + return of(minSmallest, minLargest, maxSmallest, maxLargest); + } catch (IllegalArgumentException iae) { + throw new InvalidObjectException("Invalid serialized ValueRange: " + iae.getMessage()); + } + } + //----------------------------------------------------------------------- /** * Checks if this range is equal to another range. diff --git a/jdk/test/java/time/tck/java/time/AbstractTCKTest.java b/jdk/test/java/time/tck/java/time/AbstractTCKTest.java index ff7fc02aa1f..29c2aa9fe1a 100644 --- a/jdk/test/java/time/tck/java/time/AbstractTCKTest.java +++ b/jdk/test/java/time/tck/java/time/AbstractTCKTest.java @@ -68,6 +68,8 @@ import java.io.ObjectOutputStream; import java.io.ObjectStreamConstants; import java.io.Serializable; import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Formatter; /** * Base test class. @@ -131,10 +133,10 @@ public abstract class AbstractTCKTest { assertEquals(dis.readByte(), ObjectStreamConstants.TC_NULL); // no superclasses if (expectedBytes.length < 256) { assertEquals(dis.readByte(), ObjectStreamConstants.TC_BLOCKDATA); - assertEquals(dis.readUnsignedByte(), expectedBytes.length); + assertEquals(dis.readUnsignedByte(), expectedBytes.length, "blockdata length incorrect"); } else { assertEquals(dis.readByte(), ObjectStreamConstants.TC_BLOCKDATALONG); - assertEquals(dis.readInt(), expectedBytes.length); + assertEquals(dis.readInt(), expectedBytes.length, "blockdatalong length incorrect"); } byte[] input = new byte[expectedBytes.length]; dis.readFully(input); @@ -162,4 +164,33 @@ public abstract class AbstractTCKTest { } } + + /** + * Utility method to dump a byte array in a java syntax. + * @param bytes and array of bytes + * @return a string containing the bytes formatted in java syntax + */ + protected static String dumpSerialStream(byte[] bytes) { + StringBuilder sb = new StringBuilder(bytes.length * 5); + Formatter fmt = new Formatter(sb); + fmt.format(" byte[] bytes = {" ); + final int linelen = 10; + for (int i = 0; i < bytes.length; i++) { + if (i % linelen == 0) { + fmt.format("%n "); + } + fmt.format(" %3d,", bytes[i] & 0xff); + if ((i % linelen) == (linelen-1) || i == bytes.length - 1) { + fmt.format(" /*"); + int s = i / linelen * linelen; + int k = i % linelen; + for (int j = 0; j <= k && s + j < bytes.length; j++) { + fmt.format(" %c", bytes[s + j] & 0xff); + } + fmt.format(" */"); + } + } + fmt.format("%n };%n"); + return sb.toString(); + } } diff --git a/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java b/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java index ef9f12acc47..3dc567d0ec1 100644 --- a/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java +++ b/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java @@ -80,12 +80,6 @@ public class TCKClock_Fixed extends AbstractTCKTest { private static final ZoneId PARIS = ZoneId.of("Europe/Paris"); private static final Instant INSTANT = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).atZone(ZoneOffset.ofHours(2)).toInstant(); - //----------------------------------------------------------------------- - public void test_isSerializable() throws IOException, ClassNotFoundException { - assertSerializable(Clock.fixed(INSTANT, ZoneOffset.UTC)); - assertSerializable(Clock.fixed(INSTANT, PARIS)); - } - //------------------------------------------------------------------------- public void test_fixed_InstantZoneId() { Clock test = Clock.fixed(INSTANT, PARIS); diff --git a/jdk/test/java/time/tck/java/time/TCKClock_Offset.java b/jdk/test/java/time/tck/java/time/TCKClock_Offset.java index 3bab2acd52f..644c1a63880 100644 --- a/jdk/test/java/time/tck/java/time/TCKClock_Offset.java +++ b/jdk/test/java/time/tck/java/time/TCKClock_Offset.java @@ -62,7 +62,6 @@ package tck.java.time; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertSame; -import java.io.IOException; import java.time.Clock; import java.time.Duration; import java.time.Instant; @@ -83,11 +82,6 @@ public class TCKClock_Offset extends AbstractTCKTest { private static final Instant INSTANT = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).atZone(ZoneOffset.ofHours(2)).toInstant(); private static final Duration OFFSET = Duration.ofSeconds(2); - //----------------------------------------------------------------------- - public void test_isSerializable() throws IOException, ClassNotFoundException { - assertSerializable(Clock.offset(Clock.system(PARIS), OFFSET)); - } - //----------------------------------------------------------------------- public void test_offset_ClockDuration() { Clock test = Clock.offset(Clock.fixed(INSTANT, PARIS), OFFSET); diff --git a/jdk/test/java/time/tck/java/time/TCKClock_System.java b/jdk/test/java/time/tck/java/time/TCKClock_System.java index b5440b2bfd5..94f3b57a4aa 100644 --- a/jdk/test/java/time/tck/java/time/TCKClock_System.java +++ b/jdk/test/java/time/tck/java/time/TCKClock_System.java @@ -62,7 +62,6 @@ package tck.java.time; import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; -import java.io.IOException; import java.time.Clock; import java.time.Instant; import java.time.ZoneId; @@ -79,13 +78,6 @@ public class TCKClock_System extends AbstractTCKTest { private static final ZoneId MOSCOW = ZoneId.of("Europe/Moscow"); private static final ZoneId PARIS = ZoneId.of("Europe/Paris"); - //----------------------------------------------------------------------- - public void test_isSerializable() throws IOException, ClassNotFoundException { - assertSerializable(Clock.systemUTC()); - assertSerializable(Clock.systemDefaultZone()); - assertSerializable(Clock.system(PARIS)); - } - //----------------------------------------------------------------------- public void test_instant() { Clock system = Clock.systemUTC(); diff --git a/jdk/test/java/time/tck/java/time/TCKClock_Tick.java b/jdk/test/java/time/tck/java/time/TCKClock_Tick.java index b245d143ccb..c2212373cd8 100644 --- a/jdk/test/java/time/tck/java/time/TCKClock_Tick.java +++ b/jdk/test/java/time/tck/java/time/TCKClock_Tick.java @@ -62,7 +62,6 @@ package tck.java.time; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertSame; -import java.io.IOException; import java.time.Clock; import java.time.Duration; import java.time.Instant; @@ -81,16 +80,7 @@ public class TCKClock_Tick extends AbstractTCKTest { private static final ZoneId MOSCOW = ZoneId.of("Europe/Moscow"); private static final ZoneId PARIS = ZoneId.of("Europe/Paris"); - private static final Duration AMOUNT = Duration.ofSeconds(2); private static final ZonedDateTime ZDT = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).atZone(ZoneOffset.ofHours(2)); - private static final Instant INSTANT = ZDT.toInstant(); - - //----------------------------------------------------------------------- - public void test_isSerializable() throws IOException, ClassNotFoundException { - assertSerializable(Clock.tickSeconds(PARIS)); - assertSerializable(Clock.tickMinutes(MOSCOW)); - assertSerializable(Clock.tick(Clock.fixed(INSTANT, PARIS), AMOUNT)); - } //----------------------------------------------------------------------- public void test_tick_ClockDuration_250millis() { diff --git a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java index eca228adecb..6377c1fc421 100644 --- a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java +++ b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java @@ -354,4 +354,27 @@ public final class CopticDate .append(dom < 10 ? "-0" : "-").append(dom); return buf.toString(); } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof CopticDate) { + CopticDate cd = (CopticDate)obj; + if (this.prolepticYear == cd.prolepticYear && + this.month == cd.month && + this.day == cd.day) { + return true; + } + } + return false; + } + + @Override + public int hashCode() { + long epDay = toEpochDay(); + return getChronology().hashCode() ^ ((int) (epDay ^ (epDay >>> 32))); + } + } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java index 3b89857fa45..b2b7fc2cc6c 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java @@ -320,24 +320,6 @@ public class TCKChronoZonedDateTime { } } - //----------------------------------------------------------------------- - // Test Serialization of ISO via chrono API - //----------------------------------------------------------------------- - @Test( dataProvider="calendars") - public void test_ChronoZonedDateTimeSerialization(Chronology chrono) throws Exception { - ZonedDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3).atZone(ZoneId.of("GMT+01:23")); - ChronoZonedDateTime orginal = chrono.date(ref).atTime(ref.toLocalTime()).atZone(ref.getZone()); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - @SuppressWarnings("unchecked") - ChronoZonedDateTime ser = (ChronoZonedDateTime) in.readObject(); - assertEquals(ser, orginal, "deserialized date is wrong"); - } - //----------------------------------------------------------------------- @Test(dataProvider="calendars") public void test_from_TemporalAccessor(Chronology chrono) { diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java index 363f2b94044..38f85fe08ac 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java @@ -64,7 +64,6 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; -import java.util.Locale; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; @@ -338,20 +337,4 @@ public class TCKChronology { Chronology chrono = Chronology.of("FooFoo"); } - //----------------------------------------------------------------------- - // serialization; serialize and check each calendar system - //----------------------------------------------------------------------- - @Test(dataProvider = "calendarNameAndType") - public void test_chronoSerializationSingleton(String id, String _calendarType) throws Exception { - Chronology original = Chronology.of(id); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(original); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - Chronology ser = (Chronology) in.readObject(); - assertEquals(ser, original, "Deserialized Chronology is not correct"); - } - } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java b/jdk/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java index b67f01185aa..1518c0cde29 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java @@ -60,10 +60,6 @@ package tck.java.time.chrono; import static org.testng.Assert.assertEquals; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.time.LocalDate; import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; @@ -78,29 +74,11 @@ import org.testng.annotations.Test; public class TCKTestServiceLoader { @Test - public void test_CopticServiceLoader() { + public void test_TestServiceLoader() { Chronology chrono = Chronology.of("Coptic"); ChronoLocalDate copticDate = chrono.date(1729, 4, 27); LocalDate ld = LocalDate.from(copticDate); assertEquals(ld, LocalDate.of(2013, 1, 5), "CopticDate does not match LocalDate"); } - - //----------------------------------------------------------------------- - // Test Serialization of Loaded Coptic Calendar - //----------------------------------------------------------------------- - @Test - public void test_ChronoSerialization() throws Exception { - Chronology chrono = Chronology.of("Coptic"); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(chrono); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - - ObjectInputStream in = new ObjectInputStream(bais); - @SuppressWarnings("unchecked") - Chronology ser = (Chronology) in.readObject(); - assertEquals(ser, chrono, "deserialized Chronology is wrong"); - } } diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateSerialization.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateSerialization.java new file mode 100644 index 00000000000..af6e9fb2e02 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateSerialization.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono.serial; + +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.YEAR; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.ObjectStreamConstants; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.HijrahChronology; +import java.time.chrono.HijrahDate; +import java.time.chrono.JapaneseDate; +import java.time.chrono.JapaneseEra; +import java.time.chrono.MinguoDate; +import java.time.chrono.ThaiBuddhistDate; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + + + +import tck.java.time.AbstractTCKTest; + +/** + * Test serialization of built-in chronologies. + */ +@Test +public class TCKChronoLocalDateSerialization extends AbstractTCKTest { + + static final int CHRONO_TYPE = 1; // java.time.chrono.Ser.CHRONO_TYPE + static final int JAPANESE_DATE_TYPE = 4; // java.time.chrono.Ser.JAPANESE_DATE_TYPE + static final int HIJRAH_DATE_TYPE = 6; // java.time.chrono.Ser.HIJRAH_DATE_TYPE + static final int MINGUO_DATE_TYPE = 7; // java.time.chrono.Ser.MINGUO_DATE_TYPE + static final int THAIBUDDHIST_DATE_TYPE = 8; // java.time.chrono.Ser.THAIBUDDHIST_DATE_TYPE + + //----------------------------------------------------------------------- + // Regular data factory for names and descriptions of available calendars + //----------------------------------------------------------------------- + @DataProvider(name = "calendars") + Object[][] data_of_calendars() { + return new Object[][]{ + {JapaneseDate.of(JapaneseEra.HEISEI, 25, 01, 05), JAPANESE_DATE_TYPE}, + {MinguoDate.of(102, 01, 05), MINGUO_DATE_TYPE}, + {ThaiBuddhistDate.of(2556, 01, 05), THAIBUDDHIST_DATE_TYPE}, + }; + } + + + //----------------------------------------------------------------------- + // Test Serialization of Calendars + //----------------------------------------------------------------------- + @Test( dataProvider="calendars") + public void test_ChronoSerialization(ChronoLocalDate date, int dateType) throws Exception { + assertSerializable(date); + } + + //----------------------------------------------------------------------- + // Test that serialization produces exact sequence of bytes + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + private void test_serialization_format(ChronoLocalDate date, int dateType) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(dateType); + dos.writeInt(date.get(YEAR)); + dos.writeByte(date.get(MONTH_OF_YEAR)); + dos.writeByte(date.get(DAY_OF_MONTH)); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(date, bytes); + } + + //----------------------------------------------------------------------- + // Test HijrajDate serialization is a type, Chronology, year, month, day + //----------------------------------------------------------------------- + @Test() + public void test_hijrahSerialization_format() throws Exception { + HijrahChronology chrono = HijrahChronology.INSTANCE; + HijrahDate date = HijrahDate.of(1433, 10, 29); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // Expect the type of the HijrahDate in the stream + byte[] hijrahDateBytes = new byte[] {HIJRAH_DATE_TYPE}; + + // Literal reference to Hijrah-Umalqura Chronology + byte[] hijrahChronoBytes = new byte[] { + 115, 113, 0, 126, 0, 0, /* p w \u0001 \u0006 s q \u0000 ~ \u0000 \u0000 */ + 119, 18, 1, 0, 15, 72, 105, 106, 114, 97, /* w \u0012 \u0001 \u0000 \u000f H i j r a */ + 104, 45, 117, 109, 97, 108, 113, 117, 114, 97, /* h - u m a l q u r a */ + 120, /* \u001d x */ + }; + + // Build the sequence that represents the data in the stream + baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA); + dos.writeByte(6); // 6 bytes follow + dos.writeInt(date.get(YEAR)); + dos.writeByte(date.get(MONTH_OF_YEAR)); + dos.writeByte(date.get(DAY_OF_MONTH)); + dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); + } + byte[] dateBytes = baos.toByteArray(); + + assertSerializedBySer(date, hijrahDateBytes, hijrahChronoBytes, dateBytes); + } +} diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTimeSerialization.java similarity index 78% rename from jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java rename to jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTimeSerialization.java index 1ab1cda92c5..8da904b41c8 100644 --- a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTimeSerialization.java @@ -59,21 +59,23 @@ package tck.java.time.chrono.serial; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.chrono.*; +import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.Chronology; +import java.time.chrono.HijrahChronology; +import java.time.chrono.IsoChronology; +import java.time.chrono.JapaneseChronology; +import java.time.chrono.MinguoChronology; +import java.time.chrono.ThaiBuddhistChronology; -import static org.testng.Assert.assertEquals; +import tck.java.time.AbstractTCKTest; /** - * Test assertions that must be true for all built-in chronologies. + * Test serialization of ChronoLocalDateTime for all built-in chronologies. */ @Test -public class TCKChronoLocalDateTime { +public class TCKChronoLocalDateTimeSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- // regular data factory for available calendars @@ -89,22 +91,13 @@ public class TCKChronoLocalDateTime { } //----------------------------------------------------------------------- - // Test Serialization ZonedDateTime for each Chronology + // Test Serialization of ChronoLocalDateTime //----------------------------------------------------------------------- - @Test( dataProvider="calendars") + @Test(dataProvider="calendars") public void test_ChronoLocalDateTimeSerialization(Chronology chrono) throws Exception { LocalDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3); - ChronoLocalDateTime orginal = chrono.date(ref).atTime(ref.toLocalTime()); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - ChronoLocalDateTime ser = (ChronoLocalDateTime) in.readObject(); - assertEquals(ser, orginal, "deserialized date is wrong"); + ChronoLocalDateTime original = chrono.date(ref).atTime(ref.toLocalTime()); + assertSerializable(original); } - //----------------------------------------------------------------------- - } diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoZonedDateTimeSerialization.java similarity index 77% rename from jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java rename to jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoZonedDateTimeSerialization.java index 4bec5cdc952..c941453a969 100644 --- a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoZonedDateTimeSerialization.java @@ -56,23 +56,25 @@ */ package tck.java.time.chrono.serial; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.chrono.ChronoZonedDateTime; +import java.time.chrono.Chronology; +import java.time.chrono.HijrahChronology; +import java.time.chrono.IsoChronology; +import java.time.chrono.JapaneseChronology; +import java.time.chrono.MinguoChronology; +import java.time.chrono.ThaiBuddhistChronology; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.time.LocalDate; -import java.time.chrono.*; - -import static org.testng.Assert.assertEquals; +import tck.java.time.AbstractTCKTest; /** * Test assertions that must be true for all built-in chronologies. */ @Test -public class TCKChronoLocalDate { +public class TCKChronoZonedDateTimeSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- // regular data factory for names and descriptions of available calendars @@ -84,28 +86,18 @@ public class TCKChronoLocalDate { {IsoChronology.INSTANCE}, {JapaneseChronology.INSTANCE}, {MinguoChronology.INSTANCE}, - {ThaiBuddhistChronology.INSTANCE}}; + {ThaiBuddhistChronology.INSTANCE}, + }; } - //----------------------------------------------------------------------- - // Test Serialization of Calendars + // Test Serialization of ISO via chrono API //----------------------------------------------------------------------- @Test( dataProvider="calendars") - public void test_ChronoSerialization(Chronology chrono) throws Exception { - LocalDate ref = LocalDate.of(2013, 1, 5); - ChronoLocalDate orginal = chrono.date(ref); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - @SuppressWarnings("unchecked") - ChronoLocalDate ser = (ChronoLocalDate) in.readObject(); - assertEquals(ser, orginal, "deserialized date is wrong"); + public void test_ChronoZonedDateTimeSerialization(Chronology chrono) throws Exception { + ZonedDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3).atZone(ZoneId.of("GMT+01:23")); + ChronoZonedDateTime original = chrono.date(ref).atTime(ref.toLocalTime()).atZone(ref.getZone()); + assertSerializable(original); } - //----------------------------------------------------------------------- - } diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java index aed919adafa..7f9e30d35c5 100644 --- a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java @@ -56,13 +56,9 @@ */ package tck.java.time.chrono.serial; -import static org.testng.Assert.assertEquals; - -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.PrintStream; +import java.io.DataOutputStream; + import java.time.chrono.Chronology; import java.time.chrono.HijrahChronology; import java.time.chrono.IsoChronology; @@ -73,11 +69,15 @@ import java.time.chrono.ThaiBuddhistChronology; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + @Test -public class TCKChronologySerialization { +public class TCKChronologySerialization extends AbstractTCKTest { + + static final int CHRONO_TYPE = 1; // java.time.chrono.Ser.CHRONO_TYPE //----------------------------------------------------------------------- - // regular data factory for names and descriptions of available calendars + // Regular data factory for available calendars //----------------------------------------------------------------------- @DataProvider(name = "calendars") Chronology[][] data_of_calendars() { @@ -93,44 +93,22 @@ public class TCKChronologySerialization { // Test Serialization of Calendars //----------------------------------------------------------------------- @Test(dataProvider="calendars") - public void test_ChronoSerialization(Chronology chrono) throws Exception { - System.out.printf(" ChronoSerialization: %s%n", chrono); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(chrono); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - - ObjectInputStream in = new ObjectInputStream(bais); - @SuppressWarnings("unchecked") - Chronology ser = (Chronology) in.readObject(); - assertEquals(ser, chrono, "deserialized Chronology is wrong"); + public void test_chronoSerialization(Chronology chrono) throws Exception { + assertSerializable(chrono); } - /** - * Utility method to dump a byte array in a java syntax. - * @param bytes and array of bytes - * @param os the outputstream to receive the output. - */ - static void dumpSerialStream(byte[] bytes, PrintStream os) { - os.printf(" byte[] bytes = {" ); - final int linelen = 10; - for (int i = 0; i < bytes.length; i++) { - if (i % linelen == 0) { - os.printf("%n "); - } - os.printf(" %3d,", bytes[i] & 0xff); - if ((i % linelen) == (linelen-1) || i == bytes.length - 1) { - os.printf(" /*"); - int s = i / linelen * linelen; - int k = i % linelen; - for (int j = 0; j <= k && s + j < bytes.length; j++) { - os.printf(" %c", bytes[s + j] & 0xff); - } - os.printf(" */"); - } + //----------------------------------------------------------------------- + // Test that serialization produces exact sequence of bytes + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + private void test_serializationBytes(Chronology chrono) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(CHRONO_TYPE); + dos.writeUTF(chrono.getId()); } - os.printf("%n };%n"); + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(chrono, bytes); } } diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKCopticSerialization.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKCopticSerialization.java new file mode 100644 index 00000000000..0fc489ee27c --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKCopticSerialization.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono.serial; + +import java.io.IOException; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.Chronology; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +/** + * Tests the serialization of ChronoLocalDate using a CopticDate. + */ +@Test +public class TCKCopticSerialization extends AbstractTCKTest { + + @Test + public void test_eraSerialization() throws IOException, ClassNotFoundException { + Chronology chrono = Chronology.of("Coptic"); + ChronoLocalDate copticDate = chrono.date(1729, 4, 27); + assertSerializable(copticDate); + } + +} diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKEraSerialization.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKEraSerialization.java new file mode 100644 index 00000000000..8df56baa8ef --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKEraSerialization.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono.serial; + + +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.YEAR; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.Era; +import java.time.chrono.HijrahEra; +import java.time.chrono.IsoEra; +import java.time.chrono.JapaneseEra; +import java.time.chrono.MinguoEra; +import java.time.chrono.ThaiBuddhistEra; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Tests the built-in Eras are serializable. + * Note that the serialized form of IsoEra, MinguoEra, ThaiBuddhistEra, + * and HijrahEra are defined and provided by Enum. + * The serialized form of these types are not tested, only that they are + * serializable. + */ +@Test +public class TCKEraSerialization extends AbstractTCKTest { + + static final int JAPANESE_ERA_TYPE = 5; // java.time.chrono.Ser.JAPANESE_ERA + + + //----------------------------------------------------------------------- + // Regular data factory for the available Eras + //----------------------------------------------------------------------- + @DataProvider(name = "Eras") + Era[][] data_of_calendars() { + return new Era[][] { + {HijrahEra.AH}, + {IsoEra.BCE}, + {IsoEra.CE}, + {MinguoEra.BEFORE_ROC}, + {MinguoEra.ROC}, + {ThaiBuddhistEra.BEFORE_BE}, + {ThaiBuddhistEra.BE}, + }; + } + + @Test(dataProvider="Eras") + public void test_eraSerialization(Era era) throws IOException, ClassNotFoundException { + assertSerializableSame(era); + } + + //----------------------------------------------------------------------- + // Test JapaneseEra serialization produces exact sequence of bytes + //----------------------------------------------------------------------- + @Test + private void test_JapaneseErasSerialization() throws Exception { + for (JapaneseEra era : JapaneseEra.values()) { + assertSerializableSame(era); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(JAPANESE_ERA_TYPE); + dos.writeByte(era.getValue()); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(era, bytes); + } + } + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKClockSerialization.java b/jdk/test/java/time/tck/java/time/serial/TCKClockSerialization.java new file mode 100644 index 00000000000..d3ef560fb3f --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKClockSerialization.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012 Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + + +import java.io.IOException; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Test system and offset clocks serialization. + */ +@Test +public class TCKClockSerialization extends AbstractTCKTest { + + private static final ZoneId MOSCOW = ZoneId.of("Europe/Moscow"); + private static final ZoneId PARIS = ZoneId.of("Europe/Paris"); + + private static final Duration AMOUNT = Duration.ofSeconds(2); + private static final ZonedDateTime ZDT = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).atZone(ZoneOffset.ofHours(2)); + private static final Instant INSTANT = ZDT.toInstant(); + + //----------------------------------------------------------------------- + public void test_systemClockSerializable() throws IOException, ClassNotFoundException { + assertSerializable(Clock.systemUTC()); + assertSerializable(Clock.systemDefaultZone()); + assertSerializable(Clock.system(PARIS)); + } + + //----------------------------------------------------------------------- + public void test_offsetClockSerializable() throws IOException, ClassNotFoundException { + assertSerializable(Clock.offset(Clock.system(PARIS), AMOUNT)); + } + + //----------------------------------------------------------------------- + public void test_tickClockSerializable() throws IOException, ClassNotFoundException { + assertSerializable(Clock.tickSeconds(PARIS)); + assertSerializable(Clock.tickMinutes(MOSCOW)); + assertSerializable(Clock.tick(Clock.fixed(INSTANT, PARIS), AMOUNT)); + } + + //----------------------------------------------------------------------- + public void test_fixedClockSerializable() throws IOException, ClassNotFoundException { + assertSerializable(Clock.fixed(INSTANT, ZoneOffset.UTC)); + assertSerializable(Clock.fixed(INSTANT, PARIS)); + } + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKDuration.java b/jdk/test/java/time/tck/java/time/serial/TCKDurationSerialization.java similarity index 83% rename from jdk/test/java/time/tck/java/time/serial/TCKDuration.java rename to jdk/test/java/time/tck/java/time/serial/TCKDurationSerialization.java index e4a9a3f9a18..15d079b9b41 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKDuration.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKDurationSerialization.java @@ -59,18 +59,28 @@ */ package tck.java.time.serial; +import static org.testng.Assert.assertTrue; + import org.testng.annotations.Test; import tck.java.time.AbstractTCKTest; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; +import java.io.Serializable; import java.time.Duration; /** - * Test Duration. + * Test Duration serialization. */ @Test -public class TCKDuration extends AbstractTCKTest { +public class TCKDurationSerialization extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_interfaces() { + assertTrue(Serializable.class.isAssignableFrom(Duration.class)); + assertTrue(Comparable.class.isAssignableFrom(Duration.class)); + } //----------------------------------------------------------------------- @Test @@ -92,4 +102,12 @@ public class TCKDuration extends AbstractTCKTest { assertSerializedBySer(Duration.ofSeconds(654321, 123456789), bytes); } + //----------------------------------------------------------------------- + // serialization + //----------------------------------------------------------------------- + @Test + public void test_deserializationSingleton() throws Exception { + assertSerializableSame(Duration.ZERO); + } + } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKInstant.java b/jdk/test/java/time/tck/java/time/serial/TCKInstantSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKInstant.java rename to jdk/test/java/time/tck/java/time/serial/TCKInstantSerialization.java index 783ad586375..34a7a513797 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKInstant.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKInstantSerialization.java @@ -68,10 +68,10 @@ import java.io.DataOutputStream; import java.time.Instant; /** - * Test Instant. + * Test Instant serialization. */ @Test -public class TCKInstant extends AbstractTCKTest { +public class TCKInstantSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- @Test diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateSerialization.java similarity index 96% rename from jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java rename to jdk/test/java/time/tck/java/time/serial/TCKLocalDateSerialization.java index aeaa96d372d..c42fa5ece91 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateSerialization.java @@ -68,10 +68,10 @@ import java.io.DataOutputStream; import java.time.LocalDate; /** - * Test LocalDate. + * Test LocalDate serialization. */ @Test -public class TCKLocalDate extends AbstractTCKTest { +public class TCKLocalDateSerialization extends AbstractTCKTest { private LocalDate TEST_2007_07_15; @@ -102,6 +102,4 @@ public class TCKLocalDate extends AbstractTCKTest { assertSerializedBySer(LocalDate.of(2012, 9, 16), bytes); } - //----------------------------------------------------------------------- - } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTimeSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java rename to jdk/test/java/time/tck/java/time/serial/TCKLocalDateTimeSerialization.java index a2ae9d2357c..aa739768808 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTimeSerialization.java @@ -67,10 +67,10 @@ import java.io.DataOutputStream; import java.time.LocalDateTime; /** - * Test LocalDateTime. + * Test serialization of LocalDateTime. */ @Test -public class TCKLocalDateTime extends AbstractTCKTest { +public class TCKLocalDateTimeSerialization extends AbstractTCKTest { private LocalDateTime TEST_2007_07_15_12_30_40_987654321 = LocalDateTime.of(2007, 7, 15, 12, 30, 40, 987654321); @@ -99,6 +99,4 @@ public class TCKLocalDateTime extends AbstractTCKTest { assertSerializedBySer(LocalDateTime.of(2012, 9, 16, 22, 17, 59, 459_000_000), bytes); } - - } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalTimeSerialization.java similarity index 98% rename from jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java rename to jdk/test/java/time/tck/java/time/serial/TCKLocalTimeSerialization.java index 06f2ce4c898..d78de651877 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalTimeSerialization.java @@ -68,10 +68,10 @@ import java.io.DataOutputStream; import java.time.LocalTime; /** - * Test LocalTime. + * Test LocalTime serialization. */ @Test -public class TCKLocalTime extends AbstractTCKTest { +public class TCKLocalTimeSerialization extends AbstractTCKTest { private LocalTime TEST_12_30_40_987654321; diff --git a/jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java b/jdk/test/java/time/tck/java/time/serial/TCKMonthDaySerialization.java similarity index 96% rename from jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java rename to jdk/test/java/time/tck/java/time/serial/TCKMonthDaySerialization.java index cd441663099..8650e7e641e 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKMonthDaySerialization.java @@ -69,10 +69,10 @@ import java.io.IOException; import java.time.MonthDay; /** - * Test MonthDay. + * Test MonthDay serialization. */ @Test -public class TCKMonthDay extends AbstractTCKTest { +public class TCKMonthDaySerialization extends AbstractTCKTest { private MonthDay TEST_07_15; @@ -81,8 +81,6 @@ public class TCKMonthDay extends AbstractTCKTest { TEST_07_15 = MonthDay.of(7, 15); } - - //----------------------------------------------------------------------- @Test public void test_serialization() throws ClassNotFoundException, IOException { @@ -101,7 +99,4 @@ public class TCKMonthDay extends AbstractTCKTest { assertSerializedBySer(MonthDay.of(9, 16), bytes); } - //----------------------------------------------------------------------- - - } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTimeSerialization.java similarity index 96% rename from jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java rename to jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTimeSerialization.java index 8a1406b8727..371014f5e5c 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTimeSerialization.java @@ -70,10 +70,10 @@ import java.time.OffsetDateTime; import java.time.ZoneOffset; /** - * Test OffsetDateTime. + * Test OffsetDateTime serialization. */ @Test -public class TCKOffsetDateTime extends AbstractTCKTest { +public class TCKOffsetDateTimeSerialization extends AbstractTCKTest { private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); private OffsetDateTime TEST_2008_6_30_11_30_59_000000500; @@ -83,9 +83,6 @@ public class TCKOffsetDateTime extends AbstractTCKTest { TEST_2008_6_30_11_30_59_000000500 = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 500, OFFSET_PONE); } - //----------------------------------------------------------------------- - - //----------------------------------------------------------------------- @Test public void test_serialization() throws Exception { diff --git a/jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/serial/TCKOffsetTimeSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java rename to jdk/test/java/time/tck/java/time/serial/TCKOffsetTimeSerialization.java index 6bdddba2fb3..ee04e1e298f 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKOffsetTimeSerialization.java @@ -69,10 +69,10 @@ import java.time.OffsetTime; import java.time.ZoneOffset; /** - * Test OffsetTime. + * Test OffsetTime serialization. */ @Test -public class TCKOffsetTime extends AbstractTCKTest { +public class TCKOffsetTimeSerialization extends AbstractTCKTest { private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); private OffsetTime TEST_11_30_59_500_PONE; diff --git a/jdk/test/java/time/tck/java/time/serial/TCKPeriod.java b/jdk/test/java/time/tck/java/time/serial/TCKPeriodSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKPeriod.java rename to jdk/test/java/time/tck/java/time/serial/TCKPeriodSerialization.java index 2f94df132f0..57bb92f7dce 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKPeriod.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKPeriodSerialization.java @@ -65,10 +65,10 @@ import tck.java.time.AbstractTCKTest; import java.time.Period; /** - * Test Period. + * Test serialization of Period. */ @Test -public class TCKPeriod extends AbstractTCKTest { +public class TCKPeriodSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- @Test @@ -78,5 +78,4 @@ public class TCKPeriod extends AbstractTCKTest { assertSerializable(Period.of(1, 2, 3)); } - } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java b/jdk/test/java/time/tck/java/time/serial/TCKYearMonthSerialization.java similarity index 96% rename from jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java rename to jdk/test/java/time/tck/java/time/serial/TCKYearMonthSerialization.java index 675767d976c..878b1639725 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKYearMonthSerialization.java @@ -69,10 +69,10 @@ import java.io.IOException; import java.time.YearMonth; /** - * Test YearMonth. + * Test serialization of YearMonth. */ @Test -public class TCKYearMonth extends AbstractTCKTest { +public class TCKYearMonthSerialization extends AbstractTCKTest { private YearMonth TEST_2008_06; @@ -100,7 +100,4 @@ public class TCKYearMonth extends AbstractTCKTest { assertSerializedBySer(YearMonth.of(2012, 9), bytes); } - //----------------------------------------------------------------------- - - } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKYear.java b/jdk/test/java/time/tck/java/time/serial/TCKYearSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKYear.java rename to jdk/test/java/time/tck/java/time/serial/TCKYearSerialization.java index 954dacf0c99..12f3955dcc4 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKYear.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKYearSerialization.java @@ -67,10 +67,10 @@ import java.io.DataOutputStream; import java.time.Year; /** - * Test Year. + * Test Year serialization. */ @Test -public class TCKYear extends AbstractTCKTest { +public class TCKYearSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- @Test diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZoneId.java b/jdk/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java similarity index 99% rename from jdk/test/java/time/tck/java/time/serial/TCKZoneId.java rename to jdk/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java index 26923f12a80..c6f3abee38c 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKZoneId.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java @@ -73,10 +73,10 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; /** - * Test ZoneId. + * Test serialization of ZoneId. */ @Test -public class TCKZoneId extends AbstractTCKTest { +public class TCKZoneIdSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- @Test diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java b/jdk/test/java/time/tck/java/time/serial/TCKZoneOffsetSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java rename to jdk/test/java/time/tck/java/time/serial/TCKZoneOffsetSerialization.java index 61196e909a1..223d466fcb3 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKZoneOffsetSerialization.java @@ -67,10 +67,10 @@ import java.io.DataOutputStream; import java.time.ZoneOffset; /** - * Test ZoneOffset. + * Test serialization of ZoneOffset. */ @Test -public class TCKZoneOffset extends AbstractTCKTest { +public class TCKZoneOffsetSerialization extends AbstractTCKTest { diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTimeSerialization.java similarity index 98% rename from jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java rename to jdk/test/java/time/tck/java/time/serial/TCKZonedDateTimeSerialization.java index a44946b7450..bde33acc04b 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTimeSerialization.java @@ -72,10 +72,10 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; /** - * Test ZonedDateTime. + * Test serialization of ZonedDateTime. */ @Test -public class TCKZonedDateTime extends AbstractTCKTest { +public class TCKZonedDateTimeSerialization extends AbstractTCKTest { private static final ZoneOffset OFFSET_0100 = ZoneOffset.ofHours(1); private static final ZoneId ZONE_0100 = OFFSET_0100; @@ -139,5 +139,4 @@ public class TCKZonedDateTime extends AbstractTCKTest { assertSerializedBySer(zdt, bytes); } - } diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java index 711792fbedb..a15c31dd2c7 100644 --- a/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java +++ b/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java @@ -76,7 +76,7 @@ import org.testng.annotations.Test; import tck.java.time.AbstractTCKTest; /** - * Test. + * Test Julian Fields. */ @Test public class TCKJulianFields extends AbstractTCKTest { @@ -86,16 +86,6 @@ public class TCKJulianFields extends AbstractTCKTest { private static final LocalDate NOV12_1945 = LocalDate.of(1945, 11, 12); private static final LocalDate JAN01_0001 = LocalDate.of(1, 1, 1); - //----------------------------------------------------------------------- - @DataProvider(name="julian_fields") - Object[][] julian_samples() { - return new Object[][] { - {JulianFields.JULIAN_DAY}, - {JulianFields.MODIFIED_JULIAN_DAY}, - {JulianFields.RATA_DIE}, - }; - } - @DataProvider(name="samples") Object[][] data_samples() { return new Object[][] { @@ -122,11 +112,6 @@ public class TCKJulianFields extends AbstractTCKTest { } //----------------------------------------------------------------------- - @Test(dataProvider="julian_fields") - public void test_serializable(TemporalField field) throws IOException, ClassNotFoundException { - assertSerializable(field); - } - public void test_basics() { assertEquals(JulianFields.JULIAN_DAY.isDateBased(), true); assertEquals(JulianFields.JULIAN_DAY.isTimeBased(), false); diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoFieldSerialization.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoFieldSerialization.java new file mode 100644 index 00000000000..a80869dc775 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoFieldSerialization.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal.serial; + +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; +import static java.time.temporal.ChronoField.AMPM_OF_DAY; +import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM; +import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_DAY; +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_WEEK; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; +import static java.time.temporal.ChronoField.EPOCH_DAY; +import static java.time.temporal.ChronoField.HOUR_OF_AMPM; +import static java.time.temporal.ChronoField.HOUR_OF_DAY; +import static java.time.temporal.ChronoField.MICRO_OF_DAY; +import static java.time.temporal.ChronoField.MICRO_OF_SECOND; +import static java.time.temporal.ChronoField.MILLI_OF_DAY; +import static java.time.temporal.ChronoField.MILLI_OF_SECOND; +import static java.time.temporal.ChronoField.MINUTE_OF_DAY; +import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.NANO_OF_DAY; +import static java.time.temporal.ChronoField.NANO_OF_SECOND; +import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; +import static java.time.temporal.ChronoField.SECOND_OF_DAY; +import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; +import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoField.ERA; + +import java.io.IOException; +import java.time.temporal.ChronoField; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Test serialization of ChronoField. + */ +@Test +public class TCKChronoFieldSerialization extends AbstractTCKTest { + + //----------------------------------------------------------------------- + // List of Fields + //----------------------------------------------------------------------- + @DataProvider(name="fieldBased") + Object[][] data_fieldBased() { + return new Object[][] { + {DAY_OF_WEEK}, + {ALIGNED_DAY_OF_WEEK_IN_MONTH}, + {ALIGNED_DAY_OF_WEEK_IN_YEAR}, + {DAY_OF_MONTH}, + {DAY_OF_YEAR}, + {EPOCH_DAY}, + {ALIGNED_WEEK_OF_MONTH}, + {ALIGNED_WEEK_OF_YEAR}, + {MONTH_OF_YEAR}, + {PROLEPTIC_MONTH}, + {YEAR_OF_ERA}, + {YEAR}, + {ERA}, + + {AMPM_OF_DAY}, + {CLOCK_HOUR_OF_DAY}, + {HOUR_OF_DAY}, + {CLOCK_HOUR_OF_AMPM}, + {HOUR_OF_AMPM}, + {MINUTE_OF_DAY}, + {MINUTE_OF_HOUR}, + {SECOND_OF_DAY}, + {SECOND_OF_MINUTE}, + {MILLI_OF_DAY}, + {MILLI_OF_SECOND}, + {MICRO_OF_DAY}, + {MICRO_OF_SECOND}, + {NANO_OF_DAY}, + {NANO_OF_SECOND}, + }; + } + + @Test(dataProvider = "fieldBased") + public void test_fieldSerializable(ChronoField field) throws IOException, ClassNotFoundException { + assertSerializableSame(field); + } + +} diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoUnitSerialization.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoUnitSerialization.java new file mode 100644 index 00000000000..15e34c6a1b0 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoUnitSerialization.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal.serial; + +import static java.time.temporal.ChronoUnit.CENTURIES; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.DECADES; +import static java.time.temporal.ChronoUnit.ERAS; +import static java.time.temporal.ChronoUnit.FOREVER; +import static java.time.temporal.ChronoUnit.HALF_DAYS; +import static java.time.temporal.ChronoUnit.HOURS; +import static java.time.temporal.ChronoUnit.MICROS; +import static java.time.temporal.ChronoUnit.MILLENNIA; +import static java.time.temporal.ChronoUnit.MILLIS; +import static java.time.temporal.ChronoUnit.MINUTES; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.NANOS; +import static java.time.temporal.ChronoUnit.SECONDS; +import static java.time.temporal.ChronoUnit.WEEKS; +import static java.time.temporal.ChronoUnit.YEARS; + +import java.io.IOException; +import java.time.temporal.ChronoUnit; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Test. + */ +@Test +public class TCKChronoUnitSerialization extends AbstractTCKTest { + + //----------------------------------------------------------------------- + // ChronoUnits + //----------------------------------------------------------------------- + @DataProvider(name="chronoUnit") + Object[][] data_chronoUnit() { + return new Object[][] { + {FOREVER}, + {ERAS}, + {MILLENNIA}, + {CENTURIES}, + {DECADES}, + {YEARS}, + {MONTHS}, + {WEEKS}, + {DAYS}, + + {HALF_DAYS}, + {HOURS}, + {MINUTES}, + {SECONDS}, + {MICROS}, + {MILLIS}, + {NANOS}, + + }; + } + + @Test(dataProvider = "chronoUnit") + public void test_unitType(ChronoUnit unit) throws IOException, ClassNotFoundException { + assertSerializableSame(unit); + } + +} diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKJulianFieldsSerialization.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKJulianFieldsSerialization.java new file mode 100644 index 00000000000..53047f8441a --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKJulianFieldsSerialization.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal.serial; + +import java.io.IOException; +import java.time.temporal.JulianFields; +import java.time.temporal.TemporalField; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Test serialization of JulianFields + */ +@Test +public class TCKJulianFieldsSerialization extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @DataProvider(name="julian_fields") + Object[][] julian_samples() { + return new Object[][] { + {JulianFields.JULIAN_DAY}, + {JulianFields.MODIFIED_JULIAN_DAY}, + {JulianFields.RATA_DIE}, + }; + } + + + //----------------------------------------------------------------------- + @Test(dataProvider="julian_fields") + public void test_serializable(TemporalField field) throws IOException, ClassNotFoundException { + assertSerializable(field); + } + +} diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKValueRangeSerialization.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKValueRangeSerialization.java new file mode 100644 index 00000000000..9114bec6ca0 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKValueRangeSerialization.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal.serial; + +import static org.testng.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.time.temporal.ValueRange; + +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Test serialization of ValueRange. + */ +@Test +public class TCKValueRangeSerialization extends AbstractTCKTest { + + //----------------------------------------------------------------------- + // Serialization + //----------------------------------------------------------------------- + public void test_serialization() throws Exception { + ValueRange range = ValueRange.of(1, 2, 3, 4); + assertSerializable(range); + } + + + /** + * Verify Serialized bytes of a ValueRange. + * @throws IOException if thrown during serialization is an unexpected test tailure + */ + public void test_valueRangeSerialized() throws IOException { + byte[] expected = { + (byte)172, (byte)237, 0, 5, 115, 114, 0, 29, 106, 97, /* \u00ac \u00ed \u0000 \u0005 s r \u0000 \u001d j a */ + 118, 97, 46, 116, 105, 109, 101, 46, 116, 101, /* v a . t i m e . t e */ + 109, 112, 111, 114, 97, 108, 46, 86, 97, 108, /* m p o r a l . V a l */ + 117, 101, 82, 97, 110, 103, 101, (byte)154, 113, (byte)169, /* u e R a n g e \u009a q \u00a9 */ + 86, (byte)242, (byte)205, 90, (byte)184, 2, 0, 4, 74, 0, /* V \u00f2 \u00cd Z \u00b8 \u0002 \u0000 \u0004 J \u0000 */ + 10, 109, 97, 120, 76, 97, 114, 103, 101, 115, /* m a x L a r g e s */ + 116, 74, 0, 11, 109, 97, 120, 83, 109, 97, /* t J \u0000 \u000b m a x S m a */ + 108, 108, 101, 115, 116, 74, 0, 10, 109, 105,/* l l e s t J \u0000 m i */ + 110, 76, 97, 114, 103, 101, 115, 116, 74, 0, /* n L a r g e s t J \u0000 */ + 11, 109, 105, 110, 83, 109, 97, 108, 108, 101, /* \u000b m i n S m a l l e */ + 115, 116, 120, 112, 0, 0, 0, 0, 0, 0, /* s t x p \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 */ + 0, 40, 0, 0, 0, 0, 0, 0, 0, 30, /* \u0000 ( \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u001e */ + 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, /* \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0014 \u0000 \u0000 */ + 0, 0, 0, 0, 0, 10, /* \u0000 \u0000 \u0000 \u0000 \u0000 */ + }; + + ValueRange range = ValueRange.of(10, 20, 30, 40); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos) ) { + oos.writeObject(range); + + byte[] actual = baos.toByteArray(); + assertEquals(actual, expected, "Serialized bytes incorrect"); + } + } + +} diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFieldsSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java rename to jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFieldsSerialization.java index 749515e7c9d..43f45a84f22 100644 --- a/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFieldsSerialization.java @@ -65,10 +65,10 @@ import java.time.DayOfWeek; import java.time.temporal.WeekFields; /** - * Test WeekFields. + * Test serialization of WeekFields. */ @Test -public class TCKWeekFields extends AbstractTCKTest { +public class TCKWeekFieldsSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- @Test(dataProvider="weekFields") diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java index 891deb76733..9cd42624bfa 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java @@ -127,7 +127,6 @@ public class TCKZoneOffsetTransition extends AbstractTCKTest { assertEquals(test.getOffsetBefore(), OFFSET_0200); assertEquals(test.getOffsetAfter(), OFFSET_0300); assertEquals(test.getDuration(), Duration.of(1, HOURS)); - assertSerializable(test); } @Test @@ -143,7 +142,6 @@ public class TCKZoneOffsetTransition extends AbstractTCKTest { assertEquals(test.getOffsetBefore(), OFFSET_0300); assertEquals(test.getOffsetAfter(), OFFSET_0200); assertEquals(test.getDuration(), Duration.of(-1, HOURS)); - assertSerializable(test); } diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java index 9ad26627edd..58e2ff56e7b 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java @@ -173,7 +173,6 @@ public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { assertEquals(test.getStandardOffset(), OFFSET_0200); assertEquals(test.getOffsetBefore(), OFFSET_0200); assertEquals(test.getOffsetAfter(), OFFSET_0300); - assertSerializable(test); } @Test @@ -190,7 +189,6 @@ public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { assertEquals(test.getStandardOffset(), OFFSET_0200); assertEquals(test.getOffsetBefore(), OFFSET_0200); assertEquals(test.getOffsetAfter(), OFFSET_0300); - assertSerializable(test); } @Test @@ -207,7 +205,6 @@ public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { assertEquals(test.getStandardOffset(), OFFSET_0200); assertEquals(test.getOffsetBefore(), OFFSET_0200); assertEquals(test.getOffsetAfter(), OFFSET_0300); - assertSerializable(test); } diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRulesSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java rename to jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRulesSerialization.java index b5d88d4f983..790e54fbb6d 100644 --- a/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRulesSerialization.java @@ -72,10 +72,10 @@ import java.time.zone.ZoneRules; import static org.testng.Assert.assertEquals; /** - * Test ZoneRules for fixed offset time-zones. + * Test serialization of ZoneRules for fixed offset time-zones. */ @Test -public class TCKFixedZoneRules { +public class TCKFixedZoneRulesSerialization { private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2); diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRuleSerialization.java similarity index 77% rename from jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java rename to jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRuleSerialization.java index 1ccae56c8d9..9e4bf9b455e 100644 --- a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRuleSerialization.java @@ -59,10 +59,7 @@ */ package tck.java.time.zone.serial; -import static org.testng.Assert.assertEquals; - import java.time.DayOfWeek; -import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Month; import java.time.ZoneOffset; @@ -73,17 +70,19 @@ import org.testng.annotations.Test; import tck.java.time.AbstractTCKTest; /** - * Test ZoneOffsetTransitionRule. + * Test ZoneOffsetTransitionRule serialization. */ @Test -public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { +public class TCKZoneOffsetTransitionRuleSerialization extends AbstractTCKTest { private static final LocalTime TIME_0100 = LocalTime.of(1, 0); private static final ZoneOffset OFFSET_0200 = ZoneOffset.ofHours(2); private static final ZoneOffset OFFSET_0300 = ZoneOffset.ofHours(3); - + //----------------------------------------------------------------------- + // Test serialization + //----------------------------------------------------------------------- @Test public void test_serialization_unusualOffsets() throws Exception { ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( @@ -110,5 +109,28 @@ public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { assertSerializable(test); } + @Test + public void test_serialization_floatingWeek() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL, + OFFSET_0200, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } + + @Test + public void test_serialization_floatingWeekBackwards() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, -1, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL, + OFFSET_0200, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } + + @Test + public void test_serialization_fixedDate() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.WALL, + OFFSET_0200, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } } diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionSerialization.java similarity index 78% rename from jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java rename to jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionSerialization.java index a57d31eaf71..e70fc747d88 100644 --- a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionSerialization.java @@ -59,6 +59,9 @@ */ package tck.java.time.zone.serial; +import static java.time.temporal.ChronoUnit.HOURS; + +import java.time.Duration; import org.testng.annotations.Test; import tck.java.time.AbstractTCKTest; @@ -68,10 +71,13 @@ import java.time.ZoneOffset; import java.time.zone.ZoneOffsetTransition; /** - * Test ZoneOffsetTransition. + * Test serialization of ZoneOffsetTransition. */ @Test -public class TCKZoneOffsetTransition extends AbstractTCKTest { +public class TCKZoneOffsetTransitionSerialization extends AbstractTCKTest { + + private static final ZoneOffset OFFSET_0200 = ZoneOffset.ofHours(2); + private static final ZoneOffset OFFSET_0300 = ZoneOffset.ofHours(3); //----------------------------------------------------------------------- @Test @@ -88,4 +94,20 @@ public class TCKZoneOffsetTransition extends AbstractTCKTest { assertSerializable(test); } + @Test + public void test_serialization_gap() throws Exception { + LocalDateTime before = LocalDateTime.of(2010, 3, 31, 1, 0); + LocalDateTime after = LocalDateTime.of(2010, 3, 31, 2, 0); + ZoneOffsetTransition test = ZoneOffsetTransition.of(before, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } + + @Test + public void test_serialization_overlap() throws Exception { + LocalDateTime before = LocalDateTime.of(2010, 10, 31, 1, 0); + LocalDateTime after = LocalDateTime.of(2010, 10, 31, 0, 0); + ZoneOffsetTransition test = ZoneOffsetTransition.of(before, OFFSET_0300, OFFSET_0200); + assertSerializable(test); + } + } diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRulesSerialization.java similarity index 98% rename from jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java rename to jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRulesSerialization.java index 6f83223f07c..80237967990 100644 --- a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRulesSerialization.java @@ -71,10 +71,10 @@ import java.time.zone.ZoneRules; import static org.testng.Assert.assertEquals; /** - * Test ZoneRules. + * Test serialization of ZoneRules. */ @Test -public class TCKZoneRules { +public class TCKZoneRulesSerialization { public void test_serialization_loaded() throws Exception { assertSerialization(europeLondon()); diff --git a/jdk/test/java/time/test/java/time/AbstractTest.java b/jdk/test/java/time/test/java/time/AbstractTest.java index 6d4d1340964..97f1cf4b486 100644 --- a/jdk/test/java/time/test/java/time/AbstractTest.java +++ b/jdk/test/java/time/test/java/time/AbstractTest.java @@ -63,11 +63,6 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -87,27 +82,6 @@ public abstract class AbstractTest { return true; } - protected static void assertSerializable(Object o) throws IOException, ClassNotFoundException { - Object deserialisedObject = writeThenRead(o); - assertEquals(deserialisedObject, o); - } - - protected static void assertSerializableAndSame(Object o) throws IOException, ClassNotFoundException { - Object deserialisedObject = writeThenRead(o); - assertSame(deserialisedObject, o); - } - - private static Object writeThenRead(Object o) throws IOException, ClassNotFoundException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (ObjectOutputStream oos = new ObjectOutputStream(baos) ) { - oos.writeObject(o); - } - - try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { - return ois.readObject(); - } - } - protected static void assertImmutable(Class cls) { assertTrue(Modifier.isPublic(cls.getModifiers())); assertTrue(Modifier.isFinal(cls.getModifiers())); diff --git a/jdk/test/java/time/test/java/time/TestDuration.java b/jdk/test/java/time/test/java/time/TestDuration.java index 23aedd84aa5..2b2043377f3 100644 --- a/jdk/test/java/time/test/java/time/TestDuration.java +++ b/jdk/test/java/time/test/java/time/TestDuration.java @@ -63,11 +63,6 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; import java.time.Duration; import org.testng.annotations.Test; @@ -84,29 +79,6 @@ public class TestDuration extends AbstractTest { assertImmutable(Duration.class); } - //----------------------------------------------------------------------- - @Test - public void test_interfaces() { - assertTrue(Serializable.class.isAssignableFrom(Duration.class)); - assertTrue(Comparable.class.isAssignableFrom(Duration.class)); - } - - //----------------------------------------------------------------------- - // serialization - //----------------------------------------------------------------------- - @Test - public void test_deserializationSingleton() throws Exception { - Duration orginal = Duration.ZERO; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - Duration ser = (Duration) in.readObject(); - assertSame(ser, Duration.ZERO); - } - @Test public void plus_zeroReturnsThis() { Duration t = Duration.ofSeconds(-1); diff --git a/jdk/test/java/time/test/java/time/temporal/TestDateTimeValueRange.java b/jdk/test/java/time/test/java/time/temporal/TestDateTimeValueRange.java index 67a40839257..4fa31f23b69 100644 --- a/jdk/test/java/time/test/java/time/temporal/TestDateTimeValueRange.java +++ b/jdk/test/java/time/test/java/time/temporal/TestDateTimeValueRange.java @@ -87,19 +87,6 @@ public class TestDateTimeValueRange extends AbstractTest { assertImmutable(ValueRange.class); } - //----------------------------------------------------------------------- - // Serialization - //----------------------------------------------------------------------- - public void test_serialization() throws Exception { - Object obj = ValueRange.of(1, 2, 3, 4); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(obj); - oos.close(); - ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); - assertEquals(ois.readObject(), obj); - } - //----------------------------------------------------------------------- // of(long,long) //----------------------------------------------------------------------- From f426e35d99b8c4f49f3b0b3068b480d5f8bb0517 Mon Sep 17 00:00:00 2001 From: Peter Allwin Date: Fri, 4 Oct 2013 15:00:42 +0200 Subject: [PATCH 0143/1294] 8025829: Add java/lang/instrument/RetransformBigClass.sh to problemlist Reviewed-by: sla, jbachorik --- jdk/test/ProblemList.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 984d431ef35..c8279529c28 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -134,6 +134,9 @@ java/lang/management/MemoryMXBean/LowMemoryTest2.sh generic-all # 8021230 java/lang/ThreadLocal/ThreadLocalSupplierTest.java generic-all +# 8023201 +java/lang/instrument/RetransformBigClass.sh generic-all +java/lang/instrument/RedefineBigClass.sh generic-all ############################################################################ From cbe29b7b72f02cdf21f51695d6cf87c51383bc60 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Fri, 4 Oct 2013 16:05:55 +0100 Subject: [PATCH 0144/1294] 8008296: keytool utility doesn't support '-importpassword' command Reviewed-by: weijun --- .../sun/security/tools/keytool/Main.java | 115 +++++++++-- .../sun/security/tools/keytool/Resources.java | 11 +- .../tools/keytool/StorePasswords.java | 186 ++++++++++++++++++ .../tools/keytool/StorePasswordsByShell.sh | 140 +++++++++++++ 4 files changed, 440 insertions(+), 12 deletions(-) create mode 100644 jdk/test/sun/security/tools/keytool/StorePasswords.java create mode 100644 jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Main.java b/jdk/src/share/classes/sun/security/tools/keytool/Main.java index 02ea1d0497f..c5e0fe7d627 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Main.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Main.java @@ -72,6 +72,8 @@ import sun.security.provider.certpath.CertStoreHelper; import sun.security.util.Password; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; import sun.security.pkcs.PKCS9Attribute; import sun.security.tools.KeyStoreUtil; @@ -190,6 +192,10 @@ public final class Main { KEYPASS, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V), + IMPORTPASS("Imports.a.password", + ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE, + STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS, + PROVIDERARG, PROVIDERPATH, V, PROTECTED), IMPORTKEYSTORE("Imports.one.or.all.entries.from.another.keystore", SRCKEYSTORE, DESTKEYSTORE, SRCSTORETYPE, DESTSTORETYPE, SRCSTOREPASS, DESTSTOREPASS, @@ -409,6 +415,8 @@ public final class Main { command = GENKEYPAIR; } else if (collator.compare(flags, "-import") == 0) { command = IMPORTCERT; + } else if (collator.compare(flags, "-importpassword") == 0) { + command = IMPORTPASS; } /* * Help @@ -727,6 +735,7 @@ public final class Main { command != GENSECKEY && command != IDENTITYDB && command != IMPORTCERT && + command != IMPORTPASS && command != IMPORTKEYSTORE && command != PRINTCRL) { throw new Exception(rb.getString @@ -808,6 +817,7 @@ public final class Main { command == GENKEYPAIR || command == GENSECKEY || command == IMPORTCERT || + command == IMPORTPASS || command == IMPORTKEYSTORE || command == KEYCLONE || command == CHANGEALIAS || @@ -958,6 +968,13 @@ public final class Main { } doGenSecretKey(alias, keyAlgName, keysize); kssave = true; + } else if (command == IMPORTPASS) { + if (keyAlgName == null) { + keyAlgName = "PBE"; + } + // password is stored as a secret key + doGenSecretKey(alias, keyAlgName, keysize); + kssave = true; } else if (command == IDENTITYDB) { if (filename != null) { try (InputStream inStream = new FileInputStream(filename)) { @@ -1419,6 +1436,43 @@ public final class Main { } return null; // PKCS11, MSCAPI, or -protected } + + /* + * Prompt the user for the password credential to be stored. + */ + private char[] promptForCredential() throws Exception { + // Handle password supplied via stdin + if (System.console() == null) { + char[] importPass = Password.readPassword(System.in); + passwords.add(importPass); + return importPass; + } + + int count; + for (count = 0; count < 3; count++) { + System.err.print( + rb.getString("Enter.the.password.to.be.stored.")); + System.err.flush(); + char[] entered = Password.readPassword(System.in); + passwords.add(entered); + System.err.print(rb.getString("Re.enter.password.")); + char[] passAgain = Password.readPassword(System.in); + passwords.add(passAgain); + if (!Arrays.equals(entered, passAgain)) { + System.err.println(rb.getString("They.don.t.match.Try.again")); + continue; + } + return entered; + } + + if (count == 3) { + throw new Exception(rb.getString + ("Too.many.failures.key.not.added.to.keystore")); + } + + return null; + } + /** * Creates a new secret key. */ @@ -1436,24 +1490,63 @@ public final class Main { throw new Exception(form.format(source)); } + // Use the keystore's default PBE algorithm for entry protection + boolean useDefaultPBEAlgorithm = true; SecretKey secKey = null; - KeyGenerator keygen = KeyGenerator.getInstance(keyAlgName); - if (keysize != -1) { - keygen.init(keysize); - } else if ("DES".equalsIgnoreCase(keyAlgName)) { - keygen.init(56); - } else if ("DESede".equalsIgnoreCase(keyAlgName)) { - keygen.init(168); + + if (keyAlgName.toUpperCase().startsWith("PBE")) { + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE"); + + // User is prompted for PBE credential + secKey = + factory.generateSecret(new PBEKeySpec(promptForCredential())); + + // Check whether a specific PBE algorithm was specified + if (!"PBE".equalsIgnoreCase(keyAlgName)) { + useDefaultPBEAlgorithm = false; + } + + if (verbose) { + MessageFormat form = new MessageFormat(rb.getString( + "Generated.keyAlgName.secret.key")); + Object[] source = + {useDefaultPBEAlgorithm ? "PBE" : secKey.getAlgorithm()}; + System.err.println(form.format(source)); + } } else { - throw new Exception(rb.getString - ("Please.provide.keysize.for.secret.key.generation")); + KeyGenerator keygen = KeyGenerator.getInstance(keyAlgName); + if (keysize == -1) { + if ("DES".equalsIgnoreCase(keyAlgName)) { + keysize = 56; + } else if ("DESede".equalsIgnoreCase(keyAlgName)) { + keysize = 168; + } else { + throw new Exception(rb.getString + ("Please.provide.keysize.for.secret.key.generation")); + } + } + keygen.init(keysize); + secKey = keygen.generateKey(); + + if (verbose) { + MessageFormat form = new MessageFormat(rb.getString + ("Generated.keysize.bit.keyAlgName.secret.key")); + Object[] source = {new Integer(keysize), + secKey.getAlgorithm()}; + System.err.println(form.format(source)); + } } - secKey = keygen.generateKey(); if (keyPass == null) { keyPass = promptForKeyPass(alias, null, storePass); } - keyStore.setKeyEntry(alias, secKey, keyPass, null); + + if (useDefaultPBEAlgorithm) { + keyStore.setKeyEntry(alias, secKey, keyPass, null); + } else { + keyStore.setEntry(alias, new KeyStore.SecretKeyEntry(secKey), + new KeyStore.PasswordProtection(keyPass, keyAlgName, null)); + } } /** diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources.java index 393aa3babe1..6199927ee44 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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,10 +65,16 @@ public class Resources extends java.util.ListResourceBundle { {"Generates.certificate.from.a.certificate.request", "Generates certificate from a certificate request"}, //-gencert {"Generates.CRL", "Generates CRL"}, //-gencrl + {"Generated.keyAlgName.secret.key", + "Generated {0} secret key"}, //-genseckey + {"Generated.keysize.bit.keyAlgName.secret.key", + "Generated {0}-bit {1} secret key"}, //-genseckey {"Imports.entries.from.a.JDK.1.1.x.style.identity.database", "Imports entries from a JDK 1.1.x-style identity database"}, //-identitydb {"Imports.a.certificate.or.a.certificate.chain", "Imports a certificate or a certificate chain"}, //-importcert + {"Imports.a.password", + "Imports a password"}, //-importpass {"Imports.one.or.all.entries.from.another.keystore", "Imports one or all entries from another keystore"}, //-importkeystore {"Clones.a.key.entry", @@ -220,6 +226,8 @@ public class Resources extends java.util.ListResourceBundle { {"Must.specify.alias", "Must specify alias"}, {"Keystore.password.must.be.at.least.6.characters", "Keystore password must be at least 6 characters"}, + {"Enter.the.password.to.be.stored.", + "Enter the password to be stored: "}, {"Enter.keystore.password.", "Enter keystore password: "}, {"Enter.source.keystore.password.", "Enter source keystore password: "}, {"Enter.destination.keystore.password.", "Enter destination keystore password: "}, @@ -328,6 +336,7 @@ public class Resources extends java.util.ListResourceBundle { {"New.prompt.", "New {0}: "}, {"Passwords.must.differ", "Passwords must differ"}, {"Re.enter.new.prompt.", "Re-enter new {0}: "}, + {"Re.enter.passpword.", "Re-enter password: "}, {"Re.enter.new.password.", "Re-enter new password: "}, {"They.don.t.match.Try.again", "They don't match. Try again"}, {"Enter.prompt.alias.name.", "Enter {0} alias name: "}, diff --git a/jdk/test/sun/security/tools/keytool/StorePasswords.java b/jdk/test/sun/security/tools/keytool/StorePasswords.java new file mode 100644 index 00000000000..e1f0c275b94 --- /dev/null +++ b/jdk/test/sun/security/tools/keytool/StorePasswords.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2013, 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 8008296 + * @summary Store and retrieve user passwords using PKCS#12 keystore + */ + +import java.io.*; +import java.security.*; +import java.util.*; +import javax.crypto.*; +import javax.crypto.spec.*; + +/* + * Store and retrieve passwords protected by a selection of PBE algorithms, + * using a PKCS#12 keystore. + */ +public class StorePasswords { + + private static final String[] PBE_ALGORITHMS = new String[] { + "default PBE algorithm", + "PBEWithMD5AndDES", + "PBEWithSHA1AndDESede", + "PBEWithSHA1AndRC2_40", + "PBEWithSHA1AndRC2_128", + "PBEWithSHA1AndRC4_40", + "PBEWithSHA1AndRC4_128", + "PBEWithHmacSHA1AndAES_128", + "PBEWithHmacSHA224AndAES_128", + "PBEWithHmacSHA256AndAES_128", + "PBEWithHmacSHA384AndAES_128", + "PBEWithHmacSHA512AndAES_128", + "PBEWithHmacSHA1AndAES_256", + "PBEWithHmacSHA224AndAES_256", + "PBEWithHmacSHA256AndAES_256", + "PBEWithHmacSHA384AndAES_256", + "PBEWithHmacSHA512AndAES_256" + }; + + private static final String KEYSTORE = "mykeystore.p12"; + private static final char[] KEYSTORE_PWD = "changeit".toCharArray(); + private static final char[] ENTRY_PWD = "protectit".toCharArray(); + private static final char[] USER_PWD = "hello1".toCharArray(); + + public static void main(String[] args) throws Exception { + + new File(KEYSTORE).delete(); + + int storeCount = store(); + int recoverCount = recover(); + + if (recoverCount != storeCount) { + throw new Exception("Stored " + storeCount + " user passwords, " + + "recovered " + recoverCount + " user passwords"); + } + System.out.println("\nStored " + storeCount + " user passwords, " + + "recovered " + recoverCount + " user passwords"); + } + + private static int store() throws Exception { + int count = 0; + // Load an empty PKCS#12 keystore + KeyStore keystore = KeyStore.getInstance("PKCS12"); + System.out.println("\nLoading PKCS#12 keystore..."); + keystore.load(null, null); + + // Derive a PBE key from the password + PBEKeySpec keySpec = new PBEKeySpec(USER_PWD); + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE"); + SecretKey key = factory.generateSecret(keySpec); + PBEParameterSpec specWithEightByteSalt = + new PBEParameterSpec("NaClNaCl".getBytes(), 1024); + + // Store the user password in a keystore entry (for each algorithm) + for (String algorithm : PBE_ALGORITHMS) { + + try { + System.out.println("Storing user password '" + + new String(USER_PWD) + "' (protected by " + algorithm + + ")"); + + if (algorithm.equals("default PBE algorithm")) { + keystore.setKeyEntry( + "this entry is protected by " + algorithm, key, + ENTRY_PWD, null); + } else { + keystore.setEntry( + "this entry is protected by " + algorithm, + new KeyStore.SecretKeyEntry(key), + new KeyStore.PasswordProtection(ENTRY_PWD, algorithm, + null)); + } + count++; + + } catch (KeyStoreException e) { + Throwable inner = e.getCause(); + if (inner instanceof UnrecoverableKeyException) { + Throwable inner2 = inner.getCause(); + if (inner2 instanceof InvalidAlgorithmParameterException) { + System.out.println("...re-trying due to: " + + inner2.getMessage()); + + // Some PBE algorithms demand an 8-byte salt + keystore.setEntry( + "this entry is protected by " + algorithm, + new KeyStore.SecretKeyEntry(key), + new KeyStore.PasswordProtection(ENTRY_PWD, + algorithm, specWithEightByteSalt)); + count++; + + } else if (inner2 instanceof InvalidKeyException) { + System.out.println("...skipping due to: " + + inner2.getMessage()); + // Unsupported crypto keysize + continue; + } + } else { + throw e; + } + } + } + + // Store the PKCS#12 keystore + System.out.println("Storing PKCS#12 keystore to: " + KEYSTORE); + keystore.store(new FileOutputStream(KEYSTORE), KEYSTORE_PWD); + + return count; + } + + private static int recover() throws Exception { + int count = 0; + // Load the PKCS#12 keystore + KeyStore keystore = KeyStore.getInstance("PKCS12"); + System.out.println("\nLoading PKCS#12 keystore from: " + KEYSTORE); + keystore.load(new FileInputStream(KEYSTORE), KEYSTORE_PWD); + + SecretKey key; + SecretKeyFactory factory; + PBEKeySpec keySpec; + + // Retrieve each user password from the keystore + for (String algorithm : PBE_ALGORITHMS) { + key = (SecretKey) keystore.getKey("this entry is protected by " + + algorithm, ENTRY_PWD); + + if (key != null) { + count++; + factory = SecretKeyFactory.getInstance(key.getAlgorithm()); + keySpec = + (PBEKeySpec) factory.getKeySpec(key, PBEKeySpec.class); + char[] pwd = keySpec.getPassword(); + System.out.println("Recovered user password '" + + new String(pwd) + "' (protected by " + algorithm + ")"); + + if (!Arrays.equals(USER_PWD, pwd)) { + throw new Exception("Failed to recover the user password " + + "protected by " + algorithm); + } + } + } + + return count; + } +} diff --git a/jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh b/jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh new file mode 100644 index 00000000000..7347f345878 --- /dev/null +++ b/jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh @@ -0,0 +1,140 @@ +# +# Copyright (c) 2013, 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 8008296 +# @summary confirm that keytool correctly imports user passwords +# +# @run shell StorePasswordsByShell.sh + +# set a few environment variables so that the shell-script can run stand-alone +# in the source directory +if [ "${TESTSRC}" = "" ] ; then + TESTSRC="." +fi + +if [ "${TESTCLASSES}" = "" ] ; then + TESTCLASSES="." +fi + +if [ "${TESTJAVA}" = "" ] ; then + echo "TESTJAVA not set. Test cannot execute." + echo "FAILED!!!" + exit 1 +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + SunOS ) + PATHSEP=":" + FILESEP="/" + ;; + Linux ) + PATHSEP=":" + FILESEP="/" + ;; + Darwin ) + PATHSEP=":" + FILESEP="/" + ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; + Windows* ) + PATHSEP=";" + FILESEP="\\" + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; +esac + +PBE_ALGORITHMS="\ + default-PBE-algorithm \ + PBEWithMD5AndDES \ + PBEWithSHA1AndDESede \ + PBEWithSHA1AndRC2_40 \ + PBEWithSHA1AndRC2_128 + PBEWithSHA1AndRC4_40 \ + PBEWithSHA1AndRC4_128 \ + PBEWithHmacSHA1AndAES_128 \ + PBEWithHmacSHA224AndAES_128 \ + PBEWithHmacSHA256AndAES_128 \ + PBEWithHmacSHA384AndAES_128 \ + PBEWithHmacSHA512AndAES_128 \ + PBEWithHmacSHA1AndAES_256 \ + PBEWithHmacSHA224AndAES_256 \ + PBEWithHmacSHA256AndAES_256 \ + PBEWithHmacSHA384AndAES_256 \ + PBEWithHmacSHA512AndAES_256" + +USER_PWD="hello1\n" +ALIAS_PREFIX="this entry is protected by " +COUNTER=0 + +# cleanup +rm mykeystore.p12 > /dev/null 2>&1 + +echo +for i in $PBE_ALGORITHMS; do + + if [ $i = "default-PBE-algorithm" ]; then + KEYALG="" + else + KEYALG="-keyalg ${i}" + fi + + if [ $COUNTER -lt 5 ]; then + IMPORTPASSWORD="-importpassword" + else + IMPORTPASSWORD="-importpass" + fi + + echo "Storing user password (protected by ${i})" + echo "${USER_PWD}" | \ + ${TESTJAVA}${FILESEP}bin${FILESEP}keytool ${IMPORTPASSWORD} \ + -storetype pkcs12 -keystore mykeystore.p12 -storepass changeit \ + -alias "${ALIAS_PREFIX}${i}" ${KEYALG} > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo Error + else + echo OK + COUNTER=`expr ${COUNTER} + 1` + fi +done +echo + +COUNTER2=`${TESTJAVA}${FILESEP}bin${FILESEP}keytool -list -storetype pkcs12 \ + -keystore mykeystore.p12 -storepass changeit | grep -c "${ALIAS_PREFIX}"` + +RESULT="stored ${COUNTER} user passwords, detected ${COUNTER2} user passwords" +if [ $COUNTER -ne $COUNTER2 -o $COUNTER -lt 11 ]; then + echo "ERROR: $RESULT" + exit 1 +else + echo "OK: $RESULT" + exit 0 +fi From c76298448522272938ff347e3210da58f90f74dd Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Thu, 29 Aug 2013 20:38:46 +0100 Subject: [PATCH 0145/1294] 8023764: Optimize Period addition Optimise plus/minus for common cases Reviewed-by: sherman --- jdk/src/share/classes/java/time/LocalDate.java | 10 ++++++++++ jdk/src/share/classes/java/time/LocalDateTime.java | 10 ++++++++++ jdk/src/share/classes/java/time/ZonedDateTime.java | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/jdk/src/share/classes/java/time/LocalDate.java b/jdk/src/share/classes/java/time/LocalDate.java index 3005658366a..e2043f9a90d 100644 --- a/jdk/src/share/classes/java/time/LocalDate.java +++ b/jdk/src/share/classes/java/time/LocalDate.java @@ -1125,6 +1125,11 @@ public final class LocalDate */ @Override public LocalDate plus(TemporalAmount amountToAdd) { + Objects.requireNonNull(amountToAdd, "amountToAdd"); + if (amountToAdd instanceof Period) { + Period periodToAdd = (Period) amountToAdd; + return plusMonths(periodToAdd.toTotalMonths()).plusDays(periodToAdd.getDays()); + } return (LocalDate) amountToAdd.addTo(this); } @@ -1353,6 +1358,11 @@ public final class LocalDate */ @Override public LocalDate minus(TemporalAmount amountToSubtract) { + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); + if (amountToSubtract instanceof Period) { + Period periodToSubtract = (Period) amountToSubtract; + return minusMonths(periodToSubtract.toTotalMonths()).minusDays(periodToSubtract.getDays()); + } return (LocalDate) amountToSubtract.subtractFrom(this); } diff --git a/jdk/src/share/classes/java/time/LocalDateTime.java b/jdk/src/share/classes/java/time/LocalDateTime.java index de8b246d6bb..d0b72b90f82 100644 --- a/jdk/src/share/classes/java/time/LocalDateTime.java +++ b/jdk/src/share/classes/java/time/LocalDateTime.java @@ -1129,6 +1129,11 @@ public final class LocalDateTime */ @Override public LocalDateTime plus(TemporalAmount amountToAdd) { + Objects.requireNonNull(amountToAdd, "amountToAdd"); + if (amountToAdd instanceof Period) { + Period periodToAdd = (Period) amountToAdd; + return with(date.plus(periodToAdd), time); + } return (LocalDateTime) amountToAdd.addTo(this); } @@ -1343,6 +1348,11 @@ public final class LocalDateTime */ @Override public LocalDateTime minus(TemporalAmount amountToSubtract) { + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); + if (amountToSubtract instanceof Period) { + Period periodToSubtract = (Period) amountToSubtract; + return with(date.minus(periodToSubtract), time); + } return (LocalDateTime) amountToSubtract.subtractFrom(this); } diff --git a/jdk/src/share/classes/java/time/ZonedDateTime.java b/jdk/src/share/classes/java/time/ZonedDateTime.java index 251ca888a14..971ba6daf5b 100644 --- a/jdk/src/share/classes/java/time/ZonedDateTime.java +++ b/jdk/src/share/classes/java/time/ZonedDateTime.java @@ -1540,6 +1540,11 @@ public final class ZonedDateTime */ @Override public ZonedDateTime plus(TemporalAmount amountToAdd) { + Objects.requireNonNull(amountToAdd, "amountToAdd"); + if (amountToAdd instanceof Period) { + Period periodToAdd = (Period) amountToAdd; + return resolveLocal(dateTime.plus(periodToAdd)); + } return (ZonedDateTime) amountToAdd.addTo(this); } @@ -1787,6 +1792,11 @@ public final class ZonedDateTime */ @Override public ZonedDateTime minus(TemporalAmount amountToSubtract) { + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); + if (amountToSubtract instanceof Period) { + Period periodToSubtract = (Period) amountToSubtract; + return resolveLocal(dateTime.minus(periodToSubtract)); + } return (ZonedDateTime) amountToSubtract.subtractFrom(this); } From fca9e37c80921feff5bb81d794b2622222728048 Mon Sep 17 00:00:00 2001 From: Lois Foltan Date: Thu, 29 Aug 2013 18:56:29 -0400 Subject: [PATCH 0146/1294] 8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced Declare all user-defined operator new()s within Hotspot code with the empty throw() exception specification Reviewed-by: coleenp, twisti, dholmes, hseigel, dcubed, kvn, ccheung --- hotspot/src/share/vm/adlc/arena.cpp | 6 +-- hotspot/src/share/vm/adlc/arena.hpp | 10 ++-- hotspot/src/share/vm/adlc/main.cpp | 4 +- hotspot/src/share/vm/asm/codeBuffer.hpp | 6 +-- hotspot/src/share/vm/c1/c1_Compilation.hpp | 6 +-- hotspot/src/share/vm/c1/c1_Instruction.hpp | 6 +-- hotspot/src/share/vm/code/codeBlob.cpp | 8 ++-- hotspot/src/share/vm/code/codeBlob.hpp | 8 ++-- hotspot/src/share/vm/code/debugInfoRec.cpp | 4 +- hotspot/src/share/vm/code/nmethod.cpp | 4 +- hotspot/src/share/vm/code/nmethod.hpp | 4 +- hotspot/src/share/vm/code/relocInfo.hpp | 4 +- hotspot/src/share/vm/code/vtableStubs.cpp | 4 +- hotspot/src/share/vm/code/vtableStubs.hpp | 4 +- .../vm/gc_implementation/shared/gcUtil.hpp | 6 +-- hotspot/src/share/vm/libadt/port.hpp | 6 +-- hotspot/src/share/vm/memory/allocation.cpp | 44 ++++++++--------- hotspot/src/share/vm/memory/allocation.hpp | 48 +++++++++---------- .../src/share/vm/memory/allocation.inline.hpp | 8 ++-- hotspot/src/share/vm/memory/memRegion.cpp | 6 +-- hotspot/src/share/vm/memory/memRegion.hpp | 12 ++--- hotspot/src/share/vm/oops/klass.cpp | 2 +- hotspot/src/share/vm/oops/klass.hpp | 2 +- hotspot/src/share/vm/oops/symbol.cpp | 6 +-- hotspot/src/share/vm/oops/symbol.hpp | 6 +-- hotspot/src/share/vm/opto/callGenerator.hpp | 4 +- hotspot/src/share/vm/opto/callnode.hpp | 4 +- hotspot/src/share/vm/opto/machnode.hpp | 4 +- hotspot/src/share/vm/opto/node.hpp | 4 +- hotspot/src/share/vm/opto/type.hpp | 4 +- hotspot/src/share/vm/runtime/fprofiler.cpp | 4 +- hotspot/src/share/vm/runtime/handles.cpp | 6 +-- hotspot/src/share/vm/runtime/handles.hpp | 4 +- .../src/share/vm/runtime/interfaceSupport.hpp | 4 +- .../src/share/vm/runtime/objectMonitor.hpp | 4 +- hotspot/src/share/vm/runtime/park.cpp | 4 +- hotspot/src/share/vm/runtime/park.hpp | 4 +- hotspot/src/share/vm/runtime/thread.hpp | 5 +- hotspot/src/share/vm/services/memRecorder.hpp | 4 +- .../src/share/vm/services/memTrackWorker.cpp | 6 +-- .../src/share/vm/services/memTrackWorker.hpp | 6 +-- hotspot/src/share/vm/utilities/array.hpp | 2 +- 42 files changed, 149 insertions(+), 148 deletions(-) diff --git a/hotspot/src/share/vm/adlc/arena.cpp b/hotspot/src/share/vm/adlc/arena.cpp index b8bb1a0bd8f..d7e4fc6eb44 100644 --- a/hotspot/src/share/vm/adlc/arena.cpp +++ b/hotspot/src/share/vm/adlc/arena.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include "adlc.hpp" -void* Chunk::operator new(size_t requested_size, size_t length) { +void* Chunk::operator new(size_t requested_size, size_t length) throw() { return CHeapObj::operator new(requested_size + length); } @@ -163,7 +163,7 @@ bool Arena::contains( const void *ptr ) const { //----------------------------------------------------------------------------- // CHeapObj -void* CHeapObj::operator new(size_t size){ +void* CHeapObj::operator new(size_t size) throw() { return (void *) malloc(size); } diff --git a/hotspot/src/share/vm/adlc/arena.hpp b/hotspot/src/share/vm/adlc/arena.hpp index a92857e1311..7f09511d6ca 100644 --- a/hotspot/src/share/vm/adlc/arena.hpp +++ b/hotspot/src/share/vm/adlc/arena.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ class CHeapObj { public: - void* operator new(size_t size); + void* operator new(size_t size) throw(); void operator delete(void* p); void* new_array(size_t size); }; @@ -53,7 +53,7 @@ class CHeapObj { class ValueObj { public: - void* operator new(size_t size); + void* operator new(size_t size) throw(); void operator delete(void* p); }; @@ -61,7 +61,7 @@ class ValueObj { class AllStatic { public: - void* operator new(size_t size); + void* operator new(size_t size) throw(); void operator delete(void* p); }; @@ -70,7 +70,7 @@ class AllStatic { // Linked list of raw memory chunks class Chunk: public CHeapObj { public: - void* operator new(size_t size, size_t length); + void* operator new(size_t size, size_t length) throw(); void operator delete(void* p, size_t length); Chunk(size_t length); diff --git a/hotspot/src/share/vm/adlc/main.cpp b/hotspot/src/share/vm/adlc/main.cpp index 4b812316381..b0035cbe7ef 100644 --- a/hotspot/src/share/vm/adlc/main.cpp +++ b/hotspot/src/share/vm/adlc/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -485,7 +485,7 @@ int get_legal_text(FileBuff &fbuf, char **legal_text) // VS2005 has its own definition, identical to this one. #if !defined(_WIN32) || defined(_WIN64) || _MSC_VER < 1400 -void *operator new( size_t size, int, const char *, int ) { +void *operator new( size_t size, int, const char *, int ) throw() { return ::operator new( size ); } #endif diff --git a/hotspot/src/share/vm/asm/codeBuffer.hpp b/hotspot/src/share/vm/asm/codeBuffer.hpp index 8ce94646d95..bcc5d51e7ad 100644 --- a/hotspot/src/share/vm/asm/codeBuffer.hpp +++ b/hotspot/src/share/vm/asm/codeBuffer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -296,8 +296,8 @@ class CodeBuffer: public StackObj { // CodeBuffers must be allocated on the stack except for a single // special case during expansion which is handled internally. This // is done to guarantee proper cleanup of resources. - void* operator new(size_t size) { return ResourceObj::operator new(size); } - void operator delete(void* p) { ShouldNotCallThis(); } + void* operator new(size_t size) throw() { return ResourceObj::operator new(size); } + void operator delete(void* p) { ShouldNotCallThis(); } public: typedef int csize_t; // code size type; would be size_t except for history diff --git a/hotspot/src/share/vm/c1/c1_Compilation.hpp b/hotspot/src/share/vm/c1/c1_Compilation.hpp index 897da9762cb..f98ae97f309 100644 --- a/hotspot/src/share/vm/c1/c1_Compilation.hpp +++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -279,8 +279,8 @@ class InstructionMark: public StackObj { // Base class for objects allocated by the compiler in the compilation arena class CompilationResourceObj ALLOCATION_SUPER_CLASS_SPEC { public: - void* operator new(size_t size) { return Compilation::current()->arena()->Amalloc(size); } - void* operator new(size_t size, Arena* arena) { + void* operator new(size_t size) throw() { return Compilation::current()->arena()->Amalloc(size); } + void* operator new(size_t size, Arena* arena) throw() { return arena->Amalloc(size); } void operator delete(void* p) {} // nothing to do diff --git a/hotspot/src/share/vm/c1/c1_Instruction.hpp b/hotspot/src/share/vm/c1/c1_Instruction.hpp index 6b1f6ddd380..9563b720a10 100644 --- a/hotspot/src/share/vm/c1/c1_Instruction.hpp +++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -323,7 +323,7 @@ class Instruction: public CompilationResourceObj { } public: - void* operator new(size_t size) { + void* operator new(size_t size) throw() { Compilation* c = Compilation::current(); void* res = c->arena()->Amalloc(size); ((Instruction*)res)->_id = c->get_next_id(); @@ -1611,7 +1611,7 @@ LEAF(BlockBegin, StateSplit) friend class SuxAndWeightAdjuster; public: - void* operator new(size_t size) { + void* operator new(size_t size) throw() { Compilation* c = Compilation::current(); void* res = c->arena()->Amalloc(size); ((BlockBegin*)res)->_id = c->get_next_id(); diff --git a/hotspot/src/share/vm/code/codeBlob.cpp b/hotspot/src/share/vm/code/codeBlob.cpp index a855ade0f5f..e377f893ee1 100644 --- a/hotspot/src/share/vm/code/codeBlob.cpp +++ b/hotspot/src/share/vm/code/codeBlob.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -245,7 +245,7 @@ BufferBlob* BufferBlob::create(const char* name, CodeBuffer* cb) { } -void* BufferBlob::operator new(size_t s, unsigned size) { +void* BufferBlob::operator new(size_t s, unsigned size) throw() { void* p = CodeCache::allocate(size); return p; } @@ -347,14 +347,14 @@ RuntimeStub* RuntimeStub::new_runtime_stub(const char* stub_name, } -void* RuntimeStub::operator new(size_t s, unsigned size) { +void* RuntimeStub::operator new(size_t s, unsigned size) throw() { void* p = CodeCache::allocate(size, true); if (!p) fatal("Initial size of CodeCache is too small"); return p; } // operator new shared by all singletons: -void* SingletonBlob::operator new(size_t s, unsigned size) { +void* SingletonBlob::operator new(size_t s, unsigned size) throw() { void* p = CodeCache::allocate(size, true); if (!p) fatal("Initial size of CodeCache is too small"); return p; diff --git a/hotspot/src/share/vm/code/codeBlob.hpp b/hotspot/src/share/vm/code/codeBlob.hpp index e59ae7f1f89..6587b2d2e51 100644 --- a/hotspot/src/share/vm/code/codeBlob.hpp +++ b/hotspot/src/share/vm/code/codeBlob.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -209,7 +209,7 @@ class BufferBlob: public CodeBlob { BufferBlob(const char* name, int size); BufferBlob(const char* name, int size, CodeBuffer* cb); - void* operator new(size_t s, unsigned size); + void* operator new(size_t s, unsigned size) throw(); public: // Creation @@ -283,7 +283,7 @@ class RuntimeStub: public CodeBlob { bool caller_must_gc_arguments ); - void* operator new(size_t s, unsigned size); + void* operator new(size_t s, unsigned size) throw(); public: // Creation @@ -321,7 +321,7 @@ class SingletonBlob: public CodeBlob { friend class VMStructs; protected: - void* operator new(size_t s, unsigned size); + void* operator new(size_t s, unsigned size) throw(); public: SingletonBlob( diff --git a/hotspot/src/share/vm/code/debugInfoRec.cpp b/hotspot/src/share/vm/code/debugInfoRec.cpp index eaa7188758d..fa0cb70fc94 100644 --- a/hotspot/src/share/vm/code/debugInfoRec.cpp +++ b/hotspot/src/share/vm/code/debugInfoRec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -38,7 +38,7 @@ class DIR_Chunk { int _length; // number of bytes in the stream int _hash; // hash of stream bytes (for quicker reuse) - void* operator new(size_t ignore, DebugInformationRecorder* dir) { + void* operator new(size_t ignore, DebugInformationRecorder* dir) throw() { assert(ignore == sizeof(DIR_Chunk), ""); if (dir->_next_chunk >= dir->_next_chunk_limit) { const int CHUNK = 100; diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp index 9412feff709..f41778352b7 100644 --- a/hotspot/src/share/vm/code/nmethod.cpp +++ b/hotspot/src/share/vm/code/nmethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -800,7 +800,7 @@ nmethod::nmethod( } #endif // def HAVE_DTRACE_H -void* nmethod::operator new(size_t size, int nmethod_size) throw () { +void* nmethod::operator new(size_t size, int nmethod_size) throw() { // Not critical, may return null if there is too little continuous memory return CodeCache::allocate(nmethod_size); } diff --git a/hotspot/src/share/vm/code/nmethod.hpp b/hotspot/src/share/vm/code/nmethod.hpp index 3178e90d98a..4929ea820c0 100644 --- a/hotspot/src/share/vm/code/nmethod.hpp +++ b/hotspot/src/share/vm/code/nmethod.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -265,7 +265,7 @@ class nmethod : public CodeBlob { int comp_level); // helper methods - void* operator new(size_t size, int nmethod_size); + void* operator new(size_t size, int nmethod_size) throw(); const char* reloc_string_for(u_char* begin, u_char* end); // Returns true if this thread changed the state of the nmethod or diff --git a/hotspot/src/share/vm/code/relocInfo.hpp b/hotspot/src/share/vm/code/relocInfo.hpp index 68a7f3a5889..b6adcf68302 100644 --- a/hotspot/src/share/vm/code/relocInfo.hpp +++ b/hotspot/src/share/vm/code/relocInfo.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -677,7 +677,7 @@ class Relocation VALUE_OBJ_CLASS_SPEC { } public: - void* operator new(size_t size, const RelocationHolder& holder) { + void* operator new(size_t size, const RelocationHolder& holder) throw() { if (size > sizeof(holder._relocbuf)) guarantee_size(); assert((void* const *)holder.reloc() == &holder._relocbuf[0], "ptrs must agree"); return holder.reloc(); diff --git a/hotspot/src/share/vm/code/vtableStubs.cpp b/hotspot/src/share/vm/code/vtableStubs.cpp index b0807145330..0d7b39a0241 100644 --- a/hotspot/src/share/vm/code/vtableStubs.cpp +++ b/hotspot/src/share/vm/code/vtableStubs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -49,7 +49,7 @@ VMReg VtableStub::_receiver_location = VMRegImpl::Bad(); static int num_vtable_chunks = 0; -void* VtableStub::operator new(size_t size, int code_size) { +void* VtableStub::operator new(size_t size, int code_size) throw() { assert(size == sizeof(VtableStub), "mismatched size"); num_vtable_chunks++; // compute real VtableStub size (rounded to nearest word) diff --git a/hotspot/src/share/vm/code/vtableStubs.hpp b/hotspot/src/share/vm/code/vtableStubs.hpp index d6e755a6ec8..aa95fee763c 100644 --- a/hotspot/src/share/vm/code/vtableStubs.hpp +++ b/hotspot/src/share/vm/code/vtableStubs.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ class VtableStub { bool _is_vtable_stub; // True if vtable stub, false, is itable stub /* code follows here */ // The vtableStub code - void* operator new(size_t size, int code_size); + void* operator new(size_t size, int code_size) throw(); VtableStub(bool is_vtable_stub, int index) : _next(NULL), _is_vtable_stub(is_vtable_stub), diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp index a01115d06ef..ad3075c9023 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, 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 @@ -144,9 +144,9 @@ class AdaptivePaddedAverage : public AdaptiveWeightedAverage { _padded_avg(0.0), _deviation(0.0), _padding(padding) {} // Placement support - void* operator new(size_t ignored, void* p) { return p; } + void* operator new(size_t ignored, void* p) throw() { return p; } // Allocator - void* operator new(size_t size) { return CHeapObj::operator new(size); } + void* operator new(size_t size) throw() { return CHeapObj::operator new(size); } // Accessor float padded_average() const { return _padded_avg; } diff --git a/hotspot/src/share/vm/libadt/port.hpp b/hotspot/src/share/vm/libadt/port.hpp index ad7e77c1a9a..5f712a40222 100644 --- a/hotspot/src/share/vm/libadt/port.hpp +++ b/hotspot/src/share/vm/libadt/port.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -163,8 +163,8 @@ extern void safe_free (const char *file, unsigned line, void *ptr); extern void *safe_calloc (const char *file, unsigned line, unsigned nitems, unsigned size); extern void *safe_realloc(const char *file, unsigned line, void *ptr, unsigned size); extern char *safe_strdup (const char *file, unsigned line, const char *src); -inline void *operator new( size_t size ) { return malloc(size); } -inline void operator delete( void *ptr ) { free(ptr); } +inline void *operator new( size_t size ) throw() { return malloc(size); } +inline void operator delete( void *ptr ) { free(ptr); } #endif //----------------------------------------------------------------------------- diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp index 6a80c47385e..36c0d06c3fd 100644 --- a/hotspot/src/share/vm/memory/allocation.cpp +++ b/hotspot/src/share/vm/memory/allocation.cpp @@ -49,19 +49,19 @@ # include "os_bsd.inline.hpp" #endif -void* StackObj::operator new(size_t size) { ShouldNotCallThis(); return 0; } -void StackObj::operator delete(void* p) { ShouldNotCallThis(); } -void* StackObj::operator new [](size_t size) { ShouldNotCallThis(); return 0; } -void StackObj::operator delete [](void* p) { ShouldNotCallThis(); } +void* StackObj::operator new(size_t size) throw() { ShouldNotCallThis(); return 0; } +void StackObj::operator delete(void* p) { ShouldNotCallThis(); } +void* StackObj::operator new [](size_t size) throw() { ShouldNotCallThis(); return 0; } +void StackObj::operator delete [](void* p) { ShouldNotCallThis(); } -void* _ValueObj::operator new(size_t size) { ShouldNotCallThis(); return 0; } -void _ValueObj::operator delete(void* p) { ShouldNotCallThis(); } -void* _ValueObj::operator new [](size_t size) { ShouldNotCallThis(); return 0; } -void _ValueObj::operator delete [](void* p) { ShouldNotCallThis(); } +void* _ValueObj::operator new(size_t size) throw() { ShouldNotCallThis(); return 0; } +void _ValueObj::operator delete(void* p) { ShouldNotCallThis(); } +void* _ValueObj::operator new [](size_t size) throw() { ShouldNotCallThis(); return 0; } +void _ValueObj::operator delete [](void* p) { ShouldNotCallThis(); } void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, bool read_only, - MetaspaceObj::Type type, TRAPS) { + MetaspaceObj::Type type, TRAPS) throw() { // Klass has it's own operator new return Metaspace::allocate(loader_data, word_size, read_only, type, CHECK_NULL); @@ -80,7 +80,7 @@ void MetaspaceObj::print_address_on(outputStream* st) const { st->print(" {"INTPTR_FORMAT"}", this); } -void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flags) { +void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flags) throw() { address res; switch (type) { case C_HEAP: @@ -97,12 +97,12 @@ void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flag return res; } -void* ResourceObj::operator new [](size_t size, allocation_type type, MEMFLAGS flags) { +void* ResourceObj::operator new [](size_t size, allocation_type type, MEMFLAGS flags) throw() { return (address) operator new(size, type, flags); } void* ResourceObj::operator new(size_t size, const std::nothrow_t& nothrow_constant, - allocation_type type, MEMFLAGS flags) { + allocation_type type, MEMFLAGS flags) throw() { //should only call this with std::nothrow, use other operator new() otherwise address res; switch (type) { @@ -121,7 +121,7 @@ void* ResourceObj::operator new(size_t size, const std::nothrow_t& nothrow_cons } void* ResourceObj::operator new [](size_t size, const std::nothrow_t& nothrow_constant, - allocation_type type, MEMFLAGS flags) { + allocation_type type, MEMFLAGS flags) throw() { return (address)operator new(size, nothrow_constant, type, flags); } @@ -370,7 +370,7 @@ class ChunkPoolCleaner : public PeriodicTask { //-------------------------------------------------------------------------------------- // Chunk implementation -void* Chunk::operator new (size_t requested_size, AllocFailType alloc_failmode, size_t length) { +void* Chunk::operator new (size_t requested_size, AllocFailType alloc_failmode, size_t length) throw() { // requested_size is equal to sizeof(Chunk) but in order for the arena // allocations to come out aligned as expected the size must be aligned // to expected arena alignment. @@ -478,18 +478,18 @@ Arena::~Arena() { NOT_PRODUCT(Atomic::dec(&_instance_count);) } -void* Arena::operator new(size_t size) { +void* Arena::operator new(size_t size) throw() { assert(false, "Use dynamic memory type binding"); return NULL; } -void* Arena::operator new (size_t size, const std::nothrow_t& nothrow_constant) { +void* Arena::operator new (size_t size, const std::nothrow_t& nothrow_constant) throw() { assert(false, "Use dynamic memory type binding"); return NULL; } // dynamic memory type binding -void* Arena::operator new(size_t size, MEMFLAGS flags) { +void* Arena::operator new(size_t size, MEMFLAGS flags) throw() { #ifdef ASSERT void* p = (void*)AllocateHeap(size, flags|otArena, CALLER_PC); if (PrintMallocFree) trace_heap_malloc(size, "Arena-new", p); @@ -499,7 +499,7 @@ void* Arena::operator new(size_t size, MEMFLAGS flags) { #endif } -void* Arena::operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags) { +void* Arena::operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags) throw() { #ifdef ASSERT void* p = os::malloc(size, flags|otArena, CALLER_PC); if (PrintMallocFree) trace_heap_malloc(size, "Arena-new", p); @@ -688,22 +688,22 @@ void* Arena::internal_malloc_4(size_t x) { // define ALLOW_OPERATOR_NEW_USAGE for platform on which global operator new allowed. // #ifndef ALLOW_OPERATOR_NEW_USAGE -void* operator new(size_t size){ +void* operator new(size_t size) throw() { assert(false, "Should not call global operator new"); return 0; } -void* operator new [](size_t size){ +void* operator new [](size_t size) throw() { assert(false, "Should not call global operator new[]"); return 0; } -void* operator new(size_t size, const std::nothrow_t& nothrow_constant){ +void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { assert(false, "Should not call global operator new"); return 0; } -void* operator new [](size_t size, std::nothrow_t& nothrow_constant){ +void* operator new [](size_t size, std::nothrow_t& nothrow_constant) throw() { assert(false, "Should not call global operator new[]"); return 0; } diff --git a/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp index d61bc7dcea5..739753311c5 100644 --- a/hotspot/src/share/vm/memory/allocation.hpp +++ b/hotspot/src/share/vm/memory/allocation.hpp @@ -204,12 +204,12 @@ const bool NMT_track_callsite = false; template class CHeapObj ALLOCATION_SUPER_CLASS_SPEC { public: - _NOINLINE_ void* operator new(size_t size, address caller_pc = 0); + _NOINLINE_ void* operator new(size_t size, address caller_pc = 0) throw(); _NOINLINE_ void* operator new (size_t size, const std::nothrow_t& nothrow_constant, - address caller_pc = 0); - _NOINLINE_ void* operator new [](size_t size, address caller_pc = 0); + address caller_pc = 0) throw(); + _NOINLINE_ void* operator new [](size_t size, address caller_pc = 0) throw(); _NOINLINE_ void* operator new [](size_t size, const std::nothrow_t& nothrow_constant, - address caller_pc = 0); + address caller_pc = 0) throw(); void operator delete(void* p); void operator delete [] (void* p); }; @@ -219,9 +219,9 @@ template class CHeapObj ALLOCATION_SUPER_CLASS_SPEC { class StackObj ALLOCATION_SUPER_CLASS_SPEC { private: - void* operator new(size_t size); + void* operator new(size_t size) throw(); void operator delete(void* p); - void* operator new [](size_t size); + void* operator new [](size_t size) throw(); void operator delete [](void* p); }; @@ -245,9 +245,9 @@ class StackObj ALLOCATION_SUPER_CLASS_SPEC { // class _ValueObj { private: - void* operator new(size_t size); + void* operator new(size_t size) throw(); void operator delete(void* p); - void* operator new [](size_t size); + void* operator new [](size_t size) throw(); void operator delete [](void* p); }; @@ -316,7 +316,7 @@ class MetaspaceObj { void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, bool read_only, - Type type, Thread* thread); + Type type, Thread* thread) throw(); // can't use TRAPS from this header file. void operator delete(void* p) { ShouldNotCallThis(); } }; @@ -339,7 +339,7 @@ class Chunk: CHeapObj { Chunk* _next; // Next Chunk in list const size_t _len; // Size of this Chunk public: - void* operator new(size_t size, AllocFailType alloc_failmode, size_t length); + void* operator new(size_t size, AllocFailType alloc_failmode, size_t length) throw(); void operator delete(void* p); Chunk(size_t length); @@ -422,12 +422,12 @@ protected: char* hwm() const { return _hwm; } // new operators - void* operator new (size_t size); - void* operator new (size_t size, const std::nothrow_t& nothrow_constant); + void* operator new (size_t size) throw(); + void* operator new (size_t size, const std::nothrow_t& nothrow_constant) throw(); // dynamic memory type tagging - void* operator new(size_t size, MEMFLAGS flags); - void* operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags); + void* operator new(size_t size, MEMFLAGS flags) throw(); + void* operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags) throw(); void operator delete(void* p); // Fast allocate in the arena. Common case is: pointer test + increment. @@ -583,44 +583,44 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC { #endif // ASSERT public: - void* operator new(size_t size, allocation_type type, MEMFLAGS flags); - void* operator new [](size_t size, allocation_type type, MEMFLAGS flags); + void* operator new(size_t size, allocation_type type, MEMFLAGS flags) throw(); + void* operator new [](size_t size, allocation_type type, MEMFLAGS flags) throw(); void* operator new(size_t size, const std::nothrow_t& nothrow_constant, - allocation_type type, MEMFLAGS flags); + allocation_type type, MEMFLAGS flags) throw(); void* operator new [](size_t size, const std::nothrow_t& nothrow_constant, - allocation_type type, MEMFLAGS flags); + allocation_type type, MEMFLAGS flags) throw(); - void* operator new(size_t size, Arena *arena) { + void* operator new(size_t size, Arena *arena) throw() { address res = (address)arena->Amalloc(size); DEBUG_ONLY(set_allocation_type(res, ARENA);) return res; } - void* operator new [](size_t size, Arena *arena) { + void* operator new [](size_t size, Arena *arena) throw() { address res = (address)arena->Amalloc(size); DEBUG_ONLY(set_allocation_type(res, ARENA);) return res; } - void* operator new(size_t size) { + void* operator new(size_t size) throw() { address res = (address)resource_allocate_bytes(size); DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);) return res; } - void* operator new(size_t size, const std::nothrow_t& nothrow_constant) { + void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { address res = (address)resource_allocate_bytes(size, AllocFailStrategy::RETURN_NULL); DEBUG_ONLY(if (res != NULL) set_allocation_type(res, RESOURCE_AREA);) return res; } - void* operator new [](size_t size) { + void* operator new [](size_t size) throw() { address res = (address)resource_allocate_bytes(size); DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);) return res; } - void* operator new [](size_t size, const std::nothrow_t& nothrow_constant) { + void* operator new [](size_t size, const std::nothrow_t& nothrow_constant) throw() { address res = (address)resource_allocate_bytes(size, AllocFailStrategy::RETURN_NULL); DEBUG_ONLY(if (res != NULL) set_allocation_type(res, RESOURCE_AREA);) return res; diff --git a/hotspot/src/share/vm/memory/allocation.inline.hpp b/hotspot/src/share/vm/memory/allocation.inline.hpp index f59ae5b4f0e..d8f1940a6d4 100644 --- a/hotspot/src/share/vm/memory/allocation.inline.hpp +++ b/hotspot/src/share/vm/memory/allocation.inline.hpp @@ -85,7 +85,7 @@ inline void FreeHeap(void* p, MEMFLAGS memflags = mtInternal) { template void* CHeapObj::operator new(size_t size, - address caller_pc){ + address caller_pc) throw() { void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC)); #ifdef ASSERT if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p); @@ -94,7 +94,7 @@ template void* CHeapObj::operator new(size_t size, } template void* CHeapObj::operator new (size_t size, - const std::nothrow_t& nothrow_constant, address caller_pc) { + const std::nothrow_t& nothrow_constant, address caller_pc) throw() { void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC), AllocFailStrategy::RETURN_NULL); #ifdef ASSERT @@ -104,12 +104,12 @@ template void* CHeapObj::operator new (size_t size, } template void* CHeapObj::operator new [](size_t size, - address caller_pc){ + address caller_pc) throw() { return CHeapObj::operator new(size, caller_pc); } template void* CHeapObj::operator new [](size_t size, - const std::nothrow_t& nothrow_constant, address caller_pc) { + const std::nothrow_t& nothrow_constant, address caller_pc) throw() { return CHeapObj::operator new(size, nothrow_constant, caller_pc); } diff --git a/hotspot/src/share/vm/memory/memRegion.cpp b/hotspot/src/share/vm/memory/memRegion.cpp index baabdb8781c..9eb2be56930 100644 --- a/hotspot/src/share/vm/memory/memRegion.cpp +++ b/hotspot/src/share/vm/memory/memRegion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -102,11 +102,11 @@ MemRegion MemRegion::minus(const MemRegion mr2) const { return MemRegion(); } -void* MemRegion::operator new(size_t size) { +void* MemRegion::operator new(size_t size) throw() { return (address)AllocateHeap(size, mtGC, 0, AllocFailStrategy::RETURN_NULL); } -void* MemRegion::operator new [](size_t size) { +void* MemRegion::operator new [](size_t size) throw() { return (address)AllocateHeap(size, mtGC, 0, AllocFailStrategy::RETURN_NULL); } void MemRegion::operator delete(void* p) { diff --git a/hotspot/src/share/vm/memory/memRegion.hpp b/hotspot/src/share/vm/memory/memRegion.hpp index 600d27533e8..9a72fac756e 100644 --- a/hotspot/src/share/vm/memory/memRegion.hpp +++ b/hotspot/src/share/vm/memory/memRegion.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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,8 +94,8 @@ public: size_t word_size() const { return _word_size; } bool is_empty() const { return word_size() == 0; } - void* operator new(size_t size); - void* operator new [](size_t size); + void* operator new(size_t size) throw(); + void* operator new [](size_t size) throw(); void operator delete(void* p); void operator delete [](void* p); }; @@ -111,13 +111,13 @@ public: class MemRegionClosureRO: public MemRegionClosure { public: - void* operator new(size_t size, ResourceObj::allocation_type type, MEMFLAGS flags) { + void* operator new(size_t size, ResourceObj::allocation_type type, MEMFLAGS flags) throw() { return ResourceObj::operator new(size, type, flags); } - void* operator new(size_t size, Arena *arena) { + void* operator new(size_t size, Arena *arena) throw() { return ResourceObj::operator new(size, arena); } - void* operator new(size_t size) { + void* operator new(size_t size) throw() { return ResourceObj::operator new(size); } diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index 41d5ec31c73..cf24783fbf8 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -139,7 +139,7 @@ Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature) const { return NULL; } -void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) { +void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw() { return Metaspace::allocate(loader_data, word_size, /*read_only*/false, MetaspaceObj::ClassType, CHECK_NULL); } diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp index 9e96dafe235..83bf44561b2 100644 --- a/hotspot/src/share/vm/oops/klass.hpp +++ b/hotspot/src/share/vm/oops/klass.hpp @@ -179,7 +179,7 @@ class Klass : public Metadata { // Constructor Klass(); - void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS); + void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw(); public: bool is_klass() const volatile { return true; } diff --git a/hotspot/src/share/vm/oops/symbol.cpp b/hotspot/src/share/vm/oops/symbol.cpp index f5fdfec9974..2a2c975b6ef 100644 --- a/hotspot/src/share/vm/oops/symbol.cpp +++ b/hotspot/src/share/vm/oops/symbol.cpp @@ -41,19 +41,19 @@ Symbol::Symbol(const u1* name, int length, int refcount) { } } -void* Symbol::operator new(size_t sz, int len, TRAPS) { +void* Symbol::operator new(size_t sz, int len, TRAPS) throw() { int alloc_size = size(len)*HeapWordSize; address res = (address) AllocateHeap(alloc_size, mtSymbol); return res; } -void* Symbol::operator new(size_t sz, int len, Arena* arena, TRAPS) { +void* Symbol::operator new(size_t sz, int len, Arena* arena, TRAPS) throw() { int alloc_size = size(len)*HeapWordSize; address res = (address)arena->Amalloc(alloc_size); return res; } -void* Symbol::operator new(size_t sz, int len, ClassLoaderData* loader_data, TRAPS) { +void* Symbol::operator new(size_t sz, int len, ClassLoaderData* loader_data, TRAPS) throw() { address res; int alloc_size = size(len)*HeapWordSize; res = (address) Metaspace::allocate(loader_data, size(len), true, diff --git a/hotspot/src/share/vm/oops/symbol.hpp b/hotspot/src/share/vm/oops/symbol.hpp index a71bdd454c3..f9db8d39974 100644 --- a/hotspot/src/share/vm/oops/symbol.hpp +++ b/hotspot/src/share/vm/oops/symbol.hpp @@ -136,9 +136,9 @@ class Symbol : private SymbolBase { } Symbol(const u1* name, int length, int refcount); - void* operator new(size_t size, int len, TRAPS); - void* operator new(size_t size, int len, Arena* arena, TRAPS); - void* operator new(size_t size, int len, ClassLoaderData* loader_data, TRAPS); + void* operator new(size_t size, int len, TRAPS) throw(); + void* operator new(size_t size, int len, Arena* arena, TRAPS) throw(); + void* operator new(size_t size, int len, ClassLoaderData* loader_data, TRAPS) throw(); void operator delete(void* p); diff --git a/hotspot/src/share/vm/opto/callGenerator.hpp b/hotspot/src/share/vm/opto/callGenerator.hpp index 8cdc4e827cd..0f6b2d16590 100644 --- a/hotspot/src/share/vm/opto/callGenerator.hpp +++ b/hotspot/src/share/vm/opto/callGenerator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -260,7 +260,7 @@ class WarmCallInfo : public ResourceObj { // Because WarmInfo objects live over the entire lifetime of the // Compile object, they are allocated into the comp_arena, which // does not get resource marked or reset during the compile process - void *operator new( size_t x, Compile* C ) { return C->comp_arena()->Amalloc(x); } + void *operator new( size_t x, Compile* C ) throw() { return C->comp_arena()->Amalloc(x); } void operator delete( void * ) { } // fast deallocation static WarmCallInfo* always_hot(); diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp index ebcca023315..fc6b3c0be7d 100644 --- a/hotspot/src/share/vm/opto/callnode.hpp +++ b/hotspot/src/share/vm/opto/callnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -216,7 +216,7 @@ public: // Because JVMState objects live over the entire lifetime of the // Compile object, they are allocated into the comp_arena, which // does not get resource marked or reset during the compile process - void *operator new( size_t x, Compile* C ) { return C->comp_arena()->Amalloc(x); } + void *operator new( size_t x, Compile* C ) throw() { return C->comp_arena()->Amalloc(x); } void operator delete( void * ) { } // fast deallocation // Create a new JVMState, ready for abstract interpretation. diff --git a/hotspot/src/share/vm/opto/machnode.hpp b/hotspot/src/share/vm/opto/machnode.hpp index 5b630e45c84..525135d949b 100644 --- a/hotspot/src/share/vm/opto/machnode.hpp +++ b/hotspot/src/share/vm/opto/machnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ class State; class MachOper : public ResourceObj { public: // Allocate right next to the MachNodes in the same arena - void *operator new( size_t x, Compile* C ) { return C->node_arena()->Amalloc_D(x); } + void *operator new( size_t x, Compile* C ) throw() { return C->node_arena()->Amalloc_D(x); } // Opcode virtual uint opcode() const = 0; diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index 0690d21b122..37edb1450c4 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -211,7 +211,7 @@ public: // New Operator that takes a Compile pointer, this will eventually // be the "new" New operator. - inline void* operator new( size_t x, Compile* C) { + inline void* operator new( size_t x, Compile* C) throw() { Node* n = (Node*)C->node_arena()->Amalloc_D(x); #ifdef ASSERT n->_in = (Node**)n; // magic cookie for assertion check diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp index 0626cb53f52..55d98bd5e51 100644 --- a/hotspot/src/share/vm/opto/type.hpp +++ b/hotspot/src/share/vm/opto/type.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -169,7 +169,7 @@ protected: public: - inline void* operator new( size_t x ) { + inline void* operator new( size_t x ) throw() { Compile* compile = Compile::current(); compile->set_type_last_size(x); void *temp = compile->type_arena()->Amalloc_D(x); diff --git a/hotspot/src/share/vm/runtime/fprofiler.cpp b/hotspot/src/share/vm/runtime/fprofiler.cpp index 111c4db5aa3..1928f536ae3 100644 --- a/hotspot/src/share/vm/runtime/fprofiler.cpp +++ b/hotspot/src/share/vm/runtime/fprofiler.cpp @@ -264,7 +264,7 @@ class ProfilerNode { public: - void* operator new(size_t size, ThreadProfiler* tp); + void* operator new(size_t size, ThreadProfiler* tp) throw(); void operator delete(void* p); ProfilerNode() { @@ -373,7 +373,7 @@ class ProfilerNode { } }; -void* ProfilerNode::operator new(size_t size, ThreadProfiler* tp){ +void* ProfilerNode::operator new(size_t size, ThreadProfiler* tp) throw() { void* result = (void*) tp->area_top; tp->area_top += size; diff --git a/hotspot/src/share/vm/runtime/handles.cpp b/hotspot/src/share/vm/runtime/handles.cpp index ebbdd9d7463..1b4e9faecf9 100644 --- a/hotspot/src/share/vm/runtime/handles.cpp +++ b/hotspot/src/share/vm/runtime/handles.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -179,11 +179,11 @@ HandleMark::~HandleMark() { _thread->set_last_handle_mark(previous_handle_mark()); } -void* HandleMark::operator new(size_t size) { +void* HandleMark::operator new(size_t size) throw() { return AllocateHeap(size, mtThread); } -void* HandleMark::operator new [] (size_t size) { +void* HandleMark::operator new [] (size_t size) throw() { return AllocateHeap(size, mtThread); } diff --git a/hotspot/src/share/vm/runtime/handles.hpp b/hotspot/src/share/vm/runtime/handles.hpp index 4a2a90c74c0..dc254227971 100644 --- a/hotspot/src/share/vm/runtime/handles.hpp +++ b/hotspot/src/share/vm/runtime/handles.hpp @@ -309,8 +309,8 @@ class HandleMark { // called in the destructor of HandleMarkCleaner void pop_and_restore(); // overloaded operators - void* operator new(size_t size); - void* operator new [](size_t size); + void* operator new(size_t size) throw(); + void* operator new [](size_t size) throw(); void operator delete(void* p); void operator delete[](void* p); }; diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.hpp b/hotspot/src/share/vm/runtime/interfaceSupport.hpp index 0c48e51818e..f995a4ee714 100644 --- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp +++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -56,7 +56,7 @@ class HandleMarkCleaner: public StackObj { } private: - inline void* operator new(size_t size, void* ptr) { + inline void* operator new(size_t size, void* ptr) throw() { return ptr; } }; diff --git a/hotspot/src/share/vm/runtime/objectMonitor.hpp b/hotspot/src/share/vm/runtime/objectMonitor.hpp index f0e6ed5f8d5..10b3609c0bb 100644 --- a/hotspot/src/share/vm/runtime/objectMonitor.hpp +++ b/hotspot/src/share/vm/runtime/objectMonitor.hpp @@ -312,10 +312,10 @@ public: public: static int Knob_Verbose; static int Knob_SpinLimit; - void* operator new (size_t size) { + void* operator new (size_t size) throw() { return AllocateHeap(size, mtInternal); } - void* operator new[] (size_t size) { + void* operator new[] (size_t size) throw() { return operator new (size); } void operator delete(void* p) { diff --git a/hotspot/src/share/vm/runtime/park.cpp b/hotspot/src/share/vm/runtime/park.cpp index 6fb0224ff44..6380570ef50 100644 --- a/hotspot/src/share/vm/runtime/park.cpp +++ b/hotspot/src/share/vm/runtime/park.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -140,7 +140,7 @@ void ParkEvent::Release (ParkEvent * ev) { // well as bank access imbalance on Niagara-like platforms, // although Niagara's hash function should help. -void * ParkEvent::operator new (size_t sz) { +void * ParkEvent::operator new (size_t sz) throw() { return (void *) ((intptr_t (AllocateHeap(sz + 256, mtInternal, CALLER_PC)) + 256) & -256) ; } diff --git a/hotspot/src/share/vm/runtime/park.hpp b/hotspot/src/share/vm/runtime/park.hpp index 4b72bb60962..504cb1a8524 100644 --- a/hotspot/src/share/vm/runtime/park.hpp +++ b/hotspot/src/share/vm/runtime/park.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -166,7 +166,7 @@ class ParkEvent : public os::PlatformEvent { // aligned on 256-byte address boundaries. This ensures that the least // significant byte of a ParkEvent address is always 0. - void * operator new (size_t sz) ; + void * operator new (size_t sz) throw(); void operator delete (void * a) ; public: diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp index 2c8c1875491..2afaf2a8f62 100644 --- a/hotspot/src/share/vm/runtime/thread.hpp +++ b/hotspot/src/share/vm/runtime/thread.hpp @@ -113,8 +113,9 @@ class Thread: public ThreadShadow { // Support for forcing alignment of thread objects for biased locking void* _real_malloc_address; public: - void* operator new(size_t size) { return allocate(size, true); } - void* operator new(size_t size, const std::nothrow_t& nothrow_constant) { return allocate(size, false); } + void* operator new(size_t size) throw() { return allocate(size, true); } + void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { + return allocate(size, false); } void operator delete(void* p); protected: diff --git a/hotspot/src/share/vm/services/memRecorder.hpp b/hotspot/src/share/vm/services/memRecorder.hpp index c52fad72eae..4329dad0267 100644 --- a/hotspot/src/share/vm/services/memRecorder.hpp +++ b/hotspot/src/share/vm/services/memRecorder.hpp @@ -53,13 +53,13 @@ template class FixedSizeMemPointerArray : } } - void* operator new(size_t size, const std::nothrow_t& nothrow_constant) { + void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { // the instance is part of memRecorder, needs to be tagged with 'otNMTRecorder' // to avoid recursion return os::malloc(size, (mtNMT | otNMTRecorder)); } - void* operator new(size_t size) { + void* operator new(size_t size) throw() { assert(false, "use nothrow version"); return NULL; } diff --git a/hotspot/src/share/vm/services/memTrackWorker.cpp b/hotspot/src/share/vm/services/memTrackWorker.cpp index 3e9bcd2f6c4..e1382dd1a3a 100644 --- a/hotspot/src/share/vm/services/memTrackWorker.cpp +++ b/hotspot/src/share/vm/services/memTrackWorker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,12 +63,12 @@ MemTrackWorker::~MemTrackWorker() { } } -void* MemTrackWorker::operator new(size_t size) { +void* MemTrackWorker::operator new(size_t size) throw() { assert(false, "use nothrow version"); return NULL; } -void* MemTrackWorker::operator new(size_t size, const std::nothrow_t& nothrow_constant) { +void* MemTrackWorker::operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { return allocate(size, false, mtNMT); } diff --git a/hotspot/src/share/vm/services/memTrackWorker.hpp b/hotspot/src/share/vm/services/memTrackWorker.hpp index 5d49ae1938e..ee45244e324 100644 --- a/hotspot/src/share/vm/services/memTrackWorker.hpp +++ b/hotspot/src/share/vm/services/memTrackWorker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,8 +90,8 @@ class MemTrackWorker : public NamedThread { public: MemTrackWorker(MemSnapshot* snapshot); ~MemTrackWorker(); - _NOINLINE_ void* operator new(size_t size); - _NOINLINE_ void* operator new(size_t size, const std::nothrow_t& nothrow_constant); + _NOINLINE_ void* operator new(size_t size) throw(); + _NOINLINE_ void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw(); void start(); void run(); diff --git a/hotspot/src/share/vm/utilities/array.hpp b/hotspot/src/share/vm/utilities/array.hpp index 048a5781269..fb32f5ca8fd 100644 --- a/hotspot/src/share/vm/utilities/array.hpp +++ b/hotspot/src/share/vm/utilities/array.hpp @@ -317,7 +317,7 @@ protected: Array(const Array&); void operator=(const Array&); - void* operator new(size_t size, ClassLoaderData* loader_data, int length, bool read_only, TRAPS) { + void* operator new(size_t size, ClassLoaderData* loader_data, int length, bool read_only, TRAPS) throw() { size_t word_size = Array::size(length); return (void*) Metaspace::allocate(loader_data, word_size, read_only, MetaspaceObj::array_type(sizeof(T)), CHECK_NULL); From d7bccbe430f48c15086f89ffad1f5e87369de03d Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 29 Aug 2013 19:19:23 -0700 Subject: [PATCH 0147/1294] 8023833: Replace direct use of AnnotatedType in javadoc code Reviewed-by: darcy --- .../classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java | 6 +++--- .../share/classes/com/sun/tools/javadoc/TypeMaker.java | 9 +++------ .../classes/com/sun/tools/javadoc/TypeVariableImpl.java | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java index a49dc8a3134..eb49e10f79a 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java @@ -40,7 +40,7 @@ import com.sun.tools.javac.util.List; public class AnnotatedTypeImpl extends AbstractTypeImpl implements AnnotatedType { - AnnotatedTypeImpl(DocEnv env, com.sun.tools.javac.code.Type.AnnotatedType type) { + AnnotatedTypeImpl(DocEnv env, com.sun.tools.javac.code.Type type) { super(env, type); } @@ -50,7 +50,7 @@ public class AnnotatedTypeImpl */ @Override public AnnotationDesc[] annotations() { - List tas = ((com.sun.tools.javac.code.Type.AnnotatedType)type).typeAnnotations; + List tas = type.getAnnotationMirrors(); if (tas == null || tas.isEmpty()) { return new AnnotationDesc[0]; @@ -65,7 +65,7 @@ public class AnnotatedTypeImpl @Override public com.sun.javadoc.Type underlyingType() { - return TypeMaker.getType(env, ((com.sun.tools.javac.code.Type.AnnotatedType)type).underlyingType, true, false); + return TypeMaker.getType(env, type.unannotatedType(), true, false); } @Override diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java index 721d33b7b4c..de4d54a651d 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java @@ -63,10 +63,8 @@ public class TypeMaker { t = env.types.erasure(t); } - if (considerAnnotations && - t.isAnnotated()) { - Type.AnnotatedType at = (Type.AnnotatedType) t; - return new AnnotatedTypeImpl(env, at); + if (considerAnnotations && t.isAnnotated()) { + return new AnnotatedTypeImpl(env, t); } switch (t.getTag()) { @@ -143,8 +141,7 @@ public class TypeMaker { static String getTypeString(DocEnv env, Type t, boolean full) { // TODO: should annotations be included here? if (t.isAnnotated()) { - Type.AnnotatedType at = (Type.AnnotatedType)t; - t = at.underlyingType; + t = t.unannotatedType(); } switch (t.getTag()) { case ARRAY: diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java index 3840c916ee4..48f97088ebc 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java @@ -140,7 +140,7 @@ public class TypeVariableImpl extends AbstractTypeImpl implements TypeVariable { if (!type.isAnnotated()) { return new AnnotationDesc[0]; } - List tas = ((com.sun.tools.javac.code.Type.AnnotatedType) type).typeAnnotations; + List tas = type.getAnnotationMirrors(); AnnotationDesc res[] = new AnnotationDesc[tas.length()]; int i = 0; for (Attribute.Compound a : tas) { From 6d7626dba47382ba6e5a0ff9c40430263de1c158 Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Fri, 30 Aug 2013 07:31:47 +0200 Subject: [PATCH 0148/1294] 8019902: G1: Use the average heap size rather than the minimum heap size to calculate the region size Reviewed-by: tonyp, tschatzl, sjohanss --- .../vm/gc_implementation/g1/g1CollectorPolicy.cpp | 10 +++++++++- .../share/vm/gc_implementation/g1/heapRegion.cpp | 13 +++---------- .../share/vm/gc_implementation/g1/heapRegion.hpp | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp index 75497e7c37f..178acd26afd 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -168,7 +168,15 @@ G1CollectorPolicy::G1CollectorPolicy() : // Set up the region size and associated fields. Given that the // policy is created before the heap, we have to set this up here, // so it's done as soon as possible. - HeapRegion::setup_heap_region_size(Arguments::min_heap_size()); + + // It would have been natural to pass initial_heap_byte_size() and + // max_heap_byte_size() to setup_heap_region_size() but those have + // not been set up at this point since they should be aligned with + // the region size. So, there is a circular dependency here. We base + // the region size on the heap size, but the heap size should be + // aligned with the region size. To get around this we use the + // unaligned values for the heap. + HeapRegion::setup_heap_region_size(InitialHeapSize, MaxHeapSize); HeapRegionRemSet::setup_remset_size(); G1ErgoVerbose::initialize(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp index 3a3c99a5edd..e66268885e3 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -149,18 +149,11 @@ void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr, // many regions in the heap (based on the min heap size). #define TARGET_REGION_NUMBER 2048 -void HeapRegion::setup_heap_region_size(uintx min_heap_size) { - // region_size in bytes +void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) { uintx region_size = G1HeapRegionSize; if (FLAG_IS_DEFAULT(G1HeapRegionSize)) { - // We base the automatic calculation on the min heap size. This - // can be problematic if the spread between min and max is quite - // wide, imagine -Xms128m -Xmx32g. But, if we decided it based on - // the max size, the region size might be way too large for the - // min size. Either way, some users might have to set the region - // size manually for some -Xms / -Xmx combos. - - region_size = MAX2(min_heap_size / TARGET_REGION_NUMBER, + size_t average_heap_size = (initial_heap_size + max_heap_size) / 2; + region_size = MAX2(average_heap_size / TARGET_REGION_NUMBER, (uintx) MIN_REGION_SIZE); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp index 68e58d680c9..097c0b54380 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp @@ -361,7 +361,7 @@ class HeapRegion: public G1OffsetTableContigSpace { // CardsPerRegion). All those fields are considered constant // throughout the JVM's execution, therefore they should only be set // up once during initialization time. - static void setup_heap_region_size(uintx min_heap_size); + static void setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size); enum ClaimValues { InitialClaimValue = 0, From 2e5604d06b24176d92459274539ce01818019712 Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Fri, 30 Aug 2013 11:11:53 +0400 Subject: [PATCH 0149/1294] 8023966: JViewPort.BLIT_SCROLL_MODE does not work in JLightweightFrame Reviewed-by: anthony, ant --- jdk/src/share/classes/javax/swing/JViewport.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/jdk/src/share/classes/javax/swing/JViewport.java b/jdk/src/share/classes/javax/swing/JViewport.java index c2ea60bf0ec..c271533e53e 100644 --- a/jdk/src/share/classes/javax/swing/JViewport.java +++ b/jdk/src/share/classes/javax/swing/JViewport.java @@ -25,6 +25,8 @@ package javax.swing; +import sun.swing.JLightweightFrame; + import java.awt.*; import java.awt.event.*; import java.awt.peer.ComponentPeer; @@ -361,6 +363,17 @@ public class JViewport extends JComponent implements Accessible super.remove(child); } + @Override + public void addNotify() { + super.addNotify(); + // JLightweightFrame does not support BLIT_SCROLL_MODE, so it should be replaced + Window rootWindow = SwingUtilities.getWindowAncestor(this); + if (rootWindow instanceof JLightweightFrame + && getScrollMode() == BLIT_SCROLL_MODE) { + setScrollMode(BACKINGSTORE_SCROLL_MODE); + } + } + /** * Scrolls the view so that Rectangle From 7ba96712a853754610960fd259b2393835e17e28 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 30 Aug 2013 00:29:52 -0700 Subject: [PATCH 0150/1294] 8024022: new hotspot build - hs25-b49 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index a16ed251dc6..15223e843df 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=48 +HS_BUILD_NUMBER=49 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From f8b0bf1b232b34fdff58eabcef86417a0a55f86b Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Fri, 30 Aug 2013 13:28:15 +0400 Subject: [PATCH 0151/1294] 8022401: [macosx] javax/swing/text/JTextComponent/5074573/bug5074573.java fails Reviewed-by: anthony --- jdk/src/macosx/native/sun/awt/AWTEvent.m | 2 +- .../event/KeyEvent/KeyChar/KeyCharTest.java | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/event/KeyEvent/KeyChar/KeyCharTest.java diff --git a/jdk/src/macosx/native/sun/awt/AWTEvent.m b/jdk/src/macosx/native/sun/awt/AWTEvent.m index b2d54f7e705..c6bda77d172 100644 --- a/jdk/src/macosx/native/sun/awt/AWTEvent.m +++ b/jdk/src/macosx/native/sun/awt/AWTEvent.m @@ -759,7 +759,7 @@ JNF_COCOA_EXIT(env); */ JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_event_NSEvent_nsToJavaChar -(JNIEnv *env, jclass cls, char nsChar, jint modifierFlags) +(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags) { jchar javaChar = 0; diff --git a/jdk/test/java/awt/event/KeyEvent/KeyChar/KeyCharTest.java b/jdk/test/java/awt/event/KeyEvent/KeyChar/KeyCharTest.java new file mode 100644 index 00000000000..a482cea61dd --- /dev/null +++ b/jdk/test/java/awt/event/KeyEvent/KeyChar/KeyCharTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTEvent; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.KeyEvent; +import java.util.Locale; +import sun.awt.SunToolkit; + +/* + * @test + * @bug 8022401 + * @summary Wrong key char + * @author Alexandr Scherbatiy + * @run main KeyCharTest + */ +public class KeyCharTest { + + private static volatile int eventsCount = 0; + + static { + Locale.setDefault(Locale.ENGLISH); + + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + + @Override + public void eventDispatched(AWTEvent event) { + eventsCount++; + char delete = ((KeyEvent) event).getKeyChar(); + if (delete != '\u007f') { + throw new RuntimeException("Key char is not delete: '" + delete + "'"); + } + } + }, AWTEvent.KEY_EVENT_MASK); + } + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + Frame frame = new Frame(); + frame.setSize(300, 300); + frame.setVisible(true); + toolkit.realSync(); + + Robot robot = new Robot(); + + robot.keyPress(KeyEvent.VK_DELETE); + robot.keyRelease(KeyEvent.VK_DELETE); + toolkit.realSync(); + + frame.dispose(); + + if (eventsCount != 3) { + throw new RuntimeException("Wrong number of key events: " + eventsCount); + } + } +} From 75fb106fec45102b509deef5eb5efdca67cdbb3f Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Fri, 30 Aug 2013 11:43:57 +0100 Subject: [PATCH 0152/1294] 8023763: Rename ChronoDateImpl Rename ChronoDateImpl to ChronoLocalDateImpl Reviewed-by: sherman --- .../classes/java/time/chrono/ChronoLocalDate.java | 12 ++++++------ ...hronoDateImpl.java => ChronoLocalDateImpl.java} | 14 +++++++------- .../java/time/chrono/ChronoLocalDateTimeImpl.java | 2 +- .../share/classes/java/time/chrono/HijrahDate.java | 2 +- .../classes/java/time/chrono/JapaneseDate.java | 5 +---- .../share/classes/java/time/chrono/MinguoDate.java | 2 +- .../classes/java/time/chrono/ThaiBuddhistDate.java | 2 +- 7 files changed, 18 insertions(+), 21 deletions(-) rename jdk/src/share/classes/java/time/chrono/{ChronoDateImpl.java => ChronoLocalDateImpl.java} (96%) diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java index 923e8960b0f..e02a8cd5392 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java @@ -428,7 +428,7 @@ public interface ChronoLocalDate */ @Override default ChronoLocalDate with(TemporalAdjuster adjuster) { - return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); + return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); } /** @@ -442,7 +442,7 @@ public interface ChronoLocalDate if (field instanceof ChronoField) { throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } - return ChronoDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue)); + return ChronoLocalDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue)); } /** @@ -452,7 +452,7 @@ public interface ChronoLocalDate */ @Override default ChronoLocalDate plus(TemporalAmount amount) { - return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); + return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); } /** @@ -465,7 +465,7 @@ public interface ChronoLocalDate if (unit instanceof ChronoUnit) { throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return ChronoDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd)); + return ChronoLocalDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd)); } /** @@ -475,7 +475,7 @@ public interface ChronoLocalDate */ @Override default ChronoLocalDate minus(TemporalAmount amount) { - return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); + return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); } /** @@ -486,7 +486,7 @@ public interface ChronoLocalDate */ @Override default ChronoLocalDate minus(long amountToSubtract, TemporalUnit unit) { - return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); + return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java similarity index 96% rename from jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java rename to jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java index 99ba58f05b9..fd8c8f88662 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java @@ -140,7 +140,7 @@ import java.util.Objects; * @param the ChronoLocalDate of this date-time * @since 1.8 */ -abstract class ChronoDateImpl +abstract class ChronoLocalDateImpl implements ChronoLocalDate, Temporal, TemporalAdjuster, Serializable { /** @@ -170,7 +170,7 @@ abstract class ChronoDateImpl /** * Creates an instance. */ - ChronoDateImpl() { + ChronoLocalDateImpl() { } @Override @@ -309,7 +309,7 @@ abstract class ChronoDateImpl */ @SuppressWarnings("unchecked") D minusYears(long yearsToSubtract) { - return (yearsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusYears(Long.MAX_VALUE)).plusYears(1) : plusYears(-yearsToSubtract)); + return (yearsToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl)plusYears(Long.MAX_VALUE)).plusYears(1) : plusYears(-yearsToSubtract)); } /** @@ -330,7 +330,7 @@ abstract class ChronoDateImpl */ @SuppressWarnings("unchecked") D minusMonths(long monthsToSubtract) { - return (monthsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusMonths(Long.MAX_VALUE)).plusMonths(1) : plusMonths(-monthsToSubtract)); + return (monthsToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl)plusMonths(Long.MAX_VALUE)).plusMonths(1) : plusMonths(-monthsToSubtract)); } /** @@ -350,7 +350,7 @@ abstract class ChronoDateImpl */ @SuppressWarnings("unchecked") D minusWeeks(long weeksToSubtract) { - return (weeksToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusWeeks(Long.MAX_VALUE)).plusWeeks(1) : plusWeeks(-weeksToSubtract)); + return (weeksToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl)plusWeeks(Long.MAX_VALUE)).plusWeeks(1) : plusWeeks(-weeksToSubtract)); } /** @@ -368,7 +368,7 @@ abstract class ChronoDateImpl */ @SuppressWarnings("unchecked") D minusDays(long daysToSubtract) { - return (daysToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusDays(Long.MAX_VALUE)).plusDays(1) : plusDays(-daysToSubtract)); + return (daysToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl)plusDays(Long.MAX_VALUE)).plusDays(1) : plusDays(-daysToSubtract)); } //----------------------------------------------------------------------- @@ -411,7 +411,7 @@ abstract class ChronoDateImpl private long monthsUntil(ChronoLocalDate end) { ValueRange range = getChronology().range(MONTH_OF_YEAR); if (range.getMaximum() != 12) { - throw new IllegalStateException("ChronoDateImpl only supports Chronologies with 12 months per year"); + throw new IllegalStateException("ChronoLocalDateImpl only supports Chronologies with 12 months per year"); } long packed1 = getLong(PROLEPTIC_MONTH) * 32L + get(DAY_OF_MONTH); // no overflow long packed2 = end.getLong(PROLEPTIC_MONTH) * 32L + end.get(DAY_OF_MONTH); // no overflow diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java index cd7f04e4798..13b3a0e8817 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java @@ -220,7 +220,7 @@ final class ChronoLocalDateTimeImpl return this; } // Validate that the new Temporal is a ChronoLocalDate (and not something else) - D cd = ChronoDateImpl.ensureValid(date.getChronology(), newDate); + D cd = ChronoLocalDateImpl.ensureValid(date.getChronology(), newDate); return new ChronoLocalDateTimeImpl<>(cd, newTime); } diff --git a/jdk/src/share/classes/java/time/chrono/HijrahDate.java b/jdk/src/share/classes/java/time/chrono/HijrahDate.java index 8e385c9470b..c0d942396cd 100644 --- a/jdk/src/share/classes/java/time/chrono/HijrahDate.java +++ b/jdk/src/share/classes/java/time/chrono/HijrahDate.java @@ -109,7 +109,7 @@ import java.time.temporal.ValueRange; * @since 1.8 */ public final class HijrahDate - extends ChronoDateImpl + extends ChronoLocalDateImpl implements ChronoLocalDate, Serializable { /** diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java index 24ad7a921c0..bc9f473486d 100644 --- a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java +++ b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java @@ -61,10 +61,8 @@ import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; import static java.time.temporal.ChronoField.DAY_OF_MONTH; -import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; -import static java.time.temporal.ChronoField.YEAR_OF_ERA; import java.io.DataInput; import java.io.DataOutput; @@ -76,7 +74,6 @@ import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalTime; import java.time.Period; -import java.time.Year; import java.time.ZoneId; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; @@ -119,7 +116,7 @@ import sun.util.calendar.LocalGregorianCalendar; * @since 1.8 */ public final class JapaneseDate - extends ChronoDateImpl + extends ChronoLocalDateImpl implements ChronoLocalDate, Serializable { /** diff --git a/jdk/src/share/classes/java/time/chrono/MinguoDate.java b/jdk/src/share/classes/java/time/chrono/MinguoDate.java index 16585e7e992..fd10e0e985e 100644 --- a/jdk/src/share/classes/java/time/chrono/MinguoDate.java +++ b/jdk/src/share/classes/java/time/chrono/MinguoDate.java @@ -96,7 +96,7 @@ import java.util.Objects; * @since 1.8 */ public final class MinguoDate - extends ChronoDateImpl + extends ChronoLocalDateImpl implements ChronoLocalDate, Serializable { /** diff --git a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java index 3d8f4078cc9..648793b7337 100644 --- a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java +++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java @@ -96,7 +96,7 @@ import java.util.Objects; * @since 1.8 */ public final class ThaiBuddhistDate - extends ChronoDateImpl + extends ChronoLocalDateImpl implements ChronoLocalDate, Serializable { /** From c4d7122a7f9878552a914b31bd0844b4e3754d35 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Fri, 30 Aug 2013 11:54:14 -0400 Subject: [PATCH 0153/1294] 6991327: using -Xprof trigger native memory leak Fixed a memory leak in FlatProfiler::record_thread_tick() method Reviewed-by: dholmes, ccheung --- hotspot/src/share/vm/runtime/fprofiler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hotspot/src/share/vm/runtime/fprofiler.cpp b/hotspot/src/share/vm/runtime/fprofiler.cpp index 111c4db5aa3..4fa60678fd2 100644 --- a/hotspot/src/share/vm/runtime/fprofiler.cpp +++ b/hotspot/src/share/vm/runtime/fprofiler.cpp @@ -925,6 +925,8 @@ void FlatProfiler::record_thread_ticks() { FlatProfiler::interval_print(); FlatProfiler::interval_reset(); } + + FREE_C_HEAP_ARRAY(JavaThread *, threadsList, mtInternal); } else { // Couldn't get the threads lock, just record that rather than blocking FlatProfiler::threads_lock_ticks += 1; From 9811410a0015461d29ec294c6542a69a62a72744 Mon Sep 17 00:00:00 2001 From: Jennifer Godinez Date: Fri, 30 Aug 2013 09:10:30 -0700 Subject: [PATCH 0154/1294] 8017469: [macosx] Printing problem using ja and zh_CN locales Reviewed-by: prr, jchen --- jdk/src/macosx/native/sun/awt/CTextPipe.m | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/jdk/src/macosx/native/sun/awt/CTextPipe.m b/jdk/src/macosx/native/sun/awt/CTextPipe.m index d9bf48afd92..f6510f204ae 100644 --- a/jdk/src/macosx/native/sun/awt/CTextPipe.m +++ b/jdk/src/macosx/native/sun/awt/CTextPipe.m @@ -145,11 +145,6 @@ void JavaCT_DrawGlyphVector BOOL saved = false; - /* Save and restore of graphics context is done before the iteration. - This seems to work using our test case (see bug ID 7158350) so we are restoring it at - the end of the for loop. If we find out that save/restore outside the loop - doesn't work on all cases then we will move the Save/Restore inside the loop.*/ - CGContextSaveGState(cgRef); CGAffineTransform invTx = CGAffineTransformInvert(strike->fTx); NSUInteger i; @@ -226,7 +221,9 @@ void JavaCT_DrawGlyphVector } // reset the font on the context after striking a unicode with CoreText - CGContextRestoreGState(cgRef); + if (saved) { + CGContextRestoreGState(cgRef); + } } // Using the Quartz Surface Data context, draw a hot-substituted character run From d5c4be9c658afddd0e33458cd4498fbcb65dcb98 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Fri, 30 Aug 2013 10:25:55 -0700 Subject: [PATCH 0155/1294] 4673406: RFE: Java Printing: Provide a way to display win32 printer driver's dialog Reviewed-by: jgodinez, bae --- .../sun/print/DocumentPropertiesUI.java | 62 ++++ .../classes/sun/print/PrinterJobWrapper.java | 60 ++++ .../classes/sun/print/RasterPrinterJob.java | 4 + .../classes/sun/print/ServiceDialog.java | 32 +- .../classes/sun/awt/windows/WPrinterJob.java | 315 +++++++++++++++++- .../classes/sun/print/Win32MediaTray.java | 4 + .../classes/sun/print/Win32PrintService.java | 93 +++++- .../native/sun/windows/awt_PrintControl.cpp | 6 + .../native/sun/windows/awt_PrintControl.h | 2 +- .../native/sun/windows/awt_PrintJob.cpp | 167 +++++++++- 10 files changed, 721 insertions(+), 24 deletions(-) create mode 100644 jdk/src/share/classes/sun/print/DocumentPropertiesUI.java create mode 100644 jdk/src/share/classes/sun/print/PrinterJobWrapper.java diff --git a/jdk/src/share/classes/sun/print/DocumentPropertiesUI.java b/jdk/src/share/classes/sun/print/DocumentPropertiesUI.java new file mode 100644 index 00000000000..9938e8b3951 --- /dev/null +++ b/jdk/src/share/classes/sun/print/DocumentPropertiesUI.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.print; + +import java.awt.Window; +import java.awt.print.PrinterJob; +import javax.print.PrintService; +import javax.print.ServiceUIFactory; +import javax.print.attribute.PrintRequestAttributeSet; + +public abstract class DocumentPropertiesUI { + + /** + * For Win32 doc properties sheet. + */ + public static final int + DOCUMENTPROPERTIES_ROLE = ServiceUIFactory.RESERVED_UIROLE +100; + + /** + * Name of (this) abstract class for Document Properties. + */ + public static final String + DOCPROPERTIESCLASSNAME = DocumentPropertiesUI.class.getName(); + + /** + * Invokes whatever code is needed to display a native dialog + * with the specified owner. The owner should be the cross-platform + * dialog. If the user cancels the dialog the return value is null. + * A non-null return value is always a new attribute set (or is it?) + * The cross-platform dialog may need to be updated to reflect the + * updated properties. + */ + public abstract PrintRequestAttributeSet + showDocumentProperties(PrinterJob job, + Window owner, + PrintService service, + PrintRequestAttributeSet aset); + +} diff --git a/jdk/src/share/classes/sun/print/PrinterJobWrapper.java b/jdk/src/share/classes/sun/print/PrinterJobWrapper.java new file mode 100644 index 00000000000..343da0baa77 --- /dev/null +++ b/jdk/src/share/classes/sun/print/PrinterJobWrapper.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.print; + +import java.awt.print.PrinterJob; +import javax.print.attribute.PrintRequestAttribute; + +public class PrinterJobWrapper implements PrintRequestAttribute { + + private static final long serialVersionUID = -8792124426995707237L; + + private PrinterJob job; + + public PrinterJobWrapper(PrinterJob job) { + this.job = job; + } + + public PrinterJob getPrinterJob() { + return job; + } + + public final Class getCategory() { + return PrinterJobWrapper.class; + } + + public final String getName() { + return "printerjob-wrapper"; + } + + public String toString() { + return "printerjob-wrapper: " + job.toString(); + } + + public int hashCode() { + return job.hashCode(); + } +} diff --git a/jdk/src/share/classes/sun/print/RasterPrinterJob.java b/jdk/src/share/classes/sun/print/RasterPrinterJob.java index 1752016288e..37865e3246c 100644 --- a/jdk/src/share/classes/sun/print/RasterPrinterJob.java +++ b/jdk/src/share/classes/sun/print/RasterPrinterJob.java @@ -903,6 +903,9 @@ public abstract class RasterPrinterJob extends PrinterJob { int x = bounds.x+bounds.width/3; int y = bounds.y+bounds.height/3; PrintService newService; + // temporarily add an attribute pointing back to this job. + PrinterJobWrapper jobWrapper = new PrinterJobWrapper(this); + attributes.add(jobWrapper); try { newService = ServiceUI.printDialog(gc, x, y, @@ -915,6 +918,7 @@ public abstract class RasterPrinterJob extends PrinterJob { DocFlavor.SERVICE_FORMATTED.PAGEABLE, attributes); } + attributes.remove(PrinterJobWrapper.class); if (newService == null) { return false; diff --git a/jdk/src/share/classes/sun/print/ServiceDialog.java b/jdk/src/share/classes/sun/print/ServiceDialog.java index 82703406aa9..bdfd5ba1242 100644 --- a/jdk/src/share/classes/sun/print/ServiceDialog.java +++ b/jdk/src/share/classes/sun/print/ServiceDialog.java @@ -46,6 +46,7 @@ import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; +import java.awt.print.PrinterJob; import java.io.File; import java.io.FilePermission; import java.io.IOException; @@ -119,8 +120,6 @@ public class ServiceDialog extends JDialog implements ActionListener { private AppearancePanel pnlAppearance; private boolean isAWT = false; - - static { initResource(); } @@ -801,9 +800,32 @@ public class ServiceDialog extends JDialog implements ActionListener { if (dialog != null) { dialog.show(); } else { - // REMIND: may want to notify the user why we're - // disabling the button - btnProperties.setEnabled(false); + DocumentPropertiesUI docPropertiesUI = null; + try { + docPropertiesUI = + (DocumentPropertiesUI)uiFactory.getUI + (DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE, + DocumentPropertiesUI.DOCPROPERTIESCLASSNAME); + } catch (Exception ex) { + } + if (docPropertiesUI != null) { + PrinterJobWrapper wrapper = (PrinterJobWrapper) + asCurrent.get(PrinterJobWrapper.class); + if (wrapper == null) { + return; // should not happen, defensive only. + } + PrinterJob job = wrapper.getPrinterJob(); + if (job == null) { + return; // should not happen, defensive only. + } + PrintRequestAttributeSet newAttrs = + docPropertiesUI.showDocumentProperties + (job, ServiceDialog.this, psCurrent, asCurrent); + if (newAttrs != null) { + asCurrent.addAll(newAttrs); + updatePanels(); + } + } } } } diff --git a/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java b/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java index 897e8f1baf1..519a0be422e 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java +++ b/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java @@ -179,6 +179,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { private static final int SET_RES_LOW = 0x00000080; private static final int SET_COLOR = 0x00000200; private static final int SET_ORIENTATION = 0x00004000; + private static final int SET_COLLATED = 0x00008000; /** * Values must match those defined in wingdi.h & commdlg.h @@ -189,10 +190,33 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { private static final int PD_NOSELECTION = 0x00000004; private static final int PD_COLLATE = 0x00000010; private static final int PD_PRINTTOFILE = 0x00000020; - private static final int DM_ORIENTATION = 0x00000001; - private static final int DM_PRINTQUALITY = 0x00000400; - private static final int DM_COLOR = 0x00000800; - private static final int DM_DUPLEX = 0x00001000; + private static final int DM_ORIENTATION = 0x00000001; + private static final int DM_PAPERSIZE = 0x00000002; + private static final int DM_COPIES = 0x00000100; + private static final int DM_DEFAULTSOURCE = 0x00000200; + private static final int DM_PRINTQUALITY = 0x00000400; + private static final int DM_COLOR = 0x00000800; + private static final int DM_DUPLEX = 0x00001000; + private static final int DM_YRESOLUTION = 0x00002000; + private static final int DM_COLLATE = 0x00008000; + + private static final short DMCOLLATE_FALSE = 0; + private static final short DMCOLLATE_TRUE = 1; + + private static final short DMORIENT_PORTRAIT = 1; + private static final short DMORIENT_LANDSCAPE = 2; + + private static final short DMCOLOR_MONOCHROME = 1; + private static final short DMCOLOR_COLOR = 2; + + private static final short DMRES_DRAFT = -1; + private static final short DMRES_LOW = -2; + private static final short DMRES_MEDIUM = -3; + private static final short DMRES_HIGH = -4; + + private static final short DMDUP_SIMPLEX = 1; + private static final short DMDUP_VERTICAL = 2; + private static final short DMDUP_HORIZONTAL = 3; /** * Pageable MAX pages @@ -592,13 +616,23 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { } driverDoesMultipleCopies = false; driverDoesCollation = false; - setNativePrintService(service.getName()); + setNativePrintServiceIfNeeded(service.getName()); } /* associates this job with the specified native service */ private native void setNativePrintService(String name) throws PrinterException; + private String lastNativeService = null; + private void setNativePrintServiceIfNeeded(String name) + throws PrinterException { + + if (name != null && !(name.equals(lastNativeService))) { + setNativePrintService(name); + lastNativeService = name; + } + } + public PrintService getPrintService() { if (myService == null) { String printerName = getNativePrintService(); @@ -616,7 +650,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { myService = PrintServiceLookup.lookupDefaultPrintService(); if (myService != null) { try { - setNativePrintService(myService.getName()); + setNativePrintServiceIfNeeded(myService.getName()); } catch (Exception e) { myService = null; } @@ -1754,8 +1788,13 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { mAttMediaSizeName = ((Win32PrintService)myService).findPaperID(msn); } - private void setWin32MediaAttrib(int dmIndex, int width, int length) { - MediaSizeName msn = + private void addPaperSize(PrintRequestAttributeSet aset, + int dmIndex, int width, int length) { + + if (aset == null) { + return; + } + MediaSizeName msn = ((Win32PrintService)myService).findWin32Media(dmIndex); if (msn == null) { msn = ((Win32PrintService)myService). @@ -1763,10 +1802,12 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { } if (msn != null) { - if (attributes != null) { - attributes.add(msn); - } + aset.add(msn); } + } + + private void setWin32MediaAttrib(int dmIndex, int width, int length) { + addPaperSize(attributes, dmIndex, width, length); mAttMediaSizeName = dmIndex; } @@ -1788,7 +1829,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { // no equivalent predefined value mAttMediaTray = 7; // DMBIN_AUTO } else if (attr == MediaTray.TOP) { - mAttMediaTray =1; // DMBIN_UPPER + mAttMediaTray = 1; // DMBIN_UPPER } else { if (attr instanceof Win32MediaTray) { mAttMediaTray = ((Win32MediaTray)attr).winID; @@ -1914,6 +1955,254 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { } } + private static final class DevModeValues { + int dmFields; + short copies; + short collate; + short color; + short duplex; + short orient; + short paper; + short bin; + short xres_quality; + short yres; + } + + private void getDevModeValues(PrintRequestAttributeSet aset, + DevModeValues info) { + + Copies c = (Copies)aset.get(Copies.class); + if (c != null) { + info.dmFields |= DM_COPIES; + info.copies = (short)c.getValue(); + } + + SheetCollate sc = (SheetCollate)aset.get(SheetCollate.class); + if (sc != null) { + info.dmFields |= DM_COLLATE; + info.collate = (sc == SheetCollate.COLLATED) ? + DMCOLLATE_TRUE : DMCOLLATE_FALSE; + } + + Chromaticity ch = (Chromaticity)aset.get(Chromaticity.class); + if (ch != null) { + info.dmFields |= DM_COLOR; + if (ch == Chromaticity.COLOR) { + info.color = DMCOLOR_COLOR; + } else { + info.color = DMCOLOR_MONOCHROME; + } + } + + Sides s = (Sides)aset.get(Sides.class); + if (s != null) { + info.dmFields |= DM_DUPLEX; + if (s == Sides.TWO_SIDED_LONG_EDGE) { + info.duplex = DMDUP_VERTICAL; + } else if (s == Sides.TWO_SIDED_SHORT_EDGE) { + info.duplex = DMDUP_HORIZONTAL; + } else { // Sides.ONE_SIDED + info.duplex = DMDUP_SIMPLEX; + } + } + + OrientationRequested or = + (OrientationRequested)aset.get(OrientationRequested.class); + if (or != null) { + info.dmFields |= DM_ORIENTATION; + info.orient = (or == OrientationRequested.LANDSCAPE) + ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT; + } + + Media m = (Media)aset.get(Media.class); + if (m instanceof MediaSizeName) { + info.dmFields |= DM_PAPERSIZE; + MediaSizeName msn = (MediaSizeName)m; + info.paper = + (short)((Win32PrintService)myService).findPaperID(msn); + } + + MediaTray mt = null; + if (m instanceof MediaTray) { + mt = (MediaTray)m; + } + if (mt == null) { + SunAlternateMedia sam = + (SunAlternateMedia)aset.get(SunAlternateMedia.class); + if (sam != null && (sam.getMedia() instanceof MediaTray)) { + mt = (MediaTray)sam.getMedia(); + } + } + + if (mt != null) { + info.dmFields |= DM_DEFAULTSOURCE; + info.bin = (short)(((Win32PrintService)myService).findTrayID(mt)); + } + + PrintQuality q = (PrintQuality)aset.get(PrintQuality.class); + if (q != null) { + info.dmFields |= DM_PRINTQUALITY; + if (q == PrintQuality.DRAFT) { + info.xres_quality = DMRES_DRAFT; + } else if (q == PrintQuality.HIGH) { + info.xres_quality = DMRES_HIGH; + } else { + info.xres_quality = DMRES_MEDIUM; + } + } + + PrinterResolution r = + (PrinterResolution)aset.get(PrinterResolution.class); + if (r != null) { + info.dmFields |= DM_PRINTQUALITY | DM_YRESOLUTION; + info.xres_quality = + (short)r.getCrossFeedResolution(PrinterResolution.DPI); + info.yres = (short)r.getFeedResolution(PrinterResolution.DPI); + } + } + + /* This method is called from native to update the values in the + * attribute set which originates from the cross-platform dialog, + * but updated by the native DocumentPropertiesUI which updates the + * devmode. This syncs the devmode back in to the attributes so that + * we can update the cross-platform dialog. + * The attribute set here is a temporary one installed whilst this + * happens, + */ + private final void setJobAttributes(PrintRequestAttributeSet attributes, + int fields, int values, + short copies, + short dmPaperSize, + short dmPaperWidth, + short dmPaperLength, + short dmDefaultSource, + short xRes, + short yRes) { + + if (attributes == null) { + return; + } + + if ((fields & DM_COPIES) != 0) { + attributes.add(new Copies(copies)); + } + + if ((fields & DM_COLLATE) != 0) { + if ((values & SET_COLLATED) != 0) { + attributes.add(SheetCollate.COLLATED); + } else { + attributes.add(SheetCollate.UNCOLLATED); + } + } + + if ((fields & DM_ORIENTATION) != 0) { + if ((values & SET_ORIENTATION) != 0) { + attributes.add(OrientationRequested.LANDSCAPE); + } else { + attributes.add(OrientationRequested.PORTRAIT); + } + } + + if ((fields & DM_COLOR) != 0) { + if ((values & SET_COLOR) != 0) { + attributes.add(Chromaticity.COLOR); + } else { + attributes.add(Chromaticity.MONOCHROME); + } + } + + if ((fields & DM_PRINTQUALITY) != 0) { + /* value < 0 indicates quality setting. + * value > 0 indicates X resolution. In that case + * hopefully we will also find y-resolution specified. + * If its not, assume its the same as x-res. + * Maybe Java code should try to reconcile this against + * the printers claimed set of supported resolutions. + */ + if (xRes < 0) { + PrintQuality quality; + if ((values & SET_RES_LOW) != 0) { + quality = PrintQuality.DRAFT; + } else if ((fields & SET_RES_HIGH) != 0) { + quality = PrintQuality.HIGH; + } else { + quality = PrintQuality.NORMAL; + } + attributes.add(quality); + } else if (xRes > 0 && yRes > 0) { + attributes.add( + new PrinterResolution(xRes, yRes, PrinterResolution.DPI)); + } + } + + if ((fields & DM_DUPLEX) != 0) { + Sides sides; + if ((values & SET_DUP_VERTICAL) != 0) { + sides = Sides.TWO_SIDED_LONG_EDGE; + } else if ((values & SET_DUP_HORIZONTAL) != 0) { + sides = Sides.TWO_SIDED_SHORT_EDGE; + } else { + sides = Sides.ONE_SIDED; + } + attributes.add(sides); + } + + if ((fields & DM_PAPERSIZE) != 0) { + addPaperSize(attributes, dmPaperSize, dmPaperWidth, dmPaperLength); + } + + if ((fields & DM_DEFAULTSOURCE) != 0) { + MediaTray tray = + ((Win32PrintService)myService).findMediaTray(dmDefaultSource); + attributes.add(new SunAlternateMedia(tray)); + } + } + + private native boolean showDocProperties(long hWnd, + PrintRequestAttributeSet aset, + int dmFields, + short copies, + short collate, + short color, + short duplex, + short orient, + short paper, + short bin, + short xres_quality, + short yres); + + @SuppressWarnings("deprecation") + public PrintRequestAttributeSet + showDocumentProperties(Window owner, + PrintService service, + PrintRequestAttributeSet aset) + { + try { + setNativePrintServiceIfNeeded(service.getName()); + } catch (PrinterException e) { + } + long hWnd = ((WWindowPeer)(owner.getPeer())).getHWnd(); + DevModeValues info = new DevModeValues(); + getDevModeValues(aset, info); + boolean ok = + showDocProperties(hWnd, aset, + info.dmFields, + info.copies, + info.collate, + info.color, + info.duplex, + info.orient, + info.paper, + info.bin, + info.xres_quality, + info.yres); + + if (ok) { + return aset; + } else { + return null; + } + } /* Printer Resolution. See also getXRes() and getYRes() */ private final void setResolutionDPI(int xres, int yres) { @@ -1956,7 +2245,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { } //** END Functions called by native code for querying/updating attributes - } + } class PrintToFileErrorDialog extends Dialog implements ActionListener{ public PrintToFileErrorDialog(Frame parent, String title, String message, diff --git a/jdk/src/windows/classes/sun/print/Win32MediaTray.java b/jdk/src/windows/classes/sun/print/Win32MediaTray.java index ecafcef5668..2f2cafce035 100644 --- a/jdk/src/windows/classes/sun/print/Win32MediaTray.java +++ b/jdk/src/windows/classes/sun/print/Win32MediaTray.java @@ -70,6 +70,10 @@ public class Win32MediaTray extends MediaTray { winEnumTable.add(this); } + public int getDMBinID() { + return winID; + } + private static final String[] myStringTable ={ "Manual-Envelope", "Automatic-Feeder", diff --git a/jdk/src/windows/classes/sun/print/Win32PrintService.java b/jdk/src/windows/classes/sun/print/Win32PrintService.java index c42de1ae7df..73e89269285 100644 --- a/jdk/src/windows/classes/sun/print/Win32PrintService.java +++ b/jdk/src/windows/classes/sun/print/Win32PrintService.java @@ -25,6 +25,8 @@ package sun.print; +import java.awt.Window; +import java.awt.print.PrinterJob; import java.io.File; import java.net.URI; import java.net.URISyntaxException; @@ -39,6 +41,7 @@ import javax.print.attribute.AttributeSet; import javax.print.attribute.AttributeSetUtilities; import javax.print.attribute.EnumSyntax; import javax.print.attribute.HashAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.PrintServiceAttribute; import javax.print.attribute.PrintServiceAttributeSet; import javax.print.attribute.HashPrintServiceAttributeSet; @@ -69,6 +72,7 @@ import javax.print.attribute.standard.PrintQuality; import javax.print.attribute.standard.PrinterResolution; import javax.print.attribute.standard.SheetCollate; import javax.print.event.PrintServiceAttributeListener; +import sun.awt.windows.WPrinterJob; public class Win32PrintService implements PrintService, AttributeUpdater, SunPrinterJobService { @@ -282,6 +286,22 @@ public class Win32PrintService implements PrintService, AttributeUpdater, return 0; } + public int findTrayID(MediaTray tray) { + + getMediaTrays(); // make sure they are initialised. + + if (tray instanceof Win32MediaTray) { + Win32MediaTray winTray = (Win32MediaTray)tray; + return winTray.getDMBinID(); + } + for (int id=0; id= 1 && dmBin <= dmPaperBinToPrintService.length) { return dmPaperBinToPrintService[dmBin-1]; @@ -673,7 +693,6 @@ public class Win32PrintService implements PrintService, AttributeUpdater, return arr2; } - private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() { if (getJobStatus(printer, 2) != 1) { return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS; @@ -1596,8 +1615,76 @@ public class Win32PrintService implements PrintService, AttributeUpdater, } } - public ServiceUIFactory getServiceUIFactory() { - return null; + private Win32DocumentPropertiesUI docPropertiesUI = null; + + private static class Win32DocumentPropertiesUI + extends DocumentPropertiesUI { + + Win32PrintService service; + + private Win32DocumentPropertiesUI(Win32PrintService s) { + service = s; + } + + public PrintRequestAttributeSet + showDocumentProperties(PrinterJob job, + Window owner, + PrintService service, + PrintRequestAttributeSet aset) { + + if (!(job instanceof WPrinterJob)) { + return null; + } + WPrinterJob wJob = (WPrinterJob)job; + return wJob.showDocumentProperties(owner, service, aset); + } + } + + private synchronized DocumentPropertiesUI getDocumentPropertiesUI() { + return new Win32DocumentPropertiesUI(this); + } + + private static class Win32ServiceUIFactory extends ServiceUIFactory { + + Win32PrintService service; + + Win32ServiceUIFactory(Win32PrintService s) { + service = s; + } + + public Object getUI(int role, String ui) { + if (role <= ServiceUIFactory.MAIN_UIROLE) { + return null; + } + if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE && + DocumentPropertiesUI.DOCPROPERTIESCLASSNAME.equals(ui)) + { + return service.getDocumentPropertiesUI(); + } + throw new IllegalArgumentException("Unsupported role"); + } + + public String[] getUIClassNamesForRole(int role) { + + if (role <= ServiceUIFactory.MAIN_UIROLE) { + return null; + } + if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE) { + String[] names = new String[0]; + names[0] = DocumentPropertiesUI.DOCPROPERTIESCLASSNAME; + return names; + } + throw new IllegalArgumentException("Unsupported role"); + } + } + + private Win32ServiceUIFactory uiFactory = null; + + public synchronized ServiceUIFactory getServiceUIFactory() { + if (uiFactory == null) { + uiFactory = new Win32ServiceUIFactory(this); + } + return uiFactory; } public String toString() { diff --git a/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp b/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp index 71a08d3df33..07dd90fcf2c 100644 --- a/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp +++ b/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp @@ -81,6 +81,7 @@ jmethodID AwtPrintControl::setToPageID; jmethodID AwtPrintControl::setNativeAttID; jmethodID AwtPrintControl::setRangeCopiesID; jmethodID AwtPrintControl::setResID; +jmethodID AwtPrintControl::setJobAttributesID; BOOL AwtPrintControl::IsSupportedLevel(HANDLE hPrinter, DWORD dwLevel) { @@ -297,6 +298,10 @@ void AwtPrintControl::initIDs(JNIEnv *env, jclass cls) AwtPrintControl::setPrinterID = env->GetMethodID(cls, "setPrinterNameAttrib", "(Ljava/lang/String;)V"); + AwtPrintControl::setJobAttributesID = + env->GetMethodID(cls, "setJobAttributes", + "(Ljavax/print/attribute/PrintRequestAttributeSet;IISSSSSSS)V"); + DASSERT(AwtPrintControl::driverDoesMultipleCopiesID != NULL); DASSERT(AwtPrintControl::getPrintDCID != NULL); DASSERT(AwtPrintControl::setPrintDCID != NULL); @@ -327,6 +332,7 @@ void AwtPrintControl::initIDs(JNIEnv *env, jclass cls) DASSERT(AwtPrintControl::getSidesID != NULL); DASSERT(AwtPrintControl::getSelectID != NULL); DASSERT(AwtPrintControl::getPrintToFileEnabledID != NULL); + DASSERT(AwtPrintControl::setJobAttributesID != NULL); CATCH_BAD_ALLOC; diff --git a/jdk/src/windows/native/sun/windows/awt_PrintControl.h b/jdk/src/windows/native/sun/windows/awt_PrintControl.h index 2e3fbaf2e60..e8b7415f305 100644 --- a/jdk/src/windows/native/sun/windows/awt_PrintControl.h +++ b/jdk/src/windows/native/sun/windows/awt_PrintControl.h @@ -47,7 +47,6 @@ public: static jmethodID setDevmodeID; static jmethodID getDevnamesID; static jmethodID setDevnamesID; - static jmethodID getWin32MediaID; static jmethodID setWin32MediaID; static jmethodID getWin32MediaTrayID; @@ -73,6 +72,7 @@ public: static jmethodID setNativeAttID; static jmethodID setRangeCopiesID; static jmethodID setResID; + static jmethodID setJobAttributesID; static void initIDs(JNIEnv *env, jclass cls); static BOOL FindPrinter(jstring printerName, LPBYTE pPrinterEnum, diff --git a/jdk/src/windows/native/sun/windows/awt_PrintJob.cpp b/jdk/src/windows/native/sun/windows/awt_PrintJob.cpp index a2deb14b58c..c19e4306114 100644 --- a/jdk/src/windows/native/sun/windows/awt_PrintJob.cpp +++ b/jdk/src/windows/native/sun/windows/awt_PrintJob.cpp @@ -329,6 +329,156 @@ static int CALLBACK fontEnumProcA(ENUMLOGFONTEXA *logfont, static int embolden(int currentWeight); static BOOL getPrintableArea(HDC pdc, HANDLE hDevMode, RectDouble *margin); + + +/************************************************************************ + * DocumentProperties native support + */ + +/* Values must match those defined in WPrinterJob.java */ +static const DWORD SET_COLOR = 0x00000200; +static const DWORD SET_ORIENTATION = 0x00004000; +static const DWORD SET_COLLATED = 0x00008000; +static const DWORD SET_DUP_VERTICAL = 0x00000010; +static const DWORD SET_DUP_HORIZONTAL = 0x00000020; +static const DWORD SET_RES_HIGH = 0x00000040; +static const DWORD SET_RES_LOW = 0x00000080; + +/* + * Copy DEVMODE state back into JobAttributes. + */ + +static void UpdateJobAttributes(JNIEnv *env, + jobject wJob, + jobject attrSet, + DEVMODE *devmode) { + + DWORD dmValues = 0; + int xRes = 0, yRes = 0; + + if (devmode->dmFields & DM_COLOR) { + if (devmode->dmColor == DMCOLOR_COLOR) { + dmValues |= SET_COLOR; + } + } + + if (devmode->dmFields & DM_ORIENTATION) { + if (devmode->dmOrientation == DMORIENT_LANDSCAPE) { + dmValues |= SET_ORIENTATION; + } + } + + if (devmode->dmFields & DM_COLLATE && + devmode->dmCollate == DMCOLLATE_TRUE) { + dmValues |= SET_COLLATED; + } + + if (devmode->dmFields & DM_PRINTQUALITY) { + /* value < 0 indicates quality setting. + * value > 0 indicates X resolution. In that case + * hopefully we will also find y-resolution specified. + * If its not, assume its the same as x-res. + * Maybe Java code should try to reconcile this against + * the printers claimed set of supported resolutions. + */ + if (devmode->dmPrintQuality < 0) { + if (devmode->dmPrintQuality == DMRES_HIGH) { + dmValues |= SET_RES_HIGH; + } else if ((devmode->dmPrintQuality == DMRES_LOW) || + (devmode->dmPrintQuality == DMRES_DRAFT)) { + dmValues |= SET_RES_LOW; + } + /* else if (devmode->dmPrintQuality == DMRES_MEDIUM) + * will set to NORMAL. + */ + } else { + xRes = devmode->dmPrintQuality; + yRes = (devmode->dmFields & DM_YRESOLUTION) ? + devmode->dmYResolution : devmode->dmPrintQuality; + } + } + + if (devmode->dmFields & DM_DUPLEX) { + if (devmode->dmDuplex == DMDUP_HORIZONTAL) { + dmValues |= SET_DUP_HORIZONTAL; + } else if (devmode->dmDuplex == DMDUP_VERTICAL) { + dmValues |= SET_DUP_VERTICAL; + } + } + + env->CallVoidMethod(wJob, AwtPrintControl::setJobAttributesID, attrSet, + devmode->dmFields, dmValues, devmode->dmCopies, + devmode->dmPaperSize, devmode->dmPaperWidth, + devmode->dmPaperLength, devmode->dmDefaultSource, + xRes, yRes); + +} + +JNIEXPORT jboolean JNICALL +Java_sun_awt_windows_WPrinterJob_showDocProperties(JNIEnv *env, + jobject wJob, + jlong hWndParent, + jobject attrSet, + jint dmFields, + jshort copies, + jshort collate, + jshort color, + jshort duplex, + jshort orient, + jshort paper, + jshort bin, + jshort xres_quality, + jshort yres) +{ + TRY; + + HGLOBAL hDevMode = AwtPrintControl::getPrintHDMode(env, wJob); + HGLOBAL hDevNames = AwtPrintControl::getPrintHDName(env, wJob); + DEVMODE *devmode = NULL; + DEVNAMES *devnames = NULL; + LONG rval = IDCANCEL; + jboolean ret = JNI_FALSE; + + if (hDevMode != NULL && hDevNames != NULL) { + devmode = (DEVMODE *)::GlobalLock(hDevMode); + devnames = (DEVNAMES *)::GlobalLock(hDevNames); + + LPTSTR lpdevnames = (LPTSTR)devnames; + // No need to call _tcsdup as we won't unlock until we are done. + LPTSTR printerName = lpdevnames+devnames->wDeviceOffset; + LPTSTR portName = lpdevnames+devnames->wOutputOffset; + + HANDLE hPrinter; + if (::OpenPrinter(printerName, &hPrinter, NULL) == TRUE) { + devmode->dmFields |= dmFields; + devmode->dmCopies = copies; + devmode->dmCollate = collate; + devmode->dmColor = color; + devmode->dmDuplex = duplex; + devmode->dmOrientation = orient; + devmode->dmPrintQuality = xres_quality; + devmode->dmYResolution = yres; + devmode->dmPaperSize = paper; + devmode->dmDefaultSource = bin; + + rval = ::DocumentProperties((HWND)hWndParent, + hPrinter, printerName, devmode, devmode, + DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); + if (rval == IDOK) { + UpdateJobAttributes(env, wJob, attrSet, devmode); + ret = JNI_TRUE; + } + VERIFY(::ClosePrinter(hPrinter)); + } + ::GlobalUnlock(hDevNames); + ::GlobalUnlock(hDevMode); + } + + return ret; + + CATCH_BAD_ALLOC_RET(0); +} + /************************************************************************ * WPageDialog native methods */ @@ -732,7 +882,6 @@ Java_sun_awt_windows_WPrinterJob_validatePaper(JNIEnv *env, jobject self, memset(&pd, 0, sizeof(PRINTDLG)); pd.lStructSize = sizeof(PRINTDLG); pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC; - if (::PrintDlg(&pd)) { printDC = pd.hDC; hDevMode = pd.hDevMode; @@ -792,8 +941,19 @@ Java_sun_awt_windows_WPrinterJob_validatePaper(JNIEnv *env, jobject self, jint imgPixelWid = GetDeviceCaps(printDC, HORZRES); jint imgPixelHgt = GetDeviceCaps(printDC, VERTRES); + // The DC may be obtained when we first selected the printer as a + // result of a call to setNativePrintService. + // If the Devmode was obtained later on from the DocumentProperties dialog + // the DC won't have been updated and its settings may be for PORTRAIT. + // This may happen in other cases too, but was observed for the above. + // To get a DC compatible with this devmode we should really call + // CreateDC() again to get a DC for the devmode we are using. + // The changes for that are a lot more risk, so to minimise that + // risk, assume its not LANDSCAPE unless width > height, even if the + // devmode says its LANDSCAPE. // if the values were obtained from a rotated device, swap. - if (getOrientationFromDevMode2(hDevMode) == DMORIENT_LANDSCAPE) { + if ((getOrientationFromDevMode2(hDevMode) == DMORIENT_LANDSCAPE) && + (imgPixelWid > imgPixelHgt)) { jint tmp; tmp = xPixelRes; xPixelRes = yPixelRes; @@ -941,6 +1101,9 @@ Java_sun_awt_windows_WPrinterJob_initPrinter(JNIEnv *env, jobject self) { setBooleanField(env, self, DRIVER_COLLATE_STR, JNI_FALSE); } + if (dmFields & DM_COPIES) { + setBooleanField(env, self, DRIVER_COPIES_STR, JNI_TRUE); + } } CATCH_BAD_ALLOC; From 4449fa0c56dadde1625c0211c0de0ea41e9332c7 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 30 Aug 2013 11:48:36 -0700 Subject: [PATCH 0156/1294] 8023700: Use non breaking space in various labels Reviewed-by: bpatel --- .../html/AnnotationTypeWriterImpl.java | 4 +- .../doclets/formats/html/ClassWriterImpl.java | 4 +- .../formats/html/markup/HtmlWriter.java | 41 ++++++++++++++----- .../testNavigation/TestNavigation.java | 18 ++++---- .../javadoc/testProfiles/TestProfiles.java | 24 +++++------ 5 files changed, 56 insertions(+), 35 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java index 869bc75f89c..c1c4c9d40e6 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java @@ -118,7 +118,7 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter if (prev != null) { Content prevLink = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS, prev.asClassDoc()) - .label(configuration.getText("doclet.Prev_Class")).strong(true)); + .label(prevclassLabel).strong(true)); li = HtmlTree.LI(prevLink); } else @@ -136,7 +136,7 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter if (next != null) { Content nextLink = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS, next.asClassDoc()) - .label(configuration.getText("doclet.Next_Class")).strong(true)); + .label(nextclassLabel).strong(true)); li = HtmlTree.LI(nextLink); } else diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java index 25f0f618af9..7899445dd4a 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java @@ -126,7 +126,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter if (prev != null) { Content prevLink = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS, prev) - .label(configuration.getText("doclet.Prev_Class")).strong(true)); + .label(prevclassLabel).strong(true)); li = HtmlTree.LI(prevLink); } else @@ -144,7 +144,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter if (next != null) { Content nextLink = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS, next) - .label(configuration.getText("doclet.Next_Class")).strong(true)); + .label(nextclassLabel).strong(true)); li = HtmlTree.LI(nextLink); } else diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java index 5369733893b..36becd2e7ef 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java @@ -203,27 +203,27 @@ public class HtmlWriter { useLabel = getResource("doclet.navClassUse"); prevLabel = getResource("doclet.Prev"); nextLabel = getResource("doclet.Next"); - prevclassLabel = getResource("doclet.Prev_Class"); - nextclassLabel = getResource("doclet.Next_Class"); + prevclassLabel = getNonBreakResource("doclet.Prev_Class"); + nextclassLabel = getNonBreakResource("doclet.Next_Class"); summaryLabel = getResource("doclet.Summary"); detailLabel = getResource("doclet.Detail"); framesLabel = getResource("doclet.Frames"); - noframesLabel = getResource("doclet.No_Frames"); + noframesLabel = getNonBreakResource("doclet.No_Frames"); treeLabel = getResource("doclet.Tree"); classLabel = getResource("doclet.Class"); deprecatedLabel = getResource("doclet.navDeprecated"); deprecatedPhrase = getResource("doclet.Deprecated"); - allclassesLabel = getResource("doclet.All_Classes"); - allpackagesLabel = getResource("doclet.All_Packages"); - allprofilesLabel = getResource("doclet.All_Profiles"); + allclassesLabel = getNonBreakResource("doclet.All_Classes"); + allpackagesLabel = getNonBreakResource("doclet.All_Packages"); + allprofilesLabel = getNonBreakResource("doclet.All_Profiles"); indexLabel = getResource("doclet.Index"); helpLabel = getResource("doclet.Help"); seeLabel = getResource("doclet.See"); descriptionLabel = getResource("doclet.Description"); - prevpackageLabel = getResource("doclet.Prev_Package"); - nextpackageLabel = getResource("doclet.Next_Package"); - prevprofileLabel = getResource("doclet.Prev_Profile"); - nextprofileLabel = getResource("doclet.Next_Profile"); + prevpackageLabel = getNonBreakResource("doclet.Prev_Package"); + nextpackageLabel = getNonBreakResource("doclet.Next_Package"); + prevprofileLabel = getNonBreakResource("doclet.Prev_Profile"); + nextprofileLabel = getNonBreakResource("doclet.Next_Profile"); packagesLabel = getResource("doclet.Packages"); profilesLabel = getResource("doclet.Profiles"); methodDetailsLabel = getResource("doclet.Method_Detail"); @@ -256,6 +256,27 @@ public class HtmlWriter { return configuration.getResource(key); } + /** + * Get the configuration string as a content, replacing spaces + * with non-breaking spaces. + * + * @param key the key to look for in the configuration file + * @return a content tree for the text + */ + public Content getNonBreakResource(String key) { + String text = configuration.getText(key); + Content c = configuration.newContent(); + int start = 0; + int p; + while ((p = text.indexOf(" ", start)) != -1) { + c.addContent(text.substring(start, p)); + c.addContent(RawHtml.nbsp); + start = p + 1; + } + c.addContent(text.substring(start)); + return c; + } + /** * Get the configuration string as a content. * diff --git a/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java index 9fefe1b7869..d533d98c289 100644 --- a/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java +++ b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4131628 4664607 7025314 + * @bug 4131628 4664607 7025314 8023700 * @summary Make sure the Next/Prev Class links iterate through all types. * Make sure the navagation is 2 columns, not 3. * @author jamieh @@ -45,20 +45,20 @@ public class TestNavigation extends JavadocTester { //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "A.html", "

  • Prev Class
  • "}, + {BUG_ID + FS + "pkg" + FS + "A.html", "
  • Prev Class
  • "}, {BUG_ID + FS + "pkg" + FS + "A.html", - "
    Next Class"}, + "Next Class"}, {BUG_ID + FS + "pkg" + FS + "C.html", - "Prev Class"}, + "Prev Class"}, {BUG_ID + FS + "pkg" + FS + "C.html", - "Next Class"}, + "Next Class"}, {BUG_ID + FS + "pkg" + FS + "E.html", - "Prev Class"}, + "Prev Class"}, {BUG_ID + FS + "pkg" + FS + "E.html", - "Next Class"}, + "Next Class"}, {BUG_ID + FS + "pkg" + FS + "I.html", - "Prev Class"}, - {BUG_ID + FS + "pkg" + FS + "I.html", "
  • Next Class
  • "}, + "Prev Class"}, + {BUG_ID + FS + "pkg" + FS + "I.html", "
  • Next Class
  • "}, // Test for 4664607 {BUG_ID + FS + "pkg" + FS + "I.html", "" + NL + diff --git a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java index 7d878d7ecd3..5f84abfe7ba 100644 --- a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java +++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8006124 8009684 8016921 + * @bug 8006124 8009684 8016921 8023700 * @summary Test javadoc support for profiles. * @author Bhavesh Patel * @library ../lib/ @@ -49,7 +49,7 @@ public class TestProfiles extends JavadocTester { // Tests for profile-overview-frame.html listing all profiles. {PROFILE_BUG_ID + FS + "profile-overview-frame.html", "All Packages" + + "target=\"packageListFrame\">All Packages" }, {PROFILE_BUG_ID + FS + "profile-overview-frame.html", "
  • " @@ -58,8 +58,8 @@ public class TestProfiles extends JavadocTester { // Tests for profileName-frame.html listing all packages in a profile. {PROFILE_BUG_ID + FS + "compact2-frame.html", "" - + "All PackagesAll Profiles" + + "All PackagesAll Profiles" }, {PROFILE_BUG_ID + FS + "compact2-frame.html", "
  • Prev Profile
  • " + NL - + "
  • Next Profile
  • " + "
  • Prev Profile
  • " + NL + + "
  • Next Profile
  • " }, {PROFILE_BUG_ID + FS + "compact2-summary.html", "

    Profile compact2

    " @@ -87,7 +87,7 @@ public class TestProfiles extends JavadocTester { // Tests for profileName-package-summary.html listing the summary for a // package in a profile. {PROFILE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html", - "
  • Prev Package" + "
  • Prev Package" + "
  • " }, {PROFILE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html", @@ -96,7 +96,7 @@ public class TestProfiles extends JavadocTester { //Test for "overview-frame.html" showing the "All Profiles" link. {PROFILE_BUG_ID + FS + "overview-frame.html", "All Profiles" + + "target=\"packageListFrame\">All Profiles" }, //Test for "className.html" showing the profile information for the type. {PROFILE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html", @@ -143,12 +143,12 @@ public class TestProfiles extends JavadocTester { private static final String[][] PACKAGES_NEGATED_TEST = { {PACKAGE_BUG_ID + FS + "profile-overview-frame.html", "All Packages" + + "target=\"packageListFrame\">All Packages" }, {PACKAGE_BUG_ID + FS + "compact2-frame.html", "" - + "All PackagesAll Profiles" + + "All PackagesAll Profiles" }, {PACKAGE_BUG_ID + FS + "pkg2" + FS + "compact2-package-frame.html", "" @@ -163,7 +163,7 @@ public class TestProfiles extends JavadocTester { }, {PACKAGE_BUG_ID + FS + "overview-frame.html", "All Profiles" + + "target=\"packageListFrame\">All Profiles" }, {PACKAGE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html", "
    compact1, compact2, compact3
    " From 0f6bcbe0b5e627c1634b7a49d20e0173ea500b3d Mon Sep 17 00:00:00 2001 From: Lois Foltan Date: Fri, 30 Aug 2013 15:07:23 -0400 Subject: [PATCH 0157/1294] 8024050: Incorrect optimization level and comment specified for unsafe.cpp Fix comments and optimization level. Reviewed-by: rdurbin, coleenp, hseigel --- hotspot/make/bsd/makefiles/gcc.make | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make index 1cdff227a5a..b98485f901d 100644 --- a/hotspot/make/bsd/makefiles/gcc.make +++ b/hotspot/make/bsd/makefiles/gcc.make @@ -129,13 +129,17 @@ ifeq ($(USE_CLANG), true) # We only use precompiled headers for the JVM build CFLAGS += $(VM_PCH_FLAG) - - # There are some files which don't like precompiled headers - # The following files are build with 'OPT_CFLAGS/NOOPT' (-O0) in the opt build. - # But Clang doesn't support a precompiled header which was compiled with -O3 - # to be used in a compilation unit which uses '-O0'. We could also prepare an - # extra '-O0' PCH file for the opt build and use it here, but it's probably - # not worth the effort as long as only two files need this special handling. + + # The following files are compiled at various optimization + # levels due to optimization issues encountered at the + # 'OPT_CFLAGS_DEFAULT' level. The Clang compiler issues a compile + # time error if there is an optimization level specification + # skew between the PCH file and the C++ file. Especially if the + # PCH file is compiled at a higher optimization level than + # the C++ file. One solution might be to prepare extra optimization + # level specific PCH files for the opt build and use them here, but + # it's probably not worth the effort as long as only a few files + # need this special handling. PCH_FLAG/loopTransform.o = $(PCH_FLAG/NO_PCH) PCH_FLAG/sharedRuntimeTrig.o = $(PCH_FLAG/NO_PCH) PCH_FLAG/sharedRuntimeTrans.o = $(PCH_FLAG/NO_PCH) @@ -307,7 +311,7 @@ OPT_CFLAGS/NOOPT=-O0 ifeq ($(USE_CLANG), true) ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 2), 1) OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT) - OPT_CFLAGS/unsafe.o += -01 + OPT_CFLAGS/unsafe.o += -O1 endif else # 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation. From fdf2c975ed4bfd9ff7ec1d2cc87f7f043d02721e Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Fri, 30 Aug 2013 15:15:56 -0400 Subject: [PATCH 0158/1294] 8023872: Verification error in generated lambda classes Skip verification for generated lambda classes Reviewed-by: kamg, dholmes --- hotspot/src/share/vm/classfile/verifier.cpp | 10 +++++++--- hotspot/src/share/vm/runtime/globals.hpp | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index 68e634f3a15..7134e7cdb26 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -188,6 +188,10 @@ bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool shoul bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) { Symbol* name = klass->name(); Klass* refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass(); + Klass* lambda_magic_klass = SystemDictionary::lambda_MagicLambdaImpl_klass(); + + bool is_reflect = refl_magic_klass != NULL && klass->is_subtype_of(refl_magic_klass); + bool is_lambda = lambda_magic_klass != NULL && klass->is_subtype_of(lambda_magic_klass); return (should_verify_for(klass->class_loader(), should_verify_class) && // return if the class is a bootstrapping class @@ -210,9 +214,9 @@ bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool shou // sun/reflect/SerializationConstructorAccessor. // NOTE: this is called too early in the bootstrapping process to be // guarded by Universe::is_gte_jdk14x_version()/UseNewReflection. - (refl_magic_klass == NULL || - !klass->is_subtype_of(refl_magic_klass) || - VerifyReflectionBytecodes) + // Also for lambda generated code, gte jdk8 + (!is_reflect || VerifyReflectionBytecodes) && + (!is_lambda || VerifyLambdaBytecodes) ); } diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index cee02416a4b..c9bcbe1f4d3 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -3514,6 +3514,8 @@ class CommandLineFlags { "Temporary flag for transition to AbstractMethodError wrapped " \ "in InvocationTargetException. See 6531596") \ \ + develop(bool, VerifyLambdaBytecodes, false, \ + "Force verification of jdk 8 lambda metafactory bytecodes.") \ \ develop(intx, FastSuperclassLimit, 8, \ "Depth of hardwired instanceof accelerator array") \ From 3dd18b5d8cd96bccc3021b319fd4c179589dc52b Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 30 Aug 2013 15:14:51 -0700 Subject: [PATCH 0159/1294] 8024093: Two *.rej files checked in to langtools/test directory Reviewed-by: mchung --- .../javac/diags/examples/MrefStat.java.rej | 34 ----------------- .../javac/diags/examples/MrefStat1.java.rej | 37 ------------------- 2 files changed, 71 deletions(-) delete mode 100644 langtools/test/tools/javac/diags/examples/MrefStat.java.rej delete mode 100644 langtools/test/tools/javac/diags/examples/MrefStat1.java.rej diff --git a/langtools/test/tools/javac/diags/examples/MrefStat.java.rej b/langtools/test/tools/javac/diags/examples/MrefStat.java.rej deleted file mode 100644 index f5286e5a2d2..00000000000 --- a/langtools/test/tools/javac/diags/examples/MrefStat.java.rej +++ /dev/null @@ -1,34 +0,0 @@ ---- MrefStat.java -+++ MrefStat.java -@@ -0,0 +1,31 @@ -+/* -+ * Copyright (c) 2013, 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.note.mref.stat -+// options: -XDdumpLambdaToMethodStats -+ -+class MrefStat { -+ Runnable r = MrefStat::m; -+ -+ static void m() { } -+} diff --git a/langtools/test/tools/javac/diags/examples/MrefStat1.java.rej b/langtools/test/tools/javac/diags/examples/MrefStat1.java.rej deleted file mode 100644 index b247270db53..00000000000 --- a/langtools/test/tools/javac/diags/examples/MrefStat1.java.rej +++ /dev/null @@ -1,37 +0,0 @@ ---- MrefStat1.java -+++ MrefStat1.java -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (c) 2013, 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.note.mref.stat.1 -+// options: -XDdumpLambdaToMethodStats -+ -+class MrefStat1 { -+ -+ void m() { } -+ -+ static class Sub extends MrefStat1 { -+ Runnable r = super::m; -+ } -+} From 2b932655644d10b5e6826eada40961dee77fc098 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Fri, 30 Aug 2013 15:59:33 -0700 Subject: [PATCH 0160/1294] 7198273: RFE : Javadoc Accessibility : Hyperlinks should contain text or an image with alt text Reviewed-by: jjg --- .../doclets/formats/html/HtmlDocletWriter.java | 16 ++++++++-------- .../doclets/formats/html/markup/HtmlStyle.java | 1 + .../internal/toolkit/resources/stylesheet.css | 6 ++++++ .../sun/javadoc/AccessSkipNav/AccessSkipNav.java | 10 +++++----- .../javadoc/testNavigation/TestNavigation.java | 7 +++---- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java index 8dcf113e3f3..c55ff564f2f 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java @@ -502,16 +502,17 @@ public class HtmlDocletWriter extends HtmlDocWriter { if (!configuration.nonavbar) { String allClassesId = "allclasses_"; HtmlTree navDiv = new HtmlTree(HtmlTag.DIV); + Content skipNavLinks = configuration.getResource("doclet.Skip_navigation_links"); if (header) { body.addContent(HtmlConstants.START_OF_TOP_NAVBAR); navDiv.addStyle(HtmlStyle.topNav); allClassesId += "navbar_top"; Content a = getMarkerAnchor("navbar_top"); + //WCAG - Hyperlinks should contain text or an image with alt text - for AT tools navDiv.addContent(a); - Content skipLinkContent = getHyperLink(DocLink.fragment("skip-navbar_top"), - HtmlTree.EMPTY, - configuration.getText("doclet.Skip_navigation_links"), - ""); + Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink( + DocLink.fragment("skip-navbar_top"), skipNavLinks, + skipNavLinks.toString(), "")); navDiv.addContent(skipLinkContent); } else { body.addContent(HtmlConstants.START_OF_BOTTOM_NAVBAR); @@ -519,10 +520,9 @@ public class HtmlDocletWriter extends HtmlDocWriter { allClassesId += "navbar_bottom"; Content a = getMarkerAnchor("navbar_bottom"); navDiv.addContent(a); - Content skipLinkContent = getHyperLink(DocLink.fragment("skip-navbar_bottom"), - HtmlTree.EMPTY, - configuration.getText("doclet.Skip_navigation_links"), - ""); + Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink( + DocLink.fragment("skip-navbar_bottom"), skipNavLinks, + skipNavLinks.toString(), "")); navDiv.addContent(skipLinkContent); } if (header) { diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlStyle.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlStyle.java index c20ac4c5d5f..5bf1c3259fe 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlStyle.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlStyle.java @@ -68,6 +68,7 @@ public enum HtmlStyle { packageSummary, rowColor, serializedFormContainer, + skipNav, sourceContainer, sourceLineNo, strong, diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css index b2adb742b81..c264d66b303 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css @@ -180,6 +180,12 @@ ul.subNavList li{ margin: auto 5px; border:1px solid #c9aa44; } +.skipNav { + position:absolute; + top:auto; + left:-9999px; + overflow:hidden; + } /* Page header and footer styles */ diff --git a/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java b/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java index d88329cb5db..6ad89feb8bf 100644 --- a/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java +++ b/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4638136 + * @bug 4638136 7198273 * @summary Add ability to skip over nav bar for accessibility * @author dkramer * @run main AccessSkipNav @@ -42,7 +42,7 @@ import java.io.*; */ public class AccessSkipNav { - private static final String BUGID = "4638136"; + private static final String BUGID = "4638136 - 7198273"; private static final String BUGNAME = "AccessSkipNav"; private static final String FS = System.getProperty("file.separator"); private static final String PS = System.getProperty("path.separator"); @@ -86,7 +86,7 @@ public class AccessSkipNav { // Testing only for the presence of the and // Top navbar - { "", + { "Skip navigation links", TMPDEST_DIR1 + "p1" + FS + "C1.html" }, // Top navbar @@ -95,7 +95,7 @@ public class AccessSkipNav { TMPDEST_DIR1 + "p1" + FS + "C1.html" }, // Bottom navbar - { "", + { "Skip navigation links", TMPDEST_DIR1 + "p1" + FS + "C1.html" }, // Bottom navbar diff --git a/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java index d533d98c289..4466eb87d0e 100644 --- a/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java +++ b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java @@ -23,13 +23,12 @@ /* * @test - * @bug 4131628 4664607 7025314 8023700 + * @bug 4131628 4664607 7025314 8023700 7198273 * @summary Make sure the Next/Prev Class links iterate through all types. * Make sure the navagation is 2 columns, not 3. * @author jamieh * @library ../lib/ - * @build JavadocTester - * @build TestNavigation + * @build JavadocTester TestNavigation * @run main TestNavigation */ @@ -61,7 +60,7 @@ public class TestNavigation extends JavadocTester { {BUG_ID + FS + "pkg" + FS + "I.html", "
  • Next Class
  • "}, // Test for 4664607 {BUG_ID + FS + "pkg" + FS + "I.html", - "
    " + NL + + "" + NL + "" + NL + "" + NL + ""} }; private static final String[][] NEGATED_TEST = NO_TEST; From 5793c3a33c6142e27dfe21b66770c52d309fd36a Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Fri, 30 Aug 2013 16:16:28 -0700 Subject: [PATCH 0161/1294] 8015882: Javadoc prints NPE when using Taglet Reviewed-by: jjg --- .../toolkit/taglets/LegacyTaglet.java | 8 +- .../com/sun/javadoc/testLegacyTaglet/C.java | 10 +- .../sun/javadoc/testLegacyTaglet/Check.java | 143 ++++++++++++++++++ .../testLegacyTaglet/TestLegacyTaglet.java | 22 +-- 4 files changed, 172 insertions(+), 11 deletions(-) create mode 100644 langtools/test/com/sun/javadoc/testLegacyTaglet/Check.java diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java index 2691c2b4ab3..2dfce45c157 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java @@ -130,7 +130,13 @@ public class LegacyTaglet implements Taglet { public Content getTagletOutput(Doc holder, TagletWriter writer) throws IllegalArgumentException { Content output = writer.getOutputInstance(); - output.addContent(new RawHtml(legacyTaglet.toString(holder.tags(getName())))); + Tag[] tags = holder.tags(getName()); + if (tags.length > 0) { + String tagString = legacyTaglet.toString(tags); + if (tagString != null) { + output.addContent(new RawHtml(tagString)); + } + } return output; } } diff --git a/langtools/test/com/sun/javadoc/testLegacyTaglet/C.java b/langtools/test/com/sun/javadoc/testLegacyTaglet/C.java index d5370c2dcd6..6de5ca31ef1 100644 --- a/langtools/test/com/sun/javadoc/testLegacyTaglet/C.java +++ b/langtools/test/com/sun/javadoc/testLegacyTaglet/C.java @@ -25,5 +25,13 @@ /** * This is an {@underline underline}. * @todo Finish this class. + * @check Check this. */ -public class C {} +public class C { + + /** + * @todo Tag in Method. + */ + public void mtd() { + } +} diff --git a/langtools/test/com/sun/javadoc/testLegacyTaglet/Check.java b/langtools/test/com/sun/javadoc/testLegacyTaglet/Check.java new file mode 100644 index 00000000000..a294603b99a --- /dev/null +++ b/langtools/test/com/sun/javadoc/testLegacyTaglet/Check.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.tools.doclets.Taglet; +import com.sun.javadoc.*; +import java.util.Map; + +public class Check implements Taglet { + + private static final String TAG_NAME = "check"; + private static final String TAG_HEADER = "Check:"; + + /** + * Return true since the tag can be used in package documentation. + * + * @return true since the tag can be used in package documentation. + */ + public boolean inPackage() { + return true; + } + + /** + * Return true since the tag can be used in overview documentation. + * + * @return true since the tag can be used in overview documentation. + */ + public boolean inOverview() { + return true; + } + + /** + * Return true since the tag can be used in type (class/interface) + * documentation. + * + * @return true since the tag can be used in type (class/interface) + * documentation. + */ + public boolean inType() { + return true; + } + + /** + * Return true since the tag can be used in constructor documentation. + * + * @return true since the tag can be used in constructor documentation. + */ + public boolean inConstructor() { + return true; + } + + /** + * Return true since the tag can be used in field documentation. + * + * @return true since the tag can be used in field documentation. + */ + public boolean inField() { + return true; + } + + /** + * Return true since the tag can be used in method documentation. + * + * @return true since the tag can be used in method documentation. + */ + public boolean inMethod() { + return true; + } + + /** + * Return false since the tag is not an inline tag. + * + * @return false since the tag is not an inline tag. + */ + public boolean isInlineTag() { + return false; + } + + /** + * Register this taglet. + * + * @param tagletMap the map to register this tag to. + */ + @SuppressWarnings("unchecked") + public static void register(Map tagletMap) { + Check tag = new Check(); + Taglet t = (Taglet) tagletMap.get(tag.getName()); + if (t != null) { + tagletMap.remove(tag.getName()); + } + tagletMap.put(tag.getName(), tag); + } + + /** + * Return the name of this custom tag. + * + * @return the name of this tag. + */ + public String getName() { + return TAG_NAME; + } + + /** + * Given the tag representation of this custom tag, return its string + * representation. + * + * @param tag the tag representation of this custom tag. + */ + public String toString(Tag tag) { + return "
    " + TAG_HEADER + ":
    " + tag.text() + + "
    \n"; + } + + /** + * Given an array of tags representing this custom tag, return its string + * representation. + * + * @param tags the array of tags representing of this custom tag. + * @return null to test if the javadoc throws an exception or not. + */ + public String toString(Tag[] tags) { + return null; + } +} diff --git a/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java b/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java index 8e1790de54a..f86c998e809 100644 --- a/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java +++ b/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,32 +23,33 @@ /* * @test - * @bug 4638723 + * @bug 4638723 8015882 * @summary Test to ensure that the refactored version of the standard * doclet still works with Taglets that implement the 1.4.0 interface. * @author jamieh * @library ../lib/ - * @compile ../lib/JavadocTester.java - * @compile TestLegacyTaglet.java - * @compile ToDoTaglet.java - * @compile UnderlineTaglet.java + * @compile ../lib/JavadocTester.java TestLegacyTaglet.java ToDoTaglet.java UnderlineTaglet.java Check.java * @run main TestLegacyTaglet */ public class TestLegacyTaglet extends JavadocTester { - private static final String BUG_ID = "4638723"; + private static final String BUG_ID = "4638723-8015882"; private static final String[] ARGS = new String[] {"-d", BUG_ID, "-sourcepath", SRC_DIR, - "-tagletpath", SRC_DIR, "-taglet", "ToDoTaglet", + "-tagletpath", SRC_DIR, "-taglet", "ToDoTaglet", "-taglet", "Check", "-taglet", "UnderlineTaglet", SRC_DIR + FS + "C.java"}; private static final String[][] TEST = new String[][] { {BUG_ID + FS + "C.html", "This is an underline"}, {BUG_ID + FS + "C.html", "
    To Do:
    " + - "
    Finish this class.
    "}}; + "Finish this class."}, + {BUG_ID + FS + "C.html", + "
    To Do:
    " + + "
    Tag in Method.
    "} + }; private static final String[][] NEGATED_TEST = NO_TEST; @@ -59,6 +60,9 @@ public class TestLegacyTaglet extends JavadocTester { public static void main(String[] args) { TestLegacyTaglet tester = new TestLegacyTaglet(); run(tester, ARGS, TEST, NEGATED_TEST); + if (tester.getErrorOutput().contains("NullPointerException")) { + throw new AssertionError("javadoc threw NullPointerException"); + } tester.printSummary(); } From 4cf2250826682bc71b3119301b23658f19931a9b Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 30 Aug 2013 16:27:08 -0700 Subject: [PATCH 0162/1294] 8008367: Sub-packages missing from Profiles javadoc Reviewed-by: bpatel --- .../internal/toolkit/Configuration.java | 72 ++++++++++--------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java index 32b7648e34b..0337840d248 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java @@ -383,35 +383,44 @@ public abstract class Configuration { DocErrorReporter reporter); private void initProfiles() throws IOException { - profiles = Profiles.read(new File(profilespath)); - // Generate profiles documentation only is profilespath is set and if - // profiles is not null and profiles count is 1 or more. - showProfiles = (!profilespath.isEmpty() && profiles != null && - profiles.getProfileCount() > 0); - } + if (profilespath.isEmpty()) + return; - private void initProfilePackages() throws IOException { - profilePackages = new HashMap(); - ArrayList results; - Map packageIndex = new HashMap(); - for (int i = 0; i < packages.length; i++) { - PackageDoc pkg = packages[i]; - packageIndex.put(pkg.name(), pkg); - } - for (int i = 1; i < profiles.getProfileCount(); i++) { - Set profPkgs = profiles.getPackages(i); - results = new ArrayList(); - for (String packageName : profPkgs) { - packageName = packageName.replace("/", "."); - PackageDoc profPkg = packageIndex.get(packageName); - if (profPkg != null) { - results.add(profPkg); - } + profiles = Profiles.read(new File(profilespath)); + + // Group the packages to be documented by the lowest profile (if any) + // in which each appears + Map> interimResults = + new EnumMap>(Profile.class); + for (Profile p: Profile.values()) + interimResults.put(p, new ArrayList()); + + for (PackageDoc pkg: packages) { + // the getProfile method takes a type name, not a package name, + // but isn't particularly fussy about the simple name -- so just use * + int i = profiles.getProfile(pkg.name().replace(".", "/") + "/*"); + Profile p = Profile.lookup(i); + if (p != null) { + List pkgs = interimResults.get(p); + pkgs.add(pkg); } - Collections.sort(results); - PackageDoc[] profilePkgs = results.toArray(new PackageDoc[]{}); - profilePackages.put(Profile.lookup(i).name, profilePkgs); } + + // Build the profilePackages structure used by the doclet + profilePackages = new HashMap(); + List prev = Collections.emptyList(); + for (Map.Entry> e: interimResults.entrySet()) { + Profile p = e.getKey(); + List pkgs = e.getValue(); + pkgs.addAll(prev); // each profile contains all lower profiles + Collections.sort(pkgs); + profilePackages.put(p.name, pkgs.toArray(new PackageDoc[pkgs.size()])); + prev = pkgs; + } + + // Generate profiles documentation if any profile contains any + // of the packages to be documented. + showProfiles = !prev.isEmpty(); } private void initPackageArray() { @@ -534,13 +543,10 @@ public abstract class Configuration { public void setOptions() throws Fault { initPackageArray(); setOptions(root.options()); - if (!profilespath.isEmpty()) { - try { - initProfiles(); - initProfilePackages(); - } catch (Exception e) { - throw new DocletAbortException(e); - } + try { + initProfiles(); + } catch (Exception e) { + throw new DocletAbortException(e); } setSpecificDocletOptions(root.options()); } From b8f8cab5f46da79d63c1b701d345d224e3b55cb7 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Fri, 30 Aug 2013 16:38:54 -0700 Subject: [PATCH 0163/1294] 8022738: doclet should only generate functional interface text if source >= 8 Reviewed-by: jjg --- .../com/sun/tools/javadoc/ClassDocImpl.java | 2 +- .../classes/com/sun/tools/javadoc/DocEnv.java | 6 ++++ .../testLambdaFeature/TestLambdaFeature.java | 22 +++++++++++--- .../testLambdaFeature/pkg1/FuncInf.java | 29 +++++++++++++++++++ 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 langtools/test/com/sun/javadoc/testLambdaFeature/pkg1/FuncInf.java diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java index 79580f60fb5..160ccbceb10 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java @@ -289,7 +289,7 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc { } public boolean isFunctionalInterface() { - return env.types.isFunctionalInterface(tsym); + return env.types.isFunctionalInterface(tsym) && env.source.allowLambda(); } /** diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java index 3a1c891984e..d0ff14b70ea 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java @@ -123,6 +123,11 @@ public class DocEnv { */ private boolean silent = false; + /** + * The source language version. + */ + protected Source source; + /** * Constructor * @@ -144,6 +149,7 @@ public class DocEnv { // Default. Should normally be reset with setLocale. this.doclocale = new DocLocale(this, "", breakiterator); + source = Source.instance(context); } public void setSilent(boolean silent) { diff --git a/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java b/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java index 7a157ffc17d..151549b57a2 100644 --- a/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java +++ b/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8004893 + * @bug 8004893 8022738 * @summary Make sure that the lambda feature changes work fine in * javadoc. * @author bpatel @@ -35,11 +35,15 @@ public class TestLambdaFeature extends JavadocTester { //Test information. - private static final String BUG_ID = "8004893"; + private static final String BUG_ID = "8004893-8022738"; //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "pkg1" + }; + + private static final String[] ARGS_1 = new String[] { + "-d", BUG_ID + "-2", "-sourcepath", SRC_DIR, "-source", "1.5", "pkg1" }; //Input for string search tests. @@ -60,6 +64,11 @@ public class TestLambdaFeature extends JavadocTester { "Default Methods" + " "}, {BUG_ID + FS + "pkg" + FS + "A.html", + "
    " + NL + "
    Functional Interface:
    " + NL + + "
    This is a functional interface and can therefore be used as " + + "the assignment target for a lambda expression or method " + + "reference.
    " + NL + "
    "}, + {BUG_ID + FS + "pkg1" + FS + "FuncInf.html", "
    " + NL + "
    Functional Interface:
    " + NL + "
    This is a functional interface and can therefore be used as " + "the assignment target for a lambda expression or method " + @@ -75,6 +84,10 @@ public class TestLambdaFeature extends JavadocTester { {BUG_ID + FS + "pkg" + FS + "B.html", "
    " + NL + "
    Functional Interface:
    "} }; + private static final String[][] NEGATED_TEST_1 = { + {BUG_ID + "-2" + FS + "pkg1" + FS + "FuncInf.html", + "
    " + NL + "
    Functional Interface:
    "} + }; /** * The entry point of the test. @@ -83,6 +96,7 @@ public class TestLambdaFeature extends JavadocTester { public static void main(String[] args) { TestLambdaFeature tester = new TestLambdaFeature(); run(tester, ARGS, TEST, NEGATED_TEST); + run(tester, ARGS_1, NO_TEST, NEGATED_TEST_1); tester.printSummary(); } diff --git a/langtools/test/com/sun/javadoc/testLambdaFeature/pkg1/FuncInf.java b/langtools/test/com/sun/javadoc/testLambdaFeature/pkg1/FuncInf.java new file mode 100644 index 00000000000..566acf596ca --- /dev/null +++ b/langtools/test/com/sun/javadoc/testLambdaFeature/pkg1/FuncInf.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2013, 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. + */ + +package pkg1; + +public interface FuncInf { + + V call() throws Exception; +} From 433728650249fb0fe2b92ab5692d7257daaeb0fd Mon Sep 17 00:00:00 2001 From: Evgeniya Stepanova Date: Fri, 30 Aug 2013 17:36:47 -0700 Subject: [PATCH 0164/1294] 8015663: Need to supply tests to provide javadoc for profiles support code coverage Reviewed-by: jjg --- .../javadoc/testProfiles/TestProfiles.java | 52 +++++++++- .../TestProfilesConfiguration.java | 94 +++++++++++++++++++ .../javadoc/testProfiles/pkg2/Class1Pkg2.java | 2 +- .../javadoc/testProfiles/pkg2/ClassError.java | 31 ++++++ .../testProfiles/pkg2/ClassException.java | 31 ++++++ .../pkgDeprecated/Class1PkgDeprecated.java | 36 +++++++ .../pkgDeprecated/package-info.java | 29 ++++++ .../testProfiles/profile-rtjar-includes.txt | 3 +- 8 files changed, 273 insertions(+), 5 deletions(-) create mode 100644 langtools/test/com/sun/javadoc/testProfiles/TestProfilesConfiguration.java create mode 100644 langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassError.java create mode 100644 langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassException.java create mode 100644 langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/Class1PkgDeprecated.java create mode 100644 langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/package-info.java diff --git a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java index 5f84abfe7ba..8dda141791c 100644 --- a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java +++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java @@ -25,7 +25,7 @@ * @test * @bug 8006124 8009684 8016921 8023700 * @summary Test javadoc support for profiles. - * @author Bhavesh Patel + * @author Bhavesh Patel, Evgeniya Stepanova * @library ../lib/ * @build JavadocTester TestProfiles * @run main TestProfiles @@ -38,8 +38,9 @@ public class TestProfiles extends JavadocTester { private static final String PACKAGE_BUG_ID = BUG_ID + "-2"; //Javadoc arguments. private static final String[] ARGS1 = new String[]{ - "-d", PROFILE_BUG_ID, "-sourcepath", SRC_DIR, "-Xprofilespath", SRC_DIR + FS - + "profile-rtjar-includes.txt", "pkg1", "pkg2", "pkg3", "pkg4", "pkg5" + "-d", PROFILE_BUG_ID, "-sourcepath", SRC_DIR, "-Xprofilespath", + SRC_DIR + FS + "profile-rtjar-includes.txt", "pkg1", "pkg2", + "pkg3", "pkg4", "pkg5", "pkgDeprecated" }; private static final String[] ARGS2 = new String[]{ "-d", PACKAGE_BUG_ID, "-sourcepath", SRC_DIR, "pkg1", "pkg2", "pkg3", "pkg4", "pkg5" @@ -113,6 +114,49 @@ public class TestProfiles extends JavadocTester { "target=\"classFrame\">compact2" + NL + "
  • compact3
  • " + NL + "" + }, + //Test deprecated class in profiles + {PROFILE_BUG_ID + FS + "compact1-summary.html","" + + "Class1Pkg2" + + NL + "Deprecated" + }, + {PROFILE_BUG_ID + FS + "deprecated-list.html","" + + "pkg2.Class1Pkg2" + + NL +"
    Class1Pkg2. This class is deprecated
    " + }, + //Test deprecated package in profile + {PROFILE_BUG_ID + FS + "deprecated-list.html","" + + "pkgDeprecated" + + NL +"
    This package is Deprecated." + + " Use pkg1.
    " + }, + {PROFILE_BUG_ID + FS + "pkgDeprecated" + FS + "package-summary.html", + "
    Deprecated." + + NL + "
    This package is Deprecated." + + " Use pkg1.
    " + }, + // need to add teststring when JDK-8015496 will be fixed + //Test exception in profiles + {PROFILE_BUG_ID + FS + "compact1-summary.html","" + + NL + "" + NL + "" + NL + "" + NL + "" + NL + "" + NL + "" + NL + "" + + NL + "" + }, + //Test errors in profiles + {PROFILE_BUG_ID + FS + "compact1-summary.html", + "
    Exception Summary" + + " 
    Exception" + + "Description
    ClassException
    " + + NL + "" + NL + "" + NL + "" + NL + "" + NL + "" + NL + "" + + NL + "" + NL + "" } }; private static final String[][] PROFILES_NEGATED_TEST = { @@ -125,6 +169,8 @@ public class TestProfiles extends JavadocTester { {PROFILE_BUG_ID + FS + "pkg4" + FS + "compact2-package-frame.html", "
  • Anno1Pkg4
  • " + }, + {PROFILE_BUG_ID + FS + "compact1-summary.html","
  • Use
  • " } }; private static final String[][] PACKAGES_TEST = { diff --git a/langtools/test/com/sun/javadoc/testProfiles/TestProfilesConfiguration.java b/langtools/test/com/sun/javadoc/testProfiles/TestProfilesConfiguration.java new file mode 100644 index 00000000000..140728e1ac5 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfilesConfiguration.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013, 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 8006124 8009684 8015663 + * @summary Test javadoc options support for profiles. + * @author Evgeniya Stepanova + * @library ../lib/ + * @build JavadocTester TestProfilesConfiguration + * @run main TestProfilesConfiguration + */ +public class TestProfilesConfiguration extends JavadocTester { + + //Test information. + private static final String BUG_ID = "8006124-8009684"; + private static final String PROFILE_CONFIGURATION_BUG_ID = BUG_ID + "-3"; + //Javadoc arguments. + private static final String[] ARGS3 = new String[]{ + "-d", PROFILE_CONFIGURATION_BUG_ID, "-sourcepath", SRC_DIR, "-nocomment", + "-keywords", "-Xprofilespath", SRC_DIR + FS + "profile-rtjar-includes.txt", + "-doctitle", "Simple doctitle", "-use", "pkg3", "pkg1", "pkg2", "pkg4", + "pkg5", "-packagesheader", "Simple packages header","pkgDeprecated" + }; + private static final String[][] PROFILES_CONFIGURATION_TEST = { + //-use option test string fo profile view page + {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html","
  • Use
  • " + }, + //-doctitle option test string + {PROFILE_CONFIGURATION_BUG_ID + FS + "overview-summary.html", + "
    " + NL + "

    Simple doctitle

    " + }, + //-packagesheader option test string fo profiles + {PROFILE_CONFIGURATION_BUG_ID + FS + "profile-overview-frame.html", + "

    Simple packages header

    " + }, + //-keywords option test string for profiles + {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html", + "" + } + }; + private static final String[][] PROFILES_CONFIGURATION_NEGATED_TEST = { + //-nocomments option test string + {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html", + "
    Class1Pkg2.
    " + } + }; + + /** + * The entry point of the test. + * + * @param args the array of command line arguments. + */ + public static void main(String[] args) { + TestProfilesConfiguration tester = new TestProfilesConfiguration(); + run(tester, ARGS3, PROFILES_CONFIGURATION_TEST, + PROFILES_CONFIGURATION_NEGATED_TEST); + tester.printSummary(); + } + + /** + * {@inheritDoc} + */ + public String getBugId() { + return BUG_ID; + } + + /** + * {@inheritDoc} + */ + public String getBugName() { + return getClass().getName(); + } +} diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg2/Class1Pkg2.java b/langtools/test/com/sun/javadoc/testProfiles/pkg2/Class1Pkg2.java index afa13d8444e..935bd3643ae 100644 --- a/langtools/test/com/sun/javadoc/testProfiles/pkg2/Class1Pkg2.java +++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/Class1Pkg2.java @@ -24,7 +24,7 @@ package pkg2; /** - * Another test class. + * @deprecated Class1Pkg2. This class is deprecated * * @author Bhavesh Patel */ diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassError.java b/langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassError.java new file mode 100644 index 00000000000..427b8f9c896 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassError.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013, 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. + */ + +package pkg2; + +/** + * Simple error class. + * + * @author Evgeniya Stepanova + */ +public class ClassError extends Error {} diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassException.java b/langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassException.java new file mode 100644 index 00000000000..d56412e7da2 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassException.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013, 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. + */ + +package pkg2; + +/** + * Simple exception class. + * + * @author Evgeniya Stepanova + */ +public class ClassException extends Exception {} diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/Class1PkgDeprecated.java b/langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/Class1PkgDeprecated.java new file mode 100644 index 00000000000..51475499286 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/Class1PkgDeprecated.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013, 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. + */ + +package pkgDeprecated; + +/** + * Simple deprecated class of deprecated package. + * + * @author Evgeniya Stepanova + */ +public class Class1PkgDeprecated { + + public void method(int t) { + return null; + } +} diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/package-info.java b/langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/package-info.java new file mode 100644 index 00000000000..0cc070077cb --- /dev/null +++ b/langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/package-info.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2013, 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. + */ + +/** + * Deprecated package. + * + * @deprecated This package is Deprecated. Use pkg1. + */ +package pkgDeprecated; diff --git a/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes.txt b/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes.txt index 9460b3f985b..eff8d14b438 100644 --- a/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes.txt +++ b/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes.txt @@ -1,5 +1,6 @@ PROFILE_1_RTJAR_INCLUDE_PACKAGES := \ - pkg2 + pkg2 \ + pkgDeprecated PROFILE_1_RTJAR_INCLUDE_TYPES := \ pkg3/Class1Pkg3.class From a320f6a56645f40d21e0b13d99979ddcb67cb552 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Sun, 1 Sep 2013 10:37:01 -0400 Subject: [PATCH 0165/1294] 8023381: VM fails to initialize in runtime/CDSCompressedKPtrs/XShareAuto.java runtime/SharedArchiveFile/CdsSameObjectAlignment.java Improve handling when CDS archive cannot be mapped Reviewed-by: kvn, dholmes, mseledtsov --- hotspot/src/share/vm/memory/filemap.cpp | 1 + .../test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java | 5 ++--- hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java | 2 +- .../runtime/SharedArchiveFile/CdsSameObjectAlignment.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp index d036266b00f..8eb5f452495 100644 --- a/hotspot/src/share/vm/memory/filemap.cpp +++ b/hotspot/src/share/vm/memory/filemap.cpp @@ -55,6 +55,7 @@ static void fail(const char *msg, va_list ap) { " shared archive file.\n"); jio_vfprintf(defaultStream::error_stream(), msg, ap); jio_fprintf(defaultStream::error_stream(), "\n"); + // Do not change the text of the below message because some tests check for it. vm_exit_during_initialization("Unable to use shared archive.", NULL); } diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java index b1c8ad996d2..4ce2e82c771 100644 --- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java +++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java @@ -51,9 +51,8 @@ public class CDSCompressedKPtrs { output.shouldHaveExitValue(0); } catch (RuntimeException e) { - // Report 'passed' if CDS was turned off because we could not allocate - // the klass metaspace at an address that would work with CDS. - output.shouldContain("Could not allocate metaspace at a compatible address"); + // Report 'passed' if CDS was turned off. + output.shouldContain("Unable to use shared archive"); output.shouldHaveExitValue(1); } } diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java index 0165b2cc782..7f36977ec70 100644 --- a/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java +++ b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java @@ -69,7 +69,7 @@ public class XShareAuto { "-server", "-Xshare:on", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-version"); output = new OutputAnalyzer(pb.start()); - output.shouldContain("Could not allocate metaspace at a compatible address"); + output.shouldContain("Unable to use shared archive"); output.shouldHaveExitValue(1); } } diff --git a/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java b/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java index b956095697b..5c91f604a8e 100644 --- a/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java +++ b/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java @@ -84,7 +84,7 @@ public class CdsSameObjectAlignment { // there is a chance such reservation will fail // If it does, it is NOT considered a failure of the feature, // rather a possible expected outcome, though not likely - output.shouldContain("Could not allocate metaspace at a compatible address"); + output.shouldContain("Unable to use shared archive"); output.shouldHaveExitValue(1); } } From 24f306c761ab39cb76b22ddb28fee77074d3c0ef Mon Sep 17 00:00:00 2001 From: Clemens Eisserer Date: Sun, 1 Sep 2013 09:38:03 -0700 Subject: [PATCH 0166/1294] 7189452: XRender pipeline does ignore source-surface offset for text rendering Reviewed-by: prr, bae --- jdk/src/solaris/classes/sun/font/XRTextRenderer.java | 2 +- .../solaris/classes/sun/java2d/xr/XRBackendNative.java | 9 +++++---- .../classes/sun/java2d/xr/XRCompositeManager.java | 8 ++++---- jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c | 7 ++++--- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/jdk/src/solaris/classes/sun/font/XRTextRenderer.java b/jdk/src/solaris/classes/sun/font/XRTextRenderer.java index c2aa27b43e0..308de3ab300 100644 --- a/jdk/src/solaris/classes/sun/font/XRTextRenderer.java +++ b/jdk/src/solaris/classes/sun/font/XRTextRenderer.java @@ -142,7 +142,7 @@ public class XRTextRenderer extends GlyphListPipe { } int maskFormat = containsLCDGlyphs ? XRUtils.PictStandardARGB32 : XRUtils.PictStandardA8; - maskBuffer.compositeText(x11sd.picture, 0, maskFormat, eltList); + maskBuffer.compositeText(x11sd, (int) gl.getX(), (int) gl.getY(), 0, maskFormat, eltList); eltList.clear(); } finally { diff --git a/jdk/src/solaris/classes/sun/java2d/xr/XRBackendNative.java b/jdk/src/solaris/classes/sun/java2d/xr/XRBackendNative.java index a6ffd0defcd..205ff13c6fc 100644 --- a/jdk/src/solaris/classes/sun/java2d/xr/XRBackendNative.java +++ b/jdk/src/solaris/classes/sun/java2d/xr/XRBackendNative.java @@ -267,8 +267,9 @@ public class XRBackendNative implements XRBackend { private static native void XRenderCompositeTextNative(int op, int src, int dst, - long maskFormat, int[] eltArray, - int[] glyphIDs, int eltCnt, int glyphCnt); + int srcX, int srcY, long maskFormat, + int[] eltArray, int[] glyphIDs, int eltCnt, + int glyphCnt); public int XRenderCreateGlyphSet(int formatID) { return XRenderCreateGlyphSetNative(getFormatPtr(formatID)); @@ -278,11 +279,11 @@ public class XRBackendNative implements XRBackend { public void XRenderCompositeText(byte op, int src, int dst, int maskFormatID, - int src2, int src3, int dst2, int dst3, + int sx, int sy, int dx, int dy, int glyphset, GrowableEltArray elts) { GrowableIntArray glyphs = elts.getGlyphs(); - XRenderCompositeTextNative(op, src, dst, 0, elts.getArray(), + XRenderCompositeTextNative(op, src, dst, sx, sy, 0, elts.getArray(), glyphs.getArray(), elts.getSize(), glyphs.getSize()); } diff --git a/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java b/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java index 1264d539611..b1c2ef08065 100644 --- a/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java +++ b/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java @@ -295,10 +295,10 @@ public class XRCompositeManager { sy, 0, 0, dx, dy, w, h); } - public void compositeText(int dst, int glyphSet, int maskFormat, - GrowableEltArray elts) { - con.XRenderCompositeText(compRule, src.picture, dst, maskFormat, 0, 0, - 0, 0, glyphSet, elts); + public void compositeText(XRSurfaceData dst, int sx, int sy, + int glyphSet, int maskFormat, GrowableEltArray elts) { + con.XRenderCompositeText(compRule, src.picture, dst.picture, + maskFormat, sx, sy, 0, 0, glyphSet, elts); } public XRColor getMaskColor() { diff --git a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c index 75d1cd2f4d2..cbcf0c357e3 100644 --- a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c +++ b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c @@ -911,8 +911,9 @@ Java_sun_java2d_xr_XRBackendNative_XRenderCreateGlyphSetNative JNIEXPORT void JNICALL Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative - (JNIEnv *env, jclass cls, jint op, jint src, jint dst, jlong maskFmt, - jintArray eltArray, jintArray glyphIDArray, jint eltCnt, jint glyphCnt) { + (JNIEnv *env, jclass cls, jint op, jint src, jint dst, + jint sx, jint sy, jlong maskFmt, jintArray eltArray, + jintArray glyphIDArray, jint eltCnt, jint glyphCnt) { jint i; jint *ids; jint *elts; @@ -991,7 +992,7 @@ Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative XRenderCompositeText32(awt_display, op, (Picture) src, (Picture) dst, (XRenderPictFormat *) jlong_to_ptr(maskFmt), - 0, 0, 0, 0, xelts, eltCnt); + sx, sy, 0, 0, xelts, eltCnt); (*env)->ReleasePrimitiveArrayCritical(env, glyphIDArray, ids, JNI_ABORT); (*env)->ReleasePrimitiveArrayCritical(env, eltArray, elts, JNI_ABORT); From 900acf0c449c854d5d2caa6e22ebe8a8146e0efb Mon Sep 17 00:00:00 2001 From: Niclas Adlertz Date: Sun, 1 Sep 2013 19:21:05 +0200 Subject: [PATCH 0167/1294] 8023988: Move local scheduling of nodes to the CFG creation and code motion phase (PhaseCFG) Moved local scheduling code from class Block to class PhaseCFG Reviewed-by: kvn, roland --- hotspot/src/share/vm/opto/block.cpp | 20 +- hotspot/src/share/vm/opto/block.hpp | 46 +++-- hotspot/src/share/vm/opto/coalesce.cpp | 4 +- hotspot/src/share/vm/opto/gcm.cpp | 6 +- hotspot/src/share/vm/opto/lcm.cpp | 265 +++++++++++++------------ 5 files changed, 173 insertions(+), 168 deletions(-) diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp index 41872cce667..fade19bdb6b 100644 --- a/hotspot/src/share/vm/opto/block.cpp +++ b/hotspot/src/share/vm/opto/block.cpp @@ -209,15 +209,15 @@ bool Block::has_uncommon_code() const { // True if block is low enough frequency or guarded by a test which // mostly does not go here. -bool Block::is_uncommon(PhaseCFG* cfg) const { +bool PhaseCFG::is_uncommon(const Block* block) { // Initial blocks must never be moved, so are never uncommon. - if (head()->is_Root() || head()->is_Start()) return false; + if (block->head()->is_Root() || block->head()->is_Start()) return false; // Check for way-low freq - if( _freq < BLOCK_FREQUENCY(0.00001f) ) return true; + if(block->_freq < BLOCK_FREQUENCY(0.00001f) ) return true; // Look for code shape indicating uncommon_trap or slow path - if (has_uncommon_code()) return true; + if (block->has_uncommon_code()) return true; const float epsilon = 0.05f; const float guard_factor = PROB_UNLIKELY_MAG(4) / (1.f - epsilon); @@ -225,8 +225,8 @@ bool Block::is_uncommon(PhaseCFG* cfg) const { uint freq_preds = 0; uint uncommon_for_freq_preds = 0; - for( uint i=1; iget_block_for_node(pred(i)); + for( uint i=1; i< block->num_preds(); i++ ) { + Block* guard = get_block_for_node(block->pred(i)); // Check to see if this block follows its guard 1 time out of 10000 // or less. // @@ -244,14 +244,14 @@ bool Block::is_uncommon(PhaseCFG* cfg) const { uncommon_preds++; } else { freq_preds++; - if( _freq < guard->_freq * guard_factor ) { + if(block->_freq < guard->_freq * guard_factor ) { uncommon_for_freq_preds++; } } } - if( num_preds() > 1 && + if( block->num_preds() > 1 && // The block is uncommon if all preds are uncommon or - (uncommon_preds == (num_preds()-1) || + (uncommon_preds == (block->num_preds()-1) || // it is uncommon for all frequent preds. uncommon_for_freq_preds == freq_preds) ) { return true; @@ -669,7 +669,7 @@ void PhaseCFG::remove_empty_blocks() { // Look for uncommon blocks and move to end. if (!C->do_freq_based_layout()) { - if (block->is_uncommon(this)) { + if (is_uncommon(block)) { move_to_end(block, i); last--; // No longer check for being uncommon! if (no_flip_branch(block)) { // Fall-thru case must follow? diff --git a/hotspot/src/share/vm/opto/block.hpp b/hotspot/src/share/vm/opto/block.hpp index 01478d3af04..e1574691849 100644 --- a/hotspot/src/share/vm/opto/block.hpp +++ b/hotspot/src/share/vm/opto/block.hpp @@ -318,23 +318,6 @@ public: // Find and remove n from block list void find_remove( const Node *n ); - // helper function that adds caller save registers to MachProjNode - void add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe); - // Schedule a call next in the block - uint sched_call(Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_List &worklist, GrowableArray &ready_cnt, MachCallNode *mcall, VectorSet &next_call); - - // Perform basic-block local scheduling - Node *select(PhaseCFG *cfg, Node_List &worklist, GrowableArray &ready_cnt, VectorSet &next_call, uint sched_slot); - void set_next_call( Node *n, VectorSet &next_call, PhaseCFG* cfg); - void needed_for_next_call(Node *this_call, VectorSet &next_call, PhaseCFG* cfg); - bool schedule_local(PhaseCFG *cfg, Matcher &m, GrowableArray &ready_cnt, VectorSet &next_call); - // Cleanup if any code lands between a Call and his Catch - void call_catch_cleanup(PhaseCFG* cfg, Compile *C); - // Detect implicit-null-check opportunities. Basically, find NULL checks - // with suitable memory ops nearby. Use the memory op to do the NULL check. - // I can generate a memory op if there is not one nearby. - void implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons); - // Return the empty status of a block enum { not_empty, empty_with_goto, completely_empty }; int is_Empty() const; @@ -366,10 +349,6 @@ public: // Examine block's code shape to predict if it is not commonly executed. bool has_uncommon_code() const; - // Use frequency calculations and code shape to predict if the block - // is uncommon. - bool is_uncommon(PhaseCFG* cfg) const; - #ifndef PRODUCT // Debugging print of basic block void dump_bidx(const Block* orig, outputStream* st = tty) const; @@ -452,6 +431,27 @@ class PhaseCFG : public Phase { // to late. Helper for schedule_late. Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self); + bool schedule_local(Block* block, GrowableArray& ready_cnt, VectorSet& next_call); + void set_next_call(Block* block, Node* n, VectorSet& next_call); + void needed_for_next_call(Block* block, Node* this_call, VectorSet& next_call); + + // Perform basic-block local scheduling + Node* select(Block* block, Node_List& worklist, GrowableArray& ready_cnt, VectorSet& next_call, uint sched_slot); + + // Schedule a call next in the block + uint sched_call(Block* block, uint node_cnt, Node_List& worklist, GrowableArray& ready_cnt, MachCallNode* mcall, VectorSet& next_call); + + // Cleanup if any code lands between a Call and his Catch + void call_catch_cleanup(Block* block); + + Node* catch_cleanup_find_cloned_def(Block* use_blk, Node* def, Block* def_blk, int n_clone_idx); + void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, int n_clone_idx); + + // Detect implicit-null-check opportunities. Basically, find NULL checks + // with suitable memory ops nearby. Use the memory op to do the NULL check. + // I can generate a memory op if there is not one nearby. + void implicit_null_check(Block* block, Node *proj, Node *val, int allowed_reasons); + // Perform a Depth First Search (DFS). // Setup 'vertex' as DFS to vertex mapping. // Setup 'semi' as vertex to DFS mapping. @@ -568,6 +568,10 @@ class PhaseCFG : public Phase { return (_node_to_block_mapping.lookup(node->_idx) != NULL); } + // Use frequency calculations and code shape to predict if the block + // is uncommon. + bool is_uncommon(const Block* block); + #ifdef ASSERT Unique_Node_List _raw_oops; #endif diff --git a/hotspot/src/share/vm/opto/coalesce.cpp b/hotspot/src/share/vm/opto/coalesce.cpp index b32a1ef8e25..bd207b584a1 100644 --- a/hotspot/src/share/vm/opto/coalesce.cpp +++ b/hotspot/src/share/vm/opto/coalesce.cpp @@ -339,7 +339,7 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { } // End of is two-adr // Insert a copy at a debug use for a lrg which has high frequency - if (b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(&_phc._cfg)) { + if (b->_freq < OPTO_DEBUG_SPLIT_FREQ || _phc._cfg.is_uncommon(b)) { // Walk the debug inputs to the node and check for lrg freq JVMState* jvms = n->jvms(); uint debug_start = jvms ? jvms->debug_start() : 999999; @@ -769,7 +769,7 @@ bool PhaseConservativeCoalesce::copy_copy(Node *dst_copy, Node *src_copy, Block // Conservative (but pessimistic) copy coalescing of a single block void PhaseConservativeCoalesce::coalesce( Block *b ) { // Bail out on infrequent blocks - if (b->is_uncommon(&_phc._cfg)) { + if (_phc._cfg.is_uncommon(b)) { return; } // Check this block for copies. diff --git a/hotspot/src/share/vm/opto/gcm.cpp b/hotspot/src/share/vm/opto/gcm.cpp index 7ba369513a0..db60d4d1e60 100644 --- a/hotspot/src/share/vm/opto/gcm.cpp +++ b/hotspot/src/share/vm/opto/gcm.cpp @@ -1342,7 +1342,7 @@ void PhaseCFG::global_code_motion() { Node* proj = _matcher._null_check_tests[i]; Node* val = _matcher._null_check_tests[i + 1]; Block* block = get_block_for_node(proj); - block->implicit_null_check(this, proj, val, allowed_reasons); + implicit_null_check(block, proj, val, allowed_reasons); // The implicit_null_check will only perform the transformation // if the null branch is truly uncommon, *and* it leads to an // uncommon trap. Combined with the too_many_traps guards @@ -1363,7 +1363,7 @@ void PhaseCFG::global_code_motion() { visited.Clear(); for (uint i = 0; i < number_of_blocks(); i++) { Block* block = get_block(i); - if (!block->schedule_local(this, _matcher, ready_cnt, visited)) { + if (!schedule_local(block, ready_cnt, visited)) { if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) { C->record_method_not_compilable("local schedule failed"); } @@ -1375,7 +1375,7 @@ void PhaseCFG::global_code_motion() { // clone the instructions on all paths below the Catch. for (uint i = 0; i < number_of_blocks(); i++) { Block* block = get_block(i); - block->call_catch_cleanup(this, C); + call_catch_cleanup(block); } #ifndef PRODUCT diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp index 2b28ee873bf..d57d9f64b73 100644 --- a/hotspot/src/share/vm/opto/lcm.cpp +++ b/hotspot/src/share/vm/opto/lcm.cpp @@ -58,14 +58,14 @@ // The proj is the control projection for the not-null case. // The val is the pointer being checked for nullness or // decodeHeapOop_not_null node if it did not fold into address. -void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) { +void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allowed_reasons) { // Assume if null check need for 0 offset then always needed // Intel solaris doesn't support any null checks yet and no // mechanism exists (yet) to set the switches at an os_cpu level if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return; // Make sure the ptr-is-null path appears to be uncommon! - float f = end()->as_MachIf()->_prob; + float f = block->end()->as_MachIf()->_prob; if( proj->Opcode() == Op_IfTrue ) f = 1.0f - f; if( f > PROB_UNLIKELY_MAG(4) ) return; @@ -75,13 +75,13 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe // Get the successor block for if the test ptr is non-null Block* not_null_block; // this one goes with the proj Block* null_block; - if (get_node(number_of_nodes()-1) == proj) { - null_block = _succs[0]; - not_null_block = _succs[1]; + if (block->get_node(block->number_of_nodes()-1) == proj) { + null_block = block->_succs[0]; + not_null_block = block->_succs[1]; } else { - assert(get_node(number_of_nodes()-2) == proj, "proj is one or the other"); - not_null_block = _succs[0]; - null_block = _succs[1]; + assert(block->get_node(block->number_of_nodes()-2) == proj, "proj is one or the other"); + not_null_block = block->_succs[0]; + null_block = block->_succs[1]; } while (null_block->is_Empty() == Block::empty_with_goto) { null_block = null_block->_succs[0]; @@ -93,7 +93,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe // detect failure of this optimization, as in 6366351.) { bool found_trap = false; - for (uint i1 = 0; i1 < null_block->_nodes.size(); i1++) { + for (uint i1 = 0; i1 < null_block->number_of_nodes(); i1++) { Node* nn = null_block->get_node(i1); if (nn->is_MachCall() && nn->as_MachCall()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point()) { @@ -237,20 +237,20 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe } // Check ctrl input to see if the null-check dominates the memory op - Block *cb = cfg->get_block_for_node(mach); + Block *cb = get_block_for_node(mach); cb = cb->_idom; // Always hoist at least 1 block if( !was_store ) { // Stores can be hoisted only one block - while( cb->_dom_depth > (_dom_depth + 1)) + while( cb->_dom_depth > (block->_dom_depth + 1)) cb = cb->_idom; // Hoist loads as far as we want // The non-null-block should dominate the memory op, too. Live // range spilling will insert a spill in the non-null-block if it is // needs to spill the memory op for an implicit null check. - if (cb->_dom_depth == (_dom_depth + 1)) { + if (cb->_dom_depth == (block->_dom_depth + 1)) { if (cb != not_null_block) continue; cb = cb->_idom; } } - if( cb != this ) continue; + if( cb != block ) continue; // Found a memory user; see if it can be hoisted to check-block uint vidx = 0; // Capture index of value into memop @@ -262,8 +262,8 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe if( is_decoden ) continue; } // Block of memory-op input - Block *inb = cfg->get_block_for_node(mach->in(j)); - Block *b = this; // Start from nul check + Block *inb = get_block_for_node(mach->in(j)); + Block *b = block; // Start from nul check while( b != inb && b->_dom_depth > inb->_dom_depth ) b = b->_idom; // search upwards for input // See if input dominates null check @@ -272,28 +272,28 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe } if( j > 0 ) continue; - Block *mb = cfg->get_block_for_node(mach); + Block *mb = get_block_for_node(mach); // Hoisting stores requires more checks for the anti-dependence case. // Give up hoisting if we have to move the store past any load. if( was_store ) { Block *b = mb; // Start searching here for a local load // mach use (faulting) trying to hoist // n might be blocker to hoisting - while( b != this ) { + while( b != block ) { uint k; - for( k = 1; k < b->_nodes.size(); k++ ) { + for( k = 1; k < b->number_of_nodes(); k++ ) { Node *n = b->get_node(k); if( n->needs_anti_dependence_check() && n->in(LoadNode::Memory) == mach->in(StoreNode::Memory) ) break; // Found anti-dependent load } - if( k < b->_nodes.size() ) + if( k < b->number_of_nodes() ) break; // Found anti-dependent load // Make sure control does not do a merge (would have to check allpaths) if( b->num_preds() != 2 ) break; - b = cfg->get_block_for_node(b->pred(1)); // Move up to predecessor block + b = get_block_for_node(b->pred(1)); // Move up to predecessor block } - if( b != this ) continue; + if( b != block ) continue; } // Make sure this memory op is not already being used for a NullCheck @@ -303,7 +303,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe // Found a candidate! Pick one with least dom depth - the highest // in the dom tree should be closest to the null check. - if (best == NULL || cfg->get_block_for_node(mach)->_dom_depth < cfg->get_block_for_node(best)->_dom_depth) { + if (best == NULL || get_block_for_node(mach)->_dom_depth < get_block_for_node(best)->_dom_depth) { best = mach; bidx = vidx; } @@ -319,46 +319,45 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe if( is_decoden ) { // Check if we need to hoist decodeHeapOop_not_null first. - Block *valb = cfg->get_block_for_node(val); - if( this != valb && this->_dom_depth < valb->_dom_depth ) { + Block *valb = get_block_for_node(val); + if( block != valb && block->_dom_depth < valb->_dom_depth ) { // Hoist it up to the end of the test block. valb->find_remove(val); - this->add_inst(val); - cfg->map_node_to_block(val, this); + block->add_inst(val); + map_node_to_block(val, block); // DecodeN on x86 may kill flags. Check for flag-killing projections // that also need to be hoisted. for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) { Node* n = val->fast_out(j); if( n->is_MachProj() ) { - cfg->get_block_for_node(n)->find_remove(n); - this->add_inst(n); - cfg->map_node_to_block(n, this); + get_block_for_node(n)->find_remove(n); + block->add_inst(n); + map_node_to_block(n, block); } } } } // Hoist the memory candidate up to the end of the test block. - Block *old_block = cfg->get_block_for_node(best); + Block *old_block = get_block_for_node(best); old_block->find_remove(best); - add_inst(best); - cfg->map_node_to_block(best, this); + block->add_inst(best); + map_node_to_block(best, block); // Move the control dependence if (best->in(0) && best->in(0) == old_block->head()) - best->set_req(0, head()); + best->set_req(0, block->head()); // Check for flag-killing projections that also need to be hoisted // Should be DU safe because no edge updates. for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) { Node* n = best->fast_out(j); if( n->is_MachProj() ) { - cfg->get_block_for_node(n)->find_remove(n); - add_inst(n); - cfg->map_node_to_block(n, this); + get_block_for_node(n)->find_remove(n); + block->add_inst(n); + map_node_to_block(n, block); } } - Compile *C = cfg->C; // proj==Op_True --> ne test; proj==Op_False --> eq test. // One of two graph shapes got matched: // (IfTrue (If (Bool NE (CmpP ptr NULL)))) @@ -368,10 +367,10 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe // We need to flip the projections to keep the same semantics. if( proj->Opcode() == Op_IfTrue ) { // Swap order of projections in basic block to swap branch targets - Node *tmp1 = get_node(end_idx()+1); - Node *tmp2 = get_node(end_idx()+2); - _nodes.map(end_idx()+1, tmp2); - _nodes.map(end_idx()+2, tmp1); + Node *tmp1 = block->get_node(block->end_idx()+1); + Node *tmp2 = block->get_node(block->end_idx()+2); + block->map_node(tmp2, block->end_idx()+1); + block->map_node(tmp1, block->end_idx()+2); Node *tmp = new (C) Node(C->top()); // Use not NULL input tmp1->replace_by(tmp); tmp2->replace_by(tmp1); @@ -384,8 +383,8 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe // it as well. Node *old_tst = proj->in(0); MachNode *nul_chk = new (C) MachNullCheckNode(old_tst->in(0),best,bidx); - _nodes.map(end_idx(),nul_chk); - cfg->map_node_to_block(nul_chk, this); + block->map_node(nul_chk, block->end_idx()); + map_node_to_block(nul_chk, block); // Redirect users of old_test to nul_chk for (DUIterator_Last i2min, i2 = old_tst->last_outs(i2min); i2 >= i2min; --i2) old_tst->last_out(i2)->set_req(0, nul_chk); @@ -393,8 +392,8 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe for (uint i3 = 0; i3 < old_tst->req(); i3++) old_tst->set_req(i3, NULL); - cfg->latency_from_uses(nul_chk); - cfg->latency_from_uses(best); + latency_from_uses(nul_chk); + latency_from_uses(best); } @@ -408,7 +407,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe // remaining cases (most), choose the instruction with the greatest latency // (that is, the most number of pseudo-cycles required to the end of the // routine). If there is a tie, choose the instruction with the most inputs. -Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray &ready_cnt, VectorSet &next_call, uint sched_slot) { +Node* PhaseCFG::select(Block* block, Node_List &worklist, GrowableArray &ready_cnt, VectorSet &next_call, uint sched_slot) { // If only a single entry on the stack, use it uint cnt = worklist.size(); @@ -442,7 +441,7 @@ Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray &read } // Final call in a block must be adjacent to 'catch' - Node *e = end(); + Node *e = block->end(); if( e->is_Catch() && e->in(0)->in(0) == n ) continue; @@ -468,7 +467,7 @@ Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray &read Node* use = n->fast_out(j); // The use is a conditional branch, make them adjacent - if (use->is_MachIf() && cfg->get_block_for_node(use) == this) { + if (use->is_MachIf() && get_block_for_node(use) == block) { found_machif = true; break; } @@ -501,7 +500,7 @@ Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray &read n_choice = 1; } - uint n_latency = cfg->get_latency_for_node(n); + uint n_latency = get_latency_for_node(n); uint n_score = n->req(); // Many inputs get high score to break ties // Keep best latency found @@ -529,13 +528,13 @@ Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray &read //------------------------------set_next_call---------------------------------- -void Block::set_next_call( Node *n, VectorSet &next_call, PhaseCFG* cfg) { +void PhaseCFG::set_next_call(Block* block, Node* n, VectorSet& next_call) { if( next_call.test_set(n->_idx) ) return; for( uint i=0; ilen(); i++ ) { Node *m = n->in(i); if( !m ) continue; // must see all nodes in block that precede call - if (cfg->get_block_for_node(m) == this) { - set_next_call(m, next_call, cfg); + if (get_block_for_node(m) == block) { + set_next_call(block, m, next_call); } } } @@ -546,12 +545,12 @@ void Block::set_next_call( Node *n, VectorSet &next_call, PhaseCFG* cfg) { // next subroutine call get priority - basically it moves things NOT needed // for the next call till after the call. This prevents me from trying to // carry lots of stuff live across a call. -void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, PhaseCFG* cfg) { +void PhaseCFG::needed_for_next_call(Block* block, Node* this_call, VectorSet& next_call) { // Find the next control-defining Node in this block Node* call = NULL; for (DUIterator_Fast imax, i = this_call->fast_outs(imax); i < imax; i++) { Node* m = this_call->fast_out(i); - if(cfg->get_block_for_node(m) == this && // Local-block user + if(get_block_for_node(m) == block && // Local-block user m != this_call && // Not self-start node m->is_MachCall() ) call = m; @@ -559,11 +558,12 @@ void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, PhaseCFG } if (call == NULL) return; // No next call (e.g., block end is near) // Set next-call for all inputs to this call - set_next_call(call, next_call, cfg); + set_next_call(block, call, next_call); } //------------------------------add_call_kills------------------------------------- -void Block::add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe) { +// helper function that adds caller save registers to MachProjNode +static void add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe) { // Fill in the kill mask for the call for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) { if( !regs.Member(r) ) { // Not already defined by the call @@ -579,7 +579,7 @@ void Block::add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_p //------------------------------sched_call------------------------------------- -uint Block::sched_call( Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_List &worklist, GrowableArray &ready_cnt, MachCallNode *mcall, VectorSet &next_call ) { +uint PhaseCFG::sched_call(Block* block, uint node_cnt, Node_List& worklist, GrowableArray& ready_cnt, MachCallNode* mcall, VectorSet& next_call) { RegMask regs; // Schedule all the users of the call right now. All the users are @@ -592,18 +592,18 @@ uint Block::sched_call( Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_Lis ready_cnt.at_put(n->_idx, n_cnt); assert( n_cnt == 0, "" ); // Schedule next to call - _nodes.map(node_cnt++, n); + block->map_node(n, node_cnt++); // Collect defined registers regs.OR(n->out_RegMask()); // Check for scheduling the next control-definer if( n->bottom_type() == Type::CONTROL ) // Warm up next pile of heuristic bits - needed_for_next_call(n, next_call, cfg); + needed_for_next_call(block, n, next_call); // Children of projections are now all ready for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { Node* m = n->fast_out(j); // Get user - if(cfg->get_block_for_node(m) != this) { + if(get_block_for_node(m) != block) { continue; } if( m->is_Phi() ) continue; @@ -617,14 +617,14 @@ uint Block::sched_call( Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_Lis // Act as if the call defines the Frame Pointer. // Certainly the FP is alive and well after the call. - regs.Insert(matcher.c_frame_pointer()); + regs.Insert(_matcher.c_frame_pointer()); // Set all registers killed and not already defined by the call. uint r_cnt = mcall->tf()->range()->cnt(); int op = mcall->ideal_Opcode(); - MachProjNode *proj = new (matcher.C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj ); - cfg->map_node_to_block(proj, this); - insert_node(proj, node_cnt++); + MachProjNode *proj = new (C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj ); + map_node_to_block(proj, block); + block->insert_node(proj, node_cnt++); // Select the right register save policy. const char * save_policy; @@ -633,13 +633,13 @@ uint Block::sched_call( Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_Lis case Op_CallLeaf: case Op_CallLeafNoFP: // Calling C code so use C calling convention - save_policy = matcher._c_reg_save_policy; + save_policy = _matcher._c_reg_save_policy; break; case Op_CallStaticJava: case Op_CallDynamicJava: // Calling Java code so use Java calling convention - save_policy = matcher._register_save_policy; + save_policy = _matcher._register_save_policy; break; default: @@ -674,44 +674,46 @@ uint Block::sched_call( Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_Lis //------------------------------schedule_local--------------------------------- // Topological sort within a block. Someday become a real scheduler. -bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray &ready_cnt, VectorSet &next_call) { +bool PhaseCFG::schedule_local(Block* block, GrowableArray& ready_cnt, VectorSet& next_call) { // Already "sorted" are the block start Node (as the first entry), and // the block-ending Node and any trailing control projections. We leave // these alone. PhiNodes and ParmNodes are made to follow the block start // Node. Everything else gets topo-sorted. #ifndef PRODUCT - if (cfg->trace_opto_pipelining()) { - tty->print_cr("# --- schedule_local B%d, before: ---", _pre_order); - for (uint i = 0;i < _nodes.size();i++) { + if (trace_opto_pipelining()) { + tty->print_cr("# --- schedule_local B%d, before: ---", block->_pre_order); + for (uint i = 0;i < block->number_of_nodes(); i++) { tty->print("# "); - get_node(i)->fast_dump(); + block->get_node(i)->fast_dump(); } tty->print_cr("#"); } #endif // RootNode is already sorted - if( _nodes.size() == 1 ) return true; + if (block->number_of_nodes() == 1) { + return true; + } // Move PhiNodes and ParmNodes from 1 to cnt up to the start - uint node_cnt = end_idx(); + uint node_cnt = block->end_idx(); uint phi_cnt = 1; uint i; for( i = 1; iget_node(i); if( n->is_Phi() || // Found a PhiNode or ParmNode - (n->is_Proj() && n->in(0) == head()) ) { + (n->is_Proj() && n->in(0) == block->head()) ) { // Move guy at 'phi_cnt' to the end; makes a hole at phi_cnt - _nodes.map(i,get_node(phi_cnt)); - _nodes.map(phi_cnt++,n); // swap Phi/Parm up front + block->map_node(block->get_node(phi_cnt), i); + block->map_node(n, phi_cnt++); // swap Phi/Parm up front } else { // All others // Count block-local inputs to 'n' uint cnt = n->len(); // Input count uint local = 0; for( uint j=0; jin(j); - if( m && cfg->get_block_for_node(m) == this && !m->is_top() ) + if( m && get_block_for_node(m) == block && !m->is_top() ) local++; // One more block-local input } ready_cnt.at_put(n->_idx, local); // Count em up @@ -723,7 +725,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & for (uint prec = n->req(); prec < n->len(); prec++) { Node* oop_store = n->in(prec); if (oop_store != NULL) { - assert(cfg->get_block_for_node(oop_store)->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark"); + assert(get_block_for_node(oop_store)->_dom_depth <= block->_dom_depth, "oop_store must dominate card-mark"); } } } @@ -747,16 +749,16 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & } } } - for(uint i2=i; i2<_nodes.size(); i2++ ) // Trailing guys get zapped count - ready_cnt.at_put(get_node(i2)->_idx, 0); + for(uint i2=i; i2< block->number_of_nodes(); i2++ ) // Trailing guys get zapped count + ready_cnt.at_put(block->get_node(i2)->_idx, 0); // All the prescheduled guys do not hold back internal nodes uint i3; for(i3 = 0; i3get_node(i3); // Get pre-scheduled for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { Node* m = n->fast_out(j); - if (cfg->get_block_for_node(m) == this) { // Local-block user + if (get_block_for_node(m) == block) { // Local-block user int m_cnt = ready_cnt.at(m->_idx)-1; ready_cnt.at_put(m->_idx, m_cnt); // Fix ready count } @@ -767,7 +769,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & // Make a worklist Node_List worklist; for(uint i4=i3; i4get_node(i4); if( !ready_cnt.at(m->_idx) ) { // Zero ready count? if (m->is_iteratively_computed()) { // Push induction variable increments last to allow other uses @@ -789,15 +791,15 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & } // Warm up the 'next_call' heuristic bits - needed_for_next_call(head(), next_call, cfg); + needed_for_next_call(block, block->head(), next_call); #ifndef PRODUCT - if (cfg->trace_opto_pipelining()) { - for (uint j=0; j<_nodes.size(); j++) { - Node *n = get_node(j); + if (trace_opto_pipelining()) { + for (uint j=0; j< block->number_of_nodes(); j++) { + Node *n = block->get_node(j); int idx = n->_idx; tty->print("# ready cnt:%3d ", ready_cnt.at(idx)); - tty->print("latency:%3d ", cfg->get_latency_for_node(n)); + tty->print("latency:%3d ", get_latency_for_node(n)); tty->print("%4d: %s\n", idx, n->Name()); } } @@ -808,7 +810,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & while( worklist.size() ) { // Worklist is not ready #ifndef PRODUCT - if (cfg->trace_opto_pipelining()) { + if (trace_opto_pipelining()) { tty->print("# ready list:"); for( uint i=0; i & #endif // Select and pop a ready guy from worklist - Node* n = select(cfg, worklist, ready_cnt, next_call, phi_cnt); - _nodes.map(phi_cnt++,n); // Schedule him next + Node* n = select(block, worklist, ready_cnt, next_call, phi_cnt); + block->map_node(n, phi_cnt++); // Schedule him next #ifndef PRODUCT - if (cfg->trace_opto_pipelining()) { + if (trace_opto_pipelining()) { tty->print("# select %d: %s", n->_idx, n->Name()); - tty->print(", latency:%d", cfg->get_latency_for_node(n)); + tty->print(", latency:%d", get_latency_for_node(n)); n->dump(); if (Verbose) { tty->print("# ready list:"); @@ -840,26 +842,26 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & #endif if( n->is_MachCall() ) { MachCallNode *mcall = n->as_MachCall(); - phi_cnt = sched_call(matcher, cfg, phi_cnt, worklist, ready_cnt, mcall, next_call); + phi_cnt = sched_call(block, phi_cnt, worklist, ready_cnt, mcall, next_call); continue; } if (n->is_Mach() && n->as_Mach()->has_call()) { RegMask regs; - regs.Insert(matcher.c_frame_pointer()); + regs.Insert(_matcher.c_frame_pointer()); regs.OR(n->out_RegMask()); - MachProjNode *proj = new (matcher.C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); - cfg->map_node_to_block(proj, this); - insert_node(proj, phi_cnt++); + MachProjNode *proj = new (C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); + map_node_to_block(proj, block); + block->insert_node(proj, phi_cnt++); - add_call_kills(proj, regs, matcher._c_reg_save_policy, false); + add_call_kills(proj, regs, _matcher._c_reg_save_policy, false); } // Children are now all ready for (DUIterator_Fast i5max, i5 = n->fast_outs(i5max); i5 < i5max; i5++) { Node* m = n->fast_out(i5); // Get user - if (cfg->get_block_for_node(m) != this) { + if (get_block_for_node(m) != block) { continue; } if( m->is_Phi() ) continue; @@ -874,9 +876,8 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & } } - if( phi_cnt != end_idx() ) { + if( phi_cnt != block->end_idx() ) { // did not schedule all. Retry, Bailout, or Die - Compile* C = matcher.C; if (C->subsume_loads() == true && !C->failing()) { // Retry with subsume_loads == false // If this is the first failure, the sentinel string will "stick" @@ -888,12 +889,12 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & } #ifndef PRODUCT - if (cfg->trace_opto_pipelining()) { + if (trace_opto_pipelining()) { tty->print_cr("#"); tty->print_cr("# after schedule_local"); - for (uint i = 0;i < _nodes.size();i++) { + for (uint i = 0;i < block->number_of_nodes();i++) { tty->print("# "); - get_node(i)->fast_dump(); + block->get_node(i)->fast_dump(); } tty->cr(); } @@ -919,7 +920,7 @@ static void catch_cleanup_fix_all_inputs(Node *use, Node *old_def, Node *new_def } //------------------------------catch_cleanup_find_cloned_def------------------ -static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def_blk, PhaseCFG* cfg, int n_clone_idx) { +Node* PhaseCFG::catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def_blk, int n_clone_idx) { assert( use_blk != def_blk, "Inter-block cleanup only"); // The use is some block below the Catch. Find and return the clone of the def @@ -945,8 +946,8 @@ static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def // PhiNode, the PhiNode uses from the def and IT's uses need fixup. Node_Array inputs = new Node_List(Thread::current()->resource_area()); for(uint k = 1; k < use_blk->num_preds(); k++) { - Block* block = cfg->get_block_for_node(use_blk->pred(k)); - inputs.map(k, catch_cleanup_find_cloned_def(block, def, def_blk, cfg, n_clone_idx)); + Block* block = get_block_for_node(use_blk->pred(k)); + inputs.map(k, catch_cleanup_find_cloned_def(block, def, def_blk, n_clone_idx)); } // Check to see if the use_blk already has an identical phi inserted. @@ -968,7 +969,7 @@ static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def if (fixup == NULL) { Node *new_phi = PhiNode::make(use_blk->head(), def); use_blk->insert_node(new_phi, 1); - cfg->map_node_to_block(new_phi, use_blk); + map_node_to_block(new_phi, use_blk); for (uint k = 1; k < use_blk->num_preds(); k++) { new_phi->set_req(k, inputs[k]); } @@ -1008,25 +1009,25 @@ static void catch_cleanup_intra_block(Node *use, Node *def, Block *blk, int beg, //------------------------------catch_cleanup_inter_block--------------------- // Fix all input edges in use that reference "def". The use is in a different // block than the def. -static void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, PhaseCFG* cfg, int n_clone_idx) { +void PhaseCFG::catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, int n_clone_idx) { if( !use_blk ) return; // Can happen if the use is a precedence edge - Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, cfg, n_clone_idx); + Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, n_clone_idx); catch_cleanup_fix_all_inputs(use, def, new_def); } //------------------------------call_catch_cleanup----------------------------- // If we inserted any instructions between a Call and his CatchNode, // clone the instructions on all paths below the Catch. -void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { +void PhaseCFG::call_catch_cleanup(Block* block) { // End of region to clone - uint end = end_idx(); - if( !get_node(end)->is_Catch() ) return; + uint end = block->end_idx(); + if( !block->get_node(end)->is_Catch() ) return; // Start of region to clone uint beg = end; - while(!get_node(beg-1)->is_MachProj() || - !get_node(beg-1)->in(0)->is_MachCall() ) { + while(!block->get_node(beg-1)->is_MachProj() || + !block->get_node(beg-1)->in(0)->is_MachCall() ) { beg--; assert(beg > 0,"Catch cleanup walking beyond block boundary"); } @@ -1035,15 +1036,15 @@ void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { // Clone along all Catch output paths. Clone area between the 'beg' and // 'end' indices. - for( uint i = 0; i < _num_succs; i++ ) { - Block *sb = _succs[i]; + for( uint i = 0; i < block->_num_succs; i++ ) { + Block *sb = block->_succs[i]; // Clone the entire area; ignoring the edge fixup for now. for( uint j = end; j > beg; j-- ) { // It is safe here to clone a node with anti_dependence // since clones dominate on each path. - Node *clone = get_node(j-1)->clone(); + Node *clone = block->get_node(j-1)->clone(); sb->insert_node(clone, 1); - cfg->map_node_to_block(clone, sb); + map_node_to_block(clone, sb); } } @@ -1051,7 +1052,7 @@ void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { // Fixup edges. Check the def-use info per cloned Node for(uint i2 = beg; i2 < end; i2++ ) { uint n_clone_idx = i2-beg+1; // Index of clone of n in each successor block - Node *n = get_node(i2); // Node that got cloned + Node *n = block->get_node(i2); // Node that got cloned // Need DU safe iterator because of edge manipulation in calls. Unique_Node_List *out = new Unique_Node_List(Thread::current()->resource_area()); for (DUIterator_Fast j1max, j1 = n->fast_outs(j1max); j1 < j1max; j1++) { @@ -1060,19 +1061,19 @@ void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { uint max = out->size(); for (uint j = 0; j < max; j++) {// For all users Node *use = out->pop(); - Block *buse = cfg->get_block_for_node(use); + Block *buse = get_block_for_node(use); if( use->is_Phi() ) { for( uint k = 1; k < use->req(); k++ ) if( use->in(k) == n ) { - Block* block = cfg->get_block_for_node(buse->pred(k)); - Node *fixup = catch_cleanup_find_cloned_def(block, n, this, cfg, n_clone_idx); + Block* b = get_block_for_node(buse->pred(k)); + Node *fixup = catch_cleanup_find_cloned_def(b, n, block, n_clone_idx); use->set_req(k, fixup); } } else { - if (this == buse) { - catch_cleanup_intra_block(use, n, this, beg, n_clone_idx); + if (block == buse) { + catch_cleanup_intra_block(use, n, block, beg, n_clone_idx); } else { - catch_cleanup_inter_block(use, buse, n, this, cfg, n_clone_idx); + catch_cleanup_inter_block(use, buse, n, block, n_clone_idx); } } } // End for all users @@ -1081,13 +1082,13 @@ void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { // Remove the now-dead cloned ops for(uint i3 = beg; i3 < end; i3++ ) { - get_node(beg)->disconnect_inputs(NULL, C); - remove_node(beg); + block->get_node(beg)->disconnect_inputs(NULL, C); + block->remove_node(beg); } // If the successor blocks have a CreateEx node, move it back to the top - for(uint i4 = 0; i4 < _num_succs; i4++ ) { - Block *sb = _succs[i4]; + for(uint i4 = 0; i4 < block->_num_succs; i4++ ) { + Block *sb = block->_succs[i4]; uint new_cnt = end - beg; // Remove any newly created, but dead, nodes. for( uint j = new_cnt; j > 0; j-- ) { From b59dc6762ed4fd9fa1d9285cdf8d1bc6e9277fa1 Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Fri, 13 Sep 2013 11:18:44 -0700 Subject: [PATCH 0168/1294] 8021591: Additional explicit null checks Reviewed-by: psandoz, alanb --- .../share/classes/java/util/Collections.java | 1 + .../share/classes/java/util/Hashtable.java | 3 + .../classes/java/util/IdentityHashMap.java | 2 + jdk/src/share/classes/java/util/Map.java | 9 +- jdk/src/share/classes/java/util/TreeMap.java | 2 +- .../util/concurrent/ConcurrentHashMap.java | 3 + .../classes/javax/security/auth/Subject.java | 4 +- .../util/Collection/CollectionDefaults.java | 108 ++++-- jdk/test/java/util/Collection/MOAT.java | 2 - .../testlibrary/CollectionAsserts.java | 58 ++-- .../testlibrary/CollectionSupplier.java | 309 +++++++----------- .../ExtendsAbstractCollection.java | 86 +++++ .../testlibrary/ExtendsAbstractList.java | 101 ++++++ .../testlibrary/ExtendsAbstractSet.java | 85 +++++ .../{Collection => List}/ListDefaults.java | 95 +++--- jdk/test/java/util/Map/Defaults.java | 46 ++- 16 files changed, 604 insertions(+), 310 deletions(-) create mode 100644 jdk/test/java/util/Collection/testlibrary/ExtendsAbstractCollection.java create mode 100644 jdk/test/java/util/Collection/testlibrary/ExtendsAbstractList.java create mode 100644 jdk/test/java/util/Collection/testlibrary/ExtendsAbstractSet.java rename jdk/test/java/util/{Collection => List}/ListDefaults.java (88%) diff --git a/jdk/src/share/classes/java/util/Collections.java b/jdk/src/share/classes/java/util/Collections.java index 2404b4fc9ad..947b6282db4 100644 --- a/jdk/src/share/classes/java/util/Collections.java +++ b/jdk/src/share/classes/java/util/Collections.java @@ -3900,6 +3900,7 @@ public class Collections { return batchRemove(c, true); } private boolean batchRemove(Collection c, boolean complement) { + Objects.requireNonNull(c); boolean modified = false; Iterator> it = iterator(); while (it.hasNext()) { diff --git a/jdk/src/share/classes/java/util/Hashtable.java b/jdk/src/share/classes/java/util/Hashtable.java index dc50e9393ee..b97a8e361bb 100644 --- a/jdk/src/share/classes/java/util/Hashtable.java +++ b/jdk/src/share/classes/java/util/Hashtable.java @@ -957,6 +957,8 @@ public class Hashtable @Override public synchronized boolean replace(K key, V oldValue, V newValue) { + Objects.requireNonNull(oldValue); + Objects.requireNonNull(newValue); Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @@ -977,6 +979,7 @@ public class Hashtable @Override public synchronized V replace(K key, V value) { + Objects.requireNonNull(value); Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; diff --git a/jdk/src/share/classes/java/util/IdentityHashMap.java b/jdk/src/share/classes/java/util/IdentityHashMap.java index a4bdc4b9efd..40808213894 100644 --- a/jdk/src/share/classes/java/util/IdentityHashMap.java +++ b/jdk/src/share/classes/java/util/IdentityHashMap.java @@ -997,6 +997,7 @@ public class IdentityHashMap * behavior when c is a smaller "normal" (non-identity-based) Set. */ public boolean removeAll(Collection c) { + Objects.requireNonNull(c); boolean modified = false; for (Iterator i = iterator(); i.hasNext(); ) { if (c.contains(i.next())) { @@ -1212,6 +1213,7 @@ public class IdentityHashMap * behavior when c is a smaller "normal" (non-identity-based) Set. */ public boolean removeAll(Collection c) { + Objects.requireNonNull(c); boolean modified = false; for (Iterator> i = iterator(); i.hasNext(); ) { if (c.contains(i.next())) { diff --git a/jdk/src/share/classes/java/util/Map.java b/jdk/src/share/classes/java/util/Map.java index 321233e6f8d..4340e6d9c8f 100644 --- a/jdk/src/share/classes/java/util/Map.java +++ b/jdk/src/share/classes/java/util/Map.java @@ -805,6 +805,10 @@ public interface Map { * return false; * } * + * The default implementation does not throw NullPointerException + * for maps that do not support null values if oldValue is null unless + * newValue is also null. + * * @param key key with which the specified value is associated * @param oldValue value expected to be associated with the specified key * @param newValue value to be associated with the specified key @@ -814,8 +818,11 @@ public interface Map { * (optional) * @throws ClassCastException if the class of a specified key or value * prevents it from being stored in this map - * @throws NullPointerException if a specified key or value is null, + * @throws NullPointerException if a specified key or newValue is null, * and this map does not permit null keys or values + * @throws NullPointerException if oldValue is null and this map does not + * permit null values + * (optional) * @throws IllegalArgumentException if some property of a specified key * or value prevents it from being stored in this map * @since 1.8 diff --git a/jdk/src/share/classes/java/util/TreeMap.java b/jdk/src/share/classes/java/util/TreeMap.java index 9a4681d771a..740456b7ecb 100644 --- a/jdk/src/share/classes/java/util/TreeMap.java +++ b/jdk/src/share/classes/java/util/TreeMap.java @@ -1012,7 +1012,7 @@ public class TreeMap int expectedModCount = modCount; for (Entry e = getFirstEntry(); e != null; e = successor(e)) { - e.value = Objects.requireNonNull(function.apply(e.key, e.value)); + e.value = function.apply(e.key, e.value); if (expectedModCount != modCount) { throw new ConcurrentModificationException(); diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java index 1936e244946..9476bc411ba 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -49,6 +49,7 @@ import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; +import java.util.Objects; import java.util.Set; import java.util.Spliterator; import java.util.concurrent.ConcurrentMap; @@ -4410,6 +4411,7 @@ public class ConcurrentHashMap extends AbstractMap } public final boolean removeAll(Collection c) { + Objects.requireNonNull(c); boolean modified = false; for (Iterator it = iterator(); it.hasNext();) { if (c.contains(it.next())) { @@ -4421,6 +4423,7 @@ public class ConcurrentHashMap extends AbstractMap } public final boolean retainAll(Collection c) { + Objects.requireNonNull(c); boolean modified = false; for (Iterator it = iterator(); it.hasNext();) { if (!c.contains(it.next())) { diff --git a/jdk/src/share/classes/javax/security/auth/Subject.java b/jdk/src/share/classes/javax/security/auth/Subject.java index d5e4240a40a..ba6bda71f66 100644 --- a/jdk/src/share/classes/javax/security/auth/Subject.java +++ b/jdk/src/share/classes/javax/security/auth/Subject.java @@ -1186,7 +1186,7 @@ public final class Subject implements java.io.Serializable { } public boolean removeAll(Collection c) { - + Objects.requireNonNull(c); boolean modified = false; final Iterator e = iterator(); while (e.hasNext()) { @@ -1222,7 +1222,7 @@ public final class Subject implements java.io.Serializable { } public boolean retainAll(Collection c) { - + Objects.requireNonNull(c); boolean modified = false; boolean retain = false; final Iterator e = iterator(); diff --git a/jdk/test/java/util/Collection/CollectionDefaults.java b/jdk/test/java/util/Collection/CollectionDefaults.java index 36fd8da5469..594b67adae8 100644 --- a/jdk/test/java/util/Collection/CollectionDefaults.java +++ b/jdk/test/java/util/Collection/CollectionDefaults.java @@ -21,15 +21,19 @@ * questions. */ +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; +import java.util.SortedSet; + import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -38,43 +42,68 @@ import static org.testng.Assert.fail; import java.util.TreeMap; import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListMap; import java.util.function.Predicate; +import java.util.function.Supplier; /** * @test - * @library testlibrary - * @build CollectionAsserts CollectionSupplier - * @run testng CollectionDefaults * @summary Unit tests for extension methods on Collection + * @library testlibrary + * @build CollectionAsserts CollectionSupplier ExtendsAbstractSet ExtendsAbstractCollection + * @run testng CollectionDefaults */ public class CollectionDefaults { public static final Predicate pEven = x -> 0 == x % 2; public static final Predicate pOdd = x -> 1 == x % 2; - private static final String[] SET_CLASSES = { - "java.util.HashSet", - "java.util.LinkedHashSet", - "java.util.TreeSet" + @SuppressWarnings("unchecked") + private static final Supplier[] TEST_CLASSES = { + // Collection + ExtendsAbstractCollection::new, + + // Lists + java.util.ArrayList::new, + java.util.LinkedList::new, + java.util.Vector::new, + java.util.concurrent.CopyOnWriteArrayList::new, + ExtendsAbstractList::new, + + // Sets + java.util.HashSet::new, + java.util.LinkedHashSet::new, + java.util.TreeSet::new, + java.util.concurrent.ConcurrentSkipListSet::new, + java.util.concurrent.CopyOnWriteArraySet::new, + ExtendsAbstractSet::new }; private static final int SIZE = 100; @DataProvider(name="setProvider", parallel=true) - public static Object[][] setCases() { + public static Iterator setCases() { final List cases = new LinkedList<>(); cases.add(new Object[] { new HashSet<>() }); cases.add(new Object[] { new LinkedHashSet<>() }); cases.add(new Object[] { new TreeSet<>() }); + cases.add(new Object[] { new java.util.concurrent.ConcurrentSkipListSet<>() }); + cases.add(new Object[] { new java.util.concurrent.CopyOnWriteArraySet<>() }); + + cases.add(new Object[] { new ExtendsAbstractSet<>() }); cases.add(new Object[] { Collections.newSetFromMap(new HashMap<>()) }); cases.add(new Object[] { Collections.newSetFromMap(new LinkedHashMap()) }); cases.add(new Object[] { Collections.newSetFromMap(new TreeMap<>()) }); + cases.add(new Object[] { Collections.newSetFromMap(new ConcurrentHashMap<>()) }); + cases.add(new Object[] { Collections.newSetFromMap(new ConcurrentSkipListMap<>()) }); - cases.add(new Object[] { new HashSet(){{add(42);}} }); - cases.add(new Object[] { new LinkedHashSet(){{add(42);}} }); - cases.add(new Object[] { new TreeSet(){{add(42);}} }); - return cases.toArray(new Object[0][cases.size()]); + cases.add(new Object[] { new HashSet(){{add(42);}} }); + cases.add(new Object[] { new ExtendsAbstractSet(){{add(42);}} }); + cases.add(new Object[] { new LinkedHashSet(){{add(42);}} }); + cases.add(new Object[] { new TreeSet(){{add(42);}} }); + return cases.iterator(); } @Test(dataProvider = "setProvider") @@ -82,57 +111,66 @@ public class CollectionDefaults { try { set.forEach(null); fail("expected NPE not thrown"); - } catch (NullPointerException npe) {} + } catch (NullPointerException expected) { + ; // expected + } try { set.removeIf(null); fail("expected NPE not thrown"); - } catch (NullPointerException npe) {} + } catch (NullPointerException expected) { + ; // expected + } } @Test public void testForEach() throws Exception { - final CollectionSupplier supplier = new CollectionSupplier(SET_CLASSES, SIZE); - for (final CollectionSupplier.TestCase test : supplier.get()) { - final Set original = ((Set) test.original); - final Set set = ((Set) test.collection); + final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[]) TEST_CLASSES, SIZE); + + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final Collection original = test.expected; + final Collection set = test.collection; try { set.forEach(null); fail("expected NPE not thrown"); - } catch (NullPointerException npe) {} - if (test.className.equals("java.util.HashSet")) { - CollectionAsserts.assertContentsUnordered(set, original); + } catch (NullPointerException expected) { + ; // expected + } + if (set instanceof Set && !((set instanceof SortedSet) || (set instanceof LinkedHashSet))) { + CollectionAsserts.assertContentsUnordered(set, original, test.toString()); } else { - CollectionAsserts.assertContents(set, original); + CollectionAsserts.assertContents(set, original, test.toString()); } final List actual = new LinkedList<>(); set.forEach(actual::add); - if (test.className.equals("java.util.HashSet")) { - CollectionAsserts.assertContentsUnordered(actual, set); - CollectionAsserts.assertContentsUnordered(actual, original); + if (set instanceof Set && !((set instanceof SortedSet) || (set instanceof LinkedHashSet))) { + CollectionAsserts.assertContentsUnordered(actual, set, test.toString()); + CollectionAsserts.assertContentsUnordered(actual, original, test.toString()); } else { - CollectionAsserts.assertContents(actual, set); - CollectionAsserts.assertContents(actual, original); + CollectionAsserts.assertContents(actual, set, test.toString()); + CollectionAsserts.assertContents(actual, original, test.toString()); } } } @Test public void testRemoveIf() throws Exception { - final CollectionSupplier supplier = new CollectionSupplier(SET_CLASSES, SIZE); - for (final CollectionSupplier.TestCase test : supplier.get()) { - final Set original = ((Set) test.original); - final Set set = ((Set) test.collection); + final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[]) TEST_CLASSES, SIZE); + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final Collection original = test.expected; + final Collection set = test.collection; try { set.removeIf(null); fail("expected NPE not thrown"); - } catch (NullPointerException npe) {} - if (test.className.equals("java.util.HashSet")) { - CollectionAsserts.assertContentsUnordered(set, original); + } catch (NullPointerException expected) { + ; // expected + } + if (set instanceof Set && !((set instanceof SortedSet) || (set instanceof LinkedHashSet))) { + CollectionAsserts.assertContentsUnordered(set, original, test.toString()); } else { - CollectionAsserts.assertContents(set, original); + CollectionAsserts.assertContents(set, original, test.toString()); } set.removeIf(pEven); diff --git a/jdk/test/java/util/Collection/MOAT.java b/jdk/test/java/util/Collection/MOAT.java index 37720016c3c..a039461e2b7 100644 --- a/jdk/test/java/util/Collection/MOAT.java +++ b/jdk/test/java/util/Collection/MOAT.java @@ -400,8 +400,6 @@ public class MOAT { // If add(null) succeeds, contains(null) & remove(null) should succeed //---------------------------------------------------------------- private static void testNullElement(Collection c) { - // !!!! 5018849: (coll) TreeSet.contains(null) does not agree with Javadoc - if (c instanceof TreeSet) return; try { check(c.add(null)); diff --git a/jdk/test/java/util/Collection/testlibrary/CollectionAsserts.java b/jdk/test/java/util/Collection/testlibrary/CollectionAsserts.java index a03f975152e..575dc796204 100644 --- a/jdk/test/java/util/Collection/testlibrary/CollectionAsserts.java +++ b/jdk/test/java/util/Collection/testlibrary/CollectionAsserts.java @@ -41,6 +41,10 @@ import static org.testng.Assert.fail; */ public class CollectionAsserts { + private CollectionAsserts() { + // no instances + } + public static void assertCountSum(Iterable it, int count, int sum) { assertCountSum(it.iterator(), count, sum); } @@ -117,10 +121,18 @@ public class CollectionAsserts { } public static void assertContents(Iterable actual, Iterable expected) { - assertContents(actual.iterator(), expected.iterator()); + assertContents(actual, expected, null); + } + + public static void assertContents(Iterable actual, Iterable expected, String msg) { + assertContents(actual.iterator(), expected.iterator(), msg); } public static void assertContents(Iterator actual, Iterator expected) { + assertContents(actual, expected, null); + } + + public static void assertContents(Iterator actual, Iterator expected, String msg) { List history = new ArrayList<>(); while (expected.hasNext()) { @@ -128,20 +140,23 @@ public class CollectionAsserts { List expectedData = new ArrayList<>(history); while (expected.hasNext()) expectedData.add(expected.next()); - fail(String.format("Premature end of data; expected=%s, found=%s", expectedData, history)); + fail(String.format("%s Premature end of data; expected=%s, found=%s", + (msg == null ? "" : msg), expectedData, history)); } T a = actual.next(); T e = expected.next(); history.add(a); if (!Objects.equals(a, e)) - fail(String.format("Data mismatch; preceding=%s, nextExpected=%s, nextFound=%s", history, e, a)); + fail(String.format("%s Data mismatch; preceding=%s, nextExpected=%s, nextFound=%s", + (msg == null ? "" : msg), history, e, a)); } if (actual.hasNext()) { List rest = new ArrayList<>(); while (actual.hasNext()) rest.add(actual.next()); - fail(String.format("Unexpected data %s after %s", rest, history)); + fail(String.format("%s Unexpected data %s after %s", + (msg == null ? "" : msg), rest, history)); } } @@ -151,30 +166,21 @@ public class CollectionAsserts { assertContents(actual, Arrays.asList(expected).iterator()); } - public static boolean equalsContentsUnordered(Iterable a, Iterable b) { - Set sa = new HashSet<>(); - for (T t : a) { - sa.add(t); - } - - Set sb = new HashSet<>(); - for (T t : b) { - sb.add(t); - } - - return Objects.equals(sa, sb); + public static> void assertContentsUnordered(Iterable actual, Iterable expected) { + assertContentsUnordered(actual, expected, null); } - public static> void assertContentsUnordered(Iterable actual, Iterable expected) { - ArrayList one = new ArrayList<>(); - for (T t : actual) - one.add(t); - ArrayList two = new ArrayList<>(); - for (T t : expected) - two.add(t); - Collections.sort(one); - Collections.sort(two); - assertContents(one, two); + public static> void assertContentsUnordered(Iterable actual, Iterable expected, String msg) { + List allExpected = new ArrayList<>(); + for (T t : expected) { + allExpected.add(t); + } + + for (T t : actual) { + assertTrue(allExpected.remove(t), msg + " element '" + String.valueOf(t) + "' not found"); + } + + assertTrue(allExpected.isEmpty(), msg + "expected contained additional elements"); } static void assertSplitContents(Iterable> splits, Iterable list) { diff --git a/jdk/test/java/util/Collection/testlibrary/CollectionSupplier.java b/jdk/test/java/util/Collection/testlibrary/CollectionSupplier.java index c26aaa7385f..37b3e53739c 100644 --- a/jdk/test/java/util/Collection/testlibrary/CollectionSupplier.java +++ b/jdk/test/java/util/Collection/testlibrary/CollectionSupplier.java @@ -29,13 +29,11 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Random; -import java.util.Set; import org.testng.TestException; import static org.testng.Assert.assertTrue; -import java.lang.reflect.Constructor; import java.util.Collection; import java.util.Collections; import java.util.function.Supplier; @@ -44,73 +42,61 @@ import java.util.function.Supplier; * @library * @summary A Supplier of test cases for Collection tests */ -public final class CollectionSupplier implements Supplier> { +public final class CollectionSupplier> implements Supplier>> { - private final String[] classNames; + private final Supplier[] classes; private final int size; /** * A Collection test case. */ - public static final class TestCase { + public static final class TestCase> { /** * The name of the test case. */ public final String name; - /** - * Class name of the instantiated Collection. - */ - public final String className; - /** * Unmodifiable reference collection, useful for comparisons. */ - public final Collection original; + public final List expected; /** * A modifiable test collection. */ - public final Collection collection; + public final C collection; /** * Create a Collection test case. + * * @param name name of the test case - * @param className class name of the instantiated collection - * @param original reference collection + * @param expected reference collection * @param collection the modifiable test collection */ - public TestCase(String name, String className, - Collection original, Collection collection) { + public TestCase(String name, C collection) { this.name = name; - this.className = className; - this.original = - List.class.isAssignableFrom(original.getClass()) ? - Collections.unmodifiableList((List) original) : - Set.class.isAssignableFrom(original.getClass()) ? - Collections.unmodifiableSet((Set) original) : - Collections.unmodifiableCollection(original); + this.expected = Collections.unmodifiableList( + Arrays.asList(collection.toArray(new Integer[0]))); this.collection = collection; } @Override public String toString() { - return name + " " + className + - "\n original: " + original + - "\n target: " + collection; + return name + " " + collection.getClass().toString(); } } /** * Shuffle a list using a PRNG with known seed for repeatability + * * @param list the list to be shuffled */ public static void shuffle(final List list) { // PRNG with known seed for repeatable tests final Random prng = new Random(13); final int size = list.size(); - for (int i=0; i < size; i++) { + for (int i = 0; i < size; i++) { // random index in interval [i, size) final int j = i + prng.nextInt(size - i); // swap elements at indices i & j @@ -127,178 +113,133 @@ public final class CollectionSupplier implements Supplier[] classes, int size) { + this.classes = Arrays.copyOf(classes, classes.length); this.size = size; } @Override - public Iterable get() { - try { - return getThrows(); - } catch (Exception e) { - throw new TestException(e); - } - } + public Iterable> get() { + final Collection> cases = new LinkedList<>(); + for (final Supplier type : classes) { + try { + final Collection empty = type.get(); + cases.add(new TestCase("empty", empty)); - private Iterable getThrows() throws Exception { - final Collection collections = new LinkedList<>(); - for (final String className : classNames) { - @SuppressWarnings("unchecked") - final Class> type = - (Class>) Class.forName(className); - final Constructor> - defaultConstructor = type.getConstructor(); - final Constructor> - copyConstructor = type.getConstructor(Collection.class); + final Collection single = type.get(); + single.add(42); + cases.add(new TestCase("single", single)); - final Collection empty = defaultConstructor.newInstance(); - collections.add(new TestCase("empty", - className, - copyConstructor.newInstance(empty), - empty)); - - final Collection single = defaultConstructor.newInstance(); - single.add(42); - collections.add(new TestCase("single", - className, - copyConstructor.newInstance(single), - single)); - - final Collection regular = defaultConstructor.newInstance(); - for (int i=0; i < size; i++) { - regular.add(i); - } - collections.add(new TestCase("regular", - className, - copyConstructor.newInstance(regular), - regular)); - - final Collection reverse = defaultConstructor.newInstance(); - for (int i=size; i >= 0; i--) { - reverse.add(i); - } - collections.add(new TestCase("reverse", - className, - copyConstructor.newInstance(reverse), - reverse)); - - final Collection odds = defaultConstructor.newInstance(); - for (int i=0; i < size; i++) { - odds.add((i * 2) + 1); - } - collections.add(new TestCase("odds", - className, - copyConstructor.newInstance(odds), - odds)); - - final Collection evens = defaultConstructor.newInstance(); - for (int i=0; i < size; i++) { - evens.add(i * 2); - } - collections.add(new TestCase("evens", - className, - copyConstructor.newInstance(evens), - evens)); - - final Collection fibonacci = defaultConstructor.newInstance(); - int prev2 = 0; - int prev1 = 1; - for (int i=0; i < size; i++) { - final int n = prev1 + prev2; - if (n < 0) { // stop on overflow - break; + final Collection regular = type.get(); + for (int i = 0; i < size; i++) { + regular.add(i); } - fibonacci.add(n); - prev2 = prev1; - prev1 = n; - } - collections.add(new TestCase("fibonacci", - className, - copyConstructor.newInstance(fibonacci), - fibonacci)); + cases.add(new TestCase("regular", regular)); + + final Collection reverse = type.get(); + for (int i = size; i >= 0; i--) { + reverse.add(i); + } + cases.add(new TestCase("reverse", reverse)); + + final Collection odds = type.get(); + for (int i = 0; i < size; i++) { + odds.add((i * 2) + 1); + } + cases.add(new TestCase("odds", odds)); + + final Collection evens = type.get(); + for (int i = 0; i < size; i++) { + evens.add(i * 2); + } + cases.add(new TestCase("evens", evens)); + + final Collection fibonacci = type.get(); + int prev2 = 0; + int prev1 = 1; + for (int i = 0; i < size; i++) { + final int n = prev1 + prev2; + if (n < 0) { // stop on overflow + break; + } + fibonacci.add(n); + prev2 = prev1; + prev1 = n; + } + cases.add(new TestCase("fibonacci", fibonacci)); // variants where the size of the backing storage != reported size - // created by removing half of the elements + // created by removing half of the elements + final Collection emptyWithSlack = type.get(); + emptyWithSlack.add(42); + assertTrue(emptyWithSlack.remove(42)); + cases.add(new TestCase("emptyWithSlack", emptyWithSlack)); - final Collection emptyWithSlack = defaultConstructor.newInstance(); - emptyWithSlack.add(42); - assertTrue(emptyWithSlack.remove(42)); - collections.add(new TestCase("emptyWithSlack", - className, - copyConstructor.newInstance(emptyWithSlack), - emptyWithSlack)); + final Collection singleWithSlack = type.get(); + singleWithSlack.add(42); + singleWithSlack.add(43); + assertTrue(singleWithSlack.remove(43)); + cases.add(new TestCase("singleWithSlack", singleWithSlack)); - final Collection singleWithSlack = defaultConstructor.newInstance(); - singleWithSlack.add(42); - singleWithSlack.add(43); - assertTrue(singleWithSlack.remove(43)); - collections.add(new TestCase("singleWithSlack", - className, - copyConstructor.newInstance(singleWithSlack), - singleWithSlack)); - - final Collection regularWithSlack = defaultConstructor.newInstance(); - for (int i=0; i < (2 * size); i++) { - regularWithSlack.add(i); - } - assertTrue(regularWithSlack.removeIf((x) -> {return x >= size;})); - collections.add(new TestCase("regularWithSlack", - className, - copyConstructor.newInstance(regularWithSlack), - regularWithSlack)); - - final Collection reverseWithSlack = defaultConstructor.newInstance(); - for (int i=2 * size; i >= 0; i--) { - reverseWithSlack.add(i); - } - assertTrue(reverseWithSlack.removeIf((x) -> {return x < size;})); - collections.add(new TestCase("reverseWithSlack", - className, - copyConstructor.newInstance(reverseWithSlack), - reverseWithSlack)); - - final Collection oddsWithSlack = defaultConstructor.newInstance(); - for (int i = 0; i < 2 * size; i++) { - oddsWithSlack.add((i * 2) + 1); - } - assertTrue(oddsWithSlack.removeIf((x) -> {return x >= size;})); - collections.add(new TestCase("oddsWithSlack", - className, - copyConstructor.newInstance(oddsWithSlack), - oddsWithSlack)); - - final Collection evensWithSlack = defaultConstructor.newInstance(); - for (int i = 0; i < 2 * size; i++) { - evensWithSlack.add(i * 2); - } - assertTrue(evensWithSlack.removeIf((x) -> {return x >= size;})); - collections.add(new TestCase("evensWithSlack", - className, - copyConstructor.newInstance(evensWithSlack), - evensWithSlack)); - - final Collection fibonacciWithSlack = defaultConstructor.newInstance(); - prev2 = 0; - prev1 = 1; - for (int i=0; i < size; i++) { - final int n = prev1 + prev2; - if (n < 0) { // stop on overflow - break; + final Collection regularWithSlack = type.get(); + for (int i = 0; i < (2 * size); i++) { + regularWithSlack.add(i); } - fibonacciWithSlack.add(n); - prev2 = prev1; - prev1 = n; - } - assertTrue(fibonacciWithSlack.removeIf((x) -> {return x < 20;})); - collections.add(new TestCase("fibonacciWithSlack", - className, - copyConstructor.newInstance(fibonacciWithSlack), - fibonacciWithSlack)); + assertTrue(regularWithSlack.removeIf((x) -> { + return x >= size; + })); + cases.add(new TestCase("regularWithSlack", regularWithSlack)); + final Collection reverseWithSlack = type.get(); + for (int i = 2 * size; i >= 0; i--) { + reverseWithSlack.add(i); + } + assertTrue(reverseWithSlack.removeIf((x) -> { + return x < size; + })); + cases.add(new TestCase("reverseWithSlack", reverseWithSlack)); + + final Collection oddsWithSlack = type.get(); + for (int i = 0; i < 2 * size; i++) { + oddsWithSlack.add((i * 2) + 1); + } + assertTrue(oddsWithSlack.removeIf((x) -> { + return x >= size; + })); + cases.add(new TestCase("oddsWithSlack", oddsWithSlack)); + + final Collection evensWithSlack = type.get(); + for (int i = 0; i < 2 * size; i++) { + evensWithSlack.add(i * 2); + } + assertTrue(evensWithSlack.removeIf((x) -> { + return x >= size; + })); + cases.add(new TestCase("evensWithSlack", evensWithSlack)); + + final Collection fibonacciWithSlack = type.get(); + prev2 = 0; + prev1 = 1; + for (int i = 0; i < size; i++) { + final int n = prev1 + prev2; + if (n < 0) { // stop on overflow + break; + } + fibonacciWithSlack.add(n); + prev2 = prev1; + prev1 = n; + } + assertTrue(fibonacciWithSlack.removeIf((x) -> { + return x < 20; + })); + cases.add(new TestCase("fibonacciWithSlack", + fibonacciWithSlack)); + } catch (Exception failed) { + throw new TestException(failed); + } } - return collections; + return cases; } } diff --git a/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractCollection.java b/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractCollection.java new file mode 100644 index 00000000000..a22d3d75d15 --- /dev/null +++ b/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractCollection.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.util.AbstractCollection; +import java.util.HashSet; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.function.Supplier; + +/** + * @library + * + * A simple mutable collection implementation that provides only default + * implementations of all methods. ie. none of the Collection interface default + * methods have overridden implementations. + * + * @param type of collection elements + */ +public class ExtendsAbstractCollection extends AbstractCollection { + + protected final Collection coll; + + public ExtendsAbstractCollection() { + this(ArrayList::new); + } + + public ExtendsAbstractCollection(Collection source) { + this(); + coll.addAll(source); + } + + protected ExtendsAbstractCollection(Supplier> backer) { + this.coll = backer.get(); + } + + public boolean add(E element) { + return coll.add(element); + } + + public boolean remove(Object element) { + return coll.remove(element); + } + + public Iterator iterator() { + return new Iterator() { + Iterator source = coll.iterator(); + + public boolean hasNext() { + return source.hasNext(); + } + + public E next() { + return source.next(); + } + + public void remove() { + source.remove(); + } + }; + } + + public int size() { + return coll.size(); + } +} diff --git a/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractList.java b/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractList.java new file mode 100644 index 00000000000..fb2af523d44 --- /dev/null +++ b/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractList.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.util.ArrayList; +import java.util.AbstractList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.function.Supplier; + +/** + * @library + * + * A simple mutable list implementation that provides only default + * implementations of all methods. ie. none of the List interface default + * methods have overridden implementations. + * + * @param type of list elements + */ +public class ExtendsAbstractList extends AbstractList { + + protected final List list; + + public ExtendsAbstractList() { + this(ArrayList::new); + } + + protected ExtendsAbstractList(Supplier> supplier) { + this.list = supplier.get(); + } + + public ExtendsAbstractList(Collection source) { + this(); + addAll(source); + } + + public boolean add(E element) { + return list.add(element); + } + + public E get(int index) { + return list.get(index); + } + + public boolean remove(Object element) { + return list.remove(element); + } + + public E set(int index, E element) { + return list.set(index, element); + } + + public void add(int index, E element) { + list.add(index, element); + } + + public E remove(int index) { + return list.remove(index); + } + + public Iterator iterator() { + return new Iterator() { + Iterator source = list.iterator(); + + public boolean hasNext() { + return source.hasNext(); + } + + public E next() { + return source.next(); + } + + public void remove() { + source.remove(); + } + }; + } + + public int size() { + return list.size(); + } +} diff --git a/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractSet.java b/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractSet.java new file mode 100644 index 00000000000..23661a357a9 --- /dev/null +++ b/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractSet.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.util.HashSet; +import java.util.AbstractSet; +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; +import java.util.function.Supplier; + +/** + * @library + * + * A simple mutable set implementation that provides only default + * implementations of all methods. ie. none of the Set interface default methods + * have overridden implementations. + * + * @param type of set members + */ +public class ExtendsAbstractSet extends AbstractSet { + + protected final Set set; + + public ExtendsAbstractSet() { + this(HashSet::new); + } + + public ExtendsAbstractSet(Collection source) { + this(); + addAll(source); + } + + protected ExtendsAbstractSet(Supplier> backer) { + this.set = backer.get(); + } + + public boolean add(E element) { + return set.add(element); + } + + public boolean remove(Object element) { + return set.remove(element); + } + + public Iterator iterator() { + return new Iterator() { + Iterator source = set.iterator(); + + public boolean hasNext() { + return source.hasNext(); + } + + public E next() { + return source.next(); + } + + public void remove() { + source.remove(); + } + }; + } + + public int size() { + return set.size(); + } +} diff --git a/jdk/test/java/util/Collection/ListDefaults.java b/jdk/test/java/util/List/ListDefaults.java similarity index 88% rename from jdk/test/java/util/Collection/ListDefaults.java rename to jdk/test/java/util/List/ListDefaults.java index 0d7a29152f6..76734b4e4be 100644 --- a/jdk/test/java/util/Collection/ListDefaults.java +++ b/jdk/test/java/util/List/ListDefaults.java @@ -28,8 +28,6 @@ import java.util.Comparator; import java.util.List; import java.util.LinkedList; import java.util.Stack; -import java.util.TreeMap; -import java.util.TreeSet; import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicBoolean; @@ -46,28 +44,30 @@ import static org.testng.Assert.fail; import java.lang.reflect.Constructor; import java.util.ConcurrentModificationException; import java.util.function.Predicate; +import java.util.function.Supplier; /** * @test - * @bug 8023367 - * @library testlibrary - * @build CollectionAsserts CollectionSupplier - * @run testng ListDefaults * @summary Unit tests for extension methods on List + * @bug 8023367 + * @library ../Collection/testlibrary + * @build CollectionAsserts CollectionSupplier ExtendsAbstractList + * @run testng ListDefaults */ public class ListDefaults { - private static final String[] LIST_CLASSES = { - "java.util.ArrayList", - "java.util.LinkedList", - "java.util.Vector", - "java.util.concurrent.CopyOnWriteArrayList" - }; + private static final Supplier[] LIST_CLASSES = { + java.util.ArrayList::new, + java.util.LinkedList::new, + java.util.Vector::new, + java.util.concurrent.CopyOnWriteArrayList::new, + ExtendsAbstractList::new + }; - private static final String[] LIST_CME_CLASSES = { - "java.util.ArrayList", - "java.util.Vector" - }; + private static final Supplier[] LIST_CME_CLASSES = { + java.util.ArrayList::new, + java.util.Vector::new + }; private static final Predicate pEven = x -> 0 == x % 2; private static final Predicate pOdd = x -> 1 == x % 2; @@ -139,13 +139,9 @@ public class ListDefaults { @Test public void testForEach() throws Exception { - final CollectionSupplier supplier = new CollectionSupplier(LIST_CLASSES, SIZE); - for (final CollectionSupplier.TestCase test : supplier.get()) { - final List original = ((List) test.original); - final List list = ((List) test.collection); - } - for (final CollectionSupplier.TestCase test : supplier.get()) { - final List original = ((List) test.original); + final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CLASSES, SIZE); + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final List original = ((List) test.expected); final List list = ((List) test.collection); try { @@ -182,10 +178,9 @@ public class ListDefaults { @Test public void testRemoveIf() throws Exception { - final CollectionSupplier supplier = new CollectionSupplier(LIST_CLASSES, SIZE); - - for (final CollectionSupplier.TestCase test : supplier.get()) { - final List original = ((List) test.original); + final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CLASSES, SIZE); + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final List original = ((List) test.expected); final List list = ((List) test.collection); try { @@ -201,7 +196,7 @@ public class ListDefaults { } for (final CollectionSupplier.TestCase test : supplier.get()) { - final List original = ((List) test.original); + final List original = ((List) test.expected); final List list = ((List) test.collection); list.removeIf(pOdd); for (int i : list) { @@ -217,7 +212,7 @@ public class ListDefaults { } for (final CollectionSupplier.TestCase test : supplier.get()) { - final List original = ((List) test.original); + final List original = ((List) test.expected); final List list = ((List) test.collection); final List listCopy = new ArrayList<>(list); if (original.size() > SUBLIST_SIZE) { @@ -274,9 +269,9 @@ public class ListDefaults { @Test public void testReplaceAll() throws Exception { final int scale = 3; - final CollectionSupplier supplier = new CollectionSupplier(LIST_CLASSES, SIZE); - for (final CollectionSupplier.TestCase test : supplier.get()) { - final List original = ((List) test.original); + final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CLASSES, SIZE); + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final List original = ((List) test.expected); final List list = ((List) test.collection); try { @@ -329,9 +324,9 @@ public class ListDefaults { @Test public void testSort() throws Exception { - final CollectionSupplier supplier = new CollectionSupplier(LIST_CLASSES, SIZE); - for (final CollectionSupplier.TestCase test : supplier.get()) { - final List original = ((List) test.original); + final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CLASSES, SIZE); + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final List original = ((List) test.expected); final List list = ((List) test.collection); CollectionSupplier.shuffle(list); list.sort(Integer::compare); @@ -378,17 +373,15 @@ public class ListDefaults { } @SuppressWarnings("unchecked") - final Class> type = - (Class>) Class.forName(test.className); - final Constructor> defaultConstructor = type.getConstructor(); + final Constructor> defaultConstructor = ((Class>)test.collection.getClass()).getConstructor(); final List incomparables = (List) defaultConstructor.newInstance(); - for (int i=0; i < test.original.size(); i++) { + for (int i=0; i < test.expected.size(); i++) { incomparables.add(new AtomicInteger(i)); } CollectionSupplier.shuffle(incomparables); incomparables.sort(ATOMIC_INTEGER_COMPARATOR); - for (int i=0; i < test.original.size(); i++) { + for (int i=0; i < test.expected.size(); i++) { assertEquals(i, incomparables.get(i).intValue()); } @@ -427,9 +420,10 @@ public class ListDefaults { @Test public void testForEachThrowsCME() throws Exception { - final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE); - for (final CollectionSupplier.TestCase test : supplier.get()) { + final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CME_CLASSES, SIZE); + for (final CollectionSupplier.TestCase> test : supplier.get()) { final List list = ((List) test.collection); + if (list.size() <= 1) { continue; } @@ -448,9 +442,11 @@ public class ListDefaults { @Test public void testRemoveIfThrowsCME() throws Exception { - final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE); - for (final CollectionSupplier.TestCase test : supplier.get()) { + final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CME_CLASSES, SIZE); + for (final CollectionSupplier.TestCase> test : supplier.get()) { + final List original = ((List) test.expected); final List list = ((List) test.collection); + if (list.size() <= 1) { continue; } @@ -469,9 +465,10 @@ public class ListDefaults { @Test public void testReplaceAllThrowsCME() throws Exception { - final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE); - for (final CollectionSupplier.TestCase test : supplier.get()) { + final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CME_CLASSES, SIZE); + for (final CollectionSupplier.TestCase> test : supplier.get()) { final List list = ((List) test.collection); + if (list.size() <= 1) { continue; } @@ -490,9 +487,10 @@ public class ListDefaults { @Test public void testSortThrowsCME() throws Exception { - final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE); - for (final CollectionSupplier.TestCase test : supplier.get()) { + final CollectionSupplier> supplier = new CollectionSupplier((Supplier>[])LIST_CME_CLASSES, SIZE); + for (final CollectionSupplier.TestCase> test : supplier.get()) { final List list = ((List) test.collection); + if (list.size() <= 1) { continue; } @@ -520,6 +518,7 @@ public class ListDefaults { cases.add(new Object[] { new LinkedList<>(Arrays.asList(DATA)) }); cases.add(new Object[] { new Vector<>(Arrays.asList(DATA)) }); cases.add(new Object[] { new CopyOnWriteArrayList<>(Arrays.asList(DATA)) }); + cases.add(new Object[] { new ExtendsAbstractList<>(Arrays.asList(DATA)) }); return cases.toArray(new Object[0][cases.size()]); } diff --git a/jdk/test/java/util/Map/Defaults.java b/jdk/test/java/util/Map/Defaults.java index 48a93525b7f..82470019048 100644 --- a/jdk/test/java/util/Map/Defaults.java +++ b/jdk/test/java/util/Map/Defaults.java @@ -155,7 +155,7 @@ public class Defaults { assertThrows( () -> { map.replaceAll((k,v) -> null); }, NullPointerException.class, - description); + description + " should not allow replacement with null value"); } @Test(dataProvider = "Map rw=true keys=withNull values=withNull") @@ -194,6 +194,15 @@ public class Defaults { assertSame(map.get(null), EXTRA_VALUE); } + @Test(dataProvider = "Map rw=true keys=nonNull values=nonNull") + public void testReplaceKVNoNulls(String description, Map map) { + assertTrue(map.containsKey(FIRST_KEY), "expected key missing"); + assertSame(map.get(FIRST_KEY), FIRST_VALUE, "found wrong value"); + assertThrows( () -> {map.replace(FIRST_KEY, null);}, NullPointerException.class, description + ": should throw NPE"); + assertSame(map.replace(FIRST_KEY, EXTRA_VALUE), FIRST_VALUE, description + ": replaced wrong value"); + assertSame(map.get(FIRST_KEY), EXTRA_VALUE, "found wrong value"); + } + @Test(dataProvider = "Map rw=true keys=all values=all") public void testReplaceKV(String description, Map map) { assertTrue(map.containsKey(KEYS[1])); @@ -224,6 +233,16 @@ public class Defaults { assertSame(map.get(null), EXTRA_VALUE); } + @Test(dataProvider = "Map rw=true keys=nonNull values=nonNull") + public void testReplaceKVVNoNulls(String description, Map map) { + assertTrue(map.containsKey(FIRST_KEY), "expected key missing"); + assertSame(map.get(FIRST_KEY), FIRST_VALUE, "found wrong value"); + assertThrows( () -> {map.replace(FIRST_KEY, FIRST_VALUE, null);}, NullPointerException.class, description + ": should throw NPE"); + assertThrows( () -> {if (!map.replace(FIRST_KEY, null, EXTRA_VALUE)) throw new NullPointerException("default returns false rather than throwing");}, NullPointerException.class, description + ": should throw NPE"); + assertTrue(map.replace(FIRST_KEY, FIRST_VALUE, EXTRA_VALUE), description + ": replaced wrong value"); + assertSame(map.get(FIRST_KEY), EXTRA_VALUE, "found wrong value"); + } + @Test(dataProvider = "Map rw=true keys=all values=all") public void testReplaceKVV(String description, Map map) { assertTrue(map.containsKey(KEYS[1])); @@ -470,6 +489,9 @@ public class Defaults { VALUES[each] = String.valueOf(each); } } + + private static final IntegerEnum FIRST_KEY = KEYS[0]; + private static final String FIRST_VALUE = VALUES[0]; private static final IntegerEnum EXTRA_KEY = IntegerEnum.EXTRA_KEY; private static final String EXTRA_VALUE = String.valueOf(TEST_SIZE); @@ -583,6 +605,8 @@ public class Defaults { return Arrays.asList( // null key hostile new Object[]{"EnumMap", makeMap(() -> new EnumMap(IntegerEnum.class), false, nulls)}, + new Object[]{"TreeMap", makeMap(TreeMap::new, false, nulls)}, + new Object[]{"ExtendsAbstractMap(TreeMap)", makeMap(() -> {return new ExtendsAbstractMap(new TreeMap());}, false, nulls)}, new Object[]{"Collections.synchronizedMap(EnumMap)", Collections.synchronizedMap(makeMap(() -> new EnumMap(IntegerEnum.class), false, nulls))} ); } @@ -591,10 +615,11 @@ public class Defaults { return Arrays.asList( // null key and value hostile new Object[]{"Hashtable", makeMap(Hashtable::new, false, false)}, - new Object[]{"TreeMap", makeMap(TreeMap::new, false, false)}, new Object[]{"ConcurrentHashMap", makeMap(ConcurrentHashMap::new, false, false)}, new Object[]{"ConcurrentSkipListMap", makeMap(ConcurrentSkipListMap::new, false, false)}, + new Object[]{"Collections.synchronizedMap(ConcurrentHashMap)", Collections.synchronizedMap(makeMap(ConcurrentHashMap::new, false, false))}, new Object[]{"Collections.checkedMap(ConcurrentHashMap)", Collections.checkedMap(makeMap(ConcurrentHashMap::new, false, false), IntegerEnum.class, String.class)}, + new Object[]{"ExtendsAbstractMap(ConcurrentHashMap)", makeMap(() -> {return new ExtendsAbstractMap(new ConcurrentHashMap());}, false, false)}, new Object[]{"ImplementsConcurrentMap", makeMap(ImplementsConcurrentMap::new, false, false)} ); } @@ -641,18 +666,17 @@ public class Defaults { } public static void assertThrows(Thrower thrower, Class throwable, String message) { - Throwable result; + Throwable thrown; try { thrower.run(); - result = null; + thrown = null; } catch (Throwable caught) { - result = caught; + thrown = caught; } - assertInstance(result, throwable, - (null != message) - ? message - : "Failed to throw " + throwable.getCanonicalName()); + assertInstance(thrown, throwable, + ((null != message) ? message : "") + + " Failed to throw " + throwable.getCanonicalName()); } public static void assertThrows(Class throwable, String message, Thrower... throwers) { @@ -661,11 +685,11 @@ public class Defaults { } } - public static void assertInstance(T actual, Class expected) { + public static void assertInstance(Object actual, Class expected) { assertInstance(expected.isInstance(actual), null); } - public static void assertInstance(T actual, Class expected, String message) { + public static void assertInstance(Object actual, Class expected, String message) { assertTrue(expected.isInstance(actual), message); } From c712fac717b3874071b41400865f070b4fa77868 Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Fri, 13 Sep 2013 11:19:13 -0700 Subject: [PATCH 0169/1294] 8024014: TEST.groups - split sub-groups for jdk_collections, jdk_stream, jdk_concurrent, jdk_util_other from jdk_util Reviewed-by: mchung, dholmes, alanb --- jdk/test/TEST.groups | 58 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/jdk/test/TEST.groups b/jdk/test/TEST.groups index a59b38853ff..23c9a833209 100644 --- a/jdk/test/TEST.groups +++ b/jdk/test/TEST.groups @@ -20,6 +20,7 @@ # questions. # +# java.lang package and VM runtime support jdk_lang = \ java/lang \ -java/lang/management \ @@ -30,9 +31,64 @@ jdk_lang = \ jdk/lambda \ vm +# All of the java.util package jdk_util = \ + :jdk_util_other \ + :jdk_collections \ + :jdk_concurrent \ + :jdk_stream + +# All util components not part of some other util category +jdk_util_other = \ java/util \ - sun/util + sun/util \ + -:jdk_collections \ + -:jdk_concurrent \ + -:jdk_stream + +# java.util.concurrent (JSR-166) +# Maintained by JSR-166 EG (Doug Lea et al) +# Deque and PriorityQueue are also generally maintained by JSR-166 +jdk_concurrent = \ + java/util/concurrent \ + java/util/Deque \ + java/util/PriorityQueue + +# Java Collections Framework +jdk_collections = \ + java/util/AbstractCollection \ + java/util/AbstractList \ + java/util/AbstractMap \ + java/util/AbstractSequentialList \ + java/util/ArrayList \ + java/util/Arrays \ + java/util/BitSet \ + java/util/Collection \ + java/util/Collections \ + java/util/EnumMap \ + java/util/EnumSet \ + java/util/Comparator \ + java/util/Iterator \ + java/util/HashMap \ + java/util/Hashtable \ + java/util/IdentityHashMap \ + java/util/List \ + java/util/LinkedHashMap \ + java/util/LinkedHashSet \ + java/util/LinkedList \ + java/util/Map \ + java/util/NavigableMap \ + java/util/TimSort \ + java/util/TreeMap \ + java/util/Vector \ + java/util/WeakHashMap + +# java.util.stream (JSR-335) +jdk_stream = \ + java/util/Optional \ + java/util/SummaryStatistics \ + java/util/function \ + java/util/stream jdk_math = \ java/math From ac02958e79178cd05ac03c31757921a9268745c2 Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Fri, 13 Sep 2013 11:26:44 -0700 Subject: [PATCH 0170/1294] 7199674: (props) user.home property does not return an accessible location in sandboxed environment [macosx] On MacOS X set user.home to value of NSHomeDirectory() Reviewed-by: alanb, ddehaven, mduigou --- jdk/make/common/Defs-macosx.gmk | 10 ++++------ jdk/make/java/java/Makefile | 1 + jdk/makefiles/CompileNativeLibraries.gmk | 2 ++ .../solaris/native/java/lang/java_props_macosx.c | 14 +++++++++++++- .../solaris/native/java/lang/java_props_macosx.h | 1 + jdk/src/solaris/native/java/lang/java_props_md.c | 9 ++++++++- 6 files changed, 29 insertions(+), 8 deletions(-) diff --git a/jdk/make/common/Defs-macosx.gmk b/jdk/make/common/Defs-macosx.gmk index 1b7aaa8ae20..befd2cfed5b 100644 --- a/jdk/make/common/Defs-macosx.gmk +++ b/jdk/make/common/Defs-macosx.gmk @@ -397,12 +397,10 @@ else INCLUDE_SA = true endif -ifdef CROSS_COMPILE_ARCH - # X11 headers are not under /usr/include - OTHER_CFLAGS += -I$(OPENWIN_HOME)/include - OTHER_CXXFLAGS += -I$(OPENWIN_HOME)/include - OTHER_CPPFLAGS += -I$(OPENWIN_HOME)/include -endif +# X11 headers are not under /usr/include +OTHER_CFLAGS += -I$(OPENWIN_HOME)/include +OTHER_CXXFLAGS += -I$(OPENWIN_HOME)/include +OTHER_CPPFLAGS += -I$(OPENWIN_HOME)/include LIB_LOCATION ?= $(LIBDIR) diff --git a/jdk/make/java/java/Makefile b/jdk/make/java/java/Makefile index 829cf933001..d2a663f9ae0 100644 --- a/jdk/make/java/java/Makefile +++ b/jdk/make/java/java/Makefile @@ -105,6 +105,7 @@ FILES_java += java/util/prefs/MacOSXPreferences.java \ java/util/prefs/MacOSXPreferencesFactory.java CFLAGS_$(VARIANT)/java_props_md.o = -Os -x objective-c +CFLAGS_$(VARIANT)/java_props_macosx.o = -Os -x objective-c endif # diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 656ee3c4841..d507c92a594 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.gmk @@ -211,6 +211,7 @@ ifneq ($(OPENJDK_TARGET_OS),macosx) LIBJAVA_EXCLUDE_FILES += java_props_macosx.c else BUILD_LIBJAVA_java_props_md.c_CFLAGS:=-x objective-c + BUILD_LIBJAVA_java_props_macosx.c_CFLAGS:=-x objective-c endif ifeq ($(OPENJDK_TARGET_OS),windows) @@ -252,6 +253,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA,\ LDFLAGS_SUFFIX_linux:=$(LIBDL) $(BUILD_LIBFDLIBM),\ LDFLAGS_SUFFIX_macosx:=-L$(JDK_OUTPUTDIR)/objs/ -lfdlibm \ -framework CoreFoundation \ + -framework Foundation \ -framework Security -framework SystemConfiguration, \ LDFLAGS_SUFFIX_windows:=-export:winFileHandleOpen -export:handleLseek \ jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \ diff --git a/jdk/src/solaris/native/java/lang/java_props_macosx.c b/jdk/src/solaris/native/java/lang/java_props_macosx.c index f9ad2e474b1..13fc80d3052 100644 --- a/jdk/src/solaris/native/java/lang/java_props_macosx.c +++ b/jdk/src/solaris/native/java/lang/java_props_macosx.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "java_props_macosx.h" @@ -271,9 +272,20 @@ static char * createConvertedException(CFStringRef cf_original) { return c_exception; } +/* + * Method for fetching the user.home path and storing it in the property list. + * For signed .apps running in the Mac App Sandbox, user.home is set to the + * app's sandbox container. + */ +void setUserHome(java_props_t *sprops) { + if (sprops == NULL) { return; } + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + sprops->user_home = createUTF8CString((CFStringRef)NSHomeDirectory()); + [pool drain]; +} /* - * Method for fetching proxy info and storing it in the propery list. + * Method for fetching proxy info and storing it in the property list. */ void setProxyProperties(java_props_t *sProps) { if (sProps == NULL) return; diff --git a/jdk/src/solaris/native/java/lang/java_props_macosx.h b/jdk/src/solaris/native/java/lang/java_props_macosx.h index b311804835d..19ec220ed4b 100644 --- a/jdk/src/solaris/native/java/lang/java_props_macosx.h +++ b/jdk/src/solaris/native/java/lang/java_props_macosx.h @@ -27,6 +27,7 @@ char *setupMacOSXLocale(int cat); void setOSNameAndVersion(java_props_t *sprops); +void setUserHome(java_props_t *sprops); void setProxyProperties(java_props_t *sProps); enum PreferredToolkit_enum { diff --git a/jdk/src/solaris/native/java/lang/java_props_md.c b/jdk/src/solaris/native/java/lang/java_props_md.c index 58e5e4543d7..dba053e8f4a 100644 --- a/jdk/src/solaris/native/java/lang/java_props_md.c +++ b/jdk/src/solaris/native/java/lang/java_props_md.c @@ -591,7 +591,14 @@ GetJavaProperties(JNIEnv *env) { struct passwd *pwent = getpwuid(getuid()); sprops.user_name = pwent ? strdup(pwent->pw_name) : "?"; - sprops.user_home = pwent ? strdup(pwent->pw_dir) : "?"; +#ifdef MACOSX + setUserHome(&sprops); +#else + sprops.user_home = pwent ? strdup(pwent->pw_dir) : NULL; +#endif + if (sprops.user_home == NULL) { + sprops.user_home = "?"; + } } /* User TIMEZONE */ From 320e8d21e860d431a21d98f6c44956a7f790e3e4 Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Fri, 13 Sep 2013 19:10:31 -0400 Subject: [PATCH 0171/1294] 8014967: EBehavior of DriverManager.registerDriver(dr) is unspecified if driver is null Reviewed-by: alanb --- jdk/src/share/classes/java/sql/DriverManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jdk/src/share/classes/java/sql/DriverManager.java b/jdk/src/share/classes/java/sql/DriverManager.java index 797a920d230..bd16f92de7b 100644 --- a/jdk/src/share/classes/java/sql/DriverManager.java +++ b/jdk/src/share/classes/java/sql/DriverManager.java @@ -326,6 +326,7 @@ public class DriverManager { * @param driver the new JDBC Driver that is to be registered with the * {@code DriverManager} * @exception SQLException if a database access error occurs + * @exception NullPointerException if {@code driver} is null */ public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException { @@ -345,6 +346,7 @@ public class DriverManager { * @param da the {@code DriverAction} implementation to be used when * {@code DriverManager#deregisterDriver} is called * @exception SQLException if a database access error occurs + * @exception NullPointerException if {@code driver} is null */ public static synchronized void registerDriver(java.sql.Driver driver, DriverAction da) From 9bed48236a0b365c5478d5df85fc820eca1dc3f2 Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Fri, 6 Sep 2013 15:36:00 -0700 Subject: [PATCH 0172/1294] 8024825: Some fixes are missing from java.util.stream spec update Reviewed-by: mduigou --- .../java/util/stream/ReferencePipeline.java | 3 - .../classes/java/util/stream/Stream.java | 6 +- .../java/util/stream/package-info.java | 142 +++++++++--------- 3 files changed, 78 insertions(+), 73 deletions(-) diff --git a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java index 9d6aa59c8a7..0efd978f21c 100644 --- a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java +++ b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java @@ -170,7 +170,6 @@ abstract class ReferencePipeline } @Override - @SuppressWarnings("unchecked") public void accept(P_OUT u) { if (predicate.test(u)) downstream.accept(u); @@ -264,7 +263,6 @@ abstract class ReferencePipeline } @Override - @SuppressWarnings("unchecked") public void accept(P_OUT u) { try (Stream result = mapper.apply(u)) { // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it @@ -370,7 +368,6 @@ abstract class ReferencePipeline Sink opWrapSink(int flags, Sink sink) { return new Sink.ChainedReference(sink) { @Override - @SuppressWarnings("unchecked") public void accept(P_OUT u) { action.accept(u); downstream.accept(u); diff --git a/jdk/src/share/classes/java/util/stream/Stream.java b/jdk/src/share/classes/java/util/stream/Stream.java index 4a9f05f5103..a48d59d39d9 100644 --- a/jdk/src/share/classes/java/util/stream/Stream.java +++ b/jdk/src/share/classes/java/util/stream/Stream.java @@ -567,8 +567,8 @@ public interface Stream extends BaseStream> { /** * Performs a reduction on the - * elements of this stream, using the provided identity, accumulation - * function, and combining functions. This is equivalent to: + * elements of this stream, using the provided identity, accumulation and + * combining functions. This is equivalent to: *
    {@code
          *     U result = identity;
          *     for (T element : this stream)
    @@ -886,7 +886,7 @@ public interface Stream extends BaseStream> {
          * @return the new stream
          */
         @SafeVarargs
    -    @SuppressWarnings("varargs")
    +    @SuppressWarnings("varargs") // Creating a stream from an array is safe
         public static Stream of(T... values) {
             return Arrays.stream(values);
         }
    diff --git a/jdk/src/share/classes/java/util/stream/package-info.java b/jdk/src/share/classes/java/util/stream/package-info.java
    index 2c01847ace3..440054eb468 100644
    --- a/jdk/src/share/classes/java/util/stream/package-info.java
    +++ b/jdk/src/share/classes/java/util/stream/package-info.java
    @@ -64,7 +64,7 @@
      *     operations and terminal (value- or side-effect-producing) operations.
      *     Intermediate operations are always lazy.
      *     
  • Possibly unbounded. While collections have a finite size, streams - * need not. Short-circuting operations such as {@code limit(n)} or + * need not. Short-circuiting operations such as {@code limit(n)} or * {@code findFirst()} can allow computations on infinite streams to * complete in finite time.
  • *
  • Consumable. The elements of a stream are only visited once during @@ -96,13 +96,13 @@ * *

    Stream operations and pipelines

    * - *

    Stream operations are - * divided into intermediate and terminal operations, and are - * combined to form stream pipelines. A stream pipeline consists of a - * source (such as a {@code Collection}, an array, a generator function, or an - * I/O channel); followed by zero or more intermediate operations such - * as {@code Stream.filter} or {@code Stream.map}; and a terminal - * operation such as {@code Stream.forEach} or {@code Stream.reduce}. + *

    Stream operations are divided into intermediate and + * terminal operations, and are combined to form stream + * pipelines. A stream pipeline consists of a source (such as a + * {@code Collection}, an array, a generator function, or an I/O channel); + * followed by zero or more intermediate operations such as + * {@code Stream.filter} or {@code Stream.map}; and a terminal operation such + * as {@code Stream.forEach} or {@code Stream.reduce}. * *

    Intermediate operations return a new stream. They are always * lazy; executing an intermediate operation such as @@ -176,9 +176,10 @@ * do: * *

    {@code
    - *     int sumOfWeights = widgets.}{@code parallelStream()}{@code .filter(b -> b.getColor() == RED)
    - *                                                .mapToInt(b -> b.getWeight())
    - *                                                .sum();
    + *     int sumOfWeights = widgets.}parallelStream(){@code
    + *                               .filter(b -> b.getColor() == RED)
    + *                               .mapToInt(b -> b.getWeight())
    + *                               .sum();
      * }
    * *

    The only difference between the serial and parallel versions of this @@ -485,13 +486,13 @@ * as it collects together the desired results into a result container such * as a {@code Collection}. * A {@code collect} operation requires three functions: - * a factory function to construct new instances of the result container, an + * a supplier function to construct new instances of the result container, an * accumulator function to incorporate an input element into a result * container, and a combining function to merge the contents of one result * container into another. The form of this is very similar to the general * form of ordinary reduction: *

    {@code
    - *  R collect(Supplier resultFactory,
    + *  R collect(Supplier supplier,
      *               BiConsumer accumulator,
      *               BiConsumer combiner);
      * }
    @@ -525,10 +526,10 @@ * {@code ArrayList}, and the combiner simply uses {@link java.util.ArrayList#addAll addAll} * to copy the strings from one container into the other. * - *

    The three aspects of {@code collect} -- supplier, accumulator, and combiner -- - * are tightly coupled. We can use the abstraction of - * of a {@link java.util.stream.Collector} to capture all three aspects. - * The above example for collecting strings into a {@code List} can be rewritten + *

    The three aspects of {@code collect} -- supplier, accumulator, and + * combiner -- are tightly coupled. We can use the abstraction of a + * {@link java.util.stream.Collector} to capture all three aspects. The + * above example for collecting strings into a {@code List} can be rewritten * using a standard {@code Collector} as: *

    {@code
      *     List strings = stream.map(Object::toString)
    @@ -545,7 +546,7 @@
      * 
    {@code
      *     Collector summingSalaries
      *         = Collectors.summingInt(Employee::getSalary);
    - * } 
    + * }
    * * (The {@code ?} for the second type parameter merely indicates that we don't * care about the intermediate representation used by this collector.) @@ -557,14 +558,15 @@ * Map salariesByDept * = employees.stream().collect(Collectors.groupingBy(Employee::getDepartment, * summingSalaries)); - * }
  • + * } * *

    As with the regular reduction operation, {@code collect()} operations can - * only be parallelized if appropriate conditions are met. For any partially accumulated result, - * combining it with an empty result container must produce an equivalent - * result. That is, for a partially accumulated result {@code p} that is the - * result of any series of accumulator and combiner invocations, {@code p} must - * be equivalent to {@code combiner.apply(p, supplier.get())}. + * only be parallelized if appropriate conditions are met. For any partially + * accumulated result, combining it with an empty result container must + * produce an equivalent result. That is, for a partially accumulated result + * {@code p} that is the result of any series of accumulator and combiner + * invocations, {@code p} must be equivalent to + * {@code combiner.apply(p, supplier.get())}. * *

    Further, however the computation is split, it must produce an equivalent * result. For any input elements {@code t1} and {@code t2}, the results @@ -580,7 +582,7 @@ * A a3 = supplier.get(); * accumulator.accept(a3, t2); * R r2 = finisher.apply(combiner.apply(a2, a3)); // result with splitting - * } + * } * *

    Here, equivalence generally means according to {@link java.lang.Object#equals(Object)}. * but in some cases equivalence may be relaxed to account for differences in @@ -596,8 +598,8 @@ * .collect(Collectors.groupingBy(Transaction::getBuyer)); * } * it may actually be counterproductive to perform the operation in parallel. - * This is because the combining step (merging one {@code Map} into another by key) - * can be expensive for some {@code Map} implementations. + * This is because the combining step (merging one {@code Map} into another by + * key) can be expensive for some {@code Map} implementations. * *

    Suppose, however, that the result container used in this reduction * was a concurrently modifiable collection -- such as a @@ -605,8 +607,8 @@ * invocations of the accumulator could actually deposit their results * concurrently into the same shared result container, eliminating the need for * the combiner to merge distinct result containers. This potentially provides - * a boost to the parallel execution performance. We call this a concurrent - * reduction. + * a boost to the parallel execution performance. We call this a + * concurrent reduction. * *

    A {@link java.util.stream.Collector} that supports concurrent reduction is * marked with the {@link java.util.stream.Collector.Characteristics#CONCURRENT} @@ -635,11 +637,11 @@ * (where {@link java.util.stream.Collectors#groupingByConcurrent} is the * concurrent equivalent of {@code groupingBy}). * - *

    Note that if it is important that the elements for a given key appear in the - * order they appear in the source, then we cannot use a concurrent reduction, - * as ordering is one of the casualties of concurrent insertion. We would then - * be constrained to implement either a sequential reduction or a merge-based - * parallel reduction. + *

    Note that if it is important that the elements for a given key appear in + * the order they appear in the source, then we cannot use a concurrent + * reduction, as ordering is one of the casualties of concurrent insertion. + * We would then be constrained to implement either a sequential reduction or + * a merge-based parallel reduction. * *

    Associativity

    * @@ -656,8 +658,8 @@ * So we can evaluate {@code (a op b)} in parallel with {@code (c op d)}, and * then invoke {@code op} on the results. * - *

    Examples of associative operations include numeric addition, min, and max, - * and string concatenation. + *

    Examples of associative operations include numeric addition, min, and + * max, and string concatenation. * *

    Low-level stream construction

    * @@ -665,48 +667,54 @@ * {@link java.util.Collection#stream()} or {@link java.util.Arrays#stream(Object[])} * to obtain a stream. How are those stream-bearing methods implemented? * - *

    The class {@link java.util.stream.StreamSupport} has a number of low-level - * methods for creating a stream, all using some form of a {@link java.util.Spliterator}. - * A spliterator is the parallel analogue of an {@link java.util.Iterator}; it - * describes a (possibly infinite) collection of elements, with support for - * sequentially advancing, bulk traversal, and splitting off some portion of the - * input into another spliterator which can be processed in parallel. At the - * lowest level, all streams are driven by a spliterator. + *

    The class {@link java.util.stream.StreamSupport} has a number of + * low-level methods for creating a stream, all using some form of a + * {@link java.util.Spliterator}. A spliterator is the parallel analogue of an + * {@link java.util.Iterator}; it describes a (possibly infinite) collection of + * elements, with support for sequentially advancing, bulk traversal, and + * splitting off some portion of the input into another spliterator which can + * be processed in parallel. At the lowest level, all streams are driven by a + * spliterator. * - *

    There are a number of implementation choices in implementing a spliterator, - * nearly all of which are tradeoffs between simplicity of implementation and - * runtime performance of streams using that spliterator. The simplest, but - * least performant, way to create a spliterator is to create one from an iterator - * using {@link java.util.Spliterators#spliteratorUnknownSize(java.util.Iterator, int)}. + *

    There are a number of implementation choices in implementing a + * spliterator, nearly all of which are tradeoffs between simplicity of + * implementation and runtime performance of streams using that spliterator. + * The simplest, but least performant, way to create a spliterator is to + * create one from an iterator using + * {@link java.util.Spliterators#spliteratorUnknownSize(java.util.Iterator, int)}. * While such a spliterator will work, it will likely offer poor parallel - * performance, since we have lost sizing information (how big is the underlying - * data set), as well as being constrained to a simplistic splitting algorithm. + * performance, since we have lost sizing information (how big is the + * underlying data set), as well as being constrained to a simplistic + * splitting algorithm. * - *

    A higher-quality spliterator will provide balanced and known-size splits, - * accurate sizing information, and a number of other + *

    A higher-quality spliterator will provide balanced and known-size + * splits, accurate sizing information, and a number of other * {@link java.util.Spliterator#characteristics() characteristics} of the * spliterator or data that can be used by implementations to optimize * execution. * - *

    Spliterators for mutable data sources have an additional challenge; timing - * of binding to the data, since the data could change between the time the - * spliterator is created and the time the stream pipeline is executed. Ideally, - * a spliterator for a stream would report a characteristic of {@code IMMUTABLE} - * or {@code CONCURRENT}; if not it should be late-binding. - * If a source cannot directly supply a recommended spliterator, it may - * indirectly supply a spliterator using a {@code Supplier}, and construct a - * stream via the {@code Supplier}-accepting versions of + *

    Spliterators for mutable data sources have an additional challenge; + * timing of binding to the data, since the data could change between the time + * the spliterator is created and the time the stream pipeline is executed. + * Ideally, a spliterator for a stream would report a characteristic of + + * {@code IMMUTABLE} or {@code CONCURRENT}; if not it should be + * late-binding. If a source + * cannot directly supply a recommended spliterator, it may indirectly supply + * a spliterator using a {@code Supplier}, and construct a stream via the + * {@code Supplier}-accepting versions of * {@link java.util.stream.StreamSupport#stream(Supplier, int, boolean) stream()}. * The spliterator is obtained from the supplier only after the terminal * operation of the stream pipeline commences. * - *

    These requirements significantly reduce the scope of potential interference - * between mutations of the stream source and execution of stream pipelines. - * Streams based on spliterators with the desired characteristics, or those using - * the Supplier-based factory forms, are immune to modifications of the data - * source prior to commencement of the terminal operation (provided the behavioral - * parameters to the stream operations meet the required criteria for non-interference - * and statelessness). See Non-Interference + *

    These requirements significantly reduce the scope of potential + * interference between mutations of the stream source and execution of stream + * pipelines. Streams based on spliterators with the desired characteristics, + * or those using the Supplier-based factory forms, are immune to + * modifications of the data source prior to commencement of the terminal + * operation (provided the behavioral parameters to the stream operations meet + * the required criteria for non-interference and statelessness). See + * Non-Interference * for more details. * * @since 1.8 From e2940a0e2548efe210a16a66d3dd040207db2387 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Sat, 14 Sep 2013 13:55:04 -0400 Subject: [PATCH 0173/1294] 8023639: Difference between LocalTime.now(Clock.systemDefaultZone()) and LocalTime.now() executed successively is more than 100 000 000 nanoseconds for slow machines Test timed out on a slow machine; it is not a conformance test and should be in the test subtree Reviewed-by: darcy, sherman --- .../java/time/tck/java/time/TCKLocalTime.java | 11 ---------- .../time/test/java/time/TestLocalTime.java | 21 +++++++++++++++++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/jdk/test/java/time/tck/java/time/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/TCKLocalTime.java index e0ef94cdadc..dbba80d1cec 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java @@ -282,17 +282,6 @@ public class TCKLocalTime extends AbstractDateTimeTest { check(LocalTime.MAX, 23, 59, 59, 999999999); } - //----------------------------------------------------------------------- - // now() - //----------------------------------------------------------------------- - @Test - public void now() { - LocalTime expected = LocalTime.now(Clock.systemDefaultZone()); - LocalTime test = LocalTime.now(); - long diff = Math.abs(test.toNanoOfDay() - expected.toNanoOfDay()); - assertTrue(diff < 100000000); // less than 0.1 secs - } - //----------------------------------------------------------------------- // now(ZoneId) //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/test/java/time/TestLocalTime.java b/jdk/test/java/time/test/java/time/TestLocalTime.java index ddd7b0f572e..d7f04ab5af6 100644 --- a/jdk/test/java/time/test/java/time/TestLocalTime.java +++ b/jdk/test/java/time/test/java/time/TestLocalTime.java @@ -61,7 +61,9 @@ package test.java.time; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertSame; +import static org.testng.Assert.assertTrue; +import java.time.Clock; import java.time.LocalTime; import org.testng.annotations.Test; @@ -176,4 +178,23 @@ public class TestLocalTime extends AbstractTest { } } + //----------------------------------------------------------------------- + // now() + //----------------------------------------------------------------------- + @Test + public void now() { + // Warmup the TimeZone data so the following test does not include + // one-time initialization + LocalTime expected = LocalTime.now(Clock.systemDefaultZone()); + + expected = LocalTime.now(Clock.systemDefaultZone()); + LocalTime test = LocalTime.now(); + long diff = test.toNanoOfDay() - expected.toNanoOfDay(); + if (diff < 0) { + // Adjust if for rollover around midnight + diff += 24 * 60 * 60 * 1_000_000_000L; // Nanos Per Day + } + assertTrue(diff < 500000000); // less than 0.5 secs + } + } From e763c78a79d31afd5b9ce9fb04a808dc4f837a4c Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Sat, 14 Sep 2013 13:55:06 -0400 Subject: [PATCH 0174/1294] 8023556: Update javadoc for start of Meiji era Correct the javadoc in JapaneseEra.MEIJI to match the implementation Reviewed-by: darcy, sherman --- .../classes/java/time/chrono/JapaneseEra.java | 2 +- .../time/test/java/time/TestLocalTime.java | 27 +++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseEra.java b/jdk/src/share/classes/java/time/chrono/JapaneseEra.java index 46eee0b59f8..2dbbde3aac2 100644 --- a/jdk/src/share/classes/java/time/chrono/JapaneseEra.java +++ b/jdk/src/share/classes/java/time/chrono/JapaneseEra.java @@ -104,7 +104,7 @@ public final class JapaneseEra static final sun.util.calendar.Era[] ERA_CONFIG; /** - * The singleton instance for the 'Meiji' era (1868-09-08 - 1912-07-29) + * The singleton instance for the 'Meiji' era (1868-01-01 - 1912-07-29) * which has the value -1. */ public static final JapaneseEra MEIJI = new JapaneseEra(-1, LocalDate.of(1868, 1, 1)); diff --git a/jdk/test/java/time/test/java/time/TestLocalTime.java b/jdk/test/java/time/test/java/time/TestLocalTime.java index d7f04ab5af6..8e25a85f198 100644 --- a/jdk/test/java/time/test/java/time/TestLocalTime.java +++ b/jdk/test/java/time/test/java/time/TestLocalTime.java @@ -73,6 +73,9 @@ import org.testng.annotations.Test; */ @Test public class TestLocalTime extends AbstractTest { + static final long NANOS_PER_SECOND = 1_000_000_000L; + static final long NANOS_PER_MINUTE = 60 * NANOS_PER_SECOND; + static final long NANOS_PER_DAY = 24 * 60 * NANOS_PER_MINUTE; //----------------------------------------------------------------------- @Test @@ -182,19 +185,27 @@ public class TestLocalTime extends AbstractTest { // now() //----------------------------------------------------------------------- @Test + @SuppressWarnings("unused") public void now() { // Warmup the TimeZone data so the following test does not include // one-time initialization - LocalTime expected = LocalTime.now(Clock.systemDefaultZone()); + LocalTime.now(Clock.systemDefaultZone()); - expected = LocalTime.now(Clock.systemDefaultZone()); - LocalTime test = LocalTime.now(); - long diff = test.toNanoOfDay() - expected.toNanoOfDay(); - if (diff < 0) { - // Adjust if for rollover around midnight - diff += 24 * 60 * 60 * 1_000_000_000L; // Nanos Per Day + long diff = Integer.MAX_VALUE; + for (int i = 0; i < 2; i++) { + LocalTime expected = LocalTime.now(Clock.systemDefaultZone()); + LocalTime test = LocalTime.now(); + diff = test.toNanoOfDay() - expected.toNanoOfDay(); + // Normalize for wrap-around midnight + diff = Math.floorMod(NANOS_PER_DAY + diff, NANOS_PER_DAY); + if (diff < 100000000) { + break; + } + // A second iteration may be needed if the clock changed + // due to a DST change between the two calls to now. } - assertTrue(diff < 500000000); // less than 0.5 secs + assertTrue(diff < 100000000, // less than 0.1 sec + "LocalTime.now vs LocalTime.now(Clock.systemDefaultZone()) not close"); } } From bef51c4a0895b8b525ee33d22281fdf56eea8431 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Mon, 2 Sep 2013 11:59:57 +0200 Subject: [PATCH 0175/1294] 8010293: java/util/concurrent/ConcurrentHashMap/toArray.java fails intermittently Co-authored-by: Doug Lea Co-authored-by: Peter Levart Reviewed-by: forax, chegar, alanb --- .../util/concurrent/ConcurrentHashMap.java | 302 ++++++++++++------ .../concurrent/ConcurrentHashMap/toArray.java | 64 ++-- 2 files changed, 241 insertions(+), 125 deletions(-) diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java index 9476bc411ba..c8c52a76ffd 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -374,27 +374,26 @@ public class ConcurrentHashMap extends AbstractMap * The table is resized when occupancy exceeds a percentage * threshold (nominally, 0.75, but see below). Any thread * noticing an overfull bin may assist in resizing after the - * initiating thread allocates and sets up the replacement - * array. However, rather than stalling, these other threads may - * proceed with insertions etc. The use of TreeBins shields us - * from the worst case effects of overfilling while resizes are in + * initiating thread allocates and sets up the replacement array. + * However, rather than stalling, these other threads may proceed + * with insertions etc. The use of TreeBins shields us from the + * worst case effects of overfilling while resizes are in * progress. Resizing proceeds by transferring bins, one by one, - * from the table to the next table. To enable concurrency, the - * next table must be (incrementally) prefilled with place-holders - * serving as reverse forwarders to the old table. Because we are - * using power-of-two expansion, the elements from each bin must - * either stay at same index, or move with a power of two - * offset. We eliminate unnecessary node creation by catching - * cases where old nodes can be reused because their next fields - * won't change. On average, only about one-sixth of them need - * cloning when a table doubles. The nodes they replace will be - * garbage collectable as soon as they are no longer referenced by - * any reader thread that may be in the midst of concurrently - * traversing table. Upon transfer, the old table bin contains - * only a special forwarding node (with hash field "MOVED") that - * contains the next table as its key. On encountering a - * forwarding node, access and update operations restart, using - * the new table. + * from the table to the next table. However, threads claim small + * blocks of indices to transfer (via field transferIndex) before + * doing so, reducing contention. Because we are using + * power-of-two expansion, the elements from each bin must either + * stay at same index, or move with a power of two offset. We + * eliminate unnecessary node creation by catching cases where old + * nodes can be reused because their next fields won't change. On + * average, only about one-sixth of them need cloning when a table + * doubles. The nodes they replace will be garbage collectable as + * soon as they are no longer referenced by any reader thread that + * may be in the midst of concurrently traversing table. Upon + * transfer, the old table bin contains only a special forwarding + * node (with hash field "MOVED") that contains the next table as + * its key. On encountering a forwarding node, access and update + * operations restart, using the new table. * * Each bin transfer requires its bin lock, which can stall * waiting for locks while resizing. However, because other @@ -402,13 +401,19 @@ public class ConcurrentHashMap extends AbstractMap * locks, average aggregate waits become shorter as resizing * progresses. The transfer operation must also ensure that all * accessible bins in both the old and new table are usable by any - * traversal. This is arranged by proceeding from the last bin - * (table.length - 1) up towards the first. Upon seeing a - * forwarding node, traversals (see class Traverser) arrange to - * move to the new table without revisiting nodes. However, to - * ensure that no intervening nodes are skipped, bin splitting can - * only begin after the associated reverse-forwarders are in - * place. + * traversal. This is arranged in part by proceeding from the + * last bin (table.length - 1) up towards the first. Upon seeing + * a forwarding node, traversals (see class Traverser) arrange to + * move to the new table without revisiting nodes. To ensure that + * no intervening nodes are skipped even when moved out of order, + * a stack (see class TableStack) is created on first encounter of + * a forwarding node during a traversal, to maintain its place if + * later processing the current table. The need for these + * save/restore mechanics is relatively rare, but when one + * forwarding node is encountered, typically many more will be. + * So Traversers use a simple caching scheme to avoid creating so + * many new TableStack nodes. (Thanks to Peter Levart for + * suggesting use of a stack here.) * * The traversal scheme also applies to partial traversals of * ranges of bins (via an alternate Traverser constructor) @@ -776,11 +781,6 @@ public class ConcurrentHashMap extends AbstractMap */ private transient volatile int transferIndex; - /** - * The least available table index to split while resizing. - */ - private transient volatile int transferOrigin; - /** * Spinlock (locked via CAS) used when resizing and/or creating CounterCells. */ @@ -1377,7 +1377,8 @@ public class ConcurrentHashMap extends AbstractMap } int segmentShift = 32 - sshift; int segmentMask = ssize - 1; - @SuppressWarnings("unchecked") Segment[] segments = (Segment[]) + @SuppressWarnings("unchecked") + Segment[] segments = (Segment[]) new Segment[DEFAULT_CONCURRENCY_LEVEL]; for (int i = 0; i < segments.length; ++i) segments[i] = new Segment(LOAD_FACTOR); @@ -1420,8 +1421,10 @@ public class ConcurrentHashMap extends AbstractMap long size = 0L; Node p = null; for (;;) { - @SuppressWarnings("unchecked") K k = (K) s.readObject(); - @SuppressWarnings("unchecked") V v = (V) s.readObject(); + @SuppressWarnings("unchecked") + K k = (K) s.readObject(); + @SuppressWarnings("unchecked") + V v = (V) s.readObject(); if (k != null && v != null) { p = new Node(spread(k.hashCode()), k, v, p); ++size; @@ -1439,8 +1442,8 @@ public class ConcurrentHashMap extends AbstractMap int sz = (int)size; n = tableSizeFor(sz + (sz >>> 1) + 1); } - @SuppressWarnings({"rawtypes","unchecked"}) - Node[] tab = (Node[])new Node[n]; + @SuppressWarnings("unchecked") + Node[] tab = (Node[])new Node[n]; int mask = n - 1; long added = 0L; while (p != null) { @@ -2200,8 +2203,8 @@ public class ConcurrentHashMap extends AbstractMap try { if ((tab = table) == null || tab.length == 0) { int n = (sc > 0) ? sc : DEFAULT_CAPACITY; - @SuppressWarnings({"rawtypes","unchecked"}) - Node[] nt = (Node[])new Node[n]; + @SuppressWarnings("unchecked") + Node[] nt = (Node[])new Node[n]; table = tab = nt; sc = n - (n >>> 2); } @@ -2246,7 +2249,7 @@ public class ConcurrentHashMap extends AbstractMap while (s >= (long)(sc = sizeCtl) && (tab = table) != null && tab.length < MAXIMUM_CAPACITY) { if (sc < 0) { - if (sc == -1 || transferIndex <= transferOrigin || + if (sc == -1 || transferIndex <= 0 || (nt = nextTable) == null) break; if (U.compareAndSwapInt(this, SIZECTL, sc, sc - 1)) @@ -2266,10 +2269,13 @@ public class ConcurrentHashMap extends AbstractMap Node[] nextTab; int sc; if ((f instanceof ForwardingNode) && (nextTab = ((ForwardingNode)f).nextTable) != null) { - if (nextTab == nextTable && tab == table && - transferIndex > transferOrigin && (sc = sizeCtl) < -1 && - U.compareAndSwapInt(this, SIZECTL, sc, sc - 1)) - transfer(tab, nextTab); + while (transferIndex > 0 && nextTab == nextTable && + (sc = sizeCtl) < -1) { + if (U.compareAndSwapInt(this, SIZECTL, sc, sc - 1)) { + transfer(tab, nextTab); + break; + } + } return nextTab; } return table; @@ -2291,8 +2297,8 @@ public class ConcurrentHashMap extends AbstractMap if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) { try { if (table == tab) { - @SuppressWarnings({"rawtypes","unchecked"}) - Node[] nt = (Node[])new Node[n]; + @SuppressWarnings("unchecked") + Node[] nt = (Node[])new Node[n]; table = nt; sc = n - (n >>> 2); } @@ -2319,36 +2325,27 @@ public class ConcurrentHashMap extends AbstractMap stride = MIN_TRANSFER_STRIDE; // subdivide range if (nextTab == null) { // initiating try { - @SuppressWarnings({"rawtypes","unchecked"}) - Node[] nt = (Node[])new Node[n << 1]; + @SuppressWarnings("unchecked") + Node[] nt = (Node[])new Node[n << 1]; nextTab = nt; } catch (Throwable ex) { // try to cope with OOME sizeCtl = Integer.MAX_VALUE; return; } nextTable = nextTab; - transferOrigin = n; transferIndex = n; - ForwardingNode rev = new ForwardingNode(tab); - for (int k = n; k > 0;) { // progressively reveal ready slots - int nextk = (k > stride) ? k - stride : 0; - for (int m = nextk; m < k; ++m) - nextTab[m] = rev; - for (int m = n + nextk; m < n + k; ++m) - nextTab[m] = rev; - U.putOrderedInt(this, TRANSFERORIGIN, k = nextk); - } } int nextn = nextTab.length; ForwardingNode fwd = new ForwardingNode(nextTab); boolean advance = true; boolean finishing = false; // to ensure sweep before committing nextTab for (int i = 0, bound = 0;;) { - int nextIndex, nextBound, fh; Node f; + Node f; int fh; while (advance) { + int nextIndex, nextBound; if (--i >= bound || finishing) advance = false; - else if ((nextIndex = transferIndex) <= transferOrigin) { + else if ((nextIndex = transferIndex) <= 0) { i = -1; advance = false; } @@ -2362,29 +2359,22 @@ public class ConcurrentHashMap extends AbstractMap } } if (i < 0 || i >= n || i + n >= nextn) { + int sc; if (finishing) { nextTable = null; table = nextTab; sizeCtl = (n << 1) - (n >>> 1); return; } - for (int sc;;) { - if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, ++sc)) { - if (sc != -1) - return; - finishing = advance = true; - i = n; // recheck before commit - break; - } - } - } - else if ((f = tabAt(tab, i)) == null) { - if (casTabAt(tab, i, null, fwd)) { - setTabAt(nextTab, i, null); - setTabAt(nextTab, i + n, null); - advance = true; + if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, ++sc)) { + if (sc != -1) + return; + finishing = advance = true; + i = n; // recheck before commit } } + else if ((f = tabAt(tab, i)) == null) + advance = casTabAt(tab, i, null, fwd); else if ((fh = f.hash) == MOVED) advance = true; // already processed else { @@ -3223,6 +3213,18 @@ public class ConcurrentHashMap extends AbstractMap /* ----------------Table Traversal -------------- */ + /** + * Records the table, its length, and current traversal index for a + * traverser that must process a region of a forwarded table before + * proceeding with current table. + */ + static final class TableStack { + int length; + int index; + Node[] tab; + TableStack next; + } + /** * Encapsulates traversal for methods such as containsValue; also * serves as a base class for other iterators and spliterators. @@ -3247,6 +3249,7 @@ public class ConcurrentHashMap extends AbstractMap static class Traverser { Node[] tab; // current table; updated if resized Node next; // the next entry to use + TableStack stack, spare; // to save/restore on ForwardingNodes int index; // index of bin to use next int baseIndex; // current index of initial table int baseLimit; // index bound for initial table @@ -3268,16 +3271,17 @@ public class ConcurrentHashMap extends AbstractMap if ((e = next) != null) e = e.next; for (;;) { - Node[] t; int i, n; K ek; // must use locals in checks + Node[] t; int i, n; // must use locals in checks if (e != null) return next = e; if (baseIndex >= baseLimit || (t = tab) == null || (n = t.length) <= (i = index) || i < 0) return next = null; - if ((e = tabAt(t, index)) != null && e.hash < 0) { + if ((e = tabAt(t, i)) != null && e.hash < 0) { if (e instanceof ForwardingNode) { tab = ((ForwardingNode)e).nextTable; e = null; + pushState(t, i, n); continue; } else if (e instanceof TreeBin) @@ -3285,10 +3289,49 @@ public class ConcurrentHashMap extends AbstractMap else e = null; } - if ((index += baseSize) >= n) - index = ++baseIndex; // visit upper slots if present + if (stack != null) + recoverState(n); + else if ((index = i + baseSize) >= n) + index = ++baseIndex; // visit upper slots if present } } + + /** + * Saves traversal state upon encountering a forwarding node. + */ + private void pushState(Node[] t, int i, int n) { + TableStack s = spare; // reuse if possible + if (s != null) + spare = s.next; + else + s = new TableStack(); + s.tab = t; + s.length = n; + s.index = i; + s.next = stack; + stack = s; + } + + /** + * Possibly pops traversal state. + * + * @param n length of current table + */ + private void recoverState(int n) { + TableStack s; int len; + while ((s = stack) != null && (index += (len = s.length)) >= n) { + n = len; + index = s.index; + tab = s.tab; + s.tab = null; + TableStack next = s.next; + s.next = spare; // save for reuse + stack = next; + spare = s; + } + if (s == null && (index += baseSize) >= n) + index = ++baseIndex; + } } /** @@ -4722,6 +4765,7 @@ public class ConcurrentHashMap extends AbstractMap abstract static class BulkTask extends CountedCompleter { Node[] tab; // same as Traverser Node next; + TableStack stack, spare; int index; int baseIndex; int baseLimit; @@ -4750,16 +4794,17 @@ public class ConcurrentHashMap extends AbstractMap if ((e = next) != null) e = e.next; for (;;) { - Node[] t; int i, n; K ek; // must use locals in checks + Node[] t; int i, n; if (e != null) return next = e; if (baseIndex >= baseLimit || (t = tab) == null || (n = t.length) <= (i = index) || i < 0) return next = null; - if ((e = tabAt(t, index)) != null && e.hash < 0) { + if ((e = tabAt(t, i)) != null && e.hash < 0) { if (e instanceof ForwardingNode) { tab = ((ForwardingNode)e).nextTable; e = null; + pushState(t, i, n); continue; } else if (e instanceof TreeBin) @@ -4767,10 +4812,41 @@ public class ConcurrentHashMap extends AbstractMap else e = null; } - if ((index += baseSize) >= n) - index = ++baseIndex; // visit upper slots if present + if (stack != null) + recoverState(n); + else if ((index = i + baseSize) >= n) + index = ++baseIndex; } } + + private void pushState(Node[] t, int i, int n) { + TableStack s = spare; + if (s != null) + spare = s.next; + else + s = new TableStack(); + s.tab = t; + s.length = n; + s.index = i; + s.next = stack; + stack = s; + } + + private void recoverState(int n) { + TableStack s; int len; + while ((s = stack) != null && (index += (len = s.length)) >= n) { + n = len; + index = s.index; + tab = s.tab; + s.tab = null; + TableStack next = s.next; + s.next = spare; // save for reuse + stack = next; + spare = s; + } + if (s == null && (index += baseSize) >= n) + index = ++baseIndex; + } } /* @@ -5229,7 +5305,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") ReduceKeysTask + @SuppressWarnings("unchecked") + ReduceKeysTask t = (ReduceKeysTask)c, s = t.rights; while (s != null) { @@ -5276,7 +5353,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") ReduceValuesTask + @SuppressWarnings("unchecked") + ReduceValuesTask t = (ReduceValuesTask)c, s = t.rights; while (s != null) { @@ -5321,7 +5399,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") ReduceEntriesTask + @SuppressWarnings("unchecked") + ReduceEntriesTask t = (ReduceEntriesTask)c, s = t.rights; while (s != null) { @@ -5374,7 +5453,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceKeysTask + @SuppressWarnings("unchecked") + MapReduceKeysTask t = (MapReduceKeysTask)c, s = t.rights; while (s != null) { @@ -5427,7 +5507,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceValuesTask + @SuppressWarnings("unchecked") + MapReduceValuesTask t = (MapReduceValuesTask)c, s = t.rights; while (s != null) { @@ -5480,7 +5561,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceEntriesTask + @SuppressWarnings("unchecked") + MapReduceEntriesTask t = (MapReduceEntriesTask)c, s = t.rights; while (s != null) { @@ -5533,7 +5615,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceMappingsTask + @SuppressWarnings("unchecked") + MapReduceMappingsTask t = (MapReduceMappingsTask)c, s = t.rights; while (s != null) { @@ -5585,7 +5668,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceKeysToDoubleTask + @SuppressWarnings("unchecked") + MapReduceKeysToDoubleTask t = (MapReduceKeysToDoubleTask)c, s = t.rights; while (s != null) { @@ -5634,7 +5718,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceValuesToDoubleTask + @SuppressWarnings("unchecked") + MapReduceValuesToDoubleTask t = (MapReduceValuesToDoubleTask)c, s = t.rights; while (s != null) { @@ -5683,7 +5768,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceEntriesToDoubleTask + @SuppressWarnings("unchecked") + MapReduceEntriesToDoubleTask t = (MapReduceEntriesToDoubleTask)c, s = t.rights; while (s != null) { @@ -5732,7 +5818,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceMappingsToDoubleTask + @SuppressWarnings("unchecked") + MapReduceMappingsToDoubleTask t = (MapReduceMappingsToDoubleTask)c, s = t.rights; while (s != null) { @@ -5781,7 +5868,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceKeysToLongTask + @SuppressWarnings("unchecked") + MapReduceKeysToLongTask t = (MapReduceKeysToLongTask)c, s = t.rights; while (s != null) { @@ -5830,7 +5918,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceValuesToLongTask + @SuppressWarnings("unchecked") + MapReduceValuesToLongTask t = (MapReduceValuesToLongTask)c, s = t.rights; while (s != null) { @@ -5879,7 +5968,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceEntriesToLongTask + @SuppressWarnings("unchecked") + MapReduceEntriesToLongTask t = (MapReduceEntriesToLongTask)c, s = t.rights; while (s != null) { @@ -5928,7 +6018,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceMappingsToLongTask + @SuppressWarnings("unchecked") + MapReduceMappingsToLongTask t = (MapReduceMappingsToLongTask)c, s = t.rights; while (s != null) { @@ -5977,7 +6068,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceKeysToIntTask + @SuppressWarnings("unchecked") + MapReduceKeysToIntTask t = (MapReduceKeysToIntTask)c, s = t.rights; while (s != null) { @@ -6026,7 +6118,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceValuesToIntTask + @SuppressWarnings("unchecked") + MapReduceValuesToIntTask t = (MapReduceValuesToIntTask)c, s = t.rights; while (s != null) { @@ -6075,7 +6168,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceEntriesToIntTask + @SuppressWarnings("unchecked") + MapReduceEntriesToIntTask t = (MapReduceEntriesToIntTask)c, s = t.rights; while (s != null) { @@ -6124,7 +6218,8 @@ public class ConcurrentHashMap extends AbstractMap result = r; CountedCompleter c; for (c = firstComplete(); c != null; c = c.nextComplete()) { - @SuppressWarnings("unchecked") MapReduceMappingsToIntTask + @SuppressWarnings("unchecked") + MapReduceMappingsToIntTask t = (MapReduceMappingsToIntTask)c, s = t.rights; while (s != null) { @@ -6140,7 +6235,6 @@ public class ConcurrentHashMap extends AbstractMap private static final sun.misc.Unsafe U; private static final long SIZECTL; private static final long TRANSFERINDEX; - private static final long TRANSFERORIGIN; private static final long BASECOUNT; private static final long CELLSBUSY; private static final long CELLVALUE; @@ -6155,8 +6249,6 @@ public class ConcurrentHashMap extends AbstractMap (k.getDeclaredField("sizeCtl")); TRANSFERINDEX = U.objectFieldOffset (k.getDeclaredField("transferIndex")); - TRANSFERORIGIN = U.objectFieldOffset - (k.getDeclaredField("transferOrigin")); BASECOUNT = U.objectFieldOffset (k.getDeclaredField("baseCount")); CELLSBUSY = U.objectFieldOffset diff --git a/jdk/test/java/util/concurrent/ConcurrentHashMap/toArray.java b/jdk/test/java/util/concurrent/ConcurrentHashMap/toArray.java index 0280c0c4658..81108ac9c55 100644 --- a/jdk/test/java/util/concurrent/ConcurrentHashMap/toArray.java +++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/toArray.java @@ -23,39 +23,53 @@ /* * @test - * @bug 4486658 + * @bug 4486658 8010293 * @summary thread safety of toArray methods of subCollections * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.IntStream; -public class toArray { +public class ToArray { public static void main(String[] args) throws Throwable { + // Execute a number of times to increase the probability of + // failure if there is an issue + for (int i = 0; i < 16; i++) { + executeTest(); + } + } + + static void executeTest() throws Throwable { final Throwable throwable[] = new Throwable[1]; - final int maxSize = 1000; - final ConcurrentHashMap m - = new ConcurrentHashMap(); + final ConcurrentHashMap m = new ConcurrentHashMap<>(); - final Thread t1 = new Thread() { public void run() { - for (int i = 0; i < maxSize; i++) - m.put(i,i);}}; + // Number of workers equal to the number of processors + // Each worker will put globally unique keys into the map + final int nWorkers = Runtime.getRuntime().availableProcessors(); + final int sizePerWorker = 1024; + final int maxSize = nWorkers * sizePerWorker; - final Thread t2 = new Thread() { - public Throwable exception = null; + // The foreman keeps checking that the size of the arrays + // obtained from the key and value sets is never less than the + // previously observed size and is never greater than the maximum size + // NOTE: these size constraints are not specific to toArray and are + // applicable to any form of traversal of the collection views + CompletableFuture foreman = CompletableFuture.runAsync(new Runnable() { private int prevSize = 0; private boolean checkProgress(Object[] a) { int size = a.length; if (size < prevSize) throw new RuntimeException("WRONG WAY"); - if (size > maxSize) throw new RuntimeException("OVERSHOOT"); + if (size > maxSize) throw new RuntimeException("OVERSHOOT"); if (size == maxSize) return true; prevSize = size; return false; } + @Override public void run() { try { Integer[] empty = new Integer[0]; @@ -65,15 +79,25 @@ public class toArray { if (checkProgress(m.values().toArray(empty))) return; if (checkProgress(m.keySet().toArray(empty))) return; } - } catch (Throwable t) { - throwable[0] = t; - }}}; + } + catch (Throwable t) { + throwable[0] = t; + } + } + }); - t2.start(); - t1.start(); + // Create workers + // Each worker will put globally unique keys into the map + CompletableFuture[] workers = IntStream.range(0, nWorkers). + mapToObj(w -> CompletableFuture.runAsync(() -> { + for (int i = 0, o = w * sizePerWorker; i < sizePerWorker; i++) + m.put(o + i, i); + })). + toArray(CompletableFuture[]::new); - t1.join(); - t2.join(); + // Wait for workers and then foreman to complete + CompletableFuture.allOf(workers).join(); + foreman.join(); if (throwable[0] != null) throw throwable[0]; From 24f316c8610c157c61d390aa166b9fca72e83c53 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 2 Sep 2013 14:06:24 +0400 Subject: [PATCH 0176/1294] 7156658: JTextComponent.setFocusAccelerator() spec does not state that focus accelerator is L&F dependent Reviewed-by: alexsch --- jdk/src/share/classes/javax/swing/text/JTextComponent.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/text/JTextComponent.java b/jdk/src/share/classes/javax/swing/text/JTextComponent.java index 274ae9decc5..c88b1165615 100644 --- a/jdk/src/share/classes/javax/swing/text/JTextComponent.java +++ b/jdk/src/share/classes/javax/swing/text/JTextComponent.java @@ -1562,8 +1562,10 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A /** * Sets the key accelerator that will cause the receiving text * component to get the focus. The accelerator will be the - * key combination of the alt key and the character - * given (converted to upper case). By default, there is no focus + * key combination of the platform-specific modifier key and + * the character given (converted to upper case). For example, + * the ALT key is used as a modifier on Windows and the CTRL+ALT + * combination is used on Mac. By default, there is no focus * accelerator key. Any previous key accelerator setting will be * superseded. A '\0' key setting will be registered, and has the * effect of turning off the focus accelerator. When the new key From a0509f709c489ee19da4446269b8b729ceb26242 Mon Sep 17 00:00:00 2001 From: Srikalyan Chandrashekar Date: Mon, 2 Sep 2013 16:48:51 +0400 Subject: [PATCH 0177/1294] 8022184: Fix static , Raw warnings in classes belonging to java.awt Reviewed-by: art, anthony --- .../share/classes/java/awt/AWTKeyStroke.java | 28 +++++++-------- .../share/classes/java/awt/CardLayout.java | 10 +++--- .../ContainerOrderFocusTraversalPolicy.java | 4 +-- .../java/awt/DefaultKeyboardFocusManager.java | 16 ++++----- .../java/awt/GradientPaintContext.java | 4 +-- .../classes/java/awt/GraphicsEnvironment.java | 10 +++--- .../java/awt/KeyboardFocusManager.java | 36 +++++++++---------- .../classes/java/awt/SequencedEvent.java | 2 +- .../classes/java/awt/TexturePaintContext.java | 18 +++++----- .../classes/java/awt/WaitDispatchSupport.java | 4 +-- 10 files changed, 66 insertions(+), 66 deletions(-) diff --git a/jdk/src/share/classes/java/awt/AWTKeyStroke.java b/jdk/src/share/classes/java/awt/AWTKeyStroke.java index 8966d753fb7..e94194e0a74 100644 --- a/jdk/src/share/classes/java/awt/AWTKeyStroke.java +++ b/jdk/src/share/classes/java/awt/AWTKeyStroke.java @@ -67,7 +67,7 @@ import java.lang.reflect.Field; public class AWTKeyStroke implements Serializable { static final long serialVersionUID = -6430539691155161871L; - private static Map modifierKeywords; + private static Map modifierKeywords; /** * Associates VK_XXX (as a String) with code (as Integer). This is * done to avoid the overhead of the reflective call to find the @@ -85,8 +85,8 @@ public class AWTKeyStroke implements Serializable { * AWTKeyStroke class. * Must be called under locked AWTKeyStro */ - private static Class getAWTKeyStrokeClass() { - Class clazz = (Class)AppContext.getAppContext().get(AWTKeyStroke.class); + private static Class getAWTKeyStrokeClass() { + Class clazz = (Class)AppContext.getAppContext().get(AWTKeyStroke.class); if (clazz == null) { clazz = AWTKeyStroke.class; AppContext.getAppContext().put(AWTKeyStroke.class, AWTKeyStroke.class); @@ -182,7 +182,7 @@ public class AWTKeyStroke implements Serializable { throw new IllegalArgumentException("subclass cannot be null"); } synchronized (AWTKeyStroke.class) { - Class keyStrokeClass = (Class)AppContext.getAppContext().get(AWTKeyStroke.class); + Class keyStrokeClass = (Class)AppContext.getAppContext().get(AWTKeyStroke.class); if (keyStrokeClass != null && keyStrokeClass.equals(subclass)){ // Already registered return; @@ -229,8 +229,8 @@ public class AWTKeyStroke implements Serializable { */ private static Constructor getCtor(final Class clazz) { - Object ctor = AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + Constructor ctor = AccessController.doPrivileged(new PrivilegedAction() { + public Constructor run() { try { Constructor ctor = clazz.getDeclaredConstructor((Class[]) null); if (ctor != null) { @@ -249,17 +249,17 @@ public class AWTKeyStroke implements Serializable { private static synchronized AWTKeyStroke getCachedStroke (char keyChar, int keyCode, int modifiers, boolean onKeyRelease) { - Map cache = (Map)AppContext.getAppContext().get(APP_CONTEXT_CACHE_KEY); + Map cache = (Map)AppContext.getAppContext().get(APP_CONTEXT_CACHE_KEY); AWTKeyStroke cacheKey = (AWTKeyStroke)AppContext.getAppContext().get(APP_CONTEXT_KEYSTROKE_KEY); if (cache == null) { - cache = new HashMap(); + cache = new HashMap<>(); AppContext.getAppContext().put(APP_CONTEXT_CACHE_KEY, cache); } if (cacheKey == null) { try { - Class clazz = getAWTKeyStrokeClass(); + Class clazz = getAWTKeyStrokeClass(); cacheKey = (AWTKeyStroke)getCtor(clazz).newInstance((Object[]) null); AppContext.getAppContext().put(APP_CONTEXT_KEYSTROKE_KEY, cacheKey); } catch (InstantiationException e) { @@ -513,7 +513,7 @@ public class AWTKeyStroke implements Serializable { synchronized (AWTKeyStroke.class) { if (modifierKeywords == null) { - Map uninitializedMap = new HashMap(8, 1.0f); + Map uninitializedMap = new HashMap<>(8, 1.0f); uninitializedMap.put("shift", Integer.valueOf(InputEvent.SHIFT_DOWN_MASK |InputEvent.SHIFT_MASK)); @@ -861,12 +861,12 @@ public class AWTKeyStroke implements Serializable { } class VKCollection { - Map code2name; - Map name2code; + Map code2name; + Map name2code; public VKCollection() { - code2name = new HashMap(); - name2code = new HashMap(); + code2name = new HashMap<>(); + name2code = new HashMap<>(); } public synchronized void put(String name, Integer code) { diff --git a/jdk/src/share/classes/java/awt/CardLayout.java b/jdk/src/share/classes/java/awt/CardLayout.java index 32355efed60..35ee3379267 100644 --- a/jdk/src/share/classes/java/awt/CardLayout.java +++ b/jdk/src/share/classes/java/awt/CardLayout.java @@ -66,7 +66,7 @@ public class CardLayout implements LayoutManager2, * pairs of components and their names. * @see java.util.Vector */ - Vector vector = new Vector(); + Vector vector = new Vector<>(); /* * A pair of Component and String that represents its name. @@ -570,10 +570,10 @@ public class CardLayout implements LayoutManager2, if (f.defaulted("vector")) { // pre-1.4 stream - Hashtable tab = (Hashtable)f.get("tab", null); - vector = new Vector(); + Hashtable tab = (Hashtable)f.get("tab", null); + vector = new Vector<>(); if (tab != null && !tab.isEmpty()) { - for (Enumeration e = tab.keys() ; e.hasMoreElements() ; ) { + for (Enumeration e = tab.keys() ; e.hasMoreElements() ; ) { String key = (String)e.nextElement(); Component comp = (Component)tab.get(key); vector.add(new Card(key, comp)); @@ -594,7 +594,7 @@ public class CardLayout implements LayoutManager2, private void writeObject(ObjectOutputStream s) throws IOException { - Hashtable tab = new Hashtable(); + Hashtable tab = new Hashtable<>(); int ncomponents = vector.size(); for (int i = 0; i < ncomponents; i++) { Card card = (Card)vector.get(i); diff --git a/jdk/src/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java b/jdk/src/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java index 7d36530ce2b..3f53698f7b5 100644 --- a/jdk/src/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java +++ b/jdk/src/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java @@ -85,7 +85,7 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy * list should be reused if possible. */ transient private Container cachedRoot; - transient private List cachedCycle; + transient private List cachedCycle; /* * We suppose to use getFocusTraversalCycle & getComponentIndex methods in order @@ -111,7 +111,7 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy return cycle.indexOf(aComponent); } - private void enumerateCycle(Container container, List cycle) { + private void enumerateCycle(Container container, List cycle) { if (!(container.isVisible() && container.isDisplayable())) { return; } diff --git a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java index 7c0c39d8ffa..4685a88bb6b 100644 --- a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java +++ b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java @@ -808,13 +808,13 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { } } boolean stopPostProcessing = false; - java.util.List processors = getKeyEventPostProcessors(); + java.util.List processors = getKeyEventPostProcessors(); if (processors != null) { - for (java.util.Iterator iter = processors.iterator(); + for (java.util.Iterator iter = processors.iterator(); !stopPostProcessing && iter.hasNext(); ) { - stopPostProcessing = (((KeyEventPostProcessor)(iter.next())). - postProcessKeyEvent(e)); + stopPostProcessing = iter.next(). + postProcessKeyEvent(e); } } if (!stopPostProcessing) { @@ -1059,12 +1059,12 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { return true; } - java.util.List dispatchers = getKeyEventDispatchers(); + java.util.List dispatchers = getKeyEventDispatchers(); if (dispatchers != null) { - for (java.util.Iterator iter = dispatchers.iterator(); + for (java.util.Iterator iter = dispatchers.iterator(); iter.hasNext(); ) { - if (((KeyEventDispatcher)(iter.next())). + if (iter.next(). dispatchKeyEvent(ke)) { return true; @@ -1131,7 +1131,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { oppStroke = AWTKeyStroke.getAWTKeyStroke(stroke.getKeyCode(), stroke.getModifiers(), !stroke.isOnKeyRelease()); - Set toTest; + Set toTest; boolean contains, containsOpp; toTest = focusedComponent.getFocusTraversalKeys( diff --git a/jdk/src/share/classes/java/awt/GradientPaintContext.java b/jdk/src/share/classes/java/awt/GradientPaintContext.java index ac21d52da91..2536fa2cf04 100644 --- a/jdk/src/share/classes/java/awt/GradientPaintContext.java +++ b/jdk/src/share/classes/java/awt/GradientPaintContext.java @@ -41,7 +41,7 @@ class GradientPaintContext implements PaintContext { new DirectColorModel(24, 0x000000ff, 0x0000ff00, 0x00ff0000); static ColorModel cachedModel; - static WeakReference cached; + static WeakReference cached; static synchronized Raster getCachedRaster(ColorModel cm, int w, int h) { if (cm == cachedModel) { @@ -76,7 +76,7 @@ class GradientPaintContext implements PaintContext { } } cachedModel = cm; - cached = new WeakReference(ras); + cached = new WeakReference<>(ras); } double x1; diff --git a/jdk/src/share/classes/java/awt/GraphicsEnvironment.java b/jdk/src/share/classes/java/awt/GraphicsEnvironment.java index f3d49b78243..9e1da05e35f 100644 --- a/jdk/src/share/classes/java/awt/GraphicsEnvironment.java +++ b/jdk/src/share/classes/java/awt/GraphicsEnvironment.java @@ -95,18 +95,18 @@ public abstract class GraphicsEnvironment { String nm = AccessController.doPrivileged(new GetPropertyAction("java.awt.graphicsenv", null)); try { // long t0 = System.currentTimeMillis(); - Class geCls; + Class geCls; try { // First we try if the bootclassloader finds the requested // class. This way we can avoid to run in a privileged block. - geCls = Class.forName(nm); + geCls = (Class)Class.forName(nm); } catch (ClassNotFoundException ex) { // If the bootclassloader fails, we try again with the // application classloader. ClassLoader cl = ClassLoader.getSystemClassLoader(); - geCls = Class.forName(nm, true, cl); + geCls = (Class)Class.forName(nm, true, cl); } - ge = (GraphicsEnvironment) geCls.newInstance(); + ge = geCls.newInstance(); // long t1 = System.currentTimeMillis(); // System.out.println("GE creation took " + (t1-t0)+ "ms."); if (isHeadless()) { @@ -161,7 +161,7 @@ public abstract class GraphicsEnvironment { private static boolean getHeadlessProperty() { if (headless == null) { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction() { public Object run() { String nm = System.getProperty("java.awt.headless"); diff --git a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java index 51507696cff..9bccdbbeb2f 100644 --- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java @@ -348,7 +348,7 @@ public abstract class KeyboardFocusManager * Component of those Windows that has no such array of its own explicitly * set. */ - private Set[] defaultFocusTraversalKeys = new Set[4]; + private Set[] defaultFocusTraversalKeys = new Set[4]; /** * The current focus cycle root. If the focus owner is itself a focus cycle @@ -376,7 +376,7 @@ public abstract class KeyboardFocusManager * KeyEventDispatchers are registered, this field may be null or refer to * a List of length 0. */ - private java.util.LinkedList keyEventDispatchers; + private java.util.LinkedList keyEventDispatchers; /** * This KeyboardFocusManager's KeyEventPostProcessor chain. The List does @@ -385,12 +385,12 @@ public abstract class KeyboardFocusManager * If no other KeyEventPostProcessors are registered, this field may be * null or refer to a List of length 0. */ - private java.util.LinkedList keyEventPostProcessors; + private java.util.LinkedList keyEventPostProcessors; /** * Maps Windows to those Windows' most recent focus owners. */ - private static java.util.Map mostRecentFocusOwners = new WeakHashMap(); + private static java.util.Map> mostRecentFocusOwners = new WeakHashMap<>(); /** * We cache the permission used to verify that the calling thread is @@ -431,7 +431,7 @@ public abstract class KeyboardFocusManager */ public KeyboardFocusManager() { for (int i = 0; i < TRAVERSAL_KEY_LENGTH; i++) { - Set work_set = new HashSet(); + Set work_set = new HashSet<>(); for (int j = 0; j < defaultFocusTraversalKeyStrokes[i].length; j++) { work_set.add(defaultFocusTraversalKeyStrokes[i][j]); } @@ -1125,7 +1125,7 @@ public abstract class KeyboardFocusManager throw new IllegalArgumentException("cannot set null Set of default focus traversal keys"); } - Set oldKeys; + Set oldKeys; synchronized (this) { for (AWTKeyStroke keystroke : keystrokes) { @@ -1153,7 +1153,7 @@ public abstract class KeyboardFocusManager oldKeys = defaultFocusTraversalKeys[id]; defaultFocusTraversalKeys[id] = - Collections.unmodifiableSet(new HashSet(keystrokes)); + Collections.unmodifiableSet(new HashSet<>(keystrokes)); } firePropertyChange(defaultFocusTraversalKeyPropertyNames[id], @@ -1699,7 +1699,7 @@ public abstract class KeyboardFocusManager if (dispatcher != null) { synchronized (this) { if (keyEventDispatchers == null) { - keyEventDispatchers = new java.util.LinkedList(); + keyEventDispatchers = new java.util.LinkedList<>(); } keyEventDispatchers.add(dispatcher); } @@ -1787,7 +1787,7 @@ public abstract class KeyboardFocusManager if (processor != null) { synchronized (this) { if (keyEventPostProcessors == null) { - keyEventPostProcessors = new java.util.LinkedList(); + keyEventPostProcessors = new java.util.LinkedList<>(); } keyEventPostProcessors.add(processor); } @@ -1865,9 +1865,9 @@ public abstract class KeyboardFocusManager // of Component.parent fields. Since WeakHasMap refers to its // values strongly, we need to break the strong link from the // value (component) back to its key (window). - WeakReference weakValue = null; + WeakReference weakValue = null; if (component != null) { - weakValue = new WeakReference(component); + weakValue = new WeakReference<>(component); } mostRecentFocusOwners.put(window, weakValue); } @@ -1906,7 +1906,7 @@ public abstract class KeyboardFocusManager * javax.swing.JComponent.runInputVerifier() using reflection. */ static synchronized Component getMostRecentFocusOwner(Window window) { - WeakReference weakValue = + WeakReference weakValue = (WeakReference)mostRecentFocusOwners.get(window); return weakValue == null ? null : (Component)weakValue.get(); } @@ -2649,11 +2649,11 @@ public abstract class KeyboardFocusManager Component lastFocusOwner = null; Component currentFocusOwner = null; - for (Iterator iter = localLightweightRequests.iterator(); iter.hasNext(); ) { + for (Iterator iter = localLightweightRequests.iterator(); iter.hasNext(); ) { currentFocusOwner = manager.getGlobalFocusOwner(); LightweightFocusRequest lwFocusRequest = - (LightweightFocusRequest)iter.next(); + iter.next(); /* * WARNING: This is based on DKFM's logic solely! @@ -2978,12 +2978,12 @@ public abstract class KeyboardFocusManager if (hwFocusRequest != null) { heavyweightRequests.removeFirst(); if (hwFocusRequest.lightweightRequests != null) { - for (Iterator lwIter = hwFocusRequest.lightweightRequests. + for (Iterator lwIter = hwFocusRequest.lightweightRequests. iterator(); lwIter.hasNext(); ) { manager.dequeueKeyEvents - (-1, ((LightweightFocusRequest)lwIter.next()). + (-1, lwIter.next(). component); } } @@ -3063,8 +3063,8 @@ public abstract class KeyboardFocusManager // Accessor to private field isProxyActive of KeyEvent private static boolean isProxyActiveImpl(KeyEvent e) { if (proxyActive == null) { - proxyActive = (Field) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + proxyActive = AccessController.doPrivileged(new PrivilegedAction() { + public Field run() { Field field = null; try { field = KeyEvent.class.getDeclaredField("isProxyActive"); diff --git a/jdk/src/share/classes/java/awt/SequencedEvent.java b/jdk/src/share/classes/java/awt/SequencedEvent.java index b57cde2683f..0ae8dad64db 100644 --- a/jdk/src/share/classes/java/awt/SequencedEvent.java +++ b/jdk/src/share/classes/java/awt/SequencedEvent.java @@ -49,7 +49,7 @@ class SequencedEvent extends AWTEvent implements ActiveEvent { private static final int ID = java.awt.event.FocusEvent.FOCUS_LAST + 1; - private static final LinkedList list = new LinkedList(); + private static final LinkedList list = new LinkedList<>(); private final AWTEvent nested; private AppContext appContext; diff --git a/jdk/src/share/classes/java/awt/TexturePaintContext.java b/jdk/src/share/classes/java/awt/TexturePaintContext.java index a6d2e04615d..359071e1015 100644 --- a/jdk/src/share/classes/java/awt/TexturePaintContext.java +++ b/jdk/src/share/classes/java/awt/TexturePaintContext.java @@ -73,11 +73,11 @@ abstract class TexturePaintContext implements PaintContext { WritableRaster raster = bufImg.getRaster(); ColorModel cm = bufImg.getColorModel(); int maxw = devBounds.width; - Object val = hints.get(hints.KEY_INTERPOLATION); + Object val = hints.get(RenderingHints.KEY_INTERPOLATION); boolean filter = (val == null - ? (hints.get(hints.KEY_RENDERING) == hints.VALUE_RENDER_QUALITY) - : (val != hints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)); + ? (hints.get(RenderingHints.KEY_RENDERING) == RenderingHints.VALUE_RENDER_QUALITY) + : (val != RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)); if (raster instanceof IntegerInterleavedRaster && (!filter || isFilterableDCM(cm))) { @@ -234,8 +234,8 @@ abstract class TexturePaintContext implements PaintContext { return outRas; } - private static WeakReference xrgbRasRef; - private static WeakReference argbRasRef; + private static WeakReference xrgbRasRef; + private static WeakReference argbRasRef; synchronized static WritableRaster makeRaster(ColorModel cm, Raster srcRas, @@ -278,13 +278,13 @@ abstract class TexturePaintContext implements PaintContext { return; } if (xrgbmodel == cm) { - xrgbRasRef = new WeakReference(outRas); + xrgbRasRef = new WeakReference<>(outRas); } else if (argbmodel == cm) { - argbRasRef = new WeakReference(outRas); + argbRasRef = new WeakReference<>(outRas); } } - private static WeakReference byteRasRef; + private static WeakReference byteRasRef; synchronized static WritableRaster makeByteRaster(Raster srcRas, int w, int h) @@ -307,7 +307,7 @@ abstract class TexturePaintContext implements PaintContext { if (outRas == null) { return; } - byteRasRef = new WeakReference(outRas); + byteRasRef = new WeakReference<>(outRas); } public abstract WritableRaster makeRaster(int w, int h); diff --git a/jdk/src/share/classes/java/awt/WaitDispatchSupport.java b/jdk/src/share/classes/java/awt/WaitDispatchSupport.java index 1cfd24a1416..c9a671838a9 100644 --- a/jdk/src/share/classes/java/awt/WaitDispatchSupport.java +++ b/jdk/src/share/classes/java/awt/WaitDispatchSupport.java @@ -224,8 +224,8 @@ class WaitDispatchSupport implements SecondaryLoop { // starts. Thus, the enter() method will not hang. // // Event pump should be privileged. See 6300270. - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { run.run(); return null; } From 2f5f83e38c305cd5c3083631abffeda8c8355dbd Mon Sep 17 00:00:00 2001 From: Peter Allwin Date: Mon, 30 Sep 2013 14:28:53 +0200 Subject: [PATCH 0178/1294] 8012923: [parfait] File Descriptor Leak in jdk/src/windows/demo/jvmti/hprof/hprof_md.c Reviewed-by: chegar, sla, sspitsyn, mgronlun --- jdk/src/windows/demo/jvmti/hprof/hprof_md.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/jdk/src/windows/demo/jvmti/hprof/hprof_md.c b/jdk/src/windows/demo/jvmti/hprof/hprof_md.c index 90e15ed5b84..67cf2f63c4c 100644 --- a/jdk/src/windows/demo/jvmti/hprof/hprof_md.c +++ b/jdk/src/windows/demo/jvmti/hprof/hprof_md.c @@ -82,9 +82,6 @@ md_connect(char *hostname, unsigned short port) struct sockaddr_in s; int fd; - /* create a socket */ - fd = (int)socket(AF_INET, SOCK_STREAM, 0); - /* find remote host's addr from name */ if ((hentry = gethostbyname(hostname)) == NULL) { return -1; @@ -97,8 +94,15 @@ md_connect(char *hostname, unsigned short port) s.sin_port = htons(port); s.sin_family = AF_INET; + /* create a socket */ + fd = (int)socket(AF_INET, SOCK_STREAM, 0); + if (INVALID_SOCKET == fd) { + return 0; + } + /* now try connecting */ - if (-1 == connect(fd, (struct sockaddr*)&s, sizeof(s))) { + if (SOCKET_ERROR == connect(fd, (struct sockaddr*)&s, sizeof(s))) { + closesocket(fd); return 0; } return fd; From bae75822436b3f84a52d588efaaee64d8c935582 Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Thu, 19 Sep 2013 11:59:14 -0700 Subject: [PATCH 0179/1294] 7122707: Security Providers need to have their version numbers updated for JDK8 Reviewed-by: xuelei --- .../classes/apple/security/AppleProvider.java | 4 +- .../com/sun/crypto/provider/SunJCE.java | 2 +- .../com/sun/security/sasl/Provider.java | 4 +- .../jcp/xml/dsig/internal/dom/XMLDSigRI.java | 4 +- .../share/classes/sun/security/ec/SunEC.java | 4 +- .../sun/security/jgss/SunProvider.java | 4 +- .../jgss/wrapper/SunNativeProvider.java | 4 +- .../sun/security/pkcs11/SunPKCS11.java | 4 +- .../classes/sun/security/provider/MD4.java | 4 +- .../classes/sun/security/provider/Sun.java | 2 +- .../provider/VerificationProvider.java | 4 +- .../classes/sun/security/rsa/SunRsaSign.java | 4 +- .../sun/security/smartcardio/SunPCSC.java | 4 +- .../classes/sun/security/ssl/JsseJce.java | 2 +- .../classes/sun/security/ssl/SunJSSE.java | 4 +- .../sun/security/mscapi/SunMSCAPI.java | 4 +- .../Provider/ProviderVersionCheck.java | 60 +++++++++++++++++++ 17 files changed, 89 insertions(+), 29 deletions(-) create mode 100644 jdk/test/java/security/Provider/ProviderVersionCheck.java diff --git a/jdk/src/macosx/classes/apple/security/AppleProvider.java b/jdk/src/macosx/classes/apple/security/AppleProvider.java index e1e3e2fb682..654af3c5345 100644 --- a/jdk/src/macosx/classes/apple/security/AppleProvider.java +++ b/jdk/src/macosx/classes/apple/security/AppleProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ public final class AppleProvider extends Provider { public AppleProvider() { /* We are the Apple provider */ - super("Apple", 1.1, info); + super("Apple", 1.8d, info); AccessController.doPrivileged(new java.security.PrivilegedAction() { public Object run() { diff --git a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java index af828e2a651..08e1e2ae737 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java @@ -104,7 +104,7 @@ public final class SunJCE extends Provider { public SunJCE() { /* We are the "SunJCE" provider */ - super("SunJCE", 1.7d, info); + super("SunJCE", 1.8d, info); final String BLOCK_MODES = "ECB|CBC|PCBC|CTR|CTS|CFB|OFB" + "|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" + diff --git a/jdk/src/share/classes/com/sun/security/sasl/Provider.java b/jdk/src/share/classes/com/sun/security/sasl/Provider.java index 8b9c00c8800..986a18758a1 100644 --- a/jdk/src/share/classes/com/sun/security/sasl/Provider.java +++ b/jdk/src/share/classes/com/sun/security/sasl/Provider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -53,7 +53,7 @@ public final class Provider extends java.security.Provider { " server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5, NTLM)"; public Provider() { - super("SunSASL", 1.7d, info); + super("SunSASL", 1.8d, info); AccessController.doPrivileged(new PrivilegedAction() { public Void run() { diff --git a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java index 2cc871485b3..d4dd77b7948 100644 --- a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java +++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java @@ -28,7 +28,7 @@ * =========================================================================== */ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved. */ /* * $Id: XMLDSigRI.java 1400021 2012-10-19 10:16:04Z coheigea $ @@ -61,7 +61,7 @@ public final class XMLDSigRI extends Provider { public XMLDSigRI() { /* We are the XMLDSig provider */ - super("XMLDSig", 1.8, INFO); + super("XMLDSig", 1.8d, INFO); final Map map = new HashMap(); map.put("XMLSignatureFactory.DOM", diff --git a/jdk/src/share/classes/sun/security/ec/SunEC.java b/jdk/src/share/classes/sun/security/ec/SunEC.java index 539cea41162..31891696b4f 100644 --- a/jdk/src/share/classes/sun/security/ec/SunEC.java +++ b/jdk/src/share/classes/sun/security/ec/SunEC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ public final class SunEC extends Provider { } public SunEC() { - super("SunEC", 1.7d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)"); + super("SunEC", 1.8d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)"); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a diff --git a/jdk/src/share/classes/sun/security/jgss/SunProvider.java b/jdk/src/share/classes/sun/security/jgss/SunProvider.java index a49cb8a0fee..42396754b23 100644 --- a/jdk/src/share/classes/sun/security/jgss/SunProvider.java +++ b/jdk/src/share/classes/sun/security/jgss/SunProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ public final class SunProvider extends Provider { public SunProvider() { /* We are the Sun JGSS provider */ - super("SunJGSS", 1.7d, INFO); + super("SunJGSS", 1.8d, INFO); AccessController.doPrivileged( new java.security.PrivilegedAction() { diff --git a/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java b/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java index b0e81aa2a40..b0bb15d0036 100644 --- a/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java +++ b/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -120,7 +120,7 @@ public final class SunNativeProvider extends Provider { public SunNativeProvider() { /* We are the Sun NativeGSS provider */ - super(NAME, 1.0, INFO); + super(NAME, 1.8d, INFO); if (MECH_MAP != null) { AccessController.doPrivileged(new PutAllAction(this, MECH_MAP)); diff --git a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java index ee9169b59d8..b6dd35a80e8 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -94,7 +94,7 @@ public final class SunPKCS11 extends AuthProvider { } public SunPKCS11() { - super("SunPKCS11-Dummy", 1.7d, "SunPKCS11-Dummy"); + super("SunPKCS11-Dummy", 1.8d, "SunPKCS11-Dummy"); throw new ProviderException ("SunPKCS11 requires configuration file argument"); } @@ -127,7 +127,7 @@ public final class SunPKCS11 extends AuthProvider { public SunPKCS11(String configName, InputStream configStream) { super("SunPKCS11-" + Config.getConfig(configName, configStream).getName(), - 1.7d, Config.getConfig(configName, configStream).getDescription()); + 1.8d, Config.getConfig(configName, configStream).getDescription()); this.configName = configName; this.config = Config.removeConfig(configName); diff --git a/jdk/src/share/classes/sun/security/provider/MD4.java b/jdk/src/share/classes/sun/security/provider/MD4.java index d04639f18e5..346bc9db10d 100644 --- a/jdk/src/share/classes/sun/security/provider/MD4.java +++ b/jdk/src/share/classes/sun/security/provider/MD4.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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,7 +65,7 @@ public final class MD4 extends DigestBase { private final static Provider md4Provider; static { - md4Provider = new Provider("MD4Provider", 1.0d, "MD4 MessageDigest") { + md4Provider = new Provider("MD4Provider", 1.8d, "MD4 MessageDigest") { private static final long serialVersionUID = -8850464997518327965L; }; AccessController.doPrivileged(new PrivilegedAction() { diff --git a/jdk/src/share/classes/sun/security/provider/Sun.java b/jdk/src/share/classes/sun/security/provider/Sun.java index 4af2be50864..07ef2ff4a23 100644 --- a/jdk/src/share/classes/sun/security/provider/Sun.java +++ b/jdk/src/share/classes/sun/security/provider/Sun.java @@ -47,7 +47,7 @@ public final class Sun extends Provider { public Sun() { /* We are the SUN provider */ - super("SUN", 1.8, INFO); + super("SUN", 1.8d, INFO); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a diff --git a/jdk/src/share/classes/sun/security/provider/VerificationProvider.java b/jdk/src/share/classes/sun/security/provider/VerificationProvider.java index 082427d76df..296b0343706 100644 --- a/jdk/src/share/classes/sun/security/provider/VerificationProvider.java +++ b/jdk/src/share/classes/sun/security/provider/VerificationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ public final class VerificationProvider extends Provider { } public VerificationProvider() { - super("SunJarVerification", 1.7, "Jar Verification Provider"); + super("SunJarVerification", 1.8d, "Jar Verification Provider"); // register all algorithms normally registered by the Sun and SunRsaSign // providers, but only if they are missing if (ACTIVE == false) { diff --git a/jdk/src/share/classes/sun/security/rsa/SunRsaSign.java b/jdk/src/share/classes/sun/security/rsa/SunRsaSign.java index a00bf30172f..65ae02a080e 100644 --- a/jdk/src/share/classes/sun/security/rsa/SunRsaSign.java +++ b/jdk/src/share/classes/sun/security/rsa/SunRsaSign.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ public final class SunRsaSign extends Provider { private static final long serialVersionUID = 866040293550393045L; public SunRsaSign() { - super("SunRsaSign", 1.7d, "Sun RSA signature provider"); + super("SunRsaSign", 1.8d, "Sun RSA signature provider"); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a diff --git a/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java b/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java index fa931922495..c0cb85688f9 100644 --- a/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java +++ b/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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,7 +40,7 @@ public final class SunPCSC extends Provider { private static final long serialVersionUID = 6168388284028876579L; public SunPCSC() { - super("SunPCSC", 1.7d, "Sun PC/SC provider"); + super("SunPCSC", 1.8d, "Sun PC/SC provider"); AccessController.doPrivileged(new PrivilegedAction() { public Void run() { put("TerminalFactory.PC/SC", "sun.security.smartcardio.SunPCSC$Factory"); diff --git a/jdk/src/share/classes/sun/security/ssl/JsseJce.java b/jdk/src/share/classes/sun/security/ssl/JsseJce.java index d128f2e7029..4c98772aeca 100644 --- a/jdk/src/share/classes/sun/security/ssl/JsseJce.java +++ b/jdk/src/share/classes/sun/security/ssl/JsseJce.java @@ -110,7 +110,7 @@ final class JsseJce { private static final long serialVersionUID = -3284138292032213752L; SunCertificates(final Provider p) { - super("SunCertificates", 1.0d, "SunJSSE internal"); + super("SunCertificates", 1.8d, "SunJSSE internal"); AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { diff --git a/jdk/src/share/classes/sun/security/ssl/SunJSSE.java b/jdk/src/share/classes/sun/security/ssl/SunJSSE.java index 08d03f7042b..aa55be174d9 100644 --- a/jdk/src/share/classes/sun/security/ssl/SunJSSE.java +++ b/jdk/src/share/classes/sun/security/ssl/SunJSSE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,7 +131,7 @@ public abstract class SunJSSE extends java.security.Provider { private SunJSSE(java.security.Provider cryptoProvider, String providerName) { - super("SunJSSE", 1.6d, fipsInfo + providerName + ")"); + super("SunJSSE", 1.8d, fipsInfo + providerName + ")"); subclassCheck(); if (cryptoProvider == null) { // Calling Security.getProvider() will cause other providers to be diff --git a/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java b/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java index 1af669415ee..7725b27d3c6 100644 --- a/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java +++ b/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -56,7 +56,7 @@ public final class SunMSCAPI extends Provider { } public SunMSCAPI() { - super("SunMSCAPI", 1.7d, INFO); + super("SunMSCAPI", 1.8d, INFO); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a diff --git a/jdk/test/java/security/Provider/ProviderVersionCheck.java b/jdk/test/java/security/Provider/ProviderVersionCheck.java new file mode 100644 index 00000000000..555d1df9428 --- /dev/null +++ b/jdk/test/java/security/Provider/ProviderVersionCheck.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.Provider; +import java.security.Security; +import java.lang.Exception; + +/* + * @test + * @bug 7122707 + * @run main/othervm ProviderVersionCheck + * @summary Verify all providers in the default Providers list have the proper + * version for the release + * @author Anthony Scarpino + */ + +public class ProviderVersionCheck { + + public static void main(String arg[]) throws Exception{ + + boolean failure = false; + + for (Provider p: Security.getProviders()) { + System.out.print(p.getName() + " "); + if (p.getVersion() != 1.8d) { + System.out.println("failed. " + "Version received was " + + p.getVersion()); + failure = true; + } else { + System.out.println("passed."); + } + } + + if (failure) { + throw new Exception("Provider(s) failed to have the expected " + + "version value."); + } + } + +} From cf7cbcdce886a7385a1ee152e54cf3236ec63057 Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Wed, 18 Sep 2013 14:57:29 -0700 Subject: [PATCH 0180/1294] 8004283: test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh failing intermittently Reviewed-by: vinnie --- jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh b/jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh index 30334555302..ddfc9da0ac6 100644 --- a/jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh +++ b/jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 2013, 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 @@ -143,7 +143,8 @@ fi cd ${TESTSRC} ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} \ -DDIR=${TESTSRC}${FS}BasicData${FS} \ - -classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \ + -classpath \ + ${TESTCLASSES}${PS}${TESTCLASSES}${FS}..${PS}${TESTSRC}${FS}loader.jar \ -DCUSTOM_DB_DIR=${TESTCLASSES} \ -DCUSTOM_P11_CONFIG=${TESTSRC}${FS}BasicData${FS}p11-${token}.txt \ -DNO_DEFAULT=true \ From e9806ae426add1c7d412235d5d30fd1b6536984f Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Mon, 2 Sep 2013 09:52:08 -0700 Subject: [PATCH 0181/1294] 8009438: sun/security/pkcs11/Secmod tests failing on Ubuntu 12.04 Reviewed-by: vinnie --- jdk/src/share/classes/sun/security/pkcs11/Secmod.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/sun/security/pkcs11/Secmod.java b/jdk/src/share/classes/sun/security/pkcs11/Secmod.java index 927a32ae761..1d2c5c0bdc6 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/Secmod.java +++ b/jdk/src/share/classes/sun/security/pkcs11/Secmod.java @@ -756,8 +756,12 @@ public final class Secmod { if (DEBUG) System.out.println("handles: " + handles.length); for (long handle : handles) { - TrustAttributes trust = new TrustAttributes(token, session, handle); - trustMap.put(trust.getHash(), trust); + try { + TrustAttributes trust = new TrustAttributes(token, session, handle); + trustMap.put(trust.getHash(), trust); + } catch (PKCS11Exception e) { + // skip put on pkcs11 error + } } } finally { token.releaseSession(session); From 547f4dea7b79f577a7b86e6b6c0014ba5940ae81 Mon Sep 17 00:00:00 2001 From: Niclas Adlertz Date: Mon, 2 Sep 2013 22:44:57 +0200 Subject: [PATCH 0182/1294] 8024095: Missing brackets in local scheduling code Added brackets for if-statement Reviewed-by: kvn, roland --- hotspot/src/share/vm/opto/lcm.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp index d57d9f64b73..63deec31b3f 100644 --- a/hotspot/src/share/vm/opto/lcm.cpp +++ b/hotspot/src/share/vm/opto/lcm.cpp @@ -550,11 +550,12 @@ void PhaseCFG::needed_for_next_call(Block* block, Node* this_call, VectorSet& ne Node* call = NULL; for (DUIterator_Fast imax, i = this_call->fast_outs(imax); i < imax; i++) { Node* m = this_call->fast_out(i); - if(get_block_for_node(m) == block && // Local-block user + if (get_block_for_node(m) == block && // Local-block user m != this_call && // Not self-start node - m->is_MachCall() ) + m->is_MachCall()) { call = m; break; + } } if (call == NULL) return; // No next call (e.g., block end is near) // Set next-call for all inputs to this call From 0382c78ff16d02de16679d80d2753740c3750d0b Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Mon, 2 Sep 2013 22:38:36 +0100 Subject: [PATCH 0183/1294] 8016177: structural most specific and stuckness Reviewed-by: jjg, vromero --- .../com/sun/tools/javac/code/Flags.java | 5 + .../com/sun/tools/javac/code/Lint.java | 5 + .../com/sun/tools/javac/code/Types.java | 2 +- .../com/sun/tools/javac/comp/Attr.java | 51 +-- .../com/sun/tools/javac/comp/Check.java | 80 +++- .../sun/tools/javac/comp/DeferredAttr.java | 361 ++++++++++++----- .../com/sun/tools/javac/comp/Infer.java | 382 +++++++++++++----- .../com/sun/tools/javac/comp/Resolve.java | 101 +++-- .../tools/javac/resources/compiler.properties | 13 +- .../com/sun/tools/javac/tree/JCTree.java | 7 + .../com/sun/tools/javac/util/GraphUtils.java | 41 +- .../com/sun/tools/javac/util/List.java | 13 + .../Diagnostics/compressed/T8012003c.out | 1 - .../diags/examples/BadArgTypesInLambda.java | 3 - .../IncompatibleArgTypesInMethodRef.java | 1 + ...java => PotentiallyAmbiguousOverload.java} | 21 +- .../tools/javac/lambda/8016177/T8016177a.java | 45 +++ .../tools/javac/lambda/8016177/T8016177a.out | 8 + .../tools/javac/lambda/8016177/T8016177b.java | 34 ++ .../tools/javac/lambda/8016177/T8016177b.out | 2 + .../tools/javac/lambda/8016177/T8016177c.java | 47 +++ .../tools/javac/lambda/8016177/T8016177c.out | 4 + .../tools/javac/lambda/8016177/T8016177d.java | 58 +++ .../tools/javac/lambda/8016177/T8016177e.java | 46 +++ .../tools/javac/lambda/8016177/T8016177f.java | 94 +++++ .../tools/javac/lambda/8016177/T8016177g.java | 37 ++ .../tools/javac/lambda/8016177/T8016177g.out | 2 + .../test/tools/javac/lambda/BadRecovery.out | 3 +- .../javac/lambda/ErroneousLambdaExpr.java | 3 +- .../javac/lambda/ErroneousLambdaExpr.out | 2 + .../tools/javac/lambda/MethodReference22.out | 14 +- .../tools/javac/lambda/MethodReference23.out | 4 +- .../tools/javac/lambda/MethodReference41.java | 29 +- .../tools/javac/lambda/MethodReference41.out | 4 + .../tools/javac/lambda/MethodReference42.java | 30 +- .../tools/javac/lambda/MethodReference42.out | 4 + .../tools/javac/lambda/MethodReference43.java | 34 +- .../tools/javac/lambda/MethodReference43.out | 5 + .../tools/javac/lambda/MethodReference44.java | 30 +- .../tools/javac/lambda/MethodReference44.out | 4 + .../tools/javac/lambda/MethodReference46.java | 30 +- .../tools/javac/lambda/MethodReference46.out | 4 + .../tools/javac/lambda/MethodReference47.java | 12 +- .../tools/javac/lambda/MethodReference47.out | 2 +- .../tools/javac/lambda/MethodReference48.java | 30 +- .../tools/javac/lambda/MethodReference48.out | 3 + .../tools/javac/lambda/MethodReference70.out | 2 +- .../tools/javac/lambda/MethodReference71.out | 2 +- .../tools/javac/lambda/MostSpecific04.java | 19 +- .../tools/javac/lambda/MostSpecific04.out | 2 + .../tools/javac/lambda/MostSpecific05.java | 19 +- .../tools/javac/lambda/MostSpecific05.out | 2 + .../tools/javac/lambda/MostSpecific08.java | 12 +- .../tools/javac/lambda/MostSpecific08.out | 4 + .../test/tools/javac/lambda/TargetType01.java | 2 +- .../test/tools/javac/lambda/TargetType01.out | 3 + .../test/tools/javac/lambda/TargetType02.java | 29 +- .../test/tools/javac/lambda/TargetType02.out | 3 + .../test/tools/javac/lambda/TargetType10.java | 4 +- .../test/tools/javac/lambda/TargetType10.out | 2 - .../test/tools/javac/lambda/TargetType21.java | 4 +- .../test/tools/javac/lambda/TargetType21.out | 10 +- .../test/tools/javac/lambda/TargetType24.java | 9 +- .../test/tools/javac/lambda/TargetType24.out | 16 +- .../test/tools/javac/lambda/TargetType26.out | 2 +- .../test/tools/javac/lambda/TargetType27.out | 2 +- .../test/tools/javac/lambda/TargetType39.out | 4 +- .../test/tools/javac/lambda/TargetType43.out | 3 +- .../test/tools/javac/lambda/TargetType66.java | 4 +- .../test/tools/javac/lambda/TargetType66.out | 9 +- .../StructuralMostSpecificTest.java | 20 +- .../lambda/typeInference/InferenceTest5.java | 122 ------ ...enceTest_neg5.java => InferenceTest6.java} | 8 +- .../typeInference/InferenceTest_neg1_2.out | 7 +- .../typeInference/InferenceTest_neg5.out | 2 - .../combo/TypeInferenceComboTest.java | 7 +- 76 files changed, 1377 insertions(+), 668 deletions(-) rename langtools/test/tools/javac/diags/examples/{CyclicInference.java => PotentiallyAmbiguousOverload.java} (75%) create mode 100644 langtools/test/tools/javac/lambda/8016177/T8016177a.java create mode 100644 langtools/test/tools/javac/lambda/8016177/T8016177a.out create mode 100644 langtools/test/tools/javac/lambda/8016177/T8016177b.java create mode 100644 langtools/test/tools/javac/lambda/8016177/T8016177b.out create mode 100644 langtools/test/tools/javac/lambda/8016177/T8016177c.java create mode 100644 langtools/test/tools/javac/lambda/8016177/T8016177c.out create mode 100644 langtools/test/tools/javac/lambda/8016177/T8016177d.java create mode 100644 langtools/test/tools/javac/lambda/8016177/T8016177e.java create mode 100644 langtools/test/tools/javac/lambda/8016177/T8016177f.java create mode 100644 langtools/test/tools/javac/lambda/8016177/T8016177g.java create mode 100644 langtools/test/tools/javac/lambda/8016177/T8016177g.out create mode 100644 langtools/test/tools/javac/lambda/ErroneousLambdaExpr.out create mode 100644 langtools/test/tools/javac/lambda/MethodReference41.out create mode 100644 langtools/test/tools/javac/lambda/MethodReference42.out create mode 100644 langtools/test/tools/javac/lambda/MethodReference43.out create mode 100644 langtools/test/tools/javac/lambda/MethodReference44.out create mode 100644 langtools/test/tools/javac/lambda/MethodReference46.out create mode 100644 langtools/test/tools/javac/lambda/MethodReference48.out create mode 100644 langtools/test/tools/javac/lambda/MostSpecific04.out create mode 100644 langtools/test/tools/javac/lambda/MostSpecific05.out create mode 100644 langtools/test/tools/javac/lambda/MostSpecific08.out create mode 100644 langtools/test/tools/javac/lambda/TargetType01.out create mode 100644 langtools/test/tools/javac/lambda/TargetType02.out delete mode 100644 langtools/test/tools/javac/lambda/TargetType10.out delete mode 100644 langtools/test/tools/javac/lambda/typeInference/InferenceTest5.java rename langtools/test/tools/javac/lambda/typeInference/{InferenceTest_neg5.java => InferenceTest6.java} (76%) delete mode 100644 langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java index 12acc8dc27e..b2da2807363 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java @@ -266,6 +266,11 @@ public class Flags { */ public static final long THROWS = 1L<<47; + /** + * Flag that marks potentially ambiguous overloads + */ + public static final long POTENTIALLY_AMBIGUOUS = 1L<<48; + /** Modifier masks. */ public static final int diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java index a6956f341ec..fb0ea30429f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java @@ -174,6 +174,11 @@ public class Lint */ OPTIONS("options"), + /** + * Warn about issues regarding method overloads. + */ + OVERLOADS("overloads"), + /** * Warn about issues regarding method overrides. */ diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 06744bf6d06..0d060b60bb7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -3055,7 +3055,7 @@ public class Types { /** * Does t have the same bounds for quantified variables as s? */ - boolean hasSameBounds(ForAll t, ForAll s) { + public boolean hasSameBounds(ForAll t, ForAll s) { List l1 = t.tvars; List l2 = s.tvars; while (l1.nonEmpty() && l2.nonEmpty() && diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 6ef409d9339..ad0d5003144 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2396,35 +2396,11 @@ public class Attr extends JCTree.Visitor { new ResultInfo(VAL, lambdaType.getReturnType(), funcContext); localEnv.info.returnResult = bodyResultInfo; - Log.DeferredDiagnosticHandler lambdaDeferredHandler = new Log.DeferredDiagnosticHandler(log); - try { - if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) { - attribTree(that.getBody(), localEnv, bodyResultInfo); - } else { - JCBlock body = (JCBlock)that.body; - attribStats(body.stats, localEnv); - } - - if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.SPECULATIVE) { - //check for errors in lambda body - for (JCDiagnostic deferredDiag : lambdaDeferredHandler.getDiagnostics()) { - if (deferredDiag.getKind() == JCDiagnostic.Kind.ERROR) { - resultInfo.checkContext - .report(that, diags.fragment("bad.arg.types.in.lambda", TreeInfo.types(that.params), - deferredDiag)); //hidden diag parameter - //we mark the lambda as erroneous - this is crucial in the recovery step - //as parameter-dependent type error won't be reported in that stage, - //meaning that a lambda will be deemed erroeneous only if there is - //a target-independent error (which will cause method diagnostic - //to be skipped). - result = that.type = types.createErrorType(target); - return; - } - } - } - } finally { - lambdaDeferredHandler.reportDeferredDiagnostics(); - log.popDiagnosticHandler(lambdaDeferredHandler); + if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) { + attribTree(that.getBody(), localEnv, bodyResultInfo); + } else { + JCBlock body = (JCBlock)that.body; + attribStats(body.stats, localEnv); } result = check(that, target, VAL, resultInfo); @@ -3731,7 +3707,7 @@ public class Attr extends JCTree.Visitor { * Check that method arguments conform to its instantiation. **/ public Type checkMethod(Type site, - Symbol sym, + final Symbol sym, ResultInfo resultInfo, Env env, final List argtrees, @@ -3820,8 +3796,19 @@ public class Attr extends JCTree.Visitor { resultInfo.checkContext.report(env.tree.pos(), ex.getDiagnostic()); return types.createErrorType(site); } catch (Resolve.InapplicableMethodException ex) { - Assert.error(ex.getDiagnostic().getMessage(Locale.getDefault())); - return null; + final JCDiagnostic diag = ex.getDiagnostic(); + Resolve.InapplicableSymbolError errSym = rs.new InapplicableSymbolError(null) { + @Override + protected Pair errCandidate() { + return new Pair(sym, diag); + } + }; + List argtypes2 = Type.map(argtypes, + rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase)); + JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, + env.tree, sym, site, sym.name, argtypes2, typeargtypes); + log.report(errDiag); + return types.createErrorType(site); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 1bb051b1461..5529627ed90 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -2368,7 +2368,10 @@ public class Check { //for each method m1 that is overridden (directly or indirectly) //by method 'sym' in 'site'... for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { - if (!sym.overrides(m1, site.tsym, types, false)) continue; + if (!sym.overrides(m1, site.tsym, types, false)) { + checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)m1); + continue; + } //...check each method m2 that is a member of 'site' for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { if (m2 == m1) continue; @@ -2406,14 +2409,17 @@ public class Check { for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) { //if (i) the signature of 'sym' is not a subsignature of m1 (seen as //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error - if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck) && - types.hasSameArgs(s.erasure(types), sym.erasure(types))) { - log.error(pos, - "name.clash.same.erasure.no.hide", - sym, sym.location(), - s, s.location()); - return; - } + if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) { + if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) { + log.error(pos, + "name.clash.same.erasure.no.hide", + sym, sym.location(), + s, s.location()); + return; + } else { + checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s); + } + } } } @@ -2496,6 +2502,62 @@ public class Check { } } + /** + * Report warnings for potentially ambiguous method declarations. Two declarations + * are potentially ambiguous if they feature two unrelated functional interface + * in same argument position (in which case, a call site passing an implicit + * lambda would be ambiguous). + */ + void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site, + MethodSymbol msym1, MethodSymbol msym2) { + if (msym1 != msym2 && + allowDefaultMethods && + lint.isEnabled(LintCategory.OVERLOADS) && + (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 && + (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) { + Type mt1 = types.memberType(site, msym1); + Type mt2 = types.memberType(site, msym2); + //if both generic methods, adjust type variables + if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) && + types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) { + mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars); + } + //expand varargs methods if needed + int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length()); + List args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true); + List args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true); + //if arities don't match, exit + if (args1.length() != args2.length()) return; + boolean potentiallyAmbiguous = false; + while (args1.nonEmpty() && args2.nonEmpty()) { + Type s = args1.head; + Type t = args2.head; + if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) { + if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) && + types.findDescriptorType(s).getParameterTypes().length() > 0 && + types.findDescriptorType(s).getParameterTypes().length() == + types.findDescriptorType(t).getParameterTypes().length()) { + potentiallyAmbiguous = true; + } else { + break; + } + } + args1 = args1.tail; + args2 = args2.tail; + } + if (potentiallyAmbiguous) { + //we found two incompatible functional interfaces with same arity + //this means a call site passing an implicit lambda would be ambigiuous + msym1.flags_field |= POTENTIALLY_AMBIGUOUS; + msym2.flags_field |= POTENTIALLY_AMBIGUOUS; + log.warning(LintCategory.OVERLOADS, pos, "potentially.ambiguous.overload", + msym1, msym1.location(), + msym2, msym2.location()); + return; + } + } + } + /** Report a conflict between a user symbol and a synthetic symbol. */ private void syntheticError(DiagnosticPosition pos, Symbol sym) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 6b7cfdd37ee..4db110579f7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -25,6 +25,7 @@ package com.sun.tools.javac.comp; +import com.sun.source.tree.MemberReferenceTree; import com.sun.tools.javac.code.*; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.util.*; @@ -39,7 +40,9 @@ import com.sun.tools.javac.tree.JCTree.*; import java.util.ArrayList; +import java.util.Collections; import java.util.EnumSet; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; @@ -98,7 +101,7 @@ public class DeferredAttr extends JCTree.Visitor { emptyDeferredAttrContext = new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) { @Override - void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List stuckVars) { + void addDeferredAttrNode(DeferredType dt, ResultInfo ri, DeferredStuckPolicy deferredStuckPolicy) { Assert.error("Empty deferred context!"); } @Override @@ -149,15 +152,15 @@ public class DeferredAttr extends JCTree.Visitor { class Entry { JCTree speculativeTree; - Resolve.MethodResolutionPhase phase; + ResultInfo resultInfo; - public Entry(JCTree speculativeTree, MethodResolutionPhase phase) { + public Entry(JCTree speculativeTree, ResultInfo resultInfo) { this.speculativeTree = speculativeTree; - this.phase = phase; + this.resultInfo = resultInfo; } - boolean matches(Resolve.MethodResolutionPhase phase) { - return this.phase == phase; + boolean matches(MethodResolutionPhase phase) { + return resultInfo.checkContext.deferredAttrContext().phase == phase; } } @@ -178,12 +181,13 @@ public class DeferredAttr extends JCTree.Visitor { * Stores a speculative cache entry corresponding to given symbol * and resolution phase */ - void put(Symbol msym, JCTree speculativeTree, MethodResolutionPhase phase) { + void put(JCTree speculativeTree, ResultInfo resultInfo) { + Symbol msym = resultInfo.checkContext.deferredAttrContext().msym; List entries = cache.get(msym); if (entries == null) { entries = List.nil(); } - cache.put(msym, entries.prepend(new Entry(speculativeTree, phase))); + cache.put(msym, entries.prepend(new Entry(speculativeTree, resultInfo))); } } @@ -203,15 +207,24 @@ public class DeferredAttr extends JCTree.Visitor { * attribution round must follow one or more speculative rounds. */ Type check(ResultInfo resultInfo) { - return check(resultInfo, stuckVars(tree, env, resultInfo), basicCompleter); + DeferredStuckPolicy deferredStuckPolicy; + if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) { + deferredStuckPolicy = dummyStuckPolicy; + } else if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.SPECULATIVE) { + deferredStuckPolicy = new OverloadStuckPolicy(resultInfo, this); + } else { + deferredStuckPolicy = new CheckStuckPolicy(resultInfo, this); + } + return check(resultInfo, deferredStuckPolicy, basicCompleter); } - Type check(ResultInfo resultInfo, List stuckVars, DeferredTypeCompleter deferredTypeCompleter) { + private Type check(ResultInfo resultInfo, DeferredStuckPolicy deferredStuckPolicy, + DeferredTypeCompleter deferredTypeCompleter) { DeferredAttrContext deferredAttrContext = resultInfo.checkContext.deferredAttrContext(); Assert.check(deferredAttrContext != emptyDeferredAttrContext); - if (stuckVars.nonEmpty()) { - deferredAttrContext.addDeferredAttrNode(this, resultInfo, stuckVars); + if (deferredStuckPolicy.isStuck()) { + deferredAttrContext.addDeferredAttrNode(this, resultInfo, deferredStuckPolicy); return Type.noType; } else { try { @@ -236,6 +249,7 @@ public class DeferredAttr extends JCTree.Visitor { Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext); } + /** * A basic completer for deferred types. This completer type-checks a deferred type * using attribution; depending on the attribution mode, this could be either standard @@ -249,7 +263,7 @@ public class DeferredAttr extends JCTree.Visitor { //speculative rounds... Assert.check(dt.mode == null || dt.mode == AttrMode.SPECULATIVE); JCTree speculativeTree = attribSpeculative(dt.tree, dt.env, resultInfo); - dt.speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase); + dt.speculativeCache.put(speculativeTree, resultInfo); return speculativeTree.type; case CHECK: Assert.check(dt.mode != null); @@ -267,6 +281,45 @@ public class DeferredAttr extends JCTree.Visitor { } }; + /** + * Policy for detecting stuck expressions. Different criteria might cause + * an expression to be judged as stuck, depending on whether the check + * is performed during overload resolution or after most specific. + */ + interface DeferredStuckPolicy { + /** + * Has the policy detected that a given expression should be considered stuck? + */ + boolean isStuck(); + /** + * Get the set of inference variables a given expression depends upon. + */ + Set stuckVars(); + /** + * Get the set of inference variables which might get new constraints + * if a given expression is being type-checked. + */ + Set depVars(); + } + + /** + * Basic stuck policy; an expression is never considered to be stuck. + */ + DeferredStuckPolicy dummyStuckPolicy = new DeferredStuckPolicy() { + @Override + public boolean isStuck() { + return false; + } + @Override + public Set stuckVars() { + return Collections.emptySet(); + } + @Override + public Set depVars() { + return Collections.emptySet(); + } + }; + /** * The 'mode' in which the deferred type is to be type-checked */ @@ -388,8 +441,9 @@ public class DeferredAttr extends JCTree.Visitor { * Adds a node to the list of deferred attribution nodes - used by Resolve.rawCheckArgumentsApplicable * Nodes added this way act as 'roots' for the out-of-order method checking process. */ - void addDeferredAttrNode(final DeferredType dt, ResultInfo resultInfo, List stuckVars) { - deferredAttrNodes.add(new DeferredAttrNode(dt, resultInfo, stuckVars)); + void addDeferredAttrNode(final DeferredType dt, ResultInfo resultInfo, + DeferredStuckPolicy deferredStuckPolicy) { + deferredAttrNodes.add(new DeferredAttrNode(dt, resultInfo, deferredStuckPolicy)); } /** @@ -400,23 +454,52 @@ public class DeferredAttr extends JCTree.Visitor { */ void complete() { while (!deferredAttrNodes.isEmpty()) { - Set stuckVars = new LinkedHashSet(); + Map> depVarsMap = new LinkedHashMap>(); + List stuckVars = List.nil(); boolean progress = false; //scan a defensive copy of the node list - this is because a deferred //attribution round can add new nodes to the list for (DeferredAttrNode deferredAttrNode : List.from(deferredAttrNodes)) { if (!deferredAttrNode.process(this)) { - stuckVars.addAll(deferredAttrNode.stuckVars); + List restStuckVars = + List.from(deferredAttrNode.deferredStuckPolicy.stuckVars()) + .intersect(inferenceContext.restvars()); + stuckVars = stuckVars.prependList(restStuckVars); + //update dependency map + for (Type t : List.from(deferredAttrNode.deferredStuckPolicy.depVars()) + .intersect(inferenceContext.restvars())) { + Set prevDeps = depVarsMap.get(t); + if (prevDeps == null) { + prevDeps = new LinkedHashSet(); + depVarsMap.put(t, prevDeps); + } + prevDeps.addAll(restStuckVars); + } } else { deferredAttrNodes.remove(deferredAttrNode); progress = true; } } if (!progress) { + DeferredAttrContext dac = this; + while (dac != emptyDeferredAttrContext) { + if (dac.mode == AttrMode.SPECULATIVE) { + //unsticking does not take place during overload + break; + } + dac = dac.parent; + } //remove all variables that have already been instantiated //from the list of stuck variables - inferenceContext.solveAny(List.from(stuckVars), warn); - inferenceContext.notifyChange(); + try { + inferenceContext.solveAny(stuckVars, depVarsMap, warn); + inferenceContext.notifyChange(); + } catch (Infer.GraphStrategy.NodeNotFoundException ex) { + //this means that we are in speculative mode and the + //set of contraints are too tight for progess to be made. + //Just leave the remaining expressions as stuck. + break; + } } } } @@ -426,7 +509,7 @@ public class DeferredAttr extends JCTree.Visitor { * Class representing a deferred attribution node. It keeps track of * a deferred type, along with the expected target type information. */ - class DeferredAttrNode implements Infer.FreeTypeListener { + class DeferredAttrNode { /** underlying deferred type */ DeferredType dt; @@ -434,22 +517,13 @@ public class DeferredAttr extends JCTree.Visitor { /** underlying target type information */ ResultInfo resultInfo; - /** list of uninferred inference variables causing this node to be stuck */ - List stuckVars; + /** stuck policy associated with this node */ + DeferredStuckPolicy deferredStuckPolicy; - DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, List stuckVars) { + DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, DeferredStuckPolicy deferredStuckPolicy) { this.dt = dt; this.resultInfo = resultInfo; - this.stuckVars = stuckVars; - if (!stuckVars.isEmpty()) { - resultInfo.checkContext.inferenceContext().addFreeTypeListener(stuckVars, this); - } - } - - @Override - public void typesInferred(InferenceContext inferenceContext) { - stuckVars = List.nil(); - resultInfo = resultInfo.dup(inferenceContext.asInstType(resultInfo.pt)); + this.deferredStuckPolicy = deferredStuckPolicy; } /** @@ -457,24 +531,41 @@ public class DeferredAttr extends JCTree.Visitor { * Invariant: a stuck node cannot be processed. */ @SuppressWarnings("fallthrough") - boolean process(DeferredAttrContext deferredAttrContext) { + boolean process(final DeferredAttrContext deferredAttrContext) { switch (deferredAttrContext.mode) { case SPECULATIVE: - dt.check(resultInfo, List.nil(), new StructuralStuckChecker()); - return true; + if (deferredStuckPolicy.isStuck()) { + dt.check(resultInfo, dummyStuckPolicy, new StructuralStuckChecker()); + return true; + } else { + Assert.error("Cannot get here"); + } case CHECK: - if (stuckVars.nonEmpty()) { + if (deferredStuckPolicy.isStuck()) { //stuck expression - see if we can propagate if (deferredAttrContext.parent != emptyDeferredAttrContext && - Type.containsAny(deferredAttrContext.parent.inferenceContext.inferencevars, List.from(stuckVars))) { - deferredAttrContext.parent.deferredAttrNodes.add(this); - dt.check(resultInfo, List.nil(), dummyCompleter); + Type.containsAny(deferredAttrContext.parent.inferenceContext.inferencevars, + List.from(deferredStuckPolicy.stuckVars()))) { + deferredAttrContext.parent.addDeferredAttrNode(dt, + resultInfo.dup(new Check.NestedCheckContext(resultInfo.checkContext) { + @Override + public InferenceContext inferenceContext() { + return deferredAttrContext.parent.inferenceContext; + } + @Override + public DeferredAttrContext deferredAttrContext() { + return deferredAttrContext.parent; + } + }), deferredStuckPolicy); + dt.tree.type = Type.stuckType; return true; } else { return false; } } else { - dt.check(resultInfo, stuckVars, basicCompleter); + ResultInfo instResultInfo = + resultInfo.dup(deferredAttrContext.inferenceContext.asInstType(resultInfo.pt)); + dt.check(instResultInfo, dummyStuckPolicy, basicCompleter); return true; } default: @@ -489,12 +580,14 @@ public class DeferredAttr extends JCTree.Visitor { ResultInfo resultInfo; InferenceContext inferenceContext; + Env env; public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { this.resultInfo = resultInfo; this.inferenceContext = deferredAttrContext.inferenceContext; + this.env = dt.env; dt.tree.accept(this); - dt.speculativeCache.put(deferredAttrContext.msym, stuckTree, deferredAttrContext.phase); + dt.speculativeCache.put(stuckTree, resultInfo); return Type.noType; } @@ -541,15 +634,25 @@ public class DeferredAttr extends JCTree.Visitor { } catch (Types.FunctionDescriptorLookupError ex) { checkContext.report(null, ex.getDiagnostic()); } - switch (tree.sym.kind) { + Env localEnv = env.dup(tree); + JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv, + attr.memberReferenceQualifierResult(tree)); + ListBuffer argtypes = ListBuffer.lb(); + for (Type t : types.findDescriptorType(pt).getParameterTypes()) { + argtypes.append(Type.noType); + } + JCMemberReference mref2 = new TreeCopier(make).copy(tree); + mref2.expr = exprTree; + Pair lookupRes = + rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type, + tree.name, argtypes.toList(), null, true, rs.arityMethodCheck, inferenceContext); + switch (lookupRes.fst.kind) { //note: as argtypes are erroneous types, type-errors must //have been caused by arity mismatch case Kinds.ABSENT_MTH: case Kinds.WRONG_MTH: case Kinds.WRONG_MTHS: - case Kinds.STATICERR: - case Kinds.MISSING_ENCL: - checkContext.report(null, diags.fragment("incompatible.arg.types.in.mref")); + checkContext.report(tree, diags.fragment("incompatible.arg.types.in.mref")); } } } @@ -575,18 +678,12 @@ public class DeferredAttr extends JCTree.Visitor { infer.emptyContext, emptyDeferredAttrContext, types.noWarnings); } - protected boolean validState(DeferredType dt) { - return dt.mode != null && - deferredAttrContext.mode.ordinal() <= dt.mode.ordinal(); - } - @Override public Type apply(Type t) { if (!t.hasTag(DEFERRED)) { return t.map(this); } else { DeferredType dt = (DeferredType)t; - Assert.check(validState(dt)); return typeOf(dt); } } @@ -623,11 +720,6 @@ public class DeferredAttr extends JCTree.Visitor { recover(dt) : owntype; } - @Override - protected boolean validState(DeferredType dt) { - return true; - } - /** * Synthesize a type for a deferred type that hasn't been previously * reduced to an ordinary type. Functional deferred types and conditionals @@ -646,25 +738,6 @@ public class DeferredAttr extends JCTree.Visitor { } } - /** - * Retrieves the list of inference variables that need to be inferred before - * an AST node can be type-checked - */ - @SuppressWarnings("fallthrough") - List stuckVars(JCTree tree, Env env, ResultInfo resultInfo) { - if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) { - return List.nil(); - } else { - return stuckVarsInternal(tree, resultInfo.pt, env, resultInfo.checkContext.inferenceContext()); - } - } - //where - private List stuckVarsInternal(JCTree tree, Type pt, Env env, Infer.InferenceContext inferenceContext) { - StuckChecker sc = new StuckChecker(pt, env, inferenceContext); - sc.scan(tree); - return List.from(sc.stuckVars); - } - /** * A special tree scanner that would only visit portions of a given tree. * The set of nodes visited by the scanner can be customized at construction-time. @@ -737,17 +810,41 @@ public class DeferredAttr extends JCTree.Visitor { * inferring types that make some of the nested expressions incompatible * with their corresponding instantiated target */ - class StuckChecker extends PolyScanner { + class CheckStuckPolicy extends PolyScanner implements DeferredStuckPolicy, Infer.FreeTypeListener { Type pt; - Env env; Infer.InferenceContext inferenceContext; Set stuckVars = new LinkedHashSet(); + Set depVars = new LinkedHashSet(); - StuckChecker(Type pt, Env env, Infer.InferenceContext inferenceContext) { - this.pt = pt; - this.env = env; - this.inferenceContext = inferenceContext; + @Override + public boolean isStuck() { + return !stuckVars.isEmpty(); + } + + @Override + public Set stuckVars() { + return stuckVars; + } + + @Override + public Set depVars() { + return depVars; + } + + public CheckStuckPolicy(ResultInfo resultInfo, DeferredType dt) { + this.pt = resultInfo.pt; + this.inferenceContext = resultInfo.checkContext.inferenceContext(); + scan(dt.tree); + if (!stuckVars.isEmpty()) { + resultInfo.checkContext.inferenceContext() + .addFreeTypeListener(List.from(stuckVars), this); + } + } + + @Override + public void typesInferred(InferenceContext inferenceContext) { + stuckVars.clear(); } @Override @@ -763,6 +860,7 @@ public class DeferredAttr extends JCTree.Visitor { if (tree.paramKind == JCLambda.ParameterKind.IMPLICIT && freeArgVars.nonEmpty()) { stuckVars.addAll(freeArgVars); + depVars.addAll(inferenceContext.freeVarsIn(descType.getReturnType())); } scanLambdaBody(tree, descType.getReturnType()); } @@ -780,41 +878,34 @@ public class DeferredAttr extends JCTree.Visitor { Type descType = types.findDescriptorType(pt); List freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes()); - Env localEnv = env.dup(tree, env.info.dup()); - if (freeArgVars.nonEmpty()) { - //perform arity-based check - JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv, - attr.memberReferenceQualifierResult(tree)); - ListBuffer argtypes = ListBuffer.lb(); - for (Type t : descType.getParameterTypes()) { - argtypes.append(Type.noType); - } - JCMemberReference mref2 = new TreeCopier(make).copy(tree); - mref2.expr = exprTree; - Pair lookupRes = - rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type, - tree.name, argtypes.toList(), null, true, rs.arityMethodCheck, - inferenceContext); - Symbol res = tree.sym = lookupRes.fst; - if (res.kind >= Kinds.ERRONEOUS || - res.type.hasTag(FORALL) || - (res.flags() & Flags.VARARGS) != 0 || - (TreeInfo.isStaticSelector(exprTree, tree.name.table.names) && - exprTree.type.isRaw())) { - stuckVars.addAll(freeArgVars); - } + if (freeArgVars.nonEmpty() && + tree.overloadKind == JCMemberReference.OverloadKind.OVERLOADED) { + stuckVars.addAll(freeArgVars); + depVars.addAll(inferenceContext.freeVarsIn(descType.getReturnType())); } } void scanLambdaBody(JCLambda lambda, final Type pt) { if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) { - stuckVars.addAll(stuckVarsInternal(lambda.body, pt, env, inferenceContext)); + Type prevPt = this.pt; + try { + this.pt = pt; + scan(lambda.body); + } finally { + this.pt = prevPt; + } } else { LambdaReturnScanner lambdaScanner = new LambdaReturnScanner() { @Override public void visitReturn(JCReturn tree) { if (tree.expr != null) { - stuckVars.addAll(stuckVarsInternal(tree.expr, pt, env, inferenceContext)); + Type prevPt = CheckStuckPolicy.this.pt; + try { + CheckStuckPolicy.this.pt = pt; + CheckStuckPolicy.this.scan(tree.expr); + } finally { + CheckStuckPolicy.this.pt = prevPt; + } } } }; @@ -823,6 +914,42 @@ public class DeferredAttr extends JCTree.Visitor { } } + /** + * This visitor is used to check that structural expressions conform + * to their target - this step is required as inference could end up + * inferring types that make some of the nested expressions incompatible + * with their corresponding instantiated target + */ + class OverloadStuckPolicy extends CheckStuckPolicy implements DeferredStuckPolicy { + + boolean stuck; + + @Override + public boolean isStuck() { + return super.isStuck() || stuck; + } + + public OverloadStuckPolicy(ResultInfo resultInfo, DeferredType dt) { + super(resultInfo, dt); + } + + @Override + public void visitLambda(JCLambda tree) { + super.visitLambda(tree); + if (tree.paramKind == JCLambda.ParameterKind.IMPLICIT) { + stuck = true; + } + } + + @Override + public void visitReference(JCMemberReference tree) { + super.visitReference(tree); + if (tree.overloadKind == JCMemberReference.OverloadKind.OVERLOADED) { + stuck = true; + } + } + } + /** * Does the argument expression {@code expr} need speculative type-checking? */ @@ -904,6 +1031,26 @@ public class DeferredAttr extends JCTree.Visitor { @Override public void visitReference(JCMemberReference tree) { + //perform arity-based check + Env localEnv = env.dup(tree); + JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv, + attr.memberReferenceQualifierResult(tree)); + JCMemberReference mref2 = new TreeCopier(make).copy(tree); + mref2.expr = exprTree; + Pair lookupRes = + rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type, + tree.name, List.nil(), null, true, rs.nilMethodCheck, + infer.emptyContext); + Symbol res = tree.sym = lookupRes.fst; + if (res.kind >= Kinds.ERRONEOUS || + res.type.hasTag(FORALL) || + (res.flags() & Flags.VARARGS) != 0 || + (TreeInfo.isStaticSelector(exprTree, tree.name.table.names) && + exprTree.type.isRaw())) { + tree.overloadKind = JCMemberReference.OverloadKind.OVERLOADED; + } else { + tree.overloadKind = JCMemberReference.OverloadKind.UNOVERLOADED; + } //a method reference is always a poly expression result = ArgumentExpressionKind.POLY; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index a87156a6b07..4c9568eb32c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -40,17 +40,17 @@ import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph; import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph.Node; import com.sun.tools.javac.comp.Resolve.InapplicableMethodException; import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode; - -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; +import com.sun.tools.javac.util.GraphUtils.TarjanNode; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumMap; import java.util.EnumSet; +import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; import static com.sun.tools.javac.code.TypeTag.*; @@ -113,6 +113,12 @@ public class Infer { super(diags); } + @Override + InapplicableMethodException setMessage() { + //no message to set + return this; + } + @Override InapplicableMethodException setMessage(JCDiagnostic diag) { messages = messages.append(diag); @@ -1006,10 +1012,24 @@ public class Infer { * and (ii) tell th engine when we are done fixing inference variables */ interface GraphStrategy { + + /** + * A NodeNotFoundException is thrown whenever an inference strategy fails + * to pick the next node to solve in the inference graph. + */ + public static class NodeNotFoundException extends RuntimeException { + private static final long serialVersionUID = 0; + + InferenceGraph graph; + + public NodeNotFoundException(InferenceGraph graph) { + this.graph = graph; + } + } /** * Pick the next node (leaf) to solve in the graph */ - Node pickNode(InferenceGraph g); + Node pickNode(InferenceGraph g) throws NodeNotFoundException; /** * Is this the last step? */ @@ -1022,7 +1042,10 @@ public class Infer { */ abstract class LeafSolver implements GraphStrategy { public Node pickNode(InferenceGraph g) { - Assert.check(!g.nodes.isEmpty(), "No nodes to solve!"); + if (g.nodes.isEmpty()) { + //should not happen + throw new NodeNotFoundException(g); + }; return g.nodes.get(0); } @@ -1069,6 +1092,7 @@ public class Infer { */ abstract class BestLeafSolver extends LeafSolver { + /** list of ivars of which at least one must be solved */ List varsToSolve; BestLeafSolver(List varsToSolve) { @@ -1076,54 +1100,66 @@ public class Infer { } /** - * Computes the minimum path that goes from a given node to any of the nodes - * containing a variable in {@code varsToSolve}. For any given path, the cost - * is computed as the total number of type-variables that should be eagerly - * instantiated across that path. + * Computes a path that goes from a given node to the leafs in the graph. + * Typically this will start from a node containing a variable in + * {@code varsToSolve}. For any given path, the cost is computed as the total + * number of type-variables that should be eagerly instantiated across that path. */ - int computeMinPath(InferenceGraph g, Node n) { - return computeMinPath(g, n, List.nil(), 0); + Pair, Integer> computeTreeToLeafs(Node n) { + Pair, Integer> cachedPath = treeCache.get(n); + if (cachedPath == null) { + //cache miss + if (n.isLeaf()) { + //if leaf, stop + cachedPath = new Pair, Integer>(List.of(n), n.data.length()); + } else { + //if non-leaf, proceed recursively + Pair, Integer> path = new Pair, Integer>(List.of(n), n.data.length()); + for (Node n2 : n.getAllDependencies()) { + if (n2 == n) continue; + Pair, Integer> subpath = computeTreeToLeafs(n2); + path = new Pair, Integer>( + path.fst.prependList(subpath.fst), + path.snd + subpath.snd); + } + cachedPath = path; + } + //save results in cache + treeCache.put(n, cachedPath); + } + return cachedPath; } - int computeMinPath(InferenceGraph g, Node n, List path, int cost) { - if (path.contains(n)) return Integer.MAX_VALUE; - List path2 = path.prepend(n); - int cost2 = cost + n.data.size(); - if (!Collections.disjoint(n.data, varsToSolve)) { - return cost2; - } else { - int bestPath = Integer.MAX_VALUE; - for (Node n2 : g.nodes) { - if (n2.deps.contains(n)) { - int res = computeMinPath(g, n2, path2, cost2); - if (res < bestPath) { - bestPath = res; - } - } - } - return bestPath; - } - } + /** cache used to avoid redundant computation of tree costs */ + final Map, Integer>> treeCache = + new HashMap, Integer>>(); + + /** constant value used to mark non-existent paths */ + final Pair, Integer> noPath = + new Pair, Integer>(null, Integer.MAX_VALUE); /** * Pick the leaf that minimize cost */ @Override public Node pickNode(final InferenceGraph g) { - final Map leavesMap = new HashMap(); + treeCache.clear(); //graph changes at every step - cache must be cleared + Pair, Integer> bestPath = noPath; for (Node n : g.nodes) { - if (n.isLeaf(n)) { - leavesMap.put(n, computeMinPath(g, n)); + if (!Collections.disjoint(n.data, varsToSolve)) { + Pair, Integer> path = computeTreeToLeafs(n); + //discard all paths containing at least a node in the + //closure computed above + if (path.snd < bestPath.snd) { + bestPath = path; + } } } - Assert.check(!leavesMap.isEmpty(), "No nodes to solve!"); - TreeSet orderedLeaves = new TreeSet(new Comparator() { - public int compare(Node n1, Node n2) { - return leavesMap.get(n1) - leavesMap.get(n2); - } - }); - orderedLeaves.addAll(leavesMap.keySet()); - return orderedLeaves.first(); + if (bestPath == noPath) { + //no path leads there + throw new NodeNotFoundException(g); + } + return bestPath.fst.head; } } @@ -1320,6 +1356,33 @@ public class Infer { } } + /** + * There are two kinds of dependencies between inference variables. The basic + * kind of dependency (or bound dependency) arises when a variable mention + * another variable in one of its bounds. There's also a more subtle kind + * of dependency that arises when a variable 'might' lead to better constraints + * on another variable (this is typically the case with variables holding up + * stuck expressions). + */ + enum DependencyKind implements GraphUtils.DependencyKind { + + /** bound dependency */ + BOUND("dotted"), + /** stuck dependency */ + STUCK("dashed"); + + final String dotSyle; + + private DependencyKind(String dotSyle) { + this.dotSyle = dotSyle; + } + + @Override + public String getDotStyle() { + return dotSyle; + } + } + /** * This is the graph inference solver - the solver organizes all inference variables in * a given inference context by bound dependencies - in the general case, such dependencies @@ -1331,10 +1394,12 @@ public class Infer { class GraphSolver { InferenceContext inferenceContext; + Map> stuckDeps; Warner warn; - GraphSolver(InferenceContext inferenceContext, Warner warn) { + GraphSolver(InferenceContext inferenceContext, Map> stuckDeps, Warner warn) { this.inferenceContext = inferenceContext; + this.stuckDeps = stuckDeps; this.warn = warn; } @@ -1345,7 +1410,7 @@ public class Infer { */ void solve(GraphStrategy sstrategy) { checkWithinBounds(inferenceContext, warn); //initial propagation of bounds - InferenceGraph inferenceGraph = new InferenceGraph(); + InferenceGraph inferenceGraph = new InferenceGraph(stuckDeps); while (!sstrategy.done()) { InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph); List varsToSolve = List.from(nodeToSolve.data); @@ -1390,64 +1455,172 @@ public class Infer { */ class Node extends GraphUtils.TarjanNode> { - Set deps; + /** map listing all dependencies (grouped by kind) */ + EnumMap> deps; Node(Type ivar) { super(ListBuffer.of(ivar)); - this.deps = new HashSet(); + this.deps = new EnumMap>(DependencyKind.class); } @Override - public Iterable getDependencies() { - return deps; + public GraphUtils.DependencyKind[] getSupportedDependencyKinds() { + return DependencyKind.values(); } @Override - public String printDependency(GraphUtils.Node> to) { - StringBuilder buf = new StringBuilder(); - String sep = ""; - for (Type from : data) { - UndetVar uv = (UndetVar)inferenceContext.asFree(from); - for (Type bound : uv.getBounds(InferenceBound.values())) { - if (bound.containsAny(List.from(to.data))) { - buf.append(sep); - buf.append(bound); - sep = ","; + public String getDependencyName(GraphUtils.Node> to, GraphUtils.DependencyKind dk) { + if (dk == DependencyKind.STUCK) return ""; + else { + StringBuilder buf = new StringBuilder(); + String sep = ""; + for (Type from : data) { + UndetVar uv = (UndetVar)inferenceContext.asFree(from); + for (Type bound : uv.getBounds(InferenceBound.values())) { + if (bound.containsAny(List.from(to.data))) { + buf.append(sep); + buf.append(bound); + sep = ","; + } } } + return buf.toString(); } - return buf.toString(); } - boolean isLeaf(Node n) { + @Override + public Iterable getAllDependencies() { + return getDependencies(DependencyKind.values()); + } + + @Override + public Iterable>> getDependenciesByKind(GraphUtils.DependencyKind dk) { + return getDependencies((DependencyKind)dk); + } + + /** + * Retrieves all dependencies with given kind(s). + */ + protected Set getDependencies(DependencyKind... depKinds) { + Set buf = new LinkedHashSet(); + for (DependencyKind dk : depKinds) { + Set depsByKind = deps.get(dk); + if (depsByKind != null) { + buf.addAll(depsByKind); + } + } + return buf; + } + + /** + * Adds dependency with given kind. + */ + protected void addDependency(DependencyKind dk, Node depToAdd) { + Set depsByKind = deps.get(dk); + if (depsByKind == null) { + depsByKind = new LinkedHashSet(); + deps.put(dk, depsByKind); + } + depsByKind.add(depToAdd); + } + + /** + * Add multiple dependencies of same given kind. + */ + protected void addDependencies(DependencyKind dk, Set depsToAdd) { + for (Node n : depsToAdd) { + addDependency(dk, n); + } + } + + /** + * Remove a dependency, regardless of its kind. + */ + protected Set removeDependency(Node n) { + Set removedKinds = new HashSet<>(); + for (DependencyKind dk : DependencyKind.values()) { + Set depsByKind = deps.get(dk); + if (depsByKind == null) continue; + if (depsByKind.remove(n)) { + removedKinds.add(dk); + } + } + return removedKinds; + } + + /** + * Compute closure of a give node, by recursively walking + * through all its dependencies (of given kinds) + */ + protected Set closure(DependencyKind... depKinds) { + boolean progress = true; + Set closure = new HashSet(); + closure.add(this); + while (progress) { + progress = false; + for (Node n1 : new HashSet(closure)) { + progress = closure.addAll(n1.getDependencies(depKinds)); + } + } + return closure; + } + + /** + * Is this node a leaf? This means either the node has no dependencies, + * or it just has self-dependencies. + */ + protected boolean isLeaf() { //no deps, or only one self dep - return (n.deps.isEmpty() || - n.deps.size() == 1 && n.deps.contains(n)); + Set allDeps = getDependencies(DependencyKind.BOUND, DependencyKind.STUCK); + if (allDeps.isEmpty()) return true; + for (Node n : allDeps) { + if (n != this) { + return false; + } + } + return true; } - void mergeWith(List nodes) { + /** + * Merge this node with another node, acquiring its dependencies. + * This routine is used to merge all cyclic node together and + * form an acyclic graph. + */ + protected void mergeWith(List nodes) { for (Node n : nodes) { Assert.check(n.data.length() == 1, "Attempt to merge a compound node!"); data.appendList(n.data); - deps.addAll(n.deps); + for (DependencyKind dk : DependencyKind.values()) { + addDependencies(dk, n.getDependencies(dk)); + } } //update deps - Set deps2 = new HashSet(); - for (Node d : deps) { - if (data.contains(d.data.first())) { - deps2.add(this); - } else { - deps2.add(d); + EnumMap> deps2 = new EnumMap>(DependencyKind.class); + for (DependencyKind dk : DependencyKind.values()) { + for (Node d : getDependencies(dk)) { + Set depsByKind = deps2.get(dk); + if (depsByKind == null) { + depsByKind = new LinkedHashSet(); + deps2.put(dk, depsByKind); + } + if (data.contains(d.data.first())) { + depsByKind.add(this); + } else { + depsByKind.add(d); + } } } deps = deps2; } - void graphChanged(Node from, Node to) { - if (deps.contains(from)) { - deps.remove(from); + /** + * Notify all nodes that something has changed in the graph + * topology. + */ + private void graphChanged(Node from, Node to) { + for (DependencyKind dk : removeDependency(from)) { if (to != null) { - deps.add(to); + addDependency(dk, to); } } } @@ -1456,8 +1629,21 @@ public class Infer { /** the nodes in the inference graph */ ArrayList nodes; - InferenceGraph() { - initNodes(); + InferenceGraph(Map> optDeps) { + initNodes(optDeps); + } + + /** + * Basic lookup helper for retrieving a graph node given an inference + * variable type. + */ + public Node findNode(Type t) { + for (Node n : nodes) { + if (n.data.contains(t)) { + return n; + } + } + return null; } /** @@ -1484,24 +1670,32 @@ public class Infer { * Create the graph nodes. First a simple node is created for every inference * variables to be solved. Then Tarjan is used to found all connected components * in the graph. For each component containing more than one node, a super node is - * created, effectively replacing the original cyclic nodes. + * created, effectively replacing the original cyclic nodes. */ - void initNodes() { + void initNodes(Map> stuckDeps) { + //add nodes nodes = new ArrayList(); for (Type t : inferenceContext.restvars()) { nodes.add(new Node(t)); } + //add dependencies for (Node n_i : nodes) { Type i = n_i.data.first(); + Set optDepsByNode = stuckDeps.get(i); for (Node n_j : nodes) { Type j = n_j.data.first(); UndetVar uv_i = (UndetVar)inferenceContext.asFree(i); if (Type.containsAny(uv_i.getBounds(InferenceBound.values()), List.of(j))) { - //update i's deps - n_i.deps.add(n_j); + //update i's bound dependencies + n_i.addDependency(DependencyKind.BOUND, n_j); + } + if (optDepsByNode != null && optDepsByNode.contains(j)) { + //update i's stuck dependencies + n_i.addDependency(DependencyKind.STUCK, n_j); } } } + //merge cyclic nodes ArrayList acyclicNodes = new ArrayList(); for (List conSubGraph : GraphUtils.tarjan(nodes)) { if (conSubGraph.length() > 1) { @@ -1631,8 +1825,8 @@ public class Infer { return filterVars(new Filter() { public boolean accepts(UndetVar uv) { return uv.getBounds(InferenceBound.UPPER) - .diff(uv.getDeclaredBounds()) - .appendList(uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)).nonEmpty(); + .diff(uv.getDeclaredBounds()) + .appendList(uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)).nonEmpty(); } }); } @@ -1822,11 +2016,15 @@ public class Infer { } } + private void solve(GraphStrategy ss, Warner warn) { + solve(ss, new HashMap>(), warn); + } + /** * Solve with given graph strategy. */ - private void solve(GraphStrategy ss, Warner warn) { - GraphSolver s = new GraphSolver(this, warn); + private void solve(GraphStrategy ss, Map> stuckDeps, Warner warn) { + GraphSolver s = new GraphSolver(this, stuckDeps, warn); s.solve(ss); } @@ -1855,18 +2053,12 @@ public class Infer { /** * Solve at least one variable in given list. */ - public void solveAny(List varsToSolve, Warner warn) { - checkWithinBounds(this, warn); //propagate bounds - List boundedVars = boundedVars().intersect(restvars()).intersect(varsToSolve); - if (boundedVars.isEmpty()) { - throw inferenceException.setMessage("cyclic.inference", - freeVarsIn(varsToSolve)); - } - solve(new BestLeafSolver(boundedVars) { + public void solveAny(List varsToSolve, Map> optDeps, Warner warn) { + solve(new BestLeafSolver(varsToSolve.intersect(restvars())) { public boolean done() { return instvars().intersect(varsToSolve).nonEmpty(); } - }, warn); + }, optDeps, warn); } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 0439e0d6132..03f50401171 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -568,8 +568,10 @@ public class Resolve { currentResolutionContext, warn); - currentResolutionContext.methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn), + DeferredAttr.DeferredAttrContext dc = currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn); + currentResolutionContext.methodCheck.argumentsAcceptable(env, dc, argtypes, mt.getParameterTypes(), warn); + dc.complete(); return mt; } @@ -1053,7 +1055,8 @@ public class Resolve { DeferredType dt = (DeferredType) actual; DeferredType.SpeculativeCache.Entry e = dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase); return (e == null || e.speculativeTree == deferredAttr.stuckTree) - ? false : mostSpecific(found, req, e.speculativeTree, warn); + ? super.compatible(found, req, warn) : + mostSpecific(found, req, e.speculativeTree, warn); default: return standaloneMostSpecific(found, req, actual, warn); } @@ -1125,13 +1128,15 @@ public class Resolve { @Override public void visitReference(JCMemberReference tree) { if (types.isFunctionalInterface(t.tsym) && - types.isFunctionalInterface(s.tsym) && - types.asSuper(t, s.tsym) == null && - types.asSuper(s, t.tsym) == null) { + types.isFunctionalInterface(s.tsym)) { Type desc_t = types.findDescriptorType(t); Type desc_s = types.findDescriptorType(s); - if (types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) { - if (!desc_s.getReturnType().hasTag(VOID)) { + if (types.isSameTypes(desc_t.getParameterTypes(), + inferenceContext().asFree(desc_s.getParameterTypes()))) { + if (types.asSuper(t, s.tsym) != null || + types.asSuper(s, t.tsym) != null) { + result &= MostSpecificCheckContext.super.compatible(t, s, warn); + } else if (!desc_s.getReturnType().hasTag(VOID)) { //perform structural comparison Type ret_t = desc_t.getReturnType(); Type ret_s = desc_s.getReturnType(); @@ -1141,25 +1146,24 @@ public class Resolve { } else { return; } - } else { - result &= false; } } else { - result &= MostSpecificCheckContext.super.compatible(t, s, warn); + result &= false; } } @Override public void visitLambda(JCLambda tree) { if (types.isFunctionalInterface(t.tsym) && - types.isFunctionalInterface(s.tsym) && - types.asSuper(t, s.tsym) == null && - types.asSuper(s, t.tsym) == null) { + types.isFunctionalInterface(s.tsym)) { Type desc_t = types.findDescriptorType(t); Type desc_s = types.findDescriptorType(s); - if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT - || types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) { - if (!desc_s.getReturnType().hasTag(VOID)) { + if (types.isSameTypes(desc_t.getParameterTypes(), + inferenceContext().asFree(desc_s.getParameterTypes()))) { + if (types.asSuper(t, s.tsym) != null || + types.asSuper(s, t.tsym) != null) { + result &= MostSpecificCheckContext.super.compatible(t, s, warn); + } else if (!desc_s.getReturnType().hasTag(VOID)) { //perform structural comparison Type ret_t = desc_t.getReturnType(); Type ret_s = desc_s.getReturnType(); @@ -1167,11 +1171,9 @@ public class Resolve { } else { return; } - } else { - result &= false; } } else { - result &= MostSpecificCheckContext.super.compatible(t, s, warn); + result &= false; } } //where @@ -1521,7 +1523,8 @@ public class Resolve { currentResolutionContext = prevResolutionContext; } } - private List adjustArgs(List args, Symbol msym, int length, boolean allowVarargs) { + + List adjustArgs(List args, Symbol msym, int length, boolean allowVarargs) { if ((msym.flags() & VARARGS) != 0 && allowVarargs) { Type varargsElem = types.elemtype(args.last()); if (varargsElem == null) { @@ -2241,33 +2244,33 @@ public class Resolve { public List getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List argtypes) { return (syms.operatorNames.contains(name)) ? argtypes : - Type.map(argtypes, new ResolveDeferredRecoveryMap(accessedSym)); - } - - class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap { - - public ResolveDeferredRecoveryMap(Symbol msym) { - deferredAttr.super(AttrMode.SPECULATIVE, msym, currentResolutionContext.step); - } - - @Override - protected Type typeOf(DeferredType dt) { - Type res = super.typeOf(dt); - if (!res.isErroneous()) { - switch (TreeInfo.skipParens(dt.tree).getTag()) { - case LAMBDA: - case REFERENCE: - return dt; - case CONDEXPR: - return res == Type.recoveryType ? - dt : res; - } - } - return res; - } + Type.map(argtypes, new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step)); } }; + class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap { + + public ResolveDeferredRecoveryMap(AttrMode mode, Symbol msym, MethodResolutionPhase step) { + deferredAttr.super(mode, msym, step); + } + + @Override + protected Type typeOf(DeferredType dt) { + Type res = super.typeOf(dt); + if (!res.isErroneous()) { + switch (TreeInfo.skipParens(dt.tree).getTag()) { + case LAMBDA: + case REFERENCE: + return dt; + case CONDEXPR: + return res == Type.recoveryType ? + dt : res; + } + } + return res; + } + } + /** Check that sym is not an abstract method. */ void checkNonAbstract(DiagnosticPosition pos, Symbol sym) { @@ -3969,16 +3972,6 @@ public class Resolve { static { String argMismatchRegex = MethodCheckDiag.ARG_MISMATCH.regex(); - rewriters.put(new Template(argMismatchRegex, new Template("(.*)(bad.arg.types.in.lambda)", skip, skip)), - new DiagnosticRewriter() { - @Override - public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags, - DiagnosticPosition preferedPos, DiagnosticSource preferredSource, - DiagnosticType preferredKind, JCDiagnostic d) { - return (JCDiagnostic)((JCDiagnostic)d.getArgs()[0]).getArgs()[1]; - } - }); - rewriters.put(new Template(argMismatchRegex, skip), new DiagnosticRewriter() { @Override diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 5d1a22b84a1..4ca8a90c0c0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -742,11 +742,6 @@ compiler.misc.incompatible.arg.types.in.lambda=\ compiler.misc.incompatible.arg.types.in.mref=\ incompatible parameter types in method reference -# 0: list of type, 1: message segment -compiler.misc.bad.arg.types.in.lambda=\ - cannot type-check lambda expression with inferred parameter types\n\ - inferred types: {0} - compiler.err.new.not.allowed.in.annotation=\ ''new'' not allowed in an annotation @@ -1397,6 +1392,10 @@ compiler.warn.long.SVUID=\ compiler.warn.missing.SVUID=\ serializable class {0} has no definition of serialVersionUID +# 0: symbol, 1: symbol, 2: symbol, 3: symbol +compiler.warn.potentially.ambiguous.overload=\ + {0} in {1} is potentially ambiguous with {2} in {3} + # 0: message segment compiler.warn.override.varargs.missing=\ {0}; overridden method has no ''...'' @@ -1916,10 +1915,6 @@ compiler.misc.inferred.do.not.conform.to.eq.bounds=\ inferred: {0}\n\ equality constraints(s): {1} -# 0: list of type -compiler.misc.cyclic.inference=\ - Cannot instantiate inference variables {0} because of an inference loop - # 0: symbol compiler.misc.diamond=\ {0}<> diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java index d2e9b67324b..a0581cce87a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -1908,6 +1908,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { * Selects a member expression. */ public static class JCMemberReference extends JCFunctionalExpression implements MemberReferenceTree { + public ReferenceMode mode; public ReferenceKind kind; public Name name; @@ -1917,6 +1918,12 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public Type varargsElement; public PolyKind refPolyKind; public boolean ownerAccessible; + public OverloadKind overloadKind; + + public enum OverloadKind { + OVERLOADED, + UNOVERLOADED; + } /** * Javac-dependent classification for member references, based diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java b/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java index c15f1ec66b9..aa9899ed210 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java @@ -32,6 +32,18 @@ package com.sun.tools.javac.util; */ public class GraphUtils { + /** + * Basic interface for defining various dependency kinds. All dependency kinds + * must at least support basic capabilities to tell the DOT engine how to render them. + */ + public interface DependencyKind { + /** + * Returns the DOT representation (to be used in a {@code style} attribute + * that's most suited for this dependency kind. + */ + String getDotStyle(); + } + /** * This class is a basic abstract class for representing a node. * A node is associated with a given data. @@ -43,9 +55,20 @@ public class GraphUtils { this.data = data; } - public abstract Iterable> getDependencies(); + /** + * Get an array of the dependency kinds supported by this node. + */ + public abstract DependencyKind[] getSupportedDependencyKinds(); - public abstract String printDependency(Node to); + /** + * Get all dependencies, regardless of their kind. + */ + public abstract Iterable> getAllDependencies(); + + /** + * Get a name for the dependency (of given kind) linking this node to a given node + */ + public abstract String getDependencyName(Node to, DependencyKind dk); @Override public String toString() { @@ -66,7 +89,9 @@ public class GraphUtils { super(data); } - public abstract Iterable> getDependencies(); + public abstract Iterable> getAllDependencies(); + + public abstract Iterable> getDependenciesByKind(DependencyKind dk); public int compareTo(TarjanNode o) { return (index < o.index) ? -1 : (index == o.index) ? 0 : 1; @@ -95,7 +120,7 @@ public class GraphUtils { index++; stack.prepend(v); v.active = true; - for (TarjanNode nd: v.getDependencies()) { + for (TarjanNode nd: v.getAllDependencies()) { @SuppressWarnings("unchecked") N n = (N)nd; if (n.index == -1) { @@ -134,9 +159,11 @@ public class GraphUtils { } //dump arcs for (TarjanNode from : nodes) { - for (TarjanNode to : from.getDependencies()) { - buf.append(String.format("%s -> %s [label = \" %s \"];\n", - from.hashCode(), to.hashCode(), from.printDependency(to))); + for (DependencyKind dk : from.getSupportedDependencyKinds()) { + for (TarjanNode to : from.getDependenciesByKind(dk)) { + buf.append(String.format("%s -> %s [label = \" %s \" style = %s ];\n", + from.hashCode(), to.hashCode(), from.getDependencyName(to, dk), dk.getDotStyle())); + } } } buf.append("}\n"); diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/List.java b/langtools/src/share/classes/com/sun/tools/javac/util/List.java index 611798d9caa..dee69807e2c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/List.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/List.java @@ -116,6 +116,19 @@ public class List extends AbstractCollection implements java.util.List return buf.toList(); } + /** + * Create a new list from the first {@code n} elements of this list + */ + public List take(int n) { + ListBuffer buf = ListBuffer.lb(); + int count = 0; + for (A el : this) { + if (count++ == n) break; + buf.append(el); + } + return buf.toList(); + } + /** Construct a list consisting of given element. */ public static List of(A x1) { diff --git a/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.out b/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.out index 7af49cc18e5..e2e2c8549c9 100644 --- a/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.out +++ b/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.out @@ -1,3 +1,2 @@ T8012003c.java:18:15: compiler.err.report.access: m(), private, P -- compiler.note.compressed.diags 1 error diff --git a/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java b/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java index 493c4c31efc..e4feea050d5 100644 --- a/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java +++ b/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java @@ -21,9 +21,6 @@ * questions. */ -// key: compiler.err.cant.apply.symbol -// key: compiler.misc.no.conforming.assignment.exists -// key: compiler.misc.bad.arg.types.in.lambda // key: compiler.err.prob.found.req // key: compiler.misc.inconvertible.types // options: -Xdiags:verbose diff --git a/langtools/test/tools/javac/diags/examples/IncompatibleArgTypesInMethodRef.java b/langtools/test/tools/javac/diags/examples/IncompatibleArgTypesInMethodRef.java index 999eb903296..a983af8663f 100644 --- a/langtools/test/tools/javac/diags/examples/IncompatibleArgTypesInMethodRef.java +++ b/langtools/test/tools/javac/diags/examples/IncompatibleArgTypesInMethodRef.java @@ -31,6 +31,7 @@ class IncompatibleArgTypesInMethodRef { } void g(String s, Integer i) { } + void g(Integer i, String s) { } void m(SAM s) { } diff --git a/langtools/test/tools/javac/diags/examples/CyclicInference.java b/langtools/test/tools/javac/diags/examples/PotentiallyAmbiguousOverload.java similarity index 75% rename from langtools/test/tools/javac/diags/examples/CyclicInference.java rename to langtools/test/tools/javac/diags/examples/PotentiallyAmbiguousOverload.java index 0a6bc7a2b82..50660cf49e1 100644 --- a/langtools/test/tools/javac/diags/examples/CyclicInference.java +++ b/langtools/test/tools/javac/diags/examples/PotentiallyAmbiguousOverload.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -21,17 +21,18 @@ * questions. */ -// key: compiler.err.prob.found.req -// key: compiler.misc.cyclic.inference +// key: compiler.warn.potentially.ambiguous.overload +// options: -Xlint:overloads -class CyclicInference { - interface SAM { - void m(X x); +class PotentiallyAmbiguousOverload { + interface F1 { + void m(String s); } - void g(SAM sz) { } - - void test() { - g(x-> {}); + interface F2 { + void m(Integer s); } + + void m(F1 f1) { } + void m(F2 f2) { } } diff --git a/langtools/test/tools/javac/lambda/8016177/T8016177a.java b/langtools/test/tools/javac/lambda/8016177/T8016177a.java new file mode 100644 index 00000000000..bc36c2eae00 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016177/T8016177a.java @@ -0,0 +1,45 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8016177 8016178 + * @summary structural most specific and stuckness + * @compile/fail/ref=T8016177a.out -XDrawDiagnostics T8016177a.java + */ +import java.util.List; + +class T8016177a { + + interface ToIntFunction { + int m(X x); + } + + interface Function { + Y m(X x); + } + + void m1(List s, Function f) { } + void m1(List s, ToIntFunction f) { } + + List m2(List s, Function f) { return null; } + List m2(List s, ToIntFunction f) { return null; } + + List m3(List s, Function f) { return null; } + List m3(List s, ToIntFunction f) { return null; } + + List m4(List s, Function f) { return null; } + List m4(List s, ToIntFunction f) { return null; } + + List m5(List s, Function f) { return null; } + List m5(List s, ToIntFunction f) { return null; } + + List m6(List s, Function f) { return null; } + List m6(List s, ToIntFunction f) { return null; } + + void test(List ss) { + m1(ss, s->s.length()); //ambiguous + m2(ss, s->s.length()); //ambiguous + m3(ss, s->s.length()); //ambiguous + m4(ss, s->s.length()); //ambiguous + m5(ss, s->s.length()); //ambiguous + m6(ss, s->s.length()); //ambiguous + } +} diff --git a/langtools/test/tools/javac/lambda/8016177/T8016177a.out b/langtools/test/tools/javac/lambda/8016177/T8016177a.out new file mode 100644 index 00000000000..7efd6ebfe45 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016177/T8016177a.out @@ -0,0 +1,8 @@ +T8016177a.java:38:10: compiler.err.ref.ambiguous: m1, kindname.method, m1(java.util.List,T8016177a.Function), T8016177a, kindname.method, m1(java.util.List,T8016177a.ToIntFunction), T8016177a +T8016177a.java:39:10: compiler.err.ref.ambiguous: m2, kindname.method, m2(java.util.List,T8016177a.Function), T8016177a, kindname.method, m2(java.util.List,T8016177a.ToIntFunction), T8016177a +T8016177a.java:40:10: compiler.err.ref.ambiguous: m3, kindname.method, m3(java.util.List,T8016177a.Function), T8016177a, kindname.method, m3(java.util.List,T8016177a.ToIntFunction), T8016177a +T8016177a.java:41:10: compiler.err.ref.ambiguous: m4, kindname.method, m4(java.util.List,T8016177a.Function), T8016177a, kindname.method, m4(java.util.List,T8016177a.ToIntFunction), T8016177a +T8016177a.java:42:10: compiler.err.ref.ambiguous: m5, kindname.method, m5(java.util.List,T8016177a.Function), T8016177a, kindname.method, m5(java.util.List,T8016177a.ToIntFunction), T8016177a +T8016177a.java:43:10: compiler.err.ref.ambiguous: m6, kindname.method, m6(java.util.List,T8016177a.Function), T8016177a, kindname.method, m6(java.util.List,T8016177a.ToIntFunction), T8016177a +T8016177a.java:43:12: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: T,R, (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, java.lang.String))) +7 errors diff --git a/langtools/test/tools/javac/lambda/8016177/T8016177b.java b/langtools/test/tools/javac/lambda/8016177/T8016177b.java new file mode 100644 index 00000000000..fddd6cbb8de --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016177/T8016177b.java @@ -0,0 +1,34 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8016177 8016178 + * @summary structural most specific and stuckness + * @compile/fail/ref=T8016177b.out -XDrawDiagnostics T8016177b.java + */ +class T8016177b { + interface ToIntFunction { + int m(X x); + } + + interface Function { + Y m(X x); + } + + Function id(Function arg) { return null; } + + Function id2(Function arg) { return null; } + ToIntFunction id2(ToIntFunction arg) { return null; } + + + X f(Y arg, Function f) { return null; } + + X f2(Y arg, Function f) { return null; } + X f2(Y arg, ToIntFunction f) { return null; } + + T g(T arg) { return null; } + + void test() { + g(f("hi", id(x->1))); //ok + g(f("hi", id2(x->1))); //ambiguous + g(f2("hi", id(x->1))); //ok + } +} diff --git a/langtools/test/tools/javac/lambda/8016177/T8016177b.out b/langtools/test/tools/javac/lambda/8016177/T8016177b.out new file mode 100644 index 00000000000..09bc289fc85 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016177/T8016177b.out @@ -0,0 +1,2 @@ +T8016177b.java:31:19: compiler.err.ref.ambiguous: id2, kindname.method, id2(T8016177b.Function), T8016177b, kindname.method, id2(T8016177b.ToIntFunction), T8016177b +1 error diff --git a/langtools/test/tools/javac/lambda/8016177/T8016177c.java b/langtools/test/tools/javac/lambda/8016177/T8016177c.java new file mode 100644 index 00000000000..d50b37beb9e --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016177/T8016177c.java @@ -0,0 +1,47 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8016081 8016178 + * @summary structural most specific and stuckness + * @compile/fail/ref=T8016177c.out -XDrawDiagnostics T8016177c.java + */ + +class T8016177c { + + interface Function { + Y m(X x); + } + + interface ExtFunction extends Function { } + + U m1(Function f) { return null; } + U m1(ExtFunction f) { return null; } + + void m2(Function f) { } + void m2(ExtFunction f) { } + + void m3(Function f) { } + void m3(ExtFunction f) { } + + int g1(Object s) { return 1; } + + int g2(Number s) { return 1; } + int g2(Object s) { return 1; } + + void test() { + m1((Integer x)->x); //ok - explicit lambda - subtyping picks most specific + m2((Integer x)->x); //ok - explicit lambda - subtyping picks most specific + m3((Integer x)->x); //ok - explicit lambda (only one applicable) + + m1(x->1); //ok - stuck lambda but nominal most specific wins + m2(x->1); //ok - stuck lambda but nominal most specific wins + m3(x->1); //ambiguous - implicit lambda & different params + + m1(this::g1); //ok - unambiguous ref - subtyping picks most specific + m2(this::g1); //ok - unambiguous ref - subtyping picks most specific + m3(this::g1); //ambiguous - both applicable, neither most specific + + m1(this::g2); //ok - stuck mref but nominal most specific wins + m2(this::g2); //ok - stuck mref but nominal most specific wins + m3(this::g2); //ambiguous - different params + } +} diff --git a/langtools/test/tools/javac/lambda/8016177/T8016177c.out b/langtools/test/tools/javac/lambda/8016177/T8016177c.out new file mode 100644 index 00000000000..d5780901e96 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016177/T8016177c.out @@ -0,0 +1,4 @@ +T8016177c.java:37:9: compiler.err.ref.ambiguous: m3, kindname.method, m3(T8016177c.Function), T8016177c, kindname.method, m3(T8016177c.ExtFunction), T8016177c +T8016177c.java:41:9: compiler.err.ref.ambiguous: m3, kindname.method, m3(T8016177c.Function), T8016177c, kindname.method, m3(T8016177c.ExtFunction), T8016177c +T8016177c.java:45:9: compiler.err.ref.ambiguous: m3, kindname.method, m3(T8016177c.Function), T8016177c, kindname.method, m3(T8016177c.ExtFunction), T8016177c +3 errors diff --git a/langtools/test/tools/javac/lambda/8016177/T8016177d.java b/langtools/test/tools/javac/lambda/8016177/T8016177d.java new file mode 100644 index 00000000000..e9cc243fe2f --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016177/T8016177d.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013, 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 8016081 8016178 + * @summary structural most specific and stuckness + * @compile T8016177d.java + */ +import java.util.*; + +class T8016177d { + + interface UnaryOperator { + X m(X x); + } + + interface IntStream { + IntStream sorted(); + IntStream distinct(); + IntStream limit(int i); + } + + abstract class WrappingUnaryOperator implements UnaryOperator { } + + WrappingUnaryOperator wrap1(UnaryOperator uo) { return null; } + WrappingUnaryOperator wrap2(UnaryOperator uo) { return null; } + WrappingUnaryOperator wrap3(UnaryOperator uo) { return null; } + +

    List> perm(List

    l) { return null; } + + List>> intPermutationOfFunctions = + perm(Arrays.asList( + wrap1(s -> s.sorted()), + wrap2(s -> s.distinct()), + wrap3(s -> s.limit(5)) + )); +} diff --git a/langtools/test/tools/javac/lambda/8016177/T8016177e.java b/langtools/test/tools/javac/lambda/8016177/T8016177e.java new file mode 100644 index 00000000000..b26af04bc1a --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016177/T8016177e.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013, 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 8016081 8016178 + * @summary structural most specific and stuckness + * @compile T8016177e.java + */ +import java.util.*; + +class T8016177e { + + interface TerminalOp { } + + interface Consumer { + void m(X x); + } + + TerminalOp makeRef(Consumer action) { return null; } + + void test() { + Map map = null; + TerminalOp forEachOp = makeRef(t -> { map.put(t, null); }); + } +} diff --git a/langtools/test/tools/javac/lambda/8016177/T8016177f.java b/langtools/test/tools/javac/lambda/8016177/T8016177f.java new file mode 100644 index 00000000000..5f07fbbf04b --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016177/T8016177f.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013, 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 8016081 8016178 + * @summary structural most specific and stuckness + * @compile T8016177f.java + */ +import java.util.*; + +class T8016177f { + + interface Function { + T apply(S s); + } + + interface IntFunction { + T apply(int s); + } + + + interface BiConsumer { + void m(X x, Y y); + } + + interface Consumer { + void m(X x); + } + + interface Supplier { + X make(); + } + + interface TestData> { + interface OfRef extends TestData> { } + interface OfDouble extends TestData { } + } + + interface BaseStream> { } + + interface Stream extends BaseStream> { + Stream map(Function s); + R collect(Supplier resultFactory, BiConsumer accumulator, BiConsumer combiner); + Z[] toArray(IntFunction s); + } + + interface DoubleStream extends BaseStream { + DoubleStream filter(DoublePredicate dp); + double[] toArray(); + } + + interface DoublePredicate { + boolean p(double d); + } + + , S_OUT extends BaseStream> + R exerciseTerminalOps(TestData data, + Function streamF, + Function terminalF) { return null; } + + TestData.OfRef ofCollection(Collection collection) { return null; } + + void test1(TestData.OfDouble data, DoublePredicate dp) { + exerciseTerminalOps(data, s -> s.filter(dp), s -> s.toArray()); + } + + void test2(Function fdi, TestData.OfRef td, Stream si) { + exerciseTerminalOps( + ofCollection((List)null), + s -> s.map(fdi), + s -> s.toArray(Integer[]::new)); + } +} diff --git a/langtools/test/tools/javac/lambda/8016177/T8016177g.java b/langtools/test/tools/javac/lambda/8016177/T8016177g.java new file mode 100644 index 00000000000..f8660e892f0 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016177/T8016177g.java @@ -0,0 +1,37 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8016081 8016178 + * @summary structural most specific and stuckness + * @compile/fail/ref=T8016177g.out -XDrawDiagnostics T8016177g.java + */ + + +class Test { + + interface Function { + Y m(X x); + } + + interface Box { + T get(); + R map(Function f); + } + + static class Person { + Person(String name) { } + } + + void print(Object arg) { } + void print(String arg) { } + + int abs(int a) { return 0; } + long abs(long a) { return 0; } + float abs(float a) { return 0; } + double abs(double a) { return 0; } + + void test() { + Box b = null; + print(b.map(s -> new Person(s))); + int i = abs(b.map(s -> Double.valueOf(s))); + } +} diff --git a/langtools/test/tools/javac/lambda/8016177/T8016177g.out b/langtools/test/tools/javac/lambda/8016177/T8016177g.out new file mode 100644 index 00000000000..beb47b0f53c --- /dev/null +++ b/langtools/test/tools/javac/lambda/8016177/T8016177g.out @@ -0,0 +1,2 @@ +T8016177g.java:35:20: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: double, int) +1 error diff --git a/langtools/test/tools/javac/lambda/BadRecovery.out b/langtools/test/tools/javac/lambda/BadRecovery.out index 6035eecfd6f..427d97f0f81 100644 --- a/langtools/test/tools/javac/lambda/BadRecovery.out +++ b/langtools/test/tools/javac/lambda/BadRecovery.out @@ -1,2 +1,3 @@ +BadRecovery.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, BadRecovery.SAM1, @369, kindname.class, BadRecovery, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.lambda)) BadRecovery.java:17:77: compiler.err.cant.resolve.location: kindname.variable, f, , , (compiler.misc.location: kindname.class, BadRecovery, null) -1 error +2 errors diff --git a/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java b/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java index be21473b241..173f084638b 100644 --- a/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java +++ b/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ * @bug 8003280 * @summary Add lambda tests * stale state after speculative attribution round leads to missing classfiles + * @compile/fail/ref=ErroneousLambdaExpr.out -XDrawDiagnostics ErroneousLambdaExpr.java */ public class ErroneousLambdaExpr { diff --git a/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.out b/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.out new file mode 100644 index 00000000000..aeb312fb180 --- /dev/null +++ b/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.out @@ -0,0 +1,2 @@ +ErroneousLambdaExpr.java:63:13: compiler.err.ref.ambiguous: call, kindname.method, call(ErroneousLambdaExpr.SAM1), ErroneousLambdaExpr, kindname.method, call(ErroneousLambdaExpr.SAM2), ErroneousLambdaExpr +1 error diff --git a/langtools/test/tools/javac/lambda/MethodReference22.out b/langtools/test/tools/javac/lambda/MethodReference22.out index d25b71e3a12..dfd2ebe554e 100644 --- a/langtools/test/tools/javac/lambda/MethodReference22.out +++ b/langtools/test/tools/javac/lambda/MethodReference22.out @@ -3,13 +3,17 @@ MethodReference22.java:41:15: compiler.err.invalid.mref: kindname.method, (compi MethodReference22.java:46:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String)) MethodReference22.java:47:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String)) MethodReference22.java:51:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22)) -MethodReference22.java:52:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1401, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22))) +MethodReference22.java:52:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1401, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22))) MethodReference22.java:53:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22)) -MethodReference22.java:54:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1504, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22))) +MethodReference22.java:54:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1504, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22))) MethodReference22.java:55:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22)) -MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1607, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22))) +MethodReference22.java:56:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1607, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22))) MethodReference22.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)) -MethodReference22.java:58:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1710, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))) +MethodReference22.java:58:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1710, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))) +MethodReference22.java:62:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 MethodReference22.java:62:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String)) +MethodReference22.java:63:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 +MethodReference22.java:64:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 +MethodReference22.java:65:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 MethodReference22.java:65:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String)) -14 errors +18 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference23.out b/langtools/test/tools/javac/lambda/MethodReference23.out index 3849d8631c6..462a75105ff 100644 --- a/langtools/test/tools/javac/lambda/MethodReference23.out +++ b/langtools/test/tools/javac/lambda/MethodReference23.out @@ -1,6 +1,6 @@ MethodReference23.java:52:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23)) -MethodReference23.java:53:9: compiler.err.cant.apply.symbol: kindname.method, call11, MethodReference23.SAM11, @1140, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23))) +MethodReference23.java:53:15: compiler.err.cant.apply.symbol: kindname.method, call11, MethodReference23.SAM11, @1140, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23))) MethodReference23.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23)) -MethodReference23.java:58:9: compiler.err.cant.apply.symbol: kindname.method, call12, MethodReference23.SAM12, @1282, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23))) +MethodReference23.java:58:15: compiler.err.cant.apply.symbol: kindname.method, call12, MethodReference23.SAM12, @1282, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23))) MethodReference23.java:72:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference23.SAM21), MethodReference23, kindname.method, call3(MethodReference23.SAM22), MethodReference23 5 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference41.java b/langtools/test/tools/javac/lambda/MethodReference41.java index a2593320021..836dce0f1cb 100644 --- a/langtools/test/tools/javac/lambda/MethodReference41.java +++ b/langtools/test/tools/javac/lambda/MethodReference41.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,18 +26,10 @@ * @bug 8003280 * @summary Add lambda tests * check that diamond inference is applied when using raw constructor reference qualifier - * @run main MethodReference41 + * @compile/fail/ref=MethodReference41.out -XDrawDiagnostics MethodReference41.java */ public class MethodReference41 { - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - interface SAM1 { void m(String s); } @@ -54,13 +46,20 @@ public class MethodReference41 { Foo(X x) { } } + static void m1(SAM1 s) { } - static void m(SAM1 s) { assertTrue(false); } - static void m(SAM2 s) { assertTrue(true); } - static void m(SAM3 s) { assertTrue(false); } + static void m2(SAM2 s) { } + + static void m3(SAM3 s) { } + + static void m4(SAM1 s) { } + static void m4(SAM2 s) { } + static void m4(SAM3 s) { } public static void main(String[] args) { - m(Foo::new); - assertTrue(assertionCount == 1); + m1(Foo::new); + m2(Foo::new); + m3(Foo::new); + m4(Foo::new); } } diff --git a/langtools/test/tools/javac/lambda/MethodReference41.out b/langtools/test/tools/javac/lambda/MethodReference41.out new file mode 100644 index 00000000000..f4a60cb3ba6 --- /dev/null +++ b/langtools/test/tools/javac/lambda/MethodReference41.out @@ -0,0 +1,4 @@ +MethodReference41.java:60:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference41.SAM1, @1819, kindname.class, MethodReference41, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.String, kindname.class, MethodReference41.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)))) +MethodReference41.java:62:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference41.SAM3, @1863, kindname.class, MethodReference41, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference41.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) +MethodReference41.java:63:9: compiler.err.ref.ambiguous: m4, kindname.method, m4(MethodReference41.SAM2), MethodReference41, kindname.method, m4(MethodReference41.SAM3), MethodReference41 +3 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference42.java b/langtools/test/tools/javac/lambda/MethodReference42.java index 1c8aaefab75..957dc024902 100644 --- a/langtools/test/tools/javac/lambda/MethodReference42.java +++ b/langtools/test/tools/javac/lambda/MethodReference42.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,18 +26,10 @@ * @bug 8003280 * @summary Add lambda tests * check that diamond inference is applied when using raw constructor reference qualifier - * @run main MethodReference42 + * @compile/fail/ref=MethodReference42.out -XDrawDiagnostics MethodReference42.java */ public class MethodReference42 { - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - static class SuperFoo { } static class Foo extends SuperFoo { } @@ -54,12 +46,20 @@ public class MethodReference42 { SuperFoo m(); } - static void m(SAM1 s) { assertTrue(false); } - static void m(SAM2 s) { assertTrue(true); } - static void m(SAM3 s) { assertTrue(false); } + static void m1(SAM1 s) { } + + static void m2(SAM2 s) { } + + static void m3(SAM3 s) { } + + static void m4(SAM1 s) { } + static void m4(SAM2 s) { } + static void m4(SAM3 s) { } public static void main(String[] args) { - m(Foo::new); - assertTrue(assertionCount == 1); + m1(Foo::new); + m2(Foo::new); + m3(Foo::new); + m4(Foo::new); } } diff --git a/langtools/test/tools/javac/lambda/MethodReference42.out b/langtools/test/tools/javac/lambda/MethodReference42.out new file mode 100644 index 00000000000..70ec85a352e --- /dev/null +++ b/langtools/test/tools/javac/lambda/MethodReference42.out @@ -0,0 +1,4 @@ +MethodReference42.java:60:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference42.SAM1, @1851, kindname.class, MethodReference42, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number)) +MethodReference42.java:62:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference42.SAM3, @1895, kindname.class, MethodReference42, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Number)) +MethodReference42.java:63:9: compiler.err.ref.ambiguous: m4, kindname.method, m4(MethodReference42.SAM2), MethodReference42, kindname.method, m4(MethodReference42.SAM3), MethodReference42 +3 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference43.java b/langtools/test/tools/javac/lambda/MethodReference43.java index f7b8203d1b1..53cf98c702f 100644 --- a/langtools/test/tools/javac/lambda/MethodReference43.java +++ b/langtools/test/tools/javac/lambda/MethodReference43.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,18 +26,10 @@ * @bug 8003280 * @summary Add lambda tests * check that diamond inference is applied when using raw constructor reference qualifier - * @run main MethodReference43 + * @compile/fail/ref=MethodReference43.out -XDrawDiagnostics MethodReference43.java */ public class MethodReference43 { - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - interface SAM1 { Foo m(String s); } @@ -58,14 +50,24 @@ public class MethodReference43 { Foo(X x) { } } + static void m1(SAM1 s) { } - static void m(SAM1 s) { assertTrue(false); } - static void m(SAM2 s) { assertTrue(false); } - static void m(SAM3 s) { assertTrue(false); } - static void m(SAM4 s) { assertTrue(true); } + static void m2(SAM2 s) { } + + static void m3(SAM3 s) { } + + static void m4(SAM4 s) { } + + static void m5(SAM1 s) { } + static void m5(SAM2 s) { } + static void m5(SAM3 s) { } + static void m5(SAM4 s) { } public static void main(String[] args) { - m(Foo::new); - assertTrue(assertionCount == 1); + m1(Foo::new); + m2(Foo::new); + m3(Foo::new); + m4(Foo::new); + m5(Foo::new); } } diff --git a/langtools/test/tools/javac/lambda/MethodReference43.out b/langtools/test/tools/javac/lambda/MethodReference43.out new file mode 100644 index 00000000000..e1e0461d80f --- /dev/null +++ b/langtools/test/tools/javac/lambda/MethodReference43.out @@ -0,0 +1,5 @@ +MethodReference43.java:67:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference43.SAM1, @1937, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.String, kindname.class, MethodReference43.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)))) +MethodReference43.java:69:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference43.SAM3, @1981, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference43.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) +MethodReference43.java:71:9: compiler.err.ref.ambiguous: m5, kindname.method, m5(MethodReference43.SAM3), MethodReference43, kindname.method, m5(MethodReference43.SAM4), MethodReference43 +MethodReference43.java:71:11: compiler.err.cant.apply.symbol: kindname.method, m5, MethodReference43.SAM3, @2025, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference43.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) +4 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference44.java b/langtools/test/tools/javac/lambda/MethodReference44.java index 8c92593b43a..be96ad2987b 100644 --- a/langtools/test/tools/javac/lambda/MethodReference44.java +++ b/langtools/test/tools/javac/lambda/MethodReference44.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,18 +26,10 @@ * @bug 8003280 * @summary Add lambda tests * check that generic method reference is inferred when type parameters are omitted - * @run main MethodReference44 + * @compile/fail/ref=MethodReference44.out -XDrawDiagnostics MethodReference44.java */ public class MethodReference44 { - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - static class SuperFoo { } static class Foo extends SuperFoo { } @@ -56,12 +48,20 @@ public class MethodReference44 { static Foo m() { return null; } - static void g(SAM1 s) { assertTrue(false); } - static void g(SAM2 s) { assertTrue(true); } - static void g(SAM3 s) { assertTrue(false); } + static void g1(SAM1 s) { } + + static void g2(SAM2 s) { } + + static void g3(SAM3 s) { } + + static void g4(SAM1 s) { } + static void g4(SAM2 s) { } + static void g4(SAM3 s) { } public static void main(String[] args) { - g(MethodReference44::m); - assertTrue(assertionCount == 1); + g1(MethodReference44::m); + g2(MethodReference44::m); + g3(MethodReference44::m); + g4(MethodReference44::m); } } diff --git a/langtools/test/tools/javac/lambda/MethodReference44.out b/langtools/test/tools/javac/lambda/MethodReference44.out new file mode 100644 index 00000000000..dbf1a394fde --- /dev/null +++ b/langtools/test/tools/javac/lambda/MethodReference44.out @@ -0,0 +1,4 @@ +MethodReference44.java:62:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference44.SAM1, @1904, kindname.class, MethodReference44, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number)) +MethodReference44.java:64:11: compiler.err.cant.apply.symbol: kindname.method, g3, MethodReference44.SAM3, @1972, kindname.class, MethodReference44, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Number)) +MethodReference44.java:65:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference44.SAM2), MethodReference44, kindname.method, g4(MethodReference44.SAM3), MethodReference44 +3 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference46.java b/langtools/test/tools/javac/lambda/MethodReference46.java index 8f0c327faff..0a9d42b8414 100644 --- a/langtools/test/tools/javac/lambda/MethodReference46.java +++ b/langtools/test/tools/javac/lambda/MethodReference46.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,18 +26,10 @@ * @bug 8003280 * @summary Add lambda tests * check that generic method reference is inferred when type parameters are omitted - * @run main MethodReference46 + * @compile/fail/ref=MethodReference46.out -XDrawDiagnostics MethodReference46.java */ public class MethodReference46 { - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - interface SAM1 { void m(String s); } @@ -56,12 +48,20 @@ public class MethodReference46 { static void m(X fx) { } - static void g(SAM1 s) { assertTrue(false); } - static void g(SAM2 s) { assertTrue(true); } - static void g(SAM3 s) { assertTrue(false); } + static void g1(SAM1 s) { } + + static void g2(SAM2 s) { } + + static void g3(SAM3 s) { } + + static void g4(SAM1 s) { } + static void g4(SAM2 s) { } + static void g4(SAM3 s) { } public static void main(String[] args) { - g(MethodReference46::m); - assertTrue(assertionCount == 1); + g1(MethodReference46::m); + g2(MethodReference46::m); + g3(MethodReference46::m); + g4(MethodReference46::m); } } diff --git a/langtools/test/tools/javac/lambda/MethodReference46.out b/langtools/test/tools/javac/lambda/MethodReference46.out new file mode 100644 index 00000000000..544affbd675 --- /dev/null +++ b/langtools/test/tools/javac/lambda/MethodReference46.out @@ -0,0 +1,4 @@ +MethodReference46.java:62:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference46.SAM1, @1849, kindname.class, MethodReference46, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m, X, java.lang.String, kindname.class, MethodReference46, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)))) +MethodReference46.java:64:11: compiler.err.cant.apply.symbol: kindname.method, g3, MethodReference46.SAM3, @1917, kindname.class, MethodReference46, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m, X, java.lang.Object, kindname.class, MethodReference46, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) +MethodReference46.java:65:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference46.SAM2), MethodReference46, kindname.method, g4(MethodReference46.SAM3), MethodReference46 +3 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference47.java b/langtools/test/tools/javac/lambda/MethodReference47.java index 5bc949dd03b..d5fff0dd4b4 100644 --- a/langtools/test/tools/javac/lambda/MethodReference47.java +++ b/langtools/test/tools/javac/lambda/MethodReference47.java @@ -7,14 +7,6 @@ */ public class MethodReference47 { - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - interface SAM1 { void m(Integer s); } @@ -34,7 +26,7 @@ public class MethodReference47 { static void g2(SAM2 s) { } public static void main(String[] args) { - g1(MethodReference46::m); - g2(MethodReference46::m); + g1(MethodReference47::m); + g2(MethodReference47::m); } } diff --git a/langtools/test/tools/javac/lambda/MethodReference47.out b/langtools/test/tools/javac/lambda/MethodReference47.out index 39d3c31ba12..7a745728948 100644 --- a/langtools/test/tools/javac/lambda/MethodReference47.out +++ b/langtools/test/tools/javac/lambda/MethodReference47.out @@ -1,2 +1,2 @@ -MethodReference47.java:38:9: compiler.err.ref.ambiguous: g2, kindname.method, g2(MethodReference47.SAM1), MethodReference47, kindname.method, g2(MethodReference47.SAM2), MethodReference47 +MethodReference47.java:30:9: compiler.err.ref.ambiguous: g2, kindname.method, g2(MethodReference47.SAM1), MethodReference47, kindname.method, g2(MethodReference47.SAM2), MethodReference47 1 error diff --git a/langtools/test/tools/javac/lambda/MethodReference48.java b/langtools/test/tools/javac/lambda/MethodReference48.java index 8c3a704dd02..5247f4adb3b 100644 --- a/langtools/test/tools/javac/lambda/MethodReference48.java +++ b/langtools/test/tools/javac/lambda/MethodReference48.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,18 +26,10 @@ * @bug 8003280 * @summary Add lambda tests * check that raw qualifier in unbound method reference is inferred from descriptor - * @run main MethodReference48 + * @compile/fail/ref=MethodReference48.out -XDrawDiagnostics MethodReference48.java */ public class MethodReference48 { - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - static class Foo { X m() { return null; }; } @@ -54,12 +46,20 @@ public class MethodReference48 { Object m(Foo fi); } - static void g(SAM1 s) { assertTrue(false); } //return type not compatible - static void g(SAM2 s) { assertTrue(true); } //ok - static void g(SAM3 s) { assertTrue(false); } //ok but less specific + static void g1(SAM1 s) { } //return type not compatible + + static void g2(SAM2 s) { } //ok + + static void g3(SAM3 s) { } //ok + + static void g4(SAM1 s) { } //return type not compatible + static void g4(SAM2 s) { } //ok + static void g4(SAM3 s) { } //ok public static void main(String[] args) { - g(Foo::m); - assertTrue(assertionCount == 1); + g1(Foo::m); + g2(Foo::m); + g3(Foo::m); + g4(Foo::m); } } diff --git a/langtools/test/tools/javac/lambda/MethodReference48.out b/langtools/test/tools/javac/lambda/MethodReference48.out new file mode 100644 index 00000000000..732649e51f0 --- /dev/null +++ b/langtools/test/tools/javac/lambda/MethodReference48.out @@ -0,0 +1,3 @@ +MethodReference48.java:60:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference48.SAM1, @1909, kindname.class, MethodReference48, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: java.lang.String, MethodReference48.Foo))) +MethodReference48.java:63:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference48.SAM2), MethodReference48, kindname.method, g4(MethodReference48.SAM3), MethodReference48 +2 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference70.out b/langtools/test/tools/javac/lambda/MethodReference70.out index 875b9d2d064..4cdccd5a50a 100644 --- a/langtools/test/tools/javac/lambda/MethodReference70.out +++ b/langtools/test/tools/javac/lambda/MethodReference70.out @@ -1,3 +1,3 @@ MethodReference70.java:26:10: compiler.err.ref.ambiguous: g, kindname.method, g(MethodReference70.F), MethodReference70, kindname.method, g(MethodReference70.G), MethodReference70 -MethodReference70.java:26:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z) +MethodReference70.java:26:11: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, m2, java.lang.Object,{(compiler.misc.inapplicable.method: kindname.method, MethodReference70, m2(java.lang.Integer), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.Integer))),(compiler.misc.inapplicable.method: kindname.method, MethodReference70, m2(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.String)))}))) 2 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference71.out b/langtools/test/tools/javac/lambda/MethodReference71.out index f1a8942e3d1..f95734da07e 100644 --- a/langtools/test/tools/javac/lambda/MethodReference71.out +++ b/langtools/test/tools/javac/lambda/MethodReference71.out @@ -1,3 +1,3 @@ MethodReference71.java:24:10: compiler.err.ref.ambiguous: g, kindname.method, g(MethodReference71.F), MethodReference71, kindname.method, g(MethodReference71.G), MethodReference71 -MethodReference71.java:24:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z) +MethodReference71.java:24:11: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m2, java.lang.Integer[], java.lang.Object, kindname.class, MethodReference71, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.Integer))))) 2 errors diff --git a/langtools/test/tools/javac/lambda/MostSpecific04.java b/langtools/test/tools/javac/lambda/MostSpecific04.java index c5fbc3d35a5..74ac24e4bc4 100644 --- a/langtools/test/tools/javac/lambda/MostSpecific04.java +++ b/langtools/test/tools/javac/lambda/MostSpecific04.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,17 +26,10 @@ * @bug 8003280 * @summary Add lambda tests * Structural most specific doesn't handle cases with wildcards in functional interfaces + * @compile/fail/ref=MostSpecific04.out -XDrawDiagnostics MostSpecific04.java */ public class MostSpecific04 { - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - interface DoubleMapper { double map(T t); } @@ -46,13 +39,13 @@ public class MostSpecific04 { } static class MyList { - void map(DoubleMapper m) { assertTrue(false); } - void map(LongMapper m) { assertTrue(true); } + void map(DoubleMapper m) { } + void map(LongMapper m) { } } public static void main(String[] args) { MyList ls = new MyList(); - ls.map(e->e.length()); - assertTrue(assertionCount == 1); + ls.map(e->e.length()); //ambiguous - implicit + ls.map((String e)->e.length()); //ok } } diff --git a/langtools/test/tools/javac/lambda/MostSpecific04.out b/langtools/test/tools/javac/lambda/MostSpecific04.out new file mode 100644 index 00000000000..3a672f0698e --- /dev/null +++ b/langtools/test/tools/javac/lambda/MostSpecific04.out @@ -0,0 +1,2 @@ +MostSpecific04.java:48:11: compiler.err.ref.ambiguous: map, kindname.method, map(MostSpecific04.DoubleMapper), MostSpecific04.MyList, kindname.method, map(MostSpecific04.LongMapper), MostSpecific04.MyList +1 error diff --git a/langtools/test/tools/javac/lambda/MostSpecific05.java b/langtools/test/tools/javac/lambda/MostSpecific05.java index 177a43e7637..f001ccc195b 100644 --- a/langtools/test/tools/javac/lambda/MostSpecific05.java +++ b/langtools/test/tools/javac/lambda/MostSpecific05.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,17 +26,10 @@ * @bug 8003280 * @summary Add lambda tests * Structural most specific doesn't handle cases with wildcards in functional interfaces + * @compile/fail/ref=MostSpecific05.out -XDrawDiagnostics MostSpecific05.java */ public class MostSpecific05 { - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - interface ObjectConverter { T map(Object o); } @@ -46,13 +39,13 @@ public class MostSpecific05 { } static class MyMapper { - void map(ObjectConverter m) { assertTrue(false); } - void map(NumberConverter m) { assertTrue(true); } + void map(ObjectConverter m) { } + void map(NumberConverter m) { } } public static void main(String[] args) { MyMapper mm = new MyMapper(); - mm.map(e->1.0); - assertTrue(assertionCount == 1); + mm.map(e->1.0); //ambiguous - implicit + mm.map((Object e)->1.0); //ok } } diff --git a/langtools/test/tools/javac/lambda/MostSpecific05.out b/langtools/test/tools/javac/lambda/MostSpecific05.out new file mode 100644 index 00000000000..d0d86c151b4 --- /dev/null +++ b/langtools/test/tools/javac/lambda/MostSpecific05.out @@ -0,0 +1,2 @@ +MostSpecific05.java:48:11: compiler.err.ref.ambiguous: map, kindname.method, map(MostSpecific05.ObjectConverter), MostSpecific05.MyMapper, kindname.method, map(MostSpecific05.NumberConverter), MostSpecific05.MyMapper +1 error diff --git a/langtools/test/tools/javac/lambda/MostSpecific08.java b/langtools/test/tools/javac/lambda/MostSpecific08.java index 453f04cd7f4..0673ef0ba06 100644 --- a/langtools/test/tools/javac/lambda/MostSpecific08.java +++ b/langtools/test/tools/javac/lambda/MostSpecific08.java @@ -25,7 +25,7 @@ * @test * @bug 8008813 * @summary Structural most specific fails when method reference is passed to overloaded method - * @compile MostSpecific08.java + * @compile/fail/ref=MostSpecific08.out -XDrawDiagnostics MostSpecific08.java */ class MostSpecific08 { @@ -51,12 +51,14 @@ class MostSpecific08 { } void testMref(Tester t) { - IntResult pr = t.apply(C::getInt); - ReferenceResult rr = t.apply(C::getInteger); + IntResult pr = t.apply(C::getInt); //ok - unoverloaded mref + ReferenceResult rr = t.apply(C::getInteger); //ok - unoverloaded mref } void testLambda(Tester t) { - IntResult pr = t.apply(c->c.getInt()); - ReferenceResult rr = t.apply(c->c.getInteger()); + IntResult pr1 = t.apply(c->c.getInt()); //ambiguous - implicit + IntResult pr2 = t.apply((C c)->c.getInt()); //ok + ReferenceResult rr1 = t.apply(c->c.getInteger()); //ambiguous - implicit + ReferenceResult rr2 = t.apply((C c)->c.getInteger()); //ok } } diff --git a/langtools/test/tools/javac/lambda/MostSpecific08.out b/langtools/test/tools/javac/lambda/MostSpecific08.out new file mode 100644 index 00000000000..f4e47d7d0ed --- /dev/null +++ b/langtools/test/tools/javac/lambda/MostSpecific08.out @@ -0,0 +1,4 @@ +MostSpecific08.java:59:26: compiler.err.ref.ambiguous: apply, kindname.method, apply(MostSpecific08.PrimitiveFunction), MostSpecific08.Tester, kindname.method, apply(MostSpecific08.ReferenceFunction), MostSpecific08.Tester +MostSpecific08.java:61:41: compiler.err.ref.ambiguous: apply, kindname.method, apply(MostSpecific08.PrimitiveFunction), MostSpecific08.Tester, kindname.method, apply(MostSpecific08.ReferenceFunction), MostSpecific08.Tester +MostSpecific08.java:61:47: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: MostSpecific08.IntResult, MostSpecific08.ReferenceResult) +3 errors diff --git a/langtools/test/tools/javac/lambda/TargetType01.java b/langtools/test/tools/javac/lambda/TargetType01.java index 0e8f16c045c..2ad86c64c88 100644 --- a/langtools/test/tools/javac/lambda/TargetType01.java +++ b/langtools/test/tools/javac/lambda/TargetType01.java @@ -26,7 +26,7 @@ * @bug 8003280 8009131 * @summary Add lambda tests * check nested case of overload resolution and lambda parameter inference - * @compile TargetType01.java + * @compile/fail/ref=TargetType01.out -XDrawDiagnostics TargetType01.java */ class TargetType01 { diff --git a/langtools/test/tools/javac/lambda/TargetType01.out b/langtools/test/tools/javac/lambda/TargetType01.out new file mode 100644 index 00000000000..b460bfc4230 --- /dev/null +++ b/langtools/test/tools/javac/lambda/TargetType01.out @@ -0,0 +1,3 @@ +TargetType01.java:45:9: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01 +TargetType01.java:45:26: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01 +2 errors diff --git a/langtools/test/tools/javac/lambda/TargetType02.java b/langtools/test/tools/javac/lambda/TargetType02.java index f5141ed18eb..05077c88f3d 100644 --- a/langtools/test/tools/javac/lambda/TargetType02.java +++ b/langtools/test/tools/javac/lambda/TargetType02.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,19 +27,11 @@ * @summary Add lambda tests * check overload resolution and target type inference w.r.t. generic methods * @author Maurizio Cimadamore - * @run main TargetType02 + * @compile/fail/ref=TargetType02.out -XDrawDiagnostics TargetType02.java */ public class TargetType02 { - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - interface S1 { X m(Integer x); } @@ -48,15 +40,16 @@ public class TargetType02 { abstract X m(Integer x); } - static void call(S1 s) { s.m(1); assertTrue(true); } - static void call(S2 s) { s.m(2); assertTrue(false); } + static void call1(S1 s) { } + + static void call2(S2 s) { } + + static void call3(S1 s) { } + static void call3(S2 s) { } void test() { - call(i -> { toString(); return i; }); - } - - public static void main(String[] args) { - new TargetType02().test(); - assertTrue(assertionCount == 1); + call1(i -> { toString(); return i; }); + call2(i -> { toString(); return i; }); + call3(i -> { toString(); return i; }); } } diff --git a/langtools/test/tools/javac/lambda/TargetType02.out b/langtools/test/tools/javac/lambda/TargetType02.out new file mode 100644 index 00000000000..2336ef70e6b --- /dev/null +++ b/langtools/test/tools/javac/lambda/TargetType02.out @@ -0,0 +1,3 @@ +TargetType02.java:52:14: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String) +TargetType02.java:53:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(TargetType02.S1), TargetType02, kindname.method, call3(TargetType02.S2), TargetType02 +2 errors diff --git a/langtools/test/tools/javac/lambda/TargetType10.java b/langtools/test/tools/javac/lambda/TargetType10.java index 39afaee727a..538b8e0221d 100644 --- a/langtools/test/tools/javac/lambda/TargetType10.java +++ b/langtools/test/tools/javac/lambda/TargetType10.java @@ -1,10 +1,10 @@ /* * @test /nodynamiccopyright/ - * @bug 8003280 + * @bug 8003280 8016177 * @summary Add lambda tests * check that wildcards in the target method of a lambda conversion is handled correctly * @author Maurizio Cimadamore - * @compile/fail/ref=TargetType10.out -XDrawDiagnostics TargetType10.java + * @compile TargetType10.java */ class TargetType10 { diff --git a/langtools/test/tools/javac/lambda/TargetType10.out b/langtools/test/tools/javac/lambda/TargetType10.out deleted file mode 100644 index eaf9bb3a07f..00000000000 --- a/langtools/test/tools/javac/lambda/TargetType10.out +++ /dev/null @@ -1,2 +0,0 @@ -TargetType10.java:17:18: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: B,A) -1 error diff --git a/langtools/test/tools/javac/lambda/TargetType21.java b/langtools/test/tools/javac/lambda/TargetType21.java index ac70cacb6dc..d55e803cb4a 100644 --- a/langtools/test/tools/javac/lambda/TargetType21.java +++ b/langtools/test/tools/javac/lambda/TargetType21.java @@ -26,8 +26,10 @@ class TargetType21 { void test() { call(x -> { throw new Exception(); }); //ambiguous + call((Integer x) -> { System.out.println(""); }); //ok (only one is void) + call((Integer x) -> { return (Object) null; }); //ok (only one returns Object) call(x -> { System.out.println(""); }); //ambiguous - call(x -> { return (Object) null; }); //cyclic inference + call(x -> { return (Object) null; }); //ambiguous call(x -> { return null; }); //ambiguous } } diff --git a/langtools/test/tools/javac/lambda/TargetType21.out b/langtools/test/tools/javac/lambda/TargetType21.out index 904e30f1278..90131dc4bfc 100644 --- a/langtools/test/tools/javac/lambda/TargetType21.out +++ b/langtools/test/tools/javac/lambda/TargetType21.out @@ -1,5 +1,7 @@ TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 -TargetType21.java:29:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 -TargetType21.java:30:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: A) -TargetType21.java:31:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 -4 errors +TargetType21.java:31:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 +TargetType21.java:32:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 +TargetType21.java:32:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM2, @888, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val))) +TargetType21.java:33:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 +TargetType21.java:33:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM2, @946, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val))) +6 errors diff --git a/langtools/test/tools/javac/lambda/TargetType24.java b/langtools/test/tools/javac/lambda/TargetType24.java index b470a9169f9..5180cd5373f 100644 --- a/langtools/test/tools/javac/lambda/TargetType24.java +++ b/langtools/test/tools/javac/lambda/TargetType24.java @@ -29,11 +29,14 @@ class TargetType24 { } void test(Array as, final Array ac) { - final boolean b1 = as.forAll(s -> ac.forAll(c -> false)); //ok + final boolean b1 = as.forAll((String s) -> ac.forAll((Character c) -> false)); //ok + final boolean b2 = as.forAll(s -> ac.forAll(c -> false)); //ambiguous + final boolean b3 = as.forAll((String s) -> ac.forAll(c -> false)); //ambiguous + final boolean b4 = as.forAll(s -> ac.forAll((Character c) -> false)); //ambiguous final String s1 = as.forAll2(s -> ac.forAll2(c -> "")); //ok - final boolean b2 = as.forAll(s -> ac.forAll(c -> "" )); //fail + final boolean b5 = as.forAll(s -> ac.forAll(c -> "" )); //fail final String s2 = as.forAll2(s -> ac.forAll2(c -> false)); //fail - final boolean b3 = as.forAll((F)s -> ac.forAll((F)c -> "")); //fail + final boolean b6 = as.forAll((F)s -> ac.forAll((F)c -> "")); //fail final String s3 = as.forAll((FSub)s -> ac.forAll((FSub)c -> false)); //fail } } diff --git a/langtools/test/tools/javac/lambda/TargetType24.out b/langtools/test/tools/javac/lambda/TargetType24.out index 7554a6dd2c3..9542304a21b 100644 --- a/langtools/test/tools/javac/lambda/TargetType24.out +++ b/langtools/test/tools/javac/lambda/TargetType24.out @@ -1,5 +1,11 @@ -TargetType24.java:34:37: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, boolean) -TargetType24.java:35:45: compiler.err.cant.apply.symbol: kindname.method, forAll2, TargetType24.FSub, @945, kindname.class, TargetType24.Array, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String))) -TargetType24.java:36:101: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Boolean)) -TargetType24.java:37:104: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String)) -4 errors +TargetType24.java:33:30: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F), TargetType24.Array, kindname.method, forAll(TargetType24.FSub), TargetType24.Array +TargetType24.java:33:45: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F), TargetType24.Array, kindname.method, forAll(TargetType24.FSub), TargetType24.Array +TargetType24.java:34:54: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F), TargetType24.Array, kindname.method, forAll(TargetType24.FSub), TargetType24.Array +TargetType24.java:35:30: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F), TargetType24.Array, kindname.method, forAll(TargetType24.FSub), TargetType24.Array +TargetType24.java:37:30: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F), TargetType24.Array, kindname.method, forAll(TargetType24.FSub), TargetType24.Array +TargetType24.java:37:45: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F), TargetType24.Array, kindname.method, forAll(TargetType24.FSub), TargetType24.Array +TargetType24.java:37:52: compiler.err.cant.apply.symbol: kindname.method, forAll, TargetType24.F, @1149, kindname.class, TargetType24.Array, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Boolean))) +TargetType24.java:38:53: compiler.err.cant.apply.symbol: kindname.method, forAll2, TargetType24.FSub, @1221, kindname.class, TargetType24.Array, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String))) +TargetType24.java:39:101: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Boolean)) +TargetType24.java:40:104: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String)) +10 errors diff --git a/langtools/test/tools/javac/lambda/TargetType26.out b/langtools/test/tools/javac/lambda/TargetType26.out index 15cfc615f45..b90c658302d 100644 --- a/langtools/test/tools/javac/lambda/TargetType26.out +++ b/langtools/test/tools/javac/lambda/TargetType26.out @@ -1,2 +1,2 @@ -TargetType26.java:16:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z) +TargetType26.java:16:11: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.not.a.functional.intf: java.lang.Object)) 1 error diff --git a/langtools/test/tools/javac/lambda/TargetType27.out b/langtools/test/tools/javac/lambda/TargetType27.out index bf388592025..61cb54ead88 100644 --- a/langtools/test/tools/javac/lambda/TargetType27.out +++ b/langtools/test/tools/javac/lambda/TargetType27.out @@ -1,2 +1,2 @@ -TargetType27.java:18:10: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: R) +TargetType27.java:18:10: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: A,R, (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.not.a.functional.intf: java.lang.Object))) 1 error diff --git a/langtools/test/tools/javac/lambda/TargetType39.out b/langtools/test/tools/javac/lambda/TargetType39.out index 36a61bce0e2..6229f690173 100644 --- a/langtools/test/tools/javac/lambda/TargetType39.out +++ b/langtools/test/tools/javac/lambda/TargetType39.out @@ -1,3 +1,3 @@ -TargetType39.java:19:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: U) -TargetType39.java:20:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: V) +TargetType39.java:19:13: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: U,V, (compiler.misc.incompatible.type.in.conditional: (compiler.misc.inconvertible.types: TargetType39.SAM, TargetType39.SAM))) +TargetType39.java:20:13: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: U,V, (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.incompatible.type.in.conditional: (compiler.misc.not.a.functional.intf: java.lang.Object)))) 2 errors diff --git a/langtools/test/tools/javac/lambda/TargetType43.out b/langtools/test/tools/javac/lambda/TargetType43.out index 666e67c8341..7d50949d9a0 100644 --- a/langtools/test/tools/javac/lambda/TargetType43.out +++ b/langtools/test/tools/javac/lambda/TargetType43.out @@ -1,4 +1,5 @@ TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) TargetType43.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null) +TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object)) TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null) -3 errors +4 errors diff --git a/langtools/test/tools/javac/lambda/TargetType66.java b/langtools/test/tools/javac/lambda/TargetType66.java index d9e85a0c87e..db704fd3a6f 100644 --- a/langtools/test/tools/javac/lambda/TargetType66.java +++ b/langtools/test/tools/javac/lambda/TargetType66.java @@ -17,8 +17,8 @@ class TargetType66 { void g(SAM2 s2) { } void test() { - g(x->{ String s = x; }); //g(SAM1) - g(x->{ Integer i = x; }); //g(SAM2) + g(x->{ String s = x; }); //ambiguous + g(x->{ Integer i = x; }); //ambiguous g(x->{ Object o = x; }); //ambiguous g(x->{ Character c = x; }); //error: inapplicable methods g(x->{ Character c = ""; }); //error: incompatible types diff --git a/langtools/test/tools/javac/lambda/TargetType66.out b/langtools/test/tools/javac/lambda/TargetType66.out index b5c828df27b..8dd2ad710bb 100644 --- a/langtools/test/tools/javac/lambda/TargetType66.out +++ b/langtools/test/tools/javac/lambda/TargetType66.out @@ -1,4 +1,9 @@ +TargetType66.java:20:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66 +TargetType66.java:21:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66 +TargetType66.java:21:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer) TargetType66.java:22:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66 -TargetType66.java:23:9: compiler.err.cant.apply.symbols: kindname.method, g, @578,{(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.String, (compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character))))),(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.Integer, (compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Integer, java.lang.Character)))))} +TargetType66.java:23:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66 +TargetType66.java:23:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character) +TargetType66.java:24:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66 TargetType66.java:24:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character) -3 errors +8 errors diff --git a/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java b/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java index dbd7d1366a0..0e1f144f418 100644 --- a/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java +++ b/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java @@ -197,7 +197,7 @@ public class StructuralMostSpecificTest "class Test {\n" + " void m(SAM1 s) { }\n" + " void m(SAM2 s) { }\n" + - " { m(x->{ #LR }); }\n" + + " { m((#A1 x)->{ #LR }); }\n" + "}\n"; String source; @@ -236,14 +236,17 @@ public class StructuralMostSpecificTest void check() { checkCount.incrementAndGet(); + if (ak1 != ak2) + return; + if (!lrk.compatibleWith(rt1) || !lrk.compatibleWith(rt2)) return; if (lrk.needsConversion(rt1) != lrk.needsConversion(rt2)) return; - boolean m1MoreSpecific = moreSpecific(rt1, rt2, ek1, ek2, ak1, ak2); - boolean m2MoreSpecific = moreSpecific(rt2, rt1, ek2, ek1, ak2, ak1); + boolean m1MoreSpecific = rt1.moreSpecificThan(rt2); + boolean m2MoreSpecific = rt2.moreSpecificThan(rt1); boolean ambiguous = (m1MoreSpecific == m2MoreSpecific); @@ -268,17 +271,6 @@ public class StructuralMostSpecificTest } } - boolean moreSpecific(RetTypeKind rk1, RetTypeKind rk2, ExceptionKind ek1, - ExceptionKind ek2, ArgTypeKind ak1, ArgTypeKind ak2) { - if (!rk1.moreSpecificThan(rk2)) - return false; - - if (ak1 != ak2) - return false; - - return true; - } - static class DiagnosticChecker implements javax.tools.DiagnosticListener { diff --git a/langtools/test/tools/javac/lambda/typeInference/InferenceTest5.java b/langtools/test/tools/javac/lambda/typeInference/InferenceTest5.java deleted file mode 100644 index 291068070a4..00000000000 --- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest5.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2011, 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 8003280 - * @summary Add lambda tests - * This test is for overloaded methods, verify that the specific method is - selected when type inference occurs - * @compile InferenceTest5.java - * @run main InferenceTest5 - */ - -import java.util.List; -import java.io.File; - -public class InferenceTest5 { - - private static void assertTrue(boolean b) { - if(!b) - throw new AssertionError(); - } - - public static void main(String[] args) { - InferenceTest5 test = new InferenceTest5(); - int n = test.method1((a, b) -> {} ); - assertTrue(n == 1); - - n = test.method1(() -> null); - assertTrue(n == 2); - - n = test.method1(a -> null); - assertTrue(n == 3); - - n = test.method1(a -> {}); - assertTrue(n == 4); - - n = test.method1(() -> {}); - assertTrue(n == 5); - - n = test.method1((a, b) -> 0); - assertTrue(n == 6); - - n = test.method1((a, b) -> null); - assertTrue(n == 6); - - n = test.method1((a, b) -> null, (a, b) -> null); - assertTrue(n == 7); - } - - int method1(SAM1 s) { - return 1; - } - - int method1(SAM2 s) { - return 2; - } - - int method1(SAM3 s) { - return 3; - } - - int method1(SAM4 s) { - return 4; - } - - int method1(SAM5 s) { - return 5; - } - - int method1(SAM6 s) { - return 6; - } - - int method1(SAM6... s) { - return 7; - } - - static interface SAM1 { - void foo(List a, List b); - } - - static interface SAM2 { - List foo(); - } - - static interface SAM3 { - String foo(int a); - } - - static interface SAM4 { - void foo(List a); - } - - static interface SAM5 { - void foo(); - } - - static interface SAM6 { - V get(T t, T t2); - } -} diff --git a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.java b/langtools/test/tools/javac/lambda/typeInference/InferenceTest6.java similarity index 76% rename from langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.java rename to langtools/test/tools/javac/lambda/typeInference/InferenceTest6.java index d5f757e1379..b80a5903299 100644 --- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.java +++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest6.java @@ -1,16 +1,16 @@ /* * @test /nodynamiccopyright/ - * @bug 8003280 + * @bug 8003280 8016177 * @summary Add lambda tests * Missing cast to SAM type that causes type inference to not work. - * @compile/fail/ref=InferenceTest_neg5.out -XDrawDiagnostics InferenceTest_neg5.java + * @compile -XDrawDiagnostics InferenceTest6.java */ import java.util.*; -public class InferenceTest_neg5 { +public class InferenceTest6 { public static void main(String[] args) { - InferenceTest_neg5 test = new InferenceTest_neg5(); + InferenceTest6 test = new InferenceTest6(); test.method1(n -> {}); test.method1((SAM1)n -> {}); test.method1((SAM1)n -> {n++;}); diff --git a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg1_2.out b/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg1_2.out index cf0d1d587bf..8dc00a893ad 100644 --- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg1_2.out +++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg1_2.out @@ -1,4 +1,5 @@ InferenceTest_neg1_2.java:14:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM4), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5), InferenceTest_neg1_2 -InferenceTest_neg1_2.java:15:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM2), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM4), InferenceTest_neg1_2 -InferenceTest_neg1_2.java:16:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM3), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5), InferenceTest_neg1_2 -3 errors +InferenceTest_neg1_2.java:15:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM4), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5), InferenceTest_neg1_2 +InferenceTest_neg1_2.java:16:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM4), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5), InferenceTest_neg1_2 +InferenceTest_neg1_2.java:16:20: compiler.err.cant.apply.symbol: kindname.method, method, InferenceTest_neg1_2.SAM4, @597, kindname.class, InferenceTest_neg1_2, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, java.lang.String))) +4 errors diff --git a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.out b/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.out deleted file mode 100644 index 7f647251ecf..00000000000 --- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.out +++ /dev/null @@ -1,2 +0,0 @@ -InferenceTest_neg5.java:14:21: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: X) -1 error diff --git a/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java b/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java index 9399eb7b284..744a3ff5511 100644 --- a/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java +++ b/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java @@ -227,12 +227,7 @@ public class TypeInferenceComboTest } else if (lambdaBodyType != LambdaBody.RETURN_ARG) return false; - if ( genericDeclKind == GenericDeclKind.GENERIC_NOBOUND || - genericDeclKind == GenericDeclKind.GENERIC_BOUND ) { - if ( parameterType == TypeKind.GENERIC && - parameterKind == ParameterKind.IMPLICIT) //cyclic inference - return false; - } + return true; } From 46d7a993ada29543e07fd5952f257c7373f071f3 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Mon, 2 Sep 2013 22:44:06 +0100 Subject: [PATCH 0184/1294] 8022162: Incorrect signature determination for certain inner class generics Reviewed-by: jjg --- .../com/sun/tools/javac/jvm/ClassReader.java | 21 +++-- ...atureDeterminationForInnerClassesTest.java | 89 +++++++++++++++++++ 2 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 langtools/test/tools/javac/T8022162/IncorrectSignatureDeterminationForInnerClassesTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 1717e50194f..3fc93921c8e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -727,12 +727,14 @@ public class ClassReader implements Completer { ClassSymbol t = enterClass(names.fromUtf(signatureBuffer, startSbp, sbp - startSbp)); - if (outer == Type.noType) - outer = t.erasure(types); - else - outer = new ClassType(outer, List.nil(), t); - sbp = startSbp; - return outer; + + try { + return (outer == Type.noType) ? + t.erasure(types) : + new ClassType(outer, List.nil(), t); + } finally { + sbp = startSbp; + } } case '<': // generic arguments @@ -797,6 +799,13 @@ public class ClassReader implements Completer { continue; case '.': + //we have seen an enclosing non-generic class + if (outer != Type.noType) { + t = enterClass(names.fromUtf(signatureBuffer, + startSbp, + sbp - startSbp)); + outer = new ClassType(outer, List.nil(), t); + } signatureBuffer[sbp++] = (byte)'$'; continue; case '/': diff --git a/langtools/test/tools/javac/T8022162/IncorrectSignatureDeterminationForInnerClassesTest.java b/langtools/test/tools/javac/T8022162/IncorrectSignatureDeterminationForInnerClassesTest.java new file mode 100644 index 00000000000..4e9eaf2fb8f --- /dev/null +++ b/langtools/test/tools/javac/T8022162/IncorrectSignatureDeterminationForInnerClassesTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, 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 8022162 + * @summary Incorrect signature determination for certain inner class generics + * @library /tools/javac/lib + * @build ToolBox + * @run main IncorrectSignatureDeterminationForInnerClassesTest + */ + +import java.nio.file.Files; +import java.nio.file.Paths; + +public class IncorrectSignatureDeterminationForInnerClassesTest { + + private static final String DSrc = + "package p1;\n" + + + "public class D {\n" + + "}\n" + + + "abstract class Q {\n" + + " protected void m(M.E e) {}\n" + + + " public class M extends D {\n" + + " public class E {}\n" + + " }\n" + + "}"; + + private static final String HSrc = + "package p1;\n" + + + "public class H {\n" + + " static class EQ extends Q {\n" + + " private void m2(M.E item) {\n" + + " m(item);\n" + + " }\n" + + " }\n" + + "}"; + + public static void main(String args[]) throws Exception { + new IncorrectSignatureDeterminationForInnerClassesTest().run(); + } + + void run() throws Exception { + compile(); + } + + void compile() throws Exception { + Files.createDirectory(Paths.get("classes")); + + ToolBox.JavaToolArgs javacParams = + new ToolBox.JavaToolArgs() + .appendArgs("-d", "classes") + .setSources(DSrc); + + ToolBox.javac(javacParams); + + // compile class H against the class files for classes D and Q + javacParams = + new ToolBox.JavaToolArgs() + .appendArgs("-d", "classes", "-cp", "classes") + .setSources(HSrc); + ToolBox.javac(javacParams); + } + +} From 4247113e6a6fd62155a793d60a5b91853b5113d1 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 3 Sep 2013 11:00:06 +0400 Subject: [PATCH 0185/1294] 6943780: JTabbedPane throws ArrayIndexOutOfBoundsException sometimes Reviewed-by: alexsch --- .../swing/plaf/basic/BasicTabbedPaneUI.java | 1 + .../basic/BasicTabbedPaneUI/Test6943780.java | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 jdk/test/javax/swing/plaf/basic/BasicTabbedPaneUI/Test6943780.java diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java index a9b3d26358c..983e173e3af 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -3350,6 +3350,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { private void updateView() { int tabPlacement = tabPane.getTabPlacement(); int tabCount = tabPane.getTabCount(); + assureRectsCreated(tabCount); Rectangle vpRect = viewport.getBounds(); Dimension viewSize = viewport.getViewSize(); Rectangle viewRect = viewport.getViewRect(); diff --git a/jdk/test/javax/swing/plaf/basic/BasicTabbedPaneUI/Test6943780.java b/jdk/test/javax/swing/plaf/basic/BasicTabbedPaneUI/Test6943780.java new file mode 100644 index 00000000000..d1739a33574 --- /dev/null +++ b/jdk/test/javax/swing/plaf/basic/BasicTabbedPaneUI/Test6943780.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.JButton; +import javax.swing.JTabbedPane; +import java.awt.Component; + +import static javax.swing.SwingUtilities.invokeAndWait; + +/* + * @test + * @bug 4873983 6943780 + * @summary Tests JTabbedPane with SCROLL_TAB_LAYOUT + * @author Sergey Malenkov + */ +public class Test6943780 implements Runnable, Thread.UncaughtExceptionHandler { + public static void main(String[] args) throws Exception { + invokeAndWait(new Test6943780()); + } + + @Override + public void uncaughtException(Thread thread, Throwable throwable) { + throwable.printStackTrace(); + System.exit(1); + } + + @Override + public void run() { + JTabbedPane pane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT); + pane.addTab("first", new JButton("first")); + pane.addTab("second", new JButton("second")); + for (Component component : pane.getComponents()) { + component.setSize(100, 100); + } + } +} From 6ffe7bb5137c7608cf2bc6cd0fa57a7618059c09 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Tue, 3 Sep 2013 17:27:20 +0400 Subject: [PATCH 0186/1294] 8007156: [macosx] Wrong events in processKeyBinding of JTable Submit Date Reviewed-by: leonidr --- .../classes/sun/lwawt/LWComponentPeer.java | 2 + .../classes/sun/lwawt/LWWindowPeer.java | 7 +- .../ExtendedKeyCode/ExtendedKeyCodeTest.java | 81 +++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java diff --git a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java index 05d1d5d1fad..5b081b1f2f2 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java @@ -1254,6 +1254,8 @@ public abstract class LWComponentPeer KeyEvent ke = (KeyEvent) e; delegateEvent = new KeyEvent(getDelegateFocusOwner(), ke.getID(), ke.getWhen(), ke.getModifiers(), ke.getKeyCode(), ke.getKeyChar(), ke.getKeyLocation()); + AWTAccessor.getKeyEventAccessor().setExtendedKeyCode((KeyEvent) delegateEvent, + ke.getExtendedKeyCode()); } else if (e instanceof FocusEvent) { FocusEvent fe = (FocusEvent) e; delegateEvent = new FocusEvent(getDelegateFocusOwner(), fe.getID(), fe.isTemporary()); diff --git a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java index 2be41cf3b0d..6000016306a 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java @@ -933,7 +933,12 @@ public class LWWindowPeer focusOwner = this.getTarget(); } } - postEvent(new KeyEvent(focusOwner, id, when, modifiers, keyCode, keyChar, keyLocation)); + + KeyEvent keyEvent = new KeyEvent(focusOwner, id, when, modifiers, + keyCode, keyChar, keyLocation); + AWTAccessor.getKeyEventAccessor().setExtendedKeyCode(keyEvent, + ExtendedKeyCodes.getExtendedKeyCodeForChar(keyChar)); + postEvent(keyEvent); } // ---- UTILITY METHODS ---- // diff --git a/jdk/test/java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java b/jdk/test/java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java new file mode 100644 index 00000000000..5d1342d171f --- /dev/null +++ b/jdk/test/java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.KeyEvent; +import java.awt.event.KeyAdapter; +import sun.awt.ExtendedKeyCodes; +import sun.awt.SunToolkit; + +/* + * @test + * @bug 8007156 + * @summary Extended key code is not set for a key event + * @author Alexandr Scherbatiy + * @run main ExtendedKeyCodeTest + */ +public class ExtendedKeyCodeTest { + + private static volatile boolean setExtendedKeyCode = true; + private static volatile int eventsCount = 0; + + public static void main(String[] args) throws Exception { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + + Frame frame = new Frame(); + frame.setSize(300, 300); + + frame.addKeyListener(new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) { + eventsCount++; + setExtendedKeyCode = setExtendedKeyCode && (e.getExtendedKeyCode() + == ExtendedKeyCodes.getExtendedKeyCodeForChar(e.getKeyChar())); + } + + @Override + public void keyReleased(KeyEvent e) { + eventsCount++; + setExtendedKeyCode = setExtendedKeyCode && (e.getExtendedKeyCode() + == ExtendedKeyCodes.getExtendedKeyCodeForChar(e.getKeyChar())); + } + }); + + frame.setVisible(true); + toolkit.realSync(); + + robot.keyPress(KeyEvent.VK_D); + robot.keyRelease(KeyEvent.VK_D); + toolkit.realSync(); + + frame.dispose(); + + if (eventsCount != 2 || !setExtendedKeyCode) { + throw new RuntimeException("Wrong extended key code"); + } + } +} From 22039ebd3e8d299215c64b8a27209cf9e8c27cf4 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 3 Sep 2013 21:53:14 +0400 Subject: [PATCH 0187/1294] 7172865: PropertyDescriptor fails to work with setter method name if setter is non-void Reviewed-by: art, alexsch --- .../java/beans/IndexedPropertyDescriptor.java | 42 ++--- .../classes/java/beans/MethodDescriptor.java | 24 +-- .../share/classes/java/beans/MethodRef.java | 87 ++++++++++ .../java/beans/PropertyDescriptor.java | 46 ++--- .../java/beans/Introspector/Test7172865.java | 162 ++++++++++++++++++ 5 files changed, 287 insertions(+), 74 deletions(-) create mode 100644 jdk/src/share/classes/java/beans/MethodRef.java create mode 100644 jdk/test/java/beans/Introspector/Test7172865.java diff --git a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java index 1d59f7afddb..866d35ba56c 100644 --- a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java +++ b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java @@ -41,8 +41,8 @@ import java.lang.reflect.Method; public class IndexedPropertyDescriptor extends PropertyDescriptor { private Reference> indexedPropertyTypeRef; - private Reference indexedReadMethodRef; - private Reference indexedWriteMethodRef; + private final MethodRef indexedReadMethodRef = new MethodRef(); + private final MethodRef indexedWriteMethodRef = new MethodRef(); private String indexedReadMethodName; private String indexedWriteMethodName; @@ -173,11 +173,11 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { * May return null if the property isn't indexed or is write-only. */ public synchronized Method getIndexedReadMethod() { - Method indexedReadMethod = getIndexedReadMethod0(); + Method indexedReadMethod = this.indexedReadMethodRef.get(); if (indexedReadMethod == null) { Class cls = getClass0(); if (cls == null || - (indexedReadMethodName == null && indexedReadMethodRef == null)) { + (indexedReadMethodName == null && !this.indexedReadMethodRef.isSet())) { // the Indexed readMethod was explicitly set to null. return null; } @@ -215,20 +215,19 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { // the indexed property type is set by the reader. setIndexedPropertyType(findIndexedPropertyType(readMethod, - getIndexedWriteMethod0())); + this.indexedWriteMethodRef.get())); setIndexedReadMethod0(readMethod); } private void setIndexedReadMethod0(Method readMethod) { + this.indexedReadMethodRef.set(readMethod); if (readMethod == null) { indexedReadMethodName = null; - indexedReadMethodRef = null; return; } setClass0(readMethod.getDeclaringClass()); indexedReadMethodName = readMethod.getName(); - this.indexedReadMethodRef = getSoftReference(readMethod); setTransient(readMethod.getAnnotation(Transient.class)); } @@ -241,11 +240,11 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { * May return null if the property isn't indexed or is read-only. */ public synchronized Method getIndexedWriteMethod() { - Method indexedWriteMethod = getIndexedWriteMethod0(); + Method indexedWriteMethod = this.indexedWriteMethodRef.get(); if (indexedWriteMethod == null) { Class cls = getClass0(); if (cls == null || - (indexedWriteMethodName == null && indexedWriteMethodRef == null)) { + (indexedWriteMethodName == null && !this.indexedWriteMethodRef.isSet())) { // the Indexed writeMethod was explicitly set to null. return null; } @@ -301,15 +300,14 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { } private void setIndexedWriteMethod0(Method writeMethod) { + this.indexedWriteMethodRef.set(writeMethod); if (writeMethod == null) { indexedWriteMethodName = null; - indexedWriteMethodRef = null; return; } setClass0(writeMethod.getDeclaringClass()); indexedWriteMethodName = writeMethod.getName(); - this.indexedWriteMethodRef = getSoftReference(writeMethod); setTransient(writeMethod.getAnnotation(Transient.class)); } @@ -349,18 +347,6 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { : null; } - private Method getIndexedReadMethod0() { - return (this.indexedReadMethodRef != null) - ? this.indexedReadMethodRef.get() - : null; - } - - private Method getIndexedWriteMethod0() { - return (this.indexedWriteMethodRef != null) - ? this.indexedWriteMethodRef.get() - : null; - } - private Class findIndexedPropertyType(Method indexedReadMethod, Method indexedWriteMethod) throws IntrospectionException { @@ -492,8 +478,8 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { */ IndexedPropertyDescriptor(IndexedPropertyDescriptor old) { super(old); - indexedReadMethodRef = old.indexedReadMethodRef; - indexedWriteMethodRef = old.indexedWriteMethodRef; + this.indexedReadMethodRef.set(old.indexedReadMethodRef.get()); + this.indexedWriteMethodRef.set(old.indexedWriteMethodRef.get()); indexedPropertyTypeRef = old.indexedPropertyTypeRef; indexedWriteMethodName = old.indexedWriteMethodName; indexedReadMethodName = old.indexedReadMethodName; @@ -502,7 +488,7 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { void updateGenericsFor(Class type) { super.updateGenericsFor(type); try { - setIndexedPropertyType(findIndexedPropertyType(getIndexedReadMethod0(), getIndexedWriteMethod0())); + setIndexedPropertyType(findIndexedPropertyType(this.indexedReadMethodRef.get(), this.indexedWriteMethodRef.get())); } catch (IntrospectionException exception) { setIndexedPropertyType(null); @@ -532,7 +518,7 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { void appendTo(StringBuilder sb) { super.appendTo(sb); appendTo(sb, "indexedPropertyType", this.indexedPropertyTypeRef); - appendTo(sb, "indexedReadMethod", this.indexedReadMethodRef); - appendTo(sb, "indexedWriteMethod", this.indexedWriteMethodRef); + appendTo(sb, "indexedReadMethod", this.indexedReadMethodRef.get()); + appendTo(sb, "indexedWriteMethod", this.indexedWriteMethodRef.get()); } } diff --git a/jdk/src/share/classes/java/beans/MethodDescriptor.java b/jdk/src/share/classes/java/beans/MethodDescriptor.java index db760c0e20a..f8cd73d3897 100644 --- a/jdk/src/share/classes/java/beans/MethodDescriptor.java +++ b/jdk/src/share/classes/java/beans/MethodDescriptor.java @@ -38,7 +38,7 @@ import java.util.ArrayList; public class MethodDescriptor extends FeatureDescriptor { - private Reference methodRef; + private final MethodRef methodRef = new MethodRef(); private String[] paramNames; @@ -81,7 +81,7 @@ public class MethodDescriptor extends FeatureDescriptor { * @return The low-level description of the method */ public synchronized Method getMethod() { - Method method = getMethod0(); + Method method = this.methodRef.get(); if (method == null) { Class cls = getClass0(); String name = getName(); @@ -114,13 +114,7 @@ public class MethodDescriptor extends FeatureDescriptor { setClass0(method.getDeclaringClass()); } setParams(getParameterTypes(getClass0(), method)); - this.methodRef = getSoftReference(method); - } - - private Method getMethod0() { - return (this.methodRef != null) - ? this.methodRef.get() - : null; + this.methodRef.set(method); } private synchronized void setParams(Class[] param) { @@ -177,12 +171,10 @@ public class MethodDescriptor extends FeatureDescriptor { */ MethodDescriptor(MethodDescriptor x, MethodDescriptor y) { - super(x,y); + super(x, y); - methodRef = x.methodRef; - if (y.methodRef != null) { - methodRef = y.methodRef; - } + Method method = y.methodRef.get(); + this.methodRef.set(null != method ? method : x.methodRef.get()); params = x.params; if (y.params != null) { params = y.params; @@ -205,7 +197,7 @@ public class MethodDescriptor extends FeatureDescriptor { MethodDescriptor(MethodDescriptor old) { super(old); - methodRef = old.methodRef; + this.methodRef.set(old.getMethod()); params = old.params; paramNames = old.paramNames; @@ -219,7 +211,7 @@ public class MethodDescriptor extends FeatureDescriptor { } void appendTo(StringBuilder sb) { - appendTo(sb, "method", this.methodRef); + appendTo(sb, "method", this.methodRef.get()); if (this.parameterDescriptors != null) { sb.append("; parameterDescriptors={"); for (ParameterDescriptor pd : this.parameterDescriptors) { diff --git a/jdk/src/share/classes/java/beans/MethodRef.java b/jdk/src/share/classes/java/beans/MethodRef.java new file mode 100644 index 00000000000..59b2690b4fa --- /dev/null +++ b/jdk/src/share/classes/java/beans/MethodRef.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.beans; + +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.lang.reflect.Method; + +import static sun.reflect.misc.ReflectUtil.isPackageAccessible; + +final class MethodRef { + private String signature; + private SoftReference methodRef; + private WeakReference> typeRef; + + void set(Method method) { + if (method == null) { + this.signature = null; + this.methodRef = null; + this.typeRef = null; + } + else { + this.signature = method.toGenericString(); + this.methodRef = new SoftReference<>(method); + this.typeRef = new WeakReference>(method.getDeclaringClass()); + } + } + + boolean isSet() { + return this.methodRef != null; + } + + Method get() { + if (this.methodRef == null) { + return null; + } + Method method = this.methodRef.get(); + if (method == null) { + method = find(this.typeRef.get(), this.signature); + if (method == null) { + this.signature = null; + this.methodRef = null; + this.typeRef = null; + } + else { + this.methodRef = new SoftReference<>(method); + } + } + return isPackageAccessible(method.getDeclaringClass()) ? method : null; + } + + private static Method find(Class type, String signature) { + if (type != null) { + for (Method method : type.getMethods()) { + if (type.equals(method.getDeclaringClass())) { + if (method.toGenericString().equals(signature)) { + return method; + } + } + } + } + return null; + } +} diff --git a/jdk/src/share/classes/java/beans/PropertyDescriptor.java b/jdk/src/share/classes/java/beans/PropertyDescriptor.java index c519b504d58..aed5ec57a4d 100644 --- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java +++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java @@ -36,8 +36,8 @@ import java.lang.reflect.Constructor; public class PropertyDescriptor extends FeatureDescriptor { private Reference> propertyTypeRef; - private Reference readMethodRef; - private Reference writeMethodRef; + private final MethodRef readMethodRef = new MethodRef(); + private final MethodRef writeMethodRef = new MethodRef(); private Reference> propertyEditorClassRef; private boolean bound; @@ -68,8 +68,8 @@ public class PropertyDescriptor extends FeatureDescriptor { public PropertyDescriptor(String propertyName, Class beanClass) throws IntrospectionException { this(propertyName, beanClass, - Introspector.IS_PREFIX + NameGenerator.capitalize(propertyName), - Introspector.SET_PREFIX + NameGenerator.capitalize(propertyName)); + Introspector.IS_PREFIX + NameGenerator.capitalize(propertyName), + Introspector.SET_PREFIX + NameGenerator.capitalize(propertyName)); } /** @@ -203,10 +203,10 @@ public class PropertyDescriptor extends FeatureDescriptor { * May return null if the property can't be read. */ public synchronized Method getReadMethod() { - Method readMethod = getReadMethod0(); + Method readMethod = this.readMethodRef.get(); if (readMethod == null) { Class cls = getClass0(); - if (cls == null || (readMethodName == null && readMethodRef == null)) { + if (cls == null || (readMethodName == null && !this.readMethodRef.isSet())) { // The read method was explicitly set to null. return null; } @@ -247,17 +247,16 @@ public class PropertyDescriptor extends FeatureDescriptor { */ public synchronized void setReadMethod(Method readMethod) throws IntrospectionException { + this.readMethodRef.set(readMethod); if (readMethod == null) { readMethodName = null; - readMethodRef = null; return; } // The property type is determined by the read method. - setPropertyType(findPropertyType(readMethod, getWriteMethod0())); + setPropertyType(findPropertyType(readMethod, this.writeMethodRef.get())); setClass0(readMethod.getDeclaringClass()); readMethodName = readMethod.getName(); - this.readMethodRef = getSoftReference(readMethod); setTransient(readMethod.getAnnotation(Transient.class)); } @@ -268,10 +267,10 @@ public class PropertyDescriptor extends FeatureDescriptor { * May return null if the property can't be written. */ public synchronized Method getWriteMethod() { - Method writeMethod = getWriteMethod0(); + Method writeMethod = this.writeMethodRef.get(); if (writeMethod == null) { Class cls = getClass0(); - if (cls == null || (writeMethodName == null && writeMethodRef == null)) { + if (cls == null || (writeMethodName == null && !this.writeMethodRef.isSet())) { // The write method was explicitly set to null. return null; } @@ -318,9 +317,9 @@ public class PropertyDescriptor extends FeatureDescriptor { */ public synchronized void setWriteMethod(Method writeMethod) throws IntrospectionException { + this.writeMethodRef.set(writeMethod); if (writeMethod == null) { writeMethodName = null; - writeMethodRef = null; return; } // Set the property type - which validates the method @@ -328,22 +327,9 @@ public class PropertyDescriptor extends FeatureDescriptor { setClass0(writeMethod.getDeclaringClass()); writeMethodName = writeMethod.getName(); - this.writeMethodRef = getSoftReference(writeMethod); setTransient(writeMethod.getAnnotation(Transient.class)); } - private Method getReadMethod0() { - return (this.readMethodRef != null) - ? this.readMethodRef.get() - : null; - } - - private Method getWriteMethod0() { - return (this.writeMethodRef != null) - ? this.writeMethodRef.get() - : null; - } - /** * Overridden to ensure that a super class doesn't take precedent */ @@ -617,8 +603,8 @@ public class PropertyDescriptor extends FeatureDescriptor { PropertyDescriptor(PropertyDescriptor old) { super(old); propertyTypeRef = old.propertyTypeRef; - readMethodRef = old.readMethodRef; - writeMethodRef = old.writeMethodRef; + this.readMethodRef.set(old.readMethodRef.get()); + this.writeMethodRef.set(old.writeMethodRef.get()); propertyEditorClassRef = old.propertyEditorClassRef; writeMethodName = old.writeMethodName; @@ -632,7 +618,7 @@ public class PropertyDescriptor extends FeatureDescriptor { void updateGenericsFor(Class type) { setClass0(type); try { - setPropertyType(findPropertyType(getReadMethod0(), getWriteMethod0())); + setPropertyType(findPropertyType(this.readMethodRef.get(), this.writeMethodRef.get())); } catch (IntrospectionException exception) { setPropertyType(null); @@ -723,8 +709,8 @@ public class PropertyDescriptor extends FeatureDescriptor { appendTo(sb, "constrained", this.constrained); appendTo(sb, "propertyEditorClass", this.propertyEditorClassRef); appendTo(sb, "propertyType", this.propertyTypeRef); - appendTo(sb, "readMethod", this.readMethodRef); - appendTo(sb, "writeMethod", this.writeMethodRef); + appendTo(sb, "readMethod", this.readMethodRef.get()); + appendTo(sb, "writeMethod", this.writeMethodRef.get()); } private boolean isAssignable(Method m1, Method m2) { diff --git a/jdk/test/java/beans/Introspector/Test7172865.java b/jdk/test/java/beans/Introspector/Test7172865.java new file mode 100644 index 00000000000..6647225ca8f --- /dev/null +++ b/jdk/test/java/beans/Introspector/Test7172865.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.beans.IndexedPropertyDescriptor; +import java.beans.MethodDescriptor; +import java.beans.PropertyDescriptor; + +/* + * @test + * @bug 7172854 7172865 + * @summary Tests that cached methods are not lost + * @author Sergey Malenkov + */ + +public class Test7172865 { + public static void main(String[] args) throws Exception { + int errors = 0; + + MethodDescriptor md = new MethodDescriptor(Test7172865.class.getMethod("getGood")); + + errors += test(PropertyDescriptor.class, "good", true); + PropertyDescriptor pdGoodString = new PropertyDescriptor("good", Test7172865.class, "getGood", "setGood"); + PropertyDescriptor pdGoodMethod = new PropertyDescriptor("good", + Test7172865.class.getMethod("getGood"), + Test7172865.class.getMethod("setGood", args.getClass())); + + errors += test(PropertyDescriptor.class, "bad", false); + PropertyDescriptor pdBadString = new PropertyDescriptor("bad", Test7172865.class, "getBad", null); + PropertyDescriptor pdBadMethod = new PropertyDescriptor("bad", + Test7172865.class.getMethod("getBad"), + Test7172865.class.getMethod("setBad", args.getClass())); + + errors += test(IndexedPropertyDescriptor.class, "good", true); + IndexedPropertyDescriptor ipdGoodString = new IndexedPropertyDescriptor("good", Test7172865.class, "getGood", "setGood", "getGood", "setGood"); + IndexedPropertyDescriptor ipdGoodMethod = new IndexedPropertyDescriptor("good", + Test7172865.class.getMethod("getGood"), + Test7172865.class.getMethod("setGood", args.getClass()), + Test7172865.class.getMethod("getGood", Integer.TYPE), + Test7172865.class.getMethod("setGood", Integer.TYPE, String.class)); + + errors += test(IndexedPropertyDescriptor.class, "bad", false); + IndexedPropertyDescriptor ipdBadString = new IndexedPropertyDescriptor("bad", Test7172865.class, "getBad", null, "getBad", null); + IndexedPropertyDescriptor ipdBadMethod = new IndexedPropertyDescriptor("bad", + Test7172865.class.getMethod("getBad"), + Test7172865.class.getMethod("setBad", args.getClass()), + Test7172865.class.getMethod("getBad", Integer.TYPE), + Test7172865.class.getMethod("setBad", Integer.TYPE, String.class)); + + for (int i = 1; i <= 2; i++) { + System.out.println("STEP: " + i); + errors += test("md", null != md.getMethod()); + + errors += test("pdGoodString", pdGoodString, true, true); + errors += test("pdGoodMethod", pdGoodMethod, true, true); + + errors += test("pdBadString", pdBadString, true, false); + errors += test("pdBadMethod", pdBadMethod, true, true); + + errors += test("ipdGoodString", ipdGoodString, true, true, true, true); + errors += test("ipdGoodMethod", ipdGoodMethod, true, true, true, true); + + errors += test("ipdBadString", ipdBadString, true, false, true, false); + errors += test("ipdBadMethod", ipdBadMethod, true, true, true, true); + + try { + int[] array = new int[1024]; + while (true) { + array = new int[array.length << 1]; + } + } + catch (OutOfMemoryError error) { + System.gc(); + } + } + if (errors > 0) { + throw new Error("found " + errors + " errors"); + } + } + + private static int test(Class type, String property, boolean value) { + String message = type.getSimpleName() + "(" + property + ") "; + try { + type.getConstructor(String.class, Class.class).newInstance(property, Test7172865.class); + message += "passed"; + } + catch (Exception exception) { + message += "failed"; + value = !value; + } + if (value) { + message += " as expected"; + } + System.out.println(message); + return value ? 0 : 1; + } + + private static int test(String message, boolean value) { + System.out.println(message + ": " + (value ? "passed" : "failed")); + return value ? 0 : 1; + } + + private static int test(String message, PropertyDescriptor pd, boolean rm, boolean wm) { + return test(message + ".Read", rm == (null != pd.getReadMethod())) + + test(message + ".Write", wm == (null != pd.getWriteMethod())); + } + + private static int test(String message, IndexedPropertyDescriptor ipd, boolean rm, boolean wm, boolean irm, boolean iwm) { + return test(message, ipd, rm, wm) + + test(message + ".IndexedRead", irm == (null != ipd.getIndexedReadMethod())) + + test(message + ".IndexedWrite", iwm == (null != ipd.getIndexedWriteMethod())); + } + + public String[] getGood() { + return null; + } + + public String getGood(int index) { + return null; + } + + public void setGood(String[] good) { + } + + public void setGood(int index, String value) { + } + + public String[] getBad() { + return null; + } + + public String getBad(int index) { + return null; + } + + public Test7172865 setBad(String[] bad) { + return null; + } + + public Test7172865 setBad(int index, String value) { + return null; + } +} From bfb3ea37f74b0832c2cfc282342e4b42822ef587 Mon Sep 17 00:00:00 2001 From: Sean Coffey Date: Tue, 3 Sep 2013 22:35:05 +0100 Subject: [PATCH 0188/1294] 8017195: Introduce option to setKeepAlive parameter on CORBA sockets Reviewed-by: chegar, msheppar --- .../transport/DefaultSocketFactoryImpl.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java index fc1ffc70197..63578b9c3d1 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java +++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java @@ -32,6 +32,7 @@ import java.net.SocketException; import java.net.ServerSocket; import java.nio.channels.SocketChannel; import java.nio.channels.ServerSocketChannel; +import java.security.PrivilegedAction; import com.sun.corba.se.pept.transport.Acceptor; @@ -44,6 +45,22 @@ public class DefaultSocketFactoryImpl implements ORBSocketFactory { private ORB orb; + private static final boolean keepAlive; + + static { + keepAlive = java.security.AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Boolean run () { + String value = + System.getProperty("com.sun.CORBA.transport.enableTcpKeepAlive"); + if (value != null) + return new Boolean(!"false".equalsIgnoreCase(value)); + + return Boolean.FALSE; + } + }); + } public void setORB(ORB orb) { @@ -85,6 +102,9 @@ public class DefaultSocketFactoryImpl // Disable Nagle's algorithm (i.e., always send immediately). socket.setTcpNoDelay(true); + if (keepAlive) + socket.setKeepAlive(true); + return socket; } @@ -95,6 +115,8 @@ public class DefaultSocketFactoryImpl { // Disable Nagle's algorithm (i.e., always send immediately). socket.setTcpNoDelay(true); + if (keepAlive) + socket.setKeepAlive(true); } } From 0e90cf9ba0ebff017b843a20aced1b5d193873b5 Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Tue, 3 Sep 2013 15:23:16 -0700 Subject: [PATCH 0189/1294] 8024200: handle hg wrapper with space after #! Reviewed-by: tbell --- common/bin/hgforest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/bin/hgforest.sh b/common/bin/hgforest.sh index 12cf0234b17..1dc50390b42 100644 --- a/common/bin/hgforest.sh +++ b/common/bin/hgforest.sh @@ -47,7 +47,7 @@ python="" bpython="" if [ "#!" = "$has_hash_bang" ] ; then - python="`head -n 1 ${whichhg} | cut -b 3-`" + python="`head -n 1 ${whichhg} | cut -b 3- | sed -e 's/^[ \t]*//;s/[ \t]*$//'`" bpython="`basename "$python"`" fi From 06caeea3d6ec543161ee0f2e19f71e19aa62fdfb Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 3 Sep 2013 23:31:33 +0100 Subject: [PATCH 0190/1294] 8023389: Javac fails to infer type for lambda used with intersection type and wildcards Reviewed-by: jjg, vromero --- .../com/sun/tools/javac/comp/Attr.java | 29 +++++++----- .../tools/javac/lambda/8023389/T8023389.java | 46 +++++++++++++++++++ 2 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 langtools/test/tools/javac/lambda/8023389/T8023389.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index ad0d5003144..4c49601e2a4 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2319,30 +2319,37 @@ public class Attr extends JCTree.Visitor { boolean needsRecovery = resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK; try { - Type target = pt(); + Type currentTarget = pt(); List explicitParamTypes = null; if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) { //attribute lambda parameters attribStats(that.params, localEnv); explicitParamTypes = TreeInfo.types(that.params); - target = infer.instantiateFunctionalInterface(that, target, explicitParamTypes, resultInfo.checkContext); } Type lambdaType; if (pt() != Type.recoveryType) { - target = targetChecker.visit(target, that); - lambdaType = types.findDescriptorType(target); + /* We need to adjust the target. If the target is an + * intersection type, for example: SAM & I1 & I2 ... + * the target will be updated to SAM + */ + currentTarget = targetChecker.visit(currentTarget, that); + if (explicitParamTypes != null) { + currentTarget = infer.instantiateFunctionalInterface(that, + currentTarget, explicitParamTypes, resultInfo.checkContext); + } + lambdaType = types.findDescriptorType(currentTarget); } else { - target = Type.recoveryType; + currentTarget = Type.recoveryType; lambdaType = fallbackDescriptorType(that); } - setFunctionalInfo(localEnv, that, pt(), lambdaType, target, resultInfo.checkContext); + setFunctionalInfo(localEnv, that, pt(), lambdaType, currentTarget, resultInfo.checkContext); if (lambdaType.hasTag(FORALL)) { //lambda expression target desc cannot be a generic method resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target", - lambdaType, kindName(target.tsym), target.tsym)); + lambdaType, kindName(currentTarget.tsym), currentTarget.tsym)); result = that.type = types.createErrorType(pt()); return; } @@ -2376,7 +2383,7 @@ public class Attr extends JCTree.Visitor { if (arityMismatch) { resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda")); - result = that.type = types.createErrorType(target); + result = that.type = types.createErrorType(currentTarget); return; } } @@ -2403,7 +2410,7 @@ public class Attr extends JCTree.Visitor { attribStats(body.stats, localEnv); } - result = check(that, target, VAL, resultInfo); + result = check(that, currentTarget, VAL, resultInfo); boolean isSpeculativeRound = resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE; @@ -2414,9 +2421,9 @@ public class Attr extends JCTree.Visitor { checkLambdaCompatible(that, lambdaType, resultInfo.checkContext, isSpeculativeRound); if (!isSpeculativeRound) { - checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, target); + checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, currentTarget); } - result = check(that, target, VAL, resultInfo); + result = check(that, currentTarget, VAL, resultInfo); } catch (Types.FunctionDescriptorLookupError ex) { JCDiagnostic cause = ex.getDiagnostic(); resultInfo.checkContext.report(that, cause); diff --git a/langtools/test/tools/javac/lambda/8023389/T8023389.java b/langtools/test/tools/javac/lambda/8023389/T8023389.java new file mode 100644 index 00000000000..25eb0c8a066 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8023389/T8023389.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013, 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 8023389 + * @summary Javac fails to infer type for lambda used with intersection type and wildcards + * @compile T8023389.java + */ +public class T8023389 { + + static class U1 {} + static class X1 extends U1 {} + + interface I { } + + interface SAM { + void m(T t); + } + + /* Strictly speaking only the second of the following declarations provokes the bug. + * But the first line is also a useful test case. + */ + SAM sam1 = (SAM) (X1 x) -> { }; + SAM sam2 = (SAM & I) (X1 x) -> { }; +} From cab6b226ffd147158a7528c36f92a34ed10e685c Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Tue, 3 Sep 2013 23:41:37 +0100 Subject: [PATCH 0191/1294] 8023545: Misleading error message when using diamond operator with private constructor Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Resolve.java | 36 ++++++++++--------- ...ingErrorMsgDiamondPlusPrivateCtorTest.java | 16 +++++++++ ...dingErrorMsgDiamondPlusPrivateCtorTest.out | 2 ++ 3 files changed, 38 insertions(+), 16 deletions(-) create mode 100644 langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.java create mode 100644 langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 03f50401171..f89bfed0161 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -2546,22 +2546,26 @@ public class Resolve { @Override Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) { if (sym.kind >= AMBIGUOUS) { - final JCDiagnostic details = sym.kind == WRONG_MTH ? - ((InapplicableSymbolError)sym).errCandidate().snd : - null; - sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) { - @Override - JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, - Symbol location, Type site, Name name, List argtypes, List typeargtypes) { - String key = details == null ? - "cant.apply.diamond" : - "cant.apply.diamond.1"; - return diags.create(dkind, log.currentSource(), pos, key, - diags.fragment("diamond", site.tsym), details); - } - }; - sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes); - env.info.pendingResolutionPhase = currentResolutionContext.step; + if (sym.kind == HIDDEN) { + sym = super.access(env, pos, location, sym); + } else { + final JCDiagnostic details = sym.kind == WRONG_MTH ? + ((InapplicableSymbolError)sym).errCandidate().snd : + null; + sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) { + @Override + JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, + Symbol location, Type site, Name name, List argtypes, List typeargtypes) { + String key = details == null ? + "cant.apply.diamond" : + "cant.apply.diamond.1"; + return diags.create(dkind, log.currentSource(), pos, key, + diags.fragment("diamond", site.tsym), details); + } + }; + sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes); + env.info.pendingResolutionPhase = currentResolutionContext.step; + } } return sym; }}); diff --git a/langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.java b/langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.java new file mode 100644 index 00000000000..75959e29e22 --- /dev/null +++ b/langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8023545 + * @summary Misleading error message when using diamond operator with private constructor + * @compile/fail/ref=MisleadingErrorMsgDiamondPlusPrivateCtorTest.out -XDrawDiagnostics MisleadingErrorMsgDiamondPlusPrivateCtorTest.java + */ + +public class MisleadingErrorMsgDiamondPlusPrivateCtorTest { + public void foo() { + MyClass foo = new MyClass<>(); + } +} + +class MyClass { + private MyClass() {} +} diff --git a/langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.out b/langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.out new file mode 100644 index 00000000000..488e6a1041c --- /dev/null +++ b/langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.out @@ -0,0 +1,2 @@ +MisleadingErrorMsgDiamondPlusPrivateCtorTest.java:10:31: compiler.err.report.access: MyClass(), private, MyClass +1 error From 4cc7a55aab23a17d3bc0b6dc994593b07db64ae7 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 4 Sep 2013 00:01:05 +0100 Subject: [PATCH 0192/1294] 8023549: Compiler emitting spurious errors when constructor reference type is inferred and explicit type arguments are supplied Reviewed-by: jjg, vromero --- .../com/sun/tools/javac/comp/Attr.java | 7 ++++ .../tools/javac/resources/compiler.properties | 4 +++ .../examples/MrefInferAndExplicitParams.java | 35 +++++++++++++++++++ .../tools/javac/lambda/8023549/T8023549.java | 27 ++++++++++++++ .../tools/javac/lambda/8023549/T8023549.out | 5 +++ 5 files changed, 78 insertions(+) create mode 100644 langtools/test/tools/javac/diags/examples/MrefInferAndExplicitParams.java create mode 100644 langtools/test/tools/javac/lambda/8023549/T8023549.java create mode 100644 langtools/test/tools/javac/lambda/8023549/T8023549.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 4c49601e2a4..434f0b3815b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2647,6 +2647,13 @@ public class Attr extends JCTree.Visitor { if (that.getMode() == JCMemberReference.ReferenceMode.NEW) { exprType = chk.checkConstructorRefType(that.expr, exprType); + if (!exprType.isErroneous() && + exprType.isRaw() && + that.typeargs != null) { + log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()), + diags.fragment("mref.infer.and.explicit.params")); + exprType = types.createErrorType(exprType); + } } if (exprType.isErroneous()) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 4ca8a90c0c0..a87abc35b70 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1927,6 +1927,10 @@ compiler.misc.diamond.non.generic=\ compiler.misc.diamond.and.explicit.params=\ cannot use ''<>'' with explicit type parameters for constructor +# 0: unused +compiler.misc.mref.infer.and.explicit.params=\ + cannot use raw constructor reference with explicit type parameters for constructor + # 0: type, 1: list of type compiler.misc.explicit.param.do.not.conform.to.bounds=\ explicit type argument {0} does not conform to declared bound(s) {1} diff --git a/langtools/test/tools/javac/diags/examples/MrefInferAndExplicitParams.java b/langtools/test/tools/javac/diags/examples/MrefInferAndExplicitParams.java new file mode 100644 index 00000000000..ce24f82e60e --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/MrefInferAndExplicitParams.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, 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.mref +// key: compiler.misc.mref.infer.and.explicit.params + +public class MrefInferAndExplicitParams { + static class Foo {} + + interface Supplier { + X make(); + } + + Supplier> sfs = Foo::new; +} diff --git a/langtools/test/tools/javac/lambda/8023549/T8023549.java b/langtools/test/tools/javac/lambda/8023549/T8023549.java new file mode 100644 index 00000000000..efee943b8d6 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8023549/T8023549.java @@ -0,0 +1,27 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8023549 + * @summary Compiler emitting spurious errors when constructor reference type is inferred and explicit type arguments are supplied + * @compile/fail/ref=T8023549.out -XDrawDiagnostics T8023549.java + */ + +public class T8023549 { + static class Foo { } + + interface Supplier { + X make(); + } + + interface ExtSupplier extends Supplier { } + + void m1(Supplier> sfs) { } + + void m2(Supplier> sfs) { } + void m2(ExtSupplier> sfs) { } + + void test() { + Supplier> sfs = Foo::new; + m1(Foo::new); + m2(Foo::new); + } +} diff --git a/langtools/test/tools/javac/lambda/8023549/T8023549.out b/langtools/test/tools/javac/lambda/8023549/T8023549.out new file mode 100644 index 00000000000..d25a412378e --- /dev/null +++ b/langtools/test/tools/javac/lambda/8023549/T8023549.out @@ -0,0 +1,5 @@ +T8023549.java:23:37: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.mref.infer.and.explicit.params) +T8023549.java:24:12: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.mref.infer.and.explicit.params) +T8023549.java:25:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(T8023549.Supplier>), T8023549, kindname.method, m2(T8023549.ExtSupplier>), T8023549 +T8023549.java:25:12: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.mref.infer.and.explicit.params) +4 errors From 0fb014c2b3cff00c15e9e7cb6653818d061216e9 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Wed, 4 Sep 2013 09:34:25 +0200 Subject: [PATCH 0193/1294] 8023463: Improvements to HashMap/LinkedHashMap use of bins/buckets and trees (red/black) 8012913: LinkedHashMap key/value/entry spliterators should report ORDERED Co-authored-by: Doug Lea Reviewed-by: mduigou, forax, bchristi, alanb --- jdk/src/share/classes/java/util/HashMap.java | 4155 +++++++---------- .../classes/java/util/LinkedHashMap.java | 608 ++- .../java/lang/reflect/Generics/Probe.java | 6 +- .../java/util/Map/CheckRandomHashSeed.java | 2 - .../java/util/Map/InPlaceOpsCollisions.java | 1 - .../java/util/Map/MapBinToFromTreeTest.java | 240 + .../util/Map/TreeBinSplitBackToEntries.java | 255 - .../SpliteratorCharacteristics.java | 107 +- 8 files changed, 2429 insertions(+), 2945 deletions(-) create mode 100644 jdk/test/java/util/Map/MapBinToFromTreeTest.java delete mode 100644 jdk/test/java/util/Map/TreeBinSplitBackToEntries.java diff --git a/jdk/src/share/classes/java/util/HashMap.java b/jdk/src/share/classes/java/util/HashMap.java index 8dfafac8642..a6a7d152b5f 100644 --- a/jdk/src/share/classes/java/util/HashMap.java +++ b/jdk/src/share/classes/java/util/HashMap.java @@ -25,13 +25,14 @@ package java.util; -import java.io.*; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.concurrent.ThreadLocalRandom; import java.util.function.BiConsumer; -import java.util.function.Consumer; import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.function.Function; /** @@ -63,20 +64,25 @@ import java.util.function.Function; * structures are rebuilt) so that the hash table has approximately twice the * number of buckets. * - *

    As a general rule, the default load factor (.75) offers a good tradeoff - * between time and space costs. Higher values decrease the space overhead - * but increase the lookup cost (reflected in most of the operations of the - * HashMap class, including get and put). The - * expected number of entries in the map and its load factor should be taken - * into account when setting its initial capacity, so as to minimize the - * number of rehash operations. If the initial capacity is greater - * than the maximum number of entries divided by the load factor, no - * rehash operations will ever occur. + *

    As a general rule, the default load factor (.75) offers a good + * tradeoff between time and space costs. Higher values decrease the + * space overhead but increase the lookup cost (reflected in most of + * the operations of the HashMap class, including + * get and put). The expected number of entries in + * the map and its load factor should be taken into account when + * setting its initial capacity, so as to minimize the number of + * rehash operations. If the initial capacity is greater than the + * maximum number of entries divided by the load factor, no rehash + * operations will ever occur. * - *

    If many mappings are to be stored in a HashMap instance, - * creating it with a sufficiently large capacity will allow the mappings to - * be stored more efficiently than letting it perform automatic rehashing as - * needed to grow the table. + *

    If many mappings are to be stored in a HashMap + * instance, creating it with a sufficiently large capacity will allow + * the mappings to be stored more efficiently than letting it perform + * automatic rehashing as needed to grow the table. Note that using + * many keys with the same {@code hashCode()} is a sure way to slow + * down performance of any hash table. To ameliorate impact, when keys + * are {@link Comparable}, this class may use comparison order among + * keys to help break ties. * *

    Note that this implementation is not synchronized. * If multiple threads access a hash map concurrently, and at least one of @@ -128,11 +134,100 @@ import java.util.function.Function; * @see Hashtable * @since 1.2 */ +public class HashMap extends AbstractMap + implements Map, Cloneable, Serializable { -public class HashMap - extends AbstractMap - implements Map, Cloneable, Serializable -{ + private static final long serialVersionUID = 362498820763181265L; + + /* + * Implementation notes. + * + * This map usually acts as a binned (bucketed) hash table, but + * when bins get too large, they are transformed into bins of + * TreeNodes, each structured similarly to those in + * java.util.TreeMap. Most methods try to use normal bins, but + * relay to TreeNode methods when applicable (simply by checking + * instanceof a node). Bins of TreeNodes may be traversed and + * used like any others, but additionally support faster lookup + * when overpopulated. However, since the vast majority of bins in + * normal use are not overpopulated, checking for existence of + * tree bins may be delayed in the course of table methods. + * + * Tree bins (i.e., bins whose elements are all TreeNodes) are + * ordered primarily by hashCode, but in the case of ties, if two + * elements are of the same "class C implements Comparable", + * type then their compareTo method is used for ordering. (We + * conservatively check generic types via reflection to validate + * this -- see method comparableClassFor). The added complexity + * of tree bins is worthwhile in providing worst-case O(log n) + * operations when keys either have distinct hashes or are + * orderable, Thus, performance degrades gracefully under + * accidental or malicious usages in which hashCode() methods + * return values that are poorly distributed, as well as those in + * which many keys share a hashCode, so long as they are also + * Comparable. (If neither of these apply, we may waste about a + * factor of two in time and space compared to taking no + * precautions. But the only known cases stem from poor user + * programming practices that are already so slow that this makes + * little difference.) + * + * Because TreeNodes are about twice the size of regular nodes, we + * use them only when bins contain enough nodes to warrant use + * (see TREEIFY_THRESHOLD). And when they become too small (due to + * removal or resizing) they are converted back to plain bins. In + * usages with well-distributed user hashCodes, tree bins are + * rarely used. Ideally, under random hashCodes, the frequency of + * nodes in bins follows a Poisson distribution + * (http://en.wikipedia.org/wiki/Poisson_distribution) with a + * parameter of about 0.5 on average for the default resizing + * threshold of 0.75, although with a large variance because of + * resizing granularity. Ignoring variance, the expected + * occurrences of list size k are (exp(-0.5) * pow(0.5, k) / + * factorial(k)). The first values are: + * + * 0: 0.60653066 + * 1: 0.30326533 + * 2: 0.07581633 + * 3: 0.01263606 + * 4: 0.00157952 + * 5: 0.00015795 + * 6: 0.00001316 + * 7: 0.00000094 + * 8: 0.00000006 + * more: less than 1 in ten million + * + * The root of a tree bin is normally its first node. However, + * sometimes (currently only upon Iterator.remove), the root might + * be elsewhere, but can be recovered following parent links + * (method TreeNode.root()). + * + * All applicable internal methods accept a hash code as an + * argument (as normally supplied from a public method), allowing + * them to call each other without recomputing user hashCodes. + * Most internal methods also accept a "tab" argument, that is + * normally the current table, but may be a new or old one when + * resizing or converting. + * + * When bin lists are treeified, split, or untreeified, we keep + * them in the same relative access/traversal order (i.e., field + * Node.next) to better preserve locality, and to slightly + * simplify handling of splits and traversals that invoke + * iterator.remove. When using comparators on insertion, to keep a + * total ordering (or as close as is required here) across + * rebalancings, we compare classes and identityHashCodes as + * tie-breakers. + * + * The use and transitions among plain vs tree modes is + * complicated by the existence of subclass LinkedHashMap. See + * below for hook methods defined to be invoked upon insertion, + * removal and access that allow LinkedHashMap internals to + * otherwise remain independent of these mechanics. (This also + * requires that a map instance be passed to some utility methods + * that may create new nodes.) + * + * The concurrent-programming-like SSA-based coding style helps + * avoid aliasing errors amid all of the twisty pointer operations. + */ /** * The default initial capacity - MUST be a power of two. @@ -152,35 +247,164 @@ public class HashMap static final float DEFAULT_LOAD_FACTOR = 0.75f; /** - * An empty table instance to share when the table is not inflated. + * The bin count threshold for using a tree rather than list for a + * bin. Bins are converted to trees when adding an element to a + * bin with at least this many nodes. The value must be greater + * than 2 and should be at least 8 to mesh with assumptions in + * tree removal about conversion back to plain bins upon + * shrinkage. */ - static final Object[] EMPTY_TABLE = {}; + static final int TREEIFY_THRESHOLD = 8; /** - * The table, resized as necessary. Length MUST Always be a power of two. + * The bin count threshold for untreeifying a (split) bin during a + * resize operation. Should be less than TREEIFY_THRESHOLD, and at + * most 6 to mesh with shrinkage detection under removal. */ - transient Object[] table = EMPTY_TABLE; + static final int UNTREEIFY_THRESHOLD = 6; + + /** + * The smallest table capacity for which bins may be treeified. + * (Otherwise the table is resized if too many nodes in a bin.) + * Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts + * between resizing and treeification thresholds. + */ + static final int MIN_TREEIFY_CAPACITY = 64; + + /** + * Basic hash bin node, used for most entries. (See below for + * TreeNode subclass, and in LinkedHashMap for its Entry subclass.) + */ + static class Node implements Map.Entry { + final int hash; + final K key; + V value; + Node next; + + Node(int hash, K key, V value, Node next) { + this.hash = hash; + this.key = key; + this.value = value; + this.next = next; + } + + public final K getKey() { return key; } + public final V getValue() { return value; } + public final String toString() { return key + "=" + value; } + + public final int hashCode() { + return Objects.hashCode(key) ^ Objects.hashCode(value); + } + + public final V setValue(V newValue) { + V oldValue = value; + value = newValue; + return oldValue; + } + + public final boolean equals(Object o) { + if (o == this) + return true; + if (o instanceof Map.Entry) { + Map.Entry e = (Map.Entry)o; + if (Objects.equals(key, e.getKey()) && + Objects.equals(value, e.getValue())) + return true; + } + return false; + } + } + + /* ---------------- Static utilities -------------- */ + + /** + * Computes key.hashCode() and spreads (XORs) higher bits of hash + * to lower. Because the table uses power-of-two masking, sets of + * hashes that vary only in bits above the current mask will + * always collide. (Among known examples are sets of Float keys + * holding consecutive whole numbers in small tables.) So we + * apply a transform that spreads the impact of higher bits + * downward. There is a tradeoff between speed, utility, and + * quality of bit-spreading. Because many common sets of hashes + * are already reasonably distributed (so don't benefit from + * spreading), and because we use trees to handle large sets of + * collisions in bins, we just XOR some shifted bits in the + * cheapest possible way to reduce systematic lossage, as well as + * to incorporate impact of the highest bits that would otherwise + * never be used in index calculations because of table bounds. + */ + static final int hash(Object key) { + int h; + return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); + } + + /** + * Returns x's Class if it is of the form "class C implements + * Comparable", else null. + */ + static Class comparableClassFor(Object x) { + if (x instanceof Comparable) { + Class c; Type[] ts, as; Type t; ParameterizedType p; + if ((c = x.getClass()) == String.class) // bypass checks + return c; + if ((ts = c.getGenericInterfaces()) != null) { + for (int i = 0; i < ts.length; ++i) { + if (((t = ts[i]) instanceof ParameterizedType) && + ((p = (ParameterizedType)t).getRawType() == + Comparable.class) && + (as = p.getActualTypeArguments()) != null && + as.length == 1 && as[0] == c) // type arg is c + return c; + } + } + } + return null; + } + + /** + * Returns k.compareTo(x) if x matches kc (k's screened comparable + * class), else 0. + */ + @SuppressWarnings({"rawtypes","unchecked"}) // for cast to Comparable + static int compareComparables(Class kc, Object k, Object x) { + return (x == null || x.getClass() != kc ? 0 : + ((Comparable)k).compareTo(x)); + } + + /** + * Returns a power of two size for the given target capacity. + */ + static final int tableSizeFor(int cap) { + int n = cap - 1; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; + } + + /* ---------------- Fields -------------- */ + + /** + * The table, initialized on first use, and resized as + * necessary. When allocated, length is always a power of two. + * (We also tolerate length zero in some operations to allow + * bootstrapping mechanics that are currently not needed.) + */ + transient Node[] table; + + /** + * Holds cached entrySet(). Note that AbstractMap fields are used + * for keySet() and values(). + */ + transient Set> entrySet; /** * The number of key-value mappings contained in this map. */ transient int size; - /** - * The next size value at which to resize (capacity * load factor). - * @serial - */ - // If table == EMPTY_TABLE then this is the initial capacity at which the - // table will be created when inflated. - int threshold; - - /** - * The load factor for the hash table. - * - * @serial - */ - final float loadFactor; - /** * The number of times this HashMap has been structurally modified * Structural modifications are those that change the number of mappings in @@ -191,627 +415,24 @@ public class HashMap transient int modCount; /** - * Holds values which can't be initialized until after VM is booted. - */ - private static class Holder { - static final sun.misc.Unsafe UNSAFE; - - /** - * Offset of "final" hashSeed field we must set in - * readObject() method. - */ - static final long HASHSEED_OFFSET; - - static final boolean USE_HASHSEED; - - static { - String hashSeedProp = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "jdk.map.useRandomSeed")); - boolean localBool = (null != hashSeedProp) - ? Boolean.parseBoolean(hashSeedProp) : false; - USE_HASHSEED = localBool; - - if (USE_HASHSEED) { - try { - UNSAFE = sun.misc.Unsafe.getUnsafe(); - HASHSEED_OFFSET = UNSAFE.objectFieldOffset( - HashMap.class.getDeclaredField("hashSeed")); - } catch (NoSuchFieldException | SecurityException e) { - throw new InternalError("Failed to record hashSeed offset", e); - } - } else { - UNSAFE = null; - HASHSEED_OFFSET = 0; - } - } - } - - /* - * A randomizing value associated with this instance that is applied to - * hash code of keys to make hash collisions harder to find. + * The next size value at which to resize (capacity * load factor). * - * Non-final so it can be set lazily, but be sure not to set more than once. + * @serial */ - transient final int hashSeed; - - /* - * TreeBin/TreeNode code from CHM doesn't handle the null key. Store the - * null key entry here. - */ - transient Entry nullKeyEntry = null; - - /* - * In order to improve performance under high hash-collision conditions, - * HashMap will switch to storing a bin's entries in a balanced tree - * (TreeBin) instead of a linked-list once the number of entries in the bin - * passes a certain threshold (TreeBin.TREE_THRESHOLD), if at least one of - * the keys in the bin implements Comparable. This technique is borrowed - * from ConcurrentHashMap. - */ - - /* - * Code based on CHMv8 - * - * Node type for TreeBin - */ - final static class TreeNode { - TreeNode parent; // red-black tree links - TreeNode left; - TreeNode right; - TreeNode prev; // needed to unlink next upon deletion - boolean red; - final HashMap.Entry entry; - - TreeNode(HashMap.Entry entry, Object next, TreeNode parent) { - this.entry = entry; - this.entry.next = next; - this.parent = parent; - } - } + // (The javadoc description is true upon serialization. + // Additionally, if the table array has not been allocated, this + // field holds the initial array capacity, or zero signifying + // DEFAULT_INITIAL_CAPACITY.) + int threshold; /** - * Returns a Class for the given object of the form "class C - * implements Comparable", if one exists, else null. See the TreeBin - * docs, below, for explanation. - */ - static Class comparableClassFor(Object x) { - Class c, s, cmpc; Type[] ts, as; Type t; ParameterizedType p; - if ((c = x.getClass()) == String.class) // bypass checks - return c; - if ((cmpc = Comparable.class).isAssignableFrom(c)) { - while (cmpc.isAssignableFrom(s = c.getSuperclass())) - c = s; // find topmost comparable class - if ((ts = c.getGenericInterfaces()) != null) { - for (int i = 0; i < ts.length; ++i) { - if (((t = ts[i]) instanceof ParameterizedType) && - ((p = (ParameterizedType)t).getRawType() == cmpc) && - (as = p.getActualTypeArguments()) != null && - as.length == 1 && as[0] == c) // type arg is c - return c; - } - } - } - return null; - } - - /* - * Code based on CHMv8 + * The load factor for the hash table. * - * A specialized form of red-black tree for use in bins - * whose size exceeds a threshold. - * - * TreeBins use a special form of comparison for search and - * related operations (which is the main reason we cannot use - * existing collections such as TreeMaps). TreeBins contain - * Comparable elements, but may contain others, as well as - * elements that are Comparable but not necessarily Comparable - * for the same T, so we cannot invoke compareTo among them. To - * handle this, the tree is ordered primarily by hash value, then - * by Comparable.compareTo order if applicable. On lookup at a - * node, if elements are not comparable or compare as 0 then both - * left and right children may need to be searched in the case of - * tied hash values. (This corresponds to the full list search - * that would be necessary if all elements were non-Comparable and - * had tied hashes.) The red-black balancing code is updated from - * pre-jdk-collections - * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) - * based in turn on Cormen, Leiserson, and Rivest "Introduction to - * Algorithms" (CLR). + * @serial */ - final class TreeBin { - /* - * The bin count threshold for using a tree rather than list for a bin. The - * value reflects the approximate break-even point for using tree-based - * operations. - */ - static final int TREE_THRESHOLD = 16; + final float loadFactor; - TreeNode root; // root of tree - TreeNode first; // head of next-pointer list - - /* - * Split a TreeBin into lo and hi parts and install in given table. - * - * Existing Entrys are re-used, which maintains the before/after links for - * LinkedHashMap.Entry. - * - * No check for Comparable, though this is the same as CHM. - */ - final void splitTreeBin(Object[] newTable, int i, TreeBin loTree, TreeBin hiTree) { - TreeBin oldTree = this; - int bit = newTable.length >>> 1; - int loCount = 0, hiCount = 0; - TreeNode e = oldTree.first; - TreeNode next; - - // This method is called when the table has just increased capacity, - // so indexFor() is now taking one additional bit of hash into - // account ("bit"). Entries in this TreeBin now belong in one of - // two bins, "i" or "i+bit", depending on if the new top bit of the - // hash is set. The trees for the two bins are loTree and hiTree. - // If either tree ends up containing fewer than TREE_THRESHOLD - // entries, it is converted back to a linked list. - while (e != null) { - // Save entry.next - it will get overwritten in putTreeNode() - next = (TreeNode)e.entry.next; - - int h = e.entry.hash; - K k = (K) e.entry.key; - V v = e.entry.value; - if ((h & bit) == 0) { - ++loCount; - // Re-using e.entry - loTree.putTreeNode(h, k, v, e.entry); - } else { - ++hiCount; - hiTree.putTreeNode(h, k, v, e.entry); - } - // Iterate using the saved 'next' - e = next; - } - if (loCount < TREE_THRESHOLD) { // too small, convert back to list - HashMap.Entry loEntry = null; - TreeNode p = loTree.first; - while (p != null) { - @SuppressWarnings("unchecked") - TreeNode savedNext = (TreeNode) p.entry.next; - p.entry.next = loEntry; - loEntry = p.entry; - p = savedNext; - } - // assert newTable[i] == null; - newTable[i] = loEntry; - } else { - // assert newTable[i] == null; - newTable[i] = loTree; - } - if (hiCount < TREE_THRESHOLD) { // too small, convert back to list - HashMap.Entry hiEntry = null; - TreeNode p = hiTree.first; - while (p != null) { - @SuppressWarnings("unchecked") - TreeNode savedNext = (TreeNode) p.entry.next; - p.entry.next = hiEntry; - hiEntry = p.entry; - p = savedNext; - } - // assert newTable[i + bit] == null; - newTable[i + bit] = hiEntry; - } else { - // assert newTable[i + bit] == null; - newTable[i + bit] = hiTree; - } - } - - /* - * Popuplate the TreeBin with entries from the linked list e - * - * Assumes 'this' is a new/empty TreeBin - * - * Note: no check for Comparable - * Note: I believe this changes iteration order - */ - @SuppressWarnings("unchecked") - void populate(HashMap.Entry e) { - // assert root == null; - // assert first == null; - HashMap.Entry next; - while (e != null) { - // Save entry.next - it will get overwritten in putTreeNode() - next = (HashMap.Entry)e.next; - // Re-using Entry e will maintain before/after in LinkedHM - putTreeNode(e.hash, (K)e.key, (V)e.value, e); - // Iterate using the saved 'next' - e = next; - } - } - - /** - * Copied from CHMv8 - * From CLR - */ - private void rotateLeft(TreeNode p) { - if (p != null) { - TreeNode r = p.right, pp, rl; - if ((rl = p.right = r.left) != null) { - rl.parent = p; - } - if ((pp = r.parent = p.parent) == null) { - root = r; - } else if (pp.left == p) { - pp.left = r; - } else { - pp.right = r; - } - r.left = p; - p.parent = r; - } - } - - /** - * Copied from CHMv8 - * From CLR - */ - private void rotateRight(TreeNode p) { - if (p != null) { - TreeNode l = p.left, pp, lr; - if ((lr = p.left = l.right) != null) { - lr.parent = p; - } - if ((pp = l.parent = p.parent) == null) { - root = l; - } else if (pp.right == p) { - pp.right = l; - } else { - pp.left = l; - } - l.right = p; - p.parent = l; - } - } - - /** - * Returns the TreeNode (or null if not found) for the given - * key. A front-end for recursive version. - */ - final TreeNode getTreeNode(int h, K k) { - return getTreeNode(h, k, root, comparableClassFor(k)); - } - - /** - * Returns the TreeNode (or null if not found) for the given key - * starting at given root. - */ - @SuppressWarnings("unchecked") - final TreeNode getTreeNode (int h, K k, TreeNode p, Class cc) { - // assert k != null; - while (p != null) { - int dir, ph; Object pk; - if ((ph = p.entry.hash) != h) - dir = (h < ph) ? -1 : 1; - else if ((pk = p.entry.key) == k || k.equals(pk)) - return p; - else if (cc == null || comparableClassFor(pk) != cc || - (dir = ((Comparable)k).compareTo(pk)) == 0) { - // assert pk != null; - TreeNode r, pl, pr; // check both sides - if ((pr = p.right) != null && - (r = getTreeNode(h, k, pr, cc)) != null) - return r; - else if ((pl = p.left) != null) - dir = -1; - else // nothing there - break; - } - p = (dir > 0) ? p.right : p.left; - } - return null; - } - - /* - * Finds or adds a node. - * - * 'entry' should be used to recycle an existing Entry (e.g. in the case - * of converting a linked-list bin to a TreeBin). - * If entry is null, a new Entry will be created for the new TreeNode - * - * @return the TreeNode containing the mapping, or null if a new - * TreeNode was added - */ - @SuppressWarnings("unchecked") - TreeNode putTreeNode(int h, K k, V v, HashMap.Entry entry) { - // assert k != null; - //if (entry != null) { - // assert h == entry.hash; - // assert k == entry.key; - // assert v == entry.value; - // } - Class cc = comparableClassFor(k); - TreeNode pp = root, p = null; - int dir = 0; - while (pp != null) { // find existing node or leaf to insert at - int ph; Object pk; - p = pp; - if ((ph = p.entry.hash) != h) - dir = (h < ph) ? -1 : 1; - else if ((pk = p.entry.key) == k || k.equals(pk)) - return p; - else if (cc == null || comparableClassFor(pk) != cc || - (dir = ((Comparable)k).compareTo(pk)) == 0) { - TreeNode r, pr; - if ((pr = p.right) != null && - (r = getTreeNode(h, k, pr, cc)) != null) - return r; - else // continue left - dir = -1; - } - pp = (dir > 0) ? p.right : p.left; - } - - // Didn't find the mapping in the tree, so add it - TreeNode f = first; - TreeNode x; - if (entry != null) { - x = new TreeNode(entry, f, p); - } else { - x = new TreeNode(newEntry(h, k, v, null), f, p); - } - first = x; - - if (p == null) { - root = x; - } else { // attach and rebalance; adapted from CLR - TreeNode xp, xpp; - if (f != null) { - f.prev = x; - } - if (dir <= 0) { - p.left = x; - } else { - p.right = x; - } - x.red = true; - while (x != null && (xp = x.parent) != null && xp.red - && (xpp = xp.parent) != null) { - TreeNode xppl = xpp.left; - if (xp == xppl) { - TreeNode y = xpp.right; - if (y != null && y.red) { - y.red = false; - xp.red = false; - xpp.red = true; - x = xpp; - } else { - if (x == xp.right) { - rotateLeft(x = xp); - xpp = (xp = x.parent) == null ? null : xp.parent; - } - if (xp != null) { - xp.red = false; - if (xpp != null) { - xpp.red = true; - rotateRight(xpp); - } - } - } - } else { - TreeNode y = xppl; - if (y != null && y.red) { - y.red = false; - xp.red = false; - xpp.red = true; - x = xpp; - } else { - if (x == xp.left) { - rotateRight(x = xp); - xpp = (xp = x.parent) == null ? null : xp.parent; - } - if (xp != null) { - xp.red = false; - if (xpp != null) { - xpp.red = true; - rotateLeft(xpp); - } - } - } - } - } - TreeNode r = root; - if (r != null && r.red) { - r.red = false; - } - } - return null; - } - - /* - * From CHMv8 - * - * Removes the given node, that must be present before this - * call. This is messier than typical red-black deletion code - * because we cannot swap the contents of an interior node - * with a leaf successor that is pinned by "next" pointers - * that are accessible independently of lock. So instead we - * swap the tree linkages. - */ - final void deleteTreeNode(TreeNode p) { - TreeNode next = (TreeNode) p.entry.next; // unlink traversal pointers - TreeNode pred = p.prev; - if (pred == null) { - first = next; - } else { - pred.entry.next = next; - } - if (next != null) { - next.prev = pred; - } - TreeNode replacement; - TreeNode pl = p.left; - TreeNode pr = p.right; - if (pl != null && pr != null) { - TreeNode s = pr, sl; - while ((sl = s.left) != null) // find successor - { - s = sl; - } - boolean c = s.red; - s.red = p.red; - p.red = c; // swap colors - TreeNode sr = s.right; - TreeNode pp = p.parent; - if (s == pr) { // p was s's direct parent - p.parent = s; - s.right = p; - } else { - TreeNode sp = s.parent; - if ((p.parent = sp) != null) { - if (s == sp.left) { - sp.left = p; - } else { - sp.right = p; - } - } - if ((s.right = pr) != null) { - pr.parent = s; - } - } - p.left = null; - if ((p.right = sr) != null) { - sr.parent = p; - } - if ((s.left = pl) != null) { - pl.parent = s; - } - if ((s.parent = pp) == null) { - root = s; - } else if (p == pp.left) { - pp.left = s; - } else { - pp.right = s; - } - replacement = sr; - } else { - replacement = (pl != null) ? pl : pr; - } - TreeNode pp = p.parent; - if (replacement == null) { - if (pp == null) { - root = null; - return; - } - replacement = p; - } else { - replacement.parent = pp; - if (pp == null) { - root = replacement; - } else if (p == pp.left) { - pp.left = replacement; - } else { - pp.right = replacement; - } - p.left = p.right = p.parent = null; - } - if (!p.red) { // rebalance, from CLR - TreeNode x = replacement; - while (x != null) { - TreeNode xp, xpl; - if (x.red || (xp = x.parent) == null) { - x.red = false; - break; - } - if (x == (xpl = xp.left)) { - TreeNode sib = xp.right; - if (sib != null && sib.red) { - sib.red = false; - xp.red = true; - rotateLeft(xp); - sib = (xp = x.parent) == null ? null : xp.right; - } - if (sib == null) { - x = xp; - } else { - TreeNode sl = sib.left, sr = sib.right; - if ((sr == null || !sr.red) - && (sl == null || !sl.red)) { - sib.red = true; - x = xp; - } else { - if (sr == null || !sr.red) { - if (sl != null) { - sl.red = false; - } - sib.red = true; - rotateRight(sib); - sib = (xp = x.parent) == null ? - null : xp.right; - } - if (sib != null) { - sib.red = (xp == null) ? false : xp.red; - if ((sr = sib.right) != null) { - sr.red = false; - } - } - if (xp != null) { - xp.red = false; - rotateLeft(xp); - } - x = root; - } - } - } else { // symmetric - TreeNode sib = xpl; - if (sib != null && sib.red) { - sib.red = false; - xp.red = true; - rotateRight(xp); - sib = (xp = x.parent) == null ? null : xp.left; - } - if (sib == null) { - x = xp; - } else { - TreeNode sl = sib.left, sr = sib.right; - if ((sl == null || !sl.red) - && (sr == null || !sr.red)) { - sib.red = true; - x = xp; - } else { - if (sl == null || !sl.red) { - if (sr != null) { - sr.red = false; - } - sib.red = true; - rotateLeft(sib); - sib = (xp = x.parent) == null ? - null : xp.left; - } - if (sib != null) { - sib.red = (xp == null) ? false : xp.red; - if ((sl = sib.left) != null) { - sl.red = false; - } - } - if (xp != null) { - xp.red = false; - rotateRight(xp); - } - x = root; - } - } - } - } - } - if (p == replacement && (pp = p.parent) != null) { - if (p == pp.left) // detach pointers - { - pp.left = null; - } else if (p == pp.right) { - pp.right = null; - } - p.parent = null; - } - } - } + /* ---------------- Public operations -------------- */ /** * Constructs an empty HashMap with the specified initial @@ -832,9 +453,7 @@ public class HashMap throw new IllegalArgumentException("Illegal load factor: " + loadFactor); this.loadFactor = loadFactor; - threshold = initialCapacity; - hashSeed = initHashSeed(); - init(); + this.threshold = tableSizeFor(initialCapacity); } /** @@ -853,7 +472,7 @@ public class HashMap * (16) and the default load factor (0.75). */ public HashMap() { - this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); + this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted } /** @@ -866,79 +485,35 @@ public class HashMap * @throws NullPointerException if the specified map is null */ public HashMap(Map m) { - this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, - DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR); - inflateTable(threshold); - - putAllForCreate(m); - // assert size == m.size(); - } - - private static int roundUpToPowerOf2(int number) { - // assert number >= 0 : "number must be non-negative"; - return number >= MAXIMUM_CAPACITY - ? MAXIMUM_CAPACITY - : (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1; + this.loadFactor = DEFAULT_LOAD_FACTOR; + putMapEntries(m, false); } /** - * Inflates the table. + * Implements Map.putAll and Map constructor + * + * @param m the map + * @param evict false when initially constructing this map, else + * true (relayed to method afterNodeInsertion). */ - private void inflateTable(int toSize) { - // Find a power of 2 >= toSize - int capacity = roundUpToPowerOf2(toSize); - - threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1); - table = new Object[capacity]; - } - - // internal utilities - - /** - * Initialization hook for subclasses. This method is called - * in all constructors and pseudo-constructors (clone, readObject) - * after HashMap has been initialized but before any entries have - * been inserted. (In the absence of this method, readObject would - * require explicit knowledge of subclasses.) - */ - void init() { - } - - /** - * Return an initial value for the hashSeed, or 0 if the random seed is not - * enabled. - */ - final int initHashSeed() { - if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) { - int seed = ThreadLocalRandom.current().nextInt(); - return (seed != 0) ? seed : 1; + final void putMapEntries(Map m, boolean evict) { + int s = m.size(); + if (s > 0) { + if (table == null) { // pre-size + float ft = ((float)s / loadFactor) + 1.0F; + int t = ((ft < (float)MAXIMUM_CAPACITY) ? + (int)ft : MAXIMUM_CAPACITY); + if (t > threshold) + threshold = tableSizeFor(t); + } + else if (s > threshold) + resize(); + for (Map.Entry e : m.entrySet()) { + K key = e.getKey(); + V value = e.getValue(); + putVal(hash(key), key, value, false, evict); + } } - return 0; - } - - /** - * Retrieve object hash code and applies a supplemental hash function to the - * result hash, which defends against poor quality hash functions. This is - * critical because HashMap uses power-of-two length hash tables, that - * otherwise encounter collisions for hashCodes that do not differ - * in lower bits. - */ - final int hash(Object k) { - int h = hashSeed ^ k.hashCode(); - - // This function ensures that hashCodes that differ only by - // constant multiples at each bit position have a bounded - // number of collisions (approximately 8 at default load factor). - h ^= (h >>> 20) ^ (h >>> 12); - return h ^ (h >>> 7) ^ (h >>> 4); - } - - /** - * Returns index for hash code h. - */ - static int indexFor(int h, int length) { - // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2"; - return h & (length-1); } /** @@ -976,18 +551,36 @@ public class HashMap * * @see #put(Object, Object) */ - @SuppressWarnings("unchecked") public V get(Object key) { - Entry entry = getEntry(key); - - return null == entry ? null : entry.getValue(); + Node e; + return (e = getNode(hash(key), key)) == null ? null : e.value; } - @Override - public V getOrDefault(Object key, V defaultValue) { - Entry entry = getEntry(key); - - return (entry == null) ? defaultValue : entry.getValue(); + /** + * Implements Map.get and related methods + * + * @param hash hash for key + * @param key the key + * @return the node, or null if none + */ + final Node getNode(int hash, Object key) { + Node[] tab; Node first, e; int n; K k; + if ((tab = table) != null && (n = tab.length) > 0 && + (first = tab[(n - 1) & hash]) != null) { + if (first.hash == hash && // always check first node + ((k = first.key) == key || (key != null && key.equals(k)))) + return first; + if ((e = first.next) != null) { + if (first instanceof TreeNode) + return ((TreeNode)first).getTreeNode(hash, key); + do { + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) + return e; + } while ((e = e.next) != null); + } + } + return null; } /** @@ -999,48 +592,9 @@ public class HashMap * key. */ public boolean containsKey(Object key) { - return getEntry(key) != null; + return getNode(hash(key), key) != null; } - /** - * Returns the entry associated with the specified key in the - * HashMap. Returns null if the HashMap contains no mapping - * for the key. - */ - @SuppressWarnings("unchecked") - final Entry getEntry(Object key) { - if (size == 0) { - return null; - } - if (key == null) { - return nullKeyEntry; - } - int hash = hash(key); - int bin = indexFor(hash, table.length); - - if (table[bin] instanceof Entry) { - Entry e = (Entry) table[bin]; - for (; e != null; e = (Entry)e.next) { - Object k; - if (e.hash == hash && - ((k = e.key) == key || key.equals(k))) { - return e; - } - } - } else if (table[bin] != null) { - TreeBin e = (TreeBin)table[bin]; - TreeNode p = e.getTreeNode(hash, (K)key); - if (p != null) { - // assert p.entry.hash == hash && p.entry.key.equals(key); - return (Entry)p.entry; - } else { - return null; - } - } - return null; - } - - /** * Associates the specified value with the specified key in this map. * If the map previously contained a mapping for the key, the old @@ -1053,202 +607,169 @@ public class HashMap * (A null return can also indicate that the map * previously associated null with key.) */ - @SuppressWarnings("unchecked") public V put(K key, V value) { - if (table == EMPTY_TABLE) { - inflateTable(threshold); - } - if (key == null) - return putForNullKey(value); - int hash = hash(key); - int i = indexFor(hash, table.length); - boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? + return putVal(hash(key), key, value, false, true); + } - if (table[i] instanceof Entry) { - // Bin contains ordinary Entries. Search for key in the linked list - // of entries, counting the number of entries. Only check for - // TreeBin conversion if the list size is >= TREE_THRESHOLD. - // (The conversion still may not happen if the table gets resized.) - int listSize = 0; - Entry e = (Entry) table[i]; - for (; e != null; e = (Entry)e.next) { - Object k; - if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { - V oldValue = e.value; - e.value = value; - e.recordAccess(this); - return oldValue; + /** + * Implements Map.put and related methods + * + * @param hash hash for key + * @param key the key + * @param value the value to put + * @param onlyIfAbsent if true, don't change existing value + * @param evict if false, the table is in creation mode. + * @return previous value, or null if none + */ + final V putVal(int hash, K key, V value, boolean onlyIfAbsent, + boolean evict) { + Node[] tab; Node p; int n, i; + if (size > threshold || (tab = table) == null || + (n = tab.length) == 0) + n = (tab = resize()).length; + if ((p = tab[i = (n - 1) & hash]) == null) + tab[i] = newNode(hash, key, value, null); + else { + Node e; K k; + if (p.hash == hash && + ((k = p.key) == key || (key != null && key.equals(k)))) + e = p; + else if (p instanceof TreeNode) + e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value); + else { + for (int binCount = 0; ; ++binCount) { + if ((e = p.next) == null) { + p.next = newNode(hash, key, value, null); + if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st + treeifyBin(tab, hash); + break; + } + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) + break; + p = e; } - listSize++; } - // Didn't find, so fall through and call addEntry() to add the - // Entry and check for TreeBin conversion. - checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; - } else if (table[i] != null) { - TreeBin e = (TreeBin)table[i]; - TreeNode p = e.putTreeNode(hash, key, value, null); - if (p == null) { // putTreeNode() added a new node - modCount++; - size++; - if (size >= threshold) { - resize(2 * table.length); - } - return null; - } else { // putTreeNode() found an existing node - Entry pEntry = (Entry)p.entry; - V oldVal = pEntry.value; - pEntry.value = value; - pEntry.recordAccess(this); - return oldVal; + if (e != null) { // existing mapping for key + V oldValue = e.value; + if (!onlyIfAbsent || oldValue == null) + e.value = value; + afterNodeAccess(e); + return oldValue; } } - modCount++; - addEntry(hash, key, value, i, checkIfNeedTree); + ++modCount; + ++size; + afterNodeInsertion(evict); return null; } /** - * Offloaded version of put for null keys + * Initializes or doubles table size. If null, allocates in + * accord with initial capacity target held in field threshold. + * Otherwise, because we are using power-of-two expansion, the + * elements from each bin must either stay at same index, or move + * with a power of two offset in the new table. + * + * @return the table */ - private V putForNullKey(V value) { - if (nullKeyEntry != null) { - V oldValue = nullKeyEntry.value; - nullKeyEntry.value = value; - nullKeyEntry.recordAccess(this); - return oldValue; + final Node[] resize() { + Node[] oldTab = table; + int oldCap = (oldTab == null) ? 0 : oldTab.length; + int oldThr = threshold; + int newCap, newThr = 0; + if (oldCap > 0) { + if (oldCap >= MAXIMUM_CAPACITY) { + threshold = Integer.MAX_VALUE; + return oldTab; + } + else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && + oldCap >= DEFAULT_INITIAL_CAPACITY) + newThr = oldThr << 1; // double threshold } - modCount++; - size++; // newEntry() skips size++ - nullKeyEntry = newEntry(0, null, value, null); - return null; - } - - private void putForCreateNullKey(V value) { - // Look for preexisting entry for key. This will never happen for - // clone or deserialize. It will only happen for construction if the - // input Map is a sorted map whose ordering is inconsistent w/ equals. - if (nullKeyEntry != null) { - nullKeyEntry.value = value; - } else { - nullKeyEntry = newEntry(0, null, value, null); - size++; + else if (oldThr > 0) // initial capacity was placed in threshold + newCap = oldThr; + else { // zero initial threshold signifies using defaults + newCap = DEFAULT_INITIAL_CAPACITY; + newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY); } - } - - - /** - * This method is used instead of put by constructors and - * pseudoconstructors (clone, readObject). It does not resize the table, - * check for comodification, etc, though it will convert bins to TreeBins - * as needed. It calls createEntry rather than addEntry. - */ - @SuppressWarnings("unchecked") - private void putForCreate(K key, V value) { - if (null == key) { - putForCreateNullKey(value); - return; + if (newThr == 0) { + float ft = (float)newCap * loadFactor; + newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ? + (int)ft : Integer.MAX_VALUE); } - int hash = hash(key); - int i = indexFor(hash, table.length); - boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? - - /** - * Look for preexisting entry for key. This will never happen for - * clone or deserialize. It will only happen for construction if the - * input Map is a sorted map whose ordering is inconsistent w/ equals. - */ - if (table[i] instanceof Entry) { - int listSize = 0; - Entry e = (Entry) table[i]; - for (; e != null; e = (Entry)e.next) { - Object k; - if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { - e.value = value; - return; + threshold = newThr; + @SuppressWarnings({"rawtypes","unchecked"}) + Node[] newTab = (Node[])new Node[newCap]; + table = newTab; + if (oldTab != null) { + for (int j = 0; j < oldCap; ++j) { + Node e; + if ((e = oldTab[j]) != null) { + oldTab[j] = null; + if (e.next == null) + newTab[e.hash & (newCap - 1)] = e; + else if (e instanceof TreeNode) + ((TreeNode)e).split(this, newTab, j, oldCap); + else { // preserve order + Node loHead = null, loTail = null; + Node hiHead = null, hiTail = null; + Node next; + do { + next = e.next; + if ((e.hash & oldCap) == 0) { + if (loTail == null) + loHead = e; + else + loTail.next = e; + loTail = e; + } + else { + if (hiTail == null) + hiHead = e; + else + hiTail.next = e; + hiTail = e; + } + } while ((e = next) != null); + if (loTail != null) { + loTail.next = null; + newTab[j] = loHead; + } + if (hiTail != null) { + hiTail.next = null; + newTab[j + oldCap] = hiHead; + } + } } - listSize++; } - // Didn't find, fall through to createEntry(). - // Check for conversion to TreeBin done via createEntry(). - checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; - } else if (table[i] != null) { - TreeBin e = (TreeBin)table[i]; - TreeNode p = e.putTreeNode(hash, key, value, null); - if (p != null) { - p.entry.setValue(value); // Found an existing node, set value - } else { - size++; // Added a new TreeNode, so update size - } - // don't need modCount++/check for resize - just return - return; } - - createEntry(hash, key, value, i, checkIfNeedTree); - } - - private void putAllForCreate(Map m) { - for (Map.Entry e : m.entrySet()) - putForCreate(e.getKey(), e.getValue()); + return newTab; } /** - * Rehashes the contents of this map into a new array with a - * larger capacity. This method is called automatically when the - * number of keys in this map reaches its threshold. - * - * If current capacity is MAXIMUM_CAPACITY, this method does not - * resize the map, but sets threshold to Integer.MAX_VALUE. - * This has the effect of preventing future calls. - * - * @param newCapacity the new capacity, MUST be a power of two; - * must be greater than current capacity unless current - * capacity is MAXIMUM_CAPACITY (in which case value - * is irrelevant). + * Replaces all linked nodes in bin at index for given hash unless + * table is too small, in which case resizes instead. */ - void resize(int newCapacity) { - Object[] oldTable = table; - int oldCapacity = oldTable.length; - if (oldCapacity == MAXIMUM_CAPACITY) { - threshold = Integer.MAX_VALUE; - return; - } - - Object[] newTable = new Object[newCapacity]; - transfer(newTable); - table = newTable; - threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1); - } - - /** - * Transfers all entries from current table to newTable. - * - * Assumes newTable is larger than table - */ - @SuppressWarnings("unchecked") - void transfer(Object[] newTable) { - Object[] src = table; - // assert newTable.length > src.length : "newTable.length(" + - // newTable.length + ") expected to be > src.length("+src.length+")"; - int newCapacity = newTable.length; - for (int j = 0; j < src.length; j++) { - if (src[j] instanceof Entry) { - // Assume: since wasn't TreeBin before, won't need TreeBin now - Entry e = (Entry) src[j]; - while (null != e) { - Entry next = (Entry)e.next; - int i = indexFor(e.hash, newCapacity); - e.next = (Entry) newTable[i]; - newTable[i] = e; - e = next; + final void treeifyBin(Node[] tab, int hash) { + int n, index; Node e; + if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY) + resize(); + else if ((e = tab[index = (n - 1) & hash]) != null) { + TreeNode hd = null, tl = null; + do { + TreeNode p = replacementTreeNode(e, null); + if (tl == null) + hd = p; + else { + p.prev = tl; + tl.next = p; } - } else if (src[j] != null) { - TreeBin e = (TreeBin) src[j]; - TreeBin loTree = new TreeBin(); - TreeBin hiTree = new TreeBin(); - e.splitTreeBin(newTable, j, loTree, hiTree); - } + tl = p; + } while ((e = e.next) != null); + if ((tab[index] = hd) != null) + hd.treeify(tab); } - Arrays.fill(table, null); } /** @@ -1260,30 +781,8 @@ public class HashMap * @throws NullPointerException if the specified map is null */ public void putAll(Map m) { - int numKeysToBeAdded = m.size(); - if (numKeysToBeAdded == 0) - return; - - if (table == EMPTY_TABLE) { - inflateTable((int) Math.max(numKeysToBeAdded * loadFactor, threshold)); - } - - /* - * Expand the map if the map if the number of mappings to be added - * is greater than or equal to threshold. This is conservative; the - * obvious condition is (m.size() + size) >= threshold, but this - * condition could result in a map with twice the appropriate capacity, - * if the keys to be added overlap with the keys already in this map. - * By using the conservative calculation, we subject ourself - * to at most one extra resize. - */ - if (numKeysToBeAdded > threshold && table.length < MAXIMUM_CAPACITY) { - resize(table.length * 2); - } - - for (Map.Entry e : m.entrySet()) - put(e.getKey(), e.getValue()); - } + putMapEntries(m, true); + } /** * Removes the mapping for the specified key from this map if present. @@ -1295,834 +794,74 @@ public class HashMap * previously associated null with key.) */ public V remove(Object key) { - Entry e = removeEntryForKey(key); - return (e == null ? null : e.value); - } - - // optimized implementations of default methods in Map - - @Override - public void forEach(BiConsumer action) { - Objects.requireNonNull(action); - final int expectedModCount = modCount; - if (nullKeyEntry != null) { - forEachNullKey(expectedModCount, action); - } - Object[] tab = this.table; - for (int index = 0; index < tab.length; index++) { - Object item = tab[index]; - if (item == null) { - continue; - } - if (item instanceof HashMap.TreeBin) { - eachTreeNode(expectedModCount, ((TreeBin)item).first, action); - continue; - } - @SuppressWarnings("unchecked") - Entry entry = (Entry)item; - while (entry != null) { - action.accept(entry.key, entry.value); - entry = (Entry)entry.next; - - if (expectedModCount != modCount) { - throw new ConcurrentModificationException(); - } - } - } - } - - private void eachTreeNode(int expectedModCount, TreeNode node, BiConsumer action) { - while (node != null) { - @SuppressWarnings("unchecked") - Entry entry = (Entry)node.entry; - action.accept(entry.key, entry.value); - node = (TreeNode)entry.next; - - if (expectedModCount != modCount) { - throw new ConcurrentModificationException(); - } - } - } - - private void forEachNullKey(int expectedModCount, BiConsumer action) { - action.accept(null, nullKeyEntry.value); - - if (expectedModCount != modCount) { - throw new ConcurrentModificationException(); - } - } - - @Override - public void replaceAll(BiFunction function) { - Objects.requireNonNull(function); - final int expectedModCount = modCount; - if (nullKeyEntry != null) { - replaceforNullKey(expectedModCount, function); - } - Object[] tab = this.table; - for (int index = 0; index < tab.length; index++) { - Object item = tab[index]; - if (item == null) { - continue; - } - if (item instanceof HashMap.TreeBin) { - replaceEachTreeNode(expectedModCount, ((TreeBin)item).first, function); - continue; - } - @SuppressWarnings("unchecked") - Entry entry = (Entry)item; - while (entry != null) { - entry.value = function.apply(entry.key, entry.value); - entry = (Entry)entry.next; - - if (expectedModCount != modCount) { - throw new ConcurrentModificationException(); - } - } - } - } - - private void replaceEachTreeNode(int expectedModCount, TreeNode node, BiFunction function) { - while (node != null) { - @SuppressWarnings("unchecked") - Entry entry = (Entry)node.entry; - entry.value = function.apply(entry.key, entry.value); - node = (TreeNode)entry.next; - - if (expectedModCount != modCount) { - throw new ConcurrentModificationException(); - } - } - } - - private void replaceforNullKey(int expectedModCount, BiFunction function) { - nullKeyEntry.value = function.apply(null, nullKeyEntry.value); - - if (expectedModCount != modCount) { - throw new ConcurrentModificationException(); - } - } - - @Override - public V putIfAbsent(K key, V value) { - if (table == EMPTY_TABLE) { - inflateTable(threshold); - } - if (key == null) { - if (nullKeyEntry == null || nullKeyEntry.value == null) { - putForNullKey(value); - return null; - } else { - return nullKeyEntry.value; - } - } - int hash = hash(key); - int i = indexFor(hash, table.length); - boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? - - if (table[i] instanceof Entry) { - int listSize = 0; - Entry e = (Entry) table[i]; - for (; e != null; e = (Entry)e.next) { - if (e.hash == hash && Objects.equals(e.key, key)) { - if (e.value != null) { - return e.value; - } - e.value = value; - e.recordAccess(this); - return null; - } - listSize++; - } - // Didn't find, so fall through and call addEntry() to add the - // Entry and check for TreeBin conversion. - checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; - } else if (table[i] != null) { - TreeBin e = (TreeBin)table[i]; - TreeNode p = e.putTreeNode(hash, key, value, null); - if (p == null) { // not found, putTreeNode() added a new node - modCount++; - size++; - if (size >= threshold) { - resize(2 * table.length); - } - return null; - } else { // putTreeNode() found an existing node - Entry pEntry = (Entry)p.entry; - V oldVal = pEntry.value; - if (oldVal == null) { // only replace if maps to null - pEntry.value = value; - pEntry.recordAccess(this); - } - return oldVal; - } - } - modCount++; - addEntry(hash, key, value, i, checkIfNeedTree); - return null; - } - - @Override - public boolean remove(Object key, Object value) { - if (size == 0) { - return false; - } - if (key == null) { - if (nullKeyEntry != null && - Objects.equals(nullKeyEntry.value, value)) { - removeNullKey(); - return true; - } - return false; - } - int hash = hash(key); - int i = indexFor(hash, table.length); - - if (table[i] instanceof Entry) { - @SuppressWarnings("unchecked") - Entry prev = (Entry) table[i]; - Entry e = prev; - while (e != null) { - @SuppressWarnings("unchecked") - Entry next = (Entry) e.next; - if (e.hash == hash && Objects.equals(e.key, key)) { - if (!Objects.equals(e.value, value)) { - return false; - } - modCount++; - size--; - if (prev == e) - table[i] = next; - else - prev.next = next; - e.recordRemoval(this); - return true; - } - prev = e; - e = next; - } - } else if (table[i] != null) { - TreeBin tb = ((TreeBin) table[i]); - TreeNode p = tb.getTreeNode(hash, (K)key); - if (p != null) { - Entry pEntry = (Entry)p.entry; - // assert pEntry.key.equals(key); - if (Objects.equals(pEntry.value, value)) { - modCount++; - size--; - tb.deleteTreeNode(p); - pEntry.recordRemoval(this); - if (tb.root == null || tb.first == null) { - // assert tb.root == null && tb.first == null : - // "TreeBin.first and root should both be null"; - // TreeBin is now empty, we should blank this bin - table[i] = null; - } - return true; - } - } - } - return false; - } - - @Override - public boolean replace(K key, V oldValue, V newValue) { - if (size == 0) { - return false; - } - if (key == null) { - if (nullKeyEntry != null && - Objects.equals(nullKeyEntry.value, oldValue)) { - putForNullKey(newValue); - return true; - } - return false; - } - int hash = hash(key); - int i = indexFor(hash, table.length); - - if (table[i] instanceof Entry) { - @SuppressWarnings("unchecked") - Entry e = (Entry) table[i]; - for (; e != null; e = (Entry)e.next) { - if (e.hash == hash && Objects.equals(e.key, key) && Objects.equals(e.value, oldValue)) { - e.value = newValue; - e.recordAccess(this); - return true; - } - } - return false; - } else if (table[i] != null) { - TreeBin tb = ((TreeBin) table[i]); - TreeNode p = tb.getTreeNode(hash, key); - if (p != null) { - Entry pEntry = (Entry)p.entry; - // assert pEntry.key.equals(key); - if (Objects.equals(pEntry.value, oldValue)) { - pEntry.value = newValue; - pEntry.recordAccess(this); - return true; - } - } - } - return false; - } - - @Override - public V replace(K key, V value) { - if (size == 0) { - return null; - } - if (key == null) { - if (nullKeyEntry != null) { - return putForNullKey(value); - } - return null; - } - int hash = hash(key); - int i = indexFor(hash, table.length); - if (table[i] instanceof Entry) { - @SuppressWarnings("unchecked") - Entry e = (Entry)table[i]; - for (; e != null; e = (Entry)e.next) { - if (e.hash == hash && Objects.equals(e.key, key)) { - V oldValue = e.value; - e.value = value; - e.recordAccess(this); - return oldValue; - } - } - - return null; - } else if (table[i] != null) { - TreeBin tb = ((TreeBin) table[i]); - TreeNode p = tb.getTreeNode(hash, key); - if (p != null) { - Entry pEntry = (Entry)p.entry; - // assert pEntry.key.equals(key); - V oldValue = pEntry.value; - pEntry.value = value; - pEntry.recordAccess(this); - return oldValue; - } - } - return null; - } - - @Override - public V computeIfAbsent(K key, Function mappingFunction) { - if (table == EMPTY_TABLE) { - inflateTable(threshold); - } - if (key == null) { - if (nullKeyEntry == null || nullKeyEntry.value == null) { - V newValue = mappingFunction.apply(key); - if (newValue != null) { - putForNullKey(newValue); - } - return newValue; - } - return nullKeyEntry.value; - } - int hash = hash(key); - int i = indexFor(hash, table.length); - boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? - - if (table[i] instanceof Entry) { - int listSize = 0; - @SuppressWarnings("unchecked") - Entry e = (Entry)table[i]; - for (; e != null; e = (Entry)e.next) { - if (e.hash == hash && Objects.equals(e.key, key)) { - V oldValue = e.value; - if (oldValue == null) { - V newValue = mappingFunction.apply(key); - if (newValue != null) { - e.value = newValue; - e.recordAccess(this); - } - return newValue; - } - return oldValue; - } - listSize++; - } - // Didn't find, fall through to call the mapping function - checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; - } else if (table[i] != null) { - TreeBin e = (TreeBin)table[i]; - V value = mappingFunction.apply(key); - if (value == null) { // Return the existing value, if any - TreeNode p = e.getTreeNode(hash, key); - if (p != null) { - return (V) p.entry.value; - } - return null; - } else { // Put the new value into the Tree, if absent - TreeNode p = e.putTreeNode(hash, key, value, null); - if (p == null) { // not found, new node was added - modCount++; - size++; - if (size >= threshold) { - resize(2 * table.length); - } - return value; - } else { // putTreeNode() found an existing node - Entry pEntry = (Entry)p.entry; - V oldVal = pEntry.value; - if (oldVal == null) { // only replace if maps to null - pEntry.value = value; - pEntry.recordAccess(this); - return value; - } - return oldVal; - } - } - } - V newValue = mappingFunction.apply(key); - if (newValue != null) { // add Entry and check for TreeBin conversion - modCount++; - addEntry(hash, key, newValue, i, checkIfNeedTree); - } - - return newValue; - } - - @Override - public V computeIfPresent(K key, BiFunction remappingFunction) { - if (size == 0) { - return null; - } - if (key == null) { - V oldValue; - if (nullKeyEntry != null && (oldValue = nullKeyEntry.value) != null) { - V newValue = remappingFunction.apply(key, oldValue); - if (newValue != null ) { - putForNullKey(newValue); - return newValue; - } else { - removeNullKey(); - } - } - return null; - } - int hash = hash(key); - int i = indexFor(hash, table.length); - if (table[i] instanceof Entry) { - @SuppressWarnings("unchecked") - Entry prev = (Entry)table[i]; - Entry e = prev; - while (e != null) { - Entry next = (Entry)e.next; - if (e.hash == hash && Objects.equals(e.key, key)) { - V oldValue = e.value; - if (oldValue == null) - break; - V newValue = remappingFunction.apply(key, oldValue); - if (newValue == null) { - modCount++; - size--; - if (prev == e) - table[i] = next; - else - prev.next = next; - e.recordRemoval(this); - } else { - e.value = newValue; - e.recordAccess(this); - } - return newValue; - } - prev = e; - e = next; - } - } else if (table[i] != null) { - TreeBin tb = (TreeBin)table[i]; - TreeNode p = tb.getTreeNode(hash, key); - if (p != null) { - Entry pEntry = (Entry)p.entry; - // assert pEntry.key.equals(key); - V oldValue = pEntry.value; - if (oldValue != null) { - V newValue = remappingFunction.apply(key, oldValue); - if (newValue == null) { // remove mapping - modCount++; - size--; - tb.deleteTreeNode(p); - pEntry.recordRemoval(this); - if (tb.root == null || tb.first == null) { - // assert tb.root == null && tb.first == null : - // "TreeBin.first and root should both be null"; - // TreeBin is now empty, we should blank this bin - table[i] = null; - } - } else { - pEntry.value = newValue; - pEntry.recordAccess(this); - } - return newValue; - } - } - } - return null; - } - - @Override - public V compute(K key, BiFunction remappingFunction) { - if (table == EMPTY_TABLE) { - inflateTable(threshold); - } - if (key == null) { - V oldValue = nullKeyEntry == null ? null : nullKeyEntry.value; - V newValue = remappingFunction.apply(key, oldValue); - if (newValue != oldValue || (oldValue == null && nullKeyEntry != null)) { - if (newValue == null) { - removeNullKey(); - } else { - putForNullKey(newValue); - } - } - return newValue; - } - int hash = hash(key); - int i = indexFor(hash, table.length); - boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? - - if (table[i] instanceof Entry) { - int listSize = 0; - @SuppressWarnings("unchecked") - Entry prev = (Entry)table[i]; - Entry e = prev; - - while (e != null) { - Entry next = (Entry)e.next; - if (e.hash == hash && Objects.equals(e.key, key)) { - V oldValue = e.value; - V newValue = remappingFunction.apply(key, oldValue); - if (newValue != oldValue || oldValue == null) { - if (newValue == null) { - modCount++; - size--; - if (prev == e) - table[i] = next; - else - prev.next = next; - e.recordRemoval(this); - } else { - e.value = newValue; - e.recordAccess(this); - } - } - return newValue; - } - prev = e; - e = next; - listSize++; - } - checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; - } else if (table[i] != null) { - TreeBin tb = (TreeBin)table[i]; - TreeNode p = tb.getTreeNode(hash, key); - V oldValue = p == null ? null : (V)p.entry.value; - V newValue = remappingFunction.apply(key, oldValue); - if (newValue != oldValue || (oldValue == null && p != null)) { - if (newValue == null) { - Entry pEntry = (Entry)p.entry; - modCount++; - size--; - tb.deleteTreeNode(p); - pEntry.recordRemoval(this); - if (tb.root == null || tb.first == null) { - // assert tb.root == null && tb.first == null : - // "TreeBin.first and root should both be null"; - // TreeBin is now empty, we should blank this bin - table[i] = null; - } - } else { - if (p != null) { // just update the value - Entry pEntry = (Entry)p.entry; - pEntry.value = newValue; - pEntry.recordAccess(this); - } else { // need to put new node - p = tb.putTreeNode(hash, key, newValue, null); - // assert p == null; // should have added a new node - modCount++; - size++; - if (size >= threshold) { - resize(2 * table.length); - } - } - } - } - return newValue; - } - - V newValue = remappingFunction.apply(key, null); - if (newValue != null) { - modCount++; - addEntry(hash, key, newValue, i, checkIfNeedTree); - } - - return newValue; - } - - @Override - public V merge(K key, V value, BiFunction remappingFunction) { - if (table == EMPTY_TABLE) { - inflateTable(threshold); - } - if (key == null) { - V oldValue = nullKeyEntry == null ? null : nullKeyEntry.value; - V newValue = oldValue == null ? value : remappingFunction.apply(oldValue, value); - if (newValue != null) { - putForNullKey(newValue); - } else if (nullKeyEntry != null) { - removeNullKey(); - } - return newValue; - } - int hash = hash(key); - int i = indexFor(hash, table.length); - boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? - - if (table[i] instanceof Entry) { - int listSize = 0; - @SuppressWarnings("unchecked") - Entry prev = (Entry)table[i]; - Entry e = prev; - - while (e != null) { - Entry next = (Entry)e.next; - if (e.hash == hash && Objects.equals(e.key, key)) { - V oldValue = e.value; - V newValue = (oldValue == null) ? value : - remappingFunction.apply(oldValue, value); - if (newValue == null) { - modCount++; - size--; - if (prev == e) - table[i] = next; - else - prev.next = next; - e.recordRemoval(this); - } else { - e.value = newValue; - e.recordAccess(this); - } - return newValue; - } - prev = e; - e = next; - listSize++; - } - // Didn't find, so fall through and (maybe) call addEntry() to add - // the Entry and check for TreeBin conversion. - checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; - } else if (table[i] != null) { - TreeBin tb = (TreeBin)table[i]; - TreeNode p = tb.getTreeNode(hash, key); - V oldValue = p == null ? null : (V)p.entry.value; - V newValue = (oldValue == null) ? value : - remappingFunction.apply(oldValue, value); - if (newValue == null) { - if (p != null) { - Entry pEntry = (Entry)p.entry; - modCount++; - size--; - tb.deleteTreeNode(p); - pEntry.recordRemoval(this); - - if (tb.root == null || tb.first == null) { - // assert tb.root == null && tb.first == null : - // "TreeBin.first and root should both be null"; - // TreeBin is now empty, we should blank this bin - table[i] = null; - } - } - return null; - } else if (newValue != oldValue) { - if (p != null) { // just update the value - Entry pEntry = (Entry)p.entry; - pEntry.value = newValue; - pEntry.recordAccess(this); - } else { // need to put new node - p = tb.putTreeNode(hash, key, newValue, null); - // assert p == null; // should have added a new node - modCount++; - size++; - if (size >= threshold) { - resize(2 * table.length); - } - } - } - return newValue; - } - if (value != null) { - modCount++; - addEntry(hash, key, value, i, checkIfNeedTree); - } - return value; - } - - // end of optimized implementations of default methods in Map - - /** - * Removes and returns the entry associated with the specified key - * in the HashMap. Returns null if the HashMap contains no mapping - * for this key. - * - * We don't bother converting TreeBins back to Entry lists if the bin falls - * back below TREE_THRESHOLD, but we do clear bins when removing the last - * TreeNode in a TreeBin. - */ - final Entry removeEntryForKey(Object key) { - if (size == 0) { - return null; - } - if (key == null) { - if (nullKeyEntry != null) { - return removeNullKey(); - } - return null; - } - int hash = hash(key); - int i = indexFor(hash, table.length); - - if (table[i] instanceof Entry) { - @SuppressWarnings("unchecked") - Entry prev = (Entry)table[i]; - Entry e = prev; - - while (e != null) { - @SuppressWarnings("unchecked") - Entry next = (Entry) e.next; - if (e.hash == hash && Objects.equals(e.key, key)) { - modCount++; - size--; - if (prev == e) - table[i] = next; - else - prev.next = next; - e.recordRemoval(this); - return e; - } - prev = e; - e = next; - } - } else if (table[i] != null) { - TreeBin tb = ((TreeBin) table[i]); - TreeNode p = tb.getTreeNode(hash, (K)key); - if (p != null) { - Entry pEntry = (Entry)p.entry; - // assert pEntry.key.equals(key); - modCount++; - size--; - tb.deleteTreeNode(p); - pEntry.recordRemoval(this); - if (tb.root == null || tb.first == null) { - // assert tb.root == null && tb.first == null : - // "TreeBin.first and root should both be null"; - // TreeBin is now empty, we should blank this bin - table[i] = null; - } - return pEntry; - } - } - return null; + Node e; + return (e = removeNode(hash(key), key, null, false, true)) == null ? + null : e.value; } /** - * Special version of remove for EntrySet using {@code Map.Entry.equals()} - * for matching. + * Implements Map.remove and related methods + * + * @param hash hash for key + * @param key the key + * @param value the value to match if matchValue, else ignored + * @param matchValue if true only remove if value is equal + * @param movable if false do not move other nodes while removing + * @return the node, or null if none */ - final Entry removeMapping(Object o) { - if (size == 0 || !(o instanceof Map.Entry)) - return null; - - Map.Entry entry = (Map.Entry) o; - Object key = entry.getKey(); - - if (key == null) { - if (entry.equals(nullKeyEntry)) { - return removeNullKey(); - } - return null; - } - - int hash = hash(key); - int i = indexFor(hash, table.length); - - if (table[i] instanceof Entry) { - @SuppressWarnings("unchecked") - Entry prev = (Entry)table[i]; - Entry e = prev; - - while (e != null) { - @SuppressWarnings("unchecked") - Entry next = (Entry)e.next; - if (e.hash == hash && e.equals(entry)) { - modCount++; - size--; - if (prev == e) - table[i] = next; - else - prev.next = next; - e.recordRemoval(this); - return e; + final Node removeNode(int hash, Object key, Object value, + boolean matchValue, boolean movable) { + Node[] tab; Node p; int n, index; + if ((tab = table) != null && (n = tab.length) > 0 && + (p = tab[index = (n - 1) & hash]) != null) { + Node node = null, e; K k; V v; + if (p.hash == hash && + ((k = p.key) == key || (key != null && key.equals(k)))) + node = p; + else if ((e = p.next) != null) { + if (p instanceof TreeNode) + node = ((TreeNode)p).getTreeNode(hash, key); + else { + do { + if (e.hash == hash && + ((k = e.key) == key || + (key != null && key.equals(k)))) { + node = e; + break; + } + p = e; + } while ((e = e.next) != null); } - prev = e; - e = next; } - } else if (table[i] != null) { - TreeBin tb = ((TreeBin) table[i]); - TreeNode p = tb.getTreeNode(hash, (K)key); - if (p != null && p.entry.equals(entry)) { - @SuppressWarnings("unchecked") - Entry pEntry = (Entry)p.entry; - // assert pEntry.key.equals(key); - modCount++; - size--; - tb.deleteTreeNode(p); - pEntry.recordRemoval(this); - if (tb.root == null || tb.first == null) { - // assert tb.root == null && tb.first == null : - // "TreeBin.first and root should both be null"; - // TreeBin is now empty, we should blank this bin - table[i] = null; - } - return pEntry; + if (node != null && (!matchValue || (v = node.value) == value || + (value != null && value.equals(v)))) { + if (node instanceof TreeNode) + ((TreeNode)node).removeTreeNode(this, tab, movable); + else if (node == p) + tab[index] = node.next; + else + p.next = node.next; + ++modCount; + --size; + afterNodeRemoval(node); + return node; } } return null; } - /* - * Remove the mapping for the null key, and update internal accounting - * (size, modcount, recordRemoval, etc). - * - * Assumes nullKeyEntry is non-null. - */ - private Entry removeNullKey() { - // assert nullKeyEntry != null; - Entry retVal = nullKeyEntry; - modCount++; - size--; - retVal.recordRemoval(this); - nullKeyEntry = null; - return retVal; - } - /** * Removes all of the mappings from this map. * The map will be empty after this call returns. */ public void clear() { + Node[] tab; modCount++; - if (nullKeyEntry != null) { - nullKeyEntry = null; + if ((tab = table) != null && size > 0) { + size = 0; + for (int i = 0; i < tab.length; ++i) + tab[i] = null; } - Arrays.fill(table, null); - size = 0; } /** @@ -2134,351 +873,19 @@ public class HashMap * specified value */ public boolean containsValue(Object value) { - if (value == null) { - return containsNullValue(); - } - Object[] tab = table; - for (int i = 0; i < tab.length; i++) { - if (tab[i] instanceof Entry) { - Entry e = (Entry)tab[i]; - for (; e != null; e = (Entry)e.next) { - if (value.equals(e.value)) { + Node[] tab; V v; + if ((tab = table) != null && size > 0) { + for (int i = 0; i < tab.length; ++i) { + for (Node e = tab[i]; e != null; e = e.next) { + if ((v = e.value) == value || + (value != null && value.equals(v))) return true; - } - } - } else if (tab[i] != null) { - TreeBin e = (TreeBin)tab[i]; - TreeNode p = e.first; - for (; p != null; p = (TreeNode) p.entry.next) { - if (value == p.entry.value || value.equals(p.entry.value)) { - return true; - } } } } - // Didn't find value in table - could be in nullKeyEntry - return (nullKeyEntry != null && (value == nullKeyEntry.value || - value.equals(nullKeyEntry.value))); + return false; } - /** - * Special-case code for containsValue with null argument - */ - private boolean containsNullValue() { - Object[] tab = table; - for (int i = 0; i < tab.length; i++) { - if (tab[i] instanceof Entry) { - Entry e = (Entry)tab[i]; - for (; e != null; e = (Entry)e.next) { - if (e.value == null) { - return true; - } - } - } else if (tab[i] != null) { - TreeBin e = (TreeBin)tab[i]; - TreeNode p = e.first; - for (; p != null; p = (TreeNode) p.entry.next) { - if (p.entry.value == null) { - return true; - } - } - } - } - // Didn't find value in table - could be in nullKeyEntry - return (nullKeyEntry != null && nullKeyEntry.value == null); - } - - /** - * Returns a shallow copy of this HashMap instance: the keys and - * values themselves are not cloned. - * - * @return a shallow copy of this map - */ - @SuppressWarnings("unchecked") - public Object clone() { - HashMap result = null; - try { - result = (HashMap)super.clone(); - } catch (CloneNotSupportedException e) { - // assert false; - } - if (result.table != EMPTY_TABLE) { - result.inflateTable(Math.min( - (int) Math.min( - size * Math.min(1 / loadFactor, 4.0f), - // we have limits... - HashMap.MAXIMUM_CAPACITY), - table.length)); - } - result.entrySet = null; - result.modCount = 0; - result.size = 0; - result.nullKeyEntry = null; - result.init(); - result.putAllForCreate(this); - - return result; - } - - static class Entry implements Map.Entry { - final K key; - V value; - Object next; // an Entry, or a TreeNode - final int hash; - - /** - * Creates new entry. - */ - Entry(int h, K k, V v, Object n) { - value = v; - next = n; - key = k; - hash = h; - } - - public final K getKey() { - return key; - } - - public final V getValue() { - return value; - } - - public final V setValue(V newValue) { - V oldValue = value; - value = newValue; - return oldValue; - } - - public final boolean equals(Object o) { - if (!(o instanceof Map.Entry)) - return false; - Map.Entry e = (Map.Entry)o; - Object k1 = getKey(); - Object k2 = e.getKey(); - if (k1 == k2 || (k1 != null && k1.equals(k2))) { - Object v1 = getValue(); - Object v2 = e.getValue(); - if (v1 == v2 || (v1 != null && v1.equals(v2))) - return true; - } - return false; - } - - public final int hashCode() { - return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue()); - } - - public final String toString() { - return getKey() + "=" + getValue(); - } - - /** - * This method is invoked whenever the value in an entry is - * overwritten for a key that's already in the HashMap. - */ - void recordAccess(HashMap m) { - } - - /** - * This method is invoked whenever the entry is - * removed from the table. - */ - void recordRemoval(HashMap m) { - } - } - - void addEntry(int hash, K key, V value, int bucketIndex) { - addEntry(hash, key, value, bucketIndex, true); - } - - /** - * Adds a new entry with the specified key, value and hash code to - * the specified bucket. It is the responsibility of this - * method to resize the table if appropriate. The new entry is then - * created by calling createEntry(). - * - * Subclass overrides this to alter the behavior of put method. - * - * If checkIfNeedTree is false, it is known that this bucket will not need - * to be converted to a TreeBin, so don't bothering checking. - * - * Assumes key is not null. - */ - void addEntry(int hash, K key, V value, int bucketIndex, boolean checkIfNeedTree) { - // assert key != null; - if ((size >= threshold) && (null != table[bucketIndex])) { - resize(2 * table.length); - hash = hash(key); - bucketIndex = indexFor(hash, table.length); - } - createEntry(hash, key, value, bucketIndex, checkIfNeedTree); - } - - /** - * Called by addEntry(), and also used when creating entries - * as part of Map construction or "pseudo-construction" (cloning, - * deserialization). This version does not check for resizing of the table. - * - * This method is responsible for converting a bucket to a TreeBin once - * TREE_THRESHOLD is reached. However if checkIfNeedTree is false, it is known - * that this bucket will not need to be converted to a TreeBin, so don't - * bother checking. The new entry is constructed by calling newEntry(). - * - * Assumes key is not null. - * - * Note: buckets already converted to a TreeBin don't call this method, but - * instead call TreeBin.putTreeNode() to create new entries. - */ - void createEntry(int hash, K key, V value, int bucketIndex, boolean checkIfNeedTree) { - // assert key != null; - @SuppressWarnings("unchecked") - Entry e = (Entry)table[bucketIndex]; - table[bucketIndex] = newEntry(hash, key, value, e); - size++; - - if (checkIfNeedTree) { - int listSize = 0; - for (e = (Entry) table[bucketIndex]; e != null; e = (Entry)e.next) { - listSize++; - if (listSize >= TreeBin.TREE_THRESHOLD) { // Convert to TreeBin - if (comparableClassFor(key) != null) { - TreeBin t = new TreeBin(); - t.populate((Entry)table[bucketIndex]); - table[bucketIndex] = t; - } - break; - } - } - } - } - - /* - * Factory method to create a new Entry object. - */ - Entry newEntry(int hash, K key, V value, Object next) { - return new HashMap.Entry<>(hash, key, value, next); - } - - - private abstract class HashIterator implements Iterator { - Object next; // next entry to return, an Entry or a TreeNode - int expectedModCount; // For fast-fail - int index; // current slot - Object current; // current entry, an Entry or a TreeNode - - HashIterator() { - expectedModCount = modCount; - if (size > 0) { // advance to first entry - if (nullKeyEntry != null) { - // assert nullKeyEntry.next == null; - // This works with nextEntry(): nullKeyEntry isa Entry, and - // e.next will be null, so we'll hit the findNextBin() call. - next = nullKeyEntry; - } else { - findNextBin(); - } - } - } - - public final boolean hasNext() { - return next != null; - } - - @SuppressWarnings("unchecked") - final Entry nextEntry() { - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - Object e = next; - Entry retVal; - - if (e == null) - throw new NoSuchElementException(); - - if (e instanceof TreeNode) { // TreeBin - retVal = (Entry)((TreeNode)e).entry; - next = retVal.next; - } else { - retVal = (Entry)e; - next = ((Entry)e).next; - } - - if (next == null) { // Move to next bin - findNextBin(); - } - current = e; - return retVal; - } - - public void remove() { - if (current == null) - throw new IllegalStateException(); - if (modCount != expectedModCount) - throw new ConcurrentModificationException(); - K k; - - if (current instanceof Entry) { - k = ((Entry)current).key; - } else { - k = ((Entry)((TreeNode)current).entry).key; - - } - current = null; - HashMap.this.removeEntryForKey(k); - expectedModCount = modCount; - } - - /* - * Set 'next' to the first entry of the next non-empty bin in the table - */ - private void findNextBin() { - // assert next == null; - Object[] t = table; - - while (index < t.length && (next = t[index++]) == null) - ; - if (next instanceof HashMap.TreeBin) { // Point to the first TreeNode - next = ((TreeBin) next).first; - // assert next != null; // There should be no empty TreeBins - } - } - } - - private final class ValueIterator extends HashIterator { - public V next() { - return nextEntry().value; - } - } - - private final class KeyIterator extends HashIterator { - public K next() { - return nextEntry().getKey(); - } - } - - private final class EntryIterator extends HashIterator> { - public Map.Entry next() { - return nextEntry(); - } - } - - // Subclass overrides these to alter behavior of views' iterator() method - Iterator newKeyIterator() { - return new KeyIterator(); - } - Iterator newValueIterator() { - return new ValueIterator(); - } - Iterator> newEntryIterator() { - return new EntryIterator(); - } - - - // Views - - private transient Set> entrySet = null; - /** * Returns a {@link Set} view of the keys contained in this map. * The set is backed by the map, so changes to the map are @@ -2491,35 +898,38 @@ public class HashMap * removeAll, retainAll, and clear * operations. It does not support the add or addAll * operations. + * + * @return a set view of the keys contained in this map */ public Set keySet() { - Set ks = keySet; - return (ks != null ? ks : (keySet = new KeySet())); + Set ks; + return (ks = keySet) == null ? (keySet = new KeySet()) : ks; } - private final class KeySet extends AbstractSet { - public Iterator iterator() { - return newKeyIterator(); + final class KeySet extends AbstractSet { + public final int size() { return size; } + public final void clear() { HashMap.this.clear(); } + public final Iterator iterator() { return new KeyIterator(); } + public final boolean contains(Object o) { return containsKey(o); } + public final boolean remove(Object key) { + return removeNode(hash(key), key, null, false, true) != null; } - public int size() { - return size; + public final Spliterator spliterator() { + return new KeySpliterator(HashMap.this, 0, -1, 0, 0); } - public boolean contains(Object o) { - return containsKey(o); - } - public boolean remove(Object o) { - return HashMap.this.removeEntryForKey(o) != null; - } - public void clear() { - HashMap.this.clear(); - } - - public Spliterator spliterator() { - if (HashMap.this.getClass() == HashMap.class) - return new KeySpliterator(HashMap.this, 0, -1, 0, 0); - else - return Spliterators.spliterator - (this, Spliterator.SIZED | Spliterator.DISTINCT); + public final void forEach(Consumer action) { + Node[] tab; + if (action == null) + throw new NullPointerException(); + if (size > 0 && (tab = table) != null) { + int mc = modCount; + for (int i = 0; i < tab.length; ++i) { + for (Node e = tab[i]; e != null; e = e.next) + action.accept(e.key); + } + if (modCount != mc) + throw new ConcurrentModificationException(); + } } } @@ -2535,32 +945,35 @@ public class HashMap * Collection.remove, removeAll, * retainAll and clear operations. It does not * support the add or addAll operations. + * + * @return a view of the values contained in this map */ public Collection values() { - Collection vs = values; - return (vs != null ? vs : (values = new Values())); + Collection vs; + return (vs = values) == null ? (values = new Values()) : vs; } - private final class Values extends AbstractCollection { - public Iterator iterator() { - return newValueIterator(); + final class Values extends AbstractCollection { + public final int size() { return size; } + public final void clear() { HashMap.this.clear(); } + public final Iterator iterator() { return new ValueIterator(); } + public final boolean contains(Object o) { return containsValue(o); } + public final Spliterator spliterator() { + return new ValueSpliterator(HashMap.this, 0, -1, 0, 0); } - public int size() { - return size; - } - public boolean contains(Object o) { - return containsValue(o); - } - public void clear() { - HashMap.this.clear(); - } - - public Spliterator spliterator() { - if (HashMap.this.getClass() == HashMap.class) - return new ValueSpliterator(HashMap.this, 0, -1, 0, 0); - else - return Spliterators.spliterator - (this, Spliterator.SIZED); + public final void forEach(Consumer action) { + Node[] tab; + if (action == null) + throw new NullPointerException(); + if (size > 0 && (tab = table) != null) { + int mc = modCount; + for (int i = 0; i < tab.length; ++i) { + for (Node e = tab[i]; e != null; e = e.next) + action.accept(e.value); + } + if (modCount != mc) + throw new ConcurrentModificationException(); + } } } @@ -2581,42 +994,324 @@ public class HashMap * @return a set view of the mappings contained in this map */ public Set> entrySet() { - return entrySet0(); + Set> es; + return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } - private Set> entrySet0() { - Set> es = entrySet; - return es != null ? es : (entrySet = new EntrySet()); - } - - private final class EntrySet extends AbstractSet> { - public Iterator> iterator() { - return newEntryIterator(); + final class EntrySet extends AbstractSet> { + public final int size() { return size; } + public final void clear() { HashMap.this.clear(); } + public final Iterator> iterator() { + return new EntryIterator(); } - public boolean contains(Object o) { + public final boolean contains(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry e = (Map.Entry) o; - Entry candidate = getEntry(e.getKey()); + Object key = e.getKey(); + Node candidate = getNode(hash(key), key); return candidate != null && candidate.equals(e); } - public boolean remove(Object o) { - return removeMapping(o) != null; + public final boolean remove(Object o) { + if (o instanceof Map.Entry) { + Map.Entry e = (Map.Entry) o; + Object key = e.getKey(); + Object value = e.getValue(); + return removeNode(hash(key), key, value, true, true) != null; + } + return false; } - public int size() { - return size; + public final Spliterator> spliterator() { + return new EntrySpliterator(HashMap.this, 0, -1, 0, 0); } - public void clear() { - HashMap.this.clear(); + public final void forEach(Consumer> action) { + Node[] tab; + if (action == null) + throw new NullPointerException(); + if (size > 0 && (tab = table) != null) { + int mc = modCount; + for (int i = 0; i < tab.length; ++i) { + for (Node e = tab[i]; e != null; e = e.next) + action.accept(e); + } + if (modCount != mc) + throw new ConcurrentModificationException(); + } } + } - public Spliterator> spliterator() { - if (HashMap.this.getClass() == HashMap.class) - return new EntrySpliterator(HashMap.this, 0, -1, 0, 0); - else - return Spliterators.spliterator - (this, Spliterator.SIZED | Spliterator.DISTINCT); + // Overrides of JDK8 Map extension methods + + public V getOrDefault(Object key, V defaultValue) { + Node e; + return (e = getNode(hash(key), key)) == null ? defaultValue : e.value; + } + + public V putIfAbsent(K key, V value) { + return putVal(hash(key), key, value, true, true); + } + + public boolean remove(Object key, Object value) { + return removeNode(hash(key), key, value, true, true) != null; + } + + public boolean replace(K key, V oldValue, V newValue) { + Node e; V v; + if ((e = getNode(hash(key), key)) != null && + ((v = e.value) == oldValue || (v != null && v.equals(oldValue)))) { + e.value = newValue; + afterNodeAccess(e); + return true; } + return false; + } + + public V replace(K key, V value) { + Node e; + if ((e = getNode(hash(key), key)) != null) { + V oldValue = e.value; + e.value = value; + afterNodeAccess(e); + return oldValue; + } + return null; + } + + public V computeIfAbsent(K key, + Function mappingFunction) { + if (mappingFunction == null) + throw new NullPointerException(); + int hash = hash(key); + Node[] tab; Node first; int n, i; + int binCount = 0; + TreeNode t = null; + Node old = null; + if (size > threshold || (tab = table) == null || + (n = tab.length) == 0) + n = (tab = resize()).length; + if ((first = tab[i = (n - 1) & hash]) != null) { + if (first instanceof TreeNode) + old = (t = (TreeNode)first).getTreeNode(hash, key); + else { + Node e = first; K k; + do { + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) { + old = e; + break; + } + ++binCount; + } while ((e = e.next) != null); + } + V oldValue; + if (old != null && (oldValue = old.value) != null) { + afterNodeAccess(old); + return oldValue; + } + } + V v = mappingFunction.apply(key); + if (old != null) { + old.value = v; + afterNodeAccess(old); + return v; + } + else if (v == null) + return null; + else if (t != null) + t.putTreeVal(this, tab, hash, key, v); + else { + tab[i] = newNode(hash, key, v, first); + if (binCount >= TREEIFY_THRESHOLD - 1) + treeifyBin(tab, hash); + } + ++modCount; + ++size; + afterNodeInsertion(true); + return v; + } + + public V computeIfPresent(K key, + BiFunction remappingFunction) { + Node e; V oldValue; + int hash = hash(key); + if ((e = getNode(hash, key)) != null && + (oldValue = e.value) != null) { + V v = remappingFunction.apply(key, oldValue); + if (v != null) { + e.value = v; + afterNodeAccess(e); + return v; + } + else + removeNode(hash, key, null, false, true); + } + return null; + } + + public V compute(K key, + BiFunction remappingFunction) { + if (remappingFunction == null) + throw new NullPointerException(); + int hash = hash(key); + Node[] tab; Node first; int n, i; + int binCount = 0; + TreeNode t = null; + Node old = null; + if (size > threshold || (tab = table) == null || + (n = tab.length) == 0) + n = (tab = resize()).length; + if ((first = tab[i = (n - 1) & hash]) != null) { + if (first instanceof TreeNode) + old = (t = (TreeNode)first).getTreeNode(hash, key); + else { + Node e = first; K k; + do { + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) { + old = e; + break; + } + ++binCount; + } while ((e = e.next) != null); + } + } + V oldValue = (old == null) ? null : old.value; + V v = remappingFunction.apply(key, oldValue); + if (old != null) { + if (v != null) { + old.value = v; + afterNodeAccess(old); + } + else + removeNode(hash, key, null, false, true); + } + else if (v != null) { + if (t != null) + t.putTreeVal(this, tab, hash, key, v); + else { + tab[i] = newNode(hash, key, v, first); + if (binCount >= TREEIFY_THRESHOLD - 1) + treeifyBin(tab, hash); + } + ++modCount; + ++size; + afterNodeInsertion(true); + } + return v; + } + + public V merge(K key, V value, + BiFunction remappingFunction) { + if (remappingFunction == null) + throw new NullPointerException(); + int hash = hash(key); + Node[] tab; Node first; int n, i; + int binCount = 0; + TreeNode t = null; + Node old = null; + if (size > threshold || (tab = table) == null || + (n = tab.length) == 0) + n = (tab = resize()).length; + if ((first = tab[i = (n - 1) & hash]) != null) { + if (first instanceof TreeNode) + old = (t = (TreeNode)first).getTreeNode(hash, key); + else { + Node e = first; K k; + do { + if (e.hash == hash && + ((k = e.key) == key || (key != null && key.equals(k)))) { + old = e; + break; + } + ++binCount; + } while ((e = e.next) != null); + } + } + if (old != null) { + V v = remappingFunction.apply(old.value, value); + if (v != null) { + old.value = v; + afterNodeAccess(old); + } + else + removeNode(hash, key, null, false, true); + return v; + } + if (value != null) { + if (t != null) + t.putTreeVal(this, tab, hash, key, value); + else { + tab[i] = newNode(hash, key, value, first); + if (binCount >= TREEIFY_THRESHOLD - 1) + treeifyBin(tab, hash); + } + ++modCount; + ++size; + afterNodeInsertion(true); + } + return value; + } + + public void forEach(BiConsumer action) { + Node[] tab; + if (action == null) + throw new NullPointerException(); + if (size > 0 && (tab = table) != null) { + int mc = modCount; + for (int i = 0; i < tab.length; ++i) { + for (Node e = tab[i]; e != null; e = e.next) + action.accept(e.key, e.value); + } + if (modCount != mc) + throw new ConcurrentModificationException(); + } + } + + public void replaceAll(BiFunction function) { + Node[] tab; + if (function == null) + throw new NullPointerException(); + if (size > 0 && (tab = table) != null) { + int mc = modCount; + for (int i = 0; i < tab.length; ++i) { + for (Node e = tab[i]; e != null; e = e.next) { + e.value = function.apply(e.key, e.value); + } + } + if (modCount != mc) + throw new ConcurrentModificationException(); + } + } + + /* ------------------------------------------------------------ */ + // Cloning and serialization + + /** + * Returns a shallow copy of this HashMap instance: the keys and + * values themselves are not cloned. + * + * @return a shallow copy of this map + */ + @SuppressWarnings("unchecked") + public Object clone() { + HashMap result; + try { + result = (HashMap)super.clone(); + } catch (CloneNotSupportedException e) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(e); + } + result.reinitialize(); + result.putMapEntries(this, false); + return result; + } + + // These methods are also used when serializing HashSets + final float loadFactor() { return loadFactor; } + final int capacity() { + return (table != null) ? table.length : + (threshold > 0) ? threshold : + DEFAULT_INITIAL_CAPACITY; } /** @@ -2631,118 +1326,143 @@ public class HashMap * emitted in no particular order. */ private void writeObject(java.io.ObjectOutputStream s) - throws IOException - { + throws IOException { + int buckets = capacity(); // Write out the threshold, loadfactor, and any hidden stuff s.defaultWriteObject(); - - // Write out number of buckets - if (table==EMPTY_TABLE) { - s.writeInt(roundUpToPowerOf2(threshold)); - } else { - s.writeInt(table.length); - } - - // Write out size (number of Mappings) + s.writeInt(buckets); s.writeInt(size); - - // Write out keys and values (alternating) - if (size > 0) { - for(Map.Entry e : entrySet0()) { - s.writeObject(e.getKey()); - s.writeObject(e.getValue()); - } - } + internalWriteEntries(s); } - private static final long serialVersionUID = 362498820763181265L; - /** * Reconstitute the {@code HashMap} instance from a stream (i.e., * deserialize it). */ private void readObject(java.io.ObjectInputStream s) - throws IOException, ClassNotFoundException - { + throws IOException, ClassNotFoundException { // Read in the threshold (ignored), loadfactor, and any hidden stuff s.defaultReadObject(); - if (loadFactor <= 0 || Float.isNaN(loadFactor)) { + reinitialize(); + if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new InvalidObjectException("Illegal load factor: " + - loadFactor); - } - - // set other fields that need values - if (Holder.USE_HASHSEED) { - int seed = ThreadLocalRandom.current().nextInt(); - Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET, - (seed != 0) ? seed : 1); - } - table = EMPTY_TABLE; - - // Read in number of buckets - s.readInt(); // ignored. - - // Read number of mappings - int mappings = s.readInt(); + loadFactor); + s.readInt(); // Read and ignore number of buckets + int mappings = s.readInt(); // Read number of mappings (size) if (mappings < 0) throw new InvalidObjectException("Illegal mappings count: " + - mappings); + mappings); + else if (mappings > 0) { // (if zero, use defaults) + // Size the table using given load factor only if within + // range of 0.25...4.0 + float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f); + float fc = (float)mappings / lf + 1.0f; + int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ? + DEFAULT_INITIAL_CAPACITY : + (fc >= MAXIMUM_CAPACITY) ? + MAXIMUM_CAPACITY : + tableSizeFor((int)fc)); + float ft = (float)cap * lf; + threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ? + (int)ft : Integer.MAX_VALUE); + @SuppressWarnings({"rawtypes","unchecked"}) + Node[] tab = (Node[])new Node[cap]; + table = tab; - // capacity chosen by number of mappings and desired load (if >= 0.25) - int capacity = (int) Math.min( - mappings * Math.min(1 / loadFactor, 4.0f), - // we have limits... - HashMap.MAXIMUM_CAPACITY); - - // allocate the bucket array; - if (mappings > 0) { - inflateTable(capacity); - } else { - threshold = capacity; - } - - init(); // Give subclass a chance to do its thing. - - // Read the keys and values, and put the mappings in the HashMap - for (int i=0; i next; // next entry to return + Node current; // current entry + int expectedModCount; // for fast-fail + int index; // current slot + + HashIterator() { + expectedModCount = modCount; + Node[] t = table; + current = next = null; + index = 0; + if (t != null && size > 0) { // advance to first entry + do {} while (index < t.length && (next = t[index++]) == null); + } + } + + public final boolean hasNext() { + return next != null; + } + + final Node nextNode() { + Node[] t; + Node e = next; + if (modCount != expectedModCount) + throw new ConcurrentModificationException(); + if (e == null) + throw new NoSuchElementException(); + if ((next = (current = e).next) == null && (t = table) != null) { + do {} while (index < t.length && (next = t[index++]) == null); + } + return e; + } + + public final void remove() { + Node p = current; + if (p == null) + throw new IllegalStateException(); + if (modCount != expectedModCount) + throw new ConcurrentModificationException(); + current = null; + K key = p.key; + removeNode(hash(key), key, null, false, false); + expectedModCount = modCount; + } + } + + final class KeyIterator extends HashIterator + implements Iterator { + public final K next() { return nextNode().key; } + } + + final class ValueIterator extends HashIterator + implements Iterator { + public final V next() { return nextNode().value; } + } + + final class EntryIterator extends HashIterator + implements Iterator> { + public final Map.Entry next() { return nextNode(); } + } + + /* ------------------------------------------------------------ */ + // spliterators - /** - * Standin until HM overhaul; based loosely on Weak and Identity HM. - */ static class HashMapSpliterator { final HashMap map; - Object current; // current node, can be Entry or TreeNode + Node current; // current node int index; // current index, modified on advance/split int fence; // one past last index int est; // size estimate int expectedModCount; // for comodification checks - boolean acceptedNull; // Have we accepted the null key? - // Without this, we can't distinguish - // between being at the very beginning (and - // needing to accept null), or being at the - // end of the list in bin 0. In both cases, - // current == null && index == 0. HashMapSpliterator(HashMap m, int origin, - int fence, int est, - int expectedModCount) { + int fence, int est, + int expectedModCount) { this.map = m; this.index = origin; this.fence = fence; this.est = est; this.expectedModCount = expectedModCount; - this.acceptedNull = false; } final int getFence() { // initialize fence and size on first use @@ -2751,7 +1471,8 @@ public class HashMap HashMap m = map; est = m.size; expectedModCount = m.modCount; - hi = fence = m.table.length; + Node[] tab = m.table; + hi = fence = (tab == null) ? 0 : tab.length; } return hi; } @@ -2772,56 +1493,33 @@ public class HashMap public KeySpliterator trySplit() { int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; - if (lo >= mid || current != null) { - return null; - } else { - KeySpliterator retVal = new KeySpliterator(map, lo, - index = mid, est >>>= 1, expectedModCount); - // Only 'this' Spliterator chould check for null. - retVal.acceptedNull = true; - return retVal; - } + return (lo >= mid || current != null) ? null : + new KeySpliterator(map, lo, index = mid, est >>>= 1, + expectedModCount); } - @SuppressWarnings("unchecked") public void forEachRemaining(Consumer action) { int i, hi, mc; if (action == null) throw new NullPointerException(); HashMap m = map; - Object[] tab = m.table; + Node[] tab = m.table; if ((hi = fence) < 0) { mc = expectedModCount = m.modCount; - hi = fence = tab.length; + hi = fence = (tab == null) ? 0 : tab.length; } else mc = expectedModCount; - - if (!acceptedNull) { - acceptedNull = true; - if (m.nullKeyEntry != null) { - action.accept(m.nullKeyEntry.key); - } - } - if (tab.length >= hi && (i = index) >= 0 && - (i < (index = hi) || current != null)) { - Object p = current; + if (tab != null && tab.length >= hi && + (i = index) >= 0 && (i < (index = hi) || current != null)) { + Node p = current; current = null; do { - if (p == null) { + if (p == null) p = tab[i++]; - if (p instanceof HashMap.TreeBin) { - p = ((HashMap.TreeBin)p).first; - } - } else { - HashMap.Entry entry; - if (p instanceof HashMap.Entry) { - entry = (HashMap.Entry)p; - } else { - entry = (HashMap.Entry)((TreeNode)p).entry; - } - action.accept(entry.key); - p = entry.next; + else { + action.accept(p.key); + p = p.next; } } while (p != null || i < hi); if (m.modCount != mc) @@ -2829,39 +1527,18 @@ public class HashMap } } - @SuppressWarnings("unchecked") public boolean tryAdvance(Consumer action) { int hi; if (action == null) throw new NullPointerException(); - Object[] tab = map.table; - hi = getFence(); - - if (!acceptedNull) { - acceptedNull = true; - if (map.nullKeyEntry != null) { - action.accept(map.nullKeyEntry.key); - if (map.modCount != expectedModCount) - throw new ConcurrentModificationException(); - return true; - } - } - if (tab.length >= hi && index >= 0) { + Node[] tab = map.table; + if (tab != null && tab.length >= (hi = getFence()) && index >= 0) { while (current != null || index < hi) { - if (current == null) { + if (current == null) current = tab[index++]; - if (current instanceof HashMap.TreeBin) { - current = ((HashMap.TreeBin)current).first; - } - } else { - HashMap.Entry entry; - if (current instanceof HashMap.Entry) { - entry = (HashMap.Entry)current; - } else { - entry = (HashMap.Entry)((TreeNode)current).entry; - } - K k = entry.key; - current = entry.next; + else { + K k = current.key; + current = current.next; action.accept(k); if (map.modCount != expectedModCount) throw new ConcurrentModificationException(); @@ -2888,56 +1565,33 @@ public class HashMap public ValueSpliterator trySplit() { int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; - if (lo >= mid || current != null) { - return null; - } else { - ValueSpliterator retVal = new ValueSpliterator(map, - lo, index = mid, est >>>= 1, expectedModCount); - // Only 'this' Spliterator chould check for null. - retVal.acceptedNull = true; - return retVal; - } + return (lo >= mid || current != null) ? null : + new ValueSpliterator(map, lo, index = mid, est >>>= 1, + expectedModCount); } - @SuppressWarnings("unchecked") public void forEachRemaining(Consumer action) { int i, hi, mc; if (action == null) throw new NullPointerException(); HashMap m = map; - Object[] tab = m.table; + Node[] tab = m.table; if ((hi = fence) < 0) { mc = expectedModCount = m.modCount; - hi = fence = tab.length; + hi = fence = (tab == null) ? 0 : tab.length; } else mc = expectedModCount; - - if (!acceptedNull) { - acceptedNull = true; - if (m.nullKeyEntry != null) { - action.accept(m.nullKeyEntry.value); - } - } - if (tab.length >= hi && (i = index) >= 0 && - (i < (index = hi) || current != null)) { - Object p = current; + if (tab != null && tab.length >= hi && + (i = index) >= 0 && (i < (index = hi) || current != null)) { + Node p = current; current = null; do { - if (p == null) { + if (p == null) p = tab[i++]; - if (p instanceof HashMap.TreeBin) { - p = ((HashMap.TreeBin)p).first; - } - } else { - HashMap.Entry entry; - if (p instanceof HashMap.Entry) { - entry = (HashMap.Entry)p; - } else { - entry = (HashMap.Entry)((TreeNode)p).entry; - } - action.accept(entry.value); - p = entry.next; + else { + action.accept(p.value); + p = p.next; } } while (p != null || i < hi); if (m.modCount != mc) @@ -2945,39 +1599,18 @@ public class HashMap } } - @SuppressWarnings("unchecked") public boolean tryAdvance(Consumer action) { int hi; if (action == null) throw new NullPointerException(); - Object[] tab = map.table; - hi = getFence(); - - if (!acceptedNull) { - acceptedNull = true; - if (map.nullKeyEntry != null) { - action.accept(map.nullKeyEntry.value); - if (map.modCount != expectedModCount) - throw new ConcurrentModificationException(); - return true; - } - } - if (tab.length >= hi && index >= 0) { + Node[] tab = map.table; + if (tab != null && tab.length >= (hi = getFence()) && index >= 0) { while (current != null || index < hi) { - if (current == null) { + if (current == null) current = tab[index++]; - if (current instanceof HashMap.TreeBin) { - current = ((HashMap.TreeBin)current).first; - } - } else { - HashMap.Entry entry; - if (current instanceof HashMap.Entry) { - entry = (Entry)current; - } else { - entry = (Entry)((TreeNode)current).entry; - } - V v = entry.value; - current = entry.next; + else { + V v = current.value; + current = current.next; action.accept(v); if (map.modCount != expectedModCount) throw new ConcurrentModificationException(); @@ -3003,57 +1636,33 @@ public class HashMap public EntrySpliterator trySplit() { int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; - if (lo >= mid || current != null) { - return null; - } else { - EntrySpliterator retVal = new EntrySpliterator(map, - lo, index = mid, est >>>= 1, expectedModCount); - // Only 'this' Spliterator chould check for null. - retVal.acceptedNull = true; - return retVal; - } + return (lo >= mid || current != null) ? null : + new EntrySpliterator(map, lo, index = mid, est >>>= 1, + expectedModCount); } - @SuppressWarnings("unchecked") public void forEachRemaining(Consumer> action) { int i, hi, mc; if (action == null) throw new NullPointerException(); HashMap m = map; - Object[] tab = m.table; + Node[] tab = m.table; if ((hi = fence) < 0) { mc = expectedModCount = m.modCount; - hi = fence = tab.length; + hi = fence = (tab == null) ? 0 : tab.length; } else mc = expectedModCount; - - if (!acceptedNull) { - acceptedNull = true; - if (m.nullKeyEntry != null) { - action.accept(m.nullKeyEntry); - } - } - if (tab.length >= hi && (i = index) >= 0 && - (i < (index = hi) || current != null)) { - Object p = current; + if (tab != null && tab.length >= hi && + (i = index) >= 0 && (i < (index = hi) || current != null)) { + Node p = current; current = null; do { - if (p == null) { + if (p == null) p = tab[i++]; - if (p instanceof HashMap.TreeBin) { - p = ((HashMap.TreeBin)p).first; - } - } else { - HashMap.Entry entry; - if (p instanceof HashMap.Entry) { - entry = (HashMap.Entry)p; - } else { - entry = (HashMap.Entry)((TreeNode)p).entry; - } - action.accept(entry); - p = entry.next; - + else { + action.accept(p); + p = p.next; } } while (p != null || i < hi); if (m.modCount != mc) @@ -3061,38 +1670,18 @@ public class HashMap } } - @SuppressWarnings("unchecked") public boolean tryAdvance(Consumer> action) { int hi; if (action == null) throw new NullPointerException(); - Object[] tab = map.table; - hi = getFence(); - - if (!acceptedNull) { - acceptedNull = true; - if (map.nullKeyEntry != null) { - action.accept(map.nullKeyEntry); - if (map.modCount != expectedModCount) - throw new ConcurrentModificationException(); - return true; - } - } - if (tab.length >= hi && index >= 0) { + Node[] tab = map.table; + if (tab != null && tab.length >= (hi = getFence()) && index >= 0) { while (current != null || index < hi) { - if (current == null) { + if (current == null) current = tab[index++]; - if (current instanceof HashMap.TreeBin) { - current = ((HashMap.TreeBin)current).first; - } - } else { - HashMap.Entry e; - if (current instanceof HashMap.Entry) { - e = (Entry)current; - } else { - e = (Entry)((TreeNode)current).entry; - } - current = e.next; + else { + Node e = current; + current = current.next; action.accept(e); if (map.modCount != expectedModCount) throw new ConcurrentModificationException(); @@ -3108,4 +1697,664 @@ public class HashMap Spliterator.DISTINCT; } } + + /* ------------------------------------------------------------ */ + // LinkedHashMap support + + + /* + * The following package-protected methods are designed to be + * overridden by LinkedHashMap, but not by any other subclass. + * Nearly all other internal methods are also package-protected + * but are declared final, so can be used by LinkedHashMap, view + * classes, and HashSet. + */ + + // Create a regular (non-tree) node + Node newNode(int hash, K key, V value, Node next) { + return new Node(hash, key, value, next); + } + + // For conversion from TreeNodes to plain nodes + Node replacementNode(Node p, Node next) { + return new Node(p.hash, p.key, p.value, next); + } + + // Create a tree bin node + TreeNode newTreeNode(int hash, K key, V value, Node next) { + return new TreeNode(hash, key, value, next); + } + + // For treeifyBin + TreeNode replacementTreeNode(Node p, Node next) { + return new TreeNode(p.hash, p.key, p.value, next); + } + + /** + * Reset to initial default state. Called by clone and readObject. + */ + void reinitialize() { + table = null; + entrySet = null; + keySet = null; + values = null; + modCount = 0; + threshold = 0; + size = 0; + } + + // Callbacks to allow LinkedHashMap post-actions + void afterNodeAccess(Node p) { } + void afterNodeInsertion(boolean evict) { } + void afterNodeRemoval(Node p) { } + + // Called only from writeObject, to ensure compatible ordering. + void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException { + Node[] tab; + if (size > 0 && (tab = table) != null) { + for (int i = 0; i < tab.length; ++i) { + for (Node e = tab[i]; e != null; e = e.next) { + s.writeObject(e.key); + s.writeObject(e.value); + } + } + } + } + + /* ------------------------------------------------------------ */ + // Tree bins + + /** + * Entry for Tree bins. Extends LinkedHashMap.Entry (which in turn + * extends Node) so can be used as extension of either regular or + * linked node. + */ + static final class TreeNode extends LinkedHashMap.Entry { + TreeNode parent; // red-black tree links + TreeNode left; + TreeNode right; + TreeNode prev; // needed to unlink next upon deletion + boolean red; + TreeNode(int hash, K key, V val, Node next) { + super(hash, key, val, next); + } + + /** + * Returns root of tree containing this node. + */ + final TreeNode root() { + for (TreeNode r = this, p;;) { + if ((p = r.parent) == null) + return r; + r = p; + } + } + + /** + * Ensures that the given root is the first node of its bin. + */ + static void moveRootToFront(Node[] tab, TreeNode root) { + int n; + if (root != null && tab != null && (n = tab.length) > 0) { + int index = (n - 1) & root.hash; + TreeNode first = (TreeNode)tab[index]; + if (root != first) { + Node rn; + tab[index] = root; + TreeNode rp = root.prev; + if ((rn = root.next) != null) + ((TreeNode)rn).prev = rp; + if (rp != null) + rp.next = rn; + if (first != null) + first.prev = root; + root.next = first; + root.prev = null; + } + assert checkInvariants(root); + } + } + + /** + * Finds the node starting at root p with the given hash and key. + * The kc argument caches comparableClassFor(key) upon first use + * comparing keys. + */ + final TreeNode find(int h, Object k, Class kc) { + TreeNode p = this; + do { + int ph, dir; K pk; + TreeNode pl = p.left, pr = p.right, q; + if ((ph = p.hash) > h) + p = pl; + else if (ph < h) + p = pr; + else if ((pk = p.key) == k || (k != null && k.equals(pk))) + return p; + else if (pl == null) + p = pr; + else if (pr == null) + p = pl; + else if ((kc != null || + (kc = comparableClassFor(k)) != null) && + (dir = compareComparables(kc, k, pk)) != 0) + p = (dir < 0) ? pl : pr; + else if ((q = pr.find(h, k, kc)) != null) + return q; + else + p = pl; + } while (p != null); + return null; + } + + /** + * Calls find for root node. + */ + final TreeNode getTreeNode(int h, Object k) { + return ((parent != null) ? root() : this).find(h, k, null); + } + + /** + * Tie-breaking utility for ordering insertions when equal + * hashCodes and non-comparable. We don't require a total + * order, just a consistent insertion rule to maintain + * equivalence across rebalancings. Tie-breaking further than + * necessary simplifies testing a bit. + */ + static int tieBreakOrder(Object a, Object b) { + int d; + if (a == null || b == null || + (d = a.getClass().getName(). + compareTo(b.getClass().getName())) == 0) + d = (System.identityHashCode(a) <= System.identityHashCode(b) ? + -1 : 1); + return d; + } + + /** + * Forms tree of the nodes linked from this node. + * @return root of tree + */ + final void treeify(Node[] tab) { + TreeNode root = null; + for (TreeNode x = this, next; x != null; x = next) { + next = (TreeNode)x.next; + x.left = x.right = null; + if (root == null) { + x.parent = null; + x.red = false; + root = x; + } + else { + K k = x.key; + int h = x.hash; + Class kc = null; + for (TreeNode p = root;;) { + int dir, ph; + K pk = p.key; + if ((ph = p.hash) > h) + dir = -1; + else if (ph < h) + dir = 1; + else if ((kc == null && + (kc = comparableClassFor(k)) == null) || + (dir = compareComparables(kc, k, pk)) == 0) + dir = tieBreakOrder(k, pk); + + TreeNode xp = p; + if ((p = (dir <= 0) ? p.left : p.right) == null) { + x.parent = xp; + if (dir <= 0) + xp.left = x; + else + xp.right = x; + root = balanceInsertion(root, x); + break; + } + } + } + } + moveRootToFront(tab, root); + } + + /** + * Returns a list of non-TreeNodes replacing those linked from + * this node. + */ + final Node untreeify(HashMap map) { + Node hd = null, tl = null; + for (Node q = this; q != null; q = q.next) { + Node p = map.replacementNode(q, null); + if (tl == null) + hd = p; + else + tl.next = p; + tl = p; + } + return hd; + } + + /** + * Tree version of putVal. + */ + final TreeNode putTreeVal(HashMap map, Node[] tab, + int h, K k, V v) { + Class kc = null; + boolean searched = false; + TreeNode root = (parent != null) ? root() : this; + for (TreeNode p = root;;) { + int dir, ph; K pk; + if ((ph = p.hash) > h) + dir = -1; + else if (ph < h) + dir = 1; + else if ((pk = p.key) == k || (pk != null && k.equals(pk))) + return p; + else if ((kc == null && + (kc = comparableClassFor(k)) == null) || + (dir = compareComparables(kc, k, pk)) == 0) { + if (!searched) { + TreeNode q, ch; + searched = true; + if (((ch = p.left) != null && + (q = ch.find(h, k, kc)) != null) || + ((ch = p.right) != null && + (q = ch.find(h, k, kc)) != null)) + return q; + } + dir = tieBreakOrder(k, pk); + } + + TreeNode xp = p; + if ((p = (dir <= 0) ? p.left : p.right) == null) { + Node xpn = xp.next; + TreeNode x = map.newTreeNode(h, k, v, xpn); + if (dir <= 0) + xp.left = x; + else + xp.right = x; + xp.next = x; + x.parent = x.prev = xp; + if (xpn != null) + ((TreeNode)xpn).prev = x; + moveRootToFront(tab, balanceInsertion(root, x)); + return null; + } + } + } + + /** + * Removes the given node, that must be present before this call. + * This is messier than typical red-black deletion code because we + * cannot swap the contents of an interior node with a leaf + * successor that is pinned by "next" pointers that are accessible + * independently during traversal. So instead we swap the tree + * linkages. If the current tree appears to have too few nodes, + * the bin is converted back to a plain bin. (The test triggers + * somewhere between 2 and 6 nodes, depending on tree structure). + */ + final void removeTreeNode(HashMap map, Node[] tab, + boolean movable) { + int n; + if (tab == null || (n = tab.length) == 0) + return; + int index = (n - 1) & hash; + TreeNode first = (TreeNode)tab[index], root = first, rl; + TreeNode succ = (TreeNode)next, pred = prev; + if (pred == null) + tab[index] = first = succ; + else + pred.next = succ; + if (succ != null) + succ.prev = pred; + if (first == null) + return; + if (root.parent != null) + root = root.root(); + if (root == null || root.right == null || + (rl = root.left) == null || rl.left == null) { + tab[index] = first.untreeify(map); // too small + return; + } + TreeNode p = this, pl = left, pr = right, replacement; + if (pl != null && pr != null) { + TreeNode s = pr, sl; + while ((sl = s.left) != null) // find successor + s = sl; + boolean c = s.red; s.red = p.red; p.red = c; // swap colors + TreeNode sr = s.right; + TreeNode pp = p.parent; + if (s == pr) { // p was s's direct parent + p.parent = s; + s.right = p; + } + else { + TreeNode sp = s.parent; + if ((p.parent = sp) != null) { + if (s == sp.left) + sp.left = p; + else + sp.right = p; + } + if ((s.right = pr) != null) + pr.parent = s; + } + p.left = null; + if ((p.right = sr) != null) + sr.parent = p; + if ((s.left = pl) != null) + pl.parent = s; + if ((s.parent = pp) == null) + root = s; + else if (p == pp.left) + pp.left = s; + else + pp.right = s; + if (sr != null) + replacement = sr; + else + replacement = p; + } + else if (pl != null) + replacement = pl; + else if (pr != null) + replacement = pr; + else + replacement = p; + if (replacement != p) { + TreeNode pp = replacement.parent = p.parent; + if (pp == null) + root = replacement; + else if (p == pp.left) + pp.left = replacement; + else + pp.right = replacement; + p.left = p.right = p.parent = null; + } + + TreeNode r = p.red ? root : balanceDeletion(root, replacement); + + if (replacement == p) { // detach + TreeNode pp = p.parent; + p.parent = null; + if (pp != null) { + if (p == pp.left) + pp.left = null; + else if (p == pp.right) + pp.right = null; + } + } + if (movable) + moveRootToFront(tab, r); + } + + /** + * Splits nodes in a tree bin into lower and upper tree bins, + * or untreeifies if now too small. Called only from resize; + * see above discussion about split bits and indices. + * + * @param map the map + * @param tab the table for recording bin heads + * @param index the index of the table being split + * @param bit the bit of hash to split on + */ + final void split(HashMap map, Node[] tab, int index, int bit) { + TreeNode b = this; + // Relink into lo and hi lists, preserving order + TreeNode loHead = null, loTail = null; + TreeNode hiHead = null, hiTail = null; + int lc = 0, hc = 0; + for (TreeNode e = b, next; e != null; e = next) { + next = (TreeNode)e.next; + e.next = null; + if ((e.hash & bit) == 0) { + if ((e.prev = loTail) == null) + loHead = e; + else + loTail.next = e; + loTail = e; + ++lc; + } + else { + if ((e.prev = hiTail) == null) + hiHead = e; + else + hiTail.next = e; + hiTail = e; + ++hc; + } + } + + if (loHead != null) { + if (lc <= UNTREEIFY_THRESHOLD) + tab[index] = loHead.untreeify(map); + else { + tab[index] = loHead; + if (hiHead != null) // (else is already treeified) + loHead.treeify(tab); + } + } + if (hiHead != null) { + if (hc <= UNTREEIFY_THRESHOLD) + tab[index + bit] = hiHead.untreeify(map); + else { + tab[index + bit] = hiHead; + if (loHead != null) + hiHead.treeify(tab); + } + } + } + + /* ------------------------------------------------------------ */ + // Red-black tree methods, all adapted from CLR + + static TreeNode rotateLeft(TreeNode root, + TreeNode p) { + TreeNode r, pp, rl; + if (p != null && (r = p.right) != null) { + if ((rl = p.right = r.left) != null) + rl.parent = p; + if ((pp = r.parent = p.parent) == null) + (root = r).red = false; + else if (pp.left == p) + pp.left = r; + else + pp.right = r; + r.left = p; + p.parent = r; + } + return root; + } + + static TreeNode rotateRight(TreeNode root, + TreeNode p) { + TreeNode l, pp, lr; + if (p != null && (l = p.left) != null) { + if ((lr = p.left = l.right) != null) + lr.parent = p; + if ((pp = l.parent = p.parent) == null) + (root = l).red = false; + else if (pp.right == p) + pp.right = l; + else + pp.left = l; + l.right = p; + p.parent = l; + } + return root; + } + + static TreeNode balanceInsertion(TreeNode root, + TreeNode x) { + x.red = true; + for (TreeNode xp, xpp, xppl, xppr;;) { + if ((xp = x.parent) == null) { + x.red = false; + return x; + } + else if (!xp.red || (xpp = xp.parent) == null) + return root; + if (xp == (xppl = xpp.left)) { + if ((xppr = xpp.right) != null && xppr.red) { + xppr.red = false; + xp.red = false; + xpp.red = true; + x = xpp; + } + else { + if (x == xp.right) { + root = rotateLeft(root, x = xp); + xpp = (xp = x.parent) == null ? null : xp.parent; + } + if (xp != null) { + xp.red = false; + if (xpp != null) { + xpp.red = true; + root = rotateRight(root, xpp); + } + } + } + } + else { + if (xppl != null && xppl.red) { + xppl.red = false; + xp.red = false; + xpp.red = true; + x = xpp; + } + else { + if (x == xp.left) { + root = rotateRight(root, x = xp); + xpp = (xp = x.parent) == null ? null : xp.parent; + } + if (xp != null) { + xp.red = false; + if (xpp != null) { + xpp.red = true; + root = rotateLeft(root, xpp); + } + } + } + } + } + } + + static TreeNode balanceDeletion(TreeNode root, + TreeNode x) { + for (TreeNode xp, xpl, xpr;;) { + if (x == null || x == root) + return root; + else if ((xp = x.parent) == null) { + x.red = false; + return x; + } + else if (x.red) { + x.red = false; + return root; + } + else if ((xpl = xp.left) == x) { + if ((xpr = xp.right) != null && xpr.red) { + xpr.red = false; + xp.red = true; + root = rotateLeft(root, xp); + xpr = (xp = x.parent) == null ? null : xp.right; + } + if (xpr == null) + x = xp; + else { + TreeNode sl = xpr.left, sr = xpr.right; + if ((sr == null || !sr.red) && + (sl == null || !sl.red)) { + xpr.red = true; + x = xp; + } + else { + if (sr == null || !sr.red) { + if (sl != null) + sl.red = false; + xpr.red = true; + root = rotateRight(root, xpr); + xpr = (xp = x.parent) == null ? + null : xp.right; + } + if (xpr != null) { + xpr.red = (xp == null) ? false : xp.red; + if ((sr = xpr.right) != null) + sr.red = false; + } + if (xp != null) { + xp.red = false; + root = rotateLeft(root, xp); + } + x = root; + } + } + } + else { // symmetric + if (xpl != null && xpl.red) { + xpl.red = false; + xp.red = true; + root = rotateRight(root, xp); + xpl = (xp = x.parent) == null ? null : xp.left; + } + if (xpl == null) + x = xp; + else { + TreeNode sl = xpl.left, sr = xpl.right; + if ((sl == null || !sl.red) && + (sr == null || !sr.red)) { + xpl.red = true; + x = xp; + } + else { + if (sl == null || !sl.red) { + if (sr != null) + sr.red = false; + xpl.red = true; + root = rotateLeft(root, xpl); + xpl = (xp = x.parent) == null ? + null : xp.left; + } + if (xpl != null) { + xpl.red = (xp == null) ? false : xp.red; + if ((sl = xpl.left) != null) + sl.red = false; + } + if (xp != null) { + xp.red = false; + root = rotateRight(root, xp); + } + x = root; + } + } + } + } + } + + /** + * Recursive invariant check + */ + static boolean checkInvariants(TreeNode t) { + TreeNode tp = t.parent, tl = t.left, tr = t.right, + tb = t.prev, tn = (TreeNode)t.next; + if (tb != null && tb.next != t) + return false; + if (tn != null && tn.prev != t) + return false; + if (tp != null && t != tp.left && t != tp.right) + return false; + if (tl != null && (tl.parent != t || tl.hash > t.hash)) + return false; + if (tr != null && (tr.parent != t || tr.hash < t.hash)) + return false; + if (t.red && tl != null && tl.red && tr != null && tr.red) + return false; + if (tl != null && !checkInvariants(tl)) + return false; + if (tr != null && !checkInvariants(tr)) + return false; + return true; + } + } + } diff --git a/jdk/src/share/classes/java/util/LinkedHashMap.java b/jdk/src/share/classes/java/util/LinkedHashMap.java index feb1005b2aa..0e4fc73f0df 100644 --- a/jdk/src/share/classes/java/util/LinkedHashMap.java +++ b/jdk/src/share/classes/java/util/LinkedHashMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,9 +24,12 @@ */ package java.util; -import java.io.*; + +import java.util.function.Consumer; import java.util.function.BiConsumer; import java.util.function.BiFunction; +import java.io.Serializable; +import java.io.IOException; /** *

    Hash table and linked list implementation of the Map interface, @@ -57,9 +60,9 @@ import java.util.function.BiFunction; * order they were presented.) * *

    A special {@link #LinkedHashMap(int,float,boolean) constructor} is - * provided to create a LinkedHashMap whose order of iteration is the - * order in which its entries were last accessed, from least-recently accessed - * to most-recently (access-order). This kind of map is well-suited to + * provided to create a linked hash map whose order of iteration is the order + * in which its entries were last accessed, from least-recently accessed to + * most-recently (access-order). This kind of map is well-suited to * building LRU caches. Invoking the put or get method * results in an access to the corresponding entry (assuming it exists after * the invocation completes). The putAll method generates one entry @@ -155,18 +158,53 @@ import java.util.function.BiFunction; * @see Hashtable * @since 1.4 */ - public class LinkedHashMap extends HashMap implements Map { + /* + * Implementation note. A previous version of this class was + * internally structured a little differently. Because superclass + * HashMap now uses trees for some of its nodes, class + * LinkedHashMap.Entry is now treated as intermediary node class + * that can also be converted to tree form. The name of this + * class, LinkedHashMap.Entry, is confusing in several ways in its + * current context, but cannot be changed. Otherwise, even though + * it is not exported outside this package, some existing source + * code is known to have relied on a symbol resolution corner case + * rule in calls to removeEldestEntry that suppressed compilation + * errors due to ambiguous usages. So, we keep the name to + * preserve unmodified compilability. + * + * The changes in node classes also require using two fields + * (head, tail) rather than a pointer to a header node to maintain + * the doubly-linked before/after list. This class also + * previously used a different style of callback methods upon + * access, insertion, and removal. + */ + + /** + * HashMap.Node subclass for normal LinkedHashMap entries. + */ + static class Entry extends HashMap.Node { + Entry before, after; + Entry(int hash, K key, V value, Node next) { + super(hash, key, value, next); + } + } + private static final long serialVersionUID = 3801124242820219131L; /** - * The head of the doubly linked list. + * The head (eldest) of the doubly linked list. */ - private transient Entry header; + transient LinkedHashMap.Entry head; + + /** + * The tail (youngest) of the doubly linked list. + */ + transient LinkedHashMap.Entry tail; /** * The iteration ordering method for this linked hash map: true @@ -174,7 +212,125 @@ public class LinkedHashMap * * @serial */ - private final boolean accessOrder; + final boolean accessOrder; + + // internal utilities + + // link at the end of list + private void linkNodeLast(LinkedHashMap.Entry p) { + LinkedHashMap.Entry last = tail; + tail = p; + if (last == null) + head = p; + else { + p.before = last; + last.after = p; + } + } + + // apply src's links to dst + private void transferLinks(LinkedHashMap.Entry src, + LinkedHashMap.Entry dst) { + LinkedHashMap.Entry b = dst.before = src.before; + LinkedHashMap.Entry a = dst.after = src.after; + if (b == null) + head = dst; + else + b.after = dst; + if (a == null) + tail = dst; + else + a.before = dst; + } + + // overrides of HashMap hook methods + + void reinitialize() { + super.reinitialize(); + head = tail = null; + } + + Node newNode(int hash, K key, V value, Node e) { + LinkedHashMap.Entry p = + new LinkedHashMap.Entry(hash, key, value, e); + linkNodeLast(p); + return p; + } + + Node replacementNode(Node p, Node next) { + LinkedHashMap.Entry q = (LinkedHashMap.Entry)p; + LinkedHashMap.Entry t = + new LinkedHashMap.Entry(q.hash, q.key, q.value, next); + transferLinks(q, t); + return t; + } + + TreeNode newTreeNode(int hash, K key, V value, Node next) { + TreeNode p = new TreeNode(hash, key, value, next); + linkNodeLast(p); + return p; + } + + TreeNode replacementTreeNode(Node p, Node next) { + LinkedHashMap.Entry q = (LinkedHashMap.Entry)p; + TreeNode t = new TreeNode(q.hash, q.key, q.value, next); + transferLinks(q, t); + return t; + } + + void afterNodeRemoval(Node e) { // unlink + LinkedHashMap.Entry p = + (LinkedHashMap.Entry)e, b = p.before, a = p.after; + p.before = p.after = null; + if (b == null) + head = a; + else + b.after = a; + if (a == null) + tail = b; + else + a.before = b; + } + + void afterNodeInsertion(boolean evict) { // possibly remove eldest + LinkedHashMap.Entry first; + if (evict && (first = head) != null && removeEldestEntry(first)) { + K key = first.key; + removeNode(hash(key), key, null, false, true); + } + } + + void afterNodeAccess(Node e) { // move node to last + LinkedHashMap.Entry last; + if (accessOrder && (last = tail) != e) { + LinkedHashMap.Entry p = + (LinkedHashMap.Entry)e, b = p.before, a = p.after; + p.after = null; + if (b == null) + head = a; + else + b.after = a; + if (a != null) + a.before = b; + else + last = b; + if (last == null) + head = p; + else { + p.before = last; + last.after = p; + } + tail = p; + ++modCount; + } + } + + void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException { + for (LinkedHashMap.Entry e = head; e != null; e = e.after) { + s.writeObject(e.key); + s.writeObject(e.value); + } + } /** * Constructs an empty insertion-ordered LinkedHashMap instance @@ -221,8 +377,9 @@ public class LinkedHashMap * @throws NullPointerException if the specified map is null */ public LinkedHashMap(Map m) { - super(m); + super(); accessOrder = false; + putMapEntries(m, false); } /** @@ -243,16 +400,6 @@ public class LinkedHashMap this.accessOrder = accessOrder; } - /** - * Called by superclass constructors and pseudoconstructors (clone, - * readObject) before any entries are inserted into the map. Initializes - * the chain. - */ - @Override - void init() { - header = new Entry<>(-1, null, null, null); - header.before = header.after = header; - } /** * Returns true if this map maps one or more keys to the @@ -263,15 +410,10 @@ public class LinkedHashMap * specified value */ public boolean containsValue(Object value) { - // Overridden to take advantage of faster iterator - if (value==null) { - for (Entry e = header.after; e != header; e = e.after) - if (e.value==null) - return true; - } else { - for (Entry e = header.after; e != header; e = e.after) - if (value.equals(e.value)) - return true; + for (LinkedHashMap.Entry e = head; e != null; e = e.after) { + V v = e.value; + if (v == value || (value != null && value.equals(v))) + return true; } return false; } @@ -292,10 +434,11 @@ public class LinkedHashMap * distinguish these two cases. */ public V get(Object key) { - Entry e = (Entry)getEntry(key); - if (e == null) + Node e; + if ((e = getNode(hash(key), key)) == null) return null; - e.recordAccess(this); + if (accessOrder) + afterNodeAccess(e); return e.value; } @@ -305,163 +448,7 @@ public class LinkedHashMap */ public void clear() { super.clear(); - header.before = header.after = header; - } - - @Override - public void forEach(BiConsumer action) { - Objects.requireNonNull(action); - int expectedModCount = modCount; - for (Entry entry = header.after; entry != header; entry = entry.after) { - action.accept(entry.key, entry.value); - - if (expectedModCount != modCount) { - throw new ConcurrentModificationException(); - } - } - } - - @Override - public void replaceAll(BiFunction function) { - Objects.requireNonNull(function); - int expectedModCount = modCount; - for (Entry entry = header.after; entry != header; entry = entry.after) { - entry.value = function.apply(entry.key, entry.value); - - if (expectedModCount != modCount) { - throw new ConcurrentModificationException(); - } - } - } - - /** - * LinkedHashMap entry. - */ - private static class Entry extends HashMap.Entry { - // These fields comprise the doubly linked list used for iteration. - Entry before, after; - - Entry(int hash, K key, V value, Object next) { - super(hash, key, value, next); - } - - /** - * Removes this entry from the linked list. - */ - private void remove() { - before.after = after; - after.before = before; - } - - /** - * Inserts this entry before the specified existing entry in the list. - */ - private void addBefore(Entry existingEntry) { - after = existingEntry; - before = existingEntry.before; - before.after = this; - after.before = this; - } - - /** - * This method is invoked by the superclass whenever the value - * of a pre-existing entry is read by Map.get or modified by Map.put. - * If the enclosing Map is access-ordered, it moves the entry - * to the end of the list; otherwise, it does nothing. - */ - void recordAccess(HashMap m) { - LinkedHashMap lm = (LinkedHashMap)m; - if (lm.accessOrder) { - lm.modCount++; - remove(); - addBefore(lm.header); - } - } - - void recordRemoval(HashMap m) { - remove(); - } - } - - private abstract class LinkedHashIterator implements Iterator { - Entry nextEntry = header.after; - Entry lastReturned = null; - - /** - * The modCount value that the iterator believes that the backing - * List should have. If this expectation is violated, the iterator - * has detected concurrent modification. - */ - int expectedModCount = modCount; - - public boolean hasNext() { - return nextEntry != header; - } - - public void remove() { - if (lastReturned == null) - throw new IllegalStateException(); - if (modCount != expectedModCount) - throw new ConcurrentModificationException(); - - LinkedHashMap.this.remove(lastReturned.key); - lastReturned = null; - expectedModCount = modCount; - } - - Entry nextEntry() { - if (modCount != expectedModCount) - throw new ConcurrentModificationException(); - if (nextEntry == header) - throw new NoSuchElementException(); - - Entry e = lastReturned = nextEntry; - nextEntry = e.after; - return e; - } - } - - private class KeyIterator extends LinkedHashIterator { - public K next() { return nextEntry().getKey(); } - } - - private class ValueIterator extends LinkedHashIterator { - public V next() { return nextEntry().value; } - } - - private class EntryIterator extends LinkedHashIterator> { - public Map.Entry next() { return nextEntry(); } - } - - // These Overrides alter the behavior of superclass view iterator() methods - Iterator newKeyIterator() { return new KeyIterator(); } - Iterator newValueIterator() { return new ValueIterator(); } - Iterator> newEntryIterator() { return new EntryIterator(); } - - /** - * This override alters behavior of superclass put method. It causes newly - * allocated entry to get inserted at the end of the linked list and - * removes the eldest entry if appropriate. - */ - @Override - void addEntry(int hash, K key, V value, int bucketIndex, boolean checkIfNeedTree) { - super.addEntry(hash, key, value, bucketIndex, checkIfNeedTree); - - // Remove eldest entry if instructed - Entry eldest = header.after; - if (removeEldestEntry(eldest)) { - removeEntryForKey(eldest.key); - } - } - - /* - * Create a new LinkedHashMap.Entry and setup the before/after pointers - */ - @Override - HashMap.Entry newEntry(int hash, K key, V value, Object next) { - Entry newEntry = new Entry<>(hash, key, value, next); - newEntry.addBefore(header); - return newEntry; + head = tail = null; } /** @@ -475,13 +462,13 @@ public class LinkedHashMap *

    Sample use: this override will allow the map to grow up to 100 * entries and then delete the eldest entry each time a new entry is * added, maintaining a steady state of 100 entries. - *

    {@code
    +     * 
          *     private static final int MAX_ENTRIES = 100;
          *
          *     protected boolean removeEldestEntry(Map.Entry eldest) {
    -     *        return size() > MAX_ENTRIES;
    +     *        return size() > MAX_ENTRIES;
          *     }
    -     * }
    + *
    * *

    This method typically does not modify the map in any way, * instead allowing the map to modify itself as directed by its @@ -508,4 +495,241 @@ public class LinkedHashMap protected boolean removeEldestEntry(Map.Entry eldest) { return false; } + + /** + * Returns a {@link Set} view of the keys contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. If the map is modified + * while an iteration over the set is in progress (except through + * the iterator's own remove operation), the results of + * the iteration are undefined. The set supports element removal, + * which removes the corresponding mapping from the map, via the + * Iterator.remove, Set.remove, + * removeAll, retainAll, and clear + * operations. It does not support the add or addAll + * operations. + * Its {@link Spliterator} typically provides faster sequential + * performance but much poorer parallel performance than that of + * {@code HashMap}. + * + * @return a set view of the keys contained in this map + */ + public Set keySet() { + Set ks; + return (ks = keySet) == null ? (keySet = new LinkedKeySet()) : ks; + } + + final class LinkedKeySet extends AbstractSet { + public final int size() { return size; } + public final void clear() { LinkedHashMap.this.clear(); } + public final Iterator iterator() { + return new LinkedKeyIterator(); + } + public final boolean contains(Object o) { return containsKey(o); } + public final boolean remove(Object key) { + return removeNode(hash(key), key, null, false, true) != null; + } + public final Spliterator spliterator() { + return Spliterators.spliterator(this, Spliterator.SIZED | + Spliterator.ORDERED | + Spliterator.DISTINCT); + } + public final void forEach(Consumer action) { + if (action == null) + throw new NullPointerException(); + int mc = modCount; + for (LinkedHashMap.Entry e = head; e != null; e = e.after) + action.accept(e.key); + if (modCount != mc) + throw new ConcurrentModificationException(); + } + } + + /** + * Returns a {@link Collection} view of the values contained in this map. + * The collection is backed by the map, so changes to the map are + * reflected in the collection, and vice-versa. If the map is + * modified while an iteration over the collection is in progress + * (except through the iterator's own remove operation), + * the results of the iteration are undefined. The collection + * supports element removal, which removes the corresponding + * mapping from the map, via the Iterator.remove, + * Collection.remove, removeAll, + * retainAll and clear operations. It does not + * support the add or addAll operations. + * Its {@link Spliterator} typically provides faster sequential + * performance but much poorer parallel performance than that of + * {@code HashMap}. + * + * @return a view of the values contained in this map + */ + public Collection values() { + Collection vs; + return (vs = values) == null ? (values = new LinkedValues()) : vs; + } + + final class LinkedValues extends AbstractCollection { + public final int size() { return size; } + public final void clear() { LinkedHashMap.this.clear(); } + public final Iterator iterator() { + return new LinkedValueIterator(); + } + public final boolean contains(Object o) { return containsValue(o); } + public final Spliterator spliterator() { + return Spliterators.spliterator(this, Spliterator.SIZED | + Spliterator.ORDERED); + } + public final void forEach(Consumer action) { + if (action == null) + throw new NullPointerException(); + int mc = modCount; + for (LinkedHashMap.Entry e = head; e != null; e = e.after) + action.accept(e.value); + if (modCount != mc) + throw new ConcurrentModificationException(); + } + } + + /** + * Returns a {@link Set} view of the mappings contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. If the map is modified + * while an iteration over the set is in progress (except through + * the iterator's own remove operation, or through the + * setValue operation on a map entry returned by the + * iterator) the results of the iteration are undefined. The set + * supports element removal, which removes the corresponding + * mapping from the map, via the Iterator.remove, + * Set.remove, removeAll, retainAll and + * clear operations. It does not support the + * add or addAll operations. + * Its {@link Spliterator} typically provides faster sequential + * performance but much poorer parallel performance than that of + * {@code HashMap}. + * + * @return a set view of the mappings contained in this map + */ + public Set> entrySet() { + Set> es; + return (es = entrySet) == null ? (entrySet = new LinkedEntrySet()) : es; + } + + final class LinkedEntrySet extends AbstractSet> { + public final int size() { return size; } + public final void clear() { LinkedHashMap.this.clear(); } + public final Iterator> iterator() { + return new LinkedEntryIterator(); + } + public final boolean contains(Object o) { + if (!(o instanceof Map.Entry)) + return false; + Map.Entry e = (Map.Entry) o; + Object key = e.getKey(); + Node candidate = getNode(hash(key), key); + return candidate != null && candidate.equals(e); + } + public final boolean remove(Object o) { + if (o instanceof Map.Entry) { + Map.Entry e = (Map.Entry) o; + Object key = e.getKey(); + Object value = e.getValue(); + return removeNode(hash(key), key, value, true, true) != null; + } + return false; + } + public final Spliterator> spliterator() { + return Spliterators.spliterator(this, Spliterator.SIZED | + Spliterator.ORDERED | + Spliterator.DISTINCT); + } + public final void forEach(Consumer> action) { + if (action == null) + throw new NullPointerException(); + int mc = modCount; + for (LinkedHashMap.Entry e = head; e != null; e = e.after) + action.accept(e); + if (modCount != mc) + throw new ConcurrentModificationException(); + } + } + + // Map overrides + + public void forEach(BiConsumer action) { + if (action == null) + throw new NullPointerException(); + int mc = modCount; + for (LinkedHashMap.Entry e = head; e != null; e = e.after) + action.accept(e.key, e.value); + if (modCount != mc) + throw new ConcurrentModificationException(); + } + + public void replaceAll(BiFunction function) { + if (function == null) + throw new NullPointerException(); + int mc = modCount; + for (LinkedHashMap.Entry e = head; e != null; e = e.after) + e.value = function.apply(e.key, e.value); + if (modCount != mc) + throw new ConcurrentModificationException(); + } + + // Iterators + + abstract class LinkedHashIterator { + LinkedHashMap.Entry next; + LinkedHashMap.Entry current; + int expectedModCount; + + LinkedHashIterator() { + next = head; + expectedModCount = modCount; + current = null; + } + + public final boolean hasNext() { + return next != null; + } + + final LinkedHashMap.Entry nextNode() { + LinkedHashMap.Entry e = next; + if (modCount != expectedModCount) + throw new ConcurrentModificationException(); + if (e == null) + throw new NoSuchElementException(); + current = e; + next = e.after; + return e; + } + + public final void remove() { + Node p = current; + if (p == null) + throw new IllegalStateException(); + if (modCount != expectedModCount) + throw new ConcurrentModificationException(); + current = null; + K key = p.key; + removeNode(hash(key), key, null, false, false); + expectedModCount = modCount; + } + } + + final class LinkedKeyIterator extends LinkedHashIterator + implements Iterator { + public final K next() { return nextNode().getKey(); } + } + + final class LinkedValueIterator extends LinkedHashIterator + implements Iterator { + public final V next() { return nextNode().value; } + } + + final class LinkedEntryIterator extends LinkedHashIterator + implements Iterator> { + public final Map.Entry next() { return nextNode(); } + } + + } diff --git a/jdk/test/java/lang/reflect/Generics/Probe.java b/jdk/test/java/lang/reflect/Generics/Probe.java index 1cdd5af3bdd..ebd98465e0c 100644 --- a/jdk/test/java/lang/reflect/Generics/Probe.java +++ b/jdk/test/java/lang/reflect/Generics/Probe.java @@ -50,9 +50,9 @@ import static java.util.Arrays.*; "java.util.HashMap$EntryIterator", "java.util.HashMap$KeyIterator", "java.util.HashMap$ValueIterator", - "java.util.LinkedHashMap$EntryIterator", - "java.util.LinkedHashMap$KeyIterator", - "java.util.LinkedHashMap$ValueIterator"}) + "java.util.LinkedHashMap$LinkedEntryIterator", + "java.util.LinkedHashMap$LinkedKeyIterator", + "java.util.LinkedHashMap$LinkedValueIterator"}) public class Probe { public static void main (String... args) throws Throwable { Classes classesAnnotation = (Probe.class).getAnnotation(Classes.class); diff --git a/jdk/test/java/util/Map/CheckRandomHashSeed.java b/jdk/test/java/util/Map/CheckRandomHashSeed.java index 5395ec999ee..2acf1bc8c9c 100644 --- a/jdk/test/java/util/Map/CheckRandomHashSeed.java +++ b/jdk/test/java/util/Map/CheckRandomHashSeed.java @@ -53,8 +53,6 @@ public class CheckRandomHashSeed { throw new Error("Error in test setup: " + (expectRandom ? "" : "not " ) + "expecting random hashSeed, but " + PROP_NAME + " is " + (propSet ? "" : "not ") + "enabled"); } - testMap(new HashMap()); - testMap(new LinkedHashMap()); testMap(new WeakHashMap()); testMap(new Hashtable()); } diff --git a/jdk/test/java/util/Map/InPlaceOpsCollisions.java b/jdk/test/java/util/Map/InPlaceOpsCollisions.java index 4a755bd4415..e24ba6ac508 100644 --- a/jdk/test/java/util/Map/InPlaceOpsCollisions.java +++ b/jdk/test/java/util/Map/InPlaceOpsCollisions.java @@ -25,7 +25,6 @@ * @test * @bug 8005698 * @run main InPlaceOpsCollisions -shortrun - * @run main/othervm -Djdk.map.randomseed=true InPlaceOpsCollisions -shortrun * @summary Ensure overrides of in-place operations in Maps behave well with lots of collisions. * @author Brent Christian */ diff --git a/jdk/test/java/util/Map/MapBinToFromTreeTest.java b/jdk/test/java/util/Map/MapBinToFromTreeTest.java new file mode 100644 index 00000000000..0b40a4ef16e --- /dev/null +++ b/jdk/test/java/util/Map/MapBinToFromTreeTest.java @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiConsumer; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.testng.Assert.assertEquals; + +/* + * @test + * @bug 8023463 + * @summary Test the case where a bin is treeified and vice verser + * @run testng MapBinToFromTreeTest + */ + +@Test +public class MapBinToFromTreeTest { + + // Initial capacity of map + // Should be >= the map capacity for treeifiying, see HashMap/ConcurrentMap.MIN_TREEIFY_CAPACITY + static final int INITIAL_CAPACITY = 64; + + // Maximum size of map + // Should be > the treeify threshold, see HashMap/ConcurrentMap.TREEIFY_THRESHOLD + // Should be > INITIAL_CAPACITY to ensure resize occurs + static final int SIZE = 256; + + // Load factor of map + // A value 1.0 will ensure that a new threshold == capacity + static final float LOAD_FACTOR = 1.0f; + + @DataProvider(name = "maps") + static Object[][] mapProvider() { + return new Object[][] { + // Pass in the class name as a description for test reporting + // purposes + { HashMap.class.getName(), new HashMap(INITIAL_CAPACITY, LOAD_FACTOR) }, + { LinkedHashMap.class.getName(), new LinkedHashMap(INITIAL_CAPACITY, LOAD_FACTOR) }, + { ConcurrentHashMap.class.getName(), new ConcurrentHashMap(INITIAL_CAPACITY, LOAD_FACTOR) }, + }; + } + + @Test(dataProvider = "maps") + public void testPutThenGet(String d, Map m) { + put(SIZE, m, (i, s) -> { + for (int j = 0; j < s; j++) { + assertEquals(m.get(new HashCodeInteger(j)).intValue(), j, + String.format("Map.get(%d)", j)); + } + }); + } + + @Test(dataProvider = "maps") + public void testPutThenTraverse(String d, Map m) { + Collector> c = getCollector(m); + + put(SIZE, m, (i, s) -> { + // Note that it is OK to collect to a Set (HashSet) as long as + // integer values are used since these tests only check for + // collisions and other tests will verify more general functionality + Collection actual = m.keySet().stream().map(e -> e.value).collect(c); + Collection expected = IntStream.range(0, s).boxed().collect(c); + assertEquals(actual, expected, "Map.keySet()"); + }); + } + + @Test(dataProvider = "maps") + public void testRemoveThenGet(String d, Map m) { + put(SIZE, m, (i, s) -> { }); + + remove(m, (i, s) -> { + for (int j = i + 1; j < SIZE; j++) { + assertEquals(m.get(new HashCodeInteger(j)).intValue(), j, + String.format("Map.get(%d)", j)); + } + }); + } + + @Test(dataProvider = "maps") + public void testRemoveThenTraverse(String d, Map m) { + put(SIZE, m, (i, s) -> { }); + + Collector> c = getCollector(m); + + remove(m, (i, s) -> { + Collection actual = m.keySet().stream().map(e -> e.value).collect(c); + Collection expected = IntStream.range(i + 1, SIZE).boxed().collect(c); + assertEquals(actual, expected, "Map.keySet()"); + }); + } + + @Test(dataProvider = "maps") + public void testUntreeifyOnResizeWithGet(String d, Map m) { + // Fill the map with 64 entries grouped into 4 buckets + put(INITIAL_CAPACITY, m, (i, s) -> { }); + + for (int i = INITIAL_CAPACITY; i < SIZE; i++) { + // Add further entries in the 0'th bucket so as not to disturb + // other buckets, entries of which may be distributed and/or + // the bucket untreeified on resize + m.put(new HashCodeInteger(i, 0), i); + + for (int j = 0; j < INITIAL_CAPACITY; j++) { + assertEquals(m.get(new HashCodeInteger(j)).intValue(), j, + String.format("Map.get(%d) < INITIAL_CAPACITY", j)); + } + for (int j = INITIAL_CAPACITY; j <= i; j++) { + assertEquals(m.get(new HashCodeInteger(j, 0)).intValue(), j, + String.format("Map.get(%d) >= INITIAL_CAPACITY", j)); + } + } + } + + @Test(dataProvider = "maps") + public void testUntreeifyOnResizeWithTraverse(String d, Map m) { + // Fill the map with 64 entries grouped into 4 buckets + put(INITIAL_CAPACITY, m, (i, s) -> { }); + + Collector> c = getCollector(m); + + for (int i = INITIAL_CAPACITY; i < SIZE; i++) { + // Add further entries in the 0'th bucket so as not to disturb + // other buckets, entries of which may be distributed and/or + // the bucket untreeified on resize + m.put(new HashCodeInteger(i, 0), i); + + Collection actual = m.keySet().stream().map(e -> e.value).collect(c); + Collection expected = IntStream.rangeClosed(0, i).boxed().collect(c); + assertEquals(actual, expected, "Key set"); + } + } + + Collector> getCollector(Map m) { + Collector> collector = m instanceof LinkedHashMap + ? Collectors.toList() + : Collectors.toSet(); + return collector; + } + + void put(int size, Map m, BiConsumer c) { + for (int i = 0; i < size; i++) { + m.put(new HashCodeInteger(i), i); + + c.accept(i, m.size()); + } + } + + void remove(Map m, BiConsumer c) { + int size = m.size(); + // Remove all elements thus ensuring at some point trees will be + // converting back to bins + for (int i = 0; i < size; i++) { + m.remove(new HashCodeInteger(i)); + + c.accept(i, m.size()); + } + } + + final static class HashCodeInteger implements Comparable { + final int value; + + final int hashcode; + + HashCodeInteger(int value) { + this(value, hash(value)); + } + + HashCodeInteger(int value, int hashcode) { + this.value = value; + this.hashcode = hashcode; + } + + static int hash(int i) { + // Assuming 64 entries with keys from 0 to 63 then a map: + // - of capacity 64 will have 4 buckets with 16 entries per-bucket + // - of capacity 128 will have 8 buckets with 8 entries per-bucket + // - of capacity 256 will have 16 buckets with 4 entries per-bucket + // + // Re-sizing will result in re-distribution, doubling the buckets + // and reducing the entries by half. This will result in + // untreeifying when the number of entries is less than untreeify + // threshold (see HashMap/ConcurrentMap.UNTREEIFY_THRESHOLD) + return (i % 4) + (i / 4) * INITIAL_CAPACITY; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof HashCodeInteger) { + HashCodeInteger other = (HashCodeInteger) obj; + return other.value == value; + } + return false; + } + + @Override + public int hashCode() { + return hashcode; + } + + @Override + public int compareTo(HashCodeInteger o) { + return value - o.value; + } + + @Override + public String toString() { + return Integer.toString(value); + } + } +} diff --git a/jdk/test/java/util/Map/TreeBinSplitBackToEntries.java b/jdk/test/java/util/Map/TreeBinSplitBackToEntries.java deleted file mode 100644 index 6093147a24d..00000000000 --- a/jdk/test/java/util/Map/TreeBinSplitBackToEntries.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.*; -import java.lang.reflect.Field; - -/* - * @test - * @bug 8005698 - * @summary Test the case where TreeBin.splitTreeBin() converts a bin back to an Entry list - * @run main TreeBinSplitBackToEntries unused - * @author Brent Christian - */ - -public class TreeBinSplitBackToEntries { - private static int EXPECTED_TREE_THRESHOLD = 16; - - // Easiest if this covers one bit higher then 'bit' in splitTreeBin() on the - // call where the TreeBin is converted back to an Entry list - private static int HASHMASK = 0x7F; - private static boolean verbose = false; - private static boolean fastFail = false; - private static boolean failed = false; - - static void printlnIfVerbose(String msg) { - if (verbose) {System.out.println(msg); } - } - - public static void main(String[] args) { - for (String arg : args) { - switch(arg) { - case "-verbose": - verbose = true; - break; - case "-fastfail": - fastFail = true; - break; - } - } - checkTreeThreshold(); - testMapHiTree(); - testMapLoTree(); - if (failed) { - System.out.println("Test Failed"); - System.exit(1); - } else { - System.out.println("Test Passed"); - } - } - - public static void checkTreeThreshold() { - int threshold = -1; - try { - Class treeBinClass = Class.forName("java.util.HashMap$TreeBin"); - Field treeThreshold = treeBinClass.getDeclaredField("TREE_THRESHOLD"); - treeThreshold.setAccessible(true); - threshold = treeThreshold.getInt(treeBinClass); - } catch (ClassNotFoundException|NoSuchFieldException|IllegalAccessException e) { - e.printStackTrace(); - throw new Error("Problem accessing TreeBin.TREE_THRESHOLD", e); - } - check("Expected TREE_THRESHOLD: " + EXPECTED_TREE_THRESHOLD +", found: " + threshold, - threshold == EXPECTED_TREE_THRESHOLD); - printlnIfVerbose("TREE_THRESHOLD: " + threshold); - } - - public static void testMapHiTree() { - Object[][] mapKeys = makeHiTreeTestData(); - testMapsForKeys(mapKeys, "hiTree"); - } - - public static void testMapLoTree() { - Object[][] mapKeys = makeLoTreeTestData(); - - testMapsForKeys(mapKeys, "loTree"); - } - - public static void testMapsForKeys(Object[][] mapKeys, String desc) { - // loop through data sets - for (Object[] keys_desc : mapKeys) { - Map[] maps = (Map[]) new Map[]{ - new HashMap<>(4, 0.8f), - new LinkedHashMap<>(4, 0.8f), - }; - // for each map type. - for (Map map : maps) { - Object[] keys = (Object[]) keys_desc[1]; - System.out.println(desc + ": testPutThenGet() for " + map.getClass()); - testPutThenGet(map, keys); - } - } - } - - private static void testPutThenGet(Map map, T[] keys) { - for (T key : keys) { - printlnIfVerbose("put()ing 0x" + Integer.toHexString(Integer.parseInt(key.toString())) + ", hashCode=" + Integer.toHexString(key.hashCode())); - map.put(key, key); - } - for (T key : keys) { - check("key: 0x" + Integer.toHexString(Integer.parseInt(key.toString())) + " not found in resulting " + map.getClass().getSimpleName(), map.get(key) != null); - } - } - - /* Data to force a non-empty loTree in TreeBin.splitTreeBin() to be converted back - * into an Entry list - */ - private static Object[][] makeLoTreeTestData() { - HashableInteger COLLIDING_OBJECTS[] = new HashableInteger[] { - new HashableInteger( 0x23, HASHMASK), - new HashableInteger( 0x123, HASHMASK), - new HashableInteger( 0x323, HASHMASK), - new HashableInteger( 0x523, HASHMASK), - - new HashableInteger( 0x723, HASHMASK), - new HashableInteger( 0x923, HASHMASK), - new HashableInteger( 0xB23, HASHMASK), - new HashableInteger( 0xD23, HASHMASK), - - new HashableInteger( 0xF23, HASHMASK), - new HashableInteger( 0xF123, HASHMASK), - new HashableInteger( 0x1023, HASHMASK), - new HashableInteger( 0x1123, HASHMASK), - - new HashableInteger( 0x1323, HASHMASK), - new HashableInteger( 0x1523, HASHMASK), - new HashableInteger( 0x1723, HASHMASK), - new HashableInteger( 0x1923, HASHMASK), - - new HashableInteger( 0x1B23, HASHMASK), - new HashableInteger( 0x1D23, HASHMASK), - new HashableInteger( 0x3123, HASHMASK), - new HashableInteger( 0x3323, HASHMASK), - new HashableInteger( 0x3523, HASHMASK), - - new HashableInteger( 0x3723, HASHMASK), - new HashableInteger( 0x1001, HASHMASK), - new HashableInteger( 0x4001, HASHMASK), - new HashableInteger( 0x1, HASHMASK), - }; - return new Object[][] { - new Object[]{"Colliding Objects", COLLIDING_OBJECTS}, - }; - } - - /* Data to force the hiTree in TreeBin.splitTreeBin() to be converted back - * into an Entry list - */ - private static Object[][] makeHiTreeTestData() { - HashableInteger COLLIDING_OBJECTS[] = new HashableInteger[] { - new HashableInteger( 0x1, HASHMASK), - new HashableInteger( 0x101, HASHMASK), - new HashableInteger( 0x301, HASHMASK), - new HashableInteger( 0x501, HASHMASK), - new HashableInteger( 0x701, HASHMASK), - - new HashableInteger( 0x1001, HASHMASK), - new HashableInteger( 0x1101, HASHMASK), - new HashableInteger( 0x1301, HASHMASK), - - new HashableInteger( 0x1501, HASHMASK), - new HashableInteger( 0x1701, HASHMASK), - new HashableInteger( 0x4001, HASHMASK), - new HashableInteger( 0x4101, HASHMASK), - new HashableInteger( 0x4301, HASHMASK), - - new HashableInteger( 0x4501, HASHMASK), - new HashableInteger( 0x4701, HASHMASK), - new HashableInteger( 0x8001, HASHMASK), - new HashableInteger( 0x8101, HASHMASK), - - - new HashableInteger( 0x8301, HASHMASK), - new HashableInteger( 0x8501, HASHMASK), - new HashableInteger( 0x8701, HASHMASK), - new HashableInteger( 0x9001, HASHMASK), - - new HashableInteger( 0x23, HASHMASK), - new HashableInteger( 0x123, HASHMASK), - new HashableInteger( 0x323, HASHMASK), - new HashableInteger( 0x523, HASHMASK), - }; - return new Object[][] { - new Object[]{"Colliding Objects", COLLIDING_OBJECTS}, - }; - } - - static void check(String desc, boolean cond) { - if (!cond) { - fail(desc); - } - } - - static void fail(String msg) { - failed = true; - (new Error("Failure: " + msg)).printStackTrace(System.err); - if (fastFail) { - System.exit(1); - } - } - - final static class HashableInteger implements Comparable { - final int value; - final int hashmask; //yes duplication - - HashableInteger(int value, int hashmask) { - this.value = value; - this.hashmask = hashmask; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof HashableInteger) { - HashableInteger other = (HashableInteger) obj; - return other.value == value; - } - return false; - } - - @Override - public int hashCode() { - // This version ANDs the mask - return value & hashmask; - } - - @Override - public int compareTo(HashableInteger o) { - return value - o.value; - } - - @Override - public String toString() { - return Integer.toString(value); - } - } -} diff --git a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java index bb0b7ecd976..3c74ce29dc1 100644 --- a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java +++ b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8020156 8020009 8022326 + * @bug 8020156 8020009 8022326 8012913 * @run testng SpliteratorCharacteristics */ @@ -32,6 +32,10 @@ import org.testng.annotations.Test; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.SortedMap; @@ -47,7 +51,27 @@ import static org.testng.Assert.*; @Test public class SpliteratorCharacteristics { - // TreeMap + public void testHashMap() { + assertMapCharacteristics(new HashMap<>(), + Spliterator.SIZED | Spliterator.DISTINCT); + } + + public void testHashSet() { + assertSetCharacteristics(new HashSet<>(), + Spliterator.SIZED | Spliterator.DISTINCT); + } + + public void testLinkedHashMap() { + assertMapCharacteristics(new LinkedHashMap<>(), + Spliterator.SIZED | Spliterator.DISTINCT | + Spliterator.ORDERED); + } + + public void testLinkedHashSet() { + assertSetCharacteristics(new LinkedHashSet<>(), + Spliterator.SIZED | Spliterator.DISTINCT | + Spliterator.ORDERED); + } public void testTreeMap() { assertSortedMapCharacteristics(new TreeMap<>(), @@ -61,9 +85,6 @@ public class SpliteratorCharacteristics { Spliterator.SORTED | Spliterator.ORDERED); } - - // TreeSet - public void testTreeSet() { assertSortedSetCharacteristics(new TreeSet<>(), Spliterator.SIZED | Spliterator.DISTINCT | @@ -76,9 +97,6 @@ public class SpliteratorCharacteristics { Spliterator.SORTED | Spliterator.ORDERED); } - - // ConcurrentSkipListMap - public void testConcurrentSkipListMap() { assertSortedMapCharacteristics(new ConcurrentSkipListMap<>(), Spliterator.CONCURRENT | Spliterator.NONNULL | @@ -93,9 +111,6 @@ public class SpliteratorCharacteristics { Spliterator.ORDERED); } - - // ConcurrentSkipListSet - public void testConcurrentSkipListSet() { assertSortedSetCharacteristics(new ConcurrentSkipListSet<>(), Spliterator.CONCURRENT | Spliterator.NONNULL | @@ -113,35 +128,58 @@ public class SpliteratorCharacteristics { // - void assertSortedMapCharacteristics(SortedMap m, int keyCharacteristics) { + + void assertMapCharacteristics(Map m, int keyCharacteristics) { + assertMapCharacteristics(m, keyCharacteristics, 0); + } + + void assertMapCharacteristics(Map m, int keyCharacteristics, int notValueCharacteristics) { initMap(m); - boolean hasComparator = m.comparator() != null; + assertCharacteristics(m.keySet(), keyCharacteristics); + + assertCharacteristics(m.values(), + keyCharacteristics & ~(Spliterator.DISTINCT | notValueCharacteristics)); + + assertCharacteristics(m.entrySet(), keyCharacteristics); + + if ((keyCharacteristics & Spliterator.SORTED) == 0) { + assertISEComparator(m.keySet()); + assertISEComparator(m.values()); + assertISEComparator(m.entrySet()); + } + } + + void assertSetCharacteristics(Set s, int keyCharacteristics) { + initSet(s); + + assertCharacteristics(s, keyCharacteristics); + + if ((keyCharacteristics & Spliterator.SORTED) == 0) { + assertISEComparator(s); + } + } + + void assertSortedMapCharacteristics(SortedMap m, int keyCharacteristics) { + assertMapCharacteristics(m, keyCharacteristics, Spliterator.SORTED); Set keys = m.keySet(); - assertCharacteristics(keys, keyCharacteristics); - if (hasComparator) { + if (m.comparator() != null) { assertNotNullComparator(keys); } else { assertNullComparator(keys); } - assertCharacteristics(m.values(), - keyCharacteristics & ~(Spliterator.DISTINCT | Spliterator.SORTED)); assertISEComparator(m.values()); - assertCharacteristics(m.entrySet(), keyCharacteristics); assertNotNullComparator(m.entrySet()); } void assertSortedSetCharacteristics(SortedSet s, int keyCharacteristics) { - initSet(s); + assertSetCharacteristics(s, keyCharacteristics); - boolean hasComparator = s.comparator() != null; - - assertCharacteristics(s, keyCharacteristics); - if (hasComparator) { + if (s.comparator() != null) { assertNotNullComparator(s); } else { @@ -161,27 +199,18 @@ public class SpliteratorCharacteristics { } void assertCharacteristics(Collection c, int expectedCharacteristics) { - assertCharacteristics(c.spliterator(), expectedCharacteristics); - } - - void assertCharacteristics(Spliterator s, int expectedCharacteristics) { - assertTrue(s.hasCharacteristics(expectedCharacteristics)); + assertTrue(c.spliterator().hasCharacteristics(expectedCharacteristics), + "Spliterator characteristics"); } void assertNullComparator(Collection c) { - assertNullComparator(c.spliterator()); - } - - void assertNullComparator(Spliterator s) { - assertNull(s.getComparator()); + assertNull(c.spliterator().getComparator(), + "Comparator of Spliterator of Collection"); } void assertNotNullComparator(Collection c) { - assertNotNullComparator(c.spliterator()); - } - - void assertNotNullComparator(Spliterator s) { - assertNotNull(s.getComparator()); + assertNotNull(c.spliterator().getComparator(), + "Comparator of Spliterator of Collection"); } void assertISEComparator(Collection c) { @@ -196,6 +225,6 @@ public class SpliteratorCharacteristics { catch (IllegalStateException e) { caught = true; } - assertTrue(caught); + assertTrue(caught, "Throwing IllegalStateException"); } } From 256894796fce919d11b720fb5c730f1afd78eecc Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Wed, 4 Sep 2013 12:10:07 +0400 Subject: [PATCH 0194/1294] 7043064: sun/java2d/cmm/ tests failed against RI b141 & b138-nightly Reviewed-by: prr, vadim --- jdk/make/sun/cmm/lcms/mapfile-vers | 5 +- jdk/makefiles/mapfiles/liblcms/mapfile-vers | 5 +- .../classes/java/awt/color/ICC_Profile.java | 73 ++--- .../java/awt/color/ICC_ProfileGray.java | 6 +- .../java/awt/color/ICC_ProfileRGB.java | 6 +- .../classes/sun/java2d/cmm/CMSManager.java | 44 +-- .../share/classes/sun/java2d/cmm/PCMM.java | 14 +- .../share/classes/sun/java2d/cmm/Profile.java | 43 +++ .../classes/sun/java2d/cmm/lcms/LCMS.java | 208 ++++++------ .../sun/java2d/cmm/lcms/LCMSProfile.java | 109 +++++++ .../sun/java2d/cmm/lcms/LCMSTransform.java | 14 +- .../share/native/sun/java2d/cmm/lcms/LCMS.c | 299 +++++++++++------- .../cmm/ProfileOp/ReadWriteProfileTest.java | 34 +- 13 files changed, 551 insertions(+), 309 deletions(-) create mode 100644 jdk/src/share/classes/sun/java2d/cmm/Profile.java create mode 100644 jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSProfile.java diff --git a/jdk/make/sun/cmm/lcms/mapfile-vers b/jdk/make/sun/cmm/lcms/mapfile-vers index 3d9074f746d..949ff9b5787 100644 --- a/jdk/make/sun/cmm/lcms/mapfile-vers +++ b/jdk/make/sun/cmm/lcms/mapfile-vers @@ -28,9 +28,8 @@ SUNWprivate_1.1 { global: Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative; - Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative; - Java_sun_java2d_cmm_lcms_LCMS_getProfileSize; - Java_sun_java2d_cmm_lcms_LCMS_getProfileData; + Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative; + Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative; Java_sun_java2d_cmm_lcms_LCMS_getTagNative; Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative; Java_sun_java2d_cmm_lcms_LCMS_colorConvert; diff --git a/jdk/makefiles/mapfiles/liblcms/mapfile-vers b/jdk/makefiles/mapfiles/liblcms/mapfile-vers index 024511423d3..2e63d68e5d4 100644 --- a/jdk/makefiles/mapfiles/liblcms/mapfile-vers +++ b/jdk/makefiles/mapfiles/liblcms/mapfile-vers @@ -28,9 +28,8 @@ SUNWprivate_1.1 { global: Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative; - Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative; - Java_sun_java2d_cmm_lcms_LCMS_getProfileSize; - Java_sun_java2d_cmm_lcms_LCMS_getProfileData; + Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative; + Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative; Java_sun_java2d_cmm_lcms_LCMS_getTagNative; Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative; Java_sun_java2d_cmm_lcms_LCMS_colorConvert; diff --git a/jdk/src/share/classes/java/awt/color/ICC_Profile.java b/jdk/src/share/classes/java/awt/color/ICC_Profile.java index c1534249f39..7e44947477d 100644 --- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java +++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java @@ -37,6 +37,7 @@ package java.awt.color; import sun.java2d.cmm.PCMM; import sun.java2d.cmm.CMSManager; +import sun.java2d.cmm.Profile; import sun.java2d.cmm.ProfileDataVerifier; import sun.java2d.cmm.ProfileDeferralMgr; import sun.java2d.cmm.ProfileDeferralInfo; @@ -94,7 +95,7 @@ public class ICC_Profile implements Serializable { private static final long serialVersionUID = -3938515861990936766L; - transient long ID; + private transient Profile cmmProfile; private transient ProfileDeferralInfo deferralInfo; private transient ProfileActivator profileActivator; @@ -727,8 +728,8 @@ public class ICC_Profile implements Serializable { /** * Constructs an ICC_Profile object with a given ID. */ - ICC_Profile(long ID) { - this.ID = ID; + ICC_Profile(Profile p) { + this.cmmProfile = p; } @@ -751,8 +752,8 @@ public class ICC_Profile implements Serializable { * Frees the resources associated with an ICC_Profile object. */ protected void finalize () { - if (ID != 0) { - CMSManager.getModule().freeProfile(ID); + if (cmmProfile != null) { + CMSManager.getModule().freeProfile(cmmProfile); } else if (profileActivator != null) { ProfileDeferralMgr.unregisterDeferral(profileActivator); } @@ -770,7 +771,7 @@ public class ICC_Profile implements Serializable { public static ICC_Profile getInstance(byte[] data) { ICC_Profile thisProfile; - long theID; + Profile p = null; if (ProfileDeferralMgr.deferring) { ProfileDeferralMgr.activateProfiles(); @@ -779,32 +780,32 @@ public class ICC_Profile implements Serializable { ProfileDataVerifier.verify(data); try { - theID = CMSManager.getModule().loadProfile(data); + p = CMSManager.getModule().loadProfile(data); } catch (CMMException c) { throw new IllegalArgumentException("Invalid ICC Profile Data"); } try { - if ((getColorSpaceType (theID) == ColorSpace.TYPE_GRAY) && - (getData (theID, icSigMediaWhitePointTag) != null) && - (getData (theID, icSigGrayTRCTag) != null)) { - thisProfile = new ICC_ProfileGray (theID); + if ((getColorSpaceType (p) == ColorSpace.TYPE_GRAY) && + (getData (p, icSigMediaWhitePointTag) != null) && + (getData (p, icSigGrayTRCTag) != null)) { + thisProfile = new ICC_ProfileGray (p); } - else if ((getColorSpaceType (theID) == ColorSpace.TYPE_RGB) && - (getData (theID, icSigMediaWhitePointTag) != null) && - (getData (theID, icSigRedColorantTag) != null) && - (getData (theID, icSigGreenColorantTag) != null) && - (getData (theID, icSigBlueColorantTag) != null) && - (getData (theID, icSigRedTRCTag) != null) && - (getData (theID, icSigGreenTRCTag) != null) && - (getData (theID, icSigBlueTRCTag) != null)) { - thisProfile = new ICC_ProfileRGB (theID); + else if ((getColorSpaceType (p) == ColorSpace.TYPE_RGB) && + (getData (p, icSigMediaWhitePointTag) != null) && + (getData (p, icSigRedColorantTag) != null) && + (getData (p, icSigGreenColorantTag) != null) && + (getData (p, icSigBlueColorantTag) != null) && + (getData (p, icSigRedTRCTag) != null) && + (getData (p, icSigGreenTRCTag) != null) && + (getData (p, icSigBlueTRCTag) != null)) { + thisProfile = new ICC_ProfileRGB (p); } else { - thisProfile = new ICC_Profile (theID); + thisProfile = new ICC_Profile (p); } } catch (CMMException c) { - thisProfile = new ICC_Profile (theID); + thisProfile = new ICC_Profile (p); } return thisProfile; } @@ -1119,7 +1120,7 @@ public class ICC_Profile implements Serializable { fileName); } try { - ID = CMSManager.getModule().loadProfile(profileData); + cmmProfile = CMSManager.getModule().loadProfile(profileData); } catch (CMMException c) { ProfileDataException pde = new ProfileDataException("Invalid ICC Profile Data" + fileName); @@ -1229,14 +1230,14 @@ public class ICC_Profile implements Serializable { causing a deferred profile to be loaded */ } - return getColorSpaceType(ID); + return getColorSpaceType(cmmProfile); } - static int getColorSpaceType(long profileID) { + static int getColorSpaceType(Profile p) { byte[] theHeader; int theColorSpaceSig, theColorSpace; - theHeader = getData(profileID, icSigHead); + theHeader = getData(p, icSigHead); theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace); theColorSpace = iccCStoJCS (theColorSpaceSig); return theColorSpace; @@ -1258,15 +1259,15 @@ public class ICC_Profile implements Serializable { if (ProfileDeferralMgr.deferring) { ProfileDeferralMgr.activateProfiles(); } - return getPCSType(ID); + return getPCSType(cmmProfile); } - static int getPCSType(long profileID) { + static int getPCSType(Profile p) { byte[] theHeader; int thePCSSig, thePCS; - theHeader = getData(profileID, icSigHead); + theHeader = getData(p, icSigHead); thePCSSig = intFromBigEndian(theHeader, icHdrPcs); thePCS = iccCStoJCS(thePCSSig); return thePCS; @@ -1326,12 +1327,12 @@ public class ICC_Profile implements Serializable { PCMM mdl = CMSManager.getModule(); /* get the number of bytes needed for this profile */ - profileSize = mdl.getProfileSize(ID); + profileSize = mdl.getProfileSize(cmmProfile); profileData = new byte [profileSize]; /* get the data for the profile */ - mdl.getProfileData(ID, profileData); + mdl.getProfileData(cmmProfile, profileData); return profileData; } @@ -1358,11 +1359,11 @@ public class ICC_Profile implements Serializable { ProfileDeferralMgr.activateProfiles(); } - return getData(ID, tagSignature); + return getData(cmmProfile, tagSignature); } - static byte[] getData(long profileID, int tagSignature) { + static byte[] getData(Profile p, int tagSignature) { int tagSize; byte[] tagData; @@ -1370,12 +1371,12 @@ public class ICC_Profile implements Serializable { PCMM mdl = CMSManager.getModule(); /* get the number of bytes needed for this tag */ - tagSize = mdl.getTagSize(profileID, tagSignature); + tagSize = mdl.getTagSize(p, tagSignature); tagData = new byte[tagSize]; /* get an array for the tag */ /* get the tag's data */ - mdl.getTagData(profileID, tagSignature, tagData); + mdl.getTagData(p, tagSignature, tagData); } catch(CMMException c) { tagData = null; } @@ -1406,7 +1407,7 @@ public class ICC_Profile implements Serializable { ProfileDeferralMgr.activateProfiles(); } - CMSManager.getModule().setTagData(ID, tagSignature, tagData); + CMSManager.getModule().setTagData(cmmProfile, tagSignature, tagData); } /** diff --git a/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java b/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java index d9042266663..a868a6f50fc 100644 --- a/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java +++ b/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java @@ -35,7 +35,7 @@ package java.awt.color; -import java.awt.image.LookupTable; +import sun.java2d.cmm.Profile; import sun.java2d.cmm.ProfileDeferralInfo; /** @@ -76,8 +76,8 @@ extends ICC_Profile { /** * Constructs a new ICC_ProfileGray from a CMM ID. */ - ICC_ProfileGray(long ID) { - super(ID); + ICC_ProfileGray(Profile p) { + super(p); } /** diff --git a/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java b/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java index b0bad4d9a91..dcf65828650 100644 --- a/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java +++ b/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java @@ -35,7 +35,7 @@ package java.awt.color; -import java.awt.image.LookupTable; +import sun.java2d.cmm.Profile; import sun.java2d.cmm.ProfileDeferralInfo; /** @@ -114,8 +114,8 @@ extends ICC_Profile { * @param ID The CMM ID for the profile. * */ - ICC_ProfileRGB(long ID) { - super(ID); + ICC_ProfileRGB(Profile p) { + super(p); } /** diff --git a/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java b/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java index 1e24504b45a..fcaede43a94 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java +++ b/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java @@ -104,53 +104,53 @@ public class CMSManager { cName = tcmm.getClass().getName(); } - public long loadProfile(byte[] data) { + public Profile loadProfile(byte[] data) { System.err.print(cName + ".loadProfile"); - long profileID = tcmm.loadProfile(data); - System.err.printf("(ID=%x)\n", profileID); - return profileID; + Profile p = tcmm.loadProfile(data); + System.err.printf("(ID=%s)\n", p.toString()); + return p; } - public void freeProfile(long profileID) { - System.err.printf(cName + ".freeProfile(ID=%x)\n", profileID); - tcmm.freeProfile(profileID); + public void freeProfile(Profile p) { + System.err.printf(cName + ".freeProfile(ID=%s)\n", p.toString()); + tcmm.freeProfile(p); } - public int getProfileSize(long profileID) { - System.err.print(cName + ".getProfileSize(ID=" + profileID + ")"); - int size = tcmm.getProfileSize(profileID); + public int getProfileSize(Profile p) { + System.err.print(cName + ".getProfileSize(ID=" + p + ")"); + int size = tcmm.getProfileSize(p); System.err.println("=" + size); return size; } - public void getProfileData(long profileID, byte[] data) { - System.err.print(cName + ".getProfileData(ID=" + profileID + ") "); + public void getProfileData(Profile p, byte[] data) { + System.err.print(cName + ".getProfileData(ID=" + p + ") "); System.err.println("requested " + data.length + " byte(s)"); - tcmm.getProfileData(profileID, data); + tcmm.getProfileData(p, data); } - public int getTagSize(long profileID, int tagSignature) { + public int getTagSize(Profile p, int tagSignature) { System.err.printf(cName + ".getTagSize(ID=%x, TagSig=%s)", - profileID, signatureToString(tagSignature)); - int size = tcmm.getTagSize(profileID, tagSignature); + p, signatureToString(tagSignature)); + int size = tcmm.getTagSize(p, tagSignature); System.err.println("=" + size); return size; } - public void getTagData(long profileID, int tagSignature, + public void getTagData(Profile p, int tagSignature, byte[] data) { System.err.printf(cName + ".getTagData(ID=%x, TagSig=%s)", - profileID, signatureToString(tagSignature)); + p, signatureToString(tagSignature)); System.err.println(" requested " + data.length + " byte(s)"); - tcmm.getTagData(profileID, tagSignature, data); + tcmm.getTagData(p, tagSignature, data); } - public void setTagData(long profileID, int tagSignature, + public void setTagData(Profile p, int tagSignature, byte[] data) { - System.err.print(cName + ".setTagData(ID=" + profileID + + System.err.print(cName + ".setTagData(ID=" + p + ", TagSig=" + tagSignature + ")"); System.err.println(" sending " + data.length + " byte(s)"); - tcmm.setTagData(profileID, tagSignature, data); + tcmm.setTagData(p, tagSignature, data); } /* methods for creating ColorTransforms */ diff --git a/jdk/src/share/classes/sun/java2d/cmm/PCMM.java b/jdk/src/share/classes/sun/java2d/cmm/PCMM.java index 6b6ce93546d..03f2fab6336 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/PCMM.java +++ b/jdk/src/share/classes/sun/java2d/cmm/PCMM.java @@ -32,13 +32,13 @@ import java.awt.color.ICC_Profile; public interface PCMM { /* methods invoked from ICC_Profile */ - public long loadProfile(byte[] data); - public void freeProfile(long profileID); - public int getProfileSize(long profileID); - public void getProfileData(long profileID, byte[] data); - public void getTagData(long profileID, int tagSignature, byte[] data); - public int getTagSize(long profileID, int tagSignature); - public void setTagData(long profileID, int tagSignature, byte[] data); + public Profile loadProfile(byte[] data); + public void freeProfile(Profile p); + public int getProfileSize(Profile p); + public void getProfileData(Profile p, byte[] data); + public void getTagData(Profile p, int tagSignature, byte[] data); + public int getTagSize(Profile p, int tagSignature); + public void setTagData(Profile p, int tagSignature, byte[] data); /* methods for creating ColorTransforms */ public ColorTransform createTransform(ICC_Profile profile, int renderType, diff --git a/jdk/src/share/classes/sun/java2d/cmm/Profile.java b/jdk/src/share/classes/sun/java2d/cmm/Profile.java new file mode 100644 index 00000000000..5b766b5d079 --- /dev/null +++ b/jdk/src/share/classes/sun/java2d/cmm/Profile.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.java2d.cmm; + +import java.awt.color.CMMException; + +public class Profile { + private final long nativePtr; + + protected Profile(long ptr) { + nativePtr = ptr; + } + + protected final long getNativePtr() { + if (nativePtr == 0L) { + throw new CMMException("Invalid profile: ptr is null"); + } + return nativePtr; + } +} diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java index f7ecc0b67c9..d76d99638a9 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java +++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java @@ -25,96 +25,139 @@ package sun.java2d.cmm.lcms; +import java.awt.color.CMMException; import java.awt.color.ICC_Profile; -import java.util.Arrays; -import java.util.HashMap; import sun.java2d.cmm.ColorTransform; import sun.java2d.cmm.PCMM; +import sun.java2d.cmm.Profile; +import sun.java2d.cmm.lcms.LCMSProfile.TagData; public class LCMS implements PCMM { /* methods invoked from ICC_Profile */ @Override - public long loadProfile(byte[] data) { - long id = loadProfileNative(data); + public Profile loadProfile(byte[] data) { + final Object disposerRef = new Object(); - if (id != 0L) { - if (profiles == null) { - profiles = new HashMap<>(); - } - profiles.put(id, new TagCache(id)); + final long ptr = loadProfileNative(data, disposerRef); + + if (ptr != 0L) { + return new LCMSProfile(ptr, disposerRef); } - return id; + return null; } - private native long loadProfileNative(byte[] data); + private native long loadProfileNative(byte[] data, Object ref); - @Override - public void freeProfile(long profileID) { - TagCache c = profiles.remove(profileID); - if (c != null) { - c.clear(); + private LCMSProfile getLcmsProfile(Profile p) { + if (p instanceof LCMSProfile) { + return (LCMSProfile)p; } - if (profiles.isEmpty()) { - profiles = null; - } - freeProfileNative(profileID); + throw new CMMException("Invalid profile: " + p); } - private native void freeProfileNative(long profileID); - - public native synchronized int getProfileSize(long profileID); - - public native synchronized void getProfileData(long profileID, byte[] data); @Override - public synchronized int getTagSize(long profileID, int tagSignature) { - TagCache cache = profiles.get(profileID); - - if (cache == null) { - cache = new TagCache(profileID); - profiles.put(profileID, cache); - } - - TagData t = cache.getTag(tagSignature); - return t == null ? 0 : t.getSize(); + public void freeProfile(Profile p) { + // we use disposer, so this method does nothing } - private static native byte[] getTagNative(long profileID, int signature); + @Override + public int getProfileSize(final Profile p) { + synchronized (p) { + return getProfileSizeNative(getLcmsProfile(p).getLcmsPtr()); + } + } + + private native int getProfileSizeNative(long ptr); @Override - public synchronized void getTagData(long profileID, int tagSignature, - byte[] data) + public void getProfileData(final Profile p, byte[] data) { + synchronized (p) { + getProfileDataNative(getLcmsProfile(p).getLcmsPtr(), data); + } + } + + private native void getProfileDataNative(long ptr, byte[] data); + + @Override + public int getTagSize(Profile p, int tagSignature) { + final LCMSProfile profile = getLcmsProfile(p); + + synchronized (profile) { + TagData t = profile.getTag(tagSignature); + return t == null ? 0 : t.getSize(); + } + } + + static native byte[] getTagNative(long profileID, int signature); + + @Override + public void getTagData(Profile p, int tagSignature, byte[] data) { - TagCache cache = profiles.get(profileID); + final LCMSProfile profile = getLcmsProfile(p); - if (cache == null) { - cache = new TagCache(profileID); - profiles.put(profileID, cache); - } - - TagData t = cache.getTag(tagSignature); - if (t != null) { - t.copyDataTo(data); + synchronized (profile) { + TagData t = profile.getTag(tagSignature); + if (t != null) { + t.copyDataTo(data); + } } } @Override - public synchronized void setTagData(long profileID, int tagSignature, byte[] data) { - TagCache cache = profiles.get(profileID); + public synchronized void setTagData(Profile p, int tagSignature, byte[] data) { + final LCMSProfile profile = getLcmsProfile(p); - if (cache != null) { - cache.clear(); + synchronized (profile) { + profile.clearTagCache(); + + // Now we are going to update the profile with new tag data + // In some cases, we may change the pointer to the native + // profile. + // + // If we fail to write tag data for any reason, the old pointer + // should be used. + setTagDataNative(profile.getLcmsPtr(), + tagSignature, data); } - setTagDataNative(profileID, tagSignature, data); } - private native synchronized void setTagDataNative(long profileID, int tagSignature, + /** + * Writes supplied data as a tag into the profile. + * Destroys old profile, if new one was successfully + * created. + * + * Returns valid pointer to new profile. + * + * Throws CMMException if operation fails, preserve old profile from + * destruction. + */ + private native void setTagDataNative(long ptr, int tagSignature, byte[] data); - public static native long getProfileID(ICC_Profile profile); + public synchronized static native LCMSProfile getProfileID(ICC_Profile profile); - public static native long createNativeTransform( + /* Helper method used from LCMSColorTransfrom */ + static long createTransform( + LCMSProfile[] profiles, int renderType, + int inFormatter, boolean isInIntPacked, + int outFormatter, boolean isOutIntPacked, + Object disposerRef) + { + long[] ptrs = new long[profiles.length]; + + for (int i = 0; i < profiles.length; i++) { + if (profiles[i] == null) throw new CMMException("Unknown profile ID"); + + ptrs[i] = profiles[i].getLcmsPtr(); + } + + return createNativeTransform(ptrs, renderType, inFormatter, + isInIntPacked, outFormatter, isOutIntPacked, disposerRef); + } + + private static native long createNativeTransform( long[] profileIDs, int renderType, int inFormatter, boolean isInIntPacked, int outFormatter, boolean isOutIntPacked, @@ -175,59 +218,4 @@ public class LCMS implements PCMM { return theLcms; } - - private static class TagData { - private int signature; - private byte[] data; - - TagData(int sig, byte[] data) { - this.signature = sig; - this.data = data; - } - - int getSize() { - return data.length; - } - - byte[] getData() { - return Arrays.copyOf(data, data.length); - } - - void copyDataTo(byte[] dst) { - System.arraycopy(data, 0, dst, 0, data.length); - } - - int getSignature() { - return signature; - } - } - - private static class TagCache { - private long profileID; - private HashMap tags; - - TagCache(long id) { - profileID = id; - - tags = new HashMap<>(); - } - - TagData getTag(int sig) { - TagData t = tags.get(sig); - if (t == null) { - byte[] tagData = getTagNative(profileID, sig); - if (tagData != null) { - t = new TagData(sig, tagData); - tags.put(sig, t); - } - } - return t; - } - - void clear() { - tags.clear(); - } - } - - private static HashMap profiles; } diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSProfile.java b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSProfile.java new file mode 100644 index 00000000000..12810812416 --- /dev/null +++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSProfile.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.java2d.cmm.lcms; + +import java.awt.color.CMMException; +import java.util.Arrays; +import java.util.HashMap; +import sun.java2d.cmm.Profile; + +final class LCMSProfile extends Profile { + private final TagCache tagCache; + + private final Object disposerReferent; + + LCMSProfile(long ptr, Object ref) { + super(ptr); + + disposerReferent = ref; + + tagCache = new TagCache(this); + } + + final long getLcmsPtr() { + return this.getNativePtr(); + } + + TagData getTag(int sig) { + return tagCache.getTag(sig); + } + + void clearTagCache() { + tagCache.clear(); + } + + static class TagCache { + final LCMSProfile profile; + private HashMap tags; + + TagCache(LCMSProfile p) { + profile = p; + tags = new HashMap<>(); + } + + TagData getTag(int sig) { + TagData t = tags.get(sig); + if (t == null) { + byte[] tagData = LCMS.getTagNative(profile.getNativePtr(), sig); + if (tagData != null) { + t = new TagData(sig, tagData); + tags.put(sig, t); + } + } + return t; + } + + void clear() { + tags.clear(); + } + } + + static class TagData { + private int signature; + private byte[] data; + + TagData(int sig, byte[] data) { + this.signature = sig; + this.data = data; + } + + int getSize() { + return data.length; + } + + byte[] getData() { + return Arrays.copyOf(data, data.length); + } + + void copyDataTo(byte[] dst) { + System.arraycopy(data, 0, dst, 0, data.length); + } + + int getSignature() { + return signature; + } + } +} diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java index d5ce5525989..9d6dfa9aac3 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java +++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java @@ -62,7 +62,7 @@ public class LCMSTransform implements ColorTransform { private boolean isOutIntPacked = false; ICC_Profile[] profiles; - long [] profileIDs; + LCMSProfile[] lcmsProfiles; int renderType; int transformType; @@ -84,8 +84,8 @@ public class LCMSTransform implements ColorTransform { /* Actually, it is not a complete transform but just part of it */ profiles = new ICC_Profile[1]; profiles[0] = profile; - profileIDs = new long[1]; - profileIDs[0] = LCMS.getProfileID(profile); + lcmsProfiles = new LCMSProfile[1]; + lcmsProfiles[0] = LCMS.getProfileID(profile); this.renderType = (renderType == ColorTransform.Any)? ICC_Profile.icPerceptual : renderType; this.transformType = transformType; @@ -105,14 +105,14 @@ public class LCMSTransform implements ColorTransform { size+=((LCMSTransform)transforms[i]).profiles.length; } profiles = new ICC_Profile[size]; - profileIDs = new long[size]; + lcmsProfiles = new LCMSProfile[size]; int j = 0; for (int i=0; i < transforms.length; i++) { LCMSTransform curTrans = (LCMSTransform)transforms[i]; System.arraycopy(curTrans.profiles, 0, profiles, j, curTrans.profiles.length); - System.arraycopy(curTrans.profileIDs, 0, profileIDs, j, - curTrans.profileIDs.length); + System.arraycopy(curTrans.lcmsProfiles, 0, lcmsProfiles, j, + curTrans.lcmsProfiles.length); j += curTrans.profiles.length; } renderType = ((LCMSTransform)transforms[0]).renderType; @@ -152,7 +152,7 @@ public class LCMSTransform implements ColorTransform { outFormatter = out.pixelType; isOutIntPacked = out.isIntPacked; - ID = LCMS.createNativeTransform(profileIDs, renderType, + ID = LCMS.createTransform(lcmsProfiles, renderType, inFormatter, isInIntPacked, outFormatter, isOutIntPacked, disposerReferent); diff --git a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c index 1340c82a822..13030cc41d5 100644 --- a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c @@ -94,8 +94,12 @@ cmsInt32Number TransportValue32(cmsInt32Number Value) # endif #endif -typedef union storeID_s { /* store SProfile stuff in a Java Long */ +typedef struct lcmsProfile_s { cmsHPROFILE pf; +} lcmsProfile_t, *lcmsProfile_p; + +typedef union storeID_s { /* store SProfile stuff in a Java Long */ + lcmsProfile_p lcmsPf; cmsHTRANSFORM xf; jobject jobj; jlong j; @@ -106,7 +110,6 @@ typedef union { jint j; } TagSignature_t, *TagSignature_p; -static jfieldID Trans_profileIDs_fID; static jfieldID Trans_renderType_fID; static jfieldID Trans_ID_fID; static jfieldID IL_isIntPacked_fID; @@ -118,7 +121,6 @@ static jfieldID IL_nextRowOffset_fID; static jfieldID IL_width_fID; static jfieldID IL_height_fID; static jfieldID IL_imageAtOnce_fID; -static jfieldID PF_ID_fID; JavaVM *javaVM; @@ -145,6 +147,18 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { return JNI_VERSION_1_6; } +void LCMS_freeProfile(JNIEnv *env, jlong ptr) { + storeID_t sProfile; + sProfile.j = ptr; + + if (sProfile.lcmsPf != NULL) { + if (sProfile.lcmsPf->pf != NULL) { + cmsCloseProfile(sProfile.lcmsPf->pf); + } + free(sProfile.lcmsPf); + } +} + void LCMS_freeTransform(JNIEnv *env, jlong ID) { storeID_t sTrans; @@ -170,7 +184,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform jlong* ids; size = (*env)->GetArrayLength (env, profileIDs); - ids = (*env)->GetPrimitiveArrayCritical(env, profileIDs, 0); + ids = (*env)->GetLongArrayElements(env, profileIDs, 0); #ifdef _LITTLE_ENDIAN /* Reversing data packed into int for LE archs */ @@ -186,6 +200,8 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform iccArray = (cmsHPROFILE*) malloc( size*2*sizeof(cmsHPROFILE)); if (iccArray == NULL) { + (*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0); + J2dRlsTraceLn(J2D_TRACE_ERROR, "getXForm: iccArray == NULL"); return 0L; } @@ -197,7 +213,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform cmsColorSpaceSignature cs; sTrans.j = ids[i]; - icc = sTrans.pf; + icc = sTrans.lcmsPf->pf; iccArray[j++] = icc; /* Middle non-abstract profiles should be doubled before passing to @@ -215,13 +231,15 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform sTrans.xf = cmsCreateMultiprofileTransform(iccArray, j, inFormatter, outFormatter, renderType, 0); - (*env)->ReleasePrimitiveArrayCritical(env, profileIDs, ids, 0); + (*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0); if (sTrans.xf == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: " "sTrans.xf == NULL"); - JNU_ThrowByName(env, "java/awt/color/CMMException", - "Cannot get color transform"); + if ((*env)->ExceptionOccurred(env) == NULL) { + JNU_ThrowByName(env, "java/awt/color/CMMException", + "Cannot get color transform"); + } } else { Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sTrans.j); } @@ -236,20 +254,23 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform /* * Class: sun_java2d_cmm_lcms_LCMS * Method: loadProfile - * Signature: ([B)J + * Signature: ([B,Lsun/java2d/cmm/lcms/LCMSProfile;)V */ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative - (JNIEnv *env, jobject obj, jbyteArray data) + (JNIEnv *env, jobject obj, jbyteArray data, jobject disposerRef) { jbyte* dataArray; jint dataSize; storeID_t sProf; + cmsHPROFILE pf; if (JNU_IsNull(env, data)) { JNU_ThrowIllegalArgumentException(env, "Invalid profile data"); return 0L; } + sProf.j = 0L; + dataArray = (*env)->GetByteArrayElements (env, data, 0); dataSize = (*env)->GetArrayLength (env, data); @@ -258,22 +279,37 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative return 0L; } - sProf.pf = cmsOpenProfileFromMem((const void *)dataArray, + pf = cmsOpenProfileFromMem((const void *)dataArray, (cmsUInt32Number) dataSize); (*env)->ReleaseByteArrayElements (env, data, dataArray, 0); - if (sProf.pf == NULL) { + if (pf == NULL) { JNU_ThrowIllegalArgumentException(env, "Invalid profile data"); } else { /* Sanity check: try to save the profile in order * to force basic validation. */ cmsUInt32Number pfSize = 0; - if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) || + if (!cmsSaveProfileToMem(pf, NULL, &pfSize) || pfSize < sizeof(cmsICCHeader)) { JNU_ThrowIllegalArgumentException(env, "Invalid profile data"); + + cmsCloseProfile(pf); + pf = NULL; + } + } + + if (pf != NULL) { + // create profile holder + sProf.lcmsPf = (lcmsProfile_p)malloc(sizeof(lcmsProfile_t)); + if (sProf.lcmsPf != NULL) { + // register the disposer record + sProf.lcmsPf->pf = pf; + Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sProf.j); + } else { + cmsCloseProfile(pf); } } @@ -282,37 +318,17 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative /* * Class: sun_java2d_cmm_lcms_LCMS - * Method: freeProfile - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative - (JNIEnv *env, jobject obj, jlong id) -{ - storeID_t sProf; - - sProf.j = id; - if (cmsCloseProfile(sProf.pf) == 0) { - J2dRlsTraceLn1(J2D_TRACE_ERROR, "LCMS_freeProfile: cmsCloseProfile(%d)" - "== 0", id); - JNU_ThrowByName(env, "java/awt/color/CMMException", - "Cannot close profile"); - } - -} - -/* - * Class: sun_java2d_cmm_lcms_LCMS - * Method: getProfileSize + * Method: getProfileSizeNative * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSize +JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative (JNIEnv *env, jobject obj, jlong id) { storeID_t sProf; cmsUInt32Number pfSize = 0; sProf.j = id; - if (cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) && ((jint)pfSize > 0)) { + if (cmsSaveProfileToMem(sProf.lcmsPf->pf, NULL, &pfSize) && ((jint)pfSize > 0)) { return (jint)pfSize; } else { JNU_ThrowByName(env, "java/awt/color/CMMException", @@ -323,10 +339,10 @@ JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSize /* * Class: sun_java2d_cmm_lcms_LCMS - * Method: getProfileData + * Method: getProfileDataNative * Signature: (J[B)V */ -JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData +JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative (JNIEnv *env, jobject obj, jlong id, jbyteArray data) { storeID_t sProf; @@ -338,7 +354,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData sProf.j = id; // determine actual profile size - if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize)) { + if (!cmsSaveProfileToMem(sProf.lcmsPf->pf, NULL, &pfSize)) { JNU_ThrowByName(env, "java/awt/color/CMMException", "Can not access specified profile."); return; @@ -354,7 +370,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData dataArray = (*env)->GetByteArrayElements (env, data, 0); - status = cmsSaveProfileToMem(sProf.pf, dataArray, &pfSize); + status = cmsSaveProfileToMem(sProf.lcmsPf->pf, dataArray, &pfSize); (*env)->ReleaseByteArrayElements (env, data, dataArray, 0); @@ -368,7 +384,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData /* Get profile header info */ static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize); static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize); -static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size); +static cmsHPROFILE _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size); /* @@ -412,7 +428,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative return NULL; } - status = _getHeaderInfo(sProf.pf, dataArray, bufSize); + status = _getHeaderInfo(sProf.lcmsPf->pf, dataArray, bufSize); (*env)->ReleaseByteArrayElements (env, data, dataArray, 0); @@ -425,8 +441,8 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative return data; } - if (cmsIsTag(sProf.pf, sig.cms)) { - tagSize = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0); + if (cmsIsTag(sProf.lcmsPf->pf, sig.cms)) { + tagSize = cmsReadRawTag(sProf.lcmsPf->pf, sig.cms, NULL, 0); } else { JNU_ThrowByName(env, "java/awt/color/CMMException", "ICC profile tag not found"); @@ -449,7 +465,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative return NULL; } - bufSize = cmsReadRawTag(sProf.pf, sig.cms, dataArray, tagSize); + bufSize = cmsReadRawTag(sProf.lcmsPf->pf, sig.cms, dataArray, tagSize); (*env)->ReleaseByteArrayElements (env, data, dataArray, 0); @@ -470,8 +486,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data) { storeID_t sProf; + cmsHPROFILE pfReplace = NULL; + TagSignature_t sig; - cmsBool status; + cmsBool status = FALSE; jbyte* dataArray; int tagSize; @@ -493,15 +511,24 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative } if (tagSig == SigHead) { - status = _setHeaderInfo(sProf.pf, dataArray, tagSize); + status = _setHeaderInfo(sProf.lcmsPf->pf, dataArray, tagSize); } else { - status = _writeCookedTag(sProf.pf, sig.cms, dataArray, tagSize); + /* + * New strategy for generic tags: create a place holder, + * dump all existing tags there, dump externally supplied + * tag, and return the new profile to the java. + */ + pfReplace = _writeCookedTag(sProf.lcmsPf->pf, sig.cms, dataArray, tagSize); + status = (pfReplace != NULL); } (*env)->ReleaseByteArrayElements(env, data, dataArray, 0); if (!status) { JNU_ThrowIllegalArgumentException(env, "Can not write tag data."); + } else if (pfReplace != NULL) { + cmsCloseProfile(sProf.lcmsPf->pf); + sProf.lcmsPf->pf = pfReplace; } } @@ -624,12 +651,27 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert /* * Class: sun_java2d_cmm_lcms_LCMS * Method: getProfileID - * Signature: (Ljava/awt/color/ICC_Profile;)J + * Signature: (Ljava/awt/color/ICC_Profile;)Lsun/java2d/cmm/lcms/LCMSProfile */ -JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID +JNIEXPORT jobject JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID (JNIEnv *env, jclass cls, jobject pf) { - return (*env)->GetLongField (env, pf, PF_ID_fID); + jfieldID fid = (*env)->GetFieldID (env, + (*env)->GetObjectClass(env, pf), + "cmmProfile", "Lsun/java2d/cmm/Profile;"); + + jclass clsLcmsProfile = (*env)->FindClass(env, + "sun/java2d/cmm/lcms/LCMSProfile"); + + jobject cmmProfile = (*env)->GetObjectField (env, pf, fid); + + if (JNU_IsNull(env, cmmProfile)) { + return NULL; + } + if ((*env)->IsInstanceOf(env, cmmProfile, clsLcmsProfile)) { + return cmmProfile; + } + return NULL; } /* @@ -644,7 +686,6 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS * corresponding classes to avoid problems with invalidating ids by class * unloading */ - Trans_profileIDs_fID = (*env)->GetFieldID (env, Trans, "profileIDs", "[J"); Trans_renderType_fID = (*env)->GetFieldID (env, Trans, "renderType", "I"); Trans_ID_fID = (*env)->GetFieldID (env, Trans, "ID", "J"); @@ -658,8 +699,6 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I"); IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z"); IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I"); - - PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J"); } static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize) @@ -714,76 +753,114 @@ static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize) return TRUE; } -static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, - cmsTagSignature sig, +/* Returns new profile handler, if it was created successfully, + NULL otherwise. + */ +static cmsHPROFILE _writeCookedTag(const cmsHPROFILE pfTarget, + const cmsTagSignature sig, jbyte *pData, jint size) { - cmsBool status; cmsUInt32Number pfSize = 0; - cmsUInt8Number* pfBuffer = NULL; + const cmsInt32Number tagCount = cmsGetTagCount(pfTarget); + cmsInt32Number i; + cmsHPROFILE pfSanity = NULL; + + cmsICCHeader hdr = { 0 }; cmsHPROFILE p = cmsCreateProfilePlaceholder(NULL); - if (NULL != p) { - cmsICCHeader hdr = { 0 }; - /* Populate the placeholder's header according to target profile */ - hdr.flags = cmsGetHeaderFlags(pfTarget); - hdr.renderingIntent = cmsGetHeaderRenderingIntent(pfTarget); - hdr.manufacturer = cmsGetHeaderManufacturer(pfTarget); - hdr.model = cmsGetHeaderModel(pfTarget); - hdr.pcs = cmsGetPCS(pfTarget); - hdr.colorSpace = cmsGetColorSpace(pfTarget); - hdr.deviceClass = cmsGetDeviceClass(pfTarget); - hdr.version = cmsGetEncodedICCversion(pfTarget); - cmsGetHeaderAttributes(pfTarget, &hdr.attributes); - cmsGetHeaderProfileID(pfTarget, (cmsUInt8Number*)&hdr.profileID); + if (NULL == p) { + return NULL; + } - cmsSetHeaderFlags(p, hdr.flags); - cmsSetHeaderManufacturer(p, hdr.manufacturer); - cmsSetHeaderModel(p, hdr.model); - cmsSetHeaderAttributes(p, hdr.attributes); - cmsSetHeaderProfileID(p, (cmsUInt8Number*)&(hdr.profileID)); - cmsSetHeaderRenderingIntent(p, hdr.renderingIntent); - cmsSetPCS(p, hdr.pcs); - cmsSetColorSpace(p, hdr.colorSpace); - cmsSetDeviceClass(p, hdr.deviceClass); - cmsSetEncodedICCversion(p, hdr.version); + // Populate the placeholder's header according to target profile + hdr.flags = cmsGetHeaderFlags(pfTarget); + hdr.renderingIntent = cmsGetHeaderRenderingIntent(pfTarget); + hdr.manufacturer = cmsGetHeaderManufacturer(pfTarget); + hdr.model = cmsGetHeaderModel(pfTarget); + hdr.pcs = cmsGetPCS(pfTarget); + hdr.colorSpace = cmsGetColorSpace(pfTarget); + hdr.deviceClass = cmsGetDeviceClass(pfTarget); + hdr.version = cmsGetEncodedICCversion(pfTarget); + cmsGetHeaderAttributes(pfTarget, &hdr.attributes); + cmsGetHeaderProfileID(pfTarget, (cmsUInt8Number*)&hdr.profileID); + cmsSetHeaderFlags(p, hdr.flags); + cmsSetHeaderManufacturer(p, hdr.manufacturer); + cmsSetHeaderModel(p, hdr.model); + cmsSetHeaderAttributes(p, hdr.attributes); + cmsSetHeaderProfileID(p, (cmsUInt8Number*)&(hdr.profileID)); + cmsSetHeaderRenderingIntent(p, hdr.renderingIntent); + cmsSetPCS(p, hdr.pcs); + cmsSetColorSpace(p, hdr.colorSpace); + cmsSetDeviceClass(p, hdr.deviceClass); + cmsSetEncodedICCversion(p, hdr.version); - if (cmsWriteRawTag(p, sig, pData, size)) { - if (cmsSaveProfileToMem(p, NULL, &pfSize)) { - pfBuffer = malloc(pfSize); - if (pfBuffer != NULL) { - /* load raw profile data into the buffer */ - if (!cmsSaveProfileToMem(p, pfBuffer, &pfSize)) { - free(pfBuffer); - pfBuffer = NULL; - } + // now write the user supplied tag + if (size <= 0 || !cmsWriteRawTag(p, sig, pData, size)) { + cmsCloseProfile(p); + return NULL; + } + + // copy tags from the original profile + for (i = 0; i < tagCount; i++) { + cmsBool isTagReady = FALSE; + const cmsTagSignature s = cmsGetTagSignature(pfTarget, i); + const cmsInt32Number tagSize = cmsReadRawTag(pfTarget, s, NULL, 0); + + if (s == sig) { + // skip the user supplied tag + continue; + } + + // read raw tag from the original profile + if (tagSize > 0) { + cmsUInt8Number* buf = (cmsUInt8Number*)malloc(tagSize); + if (buf != NULL) { + if (tagSize == cmsReadRawTag(pfTarget, s, buf, tagSize)) { + // now we are ready to write the tag + isTagReady = cmsWriteRawTag(p, s, buf, tagSize); } + free(buf); } } - cmsCloseProfile(p); - } - if (pfBuffer == NULL) { - return FALSE; - } - - /* re-open the placeholder profile */ - p = cmsOpenProfileFromMem(pfBuffer, pfSize); - free(pfBuffer); - status = FALSE; - - if (p != NULL) { - /* Note that pCookedTag points to internal structures of the placeholder, - * so this data is valid only while the placeholder is open. - */ - void *pCookedTag = cmsReadTag(p, sig); - if (pCookedTag != NULL) { - status = cmsWriteTag(pfTarget, sig, pCookedTag); + if (!isTagReady) { + cmsCloseProfile(p); + return NULL; } - pCookedTag = NULL; - cmsCloseProfile(p); } - return status; + + // now we have all tags moved to the new profile. + // do some sanity checks: write it to a memory buffer and read again. + if (cmsSaveProfileToMem(p, NULL, &pfSize)) { + void* buf = malloc(pfSize); + if (buf != NULL) { + // load raw profile data into the buffer + if (cmsSaveProfileToMem(p, buf, &pfSize)) { + pfSanity = cmsOpenProfileFromMem(buf, pfSize); + } + free(buf); + } + } + + if (pfSanity == NULL) { + // for some reason, we failed to save and read the updated profile + // It likely indicates that the profile is not correct, so we report + // a failure here. + cmsCloseProfile(p); + p = NULL; + } else { + // do final check whether we can read and handle the the target tag. + const void* pTag = cmsReadTag(pfSanity, sig); + if (pTag == NULL) { + // the tag can not be cooked + cmsCloseProfile(p); + p = NULL; + } + cmsCloseProfile(pfSanity); + pfSanity = NULL; + } + + return p; } diff --git a/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java b/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java index bc14128fcee..f3fa0791d46 100644 --- a/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java +++ b/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java @@ -23,7 +23,7 @@ /** * @test - * @bug 6476665 6523403 6733501 7042594 + * @bug 6476665 6523403 6733501 7042594 7043064 * @summary Verifies reading and writing profiles and tags of the standard color * spaces * @run main ReadWriteProfileTest @@ -82,6 +82,7 @@ public class ReadWriteProfileTest implements Runnable { public void run() { for (int i = 0; i < cspaces.length; i++) { + System.out.println("Profile: " + csNames[i]); ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]); byte [] data = pf.getData(); pf = ICC_Profile.getInstance(data); @@ -92,6 +93,10 @@ public class ReadWriteProfileTest implements Runnable { } for (int tagSig : tags[i].keySet()) { + String signature = SigToString(tagSig); + System.out.printf("Tag: %s\n", signature); + System.out.flush(); + byte [] tagData = pf.getData(tagSig); byte [] empty = new byte[tagData.length]; boolean emptyDataRejected = false; @@ -104,15 +109,23 @@ public class ReadWriteProfileTest implements Runnable { throw new RuntimeException("Test failed: empty tag data was not rejected."); } - pf.setData(tagSig, tagData); - + try { + pf.setData(tagSig, tagData); + } catch (IllegalArgumentException e) { + // let's ignore this exception for Kodak proprietary tags + if (isKodakExtention(signature)) { + System.out.println("Ignore Kodak tag: " + signature); + } else { + throw new RuntimeException("Test failed!", e); + } + } byte [] tagData1 = pf.getData(tagSig); if (!Arrays.equals(tagData1, tags[i].get(tagSig))) { System.err.println("Incorrect result of getData(int) with" + " tag " + - Integer.toHexString(tagSig) + + SigToString(tagSig) + " of " + csNames[i] + " profile"); throw new RuntimeException("Incorrect result of " + @@ -122,6 +135,19 @@ public class ReadWriteProfileTest implements Runnable { } } + private static boolean isKodakExtention(String signature) { + return signature.matches("K\\d\\d\\d"); + } + + private static String SigToString(int tagSig ) { + return String.format("%c%c%c%c", + (char)(0xff & (tagSig >> 24)), + (char)(0xff & (tagSig >> 16)), + (char)(0xff & (tagSig >> 8)), + (char)(0xff & (tagSig))); + + } + public static void main(String [] args) { ReadWriteProfileTest test = new ReadWriteProfileTest(); test.run(); From 5159f55769cb383f4297b3553acb5d6a6e5a25ff Mon Sep 17 00:00:00 2001 From: Clemens Eisserer Date: Wed, 4 Sep 2013 12:38:00 +0400 Subject: [PATCH 0195/1294] 7159455: Nimbus scrollbar rendering glitch with xrender enabled on i945GM Reviewed-by: prr, bae --- .../classes/sun/java2d/xr/XRPMBlitLoops.java | 92 +++++++++---------- 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java b/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java index aaa48af2e16..20f84fa8ba3 100644 --- a/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java +++ b/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java @@ -225,6 +225,9 @@ class XRPMScaledBlit extends ScaledBlit { * @author Clemens Eisserer */ class XRPMTransformedBlit extends TransformBlit { + final Rectangle compositeBounds = new Rectangle(); + final double[] srcCoords = new double[8]; + final double[] dstCoords = new double[8]; public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) { super(srcType, CompositeType.AnyAlpha, dstType); @@ -235,61 +238,68 @@ class XRPMTransformedBlit extends TransformBlit { * method is functionally equal to: Shape shp = * xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds(); * but performs significantly better. + * Returns true if the destination shape is parallel to x/y axis */ - public Rectangle getCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) { - double[] compBounds = new double[8]; - compBounds[0] = dstx; - compBounds[1] = dsty; - compBounds[2] = dstx + width; - compBounds[3] = dsty; - compBounds[4] = dstx + width; - compBounds[5] = dsty + height; - compBounds[6] = dstx; - compBounds[7] = dsty + height; + protected boolean adjustCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) { + srcCoords[0] = dstx; + srcCoords[1] = dsty; + srcCoords[2] = dstx + width; + srcCoords[3] = dsty; + srcCoords[4] = dstx + width; + srcCoords[5] = dsty + height; + srcCoords[6] = dstx; + srcCoords[7] = dsty + height; - tr.transform(compBounds, 0, compBounds, 0, 4); + tr.transform(srcCoords, 0, dstCoords, 0, 4); - double minX = Math.min(compBounds[0], Math.min(compBounds[2], Math.min(compBounds[4], compBounds[6]))); - double minY = Math.min(compBounds[1], Math.min(compBounds[3], Math.min(compBounds[5], compBounds[7]))); - double maxX = Math.max(compBounds[0], Math.max(compBounds[2], Math.max(compBounds[4], compBounds[6]))); - double maxY = Math.max(compBounds[1], Math.max(compBounds[3], Math.max(compBounds[5], compBounds[7]))); + double minX = Math.min(dstCoords[0], Math.min(dstCoords[2], Math.min(dstCoords[4], dstCoords[6]))); + double minY = Math.min(dstCoords[1], Math.min(dstCoords[3], Math.min(dstCoords[5], dstCoords[7]))); + double maxX = Math.max(dstCoords[0], Math.max(dstCoords[2], Math.max(dstCoords[4], dstCoords[6]))); + double maxY = Math.max(dstCoords[1], Math.max(dstCoords[3], Math.max(dstCoords[5], dstCoords[7]))); - minX = Math.floor(minX); - minY = Math.floor(minY); - maxX = Math.ceil(maxX); - maxY = Math.ceil(maxY); + minX = Math.round(minX); + minY = Math.round(minY); + maxX = Math.round(maxX); + maxY = Math.round(maxY); - return new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY)); + compositeBounds.x = (int) minX; + compositeBounds.y = (int) minY; + compositeBounds.width = (int) (maxX - minX); + compositeBounds.height = (int) (maxY - minY); + + boolean is0or180 = (dstCoords[1] == dstCoords[3]) && (dstCoords[2] == dstCoords[4]); + boolean is90or270 = (dstCoords[0] == dstCoords[2]) && (dstCoords[3] == dstCoords[5]); + + return is0or180 || is90or270; } - public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy, - int dstx, int dsty, int width, int height) { + public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, + int hint, int srcx, int srcy, int dstx, int dsty, int width, int height) { try { SunToolkit.awtLock(); - int filter = XRUtils.ATransOpToXRQuality(hint); - XRSurfaceData x11sdDst = (XRSurfaceData) dst; - x11sdDst.validateAsDestination(null, clip); XRSurfaceData x11sdSrc = (XRSurfaceData) src; + + int filter = XRUtils.ATransOpToXRQuality(hint); + boolean isAxisAligned = adjustCompositeBounds(xform, dstx, dsty, width, height); + + x11sdDst.validateAsDestination(null, clip); x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null); - Rectangle bounds = getCompositeBounds(xform, dstx, dsty, width, height); - - AffineTransform trx = AffineTransform.getTranslateInstance((-bounds.x), (-bounds.y)); + AffineTransform trx = AffineTransform.getTranslateInstance(-compositeBounds.x, -compositeBounds.y); trx.concatenate(xform); AffineTransform maskTX = (AffineTransform) trx.clone(); - trx.translate(-srcx, -srcy); try { trx.invert(); } catch (NoninvertibleTransformException ex) { trx.setToIdentity(); - System.err.println("Reseted to identity!"); } - boolean omitMask = isMaskOmittable(trx, comp, filter); + boolean omitMask = (filter == XRUtils.FAST) + || (isAxisAligned && ((AlphaComposite) comp).getAlpha() == 1.0f); if (!omitMask) { XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage(); @@ -297,33 +307,17 @@ class XRPMTransformedBlit extends TransformBlit { x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter); int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height); x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture, - 0, 0, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height); + 0, 0, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height); } else { int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad; x11sdSrc.validateAsSource(trx, repeat, filter); - x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height); + x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height); } } finally { SunToolkit.awtUnlock(); } } - - /* TODO: Is mask ever omitable??? ... should be for 90 degree rotation and no shear, but we always need to use RepeatPad */ - protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int filter) { - return (filter == XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /* - * If - * translate - * is - * integer - * only - */ - && trx.getTranslateY() == (int) trx.getTranslateY() && (trx.getShearX() == 0 && trx.getShearY() == 0 // Only - // 90 degree - // rotation - || trx.getShearX() == -trx.getShearY())) && ((AlphaComposite) comp).getAlpha() == 1.0f; // No - // ExtraAlpha!=1 - } } class XrSwToPMBlit extends Blit { From 1268ef5430270b148a12afc9973093ced9f1189a Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 4 Sep 2013 14:29:07 +0530 Subject: [PATCH 0196/1294] 8024120: Setting __proto__ to null removes the __proto__ property Reviewed-by: lagergren, attila --- .../internal/runtime/ScriptObject.java | 19 +++++++-- .../runtime/resources/mozilla_compat.js | 11 ----- nashorn/test/script/basic/JDK-8023368.js | 2 - .../test/script/basic/JDK-8023368.js.EXPECTED | 8 ++-- nashorn/test/script/basic/JDK-8024120.js | 42 +++++++++++++++++++ nashorn/test/script/basic/circular_proto.js | 1 - .../basic/nonextensible_proto_assign.js | 2 - 7 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8024120.js diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java index 9d7a7a6b260..1fd795fbcb4 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -87,6 +87,8 @@ import jdk.nashorn.internal.runtime.linker.NashornGuards; */ public abstract class ScriptObject extends PropertyListenerManager implements PropertyAccess { + /** __proto__ special property name */ + static final String PROTO_PROPERTY_NAME = "__proto__"; /** Search fall back routine name for "no such method" */ static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__"; @@ -130,6 +132,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr /** Indexed array data. */ private ArrayData arrayData; + static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class); + static final MethodHandle SETPROTOCHECK = findOwnMH("setProtoCheck", void.class, Object.class); + static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class); static final MethodHandle SETSPILL = findOwnMH("setSpill", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class); static final MethodHandle SETSPILLWITHNEW = findOwnMH("setSpillWithNew", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class); @@ -1745,6 +1750,10 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr MethodHandle methodHandle; if (find == null) { + if (PROTO_PROPERTY_NAME.equals(name)) { + return new GuardedInvocation(GETPROTO, NashornGuards.getScriptObjectGuard()); + } + if ("getProp".equals(operator)) { return noSuchProperty(desc, request); } else if ("getMethod".equals(operator)) { @@ -1851,6 +1860,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * toString = function() { print("global toString"); } // don't affect Object.prototype.toString */ FindProperty find = findProperty(name, true, scope, this); + // If it's not a scope search, then we don't want any inherited properties except those with user defined accessors. if (!scope && find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) { // We should still check if inherited data property is not writable @@ -1866,9 +1876,12 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr // Existing, non-writable property return createEmptySetMethod(desc, "property.not.writable", true); } - } else if (!isExtensible()) { - // Non-existing property on a non-extensible object - return createEmptySetMethod(desc, "object.non.extensible", false); + } else { + if (PROTO_PROPERTY_NAME.equals(name)) { + return new GuardedInvocation(SETPROTOCHECK, NashornGuards.getScriptObjectGuard()); + } else if (! isExtensible()) { + return createEmptySetMethod(desc, "object.non.extensible", false); + } } return new SetMethodCreator(this, find, desc).createGuardedInvocation(); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js index 60bdc7b1ab0..6b934ad4b00 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js @@ -137,17 +137,6 @@ Object.defineProperty(Object.prototype, "__lookupSetter__", { } }); -// Object.prototype.__proto__ (read-only) -Object.defineProperty(Object.prototype, "__proto__", { - configurable: true, enumerable: false, - get: function() { - return Object.getPrototypeOf(this); - }, - set: function(x) { - Object.setPrototypeOf(this, x); - } -}); - // Object.prototype.toSource Object.defineProperty(Object.prototype, "toSource", { configurable: true, enumerable: false, writable: true, diff --git a/nashorn/test/script/basic/JDK-8023368.js b/nashorn/test/script/basic/JDK-8023368.js index 9f32805caa8..da034dbc566 100644 --- a/nashorn/test/script/basic/JDK-8023368.js +++ b/nashorn/test/script/basic/JDK-8023368.js @@ -28,8 +28,6 @@ * @run */ -load("nashorn:mozilla_compat.js"); - // function to force same callsites function check(obj) { print(obj.func()); diff --git a/nashorn/test/script/basic/JDK-8023368.js.EXPECTED b/nashorn/test/script/basic/JDK-8023368.js.EXPECTED index 4ca8d077d38..c116a6b7c10 100644 --- a/nashorn/test/script/basic/JDK-8023368.js.EXPECTED +++ b/nashorn/test/script/basic/JDK-8023368.js.EXPECTED @@ -4,15 +4,15 @@ hello Func.prototype.func hello [object Object] -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 [object Object] -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 [object Object] -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 new object.toString -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 new object.toString diff --git a/nashorn/test/script/basic/JDK-8024120.js b/nashorn/test/script/basic/JDK-8024120.js new file mode 100644 index 00000000000..0ac4ff98c15 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024120.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024120: Setting __proto__ to null removes the __proto__ property + * + * @test + * @run + */ + +var obj = {}; + +obj.__proto__ = null; + +if (obj.__proto__ !== null || typeof(obj.__proto__) != 'object') { + fail("obj.__proto__ is expected to be null"); +} + +var p = Object.getPrototypeOf(obj); +if (p !== null || typeof(p) != 'object') { + fail("Object.getPrototypeOf(obj) is expected to be null"); +} diff --git a/nashorn/test/script/basic/circular_proto.js b/nashorn/test/script/basic/circular_proto.js index 5ae8f9cd03b..b381b7cf2d7 100644 --- a/nashorn/test/script/basic/circular_proto.js +++ b/nashorn/test/script/basic/circular_proto.js @@ -29,7 +29,6 @@ */ // check that we cannot create __proto__ cycle -load("nashorn:mozilla_compat.js"); var obj = {}; var obj2 = Object.create(obj); diff --git a/nashorn/test/script/basic/nonextensible_proto_assign.js b/nashorn/test/script/basic/nonextensible_proto_assign.js index 0240420d332..10ce4f53e27 100644 --- a/nashorn/test/script/basic/nonextensible_proto_assign.js +++ b/nashorn/test/script/basic/nonextensible_proto_assign.js @@ -28,8 +28,6 @@ * @run */ -load("nashorn:mozilla_compat.js") - // check that we cannot assign to __proto__ of a non-extensible object try { var obj = {} From 1530a30f52266e56a013336f3f1bc6572b0f6337 Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Wed, 4 Sep 2013 14:32:13 +0400 Subject: [PATCH 0197/1294] 8021943: FileDialog getFile returns corrupted string after previous setFile Reviewed-by: anthony, serb --- jdk/src/windows/native/sun/windows/awt_FileDialog.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp b/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp index d60fbd329b1..276f3647e68 100644 --- a/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp +++ b/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp @@ -372,7 +372,9 @@ AwtFileDialog::Show(void *p) // Report result to peer. if (result) { - jint length = (jint)GetBufferLength(ofn.lpstrFile, ofn.nMaxFile); + jint length = multipleMode + ? (jint)GetBufferLength(ofn.lpstrFile, ofn.nMaxFile) + : (jint)_tcslen(ofn.lpstrFile); jcharArray jnames = env->NewCharArray(length); env->SetCharArrayRegion(jnames, 0, length, (jchar*)ofn.lpstrFile); From cc84e69bec97b188b4b93a74a3d9f104d71cda08 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Wed, 4 Sep 2013 11:40:23 +0100 Subject: [PATCH 0198/1294] 8008981: Deprecate SecurityManager checkTopLevelWindow, checkSystemClipboardAccess, checkAwtEventQueueAccess Reviewed-by: anthony, art, mchung --- .../macosx/classes/sun/lwawt/LWToolkit.java | 3 +- .../share/classes/java/awt/TextComponent.java | 3 +- jdk/src/share/classes/java/awt/Toolkit.java | 36 ++---- jdk/src/share/classes/java/awt/Window.java | 80 ++++++-------- .../classes/java/awt/event/InputEvent.java | 3 +- .../classes/java/lang/SecurityManager.java | 21 ++++ .../classes/sun/applet/AppletSecurity.java | 2 +- .../sun/awt/dnd/SunDropTargetContextPeer.java | 3 +- .../classes/sun/swing/SwingUtilities2.java | 2 +- .../solaris/classes/sun/awt/X11/XToolkit.java | 5 +- .../classes/sun/awt/windows/WToolkit.java | 3 +- jdk/test/java/awt/security/Permissions.java | 103 ++++++++++++++++++ 12 files changed, 181 insertions(+), 83 deletions(-) create mode 100644 jdk/test/java/awt/security/Permissions.java diff --git a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java index fb7032f0b74..9765066d9d2 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java @@ -38,6 +38,7 @@ import java.util.*; import sun.awt.*; import sun.lwawt.macosx.*; import sun.print.*; +import sun.security.util.SecurityConstants; public abstract class LWToolkit extends SunToolkit implements Runnable { @@ -502,7 +503,7 @@ public abstract class LWToolkit extends SunToolkit implements Runnable { public Clipboard getSystemClipboard() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkSystemClipboardAccess(); + security.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); } synchronized (this) { diff --git a/jdk/src/share/classes/java/awt/TextComponent.java b/jdk/src/share/classes/java/awt/TextComponent.java index 7a6cd26bbf3..483657fd4ce 100644 --- a/jdk/src/share/classes/java/awt/TextComponent.java +++ b/jdk/src/share/classes/java/awt/TextComponent.java @@ -35,6 +35,7 @@ import java.text.BreakIterator; import javax.swing.text.AttributeSet; import javax.accessibility.*; import java.awt.im.InputMethodRequests; +import sun.security.util.SecurityConstants; /** * The TextComponent class is the superclass of @@ -728,7 +729,7 @@ public class TextComponent extends Component implements Accessible { SecurityManager sm = System.getSecurityManager(); if (sm == null) return true; try { - sm.checkSystemClipboardAccess(); + sm.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); return true; } catch (SecurityException e) {} return false; diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java index 92bedb7580b..32f0adab3bc 100644 --- a/jdk/src/share/classes/java/awt/Toolkit.java +++ b/jdk/src/share/classes/java/awt/Toolkit.java @@ -1270,12 +1270,8 @@ public abstract class Toolkit { *

    * Each actual implementation of this method should first check if there * is a security manager installed. If there is, the method should call - * the security manager's checkSystemClipboardAccess method - * to ensure it's ok to to access the system clipboard. If the default - * implementation of checkSystemClipboardAccess is used (that - * is, that method is not overriden), then this results in a call to the - * security manager's checkPermission method with an - * AWTPermission("accessClipboard") permission. + * the security manager's {@link SecurityManager#checkPermission + * checkPermission} method to check {@code AWTPermission("accessClipboard")}. * * @return the system Clipboard * @exception HeadlessException if GraphicsEnvironment.isHeadless() @@ -1318,14 +1314,9 @@ public abstract class Toolkit { * system selection Clipboard as described above. *

    * Each actual implementation of this method should first check if there - * is a SecurityManager installed. If there is, the method - * should call the SecurityManager's - * checkSystemClipboardAccess method to ensure that client - * code has access the system selection. If the default implementation of - * checkSystemClipboardAccess is used (that is, if the method - * is not overridden), then this results in a call to the - * SecurityManager's checkPermission method with - * an AWTPermission("accessClipboard") permission. + * is a security manager installed. If there is, the method should call + * the security manager's {@link SecurityManager#checkPermission + * checkPermission} method to check {@code AWTPermission("accessClipboard")}. * * @return the system selection as a Clipboard, or * null if the native platform does not support a @@ -1699,25 +1690,20 @@ public abstract class Toolkit { * therefore not assume that the EventQueue instance returned * by this method will be shared by other applets or the system. * - *

    First, if there is a security manager, its - * checkAwtEventQueueAccess - * method is called. - * If the default implementation of checkAwtEventQueueAccess - * is used (that is, that method is not overriden), then this results in - * a call to the security manager's checkPermission method - * with an AWTPermission("accessEventQueue") permission. + *

    If there is a security manager then its + * {@link SecurityManager#checkPermission checkPermission} method + * is called to check {@code AWTPermission("accessEventQueue")}. * * @return the EventQueue object * @throws SecurityException - * if a security manager exists and its {@link - * java.lang.SecurityManager#checkAwtEventQueueAccess} - * method denies access to the EventQueue + * if a security manager is set and it denies access to + * the {@code EventQueue} * @see java.awt.AWTPermission */ public final EventQueue getSystemEventQueue() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkAwtEventQueueAccess(); + security.checkPermission(SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION); } return getSystemEventQueueImpl(); } diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java index 4076939c7f0..c10a3b277a8 100644 --- a/jdk/src/share/classes/java/awt/Window.java +++ b/jdk/src/share/classes/java/awt/Window.java @@ -195,10 +195,9 @@ public class Window extends Container implements Accessible { /** * This represents the warning message that is * to be displayed in a non secure window. ie : - * a window that has a security manager installed for - * which calling SecurityManager.checkTopLevelWindow() - * is false. This message can be displayed anywhere in - * the window. + * a window that has a security manager installed that denies + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * This message can be displayed anywhere in the window. * * @serial * @see #getWarningString @@ -417,11 +416,10 @@ public class Window extends Container implements Accessible { * Constructs a new, initially invisible window in default size with the * specified {@code GraphicsConfiguration}. *

    - * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager, then it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")} + * to determine whether or not the window must be displayed with + * a warning banner. * * @param gc the {@code GraphicsConfiguration} of the target screen * device. If {@code gc} is {@code null}, the system default @@ -432,7 +430,6 @@ public class Window extends Container implements Accessible { * {@code GraphicsEnvironment.isHeadless()} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow */ Window(GraphicsConfiguration gc) { init(gc); @@ -511,25 +508,16 @@ public class Window extends Container implements Accessible { /** * Constructs a new, initially invisible window in the default size. - * - *

    First, if there is a security manager, its - * {@code checkTopLevelWindow} - * method is called with {@code this} - * as its argument - * to see if it's ok to display the window without a warning banner. - * If the default implementation of {@code checkTopLevelWindow} - * is used (that is, that method is not overriden), then this results in - * a call to the security manager's {@code checkPermission} method - * with an {@code AWTPermission("showWindowWithoutWarningBanner")} - * permission. It that method raises a SecurityException, - * {@code checkTopLevelWindow} returns false, otherwise it - * returns true. If it returns false, a warning banner is created. + *

    + * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * If that check fails with a {@code SecurityException} then a warning + * banner is created. * * @exception HeadlessException when * {@code GraphicsEnvironment.isHeadless()} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow */ Window() throws HeadlessException { GraphicsEnvironment.checkHeadless(); @@ -541,11 +529,10 @@ public class Window extends Container implements Accessible { * {@code Frame} as its owner. The window will not be focusable * unless its owner is showing on the screen. *

    - * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * If that check fails with a {@code SecurityException} then a warning + * banner is created. * * @param owner the {@code Frame} to act as owner or {@code null} * if this window has no owner @@ -555,7 +542,6 @@ public class Window extends Container implements Accessible { * {@code GraphicsEnvironment.isHeadless} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow * @see #isShowing */ public Window(Frame owner) { @@ -570,11 +556,10 @@ public class Window extends Container implements Accessible { * unless its nearest owning {@code Frame} or {@code Dialog} * is showing on the screen. *

    - * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * If that check fails with a {@code SecurityException} then a + * warning banner is created. * * @param owner the {@code Window} to act as owner or * {@code null} if this window has no owner @@ -585,7 +570,6 @@ public class Window extends Container implements Accessible { * {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow * @see #isShowing * * @since 1.2 @@ -603,11 +587,10 @@ public class Window extends Container implements Accessible { * its nearest owning {@code Frame} or {@code Dialog} * is showing on the screen. *

    - * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. If that + * check fails with a {@code SecurityException} then a warning banner + * is created. * * @param owner the window to act as owner or {@code null} * if this window has no owner @@ -621,7 +604,6 @@ public class Window extends Container implements Accessible { * {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow * @see GraphicsConfiguration#getBounds * @see #isShowing * @since 1.3 @@ -1362,10 +1344,9 @@ public class Window extends Container implements Accessible { * Gets the warning string that is displayed with this window. * If this window is insecure, the warning string is displayed * somewhere in the visible area of the window. A window is - * insecure if there is a security manager, and the security - * manager's {@code checkTopLevelWindow} method returns - * {@code false} when this window is passed to it as an - * argument. + * insecure if there is a security manager and the security + * manager denies + * {@code AWTPermission("showWindowWithoutWarningBanner")}. *

    * If the window is secure, then {@code getWarningString} * returns {@code null}. If the window is insecure, this @@ -1373,7 +1354,6 @@ public class Window extends Container implements Accessible { * {@code awt.appletWarning} * and returns the string value of that property. * @return the warning string for this window. - * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object) */ public final String getWarningString() { return warningString; @@ -1383,10 +1363,12 @@ public class Window extends Container implements Accessible { warningString = null; SecurityManager sm = System.getSecurityManager(); if (sm != null) { - if (!sm.checkTopLevelWindow(this)) { + try { + sm.checkPermission(SecurityConstants.AWT.TOPLEVEL_WINDOW_PERMISSION); + } catch (SecurityException se) { // make sure the privileged action is only // for getting the property! We don't want the - // above checkTopLevelWindow call to always succeed! + // above checkPermission call to always succeed! warningString = AccessController.doPrivileged( new GetPropertyAction("awt.appletWarning", "Java Applet Window")); diff --git a/jdk/src/share/classes/java/awt/event/InputEvent.java b/jdk/src/share/classes/java/awt/event/InputEvent.java index 078b1a16d6a..24965d20caf 100644 --- a/jdk/src/share/classes/java/awt/event/InputEvent.java +++ b/jdk/src/share/classes/java/awt/event/InputEvent.java @@ -33,6 +33,7 @@ import java.util.Arrays; import sun.awt.AWTAccessor; import sun.util.logging.PlatformLogger; +import sun.security.util.SecurityConstants; /** * The root event class for all component-level input events. @@ -350,7 +351,7 @@ public abstract class InputEvent extends ComponentEvent { SecurityManager sm = System.getSecurityManager(); if (sm != null) { try { - sm.checkSystemClipboardAccess(); + sm.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); b = true; } catch (SecurityException se) { if (logger.isLoggable(PlatformLogger.Level.FINE)) { diff --git a/jdk/src/share/classes/java/lang/SecurityManager.java b/jdk/src/share/classes/java/lang/SecurityManager.java index 34be905bd02..3565082033c 100644 --- a/jdk/src/share/classes/java/lang/SecurityManager.java +++ b/jdk/src/share/classes/java/lang/SecurityManager.java @@ -1336,9 +1336,16 @@ class SecurityManager { * top-level windows; false otherwise. * @exception NullPointerException if the window argument is * null. + * @deprecated The dependency on {@code AWTPermission} creates an + * impediment to future modularization of the Java platform. + * Users of this method should instead invoke + * {@link #checkPermission} directly. + * This method will be changed in a future release to check + * the permission {@code java.security.AllPermission}. * @see java.awt.Window * @see #checkPermission(java.security.Permission) checkPermission */ + @Deprecated public boolean checkTopLevelWindow(Object window) { if (window == null) { throw new NullPointerException("window can't be null"); @@ -1398,8 +1405,15 @@ class SecurityManager { * @since JDK1.1 * @exception SecurityException if the calling thread does not have * permission to access the system clipboard. + * @deprecated The dependency on {@code AWTPermission} creates an + * impediment to future modularization of the Java platform. + * Users of this method should instead invoke + * {@link #checkPermission} directly. + * This method will be changed in a future release to check + * the permission {@code java.security.AllPermission}. * @see #checkPermission(java.security.Permission) checkPermission */ + @Deprecated public void checkSystemClipboardAccess() { Permission perm = SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION; if (perm == null) { @@ -1427,8 +1441,15 @@ class SecurityManager { * @since JDK1.1 * @exception SecurityException if the calling thread does not have * permission to access the AWT event queue. + * @deprecated The dependency on {@code AWTPermission} creates an + * impediment to future modularization of the Java platform. + * Users of this method should instead invoke + * {@link #checkPermission} directly. + * This method will be changed in a future release to check + * the permission {@code java.security.AllPermission}. * @see #checkPermission(java.security.Permission) checkPermission */ + @Deprecated public void checkAwtEventQueueAccess() { Permission perm = SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION; if (perm == null) { diff --git a/jdk/src/share/classes/sun/applet/AppletSecurity.java b/jdk/src/share/classes/sun/applet/AppletSecurity.java index 4bd67decbcc..b6a71f7b910 100644 --- a/jdk/src/share/classes/sun/applet/AppletSecurity.java +++ b/jdk/src/share/classes/sun/applet/AppletSecurity.java @@ -314,7 +314,7 @@ class AppletSecurity extends AWTSecurityManager { // If we're about to allow access to the main EventQueue, // and anything untrusted is on the class context stack, // disallow access. - super.checkAwtEventQueueAccess(); + super.checkPermission(SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION); } } // checkAwtEventQueueAccess() diff --git a/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java b/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java index efbf14f1a6a..ed5b2b8b97b 100644 --- a/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java +++ b/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java @@ -57,6 +57,7 @@ import sun.awt.AppContext; import sun.awt.SunToolkit; import sun.awt.datatransfer.DataTransferer; import sun.awt.datatransfer.ToolkitThreadBlockedHandler; +import sun.security.util.SecurityConstants; /** *

    @@ -225,7 +226,7 @@ public abstract class SunDropTargetContextPeer implements DropTargetContextPeer, SecurityManager sm = System.getSecurityManager(); try { if (!dropInProcess && sm != null) { - sm.checkSystemClipboardAccess(); + sm.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); } } catch (Exception e) { Thread currentThread = Thread.currentThread(); diff --git a/jdk/src/share/classes/sun/swing/SwingUtilities2.java b/jdk/src/share/classes/sun/swing/SwingUtilities2.java index a1903f2bdd2..6bbbf0a5687 100644 --- a/jdk/src/share/classes/sun/swing/SwingUtilities2.java +++ b/jdk/src/share/classes/sun/swing/SwingUtilities2.java @@ -1184,7 +1184,7 @@ public class SwingUtilities2 { canAccess = true; } else { try { - sm.checkSystemClipboardAccess(); + sm.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); canAccess = true; } catch (SecurityException e) { } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java index 32eceaae3be..9b4daa1cef6 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -54,6 +54,7 @@ import sun.print.PrintJob2D; import sun.security.action.GetPropertyAction; import sun.security.action.GetBooleanAction; import sun.util.logging.PlatformLogger; +import sun.security.util.SecurityConstants; public final class XToolkit extends UNIXToolkit implements Runnable { private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XToolkit"); @@ -1152,7 +1153,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { public Clipboard getSystemClipboard() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkSystemClipboardAccess(); + security.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); } synchronized (this) { if (clipboard == null) { @@ -1165,7 +1166,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { public Clipboard getSystemSelection() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkSystemClipboardAccess(); + security.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); } synchronized (this) { if (selection == null) { diff --git a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java index 25b88f384cf..0f67ffe0a50 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java +++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java @@ -64,6 +64,7 @@ import sun.font.FontManagerFactory; import sun.font.SunFontManager; import sun.misc.PerformanceLogger; import sun.util.logging.PlatformLogger; +import sun.security.util.SecurityConstants; public class WToolkit extends SunToolkit implements Runnable { @@ -681,7 +682,7 @@ public class WToolkit extends SunToolkit implements Runnable { public Clipboard getSystemClipboard() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkSystemClipboardAccess(); + security.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); } synchronized (this) { if (clipboard == null) { diff --git a/jdk/test/java/awt/security/Permissions.java b/jdk/test/java/awt/security/Permissions.java new file mode 100644 index 00000000000..3f0a3ad24e3 --- /dev/null +++ b/jdk/test/java/awt/security/Permissions.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013, 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 8008981 + * @summary Test that selected Toolkit and Window methods/constructors do + * the appropriate permission check + * @run main/othervm Permissions + */ + +import java.awt.AWTPermission; +import java.awt.Frame; +import java.awt.GraphicsConfiguration; +import java.awt.Toolkit; +import java.awt.Window; +import java.util.ArrayList; +import java.util.List; +import java.security.Permission; + +public class Permissions { + + static class MySecurityManager extends SecurityManager { + private List permissionsChecked = new ArrayList<>(); + + static MySecurityManager install() { + MySecurityManager sm = new MySecurityManager(); + System.setSecurityManager(sm); + return sm; + } + + @Override + public void checkPermission(Permission perm) { + permissionsChecked.add(perm); + } + + void prepare(String msg) { + System.out.println(msg); + permissionsChecked.clear(); + } + + /** + * Checks the security manager's checkPermission method was invoked + * to check the given permission and target name. + */ + void assertChecked(Class type, String name) { + for (Permission perm: permissionsChecked) { + if (type.isInstance(perm) && perm.getName().equals(name)) + return; + } + throw new RuntimeException(type.getName() + "(\"" + name + "\") not checked"); + } + } + + public static void main(String[] args) { + MySecurityManager sm = MySecurityManager.install(); + + Toolkit toolkit = Toolkit.getDefaultToolkit(); + + sm.prepare("Toolkit.getSystemClipboard()"); + toolkit.getSystemClipboard(); + sm.assertChecked(AWTPermission.class, "accessClipboard"); + + sm.prepare("Toolkit.getSystemEventQueue()"); + toolkit.getSystemEventQueue(); + sm.assertChecked(AWTPermission.class, "accessEventQueue"); + + sm.prepare("Toolkit.getSystemSelection()"); + toolkit.getSystemSelection(); + //sm.assertChecked(AWTPermission.class, "accessClipboard"); + + sm.prepare("Window(Frame)"); + new Window((Frame)null); + sm.assertChecked(AWTPermission.class, "showWindowWithoutWarningBanner"); + + sm.prepare("Window(Window)"); + new Window((Window)null); + sm.assertChecked(AWTPermission.class, "showWindowWithoutWarningBanner"); + + sm.prepare("Window(Window,GraphicsConfiguration)"); + new Window((Window)null, (GraphicsConfiguration)null); + sm.assertChecked(AWTPermission.class, "showWindowWithoutWarningBanner"); + } +} From d28e08b5296726876b32631240631d258f61d78d Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Wed, 4 Sep 2013 11:53:09 +0100 Subject: [PATCH 0199/1294] 8008275: javac.Main should be @Supported Reviewed-by: jjg --- langtools/src/share/classes/com/sun/tools/javac/Main.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/Main.java b/langtools/src/share/classes/com/sun/tools/javac/Main.java index 2587d198972..43300b6c3c5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/Main.java +++ b/langtools/src/share/classes/com/sun/tools/javac/Main.java @@ -30,14 +30,6 @@ import java.io.PrintWriter; /** * The programmatic interface for the Java Programming Language * compiler, javac. - * - *

    Except for the two methods - * {@link #compile(java.lang.String[])} - * {@link #compile(java.lang.String[],java.io.PrintWriter)}, - * nothing described in this source file is part of any supported - * API. If you write code that depends on this, you do so at your own - * risk. This code and its internal interfaces are subject to change - * or deletion without notice. */ @jdk.Supported public class Main { From 34d47bd6722ffc6e16a4b74eb5b3bdb134209fe6 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Wed, 4 Sep 2013 08:55:08 -0400 Subject: [PATCH 0200/1294] 8022798: "assert(seq > 0) failed: counter overflow" in Kitchensink Removed incorrect assertion, sequence number can overflow Reviewed-by: dholmes, kamg --- hotspot/src/share/vm/services/memPtr.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/services/memPtr.cpp b/hotspot/src/share/vm/services/memPtr.cpp index 3e124e2bde2..bc460517c58 100644 --- a/hotspot/src/share/vm/services/memPtr.cpp +++ b/hotspot/src/share/vm/services/memPtr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,9 +34,9 @@ jint SequenceGenerator::next() { jint seq = Atomic::add(1, &_seq_number); if (seq < 0) { MemTracker::shutdown(MemTracker::NMT_sequence_overflow); + } else { + NOT_PRODUCT(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;) } - assert(seq > 0, "counter overflow"); - NOT_PRODUCT(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;) return seq; } From ac101a9d997181c3be91383172841301401091f2 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 4 Sep 2013 15:32:59 +0200 Subject: [PATCH 0201/1294] 6823527: java.util.logging.Handler has thread safety issues Reviewed-by: dholmes, mchung --- .../java/util/logging/ConsoleHandler.java | 5 ++- .../java/util/logging/FileHandler.java | 13 +++++-- .../classes/java/util/logging/Handler.java | 34 ++++++++++++------- .../java/util/logging/MemoryHandler.java | 11 +++--- .../java/util/logging/SocketHandler.java | 3 +- .../java/util/logging/StreamHandler.java | 10 ++++-- 6 files changed, 50 insertions(+), 26 deletions(-) diff --git a/jdk/src/share/classes/java/util/logging/ConsoleHandler.java b/jdk/src/share/classes/java/util/logging/ConsoleHandler.java index a8b4bc4f0cd..36ef6be6801 100644 --- a/jdk/src/share/classes/java/util/logging/ConsoleHandler.java +++ b/jdk/src/share/classes/java/util/logging/ConsoleHandler.java @@ -26,9 +26,6 @@ package java.util.logging; -import java.io.*; -import java.net.*; - /** * This Handler publishes log records to System.err. * By default the SimpleFormatter is used to generate brief summaries. @@ -114,6 +111,7 @@ public class ConsoleHandler extends StreamHandler { * @param record description of the log event. A null record is * silently ignored and is not published */ + @Override public void publish(LogRecord record) { super.publish(record); flush(); @@ -124,6 +122,7 @@ public class ConsoleHandler extends StreamHandler { * to close the output stream. That is, we do not * close System.err. */ + @Override public void close() { flush(); } diff --git a/jdk/src/share/classes/java/util/logging/FileHandler.java b/jdk/src/share/classes/java/util/logging/FileHandler.java index 52360c206ee..b2ac0d9d3e0 100644 --- a/jdk/src/share/classes/java/util/logging/FileHandler.java +++ b/jdk/src/share/classes/java/util/logging/FileHandler.java @@ -149,7 +149,7 @@ public class FileHandler extends StreamHandler { private FileChannel lockFileChannel; private File files[]; private static final int MAX_LOCKS = 100; - private static java.util.HashMap locks = new java.util.HashMap<>(); + private static final java.util.HashMap locks = new java.util.HashMap<>(); /** * A metered stream is a subclass of OutputStream that @@ -157,7 +157,7 @@ public class FileHandler extends StreamHandler { * (b) keeps track of how many bytes have been written */ private class MeteredStream extends OutputStream { - OutputStream out; + final OutputStream out; int written; MeteredStream(OutputStream out, int written) { @@ -165,25 +165,30 @@ public class FileHandler extends StreamHandler { this.written = written; } + @Override public void write(int b) throws IOException { out.write(b); written++; } + @Override public void write(byte buff[]) throws IOException { out.write(buff); written += buff.length; } + @Override public void write(byte buff[], int off, int len) throws IOException { out.write(buff,off,len); written += len; } + @Override public void flush() throws IOException { out.flush(); } + @Override public void close() throws IOException { out.close(); } @@ -607,6 +612,7 @@ public class FileHandler extends StreamHandler { * @param record description of the log event. A null record is * silently ignored and is not published */ + @Override public synchronized void publish(LogRecord record) { if (!isLoggable(record)) { return; @@ -620,6 +626,7 @@ public class FileHandler extends StreamHandler { // currently being called from untrusted code. // So it is safe to raise privilege here. AccessController.doPrivileged(new PrivilegedAction() { + @Override public Object run() { rotate(); return null; @@ -634,6 +641,7 @@ public class FileHandler extends StreamHandler { * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). */ + @Override public synchronized void close() throws SecurityException { super.close(); // Unlock any lock file. @@ -656,6 +664,7 @@ public class FileHandler extends StreamHandler { private static class InitializationErrorManager extends ErrorManager { Exception lastException; + @Override public void error(String msg, Exception ex, int code) { lastException = ex; } diff --git a/jdk/src/share/classes/java/util/logging/Handler.java b/jdk/src/share/classes/java/util/logging/Handler.java index a8c3eb4b036..1cc7b43c7de 100644 --- a/jdk/src/share/classes/java/util/logging/Handler.java +++ b/jdk/src/share/classes/java/util/logging/Handler.java @@ -47,12 +47,20 @@ import java.io.UnsupportedEncodingException; public abstract class Handler { private static final int offValue = Level.OFF.intValue(); - private LogManager manager = LogManager.getLogManager(); - private Filter filter; - private Formatter formatter; - private Level logLevel = Level.ALL; - private ErrorManager errorManager = new ErrorManager(); - private String encoding; + private final LogManager manager = LogManager.getLogManager(); + + // We're using volatile here to avoid synchronizing getters, which + // would prevent other threads from calling isLoggable() + // while publish() is executing. + // On the other hand, setters will be synchronized to exclude concurrent + // execution with more complex methods, such as StreamHandler.publish(). + // We wouldn't want 'level' to be changed by another thread in the middle + // of the execution of a 'publish' call. + private volatile Filter filter; + private volatile Formatter formatter; + private volatile Level logLevel = Level.ALL; + private volatile ErrorManager errorManager = new ErrorManager(); + private volatile String encoding; // Package private support for security checking. When sealed // is true, we access check updates to the class. @@ -110,7 +118,7 @@ public abstract class Handler { * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). */ - public void setFormatter(Formatter newFormatter) throws SecurityException { + public synchronized void setFormatter(Formatter newFormatter) throws SecurityException { checkPermission(); // Check for a null pointer: newFormatter.getClass(); @@ -138,7 +146,7 @@ public abstract class Handler { * @exception UnsupportedEncodingException if the named encoding is * not supported. */ - public void setEncoding(String encoding) + public synchronized void setEncoding(String encoding) throws SecurityException, java.io.UnsupportedEncodingException { checkPermission(); if (encoding != null) { @@ -174,7 +182,7 @@ public abstract class Handler { * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). */ - public void setFilter(Filter newFilter) throws SecurityException { + public synchronized void setFilter(Filter newFilter) throws SecurityException { checkPermission(); filter = newFilter; } @@ -198,7 +206,7 @@ public abstract class Handler { * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). */ - public void setErrorManager(ErrorManager em) { + public synchronized void setErrorManager(ErrorManager em) { checkPermission(); if (em == null) { throw new NullPointerException(); @@ -264,7 +272,7 @@ public abstract class Handler { * than this level will be discarded. * @return the level of messages being logged. */ - public synchronized Level getLevel() { + public Level getLevel() { return logLevel; } @@ -282,11 +290,11 @@ public abstract class Handler { * */ public boolean isLoggable(LogRecord record) { - int levelValue = getLevel().intValue(); + final int levelValue = getLevel().intValue(); if (record.getLevel().intValue() < levelValue || levelValue == offValue) { return false; } - Filter filter = getFilter(); + final Filter filter = getFilter(); if (filter == null) { return true; } diff --git a/jdk/src/share/classes/java/util/logging/MemoryHandler.java b/jdk/src/share/classes/java/util/logging/MemoryHandler.java index ddf72c2a1e1..684ff8f8573 100644 --- a/jdk/src/share/classes/java/util/logging/MemoryHandler.java +++ b/jdk/src/share/classes/java/util/logging/MemoryHandler.java @@ -88,7 +88,7 @@ package java.util.logging; public class MemoryHandler extends Handler { private final static int DEFAULT_SIZE = 1000; - private Level pushLevel; + private volatile Level pushLevel; private int size; private Handler target; private LogRecord buffer[]; @@ -188,6 +188,7 @@ public class MemoryHandler extends Handler { * @param record description of the log event. A null record is * silently ignored and is not published */ + @Override public synchronized void publish(LogRecord record) { if (!isLoggable(record)) { return; @@ -227,6 +228,7 @@ public class MemoryHandler extends Handler { * Note that the current contents of the MemoryHandler * buffer are not written out. That requires a "push". */ + @Override public void flush() { target.flush(); } @@ -238,6 +240,7 @@ public class MemoryHandler extends Handler { * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). */ + @Override public void close() throws SecurityException { target.close(); setLevel(Level.OFF); @@ -252,11 +255,10 @@ public class MemoryHandler extends Handler { * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). */ - public void setPushLevel(Level newLevel) throws SecurityException { + public synchronized void setPushLevel(Level newLevel) throws SecurityException { if (newLevel == null) { throw new NullPointerException(); } - LogManager manager = LogManager.getLogManager(); checkPermission(); pushLevel = newLevel; } @@ -266,7 +268,7 @@ public class MemoryHandler extends Handler { * * @return the value of the pushLevel */ - public synchronized Level getPushLevel() { + public Level getPushLevel() { return pushLevel; } @@ -283,6 +285,7 @@ public class MemoryHandler extends Handler { * @return true if the LogRecord would be logged. * */ + @Override public boolean isLoggable(LogRecord record) { return super.isLoggable(record); } diff --git a/jdk/src/share/classes/java/util/logging/SocketHandler.java b/jdk/src/share/classes/java/util/logging/SocketHandler.java index d7f2f31adbd..0d7f2ceedf4 100644 --- a/jdk/src/share/classes/java/util/logging/SocketHandler.java +++ b/jdk/src/share/classes/java/util/logging/SocketHandler.java @@ -82,7 +82,6 @@ public class SocketHandler extends StreamHandler { private Socket sock; private String host; private int port; - private String portProperty; // Private method to configure a SocketHandler from LogManager // properties and/or default values as specified in the class @@ -177,6 +176,7 @@ public class SocketHandler extends StreamHandler { * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). */ + @Override public synchronized void close() throws SecurityException { super.close(); if (sock != null) { @@ -195,6 +195,7 @@ public class SocketHandler extends StreamHandler { * @param record description of the log event. A null record is * silently ignored and is not published */ + @Override public synchronized void publish(LogRecord record) { if (!isLoggable(record)) { return; diff --git a/jdk/src/share/classes/java/util/logging/StreamHandler.java b/jdk/src/share/classes/java/util/logging/StreamHandler.java index 96dff8c9df0..b3f23743611 100644 --- a/jdk/src/share/classes/java/util/logging/StreamHandler.java +++ b/jdk/src/share/classes/java/util/logging/StreamHandler.java @@ -73,10 +73,9 @@ import java.io.*; */ public class StreamHandler extends Handler { - private LogManager manager = LogManager.getLogManager(); private OutputStream output; private boolean doneHeader; - private Writer writer; + private volatile Writer writer; // Private method to configure a StreamHandler from LogManager // properties and/or default values as specified in the class @@ -169,7 +168,8 @@ public class StreamHandler extends Handler { * @exception UnsupportedEncodingException if the named encoding is * not supported. */ - public void setEncoding(String encoding) + @Override + public synchronized void setEncoding(String encoding) throws SecurityException, java.io.UnsupportedEncodingException { super.setEncoding(encoding); if (output == null) { @@ -201,6 +201,7 @@ public class StreamHandler extends Handler { * @param record description of the log event. A null record is * silently ignored and is not published */ + @Override public synchronized void publish(LogRecord record) { if (!isLoggable(record)) { return; @@ -240,6 +241,7 @@ public class StreamHandler extends Handler { * @return true if the LogRecord would be logged. * */ + @Override public boolean isLoggable(LogRecord record) { if (writer == null || record == null) { return false; @@ -250,6 +252,7 @@ public class StreamHandler extends Handler { /** * Flush any buffered messages. */ + @Override public synchronized void flush() { if (writer != null) { try { @@ -294,6 +297,7 @@ public class StreamHandler extends Handler { * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). */ + @Override public synchronized void close() throws SecurityException { flushAndClose(); } From b33bcb918589f5f59f89f207af0aee00c2e5d4a0 Mon Sep 17 00:00:00 2001 From: Mikhail Cherkasov Date: Wed, 4 Sep 2013 18:12:49 +0400 Subject: [PATCH 0202/1294] 8023565: JPG causes javax.imageio.IIOException: ICC APP2 encoutered without prior JFIF Reviewed-by: bae, vadim --- .../com/sun/imageio/plugins/jpeg/JPEGMetadata.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java index 6036cb49870..c7b8fd3d0e5 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -278,10 +278,11 @@ public class JPEGMetadata extends IIOMetadata implements Cloneable { (JFIFMarkerSegment) findMarkerSegment (JFIFMarkerSegment.class, true); if (jfif == null) { - throw new IIOException - ("ICC APP2 encountered without prior JFIF!"); + newGuy = new MarkerSegment(buffer); + newGuy.loadData(buffer); + } else { + jfif.addICC(buffer); } - jfif.addICC(buffer); // newGuy remains null } else { newGuy = new MarkerSegment(buffer); From 61fc7dfe0c702ee5399a453515cc986eae0a7077 Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Wed, 4 Sep 2013 15:18:54 +0100 Subject: [PATCH 0203/1294] 8023762: Add ChronoPeriod interface and bind period to Chronology Make Period ISO-only, adding a Chronology-specific period concept Reviewed-by: sherman --- .../share/classes/java/time/LocalDate.java | 6 +- jdk/src/share/classes/java/time/Period.java | 198 +++++---- .../java/time/chrono/ChronoLocalDate.java | 12 +- .../java/time/chrono/ChronoPeriod.java | 365 ++++++++++++++++ .../java/time/chrono/ChronoPeriodImpl.java | 399 ++++++++++++++++++ .../classes/java/time/chrono/Chronology.java | 35 +- .../classes/java/time/chrono/HijrahDate.java | 5 +- .../java/time/chrono/IsoChronology.java | 19 + .../java/time/chrono/JapaneseDate.java | 5 +- .../classes/java/time/chrono/MinguoDate.java | 5 +- .../share/classes/java/time/chrono/Ser.java | 5 + .../java/time/chrono/ThaiBuddhistDate.java | 5 +- .../classes/java/time/temporal/Temporal.java | 27 +- .../java/time/tck/java/time/TCKPeriod.java | 111 ++++- .../tck/java/time/chrono/TCKChronoPeriod.java | 279 ++++++++++++ .../time/chrono/TCKJapaneseChronology.java | 10 +- .../java/time/chrono/TCKMinguoChronology.java | 12 +- .../chrono/TCKThaiBuddhistChronology.java | 10 +- .../time/chrono/TestUmmAlQuraChronology.java | 22 +- 19 files changed, 1390 insertions(+), 140 deletions(-) create mode 100644 jdk/src/share/classes/java/time/chrono/ChronoPeriod.java create mode 100644 jdk/src/share/classes/java/time/chrono/ChronoPeriodImpl.java create mode 100644 jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java diff --git a/jdk/src/share/classes/java/time/LocalDate.java b/jdk/src/share/classes/java/time/LocalDate.java index e2043f9a90d..110a80fc9c0 100644 --- a/jdk/src/share/classes/java/time/LocalDate.java +++ b/jdk/src/share/classes/java/time/LocalDate.java @@ -1642,12 +1642,12 @@ public final class LocalDate * * The choice should be made based on which makes the code more readable. * - * @param endDate the end date, exclusive, which may be in any chronology, not null + * @param endDateExclusive the end date, exclusive, which may be in any chronology, not null * @return the period between this date and the end date, not null */ @Override - public Period until(ChronoLocalDate endDate) { - LocalDate end = LocalDate.from(endDate); + public Period until(ChronoLocalDate endDateExclusive) { + LocalDate end = LocalDate.from(endDateExclusive); long totalMonths = end.getProlepticMonth() - this.getProlepticMonth(); // safe int days = end.day - this.day; if (totalMonths > 0 && days < 0) { diff --git a/jdk/src/share/classes/java/time/Period.java b/jdk/src/share/classes/java/time/Period.java index 161ce49e565..bd272a9913e 100644 --- a/jdk/src/share/classes/java/time/Period.java +++ b/jdk/src/share/classes/java/time/Period.java @@ -61,7 +61,6 @@ */ package java.time; -import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoUnit.DAYS; import static java.time.temporal.ChronoUnit.MONTHS; import static java.time.temporal.ChronoUnit.YEARS; @@ -70,17 +69,19 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.io.InvalidObjectException; -import java.io.InvalidObjectException; import java.io.Serializable; import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoPeriod; import java.time.chrono.Chronology; +import java.time.chrono.IsoChronology; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; +import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAmount; +import java.time.temporal.TemporalQuery; import java.time.temporal.TemporalUnit; import java.time.temporal.UnsupportedTemporalTypeException; -import java.time.temporal.ValueRange; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -89,12 +90,13 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * A date-based amount of time, such as '2 years, 3 months and 4 days'. + * A date-based amount of time in the ISO-8601 calendar system, + * such as '2 years, 3 months and 4 days'. *

    * This class models a quantity or amount of time in terms of years, months and days. * See {@link Duration} for the time-based equivalent to this class. *

    - * Durations and period differ in their treatment of daylight savings time + * Durations and periods differ in their treatment of daylight savings time * when added to {@link ZonedDateTime}. A {@code Duration} will add an exact * number of seconds, thus a duration of one day is always exactly 24 hours. * By contrast, a {@code Period} will add a conceptual day, trying to maintain @@ -110,14 +112,12 @@ import java.util.regex.Pattern; * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}. * All three fields are always present, but may be set to zero. *

    - * The period may be used with any calendar system. - * The meaning of a "year" or "month" is only applied when the object is added to a date. + * The ISO-8601 calendar system is the modern civil calendar system used today + * in most of the world. It is equivalent to the proleptic Gregorian calendar + * system, in which today's rules for leap years are applied for all time. *

    * The period is modeled as a directed amount of time, meaning that individual parts of the * period may be negative. - *

    - * The months and years fields may be {@linkplain #normalized() normalized}. - * The normalization assumes a 12 month year, so is not appropriate for all calendar systems. * * @implSpec * This class is immutable and thread-safe. @@ -125,7 +125,7 @@ import java.util.regex.Pattern; * @since 1.8 */ public final class Period - implements TemporalAmount, Serializable { + implements ChronoPeriod, Serializable { /** * A constant for a period of zero. @@ -140,6 +140,7 @@ public final class Period */ private final static Pattern PATTERN = Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)W)?(?:([-+]?[0-9]+)D)?", Pattern.CASE_INSENSITIVE); + /** * The set of supported units. */ @@ -234,12 +235,14 @@ public final class Period *

    * This obtains a period based on the specified amount. * A {@code TemporalAmount} represents an amount of time, which may be - * date-based or time-based, which this factory extracts to a period. + * date-based or time-based, which this factory extracts to a {@code Period}. *

    * The conversion loops around the set of units from the amount and uses * the {@link ChronoUnit#YEARS YEARS}, {@link ChronoUnit#MONTHS MONTHS} * and {@link ChronoUnit#DAYS DAYS} units to create a period. * If any other units are found then an exception is thrown. + *

    + * If the amount is a {@code ChronoPeriod} then it must use the ISO chronology. * * @param amount the temporal amount to convert, not null * @return the equivalent period, not null @@ -247,6 +250,14 @@ public final class Period * @throws ArithmeticException if the amount of years, months or days exceeds an int */ public static Period from(TemporalAmount amount) { + if (amount instanceof Period) { + return (Period) amount; + } + if (amount instanceof ChronoPeriod) { + if (IsoChronology.INSTANCE.equals(((ChronoPeriod) amount).getChronology()) == false) { + throw new DateTimeException("Period requires ISO chronology: " + amount); + } + } Objects.requireNonNull(amount, "amount"); int years = 0; int months = 0; @@ -358,13 +369,13 @@ public final class Period * The result of this method can be a negative period if the end is before the start. * The negative sign will be the same in each of year, month and day. * - * @param startDate the start date, inclusive, not null - * @param endDate the end date, exclusive, not null + * @param startDateInclusive the start date, inclusive, not null + * @param endDateExclusive the end date, exclusive, not null * @return the period between this date and the end date, not null * @see ChronoLocalDate#until(ChronoLocalDate) */ - public static Period between(LocalDate startDate, LocalDate endDate) { - return startDate.until(endDate); + public static Period between(LocalDate startDateInclusive, LocalDate endDateExclusive) { + return startDateInclusive.until(endDateExclusive); } //----------------------------------------------------------------------- @@ -439,6 +450,21 @@ public final class Period return SUPPORTED_UNITS; } + /** + * Gets the chronology of this period, which is the ISO calendar system. + *

    + * The {@code Chronology} represents the calendar system in use. + * The ISO-8601 calendar system is the modern civil calendar system used today + * in most of the world. It is equivalent to the proleptic Gregorian calendar + * system, in which today's rules for leap years are applied for all time. + * + * @return the ISO chronology, not null + */ + @Override + public IsoChronology getChronology() { + return IsoChronology.INSTANCE; + } + //----------------------------------------------------------------------- /** * Checks if all three units of this period are zero. @@ -468,7 +494,7 @@ public final class Period *

    * This returns the years unit. *

    - * The months unit is not normalized with the years unit. + * The months unit is not automatically normalized with the years unit. * This means that a period of "15 months" is different to a period * of "1 year and 3 months". * @@ -483,7 +509,7 @@ public final class Period *

    * This returns the months unit. *

    - * The months unit is not normalized with the years unit. + * The months unit is not automatically normalized with the years unit. * This means that a period of "15 months" is different to a period * of "1 year and 3 months". * @@ -511,7 +537,7 @@ public final class Period * This sets the amount of the years unit in a copy of this period. * The months and days units are unaffected. *

    - * The months unit is not normalized with the years unit. + * The months unit is not automatically normalized with the years unit. * This means that a period of "15 months" is different to a period * of "1 year and 3 months". *

    @@ -533,7 +559,7 @@ public final class Period * This sets the amount of the months unit in a copy of this period. * The years and days units are unaffected. *

    - * The months unit is not normalized with the years unit. + * The months unit is not automatically normalized with the years unit. * This means that a period of "15 months" is different to a period * of "1 year and 3 months". *

    @@ -572,21 +598,28 @@ public final class Period * Returns a copy of this period with the specified period added. *

    * This operates separately on the years, months and days. + * No normalization is performed. *

    * For example, "1 year, 6 months and 3 days" plus "2 years, 2 months and 2 days" * returns "3 years, 8 months and 5 days". *

    + * The specified amount is typically an instance of {@code Period}. + * Other types are interpreted using {@link Period#from(TemporalAmount)}. + *

    * This instance is immutable and unaffected by this method call. * * @param amountToAdd the period to add, not null * @return a {@code Period} based on this period with the requested period added, not null + * @throws DateTimeException if the specified amount has a non-ISO chronology or + * contains an invalid unit * @throws ArithmeticException if numeric overflow occurs */ - public Period plus(Period amountToAdd) { + public Period plus(TemporalAmount amountToAdd) { + Period isoAmount = Period.from(amountToAdd); return create( - Math.addExact(years, amountToAdd.years), - Math.addExact(months, amountToAdd.months), - Math.addExact(days, amountToAdd.days)); + Math.addExact(years, isoAmount.years), + Math.addExact(months, isoAmount.months), + Math.addExact(days, isoAmount.days)); } /** @@ -654,21 +687,28 @@ public final class Period * Returns a copy of this period with the specified period subtracted. *

    * This operates separately on the years, months and days. + * No normalization is performed. *

    * For example, "1 year, 6 months and 3 days" minus "2 years, 2 months and 2 days" * returns "-1 years, 4 months and 1 day". *

    + * The specified amount is typically an instance of {@code Period}. + * Other types are interpreted using {@link Period#from(TemporalAmount)}. + *

    * This instance is immutable and unaffected by this method call. * * @param amountToSubtract the period to subtract, not null * @return a {@code Period} based on this period with the requested period subtracted, not null + * @throws DateTimeException if the specified amount has a non-ISO chronology or + * contains an invalid unit * @throws ArithmeticException if numeric overflow occurs */ - public Period minus(Period amountToSubtract) { + public Period minus(TemporalAmount amountToSubtract) { + Period isoAmount = Period.from(amountToSubtract); return create( - Math.subtractExact(years, amountToSubtract.years), - Math.subtractExact(months, amountToSubtract.months), - Math.subtractExact(days, amountToSubtract.days)); + Math.subtractExact(years, isoAmount.years), + Math.subtractExact(months, isoAmount.months), + Math.subtractExact(days, isoAmount.days)); } /** @@ -766,8 +806,7 @@ public final class Period //----------------------------------------------------------------------- /** - * Returns a copy of this period with the years and months normalized - * using a 12 month year. + * Returns a copy of this period with the years and months normalized. *

    * This normalizes the years and months units, leaving the days unit unchanged. * The months unit is adjusted to have an absolute value less than 11, @@ -778,8 +817,6 @@ public final class Period * For example, a period of "1 year and -25 months" will be normalized to * "-1 year and -1 month". *

    - * This normalization uses a 12 month year which is not valid for all calendar systems. - *

    * This instance is immutable and unaffected by this method call. * * @return a {@code Period} based on this period with excess months normalized to years, not null @@ -796,13 +833,11 @@ public final class Period } /** - * Gets the total number of months in this period using a 12 month year. + * Gets the total number of months in this period. *

    * This returns the total number of months in the period by multiplying the * number of years by 12 and adding the number of months. *

    - * This uses a 12 month year which is not valid for all calendar systems. - *

    * This instance is immutable and unaffected by this method call. * * @return the total number of months in the period, may be negative @@ -817,6 +852,7 @@ public final class Period *

    * This returns a temporal object of the same observable type as the input * with this period added. + * If the temporal has a chronology, it must be the ISO chronology. *

    * In most cases, it is clearer to reverse the calling pattern by using * {@link Temporal#plus(TemporalAmount)}. @@ -826,10 +862,17 @@ public final class Period * dateTime = dateTime.plus(thisPeriod); * *

    - * The calculation will add the years, then months, then days. - * Only non-zero amounts will be added. - * If the date-time has a calendar system with a fixed number of months in a - * year, then the years and months will be combined before being added. + * The calculation operates as follows. + * First, the chronology of the temporal is checked to ensure it is ISO chronology or null. + * Second, if the months are zero, the years are added if non-zero, otherwise + * the combination of years and months is added if non-zero. + * Finally, any days are added. + *

    + * This approach ensures that a partial period can be added to a partial date. + * For example, a period of years and/or months can be added to a {@code YearMonth}, + * but a period including days cannot. + * The approach also adds years and months together when necessary, which ensures + * correct behaviour at the end of the month. *

    * This instance is immutable and unaffected by this method call. * @@ -840,18 +883,15 @@ public final class Period */ @Override public Temporal addTo(Temporal temporal) { - Objects.requireNonNull(temporal, "temporal"); - if ((years | months) != 0) { - long monthRange = monthRange(temporal); - if (monthRange >= 0) { - temporal = temporal.plus(years * monthRange + months, MONTHS); - } else { - if (years != 0) { - temporal = temporal.plus(years, YEARS); - } - if (months != 0) { - temporal = temporal.plus(months, MONTHS); - } + validateChrono(temporal); + if (months == 0) { + if (years != 0) { + temporal = temporal.plus(years, YEARS); + } + } else { + long totalMonths = toTotalMonths(); + if (totalMonths != 0) { + temporal = temporal.plus(totalMonths, MONTHS); } } if (days != 0) { @@ -865,6 +905,7 @@ public final class Period *

    * This returns a temporal object of the same observable type as the input * with this period subtracted. + * If the temporal has a chronology, it must be the ISO chronology. *

    * In most cases, it is clearer to reverse the calling pattern by using * {@link Temporal#minus(TemporalAmount)}. @@ -874,10 +915,17 @@ public final class Period * dateTime = dateTime.minus(thisPeriod); * *

    - * The calculation will subtract the years, then months, then days. - * Only non-zero amounts will be subtracted. - * If the date-time has a calendar system with a fixed number of months in a - * year, then the years and months will be combined before being subtracted. + * The calculation operates as follows. + * First, the chronology of the temporal is checked to ensure it is ISO chronology or null. + * Second, if the months are zero, the years are subtracted if non-zero, otherwise + * the combination of years and months is subtracted if non-zero. + * Finally, any days are subtracted. + *

    + * This approach ensures that a partial period can be subtracted from a partial date. + * For example, a period of years and/or months can be subtracted from a {@code YearMonth}, + * but a period including days cannot. + * The approach also subtracts years and months together when necessary, which ensures + * correct behaviour at the end of the month. *

    * This instance is immutable and unaffected by this method call. * @@ -888,18 +936,15 @@ public final class Period */ @Override public Temporal subtractFrom(Temporal temporal) { - Objects.requireNonNull(temporal, "temporal"); - if ((years | months) != 0) { - long monthRange = monthRange(temporal); - if (monthRange >= 0) { - temporal = temporal.minus(years * monthRange + months, MONTHS); - } else { - if (years != 0) { - temporal = temporal.minus(years, YEARS); - } - if (months != 0) { - temporal = temporal.minus(months, MONTHS); - } + validateChrono(temporal); + if (months == 0) { + if (years != 0) { + temporal = temporal.minus(years, YEARS); + } + } else { + long totalMonths = toTotalMonths(); + if (totalMonths != 0) { + temporal = temporal.minus(totalMonths, MONTHS); } } if (days != 0) { @@ -909,26 +954,21 @@ public final class Period } /** - * Calculates the range of months based on the temporal. - * - * @param temporal the temporal, not null - * @return the month range, negative if not fixed range + * Validates that the temporal has the correct chronology. */ - private long monthRange(Temporal temporal) { - if (temporal.isSupported(MONTH_OF_YEAR)) { - ValueRange startRange = Chronology.from(temporal).range(MONTH_OF_YEAR); - if (startRange.isFixed() && startRange.isIntValue()) { - return startRange.getMaximum() - startRange.getMinimum() + 1; - } + private void validateChrono(TemporalAccessor temporal) { + Objects.requireNonNull(temporal, "temporal"); + Chronology temporalChrono = temporal.query(TemporalQuery.chronology()); + if (temporalChrono != null && IsoChronology.INSTANCE.equals(temporalChrono) == false) { + throw new DateTimeException("Chronology mismatch, expected: ISO, actual: " + temporalChrono.getId()); } - return -1; } //----------------------------------------------------------------------- /** * Checks if this period is equal to another period. *

    - * The comparison is based on the amounts held in the period. + * The comparison is based on the type {@code Period} and each of the three amounts. * To be equal, the years, months and days units must be individually equal. * Note that this means that a period of "15 Months" is not equal to a period * of "1 Year and 3 Months". diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java index e02a8cd5392..58ae3b8c1c5 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java @@ -69,7 +69,6 @@ import static java.time.temporal.ChronoUnit.DAYS; import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalTime; -import java.time.Period; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; @@ -602,9 +601,12 @@ public interface ChronoLocalDate long until(Temporal endDate, TemporalUnit unit); /** - * Calculates the period between this date and another date as a {@code Period}. + * Calculates the period between this date and another date as a {@code ChronoPeriod}. + *

    + * This calculates the period between two dates. All supplied chronologies + * calculate the period using years, months and days, however the + * {@code ChronoPeriod} API allows the period to be represented using other units. *

    - * This calculates the period between two dates in terms of years, months and days. * The start and end points are {@code this} and the specified date. * The result will be negative if the end is before the start. * The negative sign will be the same in each of year, month and day. @@ -614,12 +616,12 @@ public interface ChronoLocalDate *

    * This instance is immutable and unaffected by this method call. * - * @param endDate the end date, exclusive, which may be in any chronology, not null + * @param endDateExclusive the end date, exclusive, which may be in any chronology, not null * @return the period between this date and the end date, not null * @throws DateTimeException if the period cannot be calculated * @throws ArithmeticException if numeric overflow occurs */ - Period until(ChronoLocalDate endDate); + ChronoPeriod until(ChronoLocalDate endDateExclusive); /** * Formats this date using the specified formatter. diff --git a/jdk/src/share/classes/java/time/chrono/ChronoPeriod.java b/jdk/src/share/classes/java/time/chrono/ChronoPeriod.java new file mode 100644 index 00000000000..0ac1d395143 --- /dev/null +++ b/jdk/src/share/classes/java/time/chrono/ChronoPeriod.java @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2013, 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 file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2013, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package java.time.chrono; + +import java.time.DateTimeException; +import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAmount; +import java.time.temporal.TemporalUnit; +import java.time.temporal.UnsupportedTemporalTypeException; +import java.util.List; +import java.util.Objects; + +/** + * A date-based amount of time, such as '3 years, 4 months and 5 days' in an + * arbitrary chronology, intended for advanced globalization use cases. + *

    + * This interface models a date-based amount of time in a calendar system. + * While most calendar systems use years, months and days, some do not. + * Therefore, this interface operates solely in terms of a set of supported + * units that are defined by the {@code Chronology}. + * The set of supported units is fixed for a given chronology. + * The amount of a supported unit may be set to zero. + *

    + * The period is modeled as a directed amount of time, meaning that individual + * parts of the period may be negative. + * + * @implSpec + * This interface must be implemented with care to ensure other classes operate correctly. + * All implementations that can be instantiated must be final, immutable and thread-safe. + * Subclasses should be Serializable wherever possible. + * + * @since 1.8 + */ +public interface ChronoPeriod + extends TemporalAmount { + + /** + * Obtains a {@code ChronoPeriod} consisting of amount of time between two dates. + *

    + * The start date is included, but the end date is not. + * The period is calculated using {@link ChronoLocalDate#until(ChronoLocalDate)}. + * As such, the calculation is chronology specific. + *

    + * The chronology of the first date is used. + * The chronology of the second date is ignored, with the date being converted + * to the target chronology system before the calculation starts. + *

    + * The result of this method can be a negative period if the end is before the start. + * In most cases, the positive/negative sign will be the same in each of the supported fields. + * + * @param startDateInclusive the start date, inclusive, specifying the chronology of the calculation, not null + * @param endDateExclusive the end date, exclusive, in any chronology, not null + * @return the period between this date and the end date, not null + * @see ChronoLocalDate#until(ChronoLocalDate) + */ + public static ChronoPeriod between(ChronoLocalDate startDateInclusive, ChronoLocalDate endDateExclusive) { + Objects.requireNonNull(startDateInclusive, "startDateInclusive"); + Objects.requireNonNull(endDateExclusive, "endDateExclusive"); + return startDateInclusive.until(endDateExclusive); + } + + //----------------------------------------------------------------------- + /** + * Gets the value of the requested unit. + *

    + * The supported units are chronology specific. + * They will typically be {@link ChronoUnit#YEARS YEARS}, + * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}. + * Requesting an unsupported unit will throw an exception. + * + * @param unit the {@code TemporalUnit} for which to return the value + * @return the long value of the unit + * @throws DateTimeException if the unit is not supported + * @throws UnsupportedTemporalTypeException if the unit is not supported + */ + @Override + long get(TemporalUnit unit); + + /** + * Gets the set of units supported by this period. + *

    + * The supported units are chronology specific. + * They will typically be {@link ChronoUnit#YEARS YEARS}, + * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}. + * They are returned in order from largest to smallest. + *

    + * This set can be used in conjunction with {@link #get(TemporalUnit)} + * to access the entire state of the period. + * + * @return a list containing the supported units, not null + */ + @Override + List getUnits(); + + /** + * Gets the chronology that defines the meaning of the supported units. + *

    + * The period is defined by the chronology. + * It controls the supported units and restricts addition/subtraction + * to {@code ChronoLocalDate} instances of the same chronology. + * + * @return the chronology defining the period, not null + */ + Chronology getChronology(); + + //----------------------------------------------------------------------- + /** + * Checks if all the supported units of this period are zero. + * + * @return true if this period is zero-length + */ + default boolean isZero() { + for (TemporalUnit unit : getUnits()) { + if (get(unit) != 0) { + return false; + } + } + return true; + } + + /** + * Checks if any of the supported units of this period are negative. + * + * @return true if any unit of this period is negative + */ + default boolean isNegative() { + for (TemporalUnit unit : getUnits()) { + if (get(unit) < 0) { + return true; + } + } + return false; + } + + //----------------------------------------------------------------------- + /** + * Returns a copy of this period with the specified period added. + *

    + * If the specified amount is a {@code ChronoPeriod} then it must have + * the same chronology as this period. Implementations may choose to + * accept or reject other {@code TemporalAmount} implementations. + *

    + * This instance is immutable and unaffected by this method call. + * + * @param amountToAdd the period to add, not null + * @return a {@code ChronoPeriod} based on this period with the requested period added, not null + * @throws ArithmeticException if numeric overflow occurs + */ + ChronoPeriod plus(TemporalAmount amountToAdd); + + /** + * Returns a copy of this period with the specified period subtracted. + *

    + * If the specified amount is a {@code ChronoPeriod} then it must have + * the same chronology as this period. Implementations may choose to + * accept or reject other {@code TemporalAmount} implementations. + *

    + * This instance is immutable and unaffected by this method call. + * + * @param amountToSubtract the period to subtract, not null + * @return a {@code ChronoPeriod} based on this period with the requested period subtracted, not null + * @throws ArithmeticException if numeric overflow occurs + */ + ChronoPeriod minus(TemporalAmount amountToSubtract); + + //----------------------------------------------------------------------- + /** + * Returns a new instance with each amount in this period in this period + * multiplied by the specified scalar. + *

    + * This returns a period with each supported unit individually multiplied. + * For example, a period of "2 years, -3 months and 4 days" multiplied by + * 3 will return "6 years, -9 months and 12 days". + * No normalization is performed. + * + * @param scalar the scalar to multiply by, not null + * @return a {@code ChronoPeriod} based on this period with the amounts multiplied + * by the scalar, not null + * @throws ArithmeticException if numeric overflow occurs + */ + ChronoPeriod multipliedBy(int scalar); + + /** + * Returns a new instance with each amount in this period negated. + *

    + * This returns a period with each supported unit individually negated. + * For example, a period of "2 years, -3 months and 4 days" will be + * negated to "-2 years, 3 months and -4 days". + * No normalization is performed. + * + * @return a {@code ChronoPeriod} based on this period with the amounts negated, not null + * @throws ArithmeticException if numeric overflow occurs, which only happens if + * one of the units has the value {@code Long.MIN_VALUE} + */ + default ChronoPeriod negated() { + return multipliedBy(-1); + } + + //----------------------------------------------------------------------- + /** + * Returns a copy of this period with the amounts of each unit normalized. + *

    + * The process of normalization is specific to each calendar system. + * For example, in the ISO calendar system, the years and months are + * normalized but the days are not, such that "15 months" would be + * normalized to "1 year and 3 months". + *

    + * This instance is immutable and unaffected by this method call. + * + * @return a {@code ChronoPeriod} based on this period with the amounts of each + * unit normalized, not null + * @throws ArithmeticException if numeric overflow occurs + */ + ChronoPeriod normalized(); + + //------------------------------------------------------------------------- + /** + * Adds this period to the specified temporal object. + *

    + * This returns a temporal object of the same observable type as the input + * with this period added. + *

    + * In most cases, it is clearer to reverse the calling pattern by using + * {@link Temporal#plus(TemporalAmount)}. + *

    +     *   // these two lines are equivalent, but the second approach is recommended
    +     *   dateTime = thisPeriod.addTo(dateTime);
    +     *   dateTime = dateTime.plus(thisPeriod);
    +     * 
    + *

    + * The specified temporal must have the same chronology as this period. + * This returns a temporal with the non-zero supported units added. + *

    + * This instance is immutable and unaffected by this method call. + * + * @param temporal the temporal object to adjust, not null + * @return an object of the same type with the adjustment made, not null + * @throws DateTimeException if unable to add + * @throws ArithmeticException if numeric overflow occurs + */ + @Override + Temporal addTo(Temporal temporal); + + /** + * Subtracts this period from the specified temporal object. + *

    + * This returns a temporal object of the same observable type as the input + * with this period subtracted. + *

    + * In most cases, it is clearer to reverse the calling pattern by using + * {@link Temporal#minus(TemporalAmount)}. + *

    +     *   // these two lines are equivalent, but the second approach is recommended
    +     *   dateTime = thisPeriod.subtractFrom(dateTime);
    +     *   dateTime = dateTime.minus(thisPeriod);
    +     * 
    + *

    + * The specified temporal must have the same chronology as this period. + * This returns a temporal with the non-zero supported units subtracted. + *

    + * This instance is immutable and unaffected by this method call. + * + * @param temporal the temporal object to adjust, not null + * @return an object of the same type with the adjustment made, not null + * @throws DateTimeException if unable to subtract + * @throws ArithmeticException if numeric overflow occurs + */ + @Override + Temporal subtractFrom(Temporal temporal); + + //----------------------------------------------------------------------- + /** + * Checks if this period is equal to another period, including the chronology. + *

    + * Compares this period with another ensuring that the type, each amount and + * the chronology are the same. + * Note that this means that a period of "15 Months" is not equal to a period + * of "1 Year and 3 Months". + * + * @param obj the object to check, null returns false + * @return true if this is equal to the other period + */ + @Override + boolean equals(Object obj); + + /** + * A hash code for this period. + * + * @return a suitable hash code + */ + @Override + int hashCode(); + + //----------------------------------------------------------------------- + /** + * Outputs this period as a {@code String}. + *

    + * The output will include the period amounts and chronology. + * + * @return a string representation of this period, not null + */ + @Override + String toString(); + +} diff --git a/jdk/src/share/classes/java/time/chrono/ChronoPeriodImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoPeriodImpl.java new file mode 100644 index 00000000000..d301adb2d03 --- /dev/null +++ b/jdk/src/share/classes/java/time/chrono/ChronoPeriodImpl.java @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * Copyright (c) 2013, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package java.time.chrono; + +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.YEARS; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.time.DateTimeException; +import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAmount; +import java.time.temporal.TemporalQuery; +import java.time.temporal.TemporalUnit; +import java.time.temporal.UnsupportedTemporalTypeException; +import java.time.temporal.ValueRange; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * A period expressed in terms of a standard year-month-day calendar system. + *

    + * This class is used by applications seeking to handle dates in non-ISO calendar systems. + * For example, the Japanese, Minguo, Thai Buddhist and others. + * + * @implSpec + * This class is immutable nad thread-safe. + * + * @since 1.8 + */ +final class ChronoPeriodImpl + implements ChronoPeriod, Serializable { + // this class is only used by JDK chronology implementations and makes assumptions based on that fact + + /** + * Serialization version. + */ + private static final long serialVersionUID = 57387258289L; + + /** + * The set of supported units. + */ + private final static List SUPPORTED_UNITS = + Collections.unmodifiableList(Arrays.asList(YEARS, MONTHS, DAYS)); + + /** + * The chronology. + */ + private final Chronology chrono; + /** + * The number of years. + */ + final int years; + /** + * The number of months. + */ + final int months; + /** + * The number of days. + */ + final int days; + + /** + * Creates an instance. + */ + ChronoPeriodImpl(Chronology chrono, int years, int months, int days) { + Objects.requireNonNull(chrono, "chrono"); + this.chrono = chrono; + this.years = years; + this.months = months; + this.days = days; + } + + //----------------------------------------------------------------------- + @Override + public long get(TemporalUnit unit) { + if (unit == ChronoUnit.YEARS) { + return years; + } else if (unit == ChronoUnit.MONTHS) { + return months; + } else if (unit == ChronoUnit.DAYS) { + return days; + } else { + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); + } + } + + @Override + public List getUnits() { + return ChronoPeriodImpl.SUPPORTED_UNITS; + } + + @Override + public Chronology getChronology() { + return chrono; + } + + //----------------------------------------------------------------------- + @Override + public boolean isZero() { + return years == 0 && months == 0 && days == 0; + } + + @Override + public boolean isNegative() { + return years < 0 || months < 0 || days < 0; + } + + //----------------------------------------------------------------------- + @Override + public ChronoPeriod plus(TemporalAmount amountToAdd) { + ChronoPeriodImpl amount = validateAmount(amountToAdd); + return new ChronoPeriodImpl( + chrono, + Math.addExact(years, amount.years), + Math.addExact(months, amount.months), + Math.addExact(days, amount.days)); + } + + @Override + public ChronoPeriod minus(TemporalAmount amountToSubtract) { + ChronoPeriodImpl amount = validateAmount(amountToSubtract); + return new ChronoPeriodImpl( + chrono, + Math.subtractExact(years, amount.years), + Math.subtractExact(months, amount.months), + Math.subtractExact(days, amount.days)); + } + + /** + * Obtains an instance of {@code ChronoPeriodImpl} from a temporal amount. + * + * @param amount the temporal amount to convert, not null + * @return the period, not null + */ + private ChronoPeriodImpl validateAmount(TemporalAmount amount) { + Objects.requireNonNull(amount, "amount"); + if (amount instanceof ChronoPeriodImpl == false) { + throw new DateTimeException("Unable to obtain ChronoPeriod from TemporalAmount: " + amount.getClass()); + } + ChronoPeriodImpl period = (ChronoPeriodImpl) amount; + if (chrono.equals(period.getChronology()) == false) { + throw new ClassCastException("Chronology mismatch, expected: " + chrono.getId() + ", actual: " + period.getChronology().getId()); + } + return period; + } + + //----------------------------------------------------------------------- + @Override + public ChronoPeriod multipliedBy(int scalar) { + if (this.isZero() || scalar == 1) { + return this; + } + return new ChronoPeriodImpl( + chrono, + Math.multiplyExact(years, scalar), + Math.multiplyExact(months, scalar), + Math.multiplyExact(days, scalar)); + } + + //----------------------------------------------------------------------- + @Override + public ChronoPeriod normalized() { + long monthRange = monthRange(); + if (monthRange > 0) { + long totalMonths = years * monthRange + months; + long splitYears = totalMonths / monthRange; + int splitMonths = (int) (totalMonths % monthRange); // no overflow + if (splitYears == years && splitMonths == months) { + return this; + } + return new ChronoPeriodImpl(chrono, Math.toIntExact(splitYears), splitMonths, days); + + } + return this; + } + + /** + * Calculates the range of months. + * + * @return the month range, -1 if not fixed range + */ + private long monthRange() { + ValueRange startRange = chrono.range(MONTH_OF_YEAR); + if (startRange.isFixed() && startRange.isIntValue()) { + return startRange.getMaximum() - startRange.getMinimum() + 1; + } + return -1; + } + + //------------------------------------------------------------------------- + @Override + public Temporal addTo(Temporal temporal) { + validateChrono(temporal); + if (months == 0) { + if (years != 0) { + temporal = temporal.plus(years, YEARS); + } + } else { + long monthRange = monthRange(); + if (monthRange > 0) { + temporal = temporal.plus(years * monthRange + months, MONTHS); + } else { + if (years != 0) { + temporal = temporal.plus(years, YEARS); + } + temporal = temporal.plus(months, MONTHS); + } + } + if (days != 0) { + temporal = temporal.plus(days, DAYS); + } + return temporal; + } + + + + @Override + public Temporal subtractFrom(Temporal temporal) { + validateChrono(temporal); + if (months == 0) { + if (years != 0) { + temporal = temporal.minus(years, YEARS); + } + } else { + long monthRange = monthRange(); + if (monthRange > 0) { + temporal = temporal.minus(years * monthRange + months, MONTHS); + } else { + if (years != 0) { + temporal = temporal.minus(years, YEARS); + } + temporal = temporal.minus(months, MONTHS); + } + } + if (days != 0) { + temporal = temporal.minus(days, DAYS); + } + return temporal; + } + + /** + * Validates that the temporal has the correct chronology. + */ + private void validateChrono(TemporalAccessor temporal) { + Objects.requireNonNull(temporal, "temporal"); + Chronology temporalChrono = temporal.query(TemporalQuery.chronology()); + if (temporalChrono != null && chrono.equals(temporalChrono) == false) { + throw new DateTimeException("Chronology mismatch, expected: " + chrono.getId() + ", actual: " + temporalChrono.getId()); + } + } + + //----------------------------------------------------------------------- + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ChronoPeriodImpl) { + ChronoPeriodImpl other = (ChronoPeriodImpl) obj; + return years == other.years && months == other.months && + days == other.days && chrono.equals(other.chrono); + } + return false; + } + + @Override + public int hashCode() { + return (years + Integer.rotateLeft(months, 8) + Integer.rotateLeft(days, 16)) ^ chrono.hashCode(); + } + + //----------------------------------------------------------------------- + @Override + public String toString() { + if (isZero()) { + return getChronology().toString() + " P0D"; + } else { + StringBuilder buf = new StringBuilder(); + buf.append(getChronology().toString()).append(' ').append('P'); + if (years != 0) { + buf.append(years).append('Y'); + } + if (months != 0) { + buf.append(months).append('M'); + } + if (days != 0) { + buf.append(days).append('D'); + } + return buf.toString(); + } + } + + //----------------------------------------------------------------------- + /** + * Writes the Chronology using a + * dedicated serialized form. + *

    +     *  out.writeByte(12);  // identifies this as a ChronoPeriodImpl
    +     *  out.writeUTF(getId());  // the chronology
    +     *  out.writeInt(years);
    +     *  out.writeInt(months);
    +     *  out.writeInt(days);
    +     * 
    + * + * @return the instance of {@code Ser}, not null + */ + protected Object writeReplace() { + return new Ser(Ser.CHRONO_PERIOD_TYPE, this); + } + + /** + * Defend against malicious streams. + * @return never + * @throws InvalidObjectException always + */ + private Object readResolve() throws ObjectStreamException { + throw new InvalidObjectException("Deserialization via serialization delegate"); + } + + void writeExternal(DataOutput out) throws IOException { + out.writeUTF(chrono.getId()); + out.writeInt(years); + out.writeInt(months); + out.writeInt(days); + } + + static ChronoPeriodImpl readExternal(DataInput in) throws IOException { + Chronology chrono = Chronology.of(in.readUTF()); + int years = in.readInt(); + int months = in.readInt(); + int days = in.readInt(); + return new ChronoPeriodImpl(chrono, years, months, days); + } + +} diff --git a/jdk/src/share/classes/java/time/chrono/Chronology.java b/jdk/src/share/classes/java/time/chrono/Chronology.java index 36c9d31c3fd..ed40f4138f0 100644 --- a/jdk/src/share/classes/java/time/chrono/Chronology.java +++ b/jdk/src/share/classes/java/time/chrono/Chronology.java @@ -91,14 +91,11 @@ import java.time.DayOfWeek; import java.time.Instant; import java.time.LocalDate; import java.time.LocalTime; -import java.time.Month; -import java.time.Year; import java.time.ZoneId; import java.time.format.DateTimeFormatterBuilder; import java.time.format.ResolverStyle; import java.time.format.TextStyle; import java.time.temporal.ChronoField; -import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; @@ -1190,6 +1187,38 @@ public abstract class Chronology implements Comparable { fieldValues.put(field, value); } + //----------------------------------------------------------------------- + /** + * Obtains a period for this chronology based on years, months and days. + *

    + * This returns a period tied to this chronology using the specified + * years, months and days. All supplied chronologies use periods + * based on years, months and days, however the {@code ChronoPeriod} API + * allows the period to be represented using other units. + * + * @implSpec + * The default implementation returns an implementation class suitable + * for most calendar systems. It is based solely on the three units. + * Normalization, addition and subtraction derive the number of months + * in a year from the {@link #range(ChronoField)}. If the number of + * months within a year is fixed, then the calculation approach for + * addition, subtraction and normalization is slightly different. + *

    + * If implementing an unusual calendar system that is not based on + * years, months and days, or where you want direct control, then + * the {@code ChronoPeriod} interface must be directly implemented. + *

    + * The returned period is immutable and thread-safe. + * + * @param years the number of years, may be negative + * @param months the number of years, may be negative + * @param days the number of years, may be negative + * @return the period in terms of this chronology, not null + */ + public ChronoPeriod period(int years, int months, int days) { + return new ChronoPeriodImpl(this, years, months, days); + } + //----------------------------------------------------------------------- /** * Compares this chronology to another chronology. diff --git a/jdk/src/share/classes/java/time/chrono/HijrahDate.java b/jdk/src/share/classes/java/time/chrono/HijrahDate.java index c0d942396cd..d2c9929316c 100644 --- a/jdk/src/share/classes/java/time/chrono/HijrahDate.java +++ b/jdk/src/share/classes/java/time/chrono/HijrahDate.java @@ -73,7 +73,6 @@ import java.time.Clock; import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalTime; -import java.time.Period; import java.time.ZoneId; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; @@ -582,7 +581,7 @@ public final class HijrahDate } @Override - public Period until(ChronoLocalDate endDate) { + public ChronoPeriod until(ChronoLocalDate endDate) { // TODO: untested HijrahDate end = getChronology().date(endDate); long totalMonths = (end.prolepticYear - this.prolepticYear) * 12 + (end.monthOfYear - this.monthOfYear); // safe @@ -597,7 +596,7 @@ public final class HijrahDate } long years = totalMonths / 12; // safe int months = (int) (totalMonths % 12); // safe - return Period.of(Math.toIntExact(years), months, days); + return getChronology().period(Math.toIntExact(years), months, days); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/chrono/IsoChronology.java b/jdk/src/share/classes/java/time/chrono/IsoChronology.java index 2012e64e04d..9638f6eea4f 100644 --- a/jdk/src/share/classes/java/time/chrono/IsoChronology.java +++ b/jdk/src/share/classes/java/time/chrono/IsoChronology.java @@ -77,6 +77,7 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.Month; +import java.time.Period; import java.time.Year; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -565,6 +566,24 @@ public final class IsoChronology extends Chronology implements Serializable { return field.range(); } + //----------------------------------------------------------------------- + /** + * Obtains a period for this chronology based on years, months and days. + *

    + * This returns a period tied to the ISO chronology using the specified + * years, months and days. See {@link Period} for further details. + * + * @param years the number of years, may be negative + * @param months the number of years, may be negative + * @param days the number of years, may be negative + * @return the period in terms of this chronology, not null + * @return the ISO period, not null + */ + @Override // override with covariant return type + public Period period(int years, int months, int days) { + return Period.of(years, months, days); + } + //----------------------------------------------------------------------- /** * Writes the Chronology using a diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java index bc9f473486d..ae4708dbaff 100644 --- a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java +++ b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java @@ -659,8 +659,9 @@ public final class JapaneseDate } @Override - public Period until(ChronoLocalDate endDate) { - return isoDate.until(endDate); + public ChronoPeriod until(ChronoLocalDate endDate) { + Period period = isoDate.until(endDate); + return getChronology().period(period.getYears(), period.getMonths(), period.getDays()); } @Override // override for performance diff --git a/jdk/src/share/classes/java/time/chrono/MinguoDate.java b/jdk/src/share/classes/java/time/chrono/MinguoDate.java index fd10e0e985e..42e0dab0da5 100644 --- a/jdk/src/share/classes/java/time/chrono/MinguoDate.java +++ b/jdk/src/share/classes/java/time/chrono/MinguoDate.java @@ -421,8 +421,9 @@ public final class MinguoDate } @Override - public Period until(ChronoLocalDate endDate) { - return isoDate.until(endDate); + public ChronoPeriod until(ChronoLocalDate endDate) { + Period period = isoDate.until(endDate); + return getChronology().period(period.getYears(), period.getMonths(), period.getDays()); } @Override // override for performance diff --git a/jdk/src/share/classes/java/time/chrono/Ser.java b/jdk/src/share/classes/java/time/chrono/Ser.java index cc99f481f8c..5a4e3c12623 100644 --- a/jdk/src/share/classes/java/time/chrono/Ser.java +++ b/jdk/src/share/classes/java/time/chrono/Ser.java @@ -104,6 +104,7 @@ final class Ser implements Externalizable { static final byte HIJRAH_DATE_TYPE = 6; static final byte MINGUO_DATE_TYPE = 7; static final byte THAIBUDDHIST_DATE_TYPE = 8; + static final byte CHRONO_PERIOD_TYPE = 9; /** The type being serialized. */ private byte type; @@ -183,6 +184,9 @@ final class Ser implements Externalizable { case THAIBUDDHIST_DATE_TYPE: ((ThaiBuddhistDate) object).writeExternal(out); break; + case CHRONO_PERIOD_TYPE: + ((ChronoPeriodImpl) object).writeExternal(out); + break; default: throw new InvalidClassException("Unknown serialized type"); } @@ -235,6 +239,7 @@ final class Ser implements Externalizable { case HIJRAH_DATE_TYPE: return HijrahDate.readExternal(in); case MINGUO_DATE_TYPE: return MinguoDate.readExternal(in); case THAIBUDDHIST_DATE_TYPE: return ThaiBuddhistDate.readExternal(in); + case CHRONO_PERIOD_TYPE: return ChronoPeriodImpl.readExternal(in); default: throw new StreamCorruptedException("Unknown serialized type"); } } diff --git a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java index 648793b7337..89895c8ac48 100644 --- a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java +++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java @@ -421,8 +421,9 @@ public final class ThaiBuddhistDate } @Override - public Period until(ChronoLocalDate endDate) { - return isoDate.until(endDate); + public ChronoPeriod until(ChronoLocalDate endDate) { + Period period = isoDate.until(endDate); + return getChronology().period(period.getYears(), period.getMonths(), period.getDays()); } @Override // override for performance diff --git a/jdk/src/share/classes/java/time/temporal/Temporal.java b/jdk/src/share/classes/java/time/temporal/Temporal.java index af8424c1560..54110bed771 100644 --- a/jdk/src/share/classes/java/time/temporal/Temporal.java +++ b/jdk/src/share/classes/java/time/temporal/Temporal.java @@ -170,7 +170,8 @@ public interface Temporal extends TemporalAccessor { * * * @implSpec - * Implementations must not alter either this object. + *

    + * Implementations must not alter either this object or the specified temporal object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. *

    @@ -209,7 +210,7 @@ public interface Temporal extends TemporalAccessor { * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)} * passing {@code this} as the first argument. *

    - * Implementations must not alter either this object or the specified temporal object. + * Implementations must not alter this object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. * @@ -232,16 +233,17 @@ public interface Temporal extends TemporalAccessor { *

    * Some example code indicating how and why this method is used: *

    -     *  date = date.plus(period);                      // add a Period instance
    -     *  date = date.plus(duration);                    // add a Duration instance
    -     *  date = date.plus(workingDays(6));              // example user-written workingDays method
    +     *  date = date.plus(period);                // add a Period instance
    +     *  date = date.plus(duration);              // add a Duration instance
    +     *  date = date.plus(workingDays(6));        // example user-written workingDays method
          * 
    *

    * Note that calling {@code plus} followed by {@code minus} is not guaranteed to * return the same date-time. * * @implSpec - * Implementations must not alter either this object. + *

    + * Implementations must not alter either this object or the specified temporal object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. *

    @@ -280,7 +282,7 @@ public interface Temporal extends TemporalAccessor { * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)} * passing {@code this} as the first argument. *

    - * Implementations must not alter either this object or the specified temporal object. + * Implementations must not alter this object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. * @@ -303,16 +305,17 @@ public interface Temporal extends TemporalAccessor { *

    * Some example code indicating how and why this method is used: *

    -     *  date = date.minus(period);                      // subtract a Period instance
    -     *  date = date.minus(duration);                    // subtract a Duration instance
    -     *  date = date.minus(workingDays(6));              // example user-written workingDays method
    +     *  date = date.minus(period);               // subtract a Period instance
    +     *  date = date.minus(duration);             // subtract a Duration instance
    +     *  date = date.minus(workingDays(6));       // example user-written workingDays method
          * 
    *

    * Note that calling {@code plus} followed by {@code minus} is not guaranteed to * return the same date-time. * * @implSpec - * Implementations must not alter either this object. + *

    + * Implementations must not alter either this object or the specified temporal object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. *

    @@ -345,7 +348,7 @@ public interface Temporal extends TemporalAccessor { * @implSpec * Implementations must behave in a manor equivalent to the default method behavior. *

    - * Implementations must not alter either this object or the specified temporal object. + * Implementations must not alter this object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. *

    diff --git a/jdk/test/java/time/tck/java/time/TCKPeriod.java b/jdk/test/java/time/tck/java/time/TCKPeriod.java index 3a1fe42ec45..7743512002f 100644 --- a/jdk/test/java/time/tck/java/time/TCKPeriod.java +++ b/jdk/test/java/time/tck/java/time/TCKPeriod.java @@ -60,6 +60,7 @@ package tck.java.time; import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.HOURS; import static java.time.temporal.ChronoUnit.YEARS; import static org.testng.Assert.assertEquals; @@ -67,6 +68,7 @@ import java.time.DateTimeException; import java.time.Duration; import java.time.LocalDate; import java.time.Period; +import java.time.chrono.ThaiBuddhistChronology; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; @@ -212,6 +214,41 @@ public class TCKPeriod extends AbstractTCKTest { Period.from(amount); } + @Test(expectedExceptions = DateTimeException.class) + public void factory_from_TemporalAmount_DaysHours() { + TemporalAmount amount = new TemporalAmount() { + @Override + public long get(TemporalUnit unit) { + if (unit == DAYS) { + return 1; + } else { + return 2; + } + } + @Override + public List getUnits() { + List list = new ArrayList<>(); + list.add(DAYS); + list.add(HOURS); + return list; + } + @Override + public Temporal addTo(Temporal temporal) { + throw new UnsupportedOperationException(); + } + @Override + public Temporal subtractFrom(Temporal temporal) { + throw new UnsupportedOperationException(); + } + }; + Period.from(amount); + } + + @Test(expectedExceptions = DateTimeException.class) + public void factory_from_TemporalAmount_NonISO() { + Period.from(ThaiBuddhistChronology.INSTANCE.period(1, 1, 1)); + } + @Test(expectedExceptions = DateTimeException.class) public void factory_from_TemporalAmount_Duration() { Period.from(Duration.ZERO); @@ -594,10 +631,45 @@ public class TCKPeriod extends AbstractTCKTest { } @Test(dataProvider="plus") - public void test_plus(Period base, Period add, Period expected) { + public void test_plus_TemporalAmount(Period base, Period add, Period expected) { assertEquals(base.plus(add), expected); } + @Test(expectedExceptions = DateTimeException.class) + public void test_plus_TemporalAmount_nonISO() { + pymd(4, 5, 6).plus(ThaiBuddhistChronology.INSTANCE.period(1, 0, 0)); + } + + @Test(expectedExceptions = DateTimeException.class) + public void test_plus_TemporalAmount_DaysHours() { + TemporalAmount amount = new TemporalAmount() { + @Override + public long get(TemporalUnit unit) { + if (unit == DAYS) { + return 1; + } else { + return 2; + } + } + @Override + public List getUnits() { + List list = new ArrayList<>(); + list.add(DAYS); + list.add(HOURS); + return list; + } + @Override + public Temporal addTo(Temporal temporal) { + throw new UnsupportedOperationException(); + } + @Override + public Temporal subtractFrom(Temporal temporal) { + throw new UnsupportedOperationException(); + } + }; + pymd(4, 5, 6).plus(amount); + } + //----------------------------------------------------------------------- // plusYears() //----------------------------------------------------------------------- @@ -704,10 +776,45 @@ public class TCKPeriod extends AbstractTCKTest { } @Test(dataProvider="minus") - public void test_minus(Period base, Period subtract, Period expected) { + public void test_minus_TemporalAmount(Period base, Period subtract, Period expected) { assertEquals(base.minus(subtract), expected); } + @Test(expectedExceptions = DateTimeException.class) + public void test_minus_TemporalAmount_nonISO() { + pymd(4, 5, 6).minus(ThaiBuddhistChronology.INSTANCE.period(1, 0, 0)); + } + + @Test(expectedExceptions = DateTimeException.class) + public void test_minus_TemporalAmount_DaysHours() { + TemporalAmount amount = new TemporalAmount() { + @Override + public long get(TemporalUnit unit) { + if (unit == DAYS) { + return 1; + } else { + return 2; + } + } + @Override + public List getUnits() { + List list = new ArrayList<>(); + list.add(DAYS); + list.add(HOURS); + return list; + } + @Override + public Temporal addTo(Temporal temporal) { + throw new UnsupportedOperationException(); + } + @Override + public Temporal subtractFrom(Temporal temporal) { + throw new UnsupportedOperationException(); + } + }; + pymd(4, 5, 6).minus(amount); + } + //----------------------------------------------------------------------- // minusYears() //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java new file mode 100644 index 00000000000..58a1c35eddb --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * Copyright (c) 2013, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono; + +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.HOURS; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.YEARS; +import static org.testng.Assert.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.DateTimeException; +import java.time.LocalDate; +import java.time.Period; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoPeriod; +import java.time.chrono.Chronology; +import java.time.chrono.HijrahChronology; +import java.time.chrono.IsoChronology; +import java.time.chrono.JapaneseChronology; +import java.time.chrono.MinguoChronology; +import java.time.chrono.ThaiBuddhistChronology; +import java.time.temporal.Temporal; +import java.time.temporal.UnsupportedTemporalTypeException; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class TCKChronoPeriod { + + //----------------------------------------------------------------------- + // regular data factory for names and descriptions of available calendars + //----------------------------------------------------------------------- + @DataProvider(name = "calendars") + Chronology[][] data_of_calendars() { + return new Chronology[][]{ + {HijrahChronology.INSTANCE}, + {IsoChronology.INSTANCE}, + {JapaneseChronology.INSTANCE}, + {MinguoChronology.INSTANCE}, + {ThaiBuddhistChronology.INSTANCE}}; + } + + //----------------------------------------------------------------------- + // Test Serialization of Calendars + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_serialization(Chronology chrono) throws Exception { + ChronoPeriod period = chrono.period(1, 2, 3); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(period); + out.close(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + + ObjectInputStream in = new ObjectInputStream(bais); + ChronoPeriod ser = (ChronoPeriod) in.readObject(); + assertEquals(ser, period, "deserialized ChronoPeriod is wrong"); + } + + @Test(dataProvider="calendars") + public void test_get(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + assertEquals(period.get(YEARS), 1); + assertEquals(period.get(MONTHS), 2); + assertEquals(period.get(DAYS), 3); + } + + @Test(dataProvider="calendars", expectedExceptions=UnsupportedTemporalTypeException.class) + public void test_get_unsupported(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + period.get(HOURS); + } + + @Test(dataProvider="calendars") + public void test_getUnits(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + assertEquals(period.getUnits().size(), 3); + assertEquals(period.getUnits().get(0), YEARS); + assertEquals(period.getUnits().get(1), MONTHS); + assertEquals(period.getUnits().get(2), DAYS); + } + + @Test(dataProvider="calendars") + public void test_getChronology(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + assertEquals(period.getChronology(), chrono); + } + + @Test(dataProvider="calendars") + public void test_isZero_isNegative(Chronology chrono) { + ChronoPeriod periodPositive = chrono.period(1, 2, 3); + assertEquals(periodPositive.isZero(), false); + assertEquals(periodPositive.isNegative(), false); + + ChronoPeriod periodZero = chrono.period(0, 0, 0); + assertEquals(periodZero.isZero(), true); + assertEquals(periodZero.isNegative(), false); + + ChronoPeriod periodNegative = chrono.period(-1, 0, 0); + assertEquals(periodNegative.isZero(), false); + assertEquals(periodNegative.isNegative(), true); + } + + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_plus(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoPeriod period2 = chrono.period(2, 3, 4); + ChronoPeriod result = period.plus(period2); + assertEquals(result, chrono.period(3, 5, 7)); + } + + @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class) + public void test_plus_wrongChrono(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoPeriod isoPeriod = Period.of(2, 3, 4); + ChronoPeriod thaiPeriod = ThaiBuddhistChronology.INSTANCE.period(2, 3, 4); + // one of these two will fail + period.plus(isoPeriod); + period.plus(thaiPeriod); + } + + @Test(dataProvider="calendars") + public void test_minus(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoPeriod period2 = chrono.period(2, 3, 4); + ChronoPeriod result = period.minus(period2); + assertEquals(result, chrono.period(-1, -1, -1)); + } + + @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class) + public void test_minus_wrongChrono(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoPeriod isoPeriod = Period.of(2, 3, 4); + ChronoPeriod thaiPeriod = ThaiBuddhistChronology.INSTANCE.period(2, 3, 4); + // one of these two will fail + period.minus(isoPeriod); + period.minus(thaiPeriod); + } + + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_addTo(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoLocalDate date = chrono.dateNow(); + Temporal result = period.addTo(date); + assertEquals(result, date.plus(14, MONTHS).plus(3, DAYS)); + } + + @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class) + public void test_addTo_wrongChrono(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoLocalDate isoDate = LocalDate.of(2000, 1, 1); + ChronoLocalDate thaiDate = ThaiBuddhistChronology.INSTANCE.date(2000, 1, 1); + // one of these two will fail + period.addTo(isoDate); + period.addTo(thaiDate); + } + + @Test(dataProvider="calendars") + public void test_subtractFrom(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoLocalDate date = chrono.dateNow(); + Temporal result = period.subtractFrom(date); + assertEquals(result, date.minus(14, MONTHS).minus(3, DAYS)); + } + + @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class) + public void test_subtractFrom_wrongChrono(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoLocalDate isoDate = LocalDate.of(2000, 1, 1); + ChronoLocalDate thaiDate = ThaiBuddhistChronology.INSTANCE.date(2000, 1, 1); + // one of these two will fail + period.subtractFrom(isoDate); + period.subtractFrom(thaiDate); + } + + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_negated(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + assertEquals(period.negated(), chrono.period(-1, -2, -3)); + } + + @Test(dataProvider="calendars") + public void test_multipliedBy(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + assertEquals(period.multipliedBy(3), chrono.period(3, 6, 9)); + } + + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_equals_equal(Chronology chrono) { + ChronoPeriod a1 = chrono.period(1, 2, 3); + ChronoPeriod a2 = chrono.period(1, 2, 3); + assertEquals(a1, a1); + assertEquals(a1, a2); + assertEquals(a2, a1); + assertEquals(a2, a2); + assertEquals(a1.hashCode(), a2.hashCode()); + } + + @Test(dataProvider="calendars") + public void test_equals_notEqual(Chronology chrono) { + ChronoPeriod a = chrono.period(1, 2, 3); + ChronoPeriod b = chrono.period(2, 2, 3); + assertEquals(a.equals(b), false); + assertEquals(b.equals(a), false); + assertEquals(a.equals(""), false); + assertEquals(a.equals(null), false); + } + + @Test(dataProvider="calendars") + public void test_toString(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + if (period instanceof Period == false) { + assertEquals(period.toString(), chrono.getId() + " P1Y2M3D"); + } + } + +} diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java index e9d963c73af..fd53b0f0be1 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java @@ -79,6 +79,7 @@ import java.time.Year; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoPeriod; import java.time.chrono.Chronology; import java.time.chrono.Era; import java.time.chrono.IsoChronology; @@ -87,6 +88,7 @@ import java.time.chrono.JapaneseDate; import java.time.chrono.JapaneseEra; import java.time.chrono.MinguoChronology; import java.time.chrono.MinguoDate; +import java.time.chrono.ThaiBuddhistChronology; import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; @@ -615,8 +617,8 @@ public class TCKJapaneseChronology { public void test_periodUntilDate() { JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1); JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2); - Period period = mdate1.until(mdate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(mdate2); + assertEquals(period, JapaneseChronology.INSTANCE.period(1, 1, 1)); } @Test @@ -632,8 +634,8 @@ public class TCKJapaneseChronology { JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1); JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2); MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2); - Period period = mdate1.until(ldate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(ldate2); + assertEquals(period, JapaneseChronology.INSTANCE.period(1, 1, 1)); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java index 50ddf70cb3e..ad98e9119b3 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java @@ -69,13 +69,13 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Month; import java.time.OffsetDateTime; -import java.time.Period; import java.time.Year; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.chrono.ChronoLocalDate; import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoPeriod; import java.time.chrono.ChronoZonedDateTime; import java.time.chrono.Chronology; import java.time.chrono.Era; @@ -84,8 +84,6 @@ import java.time.chrono.JapaneseDate; import java.time.chrono.MinguoChronology; import java.time.chrono.MinguoDate; import java.time.chrono.MinguoEra; -import java.time.chrono.MinguoChronology; -import java.time.chrono.MinguoDate; import java.time.chrono.ThaiBuddhistChronology; import java.time.chrono.ThaiBuddhistDate; import java.time.format.ResolverStyle; @@ -499,8 +497,8 @@ public class TCKMinguoChronology { public void test_periodUntilDate() { MinguoDate mdate1 = MinguoDate.of(1970, 1, 1); MinguoDate mdate2 = MinguoDate.of(1971, 2, 2); - Period period = mdate1.until(mdate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(mdate2); + assertEquals(period, MinguoChronology.INSTANCE.period(1, 1, 1)); } @Test @@ -516,8 +514,8 @@ public class TCKMinguoChronology { MinguoDate mdate1 = MinguoDate.of(1970, 1, 1); MinguoDate mdate2 = MinguoDate.of(1971, 2, 2); ThaiBuddhistDate ldate2 = ThaiBuddhistChronology.INSTANCE.date(mdate2); - Period period = mdate1.until(ldate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(ldate2); + assertEquals(period, MinguoChronology.INSTANCE.period(1, 1, 1)); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java index e57847c0619..5557641738a 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java @@ -72,11 +72,11 @@ import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.Month; -import java.time.Period; import java.time.Year; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoPeriod; import java.time.chrono.Chronology; import java.time.chrono.Era; import java.time.chrono.IsoChronology; @@ -458,8 +458,8 @@ public class TCKThaiBuddhistChronology { public void test_periodUntilDate() { ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1); ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2); - Period period = mdate1.until(mdate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(mdate2); + assertEquals(period, ThaiBuddhistChronology.INSTANCE.period(1, 1, 1)); } @Test @@ -475,8 +475,8 @@ public class TCKThaiBuddhistChronology { ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1); ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2); MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2); - Period period = mdate1.until(ldate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(ldate2); + assertEquals(period, ThaiBuddhistChronology.INSTANCE.period(1, 1, 1)); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java index 3e7cce46d1f..05a6d4b515d 100644 --- a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java +++ b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java @@ -26,9 +26,9 @@ package test.java.time.chrono; import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; -import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -39,12 +39,12 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; -import java.time.Period; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.chrono.ChronoLocalDate; import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoPeriod; import java.time.chrono.ChronoZonedDateTime; import java.time.chrono.Chronology; import java.time.chrono.HijrahChronology; @@ -330,26 +330,26 @@ public class TestUmmAlQuraChronology { @DataProvider(name="datesForPeriod") Object[][] data_Period() { return new Object[][] { - {HijrahDate.of(1350, 5, 15), HijrahDate.of(1434, 7, 20), Period.of(84, 2, 5)}, - {HijrahDate.of(1403, 5, 28), HijrahDate.of(1434, 7, 20), Period.of(31, 1, 22)}, - {HijrahDate.of(1434, 7, 20), HijrahDate.of(1484, 2, 15), Period.of(49, 6, 24)}, - {HijrahDate.of(1500, 6, 12), HijrahDate.of(1450, 4, 21), Period.of(-50, -1, -20)}, - {HijrahDate.of(1549, 3, 11), HijrahDate.of(1550, 3, 10), Period.of(0, 11, 28)}, + {HijrahDate.of(1350, 5, 15), HijrahDate.of(1434, 7, 20), HijrahChronology.INSTANCE.period(84, 2, 5)}, + {HijrahDate.of(1403, 5, 28), HijrahDate.of(1434, 7, 20), HijrahChronology.INSTANCE.period(31, 1, 22)}, + {HijrahDate.of(1434, 7, 20), HijrahDate.of(1484, 2, 15), HijrahChronology.INSTANCE.period(49, 6, 24)}, + {HijrahDate.of(1500, 6, 12), HijrahDate.of(1450, 4, 21), HijrahChronology.INSTANCE.period(-50, -1, -20)}, + {HijrahDate.of(1549, 3, 11), HijrahDate.of(1550, 3, 10), HijrahChronology.INSTANCE.period(0, 11, 28)}, }; } // Test to get the Period between two given dates @Test(dataProvider="datesForPeriod") - public void test_until(HijrahDate h1, HijrahDate h2, Period p) { - Period period = h1.until(h2); + public void test_until(HijrahDate h1, HijrahDate h2, ChronoPeriod p) { + ChronoPeriod period = h1.until(h2); assertEquals(period, p); } // Test to get the Period between dates in different chronologies @Test(dataProvider="datesForPeriod") - public void test_periodUntilDiffChrono(HijrahDate h1, HijrahDate h2, Period p) { + public void test_periodUntilDiffChrono(HijrahDate h1, HijrahDate h2, ChronoPeriod p) { MinguoDate m = MinguoChronology.INSTANCE.date(h2); - Period period = h1.until(m); + ChronoPeriod period = h1.until(m); assertEquals(period, p); } From a0c3d88fba62b486273b94a1b742fba9d2199cd7 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 4 Sep 2013 16:22:22 +0200 Subject: [PATCH 0204/1294] 8019853: Break logging and AWT circular dependency Break logging and AWT circular dependency, which was at the root cause for 8023258 - Logger.getLogger() after ImageIO.read() returns different logger instance Reviewed-by: mchung, art --- .../classes/java/util/logging/LogManager.java | 38 +++++----- jdk/src/share/classes/sun/awt/AppContext.java | 66 ++++++++++++---- .../share/classes/sun/misc/JavaAWTAccess.java | 14 ++-- .../share/classes/sun/misc/SharedSecrets.java | 2 +- .../util/logging/TestAppletLoggerContext.java | 19 ++--- .../TestLoggingWithMainAppContext.java | 75 +++++++++++++++++++ 6 files changed, 159 insertions(+), 55 deletions(-) create mode 100644 jdk/test/java/util/logging/TestLoggingWithMainAppContext.java diff --git a/jdk/src/share/classes/java/util/logging/LogManager.java b/jdk/src/share/classes/java/util/logging/LogManager.java index 0d63468b3cc..717e52990e1 100644 --- a/jdk/src/share/classes/java/util/logging/LogManager.java +++ b/jdk/src/share/classes/java/util/logging/LogManager.java @@ -391,6 +391,9 @@ public class LogManager { } } + // LoggerContext maps from AppContext + private static WeakHashMap contextsMap = null; + // Returns the LoggerContext for the user code (i.e. application or AppContext). // Loggers are isolated from each AppContext. private LoggerContext getUserContext() { @@ -399,33 +402,28 @@ public class LogManager { SecurityManager sm = System.getSecurityManager(); JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess(); if (sm != null && javaAwtAccess != null) { + // for each applet, it has its own LoggerContext isolated from others synchronized (javaAwtAccess) { - // AppContext.getAppContext() returns the system AppContext if called - // from a system thread but Logger.getLogger might be called from - // an applet code. Instead, find the AppContext of the applet code - // from the execution stack. - Object ecx = javaAwtAccess.getExecutionContext(); - if (ecx == null) { - // fall back to thread group seach of AppContext - ecx = javaAwtAccess.getContext(); - } + // find the AppContext of the applet code + // will be null if we are in the main app context. + final Object ecx = javaAwtAccess.getAppletContext(); if (ecx != null) { - context = (LoggerContext)javaAwtAccess.get(ecx, LoggerContext.class); + if (contextsMap == null) { + contextsMap = new WeakHashMap<>(); + } + context = contextsMap.get(ecx); if (context == null) { - if (javaAwtAccess.isMainAppContext()) { - context = userContext; - } else { - // Create a new LoggerContext for the applet. - // The new logger context has its requiresDefaultLoggers - // flag set to true - so that these loggers will be - // lazily added when the context is firt accessed. - context = new LoggerContext(true); - } - javaAwtAccess.put(ecx, LoggerContext.class, context); + // Create a new LoggerContext for the applet. + // The new logger context has its requiresDefaultLoggers + // flag set to true - so that these loggers will be + // lazily added when the context is firt accessed. + context = new LoggerContext(true); + contextsMap.put(ecx, context); } } } } + // for standalone app, return userContext return context != null ? context : userContext; } diff --git a/jdk/src/share/classes/sun/awt/AppContext.java b/jdk/src/share/classes/sun/awt/AppContext.java index d4ed6525ad8..dbdc920dd5f 100644 --- a/jdk/src/share/classes/sun/awt/AppContext.java +++ b/jdk/src/share/classes/sun/awt/AppContext.java @@ -838,21 +838,59 @@ public final class AppContext { public boolean isMainAppContext() { return (numAppContexts.get() == 1 && mainAppContext != null); } - public Object getContext() { - return getAppContext(); - } - public Object getExecutionContext() { - return getExecutionAppContext(); - } - public Object get(Object context, Object key) { - return ((AppContext)context).get(key); - } - public void put(Object context, Object key, Object value) { - ((AppContext)context).put(key, value); - } - public void remove(Object context, Object key) { - ((AppContext)context).remove(key); + + /** + * Returns the AppContext used for applet logging isolation, or null if + * the default global context can be used. + * If there's no applet, or if the caller is a stand alone application, + * or running in the main app context, returns null. + * Otherwise, returns the AppContext of the calling applet. + * @return null if the global default context can be used, + * an AppContext otherwise. + **/ + public Object getAppletContext() { + // There's no AppContext: return null. + // No need to call getAppContext() if numAppContext == 0: + // it means that no AppContext has been created yet, and + // we don't want to trigger the creation of a main app + // context since we don't need it. + if (numAppContexts.get() == 0) return null; + + // Get the context from the security manager + AppContext ecx = getExecutionAppContext(); + + // Not sure we really need to re-check numAppContexts here. + // If all applets have gone away then we could have a + // numAppContexts coming back to 0. So we recheck + // it here because we don't want to trigger the + // creation of a main AppContext in that case. + // This is probably not 100% MT-safe but should reduce + // the window of opportunity in which that issue could + // happen. + if (numAppContexts.get() > 0) { + // Defaults to thread group caching. + // This is probably not required as we only really need + // isolation in a deployed applet environment, in which + // case ecx will not be null when we reach here + // However it helps emulate the deployed environment, + // in tests for instance. + ecx = ecx != null ? ecx : getAppContext(); + } + + // getAppletContext() may be called when initializing the main + // app context - in which case mainAppContext will still be + // null. To work around this issue we simply use + // AppContext.threadGroup.getParent() == null instead, since + // mainAppContext is the only AppContext which should have + // the root TG as its thread group. + // See: JDK-8023258 + final boolean isMainAppContext = ecx == null + || mainAppContext == ecx + || mainAppContext == null && ecx.threadGroup.getParent() == null; + + return isMainAppContext ? null : ecx; } + }); } } diff --git a/jdk/src/share/classes/sun/misc/JavaAWTAccess.java b/jdk/src/share/classes/sun/misc/JavaAWTAccess.java index e64a38b22c9..e0d3c384584 100644 --- a/jdk/src/share/classes/sun/misc/JavaAWTAccess.java +++ b/jdk/src/share/classes/sun/misc/JavaAWTAccess.java @@ -26,14 +26,16 @@ package sun.misc; public interface JavaAWTAccess { - public Object getContext(); - public Object getExecutionContext(); - public Object get(Object context, Object key); - public void put(Object context, Object key, Object value); - public void remove(Object context, Object key); + // Returns the AppContext used for applet logging isolation, or null if + // no isolation is required. + // If there's no applet, or if the caller is a stand alone application, + // or running in the main app context, returns null. + // Otherwise, returns the AppContext of the calling applet. + public Object getAppletContext(); - // convenience methods whose context is the object returned by getContext() + // convenience methods to cache objects in the current thread group's + // AppContext public Object get(Object key); public void put(Object key, Object value); public void remove(Object key); diff --git a/jdk/src/share/classes/sun/misc/SharedSecrets.java b/jdk/src/share/classes/sun/misc/SharedSecrets.java index 9248afa5ed3..bc2ab2e9ea6 100644 --- a/jdk/src/share/classes/sun/misc/SharedSecrets.java +++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java @@ -170,7 +170,7 @@ public class SharedSecrets { public static JavaAWTAccess getJavaAWTAccess() { // this may return null in which case calling code needs to // provision for. - if (javaAWTAccess == null || javaAWTAccess.getContext() == null) { + if (javaAWTAccess == null) { return null; } return javaAWTAccess; diff --git a/jdk/test/java/util/logging/TestAppletLoggerContext.java b/jdk/test/java/util/logging/TestAppletLoggerContext.java index c7f3d4f4991..82c39381fe8 100644 --- a/jdk/test/java/util/logging/TestAppletLoggerContext.java +++ b/jdk/test/java/util/logging/TestAppletLoggerContext.java @@ -110,28 +110,19 @@ public class TestAppletLoggerContext { } TestExc exc; - TestExc global = new TestExc(); @Override - public Object getContext() { return active ? global : null; } + public Object getAppletContext() { return active ? exc : null; } @Override - public Object getExecutionContext() { return active ? exc : null; } + public Object get(Object o) { return exc.get(o); } @Override - public Object get(Object o, Object o1) { return TestExc.exc(o).get(o1); } + public void put(Object o, Object o1) { exc.put(o, o1); } @Override - public void put(Object o, Object o1, Object o2) { TestExc.exc(o).put(o1, o2); } - @Override - public void remove(Object o, Object o1) { TestExc.exc(o).remove(o1); } - @Override - public Object get(Object o) { return global.get(o); } - @Override - public void put(Object o, Object o1) { global.put(o, o1); } - @Override - public void remove(Object o) { global.remove(o); } + public void remove(Object o) { exc.remove(o); } @Override public boolean isDisposed() { return false; } @Override - public boolean isMainAppContext() { return exc == null; } + public boolean isMainAppContext() { return !active || exc == null; } } final static JavaAWTAccessStub javaAwtAccess = new JavaAWTAccessStub(); diff --git a/jdk/test/java/util/logging/TestLoggingWithMainAppContext.java b/jdk/test/java/util/logging/TestLoggingWithMainAppContext.java new file mode 100644 index 00000000000..5489acee22a --- /dev/null +++ b/jdk/test/java/util/logging/TestLoggingWithMainAppContext.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.logging.Logger; +import javax.imageio.ImageIO; + +/** + * @test + * @bug 8019853 8023258 + * @summary Test that the default user context is used when in the main + * application context. This test must not be run in same VM or agent + * VM mode: it would not test the intended behavior. + * @run main/othervm TestLoggingWithMainAppContext + */ +public class TestLoggingWithMainAppContext { + + public static void main(String[] args) throws IOException { + System.out.println("Creating loggers."); + + // These loggers will be created in the default user context. + final Logger foo1 = Logger.getLogger( "foo" ); + final Logger bar1 = Logger.getLogger( "foo.bar" ); + if (bar1.getParent() != foo1) { + throw new RuntimeException("Parent logger of bar1 "+bar1+" is not "+foo1); + } + System.out.println("bar1.getParent() is the same as foo1"); + + // Set a security manager + System.setSecurityManager(new SecurityManager()); + System.out.println("Now running with security manager"); + + // Triggers the creation of the main AppContext + ByteArrayInputStream is = new ByteArrayInputStream(new byte[] { 0, 1 }); + ImageIO.read(is); // triggers calls to system loggers & creation of main AppContext + + // verify that we're still using the default user context + final Logger bar2 = Logger.getLogger( "foo.bar" ); + if (bar1 != bar2) { + throw new RuntimeException("bar2 "+bar2+" is not the same as bar1 "+bar1); + } + System.out.println("bar2 is the same as bar1"); + if (bar2.getParent() != foo1) { + throw new RuntimeException("Parent logger of bar2 "+bar2+" is not foo1 "+foo1); + } + System.out.println("bar2.getParent() is the same as foo1"); + final Logger foo2 = Logger.getLogger("foo"); + if (foo1 != foo2) { + throw new RuntimeException("foo2 "+foo2+" is not the same as foo1 "+foo1); + } + System.out.println("foo2 is the same as foo1"); + + System.out.println("Test passed."); + } +} From 747b74ce5e193be61d4c3032436b3c6b7c197a71 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 4 Sep 2013 19:58:16 +0530 Subject: [PATCH 0205/1294] 8024174: Setting __proto__ property in Object literal should be supported Reviewed-by: jlaskey, lagergren --- .../internal/codegen/CodeGenerator.java | 13 ++++- .../internal/runtime/ScriptObject.java | 5 +- nashorn/test/script/basic/JDK-8024174.js | 51 +++++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8024174.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 0ccc8a40489..809b2ec21e2 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -1361,6 +1361,7 @@ final class CodeGenerator extends NodeOperatorVisitor values = new ArrayList<>(); boolean hasGettersSetters = false; + Expression protoNode = null; for (PropertyNode propertyNode: elements) { final Expression value = propertyNode.getValue(); @@ -1369,6 +1370,9 @@ final class CodeGenerator extends NodeOperatorVisitor Date: Wed, 4 Sep 2013 11:41:17 -0700 Subject: [PATCH 0206/1294] 8013938: Native OOME on fastdebug VM on Solaris Reviewed-by: azeemj, brutisso, kvn, tschatzl --- .../os_cpu/solaris_x86/vm/globals_solaris_x86.hpp | 2 +- hotspot/src/share/vm/runtime/arguments.cpp | 13 ------------- hotspot/src/share/vm/runtime/arguments.hpp | 2 -- 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp b/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp index 91a4336d903..c1f656b99f8 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp @@ -44,6 +44,6 @@ define_pd_global(uintx,JVMInvokeMethodSlack, 10*K); define_pd_global(intx, CompilerThreadStackSize, 0); // Used on 64 bit platforms for UseCompressedOops base address -define_pd_global(uintx,HeapBaseMinAddress, 256*M); +define_pd_global(uintx,HeapBaseMinAddress, 2*G); #endif // OS_CPU_SOLARIS_X86_VM_GLOBALS_SOLARIS_X86_HPP diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 38f38f1c856..f40ec7c8169 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1605,17 +1605,6 @@ julong Arguments::limit_by_allocatable_memory(julong limit) { return result; } -void Arguments::set_heap_base_min_address() { - if (FLAG_IS_DEFAULT(HeapBaseMinAddress) && UseG1GC && HeapBaseMinAddress < 1*G) { - // By default HeapBaseMinAddress is 2G on all platforms except Solaris x86. - // G1 currently needs a lot of C-heap, so on Solaris we have to give G1 - // some extra space for the C-heap compared to other collectors. - // Use FLAG_SET_DEFAULT here rather than FLAG_SET_ERGO to make sure that - // code that checks for default values work correctly. - FLAG_SET_DEFAULT(HeapBaseMinAddress, 1*G); - } -} - void Arguments::set_heap_size() { if (!FLAG_IS_DEFAULT(DefaultMaxRAMFraction)) { // Deprecated flag @@ -3537,8 +3526,6 @@ jint Arguments::parse(const JavaVMInitArgs* args) { } } - set_heap_base_min_address(); - // Set heap size based on available physical memory set_heap_size(); diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index c5a6854dcc3..974aff132e0 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -315,8 +315,6 @@ class Arguments : AllStatic { // limits the given memory size by the maximum amount of memory this process is // currently allowed to allocate or reserve. static julong limit_by_allocatable_memory(julong size); - // Setup HeapBaseMinAddress - static void set_heap_base_min_address(); // Setup heap size static void set_heap_size(); // Based on automatic selection criteria, should the From e447689d41cc514db2c7f292785f6a22d7540609 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Wed, 4 Sep 2013 12:35:22 -0700 Subject: [PATCH 0207/1294] 6341345: (spec) Console.reader() should make it clear that the reader requires line termination To clarify the spec Reviewed-by: alanb --- jdk/src/share/classes/java/io/Console.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/java/io/Console.java b/jdk/src/share/classes/java/io/Console.java index c100f8a0ccd..292e42eec7c 100644 --- a/jdk/src/share/classes/java/io/Console.java +++ b/jdk/src/share/classes/java/io/Console.java @@ -124,9 +124,11 @@ public final class Console implements Flushable * {@link java.io.Reader#read(java.nio.CharBuffer) read(java.nio.CharBuffer)} * on the returned object will not read in characters beyond the line * bound for each invocation, even if the destination buffer has space for - * more characters. A line bound is considered to be any one of a line feed - * ('\n'), a carriage return ('\r'), a carriage return - * followed immediately by a linefeed, or an end of stream. + * more characters. The {@code Reader}'s {@code read} methods may block if a + * line bound has not been entered or reached on the console's input device. + * A line bound is considered to be any one of a line feed ('\n'), + * a carriage return ('\r'), a carriage return followed immediately + * by a linefeed, or an end of stream. * * @return The reader associated with this console */ From db444fae3e243cfce00515d993f582d83e5f8768 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Wed, 4 Sep 2013 12:37:41 -0700 Subject: [PATCH 0208/1294] 7186632: NLS t13y issue on jar.properties file To remove the redundant backslash Reviewed-by: naoto --- jdk/src/share/classes/sun/tools/jar/resources/jar.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar.properties index 852cac2889a..c8e8d9aecec 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar.properties @@ -61,7 +61,7 @@ out.create=\ out.extracted=\ extracted: {0} out.inflated=\ - \ \inflated: {0} + \ inflated: {0} out.size=\ (in = {0}) (out= {1}) From 7da0f59aec2d0011cae55272a5327b8d2f38941f Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 4 Sep 2013 14:44:05 -0700 Subject: [PATCH 0209/1294] 8024288: javadoc generated-by comment should always be present Reviewed-by: bpatel --- .../formats/html/HtmlDocletWriter.java | 5 +-- .../formats/html/markup/HtmlDocWriter.java | 17 ++++----- .../testGeneratedBy/TestGeneratedBy.java | 35 +++++++++++++------ 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java index c55ff564f2f..da36fedcff0 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java @@ -406,10 +406,7 @@ public class HtmlDocletWriter extends HtmlDocWriter { Content htmlDocType = DocType.TRANSITIONAL; Content htmlComment = new Comment(configuration.getText("doclet.New_Page")); Content head = new HtmlTree(HtmlTag.HEAD); - if (!configuration.notimestamp) { - Content headComment = new Comment(getGeneratedByString()); - head.addContent(headComment); - } + head.addContent(getGeneratedBy(!configuration.notimestamp)); if (configuration.charset.length() > 0) { Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, configuration.charset); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java index 0eb40080295..c780e962cac 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java @@ -191,10 +191,7 @@ public abstract class HtmlDocWriter extends HtmlWriter { Content htmlDocType = DocType.FRAMESET; Content htmlComment = new Comment(configuration.getText("doclet.New_Page")); Content head = new HtmlTree(HtmlTag.HEAD); - if (! noTimeStamp) { - Content headComment = new Comment(getGeneratedByString()); - head.addContent(headComment); - } + head.addContent(getGeneratedBy(!noTimeStamp)); if (configuration.charset.length() > 0) { Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, configuration.charset); @@ -210,9 +207,13 @@ public abstract class HtmlDocWriter extends HtmlWriter { write(htmlDocument); } - protected String getGeneratedByString() { - Calendar calendar = new GregorianCalendar(TimeZone.getDefault()); - Date today = calendar.getTime(); - return "Generated by javadoc ("+ ConfigurationImpl.BUILD_DATE + ") on " + today; + protected Comment getGeneratedBy(boolean timestamp) { + String text = "Generated by javadoc"; // marker string, deliberately not localized + if (timestamp) { + Calendar calendar = new GregorianCalendar(TimeZone.getDefault()); + Date today = calendar.getTime(); + text += " ("+ ConfigurationImpl.BUILD_DATE + ") on " + today; + } + return new Comment(text); } } diff --git a/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java b/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java index 162105edf8b..ec85bec863b 100644 --- a/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java +++ b/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8000418 + * @bug 8000418 8024288 * @summary Verify that files use a common Generated By string * @library ../lib/ * @build JavadocTester TestGeneratedBy @@ -50,32 +50,44 @@ public class TestGeneratedBy extends JavadocTester { "index.html" }; - private static final String[] ARGS = + private static final String[] STD_ARGS = new String[] { "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; - private static final String BUG_ID = "8000418"; - private static String[][] getTests() { + private static final String[] NO_TIMESTAMP_ARGS = + new String[] { + "-notimestamp", + "-d", OUTPUT_DIR, + "-sourcepath", SRC_DIR, + "pkg" + }; + + private static final String BUG_ID = "8000418-8024288"; + + private static String[][] getTests(boolean timestamp) { String version = System.getProperty("java.version"); String[][] tests = new String[FILES.length][]; for (int i = 0; i < FILES.length; i++) { + String genBy = "Generated by javadoc"; + if (timestamp) genBy += " (" + version + ") on "; tests[i] = new String[] { - OUTPUT_DIR + FS + FILES[i], - "Generated by javadoc (" + version + ") on " + OUTPUT_DIR + FS + FILES[i], genBy }; } return tests; } - private static String[][] getNegatedTests() { + private static String[][] getNegatedTests(boolean timestamp) { String[][] tests = new String[FILES.length][]; for (int i = 0; i < FILES.length; i++) { tests[i] = new String[] { OUTPUT_DIR + FS + FILES[i], - "Generated by javadoc (version", + (timestamp + ? "Generated by javadoc (version" + : "Generated by javadoc ("), "Generated by javadoc on" }; } @@ -88,9 +100,10 @@ public class TestGeneratedBy extends JavadocTester { */ public static void main(String[] args) { TestGeneratedBy tester = new TestGeneratedBy(); - int exitCode = run(tester, ARGS, getTests(), getNegatedTests()); + int ec1 = run(tester, STD_ARGS, getTests(true), getNegatedTests(true)); + int ec2 = run(tester, NO_TIMESTAMP_ARGS, getTests(false), getNegatedTests(false)); tester.printSummary(); - if (exitCode != 0) { + if (ec1 != 0 || ec2 != 0) { throw new Error("Error found while executing Javadoc"); } } From b5cd24ccc9fda567c7a25c8088974b3a77800551 Mon Sep 17 00:00:00 2001 From: Robert Field Date: Wed, 4 Sep 2013 19:47:26 -0700 Subject: [PATCH 0210/1294] 8020816: Metafactory crashes on code with method reference 8021050: MethodHandleInfo throws exception when method handle is to a method with @CallerSensitive Fixed by 8008688 - this is a test to confirm the above fixed Reviewed-by: vlivanov --- .../MethodReferenceTestCallerSensitive.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java diff --git a/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java b/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java new file mode 100644 index 00000000000..805a6a203cb --- /dev/null +++ b/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.testng.annotations.Test; + +import java.lang.reflect.Field; +import java.util.function.Function; + + +/** + * @author Robert Field + */ + +@Test +public class MethodReferenceTestCallerSensitive { + + private static void getF(T arg) { + Function,Field[]> firstFunction = Class::getFields; + } + + public void testConstructorReferenceVarArgs() { + getF("Hello World"); + } + +} From d8b770b0cd7a1a52d39fd0f4407bd14e9232358a Mon Sep 17 00:00:00 2001 From: Clemens Eisserer Date: Thu, 5 Sep 2013 11:50:42 +0400 Subject: [PATCH 0211/1294] 8024261: xrender: improve performance of small fillRect operations Reviewed-by: prr, bae --- .../solaris/classes/sun/java2d/xr/XRCompositeManager.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java b/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java index b1c2ef08065..39b8642bb9d 100644 --- a/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java +++ b/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java @@ -285,7 +285,12 @@ public class XRCompositeManager { if (xorEnabled) { con.GCRectangles(dst.getXid(), dst.getGC(), rects); } else { - con.renderRectangles(dst.getPicture(), compRule, solidColor, rects); + if (rects.getSize() == 1) { + con.renderRectangle(dst.getPicture(), compRule, solidColor, + rects.getX(0), rects.getY(0), rects.getWidth(0), rects.getHeight(0)); + } else { + con.renderRectangles(dst.getPicture(), compRule, solidColor, rects); + } } } From 4bf1e0d9890a1df932db4b277720de1f181cfb46 Mon Sep 17 00:00:00 2001 From: Andreas Lundblad Date: Thu, 5 Sep 2013 11:27:27 +0200 Subject: [PATCH 0212/1294] 8023974: Drop 'implements Completer' and 'implements SourceCompleter' from ClassReader resp. JavaCompiler Reviewed-by: jjg, jfranck --- .../com/sun/tools/javac/jvm/ClassReader.java | 23 ++++++++++++++----- .../sun/tools/javac/main/JavaCompiler.java | 15 ++++++++++-- .../com/sun/tools/javadoc/JavadocTool.java | 4 ++-- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 3fc93921c8e..d3d9d302f1e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -72,7 +72,7 @@ import static com.sun.tools.javac.main.Option.*; * This code and its internal interfaces are subject to change or * deletion without notice. */ -public class ClassReader implements Completer { +public class ClassReader { /** The context key for the class reader. */ protected static final Context.Key classReaderKey = new Context.Key(); @@ -234,6 +234,17 @@ public class ClassReader implements Completer { */ Set warnedAttrs = new HashSet(); + /** + * Completer that delegates to the complete-method of this class. + */ + private final Completer thisCompleter = new Completer() { + @Override + public void complete(Symbol sym) throws CompletionFailure { + ClassReader.this.complete(sym); + } + }; + + /** Get the ClassReader instance for this invocation. */ public static ClassReader instance(Context context) { ClassReader instance = context.get(classReaderKey); @@ -264,8 +275,8 @@ public class ClassReader implements Completer { } packages.put(names.empty, syms.rootPackage); - syms.rootPackage.completer = this; - syms.unnamedPackage.completer = this; + syms.rootPackage.completer = thisCompleter; + syms.unnamedPackage.completer = thisCompleter; } /** Construct a new class reader, optionally treated as the @@ -2319,7 +2330,7 @@ public class ClassReader implements Completer { ClassSymbol c = new ClassSymbol(0, name, owner); if (owner.kind == PCK) Assert.checkNull(classes.get(c.flatname), c); - c.completer = this; + c.completer = thisCompleter; return c; } @@ -2389,7 +2400,7 @@ public class ClassReader implements Completer { /** Completion for classes to be loaded. Before a class is loaded * we make sure its enclosing class (if any) is loaded. */ - public void complete(Symbol sym) throws CompletionFailure { + private void complete(Symbol sym) throws CompletionFailure { if (sym.kind == TYP) { ClassSymbol c = (ClassSymbol)sym; c.members_field = new Scope.ErrorScope(c); // make sure it's always defined @@ -2610,7 +2621,7 @@ public class ClassReader implements Completer { p = new PackageSymbol( Convert.shortName(fullname), enterPackage(Convert.packagePart(fullname))); - p.completer = this; + p.completer = thisCompleter; packages.put(fullname, p); } return p; diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 73d3b020bc1..ba369172f43 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -80,7 +80,7 @@ import static com.sun.tools.javac.util.ListBuffer.lb; * This code and its internal interfaces are subject to change or * deletion without notice. */ -public class JavaCompiler implements ClassReader.SourceCompleter { +public class JavaCompiler { /** The context key for the compiler. */ protected static final Context.Key compilerKey = new Context.Key(); @@ -310,6 +310,17 @@ public class JavaCompiler implements ClassReader.SourceCompleter { */ protected JavaCompiler delegateCompiler; + /** + * SourceCompleter that delegates to the complete-method of this class. + */ + protected final ClassReader.SourceCompleter thisCompleter = + new ClassReader.SourceCompleter() { + @Override + public void complete(ClassSymbol sym) throws CompletionFailure { + JavaCompiler.this.complete(sym); + } + }; + /** * Command line options. */ @@ -374,7 +385,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { types = Types.instance(context); taskListener = MultiTaskListener.instance(context); - reader.sourceCompleter = this; + reader.sourceCompleter = thisCompleter; options = Options.instance(context); diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java index 1cc3de3c8c3..f30251ab737 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -134,7 +134,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { docenv.setEncoding(encoding); docenv.docClasses = docClasses; docenv.legacyDoclet = legacyDoclet; - javadocReader.sourceCompleter = docClasses ? null : this; + javadocReader.sourceCompleter = docClasses ? null : thisCompleter; ListBuffer names = new ListBuffer(); ListBuffer classTrees = new ListBuffer(); From 034634875cd0602cca06a97bb1c349f37198a72f Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 5 Sep 2013 02:45:32 -0700 Subject: [PATCH 0213/1294] Added tag jdk8-b106 for changeset e80e02865308 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 8faf5f45228..f96b90eb232 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -227,3 +227,4 @@ a013024b07475782f1fa8e196e950b34b4077663 jdk8-b101 49c4a777fdfd648d4c3fffc940fdb97a23108ca8 jdk8-b103 d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104 4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105 +2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106 From 250f98771a364f5959a712c3add2461d94aa2583 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 5 Sep 2013 02:45:38 -0700 Subject: [PATCH 0214/1294] Added tag jdk8-b106 for changeset a9ef5fb72167 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 56c23d248df..2cb597e46a2 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -373,3 +373,4 @@ c4697c1c448416108743b59118b4a2498b339d0c jdk8-b102 c1604d5885a6f2adc0bcea2fa142a8f6bafad2f0 hs25-b47 acac3bde66b2c22791c257a8d99611d6d08c6713 jdk8-b105 18b4798adbc42c6fa16f5ecb7d5cd3ca130754bf hs25-b48 +aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106 From 611d484e6f578c51d03aa8607d849533c8fdfa82 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 5 Sep 2013 02:45:50 -0700 Subject: [PATCH 0215/1294] Added tag jdk8-b106 for changeset dabbe0edf55c --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 4b34a22f505..e21e3e57573 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -227,3 +227,4 @@ adf49c3ef83c160d53ece623049b2cdccaf78fc7 jdk8-b99 b1ceab582fc6d795b20aaa8a3fde2eba34af9399 jdk8-b103 a22fe9bd01e6c7e7ddc7995dfc9471711692b8d1 jdk8-b104 09a46ec11f880154886c70be03aff5ab2ddf0ab7 jdk8-b105 +d3be8e3b429df917e72c1c23e7920c651219b587 jdk8-b106 From a1bee3f227e3fedba4e5506cb24d9a35ab81cb1a Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 5 Sep 2013 02:45:53 -0700 Subject: [PATCH 0216/1294] Added tag jdk8-b106 for changeset 2f514eb96d97 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 8becfa5e369..d213728514a 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -227,3 +227,4 @@ b1fb4612a2caea52b5661b87509e560fa044b194 jdk8-b98 6cdc6ed987801c175a1217d0d3e53c3bd69ba52e jdk8-b103 42211ab0ab1cca51a050d184634cf1db7ef81fbf jdk8-b104 88390df7ed2cf128298a02c5e6d978f0a603cd58 jdk8-b105 +6908370afe834ff01739e8ec992d4246c74b7e6e jdk8-b106 From f10d1b5c6e7638eb0d6ebb76bfbe3b528595fc00 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 5 Sep 2013 02:46:01 -0700 Subject: [PATCH 0217/1294] Added tag jdk8-b106 for changeset 347df39afea6 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index df88b26f840..c20c5cde8f0 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -227,3 +227,4 @@ c4908732fef5235f1b98cafe0ce507771ef7892c jdk8-b98 e0f6039c0290b7381042a6fec3100a69a5a67e37 jdk8-b103 f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104 1fe211ae3d2b8cc2dfc4f58d9a6eb96418679672 jdk8-b105 +c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106 From 16c7de00277de8f7c7f59849f9fe16158e118575 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 5 Sep 2013 02:46:21 -0700 Subject: [PATCH 0218/1294] Added tag jdk8-b106 for changeset fa7b69611589 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 221777df498..d15910c1e57 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -227,3 +227,4 @@ ce5a90df517bdceb2739d7dd3e6764b070def802 jdk8-b98 76cfe7c61f2575ea5400845b8e80dab6f4b1d7d0 jdk8-b103 dd4a00c220c6e14d9b2ce93a2bd436a1d04f0d03 jdk8-b104 375834b5cf086dd7ce9e49f602d81bb51d3e0fa9 jdk8-b105 +fcd768844b9926c5f994292ec6350c20cc7c0f76 jdk8-b106 From 115b15c1fcb2e2e42e4c3362176585a20067b74f Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 5 Sep 2013 02:46:24 -0700 Subject: [PATCH 0219/1294] Added tag jdk8-b106 for changeset 6ba209076a37 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 14ef8a6ccb7..0cc3a707a66 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -215,3 +215,4 @@ e966ff0a3ffef8a687eaf5a14167bb595b623d02 jdk8-b102 414203de4374e1964a9918c38a95fb245010a9f1 jdk8-b103 afc100513451d22f0b8135999d6eb52f36df3d36 jdk8-b104 f484bfb624dd06683cb33b524700a5dd4927a82b jdk8-b105 +bf70cbd2c8369fd97ffdfcbe1a80dbc2797408ee jdk8-b106 From 02d81bbc68127319cde94e6183557571484b6773 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Thu, 5 Sep 2013 13:04:17 +0200 Subject: [PATCH 0220/1294] 8023464: test/closed/sun/tracing/ProviderProxyTest.java failing Don't rely on assertions when an Exception suits better Reviewed-by: alanb, dfuchs, sjiang --- jdk/src/share/classes/sun/tracing/ProviderSkeleton.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/sun/tracing/ProviderSkeleton.java b/jdk/src/share/classes/sun/tracing/ProviderSkeleton.java index 2a5bc360430..f68f2650b35 100644 --- a/jdk/src/share/classes/sun/tracing/ProviderSkeleton.java +++ b/jdk/src/share/classes/sun/tracing/ProviderSkeleton.java @@ -164,7 +164,10 @@ public abstract class ProviderSkeleton implements InvocationHandler, Provider { declaringClass == Object.class) { return method.invoke(this, args); } else { - assert false; + // assert false : "this should never happen" + // reaching here would indicate a breach + // in security in the higher layers + throw new SecurityException(); } } catch (IllegalAccessException e) { assert false; From 8053376ea24dd855f539094d729095e71b6eff03 Mon Sep 17 00:00:00 2001 From: Anton Nashatyrev Date: Thu, 5 Sep 2013 15:37:40 +0400 Subject: [PATCH 0221/1294] 8023392: Swing text components printed with spaces between chars Reviewed-by: alexsch, alexp --- .../classes/sun/swing/SwingUtilities2.java | 114 +++++-- .../java/awt/print/bug8023392/bug8023392.html | 20 ++ .../java/awt/print/bug8023392/bug8023392.java | 286 ++++++++++++++++++ 3 files changed, 387 insertions(+), 33 deletions(-) create mode 100644 jdk/test/java/awt/print/bug8023392/bug8023392.html create mode 100644 jdk/test/java/awt/print/bug8023392/bug8023392.java diff --git a/jdk/src/share/classes/sun/swing/SwingUtilities2.java b/jdk/src/share/classes/sun/swing/SwingUtilities2.java index a1903f2bdd2..07bb880d0ff 100644 --- a/jdk/src/share/classes/sun/swing/SwingUtilities2.java +++ b/jdk/src/share/classes/sun/swing/SwingUtilities2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ import java.awt.event.*; import java.awt.font.*; import java.awt.geom.*; import java.awt.print.PrinterGraphics; +import java.text.CharacterIterator; import java.text.AttributedCharacterIterator; import java.text.AttributedString; @@ -504,22 +505,25 @@ public class SwingUtilities2 { * it to fit in the screen width. This distributes the spacing * more evenly than directly laying out to the screen advances. */ - float screenWidth = (float) - g2d.getFont().getStringBounds(text, DEFAULT_FRC).getWidth(); - TextLayout layout = createTextLayout(c, text, g2d.getFont(), - g2d.getFontRenderContext()); + String trimmedText = trimTrailingSpaces(text); + if (!trimmedText.isEmpty()) { + float screenWidth = (float) g2d.getFont().getStringBounds + (trimmedText, DEFAULT_FRC).getWidth(); + TextLayout layout = createTextLayout(c, text, g2d.getFont(), + g2d.getFontRenderContext()); - layout = layout.getJustifiedLayout(screenWidth); - /* Use alternate print color if specified */ - Color col = g2d.getColor(); - if (col instanceof PrintColorUIResource) { - g2d.setColor(((PrintColorUIResource)col).getPrintColor()); + layout = layout.getJustifiedLayout(screenWidth); + /* Use alternate print color if specified */ + Color col = g2d.getColor(); + if (col instanceof PrintColorUIResource) { + g2d.setColor(((PrintColorUIResource)col).getPrintColor()); + } + + layout.draw(g2d, x, y); + + g2d.setColor(col); } - layout.draw(g2d, x, y); - - g2d.setColor(col); - return; } } @@ -789,25 +793,27 @@ public class SwingUtilities2 { if (frc != null && !isFontRenderContextPrintCompatible (deviceFontRenderContext, frc)) { - TextLayout layout = - createTextLayout(c, new String(data, offset, length), - g2d.getFont(), - deviceFontRenderContext); - float screenWidth = (float)g2d.getFont(). - getStringBounds(data, offset, offset + length, frc). - getWidth(); - layout = layout.getJustifiedLayout(screenWidth); - /* Use alternate print color if specified */ - Color col = g2d.getColor(); - if (col instanceof PrintColorUIResource) { - g2d.setColor(((PrintColorUIResource)col).getPrintColor()); + String text = new String(data, offset, length); + TextLayout layout = new TextLayout(text, g2d.getFont(), + deviceFontRenderContext); + String trimmedText = trimTrailingSpaces(text); + if (!trimmedText.isEmpty()) { + float screenWidth = (float)g2d.getFont(). + getStringBounds(trimmedText, frc).getWidth(); + layout = layout.getJustifiedLayout(screenWidth); + + /* Use alternate print color if specified */ + Color col = g2d.getColor(); + if (col instanceof PrintColorUIResource) { + g2d.setColor(((PrintColorUIResource)col).getPrintColor()); + } + + layout.draw(g2d,x,y); + + g2d.setColor(col); } - layout.draw(g2d,x,y); - - g2d.setColor(col); - return nextX; } } @@ -888,14 +894,23 @@ public class SwingUtilities2 { } else { frc = g2d.getFontRenderContext(); } - TextLayout layout = new TextLayout(iterator, frc); + TextLayout layout; if (isPrinting) { FontRenderContext deviceFRC = g2d.getFontRenderContext(); if (!isFontRenderContextPrintCompatible(frc, deviceFRC)) { - float screenWidth = layout.getAdvance(); layout = new TextLayout(iterator, deviceFRC); - layout = layout.getJustifiedLayout(screenWidth); + AttributedCharacterIterator trimmedIt = + getTrimmedTrailingSpacesIterator(iterator); + if (trimmedIt != null) { + float screenWidth = new TextLayout(trimmedIt, frc). + getAdvance(); + layout = layout.getJustifiedLayout(screenWidth); + } + } else { + layout = new TextLayout(iterator, frc); } + } else { + layout = new TextLayout(iterator, frc); } layout.draw(g2d, x, y); retVal = layout.getAdvance(); @@ -1047,6 +1062,39 @@ public class SwingUtilities2 { return (g instanceof PrinterGraphics || g instanceof PrintGraphics); } + private static String trimTrailingSpaces(String s) { + int i = s.length() - 1; + while(i >= 0 && Character.isWhitespace(s.charAt(i))) { + i--; + } + return s.substring(0, i + 1); + } + + private static AttributedCharacterIterator getTrimmedTrailingSpacesIterator + (AttributedCharacterIterator iterator) { + int curIdx = iterator.getIndex(); + + char c = iterator.last(); + while(c != CharacterIterator.DONE && Character.isWhitespace(c)) { + c = iterator.previous(); + } + + if (c != CharacterIterator.DONE) { + int endIdx = iterator.getIndex(); + + if (endIdx == iterator.getEndIndex() - 1) { + iterator.setIndex(curIdx); + return iterator; + } else { + AttributedString trimmedText = new AttributedString(iterator, + iterator.getBeginIndex(), endIdx + 1); + return trimmedText.getIterator(); + } + } else { + return null; + } + } + /** * Determines whether the SelectedTextColor should be used for painting text * foreground for the specified highlight. diff --git a/jdk/test/java/awt/print/bug8023392/bug8023392.html b/jdk/test/java/awt/print/bug8023392/bug8023392.html new file mode 100644 index 00000000000..d796a21c660 --- /dev/null +++ b/jdk/test/java/awt/print/bug8023392/bug8023392.html @@ -0,0 +1,20 @@ + + + + Bug 8023392 + + + +

    Bug ID: 8023392

    + +

    See the dialog box (usually in upper left corner) for instructions

    + + + + diff --git a/jdk/test/java/awt/print/bug8023392/bug8023392.java b/jdk/test/java/awt/print/bug8023392/bug8023392.java new file mode 100644 index 00000000000..6c6fbb26ee9 --- /dev/null +++ b/jdk/test/java/awt/print/bug8023392/bug8023392.java @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + test + @bug 8023392 + @summary Swing text components printed with spaces between chars + @author Anton Nashatyrev + @run applet/manual=yesno bug8023392.html +*/ + +import javax.swing.*; +import javax.swing.border.LineBorder; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.font.TextAttribute; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.text.AttributedCharacterIterator; +import java.text.AttributedString; + + +public class bug8023392 extends Applet { + static final String[] instructions = { + "A Frame containing several pairs of labels ((a) and (b)) is displayed.", + "Labels of each pair look the same and are left-aligned (with spaces ", + "between chars).", + "1. Hit the print button.", + "2. Select any available printer (printing to file is also fine).", + "3. Look at the printing result (paper, PDF, PS, etc.):", + " The (a) and (b) labels should look almost the same and the (a) labels", + " shouldn't appear as if they are stretched along X axis."}; + + public void init() { + this.setLayout(new BorderLayout()); + add(new SimplePrint2(), BorderLayout.CENTER); + + Sysout.createDialogWithInstructions(instructions); + + } + + public static class SimplePrint2 extends JPanel + implements ActionListener, Printable { + JLabel label1; + JLabel label2; + JButton printButton; + + + public SimplePrint2() { + setLayout(new BorderLayout()); + label1 = new JLabel("2a) a b c d e" + + " "); + label2 = new JLabel("2b) a b c d e"); + + Box p1 = new Box(BoxLayout.Y_AXIS); + p1.add(label1); + p1.add(label2); + p1.add(new JLabel("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww") { + String s = "3a) a b c d e "; + @Override + protected void paintComponent(Graphics g) { + sun.swing.SwingUtilities2.drawChars(this, g, s.toCharArray(), + 0, s.length(), 0, 15); + } + }); + p1.add(new JLabel("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww") { + String s = "3b) a b c d e"; + @Override + protected void paintComponent(Graphics g) { + sun.swing.SwingUtilities2.drawChars(this, g, s.toCharArray(), + 0, s.length(), 0, 15); + } + }); + p1.add(new JLabel("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww") { + String s = "4a) a b c d e "; + AttributedCharacterIterator it; + { + AttributedString as = new AttributedString(s); + as.addAttribute(TextAttribute.FONT, getFont()); + as.addAttribute(TextAttribute.FOREGROUND, Color.RED, 3, 8); + it = as.getIterator(); + } + @Override + protected void paintComponent(Graphics g) { + sun.swing.SwingUtilities2.drawString(this, g, it, 0, 15); + } + }); + + p1.add(new JLabel("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww") { + String s = "4b) a b c d e"; + AttributedCharacterIterator it; + { + AttributedString as = new AttributedString(s); + as.addAttribute(TextAttribute.FONT, getFont()); + as.addAttribute(TextAttribute.FOREGROUND, Color.RED, 3, 8); + it = as.getIterator(); + } + @Override + protected void paintComponent(Graphics g) { + sun.swing.SwingUtilities2.drawString(this, g, it, 0, 15); + } + }); + + JPanel p2 = new JPanel(); + printButton = new JButton("Print"); + printButton.addActionListener(this); + p2.add(printButton); + + Container c = this; + c.add(p1, BorderLayout.CENTER); + c.add(p2, BorderLayout.SOUTH); + + String[] data = { + "1a) \u30aa\u30f3\u30e9\u30a4\u30f3\u6d88\u8fbc" + + " ", + "1b) \u30aa\u30f3\u30e9\u30a4\u30f3\u6d88\u8fbc" + }; + JList l0 = new JList(data); + l0.setVisibleRowCount(l0.getModel().getSize()); + JScrollPane jsp = new JScrollPane(l0); + l0.setBorder(new LineBorder(Color.GRAY)); + c.add(jsp, BorderLayout.NORTH); + + for (Component comp : new Component[]{label1, label2, printButton}) { + comp.setFont(new Font("Monospaced", 0, 16)); + } + } + + public void actionPerformed(ActionEvent e) { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(this); + if (job.printDialog()) { + try { + job.print(); + } catch (PrinterException ex) { + ex.printStackTrace(); + } + } + } + + public int print(Graphics graphics, + PageFormat pageFormat, + int pageIndex) + throws PrinterException { + if (pageIndex >= 1) { + return Printable.NO_SUCH_PAGE; + } + + this.paint(graphics); + return Printable.PAGE_EXISTS; + } + } +} + + +/** + * ************************************************* + * Standard Test Machinery + * DO NOT modify anything below -- it's a standard + * chunk of code whose purpose is to make user + * interaction uniform, and thereby make it simpler + * to read and understand someone else's test. + * ************************************************** + */ +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions(String[] instructions) { + dialog = new TestDialog(new Frame(), "Instructions"); + dialog.printInstructions(instructions); + dialog.show(); + println("Any messages for the tester will display here."); + } + + public static void createDialog() { + dialog = new TestDialog(new Frame(), "Instructions"); + String[] defInstr = {"Instructions will appear here. ", ""}; + dialog.printInstructions(defInstr); + dialog.show(); + println("Any messages for the tester will display here."); + } + + + public static void printInstructions(String[] instructions) { + dialog.printInstructions(instructions); + } + + + public static void println(String messageIn) { + dialog.displayMessage(messageIn); + } + +}// Sysout class + + +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog(Frame frame, String name) { + super(frame, name); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); + add("North", instructionsText); + + messageText = new TextArea("", 5, maxStringLength, scrollBoth); + add("South", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions(String[] instructions) { + //Clear out any current instructions + instructionsText.setText(""); + + //Go down array of instruction strings + + String printStr, remainingStr; + for (int i = 0; i < instructions.length; i++) { + //chop up each into pieces maxSringLength long + remainingStr = instructions[i]; + while (remainingStr.length() > 0) { + //if longer than max then chop off first max chars to print + if (remainingStr.length() >= maxStringLength) { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf(' ', maxStringLength - 1); + + if (posOfSpace <= 0) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring(0, posOfSpace + 1); + remainingStr = remainingStr.substring(posOfSpace + 1); + } + //else just print + else { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append(printStr + "\n"); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage(String messageIn) { + messageText.append(messageIn + "\n"); + } + +}// TestDialog class + From ea3200b7843e90ac8280feb04ce25a9482be548e Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Thu, 5 Sep 2013 14:34:22 +0200 Subject: [PATCH 0222/1294] 8004179: Few of test/java/lang/management/ThreadMXBean/* tests don't clean up the created threads Just run those tests in "othervm" mode. Reviewed-by: alanb, dfuchs, sjiang --- jdk/test/java/lang/management/ThreadMXBean/LockedMonitors.java | 2 +- .../java/lang/management/ThreadMXBean/LockedSynchronizers.java | 2 +- .../java/lang/management/ThreadMXBean/MyOwnSynchronizer.java | 2 +- .../java/lang/management/ThreadMXBean/SharedSynchronizer.java | 2 +- .../lang/management/ThreadMXBean/SynchronizationStatistics.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jdk/test/java/lang/management/ThreadMXBean/LockedMonitors.java b/jdk/test/java/lang/management/ThreadMXBean/LockedMonitors.java index 5c9747eaf9e..a693d71a841 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/LockedMonitors.java +++ b/jdk/test/java/lang/management/ThreadMXBean/LockedMonitors.java @@ -37,7 +37,7 @@ * @build Barrier * @build LockingThread * @build ThreadDump - * @run main LockedMonitors + * @run main/othervm LockedMonitors */ import java.lang.management.*; diff --git a/jdk/test/java/lang/management/ThreadMXBean/LockedSynchronizers.java b/jdk/test/java/lang/management/ThreadMXBean/LockedSynchronizers.java index b732d43f311..0fc35325926 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/LockedSynchronizers.java +++ b/jdk/test/java/lang/management/ThreadMXBean/LockedSynchronizers.java @@ -33,7 +33,7 @@ * @build Barrier * @build SynchronizerLockingThread * @build ThreadDump - * @run main LockedSynchronizers + * @run main/othervm LockedSynchronizers */ import java.lang.management.*; diff --git a/jdk/test/java/lang/management/ThreadMXBean/MyOwnSynchronizer.java b/jdk/test/java/lang/management/ThreadMXBean/MyOwnSynchronizer.java index 3968a5aab6f..c102583ddbf 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/MyOwnSynchronizer.java +++ b/jdk/test/java/lang/management/ThreadMXBean/MyOwnSynchronizer.java @@ -30,7 +30,7 @@ * * @build Barrier * @build ThreadDump - * @run main MyOwnSynchronizer + * @run main/othervm MyOwnSynchronizer */ import java.lang.management.*; diff --git a/jdk/test/java/lang/management/ThreadMXBean/SharedSynchronizer.java b/jdk/test/java/lang/management/ThreadMXBean/SharedSynchronizer.java index 6f5065dda03..6fc9e9ee0e5 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/SharedSynchronizer.java +++ b/jdk/test/java/lang/management/ThreadMXBean/SharedSynchronizer.java @@ -28,7 +28,7 @@ * in shared mode which has no owner when a thread is parked. * @author Mandy Chung * - * @run main SharedSynchronizer + * @run main/othervm SharedSynchronizer */ diff --git a/jdk/test/java/lang/management/ThreadMXBean/SynchronizationStatistics.java b/jdk/test/java/lang/management/ThreadMXBean/SynchronizationStatistics.java index ae65ca924a2..e03042864c9 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/SynchronizationStatistics.java +++ b/jdk/test/java/lang/management/ThreadMXBean/SynchronizationStatistics.java @@ -30,7 +30,7 @@ * * @ignore 6309226 * @build Semaphore - * @run main SynchronizationStatistics + * @run main/othervm SynchronizationStatistics */ import java.lang.management.*; From c73d39394791f549f2fe191c844f131ae958143b Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Thu, 5 Sep 2013 16:38:04 +0400 Subject: [PATCH 0223/1294] 8012447: Java CTW implementation Reviewed-by: vlivanov, kvn, twisti --- hotspot/test/gc/TestVerifyDuringStartup.java | 2 +- .../java/testlibrary/JDKToolFinder.java | 53 ++-- hotspot/test/testlibrary/ctw/Makefile | 73 ++++++ hotspot/test/testlibrary/ctw/README | 93 +++++++ .../hotspot/tools/ctw/ClassPathDirEntry.java | 117 +++++++++ .../hotspot/tools/ctw/ClassPathJarEntry.java | 81 ++++++ .../tools/ctw/ClassPathJarInDirEntry.java | 62 +++++ .../hotspot/tools/ctw/ClassesListInFile.java | 61 +++++ .../hotspot/tools/ctw/CompileTheWorld.java | 175 +++++++++++++ .../src/sun/hotspot/tools/ctw/Compiler.java | 235 ++++++++++++++++++ .../sun/hotspot/tools/ctw/PathHandler.java | 149 +++++++++++ .../ctw/src/sun/hotspot/tools/ctw/Utils.java | 215 ++++++++++++++++ hotspot/test/testlibrary/ctw/test/Bar.java | 5 + .../testlibrary/ctw/test/ClassesDirTest.java | 61 +++++ .../testlibrary/ctw/test/ClassesListTest.java | 58 +++++ .../test/testlibrary/ctw/test/CtwTest.java | 118 +++++++++ hotspot/test/testlibrary/ctw/test/Foo.java | 5 + .../test/testlibrary/ctw/test/JarDirTest.java | 75 ++++++ .../test/testlibrary/ctw/test/JarsTest.java | 65 +++++ hotspot/test/testlibrary/ctw/test/classes.lst | 4 + hotspot/test/testlibrary/whitebox/Makefile | 63 +++++ 21 files changed, 1752 insertions(+), 18 deletions(-) create mode 100644 hotspot/test/testlibrary/ctw/Makefile create mode 100644 hotspot/test/testlibrary/ctw/README create mode 100644 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java create mode 100644 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java create mode 100644 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java create mode 100644 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java create mode 100644 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java create mode 100644 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java create mode 100644 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java create mode 100644 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java create mode 100644 hotspot/test/testlibrary/ctw/test/Bar.java create mode 100644 hotspot/test/testlibrary/ctw/test/ClassesDirTest.java create mode 100644 hotspot/test/testlibrary/ctw/test/ClassesListTest.java create mode 100644 hotspot/test/testlibrary/ctw/test/CtwTest.java create mode 100644 hotspot/test/testlibrary/ctw/test/Foo.java create mode 100644 hotspot/test/testlibrary/ctw/test/JarDirTest.java create mode 100644 hotspot/test/testlibrary/ctw/test/JarsTest.java create mode 100644 hotspot/test/testlibrary/ctw/test/classes.lst create mode 100644 hotspot/test/testlibrary/whitebox/Makefile diff --git a/hotspot/test/gc/TestVerifyDuringStartup.java b/hotspot/test/gc/TestVerifyDuringStartup.java index f4ac347f80e..4ac32bf118e 100644 --- a/hotspot/test/gc/TestVerifyDuringStartup.java +++ b/hotspot/test/gc/TestVerifyDuringStartup.java @@ -48,7 +48,7 @@ public class TestVerifyDuringStartup { "-XX:+VerifyDuringStartup", "-version"}); - System.out.print("Testing:\n" + JDKToolFinder.getJDKTool("java")); + System.out.print("Testing:\n" + JDKToolFinder.getCurrentJDKTool("java")); for (int i = 0; i < vmOpts.size(); i += 1) { System.out.print(" " + vmOpts.get(i)); } diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java index 91ad6a8c8a9..a39abbd3626 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java @@ -27,24 +27,43 @@ import java.io.File; public final class JDKToolFinder { - private JDKToolFinder() { - } - - /** - * Returns the full path to an executable in jdk/bin based on System property - * test.jdk (set by jtreg test suite) - * - * @return Full path to an executable in jdk/bin - */ - public static String getJDKTool(String tool) { - String binPath = System.getProperty("test.jdk"); - if (binPath == null) { - throw new RuntimeException("System property 'test.jdk' not set. This property is normally set by jtreg. " - + "When running test separately, set this property using '-Dtest.jdk=/path/to/jdk'."); + private JDKToolFinder() { } - binPath += File.separatorChar + "bin" + File.separatorChar + tool; + /** + * Returns the full path to an executable in jdk/bin based on System + * property {@code compile.jdk} (set by jtreg test suite) + * + * @return Full path to an executable in jdk/bin + */ + public static String getJDKTool(String tool) { + String binPath = System.getProperty("compile.jdk"); + if (binPath == null) { + throw new RuntimeException("System property 'compile.jdk' not set. " + + "This property is normally set by jtreg. " + + "When running test separately, set this property using " + + "'-Dcompile.jdk=/path/to/jdk'."); + } + binPath += File.separatorChar + "bin" + File.separatorChar + tool; - return binPath; - } + return binPath; + } + /** + * Returns the full path to an executable in <current jdk>/bin based + * on System property {@code test.jdk} (set by jtreg test suite) + * + * @return Full path to an executable in jdk/bin + */ + public static String getCurrentJDKTool(String tool) { + String binPath = System.getProperty("test.jdk"); + if (binPath == null) { + throw new RuntimeException("System property 'test.jdk' not set. " + + "This property is normally set by jtreg. " + + "When running test separately, set this property using " + + "'-Dtest.jdk=/path/to/jdk'."); + } + binPath += File.separatorChar + "bin" + File.separatorChar + tool; + + return binPath; + } } diff --git a/hotspot/test/testlibrary/ctw/Makefile b/hotspot/test/testlibrary/ctw/Makefile new file mode 100644 index 00000000000..5bca7754c69 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/Makefile @@ -0,0 +1,73 @@ +# +# Copyright (c) 2013, 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. +# +# + +ifneq "x$(ALT_BOOTDIR)" "x" + BOOTDIR := $(ALT_BOOTDIR) +endif + +ifeq "x$(BOOTDIR)" "x" + JDK_HOME := $(shell dirname $(shell which java))/.. +else + JDK_HOME := $(BOOTDIR) +endif + +SRC_DIR = src +BUILD_DIR = build +OUTPUT_DIR = $(BUILD_DIR)/classes +WHITEBOX_DIR = ../whitebox + +JAVAC = $(JDK_HOME)/bin/javac +JAR = $(JDK_HOME)/bin/jar + +SRC_FILES = $(shell find $(SRC_DIR) -name '*.java') + +MAIN_CLASS = sun.hotspot.tools.ctw.CompileTheWorld + +.PHONY: clean cleantmp + +all: ctw.jar cleantmp + +clean: cleantmp + @rm -rf ctw.jar wb.jar + +cleantmp: + @rm -rf filelist manifest.mf + @rm -rf $(BUILD_DIR) + +ctw.jar: filelist wb.jar manifest.mf + @mkdir -p $(OUTPUT_DIR) + $(JAVAC) -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist + $(JAR) cfm ctw.jar manifest.mf -C $(OUTPUT_DIR) . + +wb.jar: + make -C ${WHITEBOX_DIR} wb.jar + cp ${WHITEBOX_DIR}/wb.jar ./ + make -C ${WHITEBOX_DIR} clean + +filelist: $(SRC_FILES) + @rm -f $@ + @echo $(SRC_FILES) > $@ + +manifest.mf: + @echo "Main-Class: ${MAIN_CLASS}" > manifest.mf diff --git a/hotspot/test/testlibrary/ctw/README b/hotspot/test/testlibrary/ctw/README new file mode 100644 index 00000000000..babb0816229 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/README @@ -0,0 +1,93 @@ +# +# Copyright (c) 2013, 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. +# +# + +DESCRIPTION + +This is replacement for CompileTheWorld (CTW) written on java. Its purpose is +to make possible the use of CTW in product builds. + +DEPENDENCES + +The tool depends on Whitebox API. Assumed, that the sources of whitebox are +located in '../whitebox' directory. + +BUILDING + +Simple way to build, just type 'make'. + +Makefile uses environment variables 'ALT_BOOTDIR', 'BOOTDIR' as root-dir of jdk +that will be used for compilation and creating jar. + +On successful building 'ctw.jar' will be created. + +RUNNING + +Since the tool uses WhiteBox API, options 'UnlockDiagnosticVMOptions' and +'WhiteBoxAPI' should be specified, and 'wb.jar' should be added to +boot-classpath: + $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar + +Arguments can be paths to '.jar, '.zip', '.lst' files or directories with +classes, that define which classes will be compiled: + - '.jar', '.zip' files and directories are interpreted like in classpath +(including '/*' syntax) + - '.lst' files -- files with class names (in java notation) to compile. +CTW will try to find these classes with default class loader, so they should +be located in classpath. + +Without arguments it would work as old version of CTW: all classes in +boot-classpath will be compiled, excluding classes in 'rt.jar' if 'rt.jar' isn't +first in boot-classpath. + +Due CTW's flags also are not available in product builds, the tool uses +properties with the same names: + - 'CompileTheWorldPreloadClasses' -- type:boolean, default:true, description: +Preload all classes used by a class before start loading + - 'CompileTheWorldStartAt' -- type:long, default:1, description: First class +to consider + - 'CompileTheWorldStopAt' -- type:long, default:Long.MAX_VALUE, description: +Last class to consider + +Also it uses additional properties: + - 'sun.hotspot.tools.ctw.verbose' -- type:boolean, default:false, +description: Verbose output, adds additional information about compilation + - 'sun.hotspot.tools.ctw.logfile' -- type:string, default:null, +description: Path to logfile, if it's null, cout will be used. + +EXAMPLES + +compile classes from 'rt.jar': + $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ${JAVA_HOME}/jre/lib/rt.jar + +compile classes from all '.jar' in './testjars' directory: + $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ./testjars/* + +compile classes from './build/classes' directory: + $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ./build/classes + +compile only java.lang.String, java.lang.Object classes: + $ echo java.lang.String > classes.lst + $ echo java.lang.Object >> classes.lst + $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar classes.lst + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java new file mode 100644 index 00000000000..3ee3526568d --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013, 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. + */ + +package sun.hotspot.tools.ctw; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Set; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.concurrent.Executor; + +import java.io.*; +import java.nio.file.*; +import java.nio.file.attribute.*; + +/** + * * Handler for dirs containing classes to compile. + * @author igor.ignatyev@oracle.com + */ +public class ClassPathDirEntry extends PathHandler { + + private final int rootLength = root.toString().length(); + + public ClassPathDirEntry(Path root, Executor executor) { + super(root, executor); + try { + URL url = root.toUri().toURL(); + setLoader(new URLClassLoader(new URL[]{url})); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + @Override + public void process() { + System.out.println("# dir: " + root); + if (!Files.exists(root)) { + return; + } + try { + Files.walkFileTree(root, EnumSet.of(FileVisitOption.FOLLOW_LINKS), + Integer.MAX_VALUE, new CompileFileVisitor()); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + private void processFile(Path file) { + if (Utils.isClassFile(file.toString())) { + processClass(pathToClassName(file)); + } + } + + private String pathToClassName(Path file) { + String fileString; + if (root == file) { + fileString = file.normalize().toString(); + } else { + fileString = file.normalize().toString().substring(rootLength + 1); + } + return Utils.fileNameToClassName(fileString); + } + + private class CompileFileVisitor extends SimpleFileVisitor { + + private final Set ready = new HashSet<>(); + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) throws IOException { + if (ready.contains(dir)) { + return FileVisitResult.SKIP_SUBTREE; + } + ready.add(dir); + return super.preVisitDirectory(dir, attrs); + } + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) throws IOException { + if (!ready.contains(file)) { + processFile(file); + } + return isFinished() ? FileVisitResult.TERMINATE + : FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, + IOException exc) throws IOException { + return FileVisitResult.CONTINUE; + } + } +} + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java new file mode 100644 index 00000000000..3d39f1b2573 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, 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. + */ + +package sun.hotspot.tools.ctw; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; +import java.util.jar.*; +import java.util.concurrent.Executor; + +import java.io.*; +import java.nio.file.*; + +/** + * Handler for jar-files containing classes to compile. + * @author igor.ignatyev@oracle.com + */ +public class ClassPathJarEntry extends PathHandler { + + public ClassPathJarEntry(Path root, Executor executor) { + super(root, executor); + try { + URL url = root.toUri().toURL(); + setLoader(new URLClassLoader(new URL[]{url})); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + @Override + public void process() { + System.out.println("# jar: " + root); + if (!Files.exists(root)) { + return; + } + try { + JarFile jarFile = new JarFile(root.toFile()); + JarEntry entry; + for (Enumeration e = jarFile.entries(); + e.hasMoreElements(); ) { + entry = e.nextElement(); + processJarEntry(entry); + if (isFinished()) { + return; + } + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + private void processJarEntry(JarEntry entry) { + String filename = entry.getName(); + if (Utils.isClassFile(filename)) { + processClass(Utils.fileNameToClassName(filename)); + } + } +} + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java new file mode 100644 index 00000000000..328280a2d88 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, 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. + */ + +package sun.hotspot.tools.ctw; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.Executor; + +/** + * Handler for dirs containing jar-files with classes to compile. + * + * @author igor.ignatyev@oracle.com + */ +public class ClassPathJarInDirEntry extends PathHandler { + + public ClassPathJarInDirEntry(Path root, Executor executor) { + super(root, executor); + } + + @Override + public void process() { + System.out.println("# jar_in_dir: " + root); + if (!Files.exists(root)) { + return; + } + try (DirectoryStream ds + = Files.newDirectoryStream(root, "*.jar")) { + for (Path p : ds) { + new ClassPathJarEntry(p, executor).process(); + if (isFinished()) { + return; + } + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } +} + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java new file mode 100644 index 00000000000..6f36d8b5c6d --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013, 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. + */ + +package sun.hotspot.tools.ctw; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.Executor; + +/** + * Handler for files containing a list of classes to compile. + * + * @author igor.ignatyev@oracle.com + */ +public class ClassesListInFile extends PathHandler { + public ClassesListInFile(Path root, Executor executor) { + super(root, executor); + } + + @Override + public void process() { + System.out.println("# list: " + root); + if (!Files.exists(root)) { + return; + } + try { + try (BufferedReader reader = Files.newBufferedReader(root, + StandardCharsets.UTF_8)) { + String line; + while (!isFinished() && ((line = reader.readLine()) != null)) { + processClass(line); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java new file mode 100644 index 00000000000..f1d46526d31 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2013, 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. + */ + +package sun.hotspot.tools.ctw; + +import sun.management.ManagementFactoryHelper; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; + +import java.util.List; +import java.util.concurrent.*; + +/** + * @author igor.ignatyev@oracle.com + */ +public class CompileTheWorld { + /** + * Entry point. Compiles classes in {@code args}, or all classes in + * boot-classpath if args is empty + * + * @param args paths to jar/zip, dir contains classes, or to .lst file + * contains list of classes to compile + */ + public static void main(String[] args) { + String logfile = Utils.LOG_FILE; + PrintStream os = null; + if (logfile != null) { + try { + os = new PrintStream(Files.newOutputStream(Paths.get(logfile))); + } catch (IOException io) { + } + } + if (os != null) { + System.setOut(os); + } + + try { + try { + if (ManagementFactoryHelper.getCompilationMXBean() == null) { + throw new RuntimeException( + "CTW can not work in interpreted mode"); + } + } catch (java.lang.NoClassDefFoundError e) { + // compact1, compact2 support + } + String[] paths = args; + boolean skipRtJar = false; + if (args.length == 0) { + paths = getDefaultPaths(); + skipRtJar = true; + } + ExecutorService executor = createExecutor(); + long start = System.currentTimeMillis(); + try { + String path; + for (int i = 0, n = paths.length; i < n + && !PathHandler.isFinished(); ++i) { + path = paths[i]; + if (skipRtJar && i > 0 && isRtJar(path)) { + // rt.jar is not first, so skip it + continue; + } + PathHandler.create(path, executor).process(); + } + } finally { + await(executor); + } + System.out.printf("Done (%d classes, %d methods, %d ms)%n", + Compiler.getClassCount(), + Compiler.getMethodCount(), + System.currentTimeMillis() - start); + } finally { + if (os != null) { + os.close(); + } + } + } + + private static ExecutorService createExecutor() { + final int threadsCount = Math.min( + Runtime.getRuntime().availableProcessors(), + Utils.CI_COMPILER_COUNT); + ExecutorService result; + if (threadsCount > 1) { + result = new ThreadPoolExecutor(threadsCount, threadsCount, + /* keepAliveTime */ 0L, TimeUnit.MILLISECONDS, + new ArrayBlockingQueue<>(threadsCount), + new ThreadPoolExecutor.CallerRunsPolicy()); + } else { + result = new CurrentThreadExecutor(); + } + return result; + } + + private static String[] getDefaultPaths() { + String property = System.getProperty("sun.boot.class.path"); + System.out.println( + "# use 'sun.boot.class.path' as args: " + property); + return Utils.PATH_SEPARATOR.split(property); + } + + private static void await(ExecutorService executor) { + executor.shutdown(); + while (!executor.isTerminated()) { + try { + executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + break; + } + } + } + + private static boolean isRtJar(String path) { + return Utils.endsWithIgnoreCase(path, File.separator + "rt.jar"); + } + + private static class CurrentThreadExecutor extends AbstractExecutorService { + private boolean isShutdown; + + @Override + public void shutdown() { + this.isShutdown = true; + } + + @Override + public List shutdownNow() { + return null; + } + + @Override + public boolean isShutdown() { + return isShutdown; + } + + @Override + public boolean isTerminated() { + return isShutdown; + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) + throws InterruptedException { + return isShutdown; + } + + @Override + public void execute(Runnable command) { + command.run(); + } + } +} + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java new file mode 100644 index 00000000000..ccb2d3ae53a --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2013, 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. + */ + +package sun.hotspot.tools.ctw; + +import sun.hotspot.WhiteBox; +import sun.misc.SharedSecrets; +import sun.reflect.ConstantPool; + +import java.lang.reflect.Executable; + +import java.util.Objects; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Provide method to compile whole class. + * Also contains compiled methods and classes counters. + * + * @author igor.ignatyev@oracle.com + */ +public class Compiler { + private Compiler() { } + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static final AtomicLong CLASS_COUNT = new AtomicLong(0L); + private static final AtomicLong METHOD_COUNT = new AtomicLong(0L); + private static volatile boolean CLASSES_LIMIT_REACHED = false; + + /** + * @return count of processed classes + */ + public static long getClassCount() { + return CLASS_COUNT.get(); + } + + /** + * @return count of processed methods + */ + public static long getMethodCount() { + return METHOD_COUNT.get(); + } + + /** + * @return {@code true} if classes limit is reached + */ + public static boolean isLimitReached() { + return CLASSES_LIMIT_REACHED; + } + + /** + * Compiles all methods and constructors. + * + * @param aClass class to compile + * @param executor executor used for compile task invocation + * @throws NullPointerException if {@code class} or {@code executor} + * is {@code null} + */ + public static void compileClass(Class aClass, Executor executor) { + Objects.requireNonNull(aClass); + Objects.requireNonNull(executor); + long id = CLASS_COUNT.incrementAndGet(); + if (id > Utils.COMPILE_THE_WORLD_STOP_AT) { + CLASS_COUNT.decrementAndGet(); + CLASSES_LIMIT_REACHED = true; + return; + } + + if (id >= Utils.COMPILE_THE_WORLD_START_AT) { + String name = aClass.getName(); + try { + System.out.printf("[%d]\t%s%n", id, name); + ConstantPool constantPool = SharedSecrets.getJavaLangAccess(). + getConstantPool(aClass); + if (Utils.COMPILE_THE_WORLD_PRELOAD_CLASSES) { + preloadClasses(name, id, constantPool); + } + long methodCount = 0; + for (Executable e : aClass.getDeclaredConstructors()) { + ++methodCount; + executor.execute(new CompileMethodCommand(id, name, e)); + } + for (Executable e : aClass.getDeclaredMethods()) { + ++methodCount; + executor.execute(new CompileMethodCommand(id, name, e)); + } + METHOD_COUNT.addAndGet(methodCount); + + if (Utils.DEOPTIMIZE_ALL_CLASSES_RATE > 0 + && (id % Utils.DEOPTIMIZE_ALL_CLASSES_RATE == 0)) { + WHITE_BOX.deoptimizeAll(); + } + } catch (Throwable t) { + System.out.printf("[%d]\t%s\tskipping %s%n", id, name, t); + t.printStackTrace(); + } + } + } + + private static void preloadClasses(String className, long id, + ConstantPool constantPool) { + try { + for (int i = 0, n = constantPool.getSize(); i < n; ++i) { + try { + constantPool.getClassAt(i); + } catch (IllegalArgumentException ignore) { + } + } + } catch (Throwable t) { + System.out.printf("[%d]\t%s\tpreloading failed : %s%n", id, + className, t); + } + } + + + + /** + * Compilation of method. + * Will compile method on all available comp levels. + */ + private static class CompileMethodCommand implements Runnable { + private final long classId; + private final String className; + private final Executable method; + + /** + * @param classId id of class + * @param className name of class + * @param method compiled for compilation + */ + public CompileMethodCommand(long classId, String className, + Executable method) { + this.classId = classId; + this.className = className; + this.method = method; + } + + @Override + public final void run() { + int compLevel = Utils.INITIAL_COMP_LEVEL; + if (Utils.TIERED_COMPILATION) { + for (int i = compLevel; i <= Utils.TIERED_STOP_AT_LEVEL; ++i) { + WHITE_BOX.deoptimizeMethod(method); + compileMethod(method, i); + } + } else { + compileMethod(method, compLevel); + } + } + + private void waitCompilation() { + if (!Utils.BACKGROUND_COMPILATION) { + return; + } + final Object obj = new Object(); + synchronized (obj) { + for (int i = 0; + i < 10 && WHITE_BOX.isMethodQueuedForCompilation(method); + ++i) { + try { + obj.wait(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } + } + + private void compileMethod(Executable method, int compLevel) { + if (WHITE_BOX.isMethodCompilable(method, compLevel)) { + try { + WHITE_BOX.enqueueMethodForCompilation(method, compLevel); + waitCompilation(); + int tmp = WHITE_BOX.getMethodCompilationLevel(method); + if (tmp != compLevel) { + logMethod(method, "compilation level = " + tmp + + ", but not " + compLevel); + } else if (Utils.IS_VERBOSE) { + logMethod(method, "compilation level = " + tmp + ". OK"); + } + } catch (Throwable t) { + logMethod(method, "error on compile at " + compLevel + + " level"); + t.printStackTrace(); + } + } else if (Utils.IS_VERBOSE) { + logMethod(method, "not compilable at " + compLevel); + } + } + + private void logMethod(Executable method, String message) { + StringBuilder builder = new StringBuilder("["); + builder.append(classId); + builder.append("]\t"); + builder.append(className); + builder.append("::"); + builder.append(method.getName()); + builder.append('('); + Class[] params = method.getParameterTypes(); + for (int i = 0, n = params.length - 1; i < n; ++i) { + builder.append(params[i].getName()); + builder.append(", "); + } + if (params.length != 0) { + builder.append(params[params.length - 1].getName()); + } + builder.append(')'); + if (message != null) { + builder.append('\t'); + builder.append(message); + } + System.err.println(builder); + } + } + +} diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java new file mode 100644 index 00000000000..5c284f896a8 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013, 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. + */ + +package sun.hotspot.tools.ctw; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.io.File; + +import java.util.Objects; +import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.util.concurrent.Executor; + +/** + * Abstract handler for path. + *

    + * Concrete subclasses should implement method {@link #process()}. + * + * @author igor.ignatyev@oracle.com + */ +public abstract class PathHandler { + private static final Pattern JAR_IN_DIR_PATTERN + = Pattern.compile("^(.*[/\\\\])?\\*$"); + protected final Path root; + protected final Executor executor; + private ClassLoader loader; + + /** + * @param root root path to process + * @param executor executor used for process task invocation + * @throws NullPointerException if {@code root} or {@code executor} is + * {@code null} + */ + protected PathHandler(Path root, Executor executor) { + Objects.requireNonNull(root); + Objects.requireNonNull(executor); + this.root = root.normalize(); + this.executor = executor; + this.loader = ClassLoader.getSystemClassLoader(); + } + + /** + * Factory method. Construct concrete handler in depends from {@code path}. + * + * @param path the path to process + * @param executor executor used for compile task invocation + * @throws NullPointerException if {@code path} or {@code executor} is + * {@code null} + */ + public static PathHandler create(String path, Executor executor) { + Objects.requireNonNull(path); + Objects.requireNonNull(executor); + Matcher matcher = JAR_IN_DIR_PATTERN.matcher(path); + if (matcher.matches()) { + path = matcher.group(1); + path = path.isEmpty() ? "." : path; + return new ClassPathJarInDirEntry(Paths.get(path), executor); + } else { + path = path.isEmpty() ? "." : path; + Path p = Paths.get(path); + if (isJarFile(p)) { + return new ClassPathJarEntry(p, executor); + } else if (isListFile(p)) { + return new ClassesListInFile(p, executor); + } else { + return new ClassPathDirEntry(p, executor); + } + } + } + + private static boolean isJarFile(Path path) { + if (Files.isRegularFile(path)) { + String name = path.toString(); + return Utils.endsWithIgnoreCase(name, ".zip") + || Utils.endsWithIgnoreCase(name, ".jar"); + } + return false; + } + + private static boolean isListFile(Path path) { + if (Files.isRegularFile(path)) { + String name = path.toString(); + return Utils.endsWithIgnoreCase(name, ".lst"); + } + return false; + } + + /** + * Processes all classes in specified path. + */ + public abstract void process(); + + /** + * Sets class loader, that will be used to define class at + * {@link #processClass(String)}. + * + * @param loader class loader + * @throws NullPointerException if {@code loader} is {@code null} + */ + protected final void setLoader(ClassLoader loader) { + Objects.requireNonNull(loader); + this.loader = loader; + } + + /** + * Processes specificed class. + * @param name fully qualified name of class to process + */ + protected final void processClass(String name) { + try { + Class aClass = Class.forName(name, true, loader); + Compiler.compileClass(aClass, executor); + } catch (ClassNotFoundException | LinkageError e) { + System.out.printf("Class %s loading failed : %s%n", name, + e.getMessage()); + } + } + + /** + * @return {@code true} if processing should be stopped + */ + public static boolean isFinished() { + return Compiler.isLimitReached(); + } + +} + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java new file mode 100644 index 00000000000..5ffd06cee8b --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2013, 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. + */ + +package sun.hotspot.tools.ctw; + +import com.sun.management.HotSpotDiagnosticMXBean; +import sun.management.ManagementFactoryHelper; + +import java.io.File; +import java.util.regex.Pattern; + +/** + * Auxiliary methods. + * + * @author igor.ignatyev@oracle.com + */ +public class Utils { + /** + * Value of {@code -XX:CompileThreshold} + */ + public static final boolean TIERED_COMPILATION + = Boolean.parseBoolean(getVMOption("TieredCompilation", "false")); + /** + * Value of {@code -XX:BackgroundCompilation} + */ + public static final boolean BACKGROUND_COMPILATION + = Boolean.parseBoolean(getVMOption("BackgroundCompilation", + "false")); + /** + * Value of {@code -XX:TieredStopAtLevel} + */ + public static final int TIERED_STOP_AT_LEVEL; + /** + * Value of {@code -XX:CICompilerCount} + */ + public static final Integer CI_COMPILER_COUNT + = Integer.valueOf(getVMOption("CICompilerCount", "1")); + /** + * Initial compilation level. + */ + public static final int INITIAL_COMP_LEVEL; + /** + * Compiled path-separator regexp. + */ + public static final Pattern PATH_SEPARATOR = Pattern.compile( + File.pathSeparator, Pattern.LITERAL); + /** + * Value of {@code -DDeoptimizeAllClassesRate}. Frequency of + * {@code WB.deoptimizeAll()} invocation If it less that {@code 0}, + * {@code WB.deoptimizeAll()} will not be invoked. + */ + public static final int DEOPTIMIZE_ALL_CLASSES_RATE + = Integer.getInteger("DeoptimizeAllClassesRate", -1); + /** + * Value of {@code -DCompileTheWorldStopAt}. Last class to consider. + */ + public static final long COMPILE_THE_WORLD_STOP_AT + = Long.getLong("CompileTheWorldStopAt", Long.MAX_VALUE); + /** + * Value of {@code -DCompileTheWorldStartAt}. First class to consider. + */ + public static final long COMPILE_THE_WORLD_START_AT + = Long.getLong("CompileTheWorldStartAt", 1); + /** + * Value of {@code -DCompileTheWorldPreloadClasses}. Preload all classes + * used by a class before start loading. + */ + public static final boolean COMPILE_THE_WORLD_PRELOAD_CLASSES; + /** + * Value of {@code -Dsun.hotspot.tools.ctw.verbose}. Verbose output, + * adds additional information about compilation. + */ + public static final boolean IS_VERBOSE + = Boolean.getBoolean("sun.hotspot.tools.ctw.verbose"); + /** + * Value of {@code -Dsun.hotspot.tools.ctw.logfile}.Path to logfile, if + * it's null, cout will be used. + */ + public static final String LOG_FILE + = System.getProperty("sun.hotspot.tools.ctw.logfile"); + static { + if (Utils.TIERED_COMPILATION) { + INITIAL_COMP_LEVEL = 1; + } else { + String vmName = System.getProperty("java.vm.name"); + if (Utils.endsWithIgnoreCase(vmName, " Server VM")) { + INITIAL_COMP_LEVEL = 4; + } else if (Utils.endsWithIgnoreCase(vmName, " Client VM") + || Utils.endsWithIgnoreCase(vmName, " Minimal VM")) { + INITIAL_COMP_LEVEL = 1; + } else { + throw new RuntimeException("Unknown VM: " + vmName); + } + } + + TIERED_STOP_AT_LEVEL = Integer.parseInt(getVMOption("TieredStopAtLevel", + String.valueOf(INITIAL_COMP_LEVEL))); + } + + static { + String tmp = System.getProperty("CompileTheWorldPreloadClasses"); + if (tmp == null) { + COMPILE_THE_WORLD_PRELOAD_CLASSES = true; + } else { + COMPILE_THE_WORLD_PRELOAD_CLASSES = Boolean.parseBoolean(tmp); + } + } + + public static final String CLASSFILE_EXT = ".class"; + + private Utils() { + } + + /** + * Tests if the string ends with the suffix, ignoring case + * considerations + * + * @param string the tested string + * @param suffix the suffix + * @return {@code true} if {@code string} ends with the {@code suffix} + * @see String#endsWith(String) + */ + public static boolean endsWithIgnoreCase(String string, String suffix) { + if (string == null || suffix == null) { + return false; + } + int length = suffix.length(); + int toffset = string.length() - length; + if (toffset < 0) { + return false; + } + return string.regionMatches(true, toffset, suffix, 0, length); + } + + /** + * Returns value of VM option. + * + * @param name option's name + * @return value of option or {@code null}, if option doesn't exist + * @throws NullPointerException if name is null + */ + public static String getVMOption(String name) { + String result; + HotSpotDiagnosticMXBean diagnostic + = ManagementFactoryHelper.getDiagnosticMXBean(); + result = diagnostic.getVMOption(name).getValue(); + return result; + } + + /** + * Returns value of VM option or default value. + * + * @param name option's name + * @param defaultValue default value + * @return value of option or {@code defaultValue}, if option doesn't exist + * @throws NullPointerException if name is null + * @see #getVMOption(String) + */ + public static String getVMOption(String name, String defaultValue) { + String result; + try { + result = getVMOption(name); + } catch (NoClassDefFoundError e) { + // compact1, compact2 support + result = defaultValue; + } + return result == null ? defaultValue : result; + } + + /** + * Tests if the filename is valid filename for class file. + * + * @param filename tested filename + */ + public static boolean isClassFile(String filename) { + // If the filename has a period after removing '.class', it's not valid class file + return endsWithIgnoreCase(filename, CLASSFILE_EXT) + && (filename.indexOf('.') + == (filename.length() - CLASSFILE_EXT.length())); + } + + /** + * Converts the filename to classname. + * + * @param filename filename to convert + * @return corresponding classname. + * @throws AssertionError if filename isn't valid filename for class file - + * {@link #isClassFile(String)} + */ + public static String fileNameToClassName(String filename) { + assert isClassFile(filename); + return filename.substring(0, filename.length() - CLASSFILE_EXT.length()) + .replace(File.separatorChar, '.'); + } +} diff --git a/hotspot/test/testlibrary/ctw/test/Bar.java b/hotspot/test/testlibrary/ctw/test/Bar.java new file mode 100644 index 00000000000..9b0324555f8 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/Bar.java @@ -0,0 +1,5 @@ +public class Bar { + private static void staticMethod() { } + public void method() { } + protected Bar() { } +} diff --git a/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java b/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java new file mode 100644 index 00000000000..ae5eaf0f2e4 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013, 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 ClassesDirTest + * @bug 8012447 + * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox ClassesDirTest Foo Bar + * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar + * @run main ClassesDirTest prepare + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes + * @run main ClassesDirTest check ctw.log + * @summary testing of CompileTheWorld :: classes in directory + * @author igor.ignatyev@oracle.com + */ + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + +public class ClassesDirTest extends CtwTest { + private static final String[] SHOULD_CONTAIN + = {"# dir: classes", "Done (2 classes, 6 methods, "}; + + private ClassesDirTest() { + super(SHOULD_CONTAIN); + } + + public static void main(String[] args) throws Exception { + new ClassesDirTest().run(args); + } + + protected void prepare() throws Exception { + String path = "classes"; + Files.createDirectory(Paths.get(path)); + Files.move(Paths.get("Foo.class"), Paths.get(path, "Foo.class"), + StandardCopyOption.REPLACE_EXISTING); + Files.move(Paths.get("Bar.class"), Paths.get(path, "Bar.class"), + StandardCopyOption.REPLACE_EXISTING); + } +} diff --git a/hotspot/test/testlibrary/ctw/test/ClassesListTest.java b/hotspot/test/testlibrary/ctw/test/ClassesListTest.java new file mode 100644 index 00000000000..a98cd53a3f6 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/ClassesListTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013, 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 ClassesListTest + * @bug 8012447 + * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox ClassesListTest Foo Bar + * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar + * @run main ClassesListTest prepare + * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes.lst + * @run main ClassesListTest check ctw.log + * @summary testing of CompileTheWorld :: list of classes in file + * @author igor.ignatyev@oracle.com + */ + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + +public class ClassesListTest extends CtwTest { + private static final String[] SHOULD_CONTAIN + = {"# list: classes.lst", "Done (4 classes, "}; + + private ClassesListTest() { + super(SHOULD_CONTAIN); + } + + public static void main(String[] args) throws Exception { + new ClassesListTest().run(args); + } + + protected void prepare() throws Exception { + String path = "classes.lst"; + Files.copy(Paths.get(System.getProperty("test.src"), path), + Paths.get(path), StandardCopyOption.REPLACE_EXISTING); + } +} diff --git a/hotspot/test/testlibrary/ctw/test/CtwTest.java b/hotspot/test/testlibrary/ctw/test/CtwTest.java new file mode 100644 index 00000000000..ecc9c59c13a --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/CtwTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.List; +import java.util.Collections; +import java.util.ArrayList; + +import java.io.File; +import java.io.Writer; +import java.io.FileWriter; +import java.io.IOException; +import java.io.BufferedReader; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.nio.charset.Charset; + +import com.oracle.java.testlibrary.JDKToolFinder; +import com.oracle.java.testlibrary.OutputAnalyzer; + +public abstract class CtwTest { + protected final String[] shouldContain; + protected CtwTest(String[] shouldContain) { + this.shouldContain = shouldContain; + } + + public void run(String[] args) throws Exception { + if (args.length == 0) { + throw new Error("args is empty"); + } + switch (args[0]) { + case "prepare": + prepare(); + break; + case "check": + check(args); + break; + default: + throw new Error("unregonized action -- " + args[0]); + } + } + + protected void prepare() throws Exception { } + + protected void check(String[] args) throws Exception { + if (args.length < 2) { + throw new Error("logfile isn't specified"); + } + String logfile = args[1]; + try (BufferedReader r = Files.newBufferedReader(Paths.get(logfile), + Charset.defaultCharset())) { + OutputAnalyzer output = readOutput(r); + for (String test : shouldContain) { + output.shouldContain(test); + } + } + } + + private static OutputAnalyzer readOutput(BufferedReader reader) + throws IOException { + StringBuilder builder = new StringBuilder(); + String eol = String.format("%n"); + String line; + + while ((line = reader.readLine()) != null) { + builder.append(line); + builder.append(eol); + } + return new OutputAnalyzer(builder.toString(), ""); + } + + protected void dump(OutputAnalyzer output, String name) { + try (Writer w = new FileWriter(name + ".out")) { + String s = output.getStdout(); + w.write(s, s.length(), 0); + } catch (IOException io) { + io.printStackTrace(); + } + try (Writer w = new FileWriter(name + ".err")) { + String s = output.getStderr(); + w.write(s, s.length(), 0); + } catch (IOException io) { + io.printStackTrace(); + } + } + + protected ProcessBuilder createJarProcessBuilder(String... command) + throws Exception { + String javapath = JDKToolFinder.getJDKTool("jar"); + + ArrayList args = new ArrayList<>(); + args.add(javapath); + Collections.addAll(args, command); + + return new ProcessBuilder(args.toArray(new String[args.size()])); + } +} diff --git a/hotspot/test/testlibrary/ctw/test/Foo.java b/hotspot/test/testlibrary/ctw/test/Foo.java new file mode 100644 index 00000000000..07d8f4643ce --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/Foo.java @@ -0,0 +1,5 @@ +public class Foo { + private static void staticMethod() { } + public void method() { } + protected Foo() { } +} diff --git a/hotspot/test/testlibrary/ctw/test/JarDirTest.java b/hotspot/test/testlibrary/ctw/test/JarDirTest.java new file mode 100644 index 00000000000..76f682fd755 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/JarDirTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013, 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 JarDirTest + * @bug 8012447 + * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox JarDirTest Foo Bar + * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar + * @run main JarDirTest prepare + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld jars/* + * @run main JarDirTest check ctw.log + * @summary testing of CompileTheWorld :: jars in directory + * @author igor.ignatyev@oracle.com + */ + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; + +import com.oracle.java.testlibrary.OutputAnalyzer; + +public class JarDirTest extends CtwTest { + private static final String[] SHOULD_CONTAIN + = {"# jar_in_dir: jars", + "# jar: jars" + File.separator +"foo.jar", + "# jar: jars" + File.separator +"bar.jar", + "Done (4 classes, 12 methods, "}; + + private JarDirTest() { + super(SHOULD_CONTAIN); + } + + public static void main(String[] args) throws Exception { + new JarDirTest().run(args); + } + + protected void prepare() throws Exception { + String path = "jars"; + Files.createDirectory(Paths.get(path)); + + ProcessBuilder pb = createJarProcessBuilder("cf", "jars/foo.jar", + "Foo.class", "Bar.class"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + dump(output, "ctw-foo.jar"); + output.shouldHaveExitValue(0); + + pb = createJarProcessBuilder("cf", "jars/bar.jar", "Foo.class", + "Bar.class"); + output = new OutputAnalyzer(pb.start()); + dump(output, "ctw-bar.jar"); + output.shouldHaveExitValue(0); + } + +} diff --git a/hotspot/test/testlibrary/ctw/test/JarsTest.java b/hotspot/test/testlibrary/ctw/test/JarsTest.java new file mode 100644 index 00000000000..04792729f4e --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/JarsTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013, 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 JarsTest + * @bug 8012447 + * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox JarsTest Foo Bar + * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar + * @run main JarsTest prepare + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld foo.jar bar.jar + * @run main JarsTest check ctw.log + * @summary testing of CompileTheWorld :: jars + * @author igor.ignatyev@oracle.com + */ + +import com.oracle.java.testlibrary.OutputAnalyzer; + +public class JarsTest extends CtwTest { + private static final String[] SHOULD_CONTAIN + = {"# jar: foo.jar", "# jar: bar.jar", + "Done (4 classes, 12 methods, "}; + + private JarsTest() { + super(SHOULD_CONTAIN); + } + + public static void main(String[] args) throws Exception { + new JarsTest().run(args); + } + + protected void prepare() throws Exception { + ProcessBuilder pb = createJarProcessBuilder("cf", "foo.jar", + "Foo.class", "Bar.class"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + dump(output, "ctw-foo.jar"); + output.shouldHaveExitValue(0); + + pb = createJarProcessBuilder("cf", "bar.jar", "Foo.class", "Bar.class"); + output = new OutputAnalyzer(pb.start()); + dump(output, "ctw-bar.jar"); + output.shouldHaveExitValue(0); + } + +} diff --git a/hotspot/test/testlibrary/ctw/test/classes.lst b/hotspot/test/testlibrary/ctw/test/classes.lst new file mode 100644 index 00000000000..044c029e783 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/classes.lst @@ -0,0 +1,4 @@ +java.lang.String +java.lang.Object +Foo +Bar diff --git a/hotspot/test/testlibrary/whitebox/Makefile b/hotspot/test/testlibrary/whitebox/Makefile new file mode 100644 index 00000000000..8a84a0a4492 --- /dev/null +++ b/hotspot/test/testlibrary/whitebox/Makefile @@ -0,0 +1,63 @@ +# +# Copyright (c) 2013, 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. +# +# + +ifneq "x$(ALT_BOOTDIR)" "x" + BOOTDIR := $(ALT_BOOTDIR) +endif + +ifeq "x$(BOOTDIR)" "x" + JDK_HOME := $(shell dirname $(shell which java))/.. +else + JDK_HOME := $(BOOTDIR) +endif + +SRC_DIR = ./ +BUILD_DIR = build +OUTPUT_DIR = $(BUILD_DIR)/classes + +JAVAC = $(JDK_HOME)/bin/javac +JAR = $(JDK_HOME)/bin/jar + +SRC_FILES = $(shell find $(SRC_DIR) -name '*.java') + +.PHONY: filelist clean cleantmp + +all: wb.jar cleantmp + +wb.jar: filelist + @mkdir -p $(OUTPUT_DIR) + $(JAVAC) -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp $(OUTPUT_DIR) @filelist + $(JAR) cf wb.jar -C $(OUTPUT_DIR) . + @rm -rf $(OUTPUT_DIR) + +filelist: $(SRC_FILES) + @rm -f $@ + @echo $(SRC_FILES) > $@ + +clean: cleantmp + @rm -rf wb.jar + +cleantmp: + @rm -rf filelist + @rm -rf $(BUILD_DIR) From 6311d280324a8c0bf04b754eafb7da070c4f9565 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 5 Sep 2013 21:17:06 +0530 Subject: [PATCH 0224/1294] 8024255: When a keyword is used as object property name, the property can not be deleted Reviewed-by: jlaskey, lagergren --- .../jdk/nashorn/internal/parser/Parser.java | 2 +- nashorn/test/script/basic/JDK-8024255.js | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8024255.js diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index ab008900f50..ea01f5984ed 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -2060,7 +2060,7 @@ loop: case FLOATING: return getLiteral(); default: - return getIdentifierName(); + return getIdentifierName().setIsPropertyName(); } } diff --git a/nashorn/test/script/basic/JDK-8024255.js b/nashorn/test/script/basic/JDK-8024255.js new file mode 100644 index 00000000000..54022a5cd1d --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024255.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024255: When a keyword is used as object property name, the property can not be deleted + * + * @test + * @run + */ + +function check(obj, name) { + var desc = Object.getOwnPropertyDescriptor(obj, name); + if (! desc.configurable) { + fail("Property " + name + " is not configurable"); + } + + if (! (delete obj[name])) { + fail("Property " + name + " can not be deleted"); + } +} + +var obj = { + default: 344, + in: 'hello', + if: false, + class: 4.223 +} + +for (var p in obj) { + check(obj, p); +} From b1127783de054ea3c5ee6b719aa8aa9fe739003c Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Thu, 5 Sep 2013 10:14:53 -0700 Subject: [PATCH 0225/1294] 8023943: Method description fix for String.toLower/UpperCase() methods Reviewed-by: okutsu --- jdk/src/share/classes/java/lang/String.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/lang/String.java b/jdk/src/share/classes/java/lang/String.java index e9d75afbbce..2231aa3bb71 100644 --- a/jdk/src/share/classes/java/lang/String.java +++ b/jdk/src/share/classes/java/lang/String.java @@ -2652,7 +2652,7 @@ public final class String * returns {@code "t\u005Cu0131tle"}, where '\u005Cu0131' is the * LATIN SMALL LETTER DOTLESS I character. * To obtain correct results for locale insensitive strings, use - * {@code toLowerCase(Locale.ENGLISH)}. + * {@code toLowerCase(Locale.ROOT)}. *

    * @return the {@code String}, converted to lowercase. * @see java.lang.String#toLowerCase(Locale) @@ -2815,7 +2815,7 @@ public final class String * returns {@code "T\u005Cu0130TLE"}, where '\u005Cu0130' is the * LATIN CAPITAL LETTER I WITH DOT ABOVE character. * To obtain correct results for locale insensitive strings, use - * {@code toUpperCase(Locale.ENGLISH)}. + * {@code toUpperCase(Locale.ROOT)}. *

    * @return the {@code String}, converted to uppercase. * @see java.lang.String#toUpperCase(Locale) From a277d40ead556c15e1869475da44cb00cd1ccf78 Mon Sep 17 00:00:00 2001 From: Vlaidmir Ivanov Date: Thu, 5 Sep 2013 14:58:49 -0700 Subject: [PATCH 0226/1294] 8024283: 10 nashorn tests fail with similar stack trace InternalError with cause being NoClassDefFoundError Fix pre-existing 292 bug tickled by combo of nashorn code and MethodHandleInfo changes Reviewed-by: jrose --- .../classes/java/lang/invoke/InvokerBytecodeGenerator.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 3ddf5d4c1c5..6228c07b7b0 100644 --- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -612,6 +612,12 @@ class InvokerBytecodeGenerator { return false; // inner class of some sort if (cls.getClassLoader() != MethodHandle.class.getClassLoader()) return false; // not on BCP + MethodType mtype = member.getMethodOrFieldType(); + if (!isStaticallyNameable(mtype.returnType())) + return false; + for (Class ptype : mtype.parameterArray()) + if (!isStaticallyNameable(ptype)) + return false; if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls)) return true; // in java.lang.invoke package if (member.isPublic() && isStaticallyNameable(cls)) From 9c6d420370b76c367d9abf96cedaa54123d513e2 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Thu, 5 Sep 2013 16:35:47 -0700 Subject: [PATCH 0227/1294] 8023608: method grouping tabs folding issue Reviewed-by: jjg --- .../internal/toolkit/resources/stylesheet.css | 12 ++---- .../testStylesheet/TestStylesheet.java | 43 ++++++++++++++++++- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css index c264d66b303..bf1bc9441de 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css @@ -378,7 +378,6 @@ Table styles overflow:hidden; padding:0px; margin:0px; - white-space:pre; } caption a:link, caption a:hover, caption a:active, caption a:visited { color:#FFFFFF; @@ -387,35 +386,32 @@ caption a:link, caption a:hover, caption a:active, caption a:visited { white-space:nowrap; padding-top:8px; padding-left:8px; - display:block; + display:inline-block; float:left; background-image:url(resources/titlebar.gif); - height:18px; } .contentContainer ul.blockList li.blockList caption span.activeTableTab span { white-space:nowrap; padding-top:8px; padding-left:8px; - display:block; + display:inline-block; float:left; background-image:url(resources/activetitlebar.gif); - height:18px; } .contentContainer ul.blockList li.blockList caption span.tableTab span { white-space:nowrap; padding-top:8px; padding-left:8px; - display:block; + display:inline-block; float:left; background-image:url(resources/titlebar.gif); - height:18px; } .contentContainer ul.blockList li.blockList caption span.tableTab, .contentContainer ul.blockList li.blockList caption span.activeTableTab { padding-top:0px; padding-left:0px; background-image:none; float:none; - display:inline; + display:inline-block; } .overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { width:10px; diff --git a/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java b/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java index c4044a53d91..b6192fb8959 100644 --- a/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java +++ b/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4494033 7028815 7052425 8007338 + * @bug 4494033 7028815 7052425 8007338 8023608 * @summary Run tests on doclet stylesheet. * @author jamieh * @library ../lib/ @@ -72,7 +72,46 @@ public class TestStylesheet extends JavadocTester { " overflow:hidden;" + NL + " padding:0px;" + NL + " margin:0px;" + NL + - " white-space:pre;" + NL + + "}"}, + {BUG_ID + FS + "stylesheet.css", + ".overviewSummary caption span, .packageSummary caption span, " + + ".contentContainer ul.blockList li.blockList caption span, " + + ".summary caption span, .classUseContainer caption span, " + + ".constantValuesContainer caption span {" + NL + + " white-space:nowrap;" + NL + + " padding-top:8px;" + NL + + " padding-left:8px;" + NL + + " display:inline-block;" + NL + + " float:left;" + NL + + " background-image:url(resources/titlebar.gif);" + NL + + "}"}, + {BUG_ID + FS + "stylesheet.css", + ".contentContainer ul.blockList li.blockList caption " + + "span.activeTableTab span {" + NL + + " white-space:nowrap;" + NL + + " padding-top:8px;" + NL + + " padding-left:8px;" + NL + + " display:inline-block;" + NL + + " float:left;" + NL + + " background-image:url(resources/activetitlebar.gif);" + NL + + "}"}, + {BUG_ID + FS + "stylesheet.css", + ".contentContainer ul.blockList li.blockList caption span.tableTab span {" + NL + + " white-space:nowrap;" + NL + + " padding-top:8px;" + NL + + " padding-left:8px;" + NL + + " display:inline-block;" + NL + + " float:left;" + NL + + " background-image:url(resources/titlebar.gif);" + NL + + "}"}, + {BUG_ID + FS + "stylesheet.css", + ".contentContainer ul.blockList li.blockList caption span.tableTab, " + + ".contentContainer ul.blockList li.blockList caption span.activeTableTab {" + NL + + " padding-top:0px;" + NL + + " padding-left:0px;" + NL + + " background-image:none;" + NL + + " float:none;" + NL + + " display:inline-block;" + NL + "}"}, // Test whether a link to the stylesheet file is inserted properly // in the class documentation. From 37709e319182570f4f11fca0726a1d530ee7aba8 Mon Sep 17 00:00:00 2001 From: John Rose Date: Fri, 6 Sep 2013 00:43:00 -0700 Subject: [PATCH 0228/1294] 8024260: 10 closed/java/lang/invoke/* tests failing after overhaul to MethodHandleInfo Reviewed-by: vlivanov, briangoetz --- .../share/classes/java/lang/invoke/MethodHandle.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java index 408cbd08abc..613d223fe2a 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java @@ -1286,7 +1286,17 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); /*non-public*/ MethodHandle withInternalMemberName(MemberName member) { - return MethodHandleImpl.makeWrappedMember(this, member); + if (member != null) { + return MethodHandleImpl.makeWrappedMember(this, member); + } else if (internalMemberName() == null) { + // The required internaMemberName is null, and this MH (like most) doesn't have one. + return this; + } else { + // The following case is rare. Mask the internalMemberName by wrapping the MH in a BMH. + MethodHandle result = rebind(); + assert (result.internalMemberName() == null); + return result; + } } /*non-public*/ From 61000f0c4b9dda6152dc37e0f49fd5bceb8eb530 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Fri, 6 Sep 2013 10:03:16 +0200 Subject: [PATCH 0229/1294] 6815130: Intermittent ThreadMXBean/Locks.java test failure Preventing stale reads from ThreadExecutionSynchronizer.waiting flag Reviewed-by: dholmes, mchung, dfuchs --- .../lang/management/ThreadMXBean/Locks.java | 23 +++++++++---------- .../ThreadExecutionSynchronizer.java | 6 ++--- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/jdk/test/java/lang/management/ThreadMXBean/Locks.java b/jdk/test/java/lang/management/ThreadMXBean/Locks.java index 5969aebc6d0..c078dccd62d 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/Locks.java +++ b/jdk/test/java/lang/management/ThreadMXBean/Locks.java @@ -193,16 +193,18 @@ public class Locks { public CheckerThread() { super("CheckerThread"); } + + private void waitForState(Thread.State state) { + thrsync.waitForSignal(); + while (waiter.getState() != state) { + goSleep(10); + } + } + public void run() { synchronized (ready) { // wait until WaitingThread about to wait for objC - thrsync.waitForSignal(); - - int retryCount = 0; - while (waiter.getState() != Thread.State.WAITING - && retryCount++ < 500) { - goSleep(100); - } + waitForState(Thread.State.WAITING); checkBlockedObject(waiter, objC, null, Thread.State.WAITING); synchronized (objC) { @@ -211,16 +213,13 @@ public class Locks { // wait for waiter thread to about to enter // synchronized object ready. - thrsync.waitForSignal(); - // give chance for waiter thread to get blocked on - // object ready. - goSleep(50); + waitForState(Thread.State.BLOCKED); checkBlockedObject(waiter, ready, this, Thread.State.BLOCKED); } // wait for signal from waiting thread that it is about // wait for objC. - thrsync.waitForSignal(); + waitForState(Thread.State.WAITING); synchronized(objC) { checkBlockedObject(waiter, objC, Thread.currentThread(), Thread.State.WAITING); objC.notify(); diff --git a/jdk/test/java/lang/management/ThreadMXBean/ThreadExecutionSynchronizer.java b/jdk/test/java/lang/management/ThreadMXBean/ThreadExecutionSynchronizer.java index dc887829bdf..6cba7e73521 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/ThreadExecutionSynchronizer.java +++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadExecutionSynchronizer.java @@ -23,7 +23,7 @@ /* * - * @summary Thiseclass is used to synchronize execution off two threads. + * @summary This class is used to synchronize execution of two threads. * @author Swamy Venkataramanappa */ @@ -31,8 +31,8 @@ import java.util.concurrent.Semaphore; public class ThreadExecutionSynchronizer { - private boolean waiting; - private Semaphore semaphore; + private volatile boolean waiting; + private final Semaphore semaphore; public ThreadExecutionSynchronizer() { semaphore = new Semaphore(1); From 26758f0ffd85e47f8f36bc567bea08c0957efe7b Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Fri, 6 Sep 2013 09:53:24 +0100 Subject: [PATCH 0230/1294] 8024039: javac, previous solution for JDK-8022186 was incorrect Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Lower.java | 20 ++- .../classes/com/sun/tools/javac/jvm/Gen.java | 124 ++++++++---------- .../NoDeadCodeGenerationOnTrySmtTest.java | 124 ++++++++++++++++++ 3 files changed, 197 insertions(+), 71 deletions(-) create mode 100644 langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 75e1d388666..7094d64b19c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -49,7 +49,6 @@ import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.jvm.ByteCodes.*; import static com.sun.tools.javac.tree.JCTree.Tag.*; -import javax.lang.model.type.TypeKind; /** This pass translates away some syntactic sugar: inner classes, * class literals, assertions, foreach loops, etc. @@ -3830,15 +3829,26 @@ public class Lower extends TreeTranslator { @Override public void visitTry(JCTry tree) { - /* special case of try without catchers and with finally emtpy. - * Don't give it a try, translate only the body. - */ if (tree.resources.isEmpty()) { + /* special case of try without catchers and with finally emtpy. + * Don't give it a try, translate only the body. + */ if (tree.catchers.isEmpty() && tree.finalizer.getStatements().isEmpty()) { result = translate(tree.body); } else { - super.visitTry(tree); + /* also if the body is empty we only need to generate the finalizer + * provided that it's not empty. + */ + if (tree.body.getStatements().isEmpty()) { + if (tree.finalizer.getStatements().isEmpty()) { + result = translate(tree.body); + } else { + result = translate(tree.finalizer); + } + } else { + super.visitTry(tree); + } } } else { result = makeTwrTry(tree); diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index cc438a73510..3f0fc861da3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -1478,82 +1478,74 @@ public class Gen extends JCTree.Visitor { code.statBegin(TreeInfo.endPos(body)); genFinalizer(env); code.statBegin(TreeInfo.endPos(env.tree)); - Chain exitChain; - if (startpc != endpc) { - exitChain = code.branch(goto_); - } else { - exitChain = code.branch(dontgoto); - } + Chain exitChain = code.branch(goto_); endFinalizerGap(env); - if (startpc != endpc) { - for (List l = catchers; l.nonEmpty(); l = l.tail) { - // start off with exception on stack - code.entryPoint(stateTry, l.head.param.sym.type); - genCatch(l.head, env, startpc, endpc, gaps); - genFinalizer(env); - if (hasFinalizer || l.tail.nonEmpty()) { - code.statBegin(TreeInfo.endPos(env.tree)); - exitChain = Code.mergeChains(exitChain, - code.branch(goto_)); - } - endFinalizerGap(env); + if (startpc != endpc) for (List l = catchers; l.nonEmpty(); l = l.tail) { + // start off with exception on stack + code.entryPoint(stateTry, l.head.param.sym.type); + genCatch(l.head, env, startpc, endpc, gaps); + genFinalizer(env); + if (hasFinalizer || l.tail.nonEmpty()) { + code.statBegin(TreeInfo.endPos(env.tree)); + exitChain = Code.mergeChains(exitChain, + code.branch(goto_)); } + endFinalizerGap(env); + } + if (hasFinalizer) { + // Create a new register segement to avoid allocating + // the same variables in finalizers and other statements. + code.newRegSegment(); - if (hasFinalizer) { - // Create a new register segement to avoid allocating - // the same variables in finalizers and other statements. - code.newRegSegment(); + // Add a catch-all clause. - // Add a catch-all clause. + // start off with exception on stack + int catchallpc = code.entryPoint(stateTry, syms.throwableType); - // start off with exception on stack - int catchallpc = code.entryPoint(stateTry, syms.throwableType); + // Register all exception ranges for catch all clause. + // The range of the catch all clause is from the beginning + // of the try or synchronized block until the present + // code pointer excluding all gaps in the current + // environment's GenContext. + int startseg = startpc; + while (env.info.gaps.nonEmpty()) { + int endseg = env.info.gaps.next().intValue(); + registerCatch(body.pos(), startseg, endseg, + catchallpc, 0); + startseg = env.info.gaps.next().intValue(); + } + code.statBegin(TreeInfo.finalizerPos(env.tree)); + code.markStatBegin(); - // Register all exception ranges for catch all clause. - // The range of the catch all clause is from the beginning - // of the try or synchronized block until the present - // code pointer excluding all gaps in the current - // environment's GenContext. - int startseg = startpc; - while (env.info.gaps.nonEmpty()) { - int endseg = env.info.gaps.next().intValue(); - registerCatch(body.pos(), startseg, endseg, - catchallpc, 0); - startseg = env.info.gaps.next().intValue(); - } + Item excVar = makeTemp(syms.throwableType); + excVar.store(); + genFinalizer(env); + excVar.load(); + registerCatch(body.pos(), startseg, + env.info.gaps.next().intValue(), + catchallpc, 0); + code.emitop0(athrow); + code.markDead(); + + // If there are jsr's to this finalizer, ... + if (env.info.cont != null) { + // Resolve all jsr's. + code.resolve(env.info.cont); + + // Mark statement line number code.statBegin(TreeInfo.finalizerPos(env.tree)); code.markStatBegin(); - Item excVar = makeTemp(syms.throwableType); - excVar.store(); - genFinalizer(env); - excVar.load(); - registerCatch(body.pos(), startseg, - env.info.gaps.next().intValue(), - catchallpc, 0); - code.emitop0(athrow); + // Save return address. + LocalItem retVar = makeTemp(syms.throwableType); + retVar.store(); + + // Generate finalizer code. + env.info.finalize.genLast(); + + // Return. + code.emitop1w(ret, retVar.reg); code.markDead(); - - // If there are jsr's to this finalizer, ... - if (env.info.cont != null) { - // Resolve all jsr's. - code.resolve(env.info.cont); - - // Mark statement line number - code.statBegin(TreeInfo.finalizerPos(env.tree)); - code.markStatBegin(); - - // Save return address. - LocalItem retVar = makeTemp(syms.throwableType); - retVar.store(); - - // Generate finalizer code. - env.info.finalize.genLast(); - - // Return. - code.emitop1w(ret, retVar.reg); - code.markDead(); - } } } // Resolve all breaks. diff --git a/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java b/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java new file mode 100644 index 00000000000..0dd25871f3a --- /dev/null +++ b/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 8024039 + * @summary javac, previous solution for JDK-8022186 was incorrect + * @library /tools/javac/lib + * @build ToolBox + * @run main NoDeadCodeGenerationOnTrySmtTest + */ + +import java.io.File; +import java.nio.file.Paths; + +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.Code_attribute.Exception_data; +import com.sun.tools.classfile.Method; +import com.sun.tools.javac.util.Assert; + +public class NoDeadCodeGenerationOnTrySmtTest { + + static final String testSource = + "public class Test {\n" + + " void m1(int arg) {\n" + + " synchronized (new Integer(arg)) {\n" + + " {\n" + + " label0:\n" + + " do {\n" + + " break label0;\n" + + " } while (arg != 0);\n" + + " }\n" + + " }\n" + + " }\n" + + + " void m2(int arg) {\n" + + " synchronized (new Integer(arg)) {\n" + + " {\n" + + " label0:\n" + + " {\n" + + " break label0;\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + + static final int[][] expectedExceptionTable = { + // {from, to, target, type}, + {11, 13, 16, 0}, + {16, 19, 16, 0} + }; + + static final String[] methodsToLookFor = {"m1", "m2"}; + + public static void main(String[] args) throws Exception { + new NoDeadCodeGenerationOnTrySmtTest().run(); + } + + void run() throws Exception { + compileTestClass(); + checkClassFile(new File(Paths.get(System.getProperty("user.dir"), + "Test.class").toUri()), methodsToLookFor); + } + + void compileTestClass() throws Exception { + ToolBox.JavaToolArgs javacSuccessArgs = + new ToolBox.JavaToolArgs().setSources(testSource); + ToolBox.javac(javacSuccessArgs); + } + + void checkClassFile(final File cfile, String[] methodsToFind) throws Exception { + ClassFile classFile = ClassFile.read(cfile); + int numberOfmethodsFound = 0; + for (String methodToFind : methodsToFind) { + for (Method method : classFile.methods) { + if (method.getName(classFile.constant_pool).equals(methodToFind)) { + numberOfmethodsFound++; + Code_attribute code = (Code_attribute) method.attributes.get("Code"); + Assert.check(code.exception_table_langth == expectedExceptionTable.length, + "The ExceptionTable found has a length different to the expected one"); + int i = 0; + for (Exception_data entry: code.exception_table) { + Assert.check(entry.start_pc == expectedExceptionTable[i][0] && + entry.end_pc == expectedExceptionTable[i][1] && + entry.handler_pc == expectedExceptionTable[i][2] && + entry.catch_type == expectedExceptionTable[i][3], + "Exception table entry at pos " + i + " differ from expected."); + i++; + } + } + } + } + Assert.check(numberOfmethodsFound == 2, "Some seek methods were not found"); + } + + void error(String msg) { + throw new AssertionError(msg); + } + +} From 8007590d3bc9e355ca133f54d05f6e183d78c60f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?= Date: Fri, 6 Sep 2013 14:20:12 +0200 Subject: [PATCH 0231/1294] 5047859: (reflect) Class.getField can't find String[].length Reviewed-by: darcy, mchung --- jdk/src/share/classes/java/lang/Class.java | 71 ++++++++++++------- .../java/lang/Class/getField/ArrayLength.java | 64 +++++++++++++++++ 2 files changed, 108 insertions(+), 27 deletions(-) create mode 100644 jdk/test/java/lang/Class/getField/ArrayLength.java diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index a3c962e0838..b8af59b7ae5 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -1484,22 +1484,24 @@ public final class Class implements java.io.Serializable, /** * Returns an array containing {@code Field} objects reflecting all * the accessible public fields of the class or interface represented by - * this {@code Class} object. The elements in the array returned are - * not sorted and are not in any particular order. This method returns an - * array of length 0 if the class or interface has no accessible public - * fields, or if it represents an array class, a primitive type, or void. + * this {@code Class} object. * - *

    Specifically, if this {@code Class} object represents a class, - * this method returns the public fields of this class and of all its - * superclasses. If this {@code Class} object represents an - * interface, this method returns the fields of this interface and of all - * its superinterfaces. + *

    If this {@code Class} object represents a class or interface with no + * no accessible public fields, then this method returns an array of length + * 0. * - *

    The implicit length field for array class is not reflected by this - * method. User code should use the methods of class {@code Array} to - * manipulate arrays. + *

    If this {@code Class} object represents a class, then this method + * returns the public fields of the class and of all its superclasses. * - *

    See The Java Language Specification, sections 8.2 and 8.3. + *

    If this {@code Class} object represents an interface, then this + * method returns the fields of the interface and of all its + * superinterfaces. + * + *

    If this {@code Class} object represents an array type, a primitive + * type, or void, then this method returns an array of length 0. + * + *

    The elements in the array returned are not sorted and are not in any + * particular order. * * @return the array of {@code Field} objects representing the * public fields @@ -1512,6 +1514,8 @@ public final class Class implements java.io.Serializable, * of this class. * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field[] getFields() throws SecurityException { @@ -1595,13 +1599,14 @@ public final class Class implements java.io.Serializable, /** - * Returns a {@code Field} object that reflects the specified public - * member field of the class or interface represented by this - * {@code Class} object. The {@code name} parameter is a - * {@code String} specifying the simple name of the desired field. + * Returns a {@code Field} object that reflects the specified public member + * field of the class or interface represented by this {@code Class} + * object. The {@code name} parameter is a {@code String} specifying the + * simple name of the desired field. * *

    The field to be reflected is determined by the algorithm that - * follows. Let C be the class represented by this object: + * follows. Let C be the class or interface represented by this object: + * *

      *
    1. If C declares a public field with the name specified, that is the * field to be reflected.
    2. @@ -1614,7 +1619,8 @@ public final class Class implements java.io.Serializable, * is thrown. *
    * - *

    See The Java Language Specification, sections 8.2 and 8.3. + *

    If this {@code Class} object represents an array type, then this + * method does not find the {@code length} field of the array type. * * @param name the field name * @return the {@code Field} object of this class specified by @@ -1631,6 +1637,8 @@ public final class Class implements java.io.Serializable, * of this class. * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field getField(String name) @@ -1800,12 +1808,15 @@ public final class Class implements java.io.Serializable, * declared by the class or interface represented by this * {@code Class} object. This includes public, protected, default * (package) access, and private fields, but excludes inherited fields. - * The elements in the array returned are not sorted and are not in any - * particular order. This method returns an array of length 0 if the class - * or interface declares no fields, or if this {@code Class} object - * represents a primitive type, an array class, or void. * - *

    See The Java Language Specification, sections 8.2 and 8.3. + *

    If this {@code Class} object represents a class or interface with no + * declared fields, then this method returns an array of length 0. + * + *

    If this {@code Class} object represents an array type, a primitive + * type, or void, then this method returns an array of length 0. + * + *

    The elements in the array returned are not sorted and are not in any + * particular order. * * @return the array of {@code Field} objects representing all the * declared fields of this class @@ -1831,6 +1842,8 @@ public final class Class implements java.io.Serializable, * * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field[] getDeclaredFields() throws SecurityException { @@ -1935,9 +1948,11 @@ public final class Class implements java.io.Serializable, /** * Returns a {@code Field} object that reflects the specified declared * field of the class or interface represented by this {@code Class} - * object. The {@code name} parameter is a {@code String} that - * specifies the simple name of the desired field. Note that this method - * will not reflect the {@code length} field of an array class. + * object. The {@code name} parameter is a {@code String} that specifies + * the simple name of the desired field. + * + *

    If this {@code Class} object represents an array type, then this + * method does not find the {@code length} field of the array type. * * @param name the name of the field * @return the {@code Field} object for the specified field in this @@ -1967,6 +1982,8 @@ public final class Class implements java.io.Serializable, * * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field getDeclaredField(String name) diff --git a/jdk/test/java/lang/Class/getField/ArrayLength.java b/jdk/test/java/lang/Class/getField/ArrayLength.java new file mode 100644 index 00000000000..c03a772c043 --- /dev/null +++ b/jdk/test/java/lang/Class/getField/ArrayLength.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013, 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 5047859 + * @summary verify that for an array type class instance, getField("length") + * throws an exception, and getFields() does not contain a Field for + * 'length' + */ + +import java.lang.reflect.Field; + +public class ArrayLength { + public static void main(String [] args) { + int failed = 0; + + try { + new String[0].getClass().getField("length"); + failed++; + System.out.println("getField(\"length\") should throw NoSuchFieldException"); + } catch (NoSuchFieldException e) { + } + try { + new String[0].getClass().getDeclaredField("length"); + failed++; + System.out.println("getDeclaredField(\"length\") should throw NoSuchFieldException"); + } catch (NoSuchFieldException e) { + } + + if (new String[0].getClass().getFields().length != 0) { + failed++; + System.out.println("getFields() for an array type should return a zero length array"); + } + + if (new String[0].getClass().getDeclaredFields().length != 0) { + failed++; + System.out.println("getDeclaredFields() for an array type should return a zero length array"); + } + + if (failed != 0) + throw new RuntimeException("Test failed see log for details"); + } +} From 8b9c8247a80ff8d9954024e12177adf1eba71fff Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Sat, 7 Sep 2013 17:05:22 -0700 Subject: [PATCH 0232/1294] 7188657: There should be a way to reorder the JSSE ciphers Reviewed-by: weijun, wetmore --- .../classes/javax/net/ssl/SSLParameters.java | 36 +- .../classes/sun/security/ssl/Handshaker.java | 31 +- .../sun/security/ssl/SSLEngineImpl.java | 10 + .../sun/security/ssl/SSLServerSocketImpl.java | 13 +- .../sun/security/ssl/SSLSocketImpl.java | 14 +- .../sun/security/ssl/ServerHandshaker.java | 17 +- .../SSLParameters/UseCipherSuitesOrder.java | 357 ++++++++++++++++++ 7 files changed, 466 insertions(+), 12 deletions(-) create mode 100644 jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java diff --git a/jdk/src/share/classes/javax/net/ssl/SSLParameters.java b/jdk/src/share/classes/javax/net/ssl/SSLParameters.java index 1dc6f3315d0..5e0d403cd39 100644 --- a/jdk/src/share/classes/javax/net/ssl/SSLParameters.java +++ b/jdk/src/share/classes/javax/net/ssl/SSLParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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,7 +40,7 @@ import java.util.LinkedHashMap; * the list of protocols to be allowed, the endpoint identification * algorithm during SSL/TLS handshaking, the Server Name Indication (SNI), * the algorithm constraints and whether SSL/TLS servers should request - * or require client authentication. + * or require client authentication, etc. *

    * SSLParameters can be created via the constructors in this class. * Objects can also be obtained using the getSSLParameters() @@ -73,13 +73,14 @@ public class SSLParameters { private AlgorithmConstraints algorithmConstraints; private Map sniNames = null; private Map sniMatchers = null; + private boolean preferLocalCipherSuites; /** * Constructs SSLParameters. *

    * The values of cipherSuites, protocols, cryptographic algorithm * constraints, endpoint identification algorithm, server names and - * server name matchers are set to null, + * server name matchers are set to null, useCipherSuitesOrder, * wantClientAuth and needClientAuth are set to false. */ public SSLParameters() { @@ -434,5 +435,34 @@ public class SSLParameters { return null; } + + /** + * Sets whether the local cipher suites preference should be honored. + * + * @param honorOrder whether local cipher suites order in + * {@code #getCipherSuites} should be honored during + * SSL/TLS handshaking. + * + * @see #getUseCipherSuitesOrder() + * + * @since 1.8 + */ + public final void setUseCipherSuitesOrder(boolean honorOrder) { + this.preferLocalCipherSuites = honorOrder; + } + + /** + * Returns whether the local cipher suites preference should be honored. + * + * @return whether local cipher suites order in {@code #getCipherSuites} + * should be honored during SSL/TLS handshaking. + * + * @see #setUseCipherSuitesOrder(boolean) + * + * @since 1.8 + */ + public final boolean getUseCipherSuitesOrder() { + return preferLocalCipherSuites; + } } diff --git a/jdk/src/share/classes/sun/security/ssl/Handshaker.java b/jdk/src/share/classes/sun/security/ssl/Handshaker.java index 17b1f92ac74..a92320451e0 100644 --- a/jdk/src/share/classes/sun/security/ssl/Handshaker.java +++ b/jdk/src/share/classes/sun/security/ssl/Handshaker.java @@ -145,6 +145,14 @@ abstract class Handshaker { /* True if it's OK to start a new SSL session */ boolean enableNewSession; + // Whether local cipher suites preference should be honored during + // handshaking? + // + // Note that in this provider, this option only applies to server side. + // Local cipher suites preference is always honored in client side in + // this provider. + boolean preferLocalCipherSuites = false; + // Temporary storage for the individual keys. Set by // calculateConnectionKeys() and cleared once the ciphers are // activated. @@ -462,6 +470,13 @@ abstract class Handshaker { this.sniMatchers = sniMatchers; } + /** + * Sets the cipher suites preference. + */ + void setUseCipherSuitesOrder(boolean on) { + this.preferLocalCipherSuites = on; + } + /** * Prior to handshaking, activate the handshake and initialize the version, * input stream and output stream. @@ -533,7 +548,9 @@ abstract class Handshaker { } /** - * Check if the given ciphersuite is enabled and available. + * Check if the given ciphersuite is enabled and available within the + * current active cipher suites. + * * Does not check if the required server certificates are available. */ boolean isNegotiable(CipherSuite s) { @@ -541,7 +558,17 @@ abstract class Handshaker { activeCipherSuites = getActiveCipherSuites(); } - return activeCipherSuites.contains(s) && s.isNegotiable(); + return isNegotiable(activeCipherSuites, s); + } + + /** + * Check if the given ciphersuite is enabled and available within the + * proposed cipher suite list. + * + * Does not check if the required server certificates are available. + */ + final static boolean isNegotiable(CipherSuiteList proposed, CipherSuite s) { + return proposed.contains(s) && s.isNegotiable(); } /** diff --git a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java index c2e94f3b401..5302b6147b4 100644 --- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java +++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java @@ -319,6 +319,12 @@ final public class SSLEngineImpl extends SSLEngine { */ private boolean isFirstAppOutputRecord = true; + /* + * Whether local cipher suites preference in server side should be + * honored during handshaking? + */ + private boolean preferLocalCipherSuites = false; + /* * Class and subclass dynamic debugging support */ @@ -470,6 +476,7 @@ final public class SSLEngineImpl extends SSLEngine { protocolVersion, connectionState == cs_HANDSHAKE, secureRenegotiation, clientVerifyData, serverVerifyData); handshaker.setSNIMatchers(sniMatchers); + handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites); } else { handshaker = new ClientHandshaker(this, sslContext, enabledProtocols, @@ -2074,6 +2081,7 @@ final public class SSLEngineImpl extends SSLEngine { params.setAlgorithmConstraints(algorithmConstraints); params.setSNIMatchers(sniMatchers); params.setServerNames(serverNames); + params.setUseCipherSuitesOrder(preferLocalCipherSuites); return params; } @@ -2088,6 +2096,7 @@ final public class SSLEngineImpl extends SSLEngine { // the super implementation does not handle the following parameters identificationProtocol = params.getEndpointIdentificationAlgorithm(); algorithmConstraints = params.getAlgorithmConstraints(); + preferLocalCipherSuites = params.getUseCipherSuitesOrder(); List sniNames = params.getServerNames(); if (sniNames != null) { @@ -2104,6 +2113,7 @@ final public class SSLEngineImpl extends SSLEngine { handshaker.setAlgorithmConstraints(algorithmConstraints); if (roleIsServer) { handshaker.setSNIMatchers(sniMatchers); + handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites); } else { handshaker.setSNIServerNames(serverNames); } diff --git a/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java index 0e0edf18e4a..464bab23ad4 100644 --- a/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java +++ b/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,6 +92,12 @@ class SSLServerSocketImpl extends SSLServerSocket Collection sniMatchers = Collections.emptyList(); + /* + * Whether local cipher suites preference in server side should be + * honored during handshaking? + */ + private boolean preferLocalCipherSuites = false; + /** * Create an SSL server socket on a port, using a non-default * authentication context and a specified connection backlog. @@ -304,6 +310,8 @@ class SSLServerSocketImpl extends SSLServerSocket params.setEndpointIdentificationAlgorithm(identificationProtocol); params.setAlgorithmConstraints(algorithmConstraints); params.setSNIMatchers(sniMatchers); + params.setUseCipherSuitesOrder(preferLocalCipherSuites); + return params; } @@ -318,6 +326,7 @@ class SSLServerSocketImpl extends SSLServerSocket // the super implementation does not handle the following parameters identificationProtocol = params.getEndpointIdentificationAlgorithm(); algorithmConstraints = params.getAlgorithmConstraints(); + preferLocalCipherSuites = params.getUseCipherSuitesOrder(); Collection matchers = params.getSNIMatchers(); if (matchers != null) { sniMatchers = params.getSNIMatchers(); @@ -334,7 +343,7 @@ class SSLServerSocketImpl extends SSLServerSocket SSLSocketImpl s = new SSLSocketImpl(sslContext, useServerMode, enabledCipherSuites, doClientAuth, enableSessionCreation, enabledProtocols, identificationProtocol, algorithmConstraints, - sniMatchers); + sniMatchers, preferLocalCipherSuites); implAccept(s); s.doneConnect(); diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java index dfe612966e0..4d591e3d7a5 100644 --- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java @@ -377,6 +377,12 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { */ private ByteArrayOutputStream heldRecordBuffer = null; + /* + * Whether local cipher suites preference in server side should be + * honored during handshaking? + */ + private boolean preferLocalCipherSuites = false; + // // CONSTRUCTORS AND INITIALIZATION CODE // @@ -482,7 +488,8 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { boolean sessionCreation, ProtocolList protocols, String identificationProtocol, AlgorithmConstraints algorithmConstraints, - Collection sniMatchers) throws IOException { + Collection sniMatchers, + boolean preferLocalCipherSuites) throws IOException { super(); doClientAuth = clientAuth; @@ -490,6 +497,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { this.identificationProtocol = identificationProtocol; this.algorithmConstraints = algorithmConstraints; this.sniMatchers = sniMatchers; + this.preferLocalCipherSuites = preferLocalCipherSuites; init(context, serverMode); /* @@ -1284,6 +1292,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { protocolVersion, connectionState == cs_HANDSHAKE, secureRenegotiation, clientVerifyData, serverVerifyData); handshaker.setSNIMatchers(sniMatchers); + handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites); } else { handshaker = new ClientHandshaker(this, sslContext, enabledProtocols, @@ -2502,6 +2511,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { params.setAlgorithmConstraints(algorithmConstraints); params.setSNIMatchers(sniMatchers); params.setServerNames(serverNames); + params.setUseCipherSuitesOrder(preferLocalCipherSuites); return params; } @@ -2516,6 +2526,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { // the super implementation does not handle the following parameters identificationProtocol = params.getEndpointIdentificationAlgorithm(); algorithmConstraints = params.getAlgorithmConstraints(); + preferLocalCipherSuites = params.getUseCipherSuitesOrder(); List sniNames = params.getServerNames(); if (sniNames != null) { @@ -2532,6 +2543,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { handshaker.setAlgorithmConstraints(algorithmConstraints); if (roleIsServer) { handshaker.setSNIMatchers(sniMatchers); + handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites); } else { handshaker.setSNIServerNames(serverNames); } diff --git a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java index e317e1f18c5..23b806f33e2 100644 --- a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java +++ b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java @@ -932,8 +932,18 @@ final class ServerHandshaker extends Handshaker { * the cipherSuite and keyExchange variables. */ private void chooseCipherSuite(ClientHello mesg) throws IOException { - for (CipherSuite suite : mesg.getCipherSuites().collection()) { - if (isNegotiable(suite) == false) { + CipherSuiteList prefered; + CipherSuiteList proposed; + if (preferLocalCipherSuites) { + prefered = getActiveCipherSuites(); + proposed = mesg.getCipherSuites(); + } else { + prefered = mesg.getCipherSuites(); + proposed = getActiveCipherSuites(); + } + + for (CipherSuite suite : prefered.collection()) { + if (isNegotiable(proposed, suite) == false) { continue; } @@ -948,8 +958,7 @@ final class ServerHandshaker extends Handshaker { } return; } - fatalSE(Alerts.alert_handshake_failure, - "no cipher suites in common"); + fatalSE(Alerts.alert_handshake_failure, "no cipher suites in common"); } /** diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java b/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java new file mode 100644 index 00000000000..c25d74c7d2c --- /dev/null +++ b/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2013, 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. + */ + +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + +/* + * @test + * @bug 7188657 + * @summary There should be a way to reorder the JSSE ciphers + * @run main/othervm UseCipherSuitesOrder + * TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA + */ + +import java.io.*; +import java.net.*; +import javax.net.ssl.*; +import java.util.Arrays; + +public class UseCipherSuitesOrder { + + /* + * ============================================================= + * Set the various variables needed for the tests, then + * specify what tests to run on each side. + */ + + /* + * Should we run the client or server in a separate thread? + * Both sides can throw exceptions, but do you have a preference + * as to which side should be the main thread. + */ + static boolean separateServerThread = false; + + /* + * Where do we find the keystores? + */ + static String pathToStores = "../../../../etc"; + static String keyStoreFile = "keystore"; + static String trustStoreFile = "truststore"; + static String passwd = "passphrase"; + + /* + * Is the server ready to serve? + */ + volatile static boolean serverReady = false; + + /* + * Turn on SSL debugging? + */ + static boolean debug = false; + + /* + * If the client or server is doing some kind of object creation + * that the other side depends on, and that thread prematurely + * exits, you may experience a hang. The test harness will + * terminate all hung threads after its timeout has expired, + * currently 3 minutes by default, but you might try to be + * smart about it.... + */ + + /* + * Define the server side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doServerSide() throws Exception { + SSLServerSocketFactory sslssf = + (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); + SSLServerSocket sslServerSocket = + (SSLServerSocket) sslssf.createServerSocket(serverPort); + serverPort = sslServerSocket.getLocalPort(); + + // use local cipher suites preference + SSLParameters params = sslServerSocket.getSSLParameters(); + params.setUseCipherSuitesOrder(true); + params.setCipherSuites(srvEnabledCipherSuites); + sslServerSocket.setSSLParameters(params); + + /* + * Signal Client, we're ready for his connect. + */ + serverReady = true; + + SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslIS.read(); + sslOS.write(85); + sslOS.flush(); + + SSLSession session = sslSocket.getSession(); + if (!srvEnabledCipherSuites[0].equals(session.getCipherSuite())) { + throw new Exception( + "Expected to negotiate " + srvEnabledCipherSuites[0] + + " , but not " + session.getCipherSuite()); + } + + sslSocket.close(); + } + + /* + * Define the client side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doClientSide() throws Exception { + + /* + * Wait for server to get started. + */ + while (!serverReady) { + Thread.sleep(50); + } + + SSLSocketFactory sslsf = + (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocket sslSocket = (SSLSocket) + sslsf.createSocket("localhost", serverPort); + sslSocket.setEnabledCipherSuites(cliEnabledCipherSuites); + + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslOS.write(280); + sslOS.flush(); + sslIS.read(); + + sslSocket.close(); + } + + // client enabled cipher suites + private static String[] cliEnabledCipherSuites; + + // server enabled cipher suites + private static String[] srvEnabledCipherSuites; + + private static void parseArguments(String[] args) throws Exception { + if (args.length != 1) { + System.out.println("Usage: java UseCipherSuitesOrder ciphersuites"); + System.out.println("\tciphersuites: " + + "a list of enabled cipher suites, separated with comma"); + throw new Exception("Incorrect usage"); + } + + cliEnabledCipherSuites = args[0].split(","); + + if (cliEnabledCipherSuites.length < 2) { + throw new Exception("Need to enable at least two cipher suites"); + } + + // Only need to use 2 cipher suites in server side. + srvEnabledCipherSuites = Arrays.copyOf( + cliEnabledCipherSuites, 2); + + // Reverse the cipher suite preference in server side. + srvEnabledCipherSuites[0] = cliEnabledCipherSuites[1]; + srvEnabledCipherSuites[1] = cliEnabledCipherSuites[0]; + } + + /* + * ============================================================= + * The remainder is just support stuff + */ + + // use any free port by default + volatile int serverPort = 0; + + volatile Exception serverException = null; + volatile Exception clientException = null; + + public static void main(String[] args) throws Exception { + // parse the arguments + parseArguments(args); + + String keyFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + keyStoreFile; + String trustFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + trustStoreFile; + + System.setProperty("javax.net.ssl.keyStore", keyFilename); + System.setProperty("javax.net.ssl.keyStorePassword", passwd); + System.setProperty("javax.net.ssl.trustStore", trustFilename); + System.setProperty("javax.net.ssl.trustStorePassword", passwd); + + if (debug) + System.setProperty("javax.net.debug", "all"); + + /* + * Start the tests. + */ + new UseCipherSuitesOrder(); + } + + Thread clientThread = null; + Thread serverThread = null; + + /* + * Primary constructor, used to drive remainder of the test. + * + * Fork off the other side, then do your work. + */ + UseCipherSuitesOrder() throws Exception { + Exception startException = null; + try { + if (separateServerThread) { + startServer(true); + startClient(false); + } else { + startClient(true); + startServer(false); + } + } catch (Exception e) { + startException = e; + } + + /* + * Wait for other side to close down. + */ + if (separateServerThread) { + if (serverThread != null) { + serverThread.join(); + } + } else { + if (clientThread != null) { + clientThread.join(); + } + } + + /* + * When we get here, the test is pretty much over. + * Which side threw the error? + */ + Exception local; + Exception remote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + } else { + remote = clientException; + local = serverException; + } + + Exception exception = null; + + /* + * Check various exception conditions. + */ + if ((local != null) && (remote != null)) { + // If both failed, return the curthread's exception. + local.initCause(remote); + exception = local; + } else if (local != null) { + exception = local; + } else if (remote != null) { + exception = remote; + } else if (startException != null) { + exception = startException; + } + + /* + * If there was an exception *AND* a startException, + * output it. + */ + if (exception != null) { + if (exception != startException && startException != null) { + exception.addSuppressed(startException); + } + throw exception; + } + + // Fall-through: no exception to throw! + } + + void startServer(boolean newThread) throws Exception { + if (newThread) { + serverThread = new Thread() { + public void run() { + try { + doServerSide(); + } catch (Exception e) { + /* + * Our server thread just died. + * + * Release the client, if not active already... + */ + System.err.println("Server died..."); + serverReady = true; + serverException = e; + } + } + }; + serverThread.start(); + } else { + try { + doServerSide(); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = true; + } + } + } + + void startClient(boolean newThread) throws Exception { + if (newThread) { + clientThread = new Thread() { + public void run() { + try { + doClientSide(); + } catch (Exception e) { + /* + * Our client thread just died. + */ + System.err.println("Client died..."); + clientException = e; + } + } + }; + clientThread.start(); + } else { + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } + } + } +} From a4c7971bdb559d5b0e8d09f145da3a25c78f5dce Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Mon, 9 Sep 2013 11:08:20 +0800 Subject: [PATCH 0233/1294] 8024046: Test sun/security/krb5/runNameEquals.sh failed on 7u45 Embedded linux-ppc* Reviewed-by: xuelei --- jdk/test/sun/security/krb5/runNameEquals.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/jdk/test/sun/security/krb5/runNameEquals.sh b/jdk/test/sun/security/krb5/runNameEquals.sh index 6db90c35315..b9cfb08d8b5 100644 --- a/jdk/test/sun/security/krb5/runNameEquals.sh +++ b/jdk/test/sun/security/krb5/runNameEquals.sh @@ -22,7 +22,7 @@ # # @test -# @bug 6317711 6944847 +# @bug 6317711 6944847 8024046 # @summary Ensure the GSSName has the correct impl which respects # the contract for equals and hashCode across different configurations. @@ -56,6 +56,15 @@ case "$OS" in PATHSEP=":" FILESEP="/" NATIVE=true + # Not all *nix has native GSS libs installed + krb5-config --libs gssapi 2> /dev/null + if [ $? != 0 ]; then + # Fedora has a different path + /usr/kerberos/bin/krb5-config --libs gssapi 2> /dev/null + if [ $? != 0 ]; then + NATIVE=false + fi + fi ;; CYGWIN* ) PATHSEP=";" From 33dbc2d51c62d6e6657ffbf64c026426bd6f072c Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Mon, 9 Sep 2013 13:59:51 +0200 Subject: [PATCH 0234/1294] 8023168: Cleanup LogManager class initialization and LogManager/LoggerContext relationship 8021003: java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java fails intermittently 8019945: test/java/util/logging/LogManagerInstanceTest.java failing intermittently This fix untangles the class initialization of Logger and LogManager, and also cleans up the relationship between LogManager, LoggerContext, and Logger, which were at the root cause of some intermittent test failures. Reviewed-by: mchung, martin, plevart --- .../classes/java/util/logging/LogManager.java | 310 ++++++++++++------ .../classes/java/util/logging/Logger.java | 42 ++- .../Logger/getGlobal/TestGetGlobal.java | 10 +- .../getGlobal/TestGetGlobalConcurrent.java | 26 +- .../java/util/logging/Logger/getGlobal/policy | 1 + .../java/util/logging/ParentLoggersTest.java | 2 +- .../util/logging/TestAppletLoggerContext.java | 151 ++++----- 7 files changed, 334 insertions(+), 208 deletions(-) diff --git a/jdk/src/share/classes/java/util/logging/LogManager.java b/jdk/src/share/classes/java/util/logging/LogManager.java index 717e52990e1..8596cbeb8fe 100644 --- a/jdk/src/share/classes/java/util/logging/LogManager.java +++ b/jdk/src/share/classes/java/util/logging/LogManager.java @@ -144,7 +144,7 @@ import sun.misc.SharedSecrets; public class LogManager { // The global LogManager object - private static LogManager manager; + private static final LogManager manager; private Properties props = new Properties(); private final static Level defaultLevel = Level.INFO; @@ -156,8 +156,10 @@ public class LogManager { // LoggerContext for system loggers and user loggers private final LoggerContext systemContext = new SystemLoggerContext(); private final LoggerContext userContext = new LoggerContext(); - private Logger rootLogger; - + // non final field - make it volatile to make sure that other threads + // will see the new value once ensureLogManagerInitialized() has finished + // executing. + private volatile Logger rootLogger; // Have we done the primordial reading of the configuration file? // (Must be done after a suitable amount of java.lang.System // initialization has been done) @@ -169,58 +171,35 @@ public class LogManager { private boolean deathImminent; static { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - String cname = null; - try { - cname = System.getProperty("java.util.logging.manager"); - if (cname != null) { - try { - Class clz = ClassLoader.getSystemClassLoader().loadClass(cname); - manager = (LogManager) clz.newInstance(); - } catch (ClassNotFoundException ex) { - Class clz = Thread.currentThread().getContextClassLoader().loadClass(cname); - manager = (LogManager) clz.newInstance(); - } + manager = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public LogManager run() { + LogManager mgr = null; + String cname = null; + try { + cname = System.getProperty("java.util.logging.manager"); + if (cname != null) { + try { + Class clz = ClassLoader.getSystemClassLoader() + .loadClass(cname); + mgr = (LogManager) clz.newInstance(); + } catch (ClassNotFoundException ex) { + Class clz = Thread.currentThread() + .getContextClassLoader().loadClass(cname); + mgr = (LogManager) clz.newInstance(); } - } catch (Exception ex) { - System.err.println("Could not load Logmanager \"" + cname + "\""); - ex.printStackTrace(); } - if (manager == null) { - manager = new LogManager(); - } - - // Create and retain Logger for the root of the namespace. - manager.rootLogger = manager.new RootLogger(); - // since by design the global manager's userContext and - // systemContext don't have their requiresDefaultLoggers - // flag set - we make sure to add the root logger to - // the global manager's default contexts here. - manager.addLogger(manager.rootLogger); - manager.systemContext.addLocalLogger(manager.rootLogger, false); - manager.userContext.addLocalLogger(manager.rootLogger, false); - - // Adding the global Logger. Doing so in the Logger. - // would deadlock with the LogManager.. - // Do not call Logger.getGlobal() here as this might trigger - // the deadlock too. - @SuppressWarnings("deprecation") - final Logger global = Logger.global; - global.setLogManager(manager); - - // Make sure the global logger will be registered in the - // global manager's default contexts. - manager.addLogger(global); - manager.systemContext.addLocalLogger(global, false); - manager.userContext.addLocalLogger(global, false); - - // We don't call readConfiguration() here, as we may be running - // very early in the JVM startup sequence. Instead readConfiguration - // will be called lazily in getLogManager(). - return null; + } catch (Exception ex) { + System.err.println("Could not load Logmanager \"" + cname + "\""); + ex.printStackTrace(); } - }); + if (mgr == null) { + mgr = new LogManager(); + } + return mgr; + + } + }); } @@ -235,6 +214,7 @@ public class LogManager { this.setContextClassLoader(null); } + @Override public void run() { // This is to ensure the LogManager. is completed // before synchronized block. Otherwise deadlocks are possible. @@ -270,13 +250,104 @@ public class LogManager { } } + /** + * Lazy initialization: if this instance of manager is the global + * manager then this method will read the initial configuration and + * add the root logger and global logger by calling addLogger(). + * + * Note that it is subtly different from what we do in LoggerContext. + * In LoggerContext we're patching up the logger context tree in order to add + * the root and global logger *to the context tree*. + * + * For this to work, addLogger() must have already have been called + * once on the LogManager instance for the default logger being + * added. + * + * This is why ensureLogManagerInitialized() needs to be called before + * any logger is added to any logger context. + * + */ + private boolean initializedCalled = false; + private volatile boolean initializationDone = false; + final void ensureLogManagerInitialized() { + final LogManager owner = this; + if (initializationDone || owner != manager) { + // we don't want to do this twice, and we don't want to do + // this on private manager instances. + return; + } + + // Maybe another thread has called ensureLogManagerInitialized() + // before us and is still executing it. If so we will block until + // the log manager has finished initialized, then acquire the monitor, + // notice that initializationDone is now true and return. + // Otherwise - we have come here first! We will acquire the monitor, + // see that initializationDone is still false, and perform the + // initialization. + // + synchronized(this) { + // If initializedCalled is true it means that we're already in + // the process of initializing the LogManager in this thread. + // There has been a recursive call to ensureLogManagerInitialized(). + final boolean isRecursiveInitialization = (initializedCalled == true); + + assert initializedCalled || !initializationDone + : "Initialization can't be done if initialized has not been called!"; + + if (isRecursiveInitialization || initializationDone) { + // If isRecursiveInitialization is true it means that we're + // already in the process of initializing the LogManager in + // this thread. There has been a recursive call to + // ensureLogManagerInitialized(). We should not proceed as + // it would lead to infinite recursion. + // + // If initializationDone is true then it means the manager + // has finished initializing; just return: we're done. + return; + } + // Calling addLogger below will in turn call requiresDefaultLogger() + // which will call ensureLogManagerInitialized(). + // We use initializedCalled to break the recursion. + initializedCalled = true; + try { + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Object run() { + assert rootLogger == null; + assert initializedCalled && !initializationDone; + + // Read configuration. + owner.readPrimordialConfiguration(); + + // Create and retain Logger for the root of the namespace. + owner.rootLogger = owner.new RootLogger(); + owner.addLogger(owner.rootLogger); + + // Adding the global Logger. + // Do not call Logger.getGlobal() here as this might trigger + // subtle inter-dependency issues. + @SuppressWarnings("deprecation") + final Logger global = Logger.global; + + // Make sure the global logger will be registered in the + // global manager + owner.addLogger(global); + return null; + } + }); + } finally { + initializationDone = true; + } + } + } + /** * Returns the global LogManager object. * @return the global LogManager object */ public static LogManager getLogManager() { if (manager != null) { - manager.readPrimordialConfiguration(); + manager.ensureLogManagerInitialized(); } return manager; } @@ -295,6 +366,7 @@ public class LogManager { try { AccessController.doPrivileged(new PrivilegedExceptionAction() { + @Override public Void run() throws Exception { readConfiguration(); @@ -304,8 +376,7 @@ public class LogManager { } }); } catch (Exception ex) { - // System.err.println("Can't read logging configuration:"); - // ex.printStackTrace(); + assert false : "Exception raised while reading logging configuration: " + ex; } } } @@ -392,7 +463,7 @@ public class LogManager { } // LoggerContext maps from AppContext - private static WeakHashMap contextsMap = null; + private WeakHashMap contextsMap = null; // Returns the LoggerContext for the user code (i.e. application or AppContext). // Loggers are isolated from each AppContext. @@ -414,10 +485,7 @@ public class LogManager { context = contextsMap.get(ecx); if (context == null) { // Create a new LoggerContext for the applet. - // The new logger context has its requiresDefaultLoggers - // flag set to true - so that these loggers will be - // lazily added when the context is firt accessed. - context = new LoggerContext(true); + context = new LoggerContext(); contextsMap.put(ecx, context); } } @@ -427,9 +495,14 @@ public class LogManager { return context != null ? context : userContext; } + // The system context. + final LoggerContext getSystemContext() { + return systemContext; + } + private List contexts() { List cxs = new ArrayList<>(); - cxs.add(systemContext); + cxs.add(getSystemContext()); cxs.add(getUserContext()); return cxs; } @@ -450,7 +523,7 @@ public class LogManager { Logger result = getLogger(name); if (result == null) { // only allocate the new logger once - Logger newLogger = new Logger(name, resourceBundleName, caller); + Logger newLogger = new Logger(name, resourceBundleName, caller, this); do { if (addLogger(newLogger)) { // We successfully added the new Logger that we @@ -477,7 +550,7 @@ public class LogManager { Logger demandSystemLogger(String name, String resourceBundleName) { // Add a system logger in the system context's namespace - final Logger sysLogger = systemContext.demandLogger(name, resourceBundleName); + final Logger sysLogger = getSystemContext().demandLogger(name, resourceBundleName); // Add the system logger to the LogManager's namespace if not exist // so that there is only one single logger of the given name. @@ -501,6 +574,7 @@ public class LogManager { // if logger already exists but handlers not set final Logger l = logger; AccessController.doPrivileged(new PrivilegedAction() { + @Override public Void run() { for (Handler hdl : l.getHandlers()) { sysLogger.addHandler(hdl); @@ -519,24 +593,52 @@ public class LogManager { // doesn't exist in the user context, it'll also be added to the user context. // The user context is queried by the user code and all other loggers are // added in the user context. - static class LoggerContext { + class LoggerContext { // Table of named Loggers that maps names to Loggers. private final Hashtable namedLoggers = new Hashtable<>(); // Tree of named Loggers private final LogNode root; - private final boolean requiresDefaultLoggers; private LoggerContext() { - this(false); - } - private LoggerContext(boolean requiresDefaultLoggers) { this.root = new LogNode(null, this); - this.requiresDefaultLoggers = requiresDefaultLoggers; + } + + + // Tells whether default loggers are required in this context. + // If true, the default loggers will be lazily added. + final boolean requiresDefaultLoggers() { + final boolean requiresDefaultLoggers = (getOwner() == manager); + if (requiresDefaultLoggers) { + getOwner().ensureLogManagerInitialized(); + } + return requiresDefaultLoggers; + } + + // This context's LogManager. + final LogManager getOwner() { + return LogManager.this; + } + + // This context owner's root logger, which if not null, and if + // the context requires default loggers, will be added to the context + // logger's tree. + final Logger getRootLogger() { + return getOwner().rootLogger; + } + + // The global logger, which if not null, and if + // the context requires default loggers, will be added to the context + // logger's tree. + final Logger getGlobalLogger() { + @SuppressWarnings("deprecated") // avoids initialization cycles. + final Logger global = Logger.global; + return global; } Logger demandLogger(String name, String resourceBundleName) { // a LogManager subclass may have its own implementation to add and // get a Logger. So delegate to the LogManager to do the work. - return manager.demandLogger(name, resourceBundleName, null); + final LogManager owner = getOwner(); + return owner.demandLogger(name, resourceBundleName, null); } @@ -548,10 +650,10 @@ public class LogManager { // or getLoggerNames() // private void ensureInitialized() { - if (requiresDefaultLoggers) { + if (requiresDefaultLoggers()) { // Ensure that the root and global loggers are set. - ensureDefaultLogger(manager.rootLogger); - ensureDefaultLogger(Logger.global); + ensureDefaultLogger(getRootLogger()); + ensureDefaultLogger(getGlobalLogger()); } } @@ -580,13 +682,13 @@ public class LogManager { // before adding 'logger'. // private void ensureAllDefaultLoggers(Logger logger) { - if (requiresDefaultLoggers) { + if (requiresDefaultLoggers()) { final String name = logger.getName(); if (!name.isEmpty()) { - ensureDefaultLogger(manager.rootLogger); - } - if (!Logger.GLOBAL_LOGGER_NAME.equals(name)) { - ensureDefaultLogger(Logger.global); + ensureDefaultLogger(getRootLogger()); + if (!Logger.GLOBAL_LOGGER_NAME.equals(name)) { + ensureDefaultLogger(getGlobalLogger()); + } } } } @@ -598,8 +700,8 @@ public class LogManager { // This check is simple sanity: we do not want that this // method be called for anything else than Logger.global // or owner.rootLogger. - if (!requiresDefaultLoggers || logger == null - || logger != Logger.global && logger != manager.rootLogger) { + if (!requiresDefaultLoggers() || logger == null + || logger != Logger.global && logger != LogManager.this.rootLogger) { // the case where we have a non null logger which is neither // Logger.global nor manager.rootLogger indicates a serious @@ -625,7 +727,7 @@ public class LogManager { boolean addLocalLogger(Logger logger) { // no need to add default loggers if it's not required - return addLocalLogger(logger, requiresDefaultLoggers); + return addLocalLogger(logger, requiresDefaultLoggers()); } // Add a logger to this context. This method will only set its level @@ -663,11 +765,13 @@ public class LogManager { // We're adding a new logger. // Note that we are creating a weak reference here. - ref = manager.new LoggerWeakRef(logger); + final LogManager owner = getOwner(); + logger.setLogManager(owner); + ref = owner.new LoggerWeakRef(logger); namedLoggers.put(name, ref); // Apply any initial level defined for the new logger. - Level level = manager.getLevelProperty(name + ".level", null); + Level level = owner.getLevelProperty(name + ".level", null); if (level != null) { doSetLevel(logger, level); } @@ -719,10 +823,12 @@ public class LogManager { // If logger.getUseParentHandlers() returns 'true' and any of the logger's // parents have levels or handlers defined, make sure they are instantiated. private void processParentHandlers(final Logger logger, final String name) { + final LogManager owner = getOwner(); AccessController.doPrivileged(new PrivilegedAction() { + @Override public Void run() { - if (logger != manager.rootLogger) { - boolean useParent = manager.getBooleanProperty(name + ".useParentHandlers", true); + if (logger != owner.rootLogger) { + boolean useParent = owner.getBooleanProperty(name + ".useParentHandlers", true); if (!useParent) { logger.setUseParentHandlers(false); } @@ -738,8 +844,8 @@ public class LogManager { break; } String pname = name.substring(0, ix2); - if (manager.getProperty(pname + ".level") != null || - manager.getProperty(pname + ".handlers") != null) { + if (owner.getProperty(pname + ".level") != null || + owner.getProperty(pname + ".handlers") != null) { // This pname has a level/handlers definition. // Make sure it exists. demandLogger(pname, null); @@ -779,16 +885,17 @@ public class LogManager { } } - static class SystemLoggerContext extends LoggerContext { + final class SystemLoggerContext extends LoggerContext { // Add a system logger in the system context's namespace as well as // in the LogManager's namespace if not exist so that there is only // one single logger of the given name. System loggers are visible // to applications unless a logger of the same name has been added. + @Override Logger demandLogger(String name, String resourceBundleName) { Logger result = findLogger(name); if (result == null) { // only allocate the new system logger once - Logger newLogger = new Logger(name, resourceBundleName); + Logger newLogger = new Logger(name, resourceBundleName, null, getOwner()); do { if (addLocalLogger(newLogger)) { // We successfully added the new Logger that we @@ -822,6 +929,7 @@ public class LogManager { final String handlersPropertyName) { AccessController.doPrivileged(new PrivilegedAction() { + @Override public Object run() { String names[] = parseClassNames(handlersPropertyName); for (int i = 0; i < names.length; i++) { @@ -1014,6 +1122,7 @@ public class LogManager { // There is a security manager. Raise privilege before // calling setLevel. AccessController.doPrivileged(new PrivilegedAction() { + @Override public Object run() { logger.setLevel(level); return null; @@ -1032,6 +1141,7 @@ public class LogManager { // There is a security manager. Raise privilege before // calling setParent. AccessController.doPrivileged(new PrivilegedAction() { + @Override public Object run() { logger.setParent(parent); return null; @@ -1129,14 +1239,9 @@ public class LogManager { f = new File(f, "logging.properties"); fname = f.getCanonicalPath(); } - InputStream in = new FileInputStream(fname); - BufferedInputStream bin = new BufferedInputStream(in); - try { + try (final InputStream in = new FileInputStream(fname)) { + final BufferedInputStream bin = new BufferedInputStream(in); readConfiguration(bin); - } finally { - if (in != null) { - in.close(); - } } } @@ -1201,7 +1306,7 @@ public class LogManager { } hands = hands.trim(); int ix = 0; - Vector result = new Vector<>(); + final List result = new ArrayList<>(); while (ix < hands.length()) { int end = ix; while (end < hands.length()) { @@ -1471,28 +1576,35 @@ public class LogManager { // We use a subclass of Logger for the root logger, so // that we only instantiate the global handlers when they // are first needed. - private class RootLogger extends Logger { + private final class RootLogger extends Logger { private RootLogger() { - super("", null); + // We do not call the protected Logger two args constructor here, + // to avoid calling LogManager.getLogManager() from within the + // RootLogger constructor. + super("", null, null, LogManager.this); setLevel(defaultLevel); } + @Override public void log(LogRecord record) { // Make sure that the global handlers have been instantiated. initializeGlobalHandlers(); super.log(record); } + @Override public void addHandler(Handler h) { initializeGlobalHandlers(); super.addHandler(h); } + @Override public void removeHandler(Handler h) { initializeGlobalHandlers(); super.removeHandler(h); } + @Override public Handler[] getHandlers() { initializeGlobalHandlers(); return super.getHandlers(); diff --git a/jdk/src/share/classes/java/util/logging/Logger.java b/jdk/src/share/classes/java/util/logging/Logger.java index a7f0cc2cd4a..1393ba2aa0d 100644 --- a/jdk/src/share/classes/java/util/logging/Logger.java +++ b/jdk/src/share/classes/java/util/logging/Logger.java @@ -245,14 +245,26 @@ public class Logger { // In order to finish the initialization of the global logger, we // will therefore call LogManager.getLogManager() here. // - // Care must be taken *not* to call Logger.getGlobal() in - // LogManager static initializers in order to avoid such - // deadlocks. - // - if (global != null && global.manager == null) { - // Complete initialization of the global Logger. - global.manager = LogManager.getLogManager(); - } + // To prevent race conditions we also need to call + // LogManager.getLogManager() unconditionally here. + // Indeed we cannot rely on the observed value of global.manager, + // because global.manager will become not null somewhere during + // the initialization of LogManager. + // If two threads are calling getGlobal() concurrently, one thread + // will see global.manager null and call LogManager.getLogManager(), + // but the other thread could come in at a time when global.manager + // is already set although ensureLogManagerInitialized is not finished + // yet... + // Calling LogManager.getLogManager() unconditionally will fix that. + + LogManager.getLogManager(); + + // Now the global LogManager should be initialized, + // and the global logger should have been added to + // it, unless we were called within the constructor of a LogManager + // subclass installed as LogManager, in which case global.manager + // would still be null, and global will be lazily initialized later on. + return global; } @@ -298,11 +310,11 @@ public class Logger { * no corresponding resource can be found. */ protected Logger(String name, String resourceBundleName) { - this(name, resourceBundleName, null); + this(name, resourceBundleName, null, LogManager.getLogManager()); } - Logger(String name, String resourceBundleName, Class caller) { - this.manager = LogManager.getLogManager(); + Logger(String name, String resourceBundleName, Class caller, LogManager manager) { + this.manager = manager; setupResourceInfo(resourceBundleName, caller); this.name = name; levelValue = Level.INFO.intValue(); @@ -332,8 +344,8 @@ public class Logger { levelValue = Level.INFO.intValue(); } - // It is called from the LogManager. to complete - // initialization of the global Logger. + // It is called from LoggerContext.addLocalLogger() when the logger + // is actually added to a LogManager. void setLogManager(LogManager manager) { this.manager = manager; } @@ -558,7 +570,7 @@ public class Logger { // cleanup some Loggers that have been GC'ed manager.drainLoggerRefQueueBounded(); Logger result = new Logger(null, resourceBundleName, - Reflection.getCallerClass()); + Reflection.getCallerClass(), manager); result.anonymous = true; Logger root = manager.getLogger(""); result.doSetParent(root); @@ -1798,7 +1810,7 @@ public class Logger { if (parent == null) { throw new NullPointerException(); } - manager.checkPermission(); + checkPermission(); doSetParent(parent); } diff --git a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java index dd901ed5f92..4c6b39b0acd 100644 --- a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java +++ b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java @@ -57,6 +57,12 @@ public class TestGetGlobal { } public static void main(String... args) { + final String manager = System.getProperty("java.util.logging.manager", null); + + final String description = "TestGetGlobal" + + (System.getSecurityManager() == null ? " " : + " -Djava.security.manager ") + + (manager == null ? "" : "-Djava.util.logging.manager=" + manager); Logger.global.info(messages[0]); // at this point LogManager is not // initialized yet, so this message should not appear. @@ -67,7 +73,9 @@ public class TestGetGlobal { final List expected = Arrays.asList(Arrays.copyOfRange(messages, 1, messages.length)); if (!testgetglobal.HandlerImpl.received.equals(expected)) { - throw new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected); + System.err.println("Test case failed: " + description); + throw new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected + + "\n\t"+description); } } } diff --git a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java index 4ef38ce3611..e3f9d1d8872 100644 --- a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java +++ b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java @@ -22,17 +22,18 @@ */ import java.util.Arrays; import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; /** * @test - * @bug 7184195 - * @summary checks that java.util.logging.Logger.getGlobal().info() logs without configuration + * @bug 7184195 8021003 + * @summary Test that the global logger can log with no configuration when accessed from multiple threads. * @build TestGetGlobalConcurrent testgetglobal.HandlerImpl testgetglobal.LogManagerImpl1 testgetglobal.LogManagerImpl2 testgetglobal.LogManagerImpl3 testgetglobal.BadLogManagerImpl testgetglobal.DummyLogManagerImpl * @run main/othervm/timeout=10 TestGetGlobalConcurrent * @run main/othervm/timeout=10/policy=policy -Djava.security.manager TestGetGlobalConcurrent - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl TestGetGlobalConcurrent + * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalConcurrent + * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalConcurrent * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalConcurrent @@ -69,7 +70,6 @@ public class TestGetGlobalConcurrent { // initialize the LogManager - and thus this message should appear. Logger.global.info(messages[i+1]); // Now that the LogManager is // initialized, this message should appear too. - final List expected = Arrays.asList(Arrays.copyOfRange(messages, i, i+2)); if (!testgetglobal.HandlerImpl.received.containsAll(expected)) { fail(new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected)); @@ -82,7 +82,6 @@ public class TestGetGlobalConcurrent { // initialize the LogManager - and thus this message should appear. Logger.global.info(messages[i+1]); // Now that the LogManager is // initialized, this message should appear too. - final List expected = Arrays.asList(Arrays.copyOfRange(messages, i, i+2)); if (!testgetglobal.HandlerImpl.received.containsAll(expected)) { fail(new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected)); @@ -96,7 +95,6 @@ public class TestGetGlobalConcurrent { // initialize the LogManager - and thus this message should appear. Logger.global.info(messages[i+1]); // Now that the LogManager is // initialized, this message should appear too. - final List expected = Arrays.asList(Arrays.copyOfRange(messages, i, i+2)); if (!testgetglobal.HandlerImpl.received.containsAll(expected)) { fail(new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected)); @@ -150,8 +148,17 @@ public class TestGetGlobalConcurrent { public void run() { test4(); } } + static String description = "Unknown"; + public static void main(String... args) throws Exception { + final String manager = System.getProperty("java.util.logging.manager", null); + + description = "TestGetGlobalConcurrent" + + (System.getSecurityManager() == null ? " " : + " -Djava.security.manager ") + + (manager == null ? "" : "-Djava.util.logging.manager=" + manager); + final Thread t1 = new Thread(new WaitAndRun(new Run1()), "test1"); final Thread t2 = new Thread(new WaitAndRun(new Run2()), "test2"); final Thread t3 = new Thread(new WaitAndRun(new Run3()), "test3"); @@ -169,14 +176,13 @@ public class TestGetGlobalConcurrent { final List expected = Arrays.asList(Arrays.copyOfRange(messages, 1, 3)); if (!testgetglobal.HandlerImpl.received.containsAll(expected)) { - throw new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected); + fail(new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected)); } - t1.join(); t2.join(); t3.join(); t4.join(); if (failed != null) { - throw new Error("Test failed.", failed); + throw new Error("Test failed: "+description, failed); } System.out.println("Test passed"); diff --git a/jdk/test/java/util/logging/Logger/getGlobal/policy b/jdk/test/java/util/logging/Logger/getGlobal/policy index bcb7cde0da3..fad24d0b814 100644 --- a/jdk/test/java/util/logging/Logger/getGlobal/policy +++ b/jdk/test/java/util/logging/Logger/getGlobal/policy @@ -1,6 +1,7 @@ grant { permission java.util.PropertyPermission "java.util.logging.config.file", "write"; permission java.util.PropertyPermission "test.src", "read"; + permission java.util.PropertyPermission "java.util.logging.manager", "read"; permission java.lang.RuntimePermission "setContextClassLoader"; permission java.lang.RuntimePermission "shutdownHooks"; permission java.util.logging.LoggingPermission "control"; diff --git a/jdk/test/java/util/logging/ParentLoggersTest.java b/jdk/test/java/util/logging/ParentLoggersTest.java index 72d5ddadc0f..a5070a375e3 100644 --- a/jdk/test/java/util/logging/ParentLoggersTest.java +++ b/jdk/test/java/util/logging/ParentLoggersTest.java @@ -29,7 +29,7 @@ * @author ss45998 * * @build ParentLoggersTest - * @run main/othervm ParentLoggersTest + * @run main ParentLoggersTest */ /* diff --git a/jdk/test/java/util/logging/TestAppletLoggerContext.java b/jdk/test/java/util/logging/TestAppletLoggerContext.java index 82c39381fe8..3db67543245 100644 --- a/jdk/test/java/util/logging/TestAppletLoggerContext.java +++ b/jdk/test/java/util/logging/TestAppletLoggerContext.java @@ -38,7 +38,7 @@ import sun.misc.SharedSecrets; /* * @test - * @bug 8017174 8010727 + * @bug 8017174 8010727 8019945 * @summary NPE when using Logger.getAnonymousLogger or * LogManager.getLogManager().getLogger * @@ -432,45 +432,36 @@ public class TestAppletLoggerContext { assertNull(manager.getLogger("")); assertNull(manager.getLogger("")); - Bridge.changeContext(); + for (int j = 0; j<3; j++) { + Bridge.changeContext(); - // this is not a supported configuration: - // We are in an applet context with several log managers. - // We however need to check our assumptions... + // this is not a supported configuration: + // We are in an applet context with several log managers. + // We however need to check our assumptions... - // Applet context => root logger and global logger are not null. - // root == LogManager.getLogManager().rootLogger - // global == Logger.global + // Applet context => root logger and global logger should also be null. - Logger logger3 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger3b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger3); - assertNotNull(logger3b); - Logger expected = (System.getSecurityManager() != null - ? Logger.getGlobal() - : global); - assertEquals(logger3, expected); // in applet context, we will not see - // the LogManager's custom global logger added above... - assertEquals(logger3b, expected); // in applet context, we will not see - // the LogManager's custom global logger added above... - Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global2); // adding a global logger will not work in applet context - // we will always get back the global logger. - // this could be considered as a bug... - Logger logger4 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger4b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger4); - assertNotNull(logger4b); - assertEquals(logger4, expected); // adding a global logger will not work in applet context - assertEquals(logger4b, expected); // adding a global logger will not work in applet context + Logger expected = (System.getSecurityManager() == null ? global : null); + Logger logger3 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); + Logger logger3b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); + assertEquals(expected, logger3); + assertEquals(expected, logger3b); + Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); + manager.addLogger(global2); + Logger logger4 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); + Logger logger4b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); + assertNotNull(logger4); + assertNotNull(logger4b); + expected = (System.getSecurityManager() == null ? global : global2);; + assertEquals(logger4, expected); + assertEquals(logger4b, expected); - Logger logger5 = manager.getLogger(""); - Logger logger5b = manager.getLogger(""); - Logger expectedRoot = (System.getSecurityManager() != null - ? LogManager.getLogManager().getLogger("") - : null); - assertEquals(logger5, expectedRoot); - assertEquals(logger5b, expectedRoot); + Logger logger5 = manager.getLogger(""); + Logger logger5b = manager.getLogger(""); + Logger expectedRoot = null; + assertEquals(logger5, expectedRoot); + assertEquals(logger5b, expectedRoot); + } } } @@ -511,57 +502,53 @@ public class TestAppletLoggerContext { assertEquals(logger4, root); assertEquals(logger4b, root); - Bridge.changeContext(); + for (int j = 0 ; j < 3 ; j++) { + Bridge.changeContext(); - // this is not a supported configuration: - // We are in an applet context with several log managers. - // We haowever need to check our assumptions... + // this is not a supported configuration: + // We are in an applet context with several log managers. + // We however need to check our assumptions... - // Applet context => root logger and global logger are not null. - // root == LogManager.getLogManager().rootLogger - // global == Logger.global + // Applet context => root logger and global logger should also be null. - Logger logger5 = manager.getLogger(""); - Logger logger5b = manager.getLogger(""); - Logger expectedRoot = (System.getSecurityManager() != null - ? LogManager.getLogManager().getLogger("") - : root); + Logger logger5 = manager.getLogger(""); + Logger logger5b = manager.getLogger(""); + Logger expectedRoot = (System.getSecurityManager() == null ? root : null); + assertEquals(logger5, expectedRoot); + assertEquals(logger5b, expectedRoot); - assertNotNull(logger5); - assertNotNull(logger5b); - assertEquals(logger5, expectedRoot); - assertEquals(logger5b, expectedRoot); - if (System.getSecurityManager() != null) { - assertNotEquals(logger5, root); - assertNotEquals(logger5b, root); + if (System.getSecurityManager() != null) { + assertNull(manager.getLogger(Logger.GLOBAL_LOGGER_NAME)); + } else { + assertEquals(global, manager.getLogger(Logger.GLOBAL_LOGGER_NAME)); + } + + Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); + manager.addLogger(global2); + Logger logger6 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); + Logger logger6b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); + Logger expectedGlobal = (System.getSecurityManager() == null ? global : global2); + + assertNotNull(logger6); + assertNotNull(logger6b); + assertEquals(logger6, expectedGlobal); + assertEquals(logger6b, expectedGlobal); + if (System.getSecurityManager() != null) { + assertNull(manager.getLogger("")); + } else { + assertEquals(root, manager.getLogger("")); + } + + Logger root2 = new Bridge.CustomLogger(""); + manager.addLogger(root2); + expectedRoot = (System.getSecurityManager() == null ? root : root2); + Logger logger7 = manager.getLogger(""); + Logger logger7b = manager.getLogger(""); + assertNotNull(logger7); + assertNotNull(logger7b); + assertEquals(logger7, expectedRoot); + assertEquals(logger7b, expectedRoot); } - - Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global2); // adding a global logger will not work in applet context - // we will always get back the global logger. - // this could be considered as a bug... - Logger logger6 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger6b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger expectedGlobal = (System.getSecurityManager() != null - ? Logger.getGlobal() - : global); - assertNotNull(logger6); - assertNotNull(logger6b); - assertEquals(logger6, expectedGlobal); // adding a global logger will not work in applet context - assertEquals(logger6b, expectedGlobal); // adding a global logger will not work in applet context - - Logger root2 = new Bridge.CustomLogger(""); - manager.addLogger(root2); // adding a root logger will not work in applet context - // we will always get back the default manager's root logger. - // this could be considered as a bug... - Logger logger7 = manager.getLogger(""); - Logger logger7b = manager.getLogger(""); - assertNotNull(logger7); - assertNotNull(logger7b); - assertEquals(logger7, expectedRoot); // adding a global logger will not work in applet context - assertEquals(logger7b, expectedRoot); // adding a global logger will not work in applet context - assertNotEquals(logger7, root2); - assertNotEquals(logger7b, root2); } } From 92c43dcb6a22965b79e8617764056f5c9d6faff5 Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Fri, 6 Sep 2013 15:00:59 +0100 Subject: [PATCH 0235/1294] 8023326: [TESTBUG] java/net/CookieHandler/LocalHostCookie.java misplaced try/finally Amended test to be more robust to set of potential exceptions thrown Reviewed-by: chegar, khazra --- jdk/test/java/net/CookieHandler/LocalHostCookie.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jdk/test/java/net/CookieHandler/LocalHostCookie.java b/jdk/test/java/net/CookieHandler/LocalHostCookie.java index ac8d61622ef..56db947126e 100644 --- a/jdk/test/java/net/CookieHandler/LocalHostCookie.java +++ b/jdk/test/java/net/CookieHandler/LocalHostCookie.java @@ -72,7 +72,9 @@ public class LocalHostCookie { } } } finally { - s.stopServer(); + if (s != null) { + s.stopServer(); + } } } @@ -96,7 +98,9 @@ public class LocalHostCookie { } public void stopServer() { - server.stop(0); + if (server != null) { + server.stop(0); + } } } From 1c2a7eea85ea261102687190d6b2e92c560770b8 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Fri, 6 Sep 2013 08:42:42 -0700 Subject: [PATCH 0236/1294] 8022335: Native stack walk while generating hs_err does not work on Windows x64 Use WinDbg API StackWalk64() Reviewed-by: zgu, dholmes --- hotspot/src/os/windows/vm/decoder_windows.cpp | 91 +++++++++++++++++- hotspot/src/os/windows/vm/decoder_windows.hpp | 41 +++++++++ .../os_cpu/windows_x86/vm/os_windows_x86.cpp | 92 +++++++++++++++++++ .../os_cpu/windows_x86/vm/os_windows_x86.hpp | 6 ++ hotspot/src/share/vm/runtime/frame.cpp | 2 +- hotspot/src/share/vm/runtime/frame.hpp | 1 + hotspot/src/share/vm/runtime/os.hpp | 8 ++ hotspot/src/share/vm/utilities/decoder.cpp | 18 +++- hotspot/src/share/vm/utilities/decoder.hpp | 14 +++ hotspot/src/share/vm/utilities/vmError.cpp | 5 + hotspot/src/share/vm/utilities/vmError.hpp | 4 + 11 files changed, 275 insertions(+), 7 deletions(-) diff --git a/hotspot/src/os/windows/vm/decoder_windows.cpp b/hotspot/src/os/windows/vm/decoder_windows.cpp index 326d3288020..b99adaa9f4f 100644 --- a/hotspot/src/os/windows/vm/decoder_windows.cpp +++ b/hotspot/src/os/windows/vm/decoder_windows.cpp @@ -32,7 +32,11 @@ WindowsDecoder::WindowsDecoder() { _can_decode_in_vm = false; _pfnSymGetSymFromAddr64 = NULL; _pfnUndecorateSymbolName = NULL; - +#ifdef AMD64 + _pfnStackWalk64 = NULL; + _pfnSymFunctionTableAccess64 = NULL; + _pfnSymGetModuleBase64 = NULL; +#endif _decoder_status = no_error; initialize(); } @@ -53,14 +57,24 @@ void WindowsDecoder::initialize() { _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)::GetProcAddress(handle, "UnDecorateSymbolName"); if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) { - _pfnSymGetSymFromAddr64 = NULL; - _pfnUndecorateSymbolName = NULL; - ::FreeLibrary(handle); - _dbghelp_handle = NULL; + uninitialize(); _decoder_status = helper_func_error; return; } +#ifdef AMD64 + _pfnStackWalk64 = (pfn_StackWalk64)::GetProcAddress(handle, "StackWalk64"); + _pfnSymFunctionTableAccess64 = (pfn_SymFunctionTableAccess64)::GetProcAddress(handle, "SymFunctionTableAccess64"); + _pfnSymGetModuleBase64 = (pfn_SymGetModuleBase64)::GetProcAddress(handle, "SymGetModuleBase64"); + if (_pfnStackWalk64 == NULL || _pfnSymFunctionTableAccess64 == NULL || _pfnSymGetModuleBase64 == NULL) { + // We can't call StackWalk64 to walk the stack, but we are still + // able to decode the symbols. Let's limp on. + _pfnStackWalk64 = NULL; + _pfnSymFunctionTableAccess64 = NULL; + _pfnSymGetModuleBase64 = NULL; + } +#endif + HANDLE hProcess = ::GetCurrentProcess(); _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS); if (!_pfnSymInitialize(hProcess, NULL, TRUE)) { @@ -156,6 +170,11 @@ void WindowsDecoder::initialize() { void WindowsDecoder::uninitialize() { _pfnSymGetSymFromAddr64 = NULL; _pfnUndecorateSymbolName = NULL; +#ifdef AMD64 + _pfnStackWalk64 = NULL; + _pfnSymFunctionTableAccess64 = NULL; + _pfnSymGetModuleBase64 = NULL; +#endif if (_dbghelp_handle != NULL) { ::FreeLibrary(_dbghelp_handle); } @@ -195,3 +214,65 @@ bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) { _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE); } +#ifdef AMD64 +BOOL WindowsDbgHelp::StackWalk64(DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress) { + DecoderLocker locker; + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); + + if (!wd->has_error() && wd->_pfnStackWalk64) { + return wd->_pfnStackWalk64(MachineType, + hProcess, + hThread, + StackFrame, + ContextRecord, + ReadMemoryRoutine, + FunctionTableAccessRoutine, + GetModuleBaseRoutine, + TranslateAddress); + } else { + return false; + } +} + +PVOID WindowsDbgHelp::SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) { + DecoderLocker locker; + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); + + if (!wd->has_error() && wd->_pfnSymFunctionTableAccess64) { + return wd->_pfnSymFunctionTableAccess64(hProcess, AddrBase); + } else { + return NULL; + } +} + +pfn_SymFunctionTableAccess64 WindowsDbgHelp::pfnSymFunctionTableAccess64() { + DecoderLocker locker; + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); + + if (!wd->has_error()) { + return wd->_pfnSymFunctionTableAccess64; + } else { + return NULL; + } +} + +pfn_SymGetModuleBase64 WindowsDbgHelp::pfnSymGetModuleBase64() { + DecoderLocker locker; + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); + + if (!wd->has_error()) { + return wd->_pfnSymGetModuleBase64; + } else { + return NULL; + } +} + +#endif // AMD64 diff --git a/hotspot/src/os/windows/vm/decoder_windows.hpp b/hotspot/src/os/windows/vm/decoder_windows.hpp index 3008ee79136..2555e8c9b79 100644 --- a/hotspot/src/os/windows/vm/decoder_windows.hpp +++ b/hotspot/src/os/windows/vm/decoder_windows.hpp @@ -38,6 +38,20 @@ typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWOR typedef BOOL (WINAPI *pfn_SymSetSearchPath)(HANDLE, PCTSTR); typedef BOOL (WINAPI *pfn_SymGetSearchPath)(HANDLE, PTSTR, int); +#ifdef AMD64 +typedef BOOL (WINAPI *pfn_StackWalk64)(DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); +typedef PVOID (WINAPI *pfn_SymFunctionTableAccess64)(HANDLE hProcess, DWORD64 AddrBase); +typedef DWORD64 (WINAPI *pfn_SymGetModuleBase64)(HANDLE hProcess, DWORD64 dwAddr); +#endif + class WindowsDecoder : public AbstractDecoder { public: @@ -61,7 +75,34 @@ private: bool _can_decode_in_vm; pfn_SymGetSymFromAddr64 _pfnSymGetSymFromAddr64; pfn_UndecorateSymbolName _pfnUndecorateSymbolName; +#ifdef AMD64 + pfn_StackWalk64 _pfnStackWalk64; + pfn_SymFunctionTableAccess64 _pfnSymFunctionTableAccess64; + pfn_SymGetModuleBase64 _pfnSymGetModuleBase64; + + friend class WindowsDbgHelp; +#endif }; +#ifdef AMD64 +// TODO: refactor and move the handling of dbghelp.dll outside of Decoder +class WindowsDbgHelp : public Decoder { +public: + static BOOL StackWalk64(DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); + static PVOID SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase); + + static pfn_SymFunctionTableAccess64 pfnSymFunctionTableAccess64(); + static pfn_SymGetModuleBase64 pfnSymGetModuleBase64(); +}; +#endif + #endif // OS_WINDOWS_VM_DECODER_WINDOWS_HPP diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp index a0f2a7680be..09735dae0c6 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp @@ -29,6 +29,7 @@ #include "classfile/vmSymbols.hpp" #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" +#include "decoder_windows.hpp" #include "interpreter/interpreter.hpp" #include "jvm_windows.h" #include "memory/allocation.inline.hpp" @@ -327,6 +328,94 @@ add_ptr_func_t* os::atomic_add_ptr_func = os::atomic_add_ptr_bootstrap cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap; +#ifdef AMD64 +/* + * Windows/x64 does not use stack frames the way expected by Java: + * [1] in most cases, there is no frame pointer. All locals are addressed via RSP + * [2] in rare cases, when alloca() is used, a frame pointer is used, but this may + * not be RBP. + * See http://msdn.microsoft.com/en-us/library/ew5tede7.aspx + * + * So it's not possible to print the native stack using the + * while (...) {... fr = os::get_sender_for_C_frame(&fr); } + * loop in vmError.cpp. We need to roll our own loop. + */ +bool os::platform_print_native_stack(outputStream* st, void* context, + char *buf, int buf_size) +{ + CONTEXT ctx; + if (context != NULL) { + memcpy(&ctx, context, sizeof(ctx)); + } else { + RtlCaptureContext(&ctx); + } + + st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"); + + STACKFRAME stk; + memset(&stk, 0, sizeof(stk)); + stk.AddrStack.Offset = ctx.Rsp; + stk.AddrStack.Mode = AddrModeFlat; + stk.AddrFrame.Offset = ctx.Rbp; + stk.AddrFrame.Mode = AddrModeFlat; + stk.AddrPC.Offset = ctx.Rip; + stk.AddrPC.Mode = AddrModeFlat; + + int count = 0; + address lastpc = 0; + while (count++ < StackPrintLimit) { + intptr_t* sp = (intptr_t*)stk.AddrStack.Offset; + intptr_t* fp = (intptr_t*)stk.AddrFrame.Offset; // NOT necessarily the same as ctx.Rbp! + address pc = (address)stk.AddrPC.Offset; + + if (pc != NULL && sp != NULL && fp != NULL) { + if (count == 2 && lastpc == pc) { + // Skip it -- StackWalk64() may return the same PC + // (but different SP) on the first try. + } else { + // Don't try to create a frame(sp, fp, pc) -- on WinX64, stk.AddrFrame + // may not contain what Java expects, and may cause the frame() constructor + // to crash. Let's just print out the symbolic address. + frame::print_C_frame(st, buf, buf_size, pc); + st->cr(); + } + lastpc = pc; + } else { + break; + } + + PVOID p = WindowsDbgHelp::SymFunctionTableAccess64(GetCurrentProcess(), stk.AddrPC.Offset); + if (!p) { + // StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash. + break; + } + + BOOL result = WindowsDbgHelp::StackWalk64( + IMAGE_FILE_MACHINE_AMD64, // __in DWORD MachineType, + GetCurrentProcess(), // __in HANDLE hProcess, + GetCurrentThread(), // __in HANDLE hThread, + &stk, // __inout LP STACKFRAME64 StackFrame, + &ctx, // __inout PVOID ContextRecord, + NULL, // __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + WindowsDbgHelp::pfnSymFunctionTableAccess64(), + // __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + WindowsDbgHelp::pfnSymGetModuleBase64(), + // __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + NULL); // __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress + + if (!result) { + break; + } + } + if (count > StackPrintLimit) { + st->print_cr("......"); + } + st->cr(); + + return true; +} +#endif // AMD64 + ExtendedPC os::fetch_frame_from_context(void* ucVoid, intptr_t** ret_sp, intptr_t** ret_fp) { @@ -401,6 +490,9 @@ frame os::current_frame() { StubRoutines::x86::get_previous_fp_entry()); if (func == NULL) return frame(); intptr_t* fp = (*func)(); + if (fp == NULL) { + return frame(); + } #else intptr_t* fp = _get_previous_fp(); #endif // AMD64 diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp index 41814b6c61b..22ffeb5dc34 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp @@ -62,4 +62,10 @@ static bool register_code_area(char *low, char *high); +#ifdef AMD64 +#define PLATFORM_PRINT_NATIVE_STACK 1 +static bool platform_print_native_stack(outputStream* st, void* context, + char *buf, int buf_size); +#endif + #endif // OS_CPU_WINDOWS_X86_VM_OS_WINDOWS_X86_HPP diff --git a/hotspot/src/share/vm/runtime/frame.cpp b/hotspot/src/share/vm/runtime/frame.cpp index 6f5724323cd..4fae1c8fe11 100644 --- a/hotspot/src/share/vm/runtime/frame.cpp +++ b/hotspot/src/share/vm/runtime/frame.cpp @@ -652,7 +652,7 @@ void frame::interpreter_frame_print_on(outputStream* st) const { // Return whether the frame is in the VM or os indicating a Hotspot problem. // Otherwise, it's likely a bug in the native library that the Java code calls, // hopefully indicating where to submit bugs. -static void print_C_frame(outputStream* st, char* buf, int buflen, address pc) { +void frame::print_C_frame(outputStream* st, char* buf, int buflen, address pc) { // C/C++ frame bool in_vm = os::address_is_in_vm(pc); st->print(in_vm ? "V" : "C"); diff --git a/hotspot/src/share/vm/runtime/frame.hpp b/hotspot/src/share/vm/runtime/frame.hpp index 096b467b5f8..78292c662ec 100644 --- a/hotspot/src/share/vm/runtime/frame.hpp +++ b/hotspot/src/share/vm/runtime/frame.hpp @@ -406,6 +406,7 @@ class frame VALUE_OBJ_CLASS_SPEC { void print_on(outputStream* st) const; void interpreter_frame_print_on(outputStream* st) const; void print_on_error(outputStream* st, char* buf, int buflen, bool verbose = false) const; + static void print_C_frame(outputStream* st, char* buf, int buflen, address pc); // Add annotated descriptions of memory locations belonging to this frame to values void describe(FrameValues& values, int frame_no); diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index e43d68981cb..4ca0d32607b 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -795,6 +795,14 @@ class os: AllStatic { #endif public: +#ifndef PLATFORM_PRINT_NATIVE_STACK + // No platform-specific code for printing the native stack. + static bool platform_print_native_stack(outputStream* st, void* context, + char *buf, int buf_size) { + return false; + } +#endif + // debugging support (mostly used by debug.cpp but also fatal error handler) static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address diff --git a/hotspot/src/share/vm/utilities/decoder.cpp b/hotspot/src/share/vm/utilities/decoder.cpp index 5489fe6fefb..3fc934b4f32 100644 --- a/hotspot/src/share/vm/utilities/decoder.cpp +++ b/hotspot/src/share/vm/utilities/decoder.cpp @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "prims/jvm.h" -#include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" #include "utilities/decoder.hpp" #include "utilities/vmError.hpp" @@ -80,6 +79,23 @@ AbstractDecoder* Decoder::create_decoder() { return decoder; } +inline bool DecoderLocker::is_first_error_thread() { + return (os::current_thread_id() == VMError::get_first_error_tid()); +} + +DecoderLocker::DecoderLocker() : + MutexLockerEx(DecoderLocker::is_first_error_thread() ? + NULL : Decoder::shared_decoder_lock(), true) { + _decoder = is_first_error_thread() ? + Decoder::get_error_handler_instance() : Decoder::get_shared_instance(); + assert(_decoder != NULL, "null decoder"); +} + +Mutex* Decoder::shared_decoder_lock() { + assert(_shared_decoder_lock != NULL, "Just check"); + return _shared_decoder_lock; +} + bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) { assert(_shared_decoder_lock != NULL, "Just check"); bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid; diff --git a/hotspot/src/share/vm/utilities/decoder.hpp b/hotspot/src/share/vm/utilities/decoder.hpp index 0d2af80986c..0cc880f1915 100644 --- a/hotspot/src/share/vm/utilities/decoder.hpp +++ b/hotspot/src/share/vm/utilities/decoder.hpp @@ -28,6 +28,7 @@ #include "memory/allocation.hpp" #include "runtime/mutex.hpp" +#include "runtime/mutexLocker.hpp" class AbstractDecoder : public CHeapObj { public: @@ -124,6 +125,19 @@ private: protected: static Mutex* _shared_decoder_lock; + static Mutex* shared_decoder_lock(); + + friend class DecoderLocker; +}; + +class DecoderLocker : public MutexLockerEx { + AbstractDecoder* _decoder; + inline bool is_first_error_thread(); +public: + DecoderLocker(); + AbstractDecoder* decoder() { + return _decoder; + } }; #endif // SHARE_VM_UTILITIES_DECODER_HPP diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp index b07404dc9b7..79769aeb3bc 100644 --- a/hotspot/src/share/vm/utilities/vmError.cpp +++ b/hotspot/src/share/vm/utilities/vmError.cpp @@ -574,6 +574,10 @@ void VMError::report(outputStream* st) { STEP(120, "(printing native stack)" ) if (_verbose) { + if (os::platform_print_native_stack(st, _context, buf, sizeof(buf))) { + // We have printed the native stack in platform-specific code + // Windows/x64 needs special handling. + } else { frame fr = _context ? os::fetch_frame_from_context(_context) : os::current_frame(); @@ -604,6 +608,7 @@ void VMError::report(outputStream* st) { st->cr(); } } + } STEP(130, "(printing Java stack)" ) diff --git a/hotspot/src/share/vm/utilities/vmError.hpp b/hotspot/src/share/vm/utilities/vmError.hpp index 1b1608bdc90..299cfaa6f3d 100644 --- a/hotspot/src/share/vm/utilities/vmError.hpp +++ b/hotspot/src/share/vm/utilities/vmError.hpp @@ -136,6 +136,10 @@ public: // check to see if fatal error reporting is in progress static bool fatal_error_in_progress() { return first_error != NULL; } + + static jlong get_first_error_tid() { + return first_error_tid; + } }; #endif // SHARE_VM_UTILITIES_VMERROR_HPP From 23d61e9b454d1b6d27a2337193f54831f36a62d1 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Fri, 6 Sep 2013 12:04:18 -0400 Subject: [PATCH 0237/1294] 8023362: Don't allow soft-fail behavior if OCSP responder returns "unauthorized" Reviewed-by: vinnie, xuelei --- .../security/cert/PKIXRevocationChecker.java | 3 +- .../provider/certpath/OCSPResponse.java | 2 +- .../OcspUnauthorized.java | 103 ++++++++++++++++++ 3 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 jdk/test/java/security/cert/PKIXRevocationChecker/OcspUnauthorized.java diff --git a/jdk/src/share/classes/java/security/cert/PKIXRevocationChecker.java b/jdk/src/share/classes/java/security/cert/PKIXRevocationChecker.java index d0e2ee02986..b667397c8e5 100644 --- a/jdk/src/share/classes/java/security/cert/PKIXRevocationChecker.java +++ b/jdk/src/share/classes/java/security/cert/PKIXRevocationChecker.java @@ -300,8 +300,7 @@ public abstract class PKIXRevocationChecker extends PKIXCertPathChecker { *
  • The CRL or OCSP response cannot be obtained because of a * network error. *
  • The OCSP responder returns one of the following errors - * specified in section 2.3 of RFC 2560: internalError, tryLater, - * or unauthorized. + * specified in section 2.3 of RFC 2560: internalError or tryLater. *
    * Note that these conditions apply to both OCSP and CRLs, and unless * the {@code NO_FALLBACK} option is set, the revocation check is diff --git a/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java b/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java index 5580dc70b88..955d63b57f3 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java @@ -385,12 +385,12 @@ public final class OCSPResponse { switch (responseStatus) { case SUCCESSFUL: break; - case UNAUTHORIZED: case TRY_LATER: case INTERNAL_ERROR: throw new CertPathValidatorException( "OCSP response error: " + responseStatus, null, null, -1, BasicReason.UNDETERMINED_REVOCATION_STATUS); + case UNAUTHORIZED: default: throw new CertPathValidatorException("OCSP response error: " + responseStatus); diff --git a/jdk/test/java/security/cert/PKIXRevocationChecker/OcspUnauthorized.java b/jdk/test/java/security/cert/PKIXRevocationChecker/OcspUnauthorized.java new file mode 100644 index 00000000000..83f19248959 --- /dev/null +++ b/jdk/test/java/security/cert/PKIXRevocationChecker/OcspUnauthorized.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013, 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 8023362 + * @summary Make sure Ocsp UNAUTHORIZED response is treated as failure when + * SOFT_FAIL option is set + */ + +import java.io.ByteArrayInputStream; +import java.security.cert.*; +import java.security.cert.PKIXRevocationChecker.Option; +import java.util.Base64; +import java.util.Collections; +import java.util.EnumSet; + +public class OcspUnauthorized { + + private final static String OCSP_RESPONSE = "MAMKAQY="; + + private final static String EE_CERT = + "MIICADCCAWmgAwIBAgIEOvxUmjANBgkqhkiG9w0BAQQFADAqMQswCQYDVQQGEwJ1czE" + + "MMAoGA1UEChMDc3VuMQ0wCwYDVQQLEwRsYWJzMB4XDTAxMDUxNDIwNDQyMVoXDTI4MD" + + "kyOTIwNDQyMVowOTELMAkGA1UEBhMCdXMxDDAKBgNVBAoTA3N1bjENMAsGA1UECxMEb" + + "GFiczENMAsGA1UECxMEaXNyZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4MmP" + + "GDriFJ+OhDlTuLpHzPy0nawDKyIYUJPZmU9M/pCAUbZewAOyAXGPYVU1og2ZiO9tWBi" + + "ZBeJGoFHEkkhfeqSVb2PsRckiXvPZ3AiSVmdX0uD/a963abmhRMYB1gDO2+jBe3F/DU" + + "pHwpyThchy8tYUMh7Gr7+m/8FwZbdbSpMCAwEAAaMkMCIwDwYDVR0PAQH/BAUDAwekA" + + "DAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAME3fmXvES0FVDXSD1iC" + + "TJLf86kUy3H+uMG7h5pOQmcfF1o9PVWlNByVf4r2b4GRgftPQ3Ao0SAvq1aSkW7YpkN" + + "pcartYqNk2E5brPajOC0v+Pkxf/g/pkRTT6Zp+9erGQF4Ta62q0iwOyc3FovSbh0Ph2" + + "WidZRP4qUG5I6JmGkI"; + + private final static String TRUST_ANCHOR = + "MIICIzCCAYygAwIBAgIEOvxT7DANBgkqhkiG9w0BAQQFADAbMQswCQYDVQQGEwJ1czE" + + "MMAoGA1UEChMDc3VuMB4XDTAxMDUxNDIxMDQyOVoXDTI4MDkyOTIxMDQyOVowKjELMA" + + "kGA1UEBhMCdXMxDDAKBgNVBAoTA3N1bjENMAsGA1UECxMEbGFiczCBnzANBgkqhkiG9" + + "w0BAQEFAAOBjQAwgYkCgYEA0/16V87rhznCM0y7IqyGcfQBentG+PglA+1hiqCuQY/A" + + "jFiDKr5N+LpcfU28P41E4M+DSDrMIEe4JchRcXeJY6aIVhpOveVV9mgtBaEKlsScrIJ" + + "zmVqM07PG9JENg2FibECnB5TNUSfVbFKfvtAqaZ7Pc971oZVoIePBWnfKV9kCAwEAAa" + + "NlMGMwPwYDVR0eAQH/BDUwM6AxMC+kKjELMAkGA1UEBhMCdXMxDDAKBgNVBAoTA3N1b" + + "jENMAsGA1UECxMEbGFic4ABAzAPBgNVHQ8BAf8EBQMDB6QAMA8GA1UdEwEB/wQFMAMB" + + "Af8wDQYJKoZIhvcNAQEEBQADgYEAfJ5HWd7K5PmX0+Vbsux4SYhoaejDwwgS43BRNa+" + + "AmFq9LIZ+ZcjBMVte8Y3sJF+nz9+1qBaUhNhbaECCqsgmWSwvI+0kUzJXL89k9AdQ8m" + + "AYf6CB6+kaZQBgrdSdqSGz3tCVa2MIK8wmb0ROM40oJ7vt3qSwgFi3UTltxkFfwQ0="; + + private static CertificateFactory cf; + private static Base64.Decoder base64Decoder = Base64.getDecoder(); + + public static void main(String[] args) throws Exception { + cf = CertificateFactory.getInstance("X.509"); + X509Certificate taCert = getX509Cert(TRUST_ANCHOR); + X509Certificate eeCert = getX509Cert(EE_CERT); + CertPath cp = cf.generateCertPath(Collections.singletonList(eeCert)); + + CertPathValidator cpv = CertPathValidator.getInstance("PKIX"); + PKIXRevocationChecker prc = + (PKIXRevocationChecker)cpv.getRevocationChecker(); + prc.setOptions(EnumSet.of(Option.SOFT_FAIL, Option.NO_FALLBACK)); + byte[] response = base64Decoder.decode(OCSP_RESPONSE); + + prc.setOcspResponses(Collections.singletonMap(eeCert, response)); + + TrustAnchor ta = new TrustAnchor(taCert, null); + PKIXParameters params = new PKIXParameters(Collections.singleton(ta)); + + params.addCertPathChecker(prc); + + try { + cpv.validate(cp, params); + throw new Exception("FAILED: expected CertPathValidatorException"); + } catch (CertPathValidatorException cpve) { + cpve.printStackTrace(); + } + } + + private static X509Certificate getX509Cert(String enc) throws Exception { + byte[] bytes = base64Decoder.decode(enc); + ByteArrayInputStream is = new ByteArrayInputStream(bytes); + return (X509Certificate)cf.generateCertificate(is); + } +} From eb65e048f9445bd886cc1ea2730ea21d55530b8d Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 6 Sep 2013 11:04:00 -0700 Subject: [PATCH 0238/1294] Added tag hs25-b49 for changeset 20a700f38686 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 2cb597e46a2..bc3aba45318 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -374,3 +374,4 @@ c1604d5885a6f2adc0bcea2fa142a8f6bafad2f0 hs25-b47 acac3bde66b2c22791c257a8d99611d6d08c6713 jdk8-b105 18b4798adbc42c6fa16f5ecb7d5cd3ca130754bf hs25-b48 aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106 +50794d8ac11c9579b41dec4de23b808fef9f34a1 hs25-b49 From 7e04c1775ca6ed242a472f8aa0909d5e33cf023e Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 6 Sep 2013 11:11:19 -0700 Subject: [PATCH 0239/1294] 8024258: new hotspot build - hs25-b50 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index 15223e843df..e1572121149 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=49 +HS_BUILD_NUMBER=50 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From f607953eb87ebe214f7696affeeabf92906a318a Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 6 Sep 2013 15:31:59 -0700 Subject: [PATCH 0240/1294] 8024434: problem running javadoc tests in samevm mode on Windows Reviewed-by: darcy --- .../internal/toolkit/util/PathDocFileFactory.java | 7 +++++-- .../test/tools/javadoc/api/basic/APITest.java | 15 +++++++++------ .../api/basic/GetTask_FileManagerTest.java | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java index 7990a347c18..faeec757e7a 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java @@ -34,6 +34,7 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; +import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -221,8 +222,10 @@ class PathDocFileFactory extends DocFileFactory { /** If the file is a directory, list its contents. */ public Iterable list() throws IOException { List files = new ArrayList(); - for (Path f: Files.newDirectoryStream(file)) { - files.add(new StandardDocFile(f)); + try (DirectoryStream ds = Files.newDirectoryStream(file)) { + for (Path f: ds) { + files.add(new StandardDocFile(f)); + } } return files; } diff --git a/langtools/test/tools/javadoc/api/basic/APITest.java b/langtools/test/tools/javadoc/api/basic/APITest.java index 358b6b3bc48..439d80c4a26 100644 --- a/langtools/test/tools/javadoc/api/basic/APITest.java +++ b/langtools/test/tools/javadoc/api/basic/APITest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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,6 +29,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URI; +import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; @@ -164,11 +165,13 @@ class APITest { } private void listFiles(Path dir, Set files) throws IOException { - for (Path f: Files.newDirectoryStream(dir)) { - if (Files.isDirectory(f)) - listFiles(f, files); - else if (Files.isRegularFile(f)) - files.add(f); + try (DirectoryStream ds = Files.newDirectoryStream(dir)) { + for (Path f: ds) { + if (Files.isDirectory(f)) + listFiles(f, files); + else if (Files.isRegularFile(f)) + files.add(f); + } } } diff --git a/langtools/test/tools/javadoc/api/basic/GetTask_FileManagerTest.java b/langtools/test/tools/javadoc/api/basic/GetTask_FileManagerTest.java index 4532e619f9b..d5ab604f6ac 100644 --- a/langtools/test/tools/javadoc/api/basic/GetTask_FileManagerTest.java +++ b/langtools/test/tools/javadoc/api/basic/GetTask_FileManagerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 6493690 + * @bug 6493690 8024434 * @summary javadoc should have a javax.tools.Tool service provider * @build APITest * @run main GetTask_FileManagerTest From ab579cbd5f466139fa402f5dae5512a72f5ce2a9 Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Mon, 9 Sep 2013 13:44:30 +0100 Subject: [PATCH 0241/1294] 8021372: NetworkInterface.getNetworkInterfaces() returns duplicate hardware address Amended src/windows/native/java/net/NetworkInterface_winXP.c to "properly" handle Ipv6IfIndex Reviewed-by: chegar, dsamersoff --- .../native/java/net/NetworkInterface_winXP.c | 19 ++- .../UniqueMacAddressesTest.java | 129 ++++++++++++++++++ 2 files changed, 141 insertions(+), 7 deletions(-) create mode 100644 jdk/test/java/net/NetworkInterface/UniqueMacAddressesTest.java diff --git a/jdk/src/windows/native/java/net/NetworkInterface_winXP.c b/jdk/src/windows/native/java/net/NetworkInterface_winXP.c index 1078d826afa..414f5c701d3 100644 --- a/jdk/src/windows/native/java/net/NetworkInterface_winXP.c +++ b/jdk/src/windows/native/java/net/NetworkInterface_winXP.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -82,7 +82,6 @@ static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) { IP_ADAPTER_ADDRESSES *adapterInfo; ULONG len; adapterInfo = (IP_ADAPTER_ADDRESSES *)malloc (bufsize); - if (adapterInfo == NULL) { JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure"); return -1; @@ -160,8 +159,12 @@ IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) { ptr = adapterInfo; ret = NULL; while (ptr != NULL) { - // IPv4 interface - if (ptr->Ipv6IfIndex == index) { + // in theory the IPv4 index and the IPv6 index can be the same + // where an interface is enabled for v4 and v6 + // IfIndex == 0 IPv4 not available on this interface + // Ipv6IfIndex == 0 IPv6 not available on this interface + if (((ptr->IfIndex != 0)&&(ptr->IfIndex == index)) || + ((ptr->Ipv6IfIndex !=0) && (ptr->Ipv6IfIndex == index))) { ret = (IP_ADAPTER_ADDRESSES *) malloc(sizeof(IP_ADAPTER_ADDRESSES)); if (ret == NULL) { free(adapterInfo); @@ -172,6 +175,7 @@ IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) { //copy the memory and break out of the while loop. memcpy(ret, ptr, sizeof(IP_ADAPTER_ADDRESSES)); break; + } ptr=ptr->Next; } @@ -192,7 +196,6 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP) int tun=0, net=0; *netifPP = NULL; - /* * Get the IPv4 interfaces. This information is the same * as what previous JDK versions would return. @@ -264,7 +267,7 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP) * set the index to the IPv6 index and add the * IPv6 addresses */ - nif->index = ptr->Ipv6IfIndex; + nif->ipv6Index = ptr->Ipv6IfIndex; c = getAddrsFromAdapter(ptr, &nif->addrs); nif->naddrs += c; break; @@ -309,6 +312,9 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP) strcpy (nif->name, newname); wcscpy ((PWCHAR)nif->displayName, ptr->FriendlyName); nif->dNameIsUnicode = TRUE; + + // the java.net.NetworkInterface abstraction only has index + // so the Ipv6IfIndex needs to map onto index nif->index = ptr->Ipv6IfIndex; nif->ipv6Index = ptr->Ipv6IfIndex; nif->hasIpv6Address = TRUE; @@ -487,7 +493,6 @@ static jobject createNetworkInterfaceXP(JNIEnv *env, netif *ifs) (*env)->SetObjectField(env, netifObj, ni_nameID, name); (*env)->SetObjectField(env, netifObj, ni_displayNameID, displayName); (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index); - /* * Get the IP addresses for this interface if necessary * Note that 0 is a valid number of addresses. diff --git a/jdk/test/java/net/NetworkInterface/UniqueMacAddressesTest.java b/jdk/test/java/net/NetworkInterface/UniqueMacAddressesTest.java new file mode 100644 index 00000000000..c2f5c495c73 --- /dev/null +++ b/jdk/test/java/net/NetworkInterface/UniqueMacAddressesTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; + + +/* + * @test + * @bug 8021372 + * @summary Tests that the MAC addresses returned by NetworkInterface.getNetworkInterfaces are unique for each adapter. + * + */ +public class UniqueMacAddressesTest { + + public static void main(String[] args) throws Exception { + new UniqueMacAddressesTest().execute(); + System.out.println("UniqueMacAddressesTest: OK"); + } + + public UniqueMacAddressesTest() { + System.out.println("UniqueMacAddressesTest: start "); + } + + public void execute() throws Exception { + Enumeration networkInterfaces; + boolean areMacAddressesUnique = false; + List networkInterfaceList = new ArrayList(); + networkInterfaces = NetworkInterface.getNetworkInterfaces(); + + // build a list of NetworkInterface objects to test MAC address + // uniqueness + createNetworkInterfaceList(networkInterfaces, networkInterfaceList); + areMacAddressesUnique = checkMacAddressesAreUnique(networkInterfaceList); + if (!areMacAddressesUnique) { + throw new RuntimeException("mac address uniqueness test failed"); + } + } + + private boolean checkMacAddressesAreUnique ( + List networkInterfaces) throws Exception { + boolean uniqueMacAddresses = true; + for (NetworkInterface networkInterface : networkInterfaces) { + for (NetworkInterface comparisonNetIf : networkInterfaces) { + System.out.println("Comparing netif " + + networkInterface.getName() + " and netif " + + comparisonNetIf.getName()); + if (testMacAddressesEqual(networkInterface, comparisonNetIf)) { + uniqueMacAddresses = false; + break; + } + } + if (uniqueMacAddresses != true) + break; + } + return uniqueMacAddresses; + } + + private boolean testMacAddressesEqual(NetworkInterface netIf1, + NetworkInterface netIf2) throws Exception { + + byte[] rawMacAddress1 = null; + byte[] rawMacAddress2 = null; + boolean macAddressesEqual = false; + if (!netIf1.getName().equals(netIf2.getName())) { + System.out.println("compare hardware addresses " + + createMacAddressString(netIf1) + " and " + createMacAddressString(netIf2)); + rawMacAddress1 = netIf1.getHardwareAddress(); + rawMacAddress2 = netIf2.getHardwareAddress(); + macAddressesEqual = Arrays.equals(rawMacAddress1, rawMacAddress2); + } else { + // same interface + macAddressesEqual = false; + } + return macAddressesEqual; + } + + private String createMacAddressString (NetworkInterface netIf) throws Exception { + byte[] macAddr = netIf.getHardwareAddress(); + StringBuilder sb = new StringBuilder(); + if (macAddr != null) { + for (int i = 0; i < macAddr.length; i++) { + sb.append(String.format("%02X%s", macAddr[i], + (i < macAddr.length - 1) ? "-" : "")); + } + } + return sb.toString(); + } + + private void createNetworkInterfaceList(Enumeration nis, + List networkInterfaceList) throws Exception { + byte[] macAddr = null; + NetworkInterface netIf = null; + while (nis.hasMoreElements()) { + netIf = (NetworkInterface) nis.nextElement(); + macAddr = netIf.getHardwareAddress(); + if (macAddr != null) { + System.out + .println("Adding NetworkInterface " + netIf.getName()); + networkInterfaceList.add(netIf); + } + } + } +} From aefe8c12c047da8a4753780397be14ff5d390975 Mon Sep 17 00:00:00 2001 From: Jason Uh Date: Mon, 9 Sep 2013 10:52:56 -0700 Subject: [PATCH 0242/1294] 8024432: Fix doclint issues in java.security Reviewed-by: darcy, mullan --- .../java/security/AccessController.java | 24 +++++++++++++++++++ .../java/security/AlgorithmParameters.java | 1 + .../java/security/AlgorithmParametersSpi.java | 2 ++ .../classes/java/security/KeyFactory.java | 2 ++ .../classes/java/security/KeyFactorySpi.java | 2 ++ .../share/classes/java/security/KeyStore.java | 1 + .../classes/java/security/Principal.java | 3 ++- .../security/cert/CertPathBuilderSpi.java | 2 ++ .../security/cert/CertPathValidatorSpi.java | 2 ++ .../security/cert/PKIXRevocationChecker.java | 3 +++ .../RSAMultiPrimePrivateCrtKey.java | 7 +++++- .../security/interfaces/RSAPrivateCrtKey.java | 7 +++++- .../security/interfaces/RSAPrivateKey.java | 7 +++++- .../security/interfaces/RSAPublicKey.java | 7 +++++- 14 files changed, 65 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/java/security/AccessController.java b/jdk/src/share/classes/java/security/AccessController.java index ed103a9186d..a7d089958fe 100644 --- a/jdk/src/share/classes/java/security/AccessController.java +++ b/jdk/src/share/classes/java/security/AccessController.java @@ -279,6 +279,9 @@ public final class AccessController { *

    Note that any DomainCombiner associated with the current * AccessControlContext will be ignored while the action is performed. * + * @param the type of the value returned by the PrivilegedAction's + * {@code run} method. + * * @param action the action to be performed. * * @return the value returned by the action's {@code run} method. @@ -305,6 +308,9 @@ public final class AccessController { *

    This method preserves the current AccessControlContext's * DomainCombiner (which may be null) while the action is performed. * + * @param the type of the value returned by the PrivilegedAction's + * {@code run} method. + * * @param action the action to be performed. * * @return the value returned by the action's {@code run} method. @@ -344,6 +350,8 @@ public final class AccessController { * {@link java.security.SecurityPermission}, then the action is performed * with no permissions. * + * @param the type of the value returned by the PrivilegedAction's + * {@code run} method. * @param action the action to be performed. * @param context an access control context * representing the restriction to be applied to the @@ -377,6 +385,8 @@ public final class AccessController { * If the action's {@code run} method throws an (unchecked) exception, * it will propagate through this method. * + * @param the type of the value returned by the PrivilegedAction's + * {@code run} method. * @param action the action to be performed. * @param context an access control context * representing the restriction to be applied to the @@ -429,6 +439,8 @@ public final class AccessController { *

    This method preserves the current AccessControlContext's * DomainCombiner (which may be null) while the action is performed. * + * @param the type of the value returned by the PrivilegedAction's + * {@code run} method. * @param action the action to be performed. * @param context an access control context * representing the restriction to be applied to the @@ -479,6 +491,9 @@ public final class AccessController { *

    Note that any DomainCombiner associated with the current * AccessControlContext will be ignored while the action is performed. * + * @param the type of the value returned by the + * PrivilegedExceptionAction's {@code run} method. + * * @param action the action to be performed * * @return the value returned by the action's {@code run} method @@ -509,6 +524,9 @@ public final class AccessController { *

    This method preserves the current AccessControlContext's * DomainCombiner (which may be null) while the action is performed. * + * @param the type of the value returned by the + * PrivilegedExceptionAction's {@code run} method. + * * @param action the action to be performed. * * @return the value returned by the action's {@code run} method @@ -585,6 +603,8 @@ public final class AccessController { * {@link java.security.SecurityPermission}, then the action is performed * with no permissions. * + * @param the type of the value returned by the + * PrivilegedExceptionAction's {@code run} method. * @param action the action to be performed * @param context an access control context * representing the restriction to be applied to the @@ -622,6 +642,8 @@ public final class AccessController { * If the action's {@code run} method throws an (unchecked) exception, * it will propagate through this method. * + * @param the type of the value returned by the + * PrivilegedExceptionAction's {@code run} method. * @param action the action to be performed. * @param context an access control context * representing the restriction to be applied to the @@ -676,6 +698,8 @@ public final class AccessController { *

    This method preserves the current AccessControlContext's * DomainCombiner (which may be null) while the action is performed. * + * @param the type of the value returned by the + * PrivilegedExceptionAction's {@code run} method. * @param action the action to be performed. * @param context an access control context * representing the restriction to be applied to the diff --git a/jdk/src/share/classes/java/security/AlgorithmParameters.java b/jdk/src/share/classes/java/security/AlgorithmParameters.java index c603a196c9f..b548fcb64c8 100644 --- a/jdk/src/share/classes/java/security/AlgorithmParameters.java +++ b/jdk/src/share/classes/java/security/AlgorithmParameters.java @@ -324,6 +324,7 @@ public class AlgorithmParameters { * parameters should be returned in an instance of the * {@code DSAParameterSpec} class. * + * @param the type of the parameter specification to be returrned * @param paramSpec the specification class in which * the parameters should be returned. * diff --git a/jdk/src/share/classes/java/security/AlgorithmParametersSpi.java b/jdk/src/share/classes/java/security/AlgorithmParametersSpi.java index be231a4cafe..282493b97b9 100644 --- a/jdk/src/share/classes/java/security/AlgorithmParametersSpi.java +++ b/jdk/src/share/classes/java/security/AlgorithmParametersSpi.java @@ -102,6 +102,8 @@ public abstract class AlgorithmParametersSpi { * parameters should be returned in an instance of the * {@code DSAParameterSpec} class. * + * @param the type of the parameter specification to be returned + * * @param paramSpec the specification class in which * the parameters should be returned. * diff --git a/jdk/src/share/classes/java/security/KeyFactory.java b/jdk/src/share/classes/java/security/KeyFactory.java index 0eb6b754107..8e761ff41f7 100644 --- a/jdk/src/share/classes/java/security/KeyFactory.java +++ b/jdk/src/share/classes/java/security/KeyFactory.java @@ -395,6 +395,8 @@ public class KeyFactory { * key material should be returned in an instance of the * {@code DSAPublicKeySpec} class. * + * @param the type of the key specification to be returned + * * @param key the key. * * @param keySpec the specification class in which diff --git a/jdk/src/share/classes/java/security/KeyFactorySpi.java b/jdk/src/share/classes/java/security/KeyFactorySpi.java index 877c3a11be1..5ee7f458931 100644 --- a/jdk/src/share/classes/java/security/KeyFactorySpi.java +++ b/jdk/src/share/classes/java/security/KeyFactorySpi.java @@ -106,6 +106,8 @@ public abstract class KeyFactorySpi { * key material should be returned in an instance of the * {@code DSAPublicKeySpec} class. * + * @param the type of the key specification to be returned + * * @param key the key. * * @param keySpec the specification class in which diff --git a/jdk/src/share/classes/java/security/KeyStore.java b/jdk/src/share/classes/java/security/KeyStore.java index c363d0719f7..187683baa50 100644 --- a/jdk/src/share/classes/java/security/KeyStore.java +++ b/jdk/src/share/classes/java/security/KeyStore.java @@ -1753,6 +1753,7 @@ public class KeyStore { /** * Returns the KeyStore described by this object. * + * @return the {@code KeyStore} described by this object * @exception KeyStoreException if an error occured during the * operation, for example if the KeyStore could not be * instantiated or loaded diff --git a/jdk/src/share/classes/java/security/Principal.java b/jdk/src/share/classes/java/security/Principal.java index 48938cfdd07..a538e707ee7 100644 --- a/jdk/src/share/classes/java/security/Principal.java +++ b/jdk/src/share/classes/java/security/Principal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -81,6 +81,7 @@ public interface Principal { *

    Subclasses may override this with a different implementation, if * necessary. * + * @param subject the {@code Subject} * @return true if {@code subject} is non-null and is * implied by this principal, or false otherwise. * @since 1.8 diff --git a/jdk/src/share/classes/java/security/cert/CertPathBuilderSpi.java b/jdk/src/share/classes/java/security/cert/CertPathBuilderSpi.java index 87908c03bd9..e7755411797 100644 --- a/jdk/src/share/classes/java/security/cert/CertPathBuilderSpi.java +++ b/jdk/src/share/classes/java/security/cert/CertPathBuilderSpi.java @@ -87,6 +87,8 @@ public abstract class CertPathBuilderSpi { * service providers, this method cannot be abstract and by default throws * an {@code UnsupportedOperationException}. * + * @return a {@code CertPathChecker} that this implementation uses to + * check the revocation status of certificates * @throws UnsupportedOperationException if this method is not supported * @since 1.8 */ diff --git a/jdk/src/share/classes/java/security/cert/CertPathValidatorSpi.java b/jdk/src/share/classes/java/security/cert/CertPathValidatorSpi.java index 50ad9c85c9b..02d503c9e62 100644 --- a/jdk/src/share/classes/java/security/cert/CertPathValidatorSpi.java +++ b/jdk/src/share/classes/java/security/cert/CertPathValidatorSpi.java @@ -97,6 +97,8 @@ public abstract class CertPathValidatorSpi { * service providers, this method cannot be abstract and by default throws * an {@code UnsupportedOperationException}. * + * @return a {@code CertPathChecker} that this implementation uses to + * check the revocation status of certificates * @throws UnsupportedOperationException if this method is not supported * @since 1.8 */ diff --git a/jdk/src/share/classes/java/security/cert/PKIXRevocationChecker.java b/jdk/src/share/classes/java/security/cert/PKIXRevocationChecker.java index b667397c8e5..3046a03ed23 100644 --- a/jdk/src/share/classes/java/security/cert/PKIXRevocationChecker.java +++ b/jdk/src/share/classes/java/security/cert/PKIXRevocationChecker.java @@ -103,6 +103,9 @@ public abstract class PKIXRevocationChecker extends PKIXCertPathChecker { private Map ocspResponses = Collections.emptyMap(); private Set

    {@code
    + *     int sum = widgets.stream()
    + *                      .filter(w -> w.getColor() == RED)
    + *                      .mapToInt(w -> w.getWeight())
    + *                      .sum();
    + * }
    + * + * In this example, {@code widgets} is a {@code Collection}. We create + * a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()}, + * filter it to produce a stream containing only the red widgets, and then + * transform it into a stream of {@code int} values representing the weight of + * each red widget. Then this stream is summed to produce a total weight. + * + *

    To perform a computation, stream + * operations are composed into a + * stream pipeline. A stream pipeline consists of a source (which + * might be an array, a collection, a generator function, an IO channel, + * etc), zero or more intermediate operations (which transform a + * stream into another stream, such as {@link Stream#filter(Predicate)}), and a + * terminal operation (which produces a result or side-effect, such + * as {@link IntStream#sum()} or {@link IntStream#forEach(IntConsumer)}). + * Streams are lazy; computation on the source data is only performed when the + * terminal operation is initiated, and source elements are consumed only + * as needed. + * + *

    Collections and streams, while bearing some superficial similarities, + * have different goals. Collections are primarily concerned with the efficient + * management of, and access to, their elements. By contrast, streams do not + * provide a means to directly access or manipulate their elements, and are + * instead concerned with declaratively describing their source and the + * computational operations which will be performed in aggregate on that source. + * However, if the provided stream operations do not offer the desired + * functionality, the {@link #iterator()} and {@link #spliterator()} operations + * can be used to perform a controlled traversal. + * + *

    A stream pipeline, like the "widgets" example above, can be viewed as + * a query on the stream source. Unless the source was explicitly + * designed for concurrent modification (such as a {@link ConcurrentHashMap}), + * unpredictable or erroneous behavior may result from modifying the stream + * source while it is being queried. + * + *

    Most stream operations accept parameters that describe user-specified + * behavior, such as the lambda expression {@code w -> w.getWeight()} passed to + * {@code mapToInt} in the example above. Such parameters are always instances + * of a functional interface such + * as {@link java.util.function.Function}, and are often lambda expressions or + * method references. These parameters can never be null, should not modify the + * stream source, and should be + * effectively stateless + * (their result should not depend on any state that might change during + * execution of the stream pipeline.) + * + *

    A stream should be operated on (invoking an intermediate or terminal stream + * operation) only once. This rules out, for example, "forked" streams, where + * the same source feeds two or more pipelines, or multiple traversals of the + * same stream. A stream implementation may throw {@link IllegalStateException} + * if it detects that the stream is being reused. However, since some stream + * operations may return their receiver rather than a new stream object, it may + * not be possible to detect reuse in all cases. + * + *

    Streams have a {@link #close()} method and implement {@link AutoCloseable}, + * but nearly all stream instances do not actually need to be closed after use. + * Generally, only streams whose source is an IO channel (such as those returned + * by {@link Files#lines(Path, Charset)}) will require closing. Most streams + * are backed by collections, arrays, or generating functions, which require no + * special resource management. (If a stream does require closing, it can be + * declared as a resource in a {@code try}-with-resources statement.) + * + *

    Stream pipelines may execute either sequentially or in + * parallel. This + * execution mode is a property of the stream. Streams are created + * with an initial choice of sequential or parallel execution. (For example, + * {@link Collection#stream() Collection.stream()} creates a sequential stream, + * and {@link Collection#parallelStream() Collection.parallelStream()} creates + * a parallel one.) This choice of execution mode may be modified by the + * {@link #sequential()} or {@link #parallel()} methods, and may be queried with + * the {@link #isParallel()} method. + * + * @param the type of the stream elements + * @param the type of of the stream implementing {@code BaseStream} * @since 1.8 + * @see java.util.stream */ public interface BaseStream> extends AutoCloseable { @@ -58,14 +145,11 @@ public interface BaseStream> Spliterator spliterator(); /** - * Returns whether this stream, when executed, would execute in parallel - * (assuming no further modification of the stream, such as appending - * further intermediate operations or changing its parallelism). Calling - * this method after invoking an intermediate or terminal stream operation - * method may yield unpredictable results. + * Returns whether this stream, if a terminal operation were to be executed, + * would execute in parallel. Calling this method after invoking an + * terminal stream operation method may yield unpredictable results. * * @return {@code true} if this stream would execute in parallel if executed - * without further modification otherwise {@code false} */ boolean isParallel(); @@ -96,7 +180,8 @@ public interface BaseStream> /** * Returns an equivalent stream that is * unordered. May return - * itself if the stream was already unordered. + * itself, either because the stream was already unordered, or because + * the underlying stream state was modified to be unordered. * *

    This is an intermediate * operation. diff --git a/jdk/src/share/classes/java/util/stream/Collector.java b/jdk/src/share/classes/java/util/stream/Collector.java index 49629176032..e409d569808 100644 --- a/jdk/src/share/classes/java/util/stream/Collector.java +++ b/jdk/src/share/classes/java/util/stream/Collector.java @@ -26,6 +26,7 @@ package java.util.stream; import java.util.Collections; import java.util.EnumSet; +import java.util.Objects; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.BinaryOperator; @@ -33,71 +34,74 @@ import java.util.function.Function; import java.util.function.Supplier; /** - * A reduction operation that - * folds input elements into a mutable result container, optionally transforming + * A mutable reduction operation that + * accumulates input elements into a mutable result container, optionally transforming * the accumulated result into a final representation after all input elements - * have been processed. + * have been processed. Reduction operations can be performed either sequentially + * or in parallel. * *

    Examples of mutable reduction operations include: * accumulating elements into a {@code Collection}; concatenating * strings using a {@code StringBuilder}; computing summary information about * elements such as sum, min, max, or average; computing "pivot table" summaries - * such as "maximum valued transaction by seller", etc. Reduction operations - * can be performed either sequentially or in parallel. - * - *

    The following are examples of using the predefined {@code Collector} - * implementations in {@link Collectors} with the {@code Stream} API to perform - * mutable reduction tasks: - *

    {@code
    - *     // Accumulate names into a List
    - *     List list = people.stream().map(Person::getName).collect(Collectors.toList());
    - *
    - *     // Accumulate names into a TreeSet
    - *     Set list = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
    - *
    - *     // Convert elements to strings and concatenate them, separated by commas
    - *     String joined = things.stream()
    - *                           .map(Object::toString)
    - *                           .collect(Collectors.joining(", "));
    - *
    - *     // Find highest-paid employee
    - *     Employee highestPaid = employees.stream()
    - *                                     .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)))
    - *                                     .get();
    - *
    - *     // Group employees by department
    - *     Map> byDept
    - *         = employees.stream()
    - *                    .collect(Collectors.groupingBy(Employee::getDepartment));
    - *
    - *     // Find highest-paid employee by department
    - *     Map> highestPaidByDept
    - *         = employees.stream()
    - *                    .collect(Collectors.groupingBy(Employee::getDepartment,
    - *                                                   Collectors.maxBy(Comparators.comparing(Employee::getSalary))));
    - *
    - *     // Partition students into passing and failing
    - *     Map> passingFailing =
    - *         students.stream()
    - *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
    - *
    - * }
    + * such as "maximum valued transaction by seller", etc. The class {@link Collectors} + * provides implementations of many common mutable reductions. * *

    A {@code Collector} is specified by four functions that work together to * accumulate entries into a mutable result container, and optionally perform - * a final transform on the result. They are: creation of a new result container, - * incorporating a new data element into a result container, combining two - * result containers into one, and performing a final transform on the container. - * The combiner function is used during parallel operations, where - * subsets of the input are accumulated into separate result - * containers, and then the subresults merged into a combined result. The - * combiner function may merge one set of subresults into the other and return - * that, or it may return a new object to describe the combined results. + * a final transform on the result. They are:

      + *
    • creation of a new result container ({@link #supplier()})
    • + *
    • incorporating a new data element into a result container ({@link #accumulator()})
    • + *
    • combining two result containers into one ({@link #combiner()})
    • + *
    • performing an optional final transform on the container ({@link #finisher()})
    • + *
    * *

    Collectors also have a set of characteristics, such as - * {@link Characteristics#CONCURRENT}. These characteristics provide - * hints that can be used by a reduction implementation to provide better - * performance. + * {@link Characteristics#CONCURRENT}, that provide hints that can be used by a + * reduction implementation to provide better performance. + * + *

    A sequential implementation of a reduction using a collector would + * create a single result container using the supplier function, and invoke the + * accumulator function once for each input element. A parallel implementation + * would partition the input, create a result container for each partition, + * accumulate the contents of each partition into a subresult for that partition, + * and then use the combiner function to merge the subresults into a combined + * result. + * + *

    To ensure that sequential and parallel executions produce equivalent + * results, the collector functions must satisfy an identity and an + * associativity constraints. + * + *

    The identity constraint says that for any partially accumulated result, + * combining it with an empty result container must produce an equivalent + * result. That is, for a partially accumulated result {@code a} that is the + * result of any series of accumulator and combiner invocations, {@code a} must + * be equivalent to {@code combiner.apply(a, supplier.get())}. + * + *

    The associativity constraint says that splitting the computation must + * produce an equivalent result. That is, for any input elements {@code t1} + * and {@code t2}, the results {@code r1} and {@code r2} in the computation + * below must be equivalent: + *

    {@code
    + *     A a1 = supplier.get();
    + *     accumulator.accept(a1, t1);
    + *     accumulator.accept(a1, t2);
    + *     R r1 = finisher.apply(a1);  // result without splitting
    + *
    + *     A a2 = supplier.get();
    + *     accumulator.accept(a2, t1);
    + *     A a3 = supplier.get();
    + *     accumulator.accept(a3, t2);
    + *     R r2 = finisher.apply(combiner.apply(a2, a3));  // result with splitting
    + * } 
    + * + *

    For collectors that do not have the {@code UNORDERED} characteristic, + * two accumulated results {@code a1} and {@code a2} are equivalent if + * {@code finisher.apply(a1).equals(finisher.apply(a2))}. For unordered + * collectors, equivalence is relaxed to allow for non-equality related to + * differences in order. (For example, an unordered collector that accumulated + * elements to a {@code List} would consider two lists equivalent if they + * contained the same elements, ignoring order.) * *

    Libraries that implement reduction based on {@code Collector}, such as * {@link Stream#collect(Collector)}, must adhere to the following constraints: @@ -132,6 +136,20 @@ import java.util.function.Supplier; * originating data is unordered.

  • * * + *

    In addition to the predefined implementations in {@link Collectors}, the + * static factory methods {@link #of(Supplier, BiConsumer, BinaryOperator, Characteristics...)} + * can be used to construct collectors. For example, you could create a collector + * that accumulates widgets into a {@code TreeSet} with: + * + *

    {@code
    + *     Collector> intoSet =
    + *         Collector.of(TreeSet::new, TreeSet::add,
    + *                      (left, right) -> { left.addAll(right); return left; });
    + * }
    + * + * (This behavior is also implemented by the predefined collector + * {@link Collectors#toCollection(Supplier)}). + * * @apiNote * Performing a reduction operation with a {@code Collector} should produce a * result equivalent to: @@ -144,27 +162,35 @@ import java.util.function.Supplier; * *

    However, the library is free to partition the input, perform the reduction * on the partitions, and then use the combiner function to combine the partial - * results to achieve a parallel reduction. Depending on the specific reduction + * results to achieve a parallel reduction. (Depending on the specific reduction * operation, this may perform better or worse, depending on the relative cost - * of the accumulator and combiner functions. + * of the accumulator and combiner functions.) * - *

    An example of an operation that can be easily modeled by {@code Collector} - * is accumulating elements into a {@code TreeSet}. In this case, the {@code - * resultSupplier()} function is {@code () -> new Treeset()}, the - * {@code accumulator} function is - * {@code (set, element) -> set.add(element) }, and the combiner - * function is {@code (left, right) -> { left.addAll(right); return left; }}. - * (This behavior is implemented by - * {@code Collectors.toCollection(TreeSet::new)}). + *

    Collectors are designed to be composed; many of the methods + * in {@link Collectors} are functions that take a collector and produce + * a new collector. For example, given the following collector that computes + * the sum of the salaries of a stream of employees: * - * TODO Associativity and commutativity + *

    {@code
    + *     Collector summingSalaries
    + *         = Collectors.summingInt(Employee::getSalary))
    + * }
    + * + * If we wanted to create a collector to tabulate the sum of salaries by + * department, we could reuse the "sum of salaries" logic using + * {@link Collectors#groupingBy(Function, Collector)}: + * + *
    {@code
    + *     Collector> summingSalariesByDept
    + *         = Collectors.groupingBy(Employee::getDepartment, summingSalaries);
    + * }
    * * @see Stream#collect(Collector) * @see Collectors * * @param the type of input elements to the reduction operation * @param the mutable accumulation type of the reduction operation (often - * hidden as an implementation detail) + * hidden as an implementation detail) * @param the result type of the reduction operation * @since 1.8 */ @@ -177,25 +203,25 @@ public interface Collector { Supplier supplier(); /** - * A function that folds a new value into a mutable result container. + * A function that folds a value into a mutable result container. * - * @return a function which folds a new value into a mutable result container + * @return a function which folds a value into a mutable result container */ BiConsumer accumulator(); /** * A function that accepts two partial results and merges them. The * combiner function may fold state from one argument into the other and - * return that, or may return a new result object. + * return that, or may return a new result container. * - * @return a function which combines two partial results into a cumulative + * @return a function which combines two partial results into a combined * result */ BinaryOperator combiner(); /** * Perform the final transformation from the intermediate accumulation type - * {@code A} to the final result representation {@code R}. + * {@code A} to the final result type {@code R}. * *

    If the characteristic {@code IDENTITY_TRANSFORM} is * set, this function may be presumed to be an identity transform with an @@ -228,12 +254,17 @@ public interface Collector { * @param The type of input elements for the new collector * @param The type of intermediate accumulation result, and final result, * for the new collector + * @throws NullPointerException if any argument is null * @return the new {@code Collector} */ public static Collector of(Supplier supplier, BiConsumer accumulator, BinaryOperator combiner, Characteristics... characteristics) { + Objects.requireNonNull(supplier); + Objects.requireNonNull(accumulator); + Objects.requireNonNull(combiner); + Objects.requireNonNull(characteristics); Set cs = (characteristics.length == 0) ? Collectors.CH_ID : Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH, @@ -254,6 +285,7 @@ public interface Collector { * @param The type of input elements for the new collector * @param The intermediate accumulation type of the new collector * @param The final result type of the new collector + * @throws NullPointerException if any argument is null * @return the new {@code Collector} */ public static Collector of(Supplier supplier, @@ -261,6 +293,11 @@ public interface Collector { BinaryOperator combiner, Function finisher, Characteristics... characteristics) { + Objects.requireNonNull(supplier); + Objects.requireNonNull(accumulator); + Objects.requireNonNull(combiner); + Objects.requireNonNull(finisher); + Objects.requireNonNull(characteristics); Set cs = Collectors.CH_NOID; if (characteristics.length > 0) { cs = EnumSet.noneOf(Characteristics.class); @@ -288,8 +325,9 @@ public interface Collector { CONCURRENT, /** - * Indicates that the result container has no intrinsic order, such as - * a {@link Set}. + * Indicates that the collection operation does not commit to preserving + * the encounter order of input elements. (This might be true if the + * result container has no intrinsic order, such as a {@link Set}.) */ UNORDERED, diff --git a/jdk/src/share/classes/java/util/stream/Collectors.java b/jdk/src/share/classes/java/util/stream/Collectors.java index bdbd8ad0774..00f7c866311 100644 --- a/jdk/src/share/classes/java/util/stream/Collectors.java +++ b/jdk/src/share/classes/java/util/stream/Collectors.java @@ -62,37 +62,35 @@ import java.util.function.ToLongFunction; * operations, such as accumulating elements into collections, summarizing * elements according to various criteria, etc. * - *

    The following are examples of using the predefined {@code Collector} - * implementations in {@link Collectors} with the {@code Stream} API to perform - * mutable reduction tasks: + *

    The following are examples of using the predefined collectors to perform + * common mutable reduction tasks: * *

    {@code
      *     // Accumulate names into a List
      *     List list = people.stream().map(Person::getName).collect(Collectors.toList());
      *
      *     // Accumulate names into a TreeSet
    - *     Set list = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
    + *     Set set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
      *
      *     // Convert elements to strings and concatenate them, separated by commas
      *     String joined = things.stream()
      *                           .map(Object::toString)
      *                           .collect(Collectors.joining(", "));
      *
    - *     // Find highest-paid employee
    - *     Employee highestPaid = employees.stream()
    - *                                     .collect(Collectors.maxBy(Comparator.comparing(Employee::getSalary)))
    - *                                     .get();
    + *     // Compute sum of salaries of employee
    + *     int total = employees.stream()
    + *                          .collect(Collectors.summingInt(Employee::getSalary)));
      *
      *     // Group employees by department
      *     Map> byDept
      *         = employees.stream()
      *                    .collect(Collectors.groupingBy(Employee::getDepartment));
      *
    - *     // Find highest-paid employee by department
    - *     Map> highestPaidByDept
    + *     // Compute sum of salaries by department
    + *     Map totalByDept
      *         = employees.stream()
      *                    .collect(Collectors.groupingBy(Employee::getDepartment,
    - *                                                   Collectors.maxBy(Comparator.comparing(Employee::getSalary))));
    + *                                                   Collectors.summingInt(Employee::getSalary)));
      *
      *     // Partition students into passing and failing
      *     Map> passingFailing =
    @@ -101,8 +99,6 @@ import java.util.function.ToLongFunction;
      *
      * }
    * - * TODO explanation of parallel collection - * * @since 1.8 */ public final class Collectors { @@ -222,7 +218,8 @@ public final class Collectors { /** * Returns a {@code Collector} that accumulates the input elements into a * new {@code List}. There are no guarantees on the type, mutability, - * serializability, or thread-safety of the {@code List} returned. + * serializability, or thread-safety of the {@code List} returned; if more + * control over the returned {@code List} is required, use {@link #toCollection(Supplier)}. * * @param the type of the input elements * @return a {@code Collector} which collects all the input elements into a @@ -238,7 +235,9 @@ public final class Collectors { /** * Returns a {@code Collector} that accumulates the input elements into a * new {@code Set}. There are no guarantees on the type, mutability, - * serializability, or thread-safety of the {@code Set} returned. + * serializability, or thread-safety of the {@code Set} returned; if more + * control over the returned {@code Set} is required, use + * {@link #toCollection(Supplier)}. * *

    This is an {@link Collector.Characteristics#UNORDERED unordered} * Collector. @@ -903,7 +902,7 @@ public final class Collectors { * where the city names are sorted: *

    {@code
          *     ConcurrentMap> namesByCity
    -     *         = people.stream().collect(groupingByConcurrent(Person::getCity, ConcurrentSkipListMap::new,
    +     *         = people.stream().collect(groupingByConcurrent(Person::getCity,
          *                                                        mapping(Person::getLastName, toSet())));
          * }
    * diff --git a/jdk/src/share/classes/java/util/stream/DoublePipeline.java b/jdk/src/share/classes/java/util/stream/DoublePipeline.java index 75981d5801f..43b3d04bed9 100644 --- a/jdk/src/share/classes/java/util/stream/DoublePipeline.java +++ b/jdk/src/share/classes/java/util/stream/DoublePipeline.java @@ -313,8 +313,8 @@ abstract class DoublePipeline } @Override - public final DoubleStream peek(DoubleConsumer consumer) { - Objects.requireNonNull(consumer); + public final DoubleStream peek(DoubleConsumer action) { + Objects.requireNonNull(action); return new StatelessOp(this, StreamShape.DOUBLE_VALUE, 0) { @Override @@ -322,7 +322,7 @@ abstract class DoublePipeline return new Sink.ChainedDouble(sink) { @Override public void accept(double t) { - consumer.accept(t); + action.accept(t); downstream.accept(t); } }; @@ -436,14 +436,14 @@ abstract class DoublePipeline } @Override - public final R collect(Supplier resultFactory, + public final R collect(Supplier supplier, ObjDoubleConsumer accumulator, BiConsumer combiner) { BinaryOperator operator = (left, right) -> { combiner.accept(left, right); return left; }; - return evaluate(ReduceOps.makeDouble(resultFactory, accumulator, operator)); + return evaluate(ReduceOps.makeDouble(supplier, accumulator, operator)); } @Override diff --git a/jdk/src/share/classes/java/util/stream/DoubleStream.java b/jdk/src/share/classes/java/util/stream/DoubleStream.java index bf356926154..f10092ac7a5 100644 --- a/jdk/src/share/classes/java/util/stream/DoubleStream.java +++ b/jdk/src/share/classes/java/util/stream/DoubleStream.java @@ -24,13 +24,18 @@ */ package java.util.stream; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Arrays; +import java.util.Collection; import java.util.DoubleSummaryStatistics; import java.util.Objects; import java.util.OptionalDouble; import java.util.PrimitiveIterator; import java.util.Spliterator; import java.util.Spliterators; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.DoubleBinaryOperator; import java.util.function.DoubleConsumer; @@ -45,40 +50,87 @@ import java.util.function.ObjDoubleConsumer; import java.util.function.Supplier; /** - * A sequence of primitive double elements supporting sequential and parallel - * bulk operations. Streams support lazy intermediate operations (transforming - * a stream to another stream) such as {@code filter} and {@code map}, and terminal - * operations (consuming the contents of a stream to produce a result or - * side-effect), such as {@code forEach}, {@code findFirst}, and {@code - * iterator}. Once an operation has been performed on a stream, it - * is considered consumed and no longer usable for other operations. + * A sequence of elements supporting sequential and parallel aggregate + * operations. The following example illustrates an aggregate operation using + * {@link Stream} and {@link DoubleStream}: * - *

    For sequential stream pipelines, all operations are performed in the - * encounter order of the pipeline - * source, if the pipeline source has a defined encounter order. + *

    {@code
    + *     double sum = widgets.stream()
    + *                         .filter(w -> w.getColor() == RED)
    + *                         .mapToDouble(w -> w.getWeight())
    + *                         .sum();
    + * }
    * - *

    For parallel stream pipelines, unless otherwise specified, intermediate - * stream operations preserve the - * encounter order of their source, and terminal operations - * respect the encounter order of their source, if the source - * has an encounter order. Provided that and parameters to stream operations - * satisfy the non-interference - * requirements, and excepting differences arising from the absence of - * a defined encounter order, the result of a stream pipeline should be the - * stable across multiple executions of the same operations on the same source. - * However, the timing and thread in which side-effects occur (for those - * operations which are allowed to produce side-effects, such as - * {@link #forEach(DoubleConsumer)}), are explicitly nondeterministic for parallel - * execution of stream pipelines. + * In this example, {@code widgets} is a {@code Collection}. We create + * a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()}, + * filter it to produce a stream containing only the red widgets, and then + * transform it into a stream of {@code double} values representing the weight of + * each red widget. Then this stream is summed to produce a total weight. * - *

    Unless otherwise noted, passing a {@code null} argument to any stream - * method may result in a {@link NullPointerException}. + *

    To perform a computation, stream + * operations are composed into a + * stream pipeline. A stream pipeline consists of a source (which + * might be an array, a collection, a generator function, an IO channel, + * etc), zero or more intermediate operations (which transform a + * stream into another stream, such as {@link DoubleStream#filter(DoublePredicate)}), and a + * terminal operation (which produces a result or side-effect, such + * as {@link DoubleStream#sum()} or {@link DoubleStream#forEach(DoubleConsumer)}. + * Streams are lazy; computation on the source data is only performed when the + * terminal operation is initiated, and source elements are consumed only + * as needed. * - * @apiNote - * Streams are not data structures; they do not manage the storage for their - * elements, nor do they support access to individual elements. However, - * you can use the {@link #iterator()} or {@link #spliterator()} operations to - * perform a controlled traversal. + *

    Collections and streams, while bearing some superficial similarities, + * have different goals. Collections are primarily concerned with the efficient + * management of, and access to, their elements. By contrast, streams do not + * provide a means to directly access or manipulate their elements, and are + * instead concerned with declaratively describing their source and the + * computational operations which will be performed in aggregate on that source. + * However, if the provided stream operations do not offer the desired + * functionality, the {@link #iterator()} and {@link #spliterator()} operations + * can be used to perform a controlled traversal. + * + *

    A stream pipeline, like the "widgets" example above, can be viewed as + * a query on the stream source. Unless the source was explicitly + * designed for concurrent modification (such as a {@link ConcurrentHashMap}), + * unpredictable or erroneous behavior may result from modifying the stream + * source while it is being queried. + * + *

    Most stream operations accept parameters that describe user-specified + * behavior, such as the lambda expression {@code w -> w.getWeight()} passed to + * {@code mapToDouble} in the example above. Such parameters are always instances + * of a functional interface such + * as {@link java.util.function.Function}, and are often lambda expressions or + * method references. These parameters can never be null, should not modify the + * stream source, and should be + * effectively stateless + * (their result should not depend on any state that might change during + * execution of the stream pipeline.) + * + *

    A stream should be operated on (invoking an intermediate or terminal stream + * operation) only once. This rules out, for example, "forked" streams, where + * the same source feeds two or more pipelines, or multiple traversals of the + * same stream. A stream implementation may throw {@link IllegalStateException} + * if it detects that the stream is being reused. However, since some stream + * operations may return their receiver rather than a new stream object, it may + * not be possible to detect reuse in all cases. + * + *

    Streams have a {@link #close()} method and implement {@link AutoCloseable}, + * but nearly all stream instances do not actually need to be closed after use. + * Generally, only streams whose source is an IO channel (such as those returned + * by {@link Files#lines(Path, Charset)}) will require closing. Most streams + * are backed by collections, arrays, or generating functions, which require no + * special resource management. (If a stream does require closing, it can be + * declared as a resource in a {@code try}-with-resources statement.) + * + *

    Stream pipelines may execute either sequentially or in + * parallel. This + * execution mode is a property of the stream. Streams are created + * with an initial choice of sequential or parallel execution. (For example, + * {@link Collection#stream() Collection.stream()} creates a sequential stream, + * and {@link Collection#parallelStream() Collection.parallelStream()} creates + * a parallel one.) This choice of execution mode may be modified by the + * {@link #sequential()} or {@link #parallel()} methods, and may be queried with + * the {@link #isParallel()} method. * * @since 1.8 * @see java.util.stream @@ -159,22 +211,13 @@ public interface DoubleStream extends BaseStream { /** * Returns a stream consisting of the results of replacing each element of * this stream with the contents of the stream produced by applying the - * provided mapping function to each element. + * provided mapping function to each element. (If the result of the mapping + * function is {@code null}, this is treated as if the result was an empty + * stream.) * *

    This is an intermediate * operation. * - * @apiNote - * The {@code flatMap()} operation has the effect of applying a one-to-many - * tranformation to the elements of the stream, and then flattening the - * resulting elements into a new stream. For example, if {@code orders} - * is a stream of purchase orders, and each purchase order contains a - * collection of line items, then the following produces a stream of line - * items: - *

    {@code
    -     *     orderStream.flatMap(order -> order.getLineItems().stream())...
    -     * }
    - * * @param mapper a * non-interfering, stateless function to apply to * each element which produces an {@code DoubleStream} of new @@ -226,18 +269,18 @@ public interface DoubleStream extends BaseStream { *
    {@code
          *     list.stream()
          *         .filter(filteringFunction)
    -     *         .peek(e -> {System.out.println("Filtered value: " + e); });
    +     *         .peek(e -> System.out.println("Filtered value: " + e));
          *         .map(mappingFunction)
    -     *         .peek(e -> {System.out.println("Mapped value: " + e); });
    +     *         .peek(e -> System.out.println("Mapped value: " + e));
          *         .collect(Collectors.toDoubleSummaryStastistics());
          * }
    * - * @param consumer a + * @param action a * non-interfering action to perform on the elements as * they are consumed from the stream * @return the new stream */ - DoubleStream peek(DoubleConsumer consumer); + DoubleStream peek(DoubleConsumer action); /** * Returns a stream consisting of the elements of this stream, truncated @@ -254,8 +297,8 @@ public interface DoubleStream extends BaseStream { /** * Returns a stream consisting of the remaining elements of this stream - * after indexing {@code startInclusive} elements into the stream. If the - * {@code startInclusive} index lies past the end of this stream then an + * after discarding the first {@code startInclusive} elements of the stream. + * If this stream contains fewer than {@code startInclusive} elements then an * empty stream will be returned. * *

    This is a stateful @@ -269,10 +312,10 @@ public interface DoubleStream extends BaseStream { /** * Returns a stream consisting of the remaining elements of this stream - * after indexing {@code startInclusive} elements into the stream and - * truncated to contain no more than {@code endExclusive - startInclusive} - * elements. If the {@code startInclusive} index lies past the end - * of this stream then an empty stream will be returned. + * after discarding the first {@code startInclusive} elements and truncating + * the result to be no longer than {@code endExclusive - startInclusive} + * elements in length. If this stream contains fewer than + * {@code startInclusive} elements then an empty stream will be returned. * *

    This is a short-circuiting * stateful intermediate operation. @@ -421,12 +464,12 @@ public interface DoubleStream extends BaseStream { /** * Performs a mutable * reduction operation on the elements of this stream. A mutable - * reduction is one in which the reduced value is a mutable value holder, + * reduction is one in which the reduced value is a mutable result container, * such as an {@code ArrayList}, and elements are incorporated by updating - * the state of the result, rather than by replacing the result. This + * the state of the result rather than by replacing the result. This * produces a result equivalent to: *

    {@code
    -     *     R result = resultFactory.get();
    +     *     R result = supplier.get();
          *     for (double element : this stream)
          *         accumulator.accept(result, element);
          *     return result;
    @@ -440,10 +483,9 @@ public interface DoubleStream extends BaseStream {
          * operation.
          *
          * @param  type of the result
    -     * @param resultFactory a function that creates a new result container.
    -     *                      For a parallel execution, this function may be
    -     *                      called multiple times and must return a fresh value
    -     *                      each time.
    +     * @param supplier a function that creates a new result container. For a
    +     *                 parallel execution, this function may be called
    +     *                 multiple times and must return a fresh value each time.
          * @param accumulator an associative
          *                    non-interfering,
          *                    stateless function for incorporating an additional
    @@ -455,7 +497,7 @@ public interface DoubleStream extends BaseStream {
          * @return the result of the reduction
          * @see Stream#collect(Supplier, BiConsumer, BiConsumer)
          */
    -     R collect(Supplier resultFactory,
    +     R collect(Supplier supplier,
                       ObjDoubleConsumer accumulator,
                       BiConsumer combiner);
     
    @@ -467,12 +509,15 @@ public interface DoubleStream extends BaseStream {
          * yield more accurate results.  If any stream element is a {@code NaN} or
          * the sum is at any point a {@code NaN} then the sum will be {@code NaN}.
          * This is a special case of a
    -     * reduction and is
    +     * reduction and is
          * equivalent to:
          * 
    {@code
          *     return reduce(0, Double::sum);
          * }
    * + *

    This is a terminal + * operation. + * * @return the sum of elements in this stream */ double sum(); @@ -483,12 +528,15 @@ public interface DoubleStream extends BaseStream { * element will be {@code Double.NaN} if any stream element was NaN. Unlike * the numerical comparison operators, this method considers negative zero * to be strictly smaller than positive zero. This is a special case of a - * reduction and is + * reduction and is * equivalent to: *

    {@code
          *     return reduce(Double::min);
          * }
    * + *

    This is a terminal + * operation. + * * @return an {@code OptionalDouble} containing the minimum element of this * stream, or an empty optional if the stream is empty */ @@ -501,12 +549,15 @@ public interface DoubleStream extends BaseStream { * the numerical comparison operators, this method considers negative zero * to be strictly smaller than positive zero. This is a * special case of a - * reduction and is + * reduction and is * equivalent to: *

    {@code
          *     return reduce(Double::max);
          * }
    * + *

    This is a terminal + * operation. + * * @return an {@code OptionalDouble} containing the maximum element of this * stream, or an empty optional if the stream is empty */ @@ -514,7 +565,7 @@ public interface DoubleStream extends BaseStream { /** * Returns the count of elements in this stream. This is a special case of - * a reduction and is + * a reduction and is * equivalent to: *

    {@code
          *     return mapToLong(e -> 1L).sum();
    @@ -535,7 +586,10 @@ public interface DoubleStream extends BaseStream {
          * magnitude tend to yield more accurate results. If any recorded value is
          * a {@code NaN} or the sum is at any point a {@code NaN} then the average
          * will be {@code NaN}. This is a special case of a
    -     * reduction.
    +     * reduction.
    +     *
    +     * 

    This is a terminal + * operation. * * @return an {@code OptionalDouble} containing the average element of this * stream, or an empty optional if the stream is empty @@ -545,7 +599,10 @@ public interface DoubleStream extends BaseStream { /** * Returns a {@code DoubleSummaryStatistics} describing various summary data * about the elements of this stream. This is a special - * case of a reduction. + * case of a reduction. + * + *

    This is a terminal + * operation. * * @return a {@code DoubleSummaryStatistics} describing various summary data * about the elements of this stream @@ -602,9 +659,8 @@ public interface DoubleStream extends BaseStream { /** * Returns an {@link OptionalDouble} describing the first element of this - * stream (in the encounter order), or an empty {@code OptionalDouble} if - * the stream is empty. If the stream has no encounter order, then any - * element may be returned. + * stream, or an empty {@code OptionalDouble} if the stream is empty. If + * the stream has no encounter order, then any element may be returned. * *

    This is a short-circuiting * terminal operation. @@ -624,8 +680,8 @@ public interface DoubleStream extends BaseStream { *

    The behavior of this operation is explicitly nondeterministic; it is * free to select any element in the stream. This is to allow for maximal * performance in parallel operations; the cost is that multiple invocations - * on the same source may not return the same result. (If the first element - * in the encounter order is desired, use {@link #findFirst()} instead.) + * on the same source may not return the same result. (If a stable result + * is desired, use {@link #findFirst()} instead.) * * @return an {@code OptionalDouble} describing some element of this stream, * or an empty {@code OptionalDouble} if the stream is empty @@ -637,6 +693,9 @@ public interface DoubleStream extends BaseStream { * Returns a {@code Stream} consisting of the elements of this stream, * boxed to {@code Double}. * + *

    This is an intermediate + * operation. + * * @return a {@code Stream} consistent of the elements of this stream, * each boxed to a {@code Double} */ @@ -686,7 +745,7 @@ public interface DoubleStream extends BaseStream { } /** - * Returns a sequential stream whose elements are the specified values. + * Returns a sequential ordered stream whose elements are the specified values. * * @param values the elements of the new stream * @return the new stream @@ -696,7 +755,7 @@ public interface DoubleStream extends BaseStream { } /** - * Returns an infinite sequential {@code DoubleStream} produced by iterative + * Returns an infinite sequential ordered {@code DoubleStream} produced by iterative * application of a function {@code f} to an initial element {@code seed}, * producing a {@code Stream} consisting of {@code seed}, {@code f(seed)}, * {@code f(f(seed))}, etc. @@ -734,8 +793,8 @@ public interface DoubleStream extends BaseStream { } /** - * Returns a sequential {@code DoubleStream} where each element is - * generated by an {@code DoubleSupplier}. This is suitable for generating + * Returns a sequential stream where each element is generated by + * the provided {@code DoubleSupplier}. This is suitable for generating * constant streams, streams of random elements, etc. * * @param s the {@code DoubleSupplier} for generated elements @@ -748,16 +807,16 @@ public interface DoubleStream extends BaseStream { } /** - * Creates a lazy concatenated {@code DoubleStream} whose elements are all the - * elements of a first {@code DoubleStream} succeeded by all the elements of the - * second {@code DoubleStream}. The resulting stream is ordered if both + * Creates a lazily concatenated stream whose elements are all the + * elements of the first stream followed by all the elements of the + * second stream. The resulting stream is ordered if both * of the input streams are ordered, and parallel if either of the input * streams is parallel. When the resulting stream is closed, the close * handlers for both input streams are invoked. * * @param a the first stream - * @param b the second stream to concatenate on to end of the first stream - * @return the concatenation of the two streams + * @param b the second stream + * @return the concatenation of the two input streams */ public static DoubleStream concat(DoubleStream a, DoubleStream b) { Objects.requireNonNull(a); @@ -772,9 +831,9 @@ public interface DoubleStream extends BaseStream { /** * A mutable builder for a {@code DoubleStream}. * - *

    A stream builder has a lifecycle, where it starts in a building - * phase, during which elements can be added, and then transitions to a - * built phase, after which elements may not be added. The built phase + *

    A stream builder has a lifecycle, which starts in a building + * phase, during which elements can be added, and then transitions to a built + * phase, after which elements may not be added. The built phase * begins when the {@link #build()} method is called, which creates an * ordered stream whose elements are the elements that were added to the * stream builder, in the order they were added. diff --git a/jdk/src/share/classes/java/util/stream/IntPipeline.java b/jdk/src/share/classes/java/util/stream/IntPipeline.java index f35bc1d7a8e..13f7e0a9731 100644 --- a/jdk/src/share/classes/java/util/stream/IntPipeline.java +++ b/jdk/src/share/classes/java/util/stream/IntPipeline.java @@ -349,8 +349,8 @@ abstract class IntPipeline } @Override - public final IntStream peek(IntConsumer consumer) { - Objects.requireNonNull(consumer); + public final IntStream peek(IntConsumer action) { + Objects.requireNonNull(action); return new StatelessOp(this, StreamShape.INT_VALUE, 0) { @Override @@ -358,7 +358,7 @@ abstract class IntPipeline return new Sink.ChainedInt(sink) { @Override public void accept(int t) { - consumer.accept(t); + action.accept(t); downstream.accept(t); } }; @@ -473,14 +473,14 @@ abstract class IntPipeline } @Override - public final R collect(Supplier resultFactory, + public final R collect(Supplier supplier, ObjIntConsumer accumulator, BiConsumer combiner) { BinaryOperator operator = (left, right) -> { combiner.accept(left, right); return left; }; - return evaluate(ReduceOps.makeInt(resultFactory, accumulator, operator)); + return evaluate(ReduceOps.makeInt(supplier, accumulator, operator)); } @Override diff --git a/jdk/src/share/classes/java/util/stream/IntStream.java b/jdk/src/share/classes/java/util/stream/IntStream.java index c107ca46de9..07f9ab5dc78 100644 --- a/jdk/src/share/classes/java/util/stream/IntStream.java +++ b/jdk/src/share/classes/java/util/stream/IntStream.java @@ -24,7 +24,11 @@ */ package java.util.stream; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Arrays; +import java.util.Collection; import java.util.IntSummaryStatistics; import java.util.Objects; import java.util.OptionalDouble; @@ -32,6 +36,7 @@ import java.util.OptionalInt; import java.util.PrimitiveIterator; import java.util.Spliterator; import java.util.Spliterators; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.function.IntBinaryOperator; @@ -46,40 +51,87 @@ import java.util.function.ObjIntConsumer; import java.util.function.Supplier; /** - * A sequence of primitive integer elements supporting sequential and parallel - * bulk operations. Streams support lazy intermediate operations (transforming - * a stream to another stream) such as {@code filter} and {@code map}, and terminal - * operations (consuming the contents of a stream to produce a result or - * side-effect), such as {@code forEach}, {@code findFirst}, and {@code - * iterator}. Once an operation has been performed on a stream, it - * is considered consumed and no longer usable for other operations. + * A sequence of elements supporting sequential and parallel aggregate + * operations. The following example illustrates an aggregate operation using + * {@link Stream} and {@link IntStream}: * - *

    For sequential stream pipelines, all operations are performed in the - * encounter order of the pipeline - * source, if the pipeline source has a defined encounter order. + *

    {@code
    + *     int sum = widgets.stream()
    + *                      .filter(w -> w.getColor() == RED)
    + *                      .mapToInt(w -> w.getWeight())
    + *                      .sum();
    + * }
    * - *

    For parallel stream pipelines, unless otherwise specified, intermediate - * stream operations preserve the - * encounter order of their source, and terminal operations - * respect the encounter order of their source, if the source - * has an encounter order. Provided that and parameters to stream operations - * satisfy the non-interference - * requirements, and excepting differences arising from the absence of - * a defined encounter order, the result of a stream pipeline should be the - * stable across multiple executions of the same operations on the same source. - * However, the timing and thread in which side-effects occur (for those - * operations which are allowed to produce side-effects, such as - * {@link #forEach(IntConsumer)}), are explicitly nondeterministic for parallel - * execution of stream pipelines. + * In this example, {@code widgets} is a {@code Collection}. We create + * a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()}, + * filter it to produce a stream containing only the red widgets, and then + * transform it into a stream of {@code int} values representing the weight of + * each red widget. Then this stream is summed to produce a total weight. * - *

    Unless otherwise noted, passing a {@code null} argument to any stream - * method may result in a {@link NullPointerException}. + *

    To perform a computation, stream + * operations are composed into a + * stream pipeline. A stream pipeline consists of a source (which + * might be an array, a collection, a generator function, an IO channel, + * etc), zero or more intermediate operations (which transform a + * stream into another stream, such as {@link IntStream#filter(IntPredicate)}), and a + * terminal operation (which produces a result or side-effect, such + * as {@link IntStream#sum()} or {@link IntStream#forEach(IntConsumer)}). + * Streams are lazy; computation on the source data is only performed when the + * terminal operation is initiated, and source elements are consumed only + * as needed. * - * @apiNote - * Streams are not data structures; they do not manage the storage for their - * elements, nor do they support access to individual elements. However, - * you can use the {@link #iterator()} or {@link #spliterator()} operations to - * perform a controlled traversal. + *

    Collections and streams, while bearing some superficial similarities, + * have different goals. Collections are primarily concerned with the efficient + * management of, and access to, their elements. By contrast, streams do not + * provide a means to directly access or manipulate their elements, and are + * instead concerned with declaratively describing their source and the + * computational operations which will be performed in aggregate on that source. + * However, if the provided stream operations do not offer the desired + * functionality, the {@link #iterator()} and {@link #spliterator()} operations + * can be used to perform a controlled traversal. + * + *

    A stream pipeline, like the "widgets" example above, can be viewed as + * a query on the stream source. Unless the source was explicitly + * designed for concurrent modification (such as a {@link ConcurrentHashMap}), + * unpredictable or erroneous behavior may result from modifying the stream + * source while it is being queried. + * + *

    Most stream operations accept parameters that describe user-specified + * behavior, such as the lambda expression {@code w -> w.getWeight()} passed to + * {@code mapToInt} in the example above. Such parameters are always instances + * of a functional interface such + * as {@link java.util.function.Function}, and are often lambda expressions or + * method references. These parameters can never be null, should not modify the + * stream source, and should be + * effectively stateless + * (their result should not depend on any state that might change during + * execution of the stream pipeline.) + * + *

    A stream should be operated on (invoking an intermediate or terminal stream + * operation) only once. This rules out, for example, "forked" streams, where + * the same source feeds two or more pipelines, or multiple traversals of the + * same stream. A stream implementation may throw {@link IllegalStateException} + * if it detects that the stream is being reused. However, since some stream + * operations may return their receiver rather than a new stream object, it may + * not be possible to detect reuse in all cases. + * + *

    Streams have a {@link #close()} method and implement {@link AutoCloseable}, + * but nearly all stream instances do not actually need to be closed after use. + * Generally, only streams whose source is an IO channel (such as those returned + * by {@link Files#lines(Path, Charset)}) will require closing. Most streams + * are backed by collections, arrays, or generating functions, which require no + * special resource management. (If a stream does require closing, it can be + * declared as a resource in a {@code try}-with-resources statement.) + * + *

    Stream pipelines may execute either sequentially or in + * parallel. This + * execution mode is a property of the stream. Streams are created + * with an initial choice of sequential or parallel execution. (For example, + * {@link Collection#stream() Collection.stream()} creates a sequential stream, + * and {@link Collection#parallelStream() Collection.parallelStream()} creates + * a parallel one.) This choice of execution mode may be modified by the + * {@link #sequential()} or {@link #parallel()} methods, and may be queried with + * the {@link #isParallel()} method. * * @since 1.8 * @see java.util.stream @@ -160,22 +212,13 @@ public interface IntStream extends BaseStream { /** * Returns a stream consisting of the results of replacing each element of * this stream with the contents of the stream produced by applying the - * provided mapping function to each element. + * provided mapping function to each element. (If the result of the mapping + * function is {@code null}, this is treated as if the result was an empty + * stream.) * *

    This is an intermediate * operation. * - * @apiNote - * The {@code flatMap()} operation has the effect of applying a one-to-many - * tranformation to the elements of the stream, and then flattening the - * resulting elements into a new stream. For example, if {@code orders} - * is a stream of purchase orders, and each purchase order contains a - * collection of line items, then the following produces a stream of line - * items: - *

    {@code
    -     *     orderStream.flatMap(order -> order.getLineItems().stream())...
    -     * }
    - * * @param mapper a * non-interfering, stateless function to apply to * each element which produces an {@code IntStream} of new @@ -224,18 +267,18 @@ public interface IntStream extends BaseStream { *
    {@code
          *     list.stream()
          *         .filter(filteringFunction)
    -     *         .peek(e -> {System.out.println("Filtered value: " + e); });
    +     *         .peek(e -> System.out.println("Filtered value: " + e));
          *         .map(mappingFunction)
    -     *         .peek(e -> {System.out.println("Mapped value: " + e); });
    +     *         .peek(e -> System.out.println("Mapped value: " + e));
          *         .collect(Collectors.toIntSummaryStastistics());
          * }
    * - * @param consumer a - * non-interfering action to perform on the elements as - * they are consumed from the stream + * @param action a + * non-interfering action to perform on the elements as + * they are consumed from the stream * @return the new stream */ - IntStream peek(IntConsumer consumer); + IntStream peek(IntConsumer action); /** * Returns a stream consisting of the elements of this stream, truncated @@ -252,8 +295,8 @@ public interface IntStream extends BaseStream { /** * Returns a stream consisting of the remaining elements of this stream - * after indexing {@code startInclusive} elements into the stream. If the - * {@code startInclusive} index lies past the end of this stream then an + * after discarding the first {@code startInclusive} elements of the stream. + * If this stream contains fewer than {@code startInclusive} elements then an * empty stream will be returned. * *

    This is a stateful @@ -267,10 +310,10 @@ public interface IntStream extends BaseStream { /** * Returns a stream consisting of the remaining elements of this stream - * after indexing {@code startInclusive} elements into the stream and - * truncated to contain no more than {@code endExclusive - startInclusive} - * elements. If the {@code startInclusive} index lies past the end - * of this stream then an empty stream will be returned. + * after discarding the first {@code startInclusive} elements and truncating + * the result to be no longer than {@code endExclusive - startInclusive} + * elements in length. If this stream contains fewer than + * {@code startInclusive} elements then an empty stream will be returned. * *

    This is a short-circuiting * stateful intermediate operation. @@ -419,12 +462,12 @@ public interface IntStream extends BaseStream { /** * Performs a mutable * reduction operation on the elements of this stream. A mutable - * reduction is one in which the reduced value is a mutable value holder, + * reduction is one in which the reduced value is a mutable result container, * such as an {@code ArrayList}, and elements are incorporated by updating - * the state of the result, rather than by replacing the result. This + * the state of the result rather than by replacing the result. This * produces a result equivalent to: *

    {@code
    -     *     R result = resultFactory.get();
    +     *     R result = supplier.get();
          *     for (int element : this stream)
          *         accumulator.accept(result, element);
          *     return result;
    @@ -437,10 +480,9 @@ public interface IntStream extends BaseStream {
          * operation.
          *
          * @param  type of the result
    -     * @param resultFactory a function that creates a new result container.
    -     *                      For a parallel execution, this function may be
    -     *                      called multiple times and must return a fresh value
    -     *                      each time.
    +     * @param supplier a function that creates a new result container. For a
    +     *                 parallel execution, this function may be called
    +     *                 multiple times and must return a fresh value each time.
          * @param accumulator an associative
          *                    non-interfering,
          *                    stateless function for incorporating an additional
    @@ -452,18 +494,21 @@ public interface IntStream extends BaseStream {
          * @return the result of the reduction
          * @see Stream#collect(Supplier, BiConsumer, BiConsumer)
          */
    -     R collect(Supplier resultFactory,
    +     R collect(Supplier supplier,
                       ObjIntConsumer accumulator,
                       BiConsumer combiner);
     
         /**
          * Returns the sum of elements in this stream.  This is a special case
    -     * of a reduction
    +     * of a reduction
          * and is equivalent to:
          * 
    {@code
          *     return reduce(0, Integer::sum);
          * }
    * + *

    This is a terminal + * operation. + * * @return the sum of elements in this stream */ int sum(); @@ -471,7 +516,7 @@ public interface IntStream extends BaseStream { /** * Returns an {@code OptionalInt} describing the minimum element of this * stream, or an empty optional if this stream is empty. This is a special - * case of a reduction + * case of a reduction * and is equivalent to: *

    {@code
          *     return reduce(Integer::min);
    @@ -479,7 +524,6 @@ public interface IntStream extends BaseStream {
          *
          * 

    This is a terminal operation. * - * @return an {@code OptionalInt} containing the minimum element of this * stream, or an empty {@code OptionalInt} if the stream is empty */ @@ -488,7 +532,7 @@ public interface IntStream extends BaseStream { /** * Returns an {@code OptionalInt} describing the maximum element of this * stream, or an empty optional if this stream is empty. This is a special - * case of a reduction + * case of a reduction * and is equivalent to: *

    {@code
          *     return reduce(Integer::max);
    @@ -504,7 +548,7 @@ public interface IntStream extends BaseStream {
     
         /**
          * Returns the count of elements in this stream.  This is a special case of
    -     * a reduction and is
    +     * a reduction and is
          * equivalent to:
          * 
    {@code
          *     return mapToLong(e -> 1L).sum();
    @@ -520,7 +564,10 @@ public interface IntStream extends BaseStream {
          * Returns an {@code OptionalDouble} describing the arithmetic mean of elements of
          * this stream, or an empty optional if this stream is empty.  This is a
          * special case of a
    -     * reduction.
    +     * reduction.
    +     *
    +     * 

    This is a terminal + * operation. * * @return an {@code OptionalDouble} containing the average element of this * stream, or an empty optional if the stream is empty @@ -530,7 +577,10 @@ public interface IntStream extends BaseStream { /** * Returns an {@code IntSummaryStatistics} describing various * summary data about the elements of this stream. This is a special - * case of a reduction. + * case of a reduction. + * + *

    This is a terminal + * operation. * * @return an {@code IntSummaryStatistics} describing various summary data * about the elements of this stream @@ -587,9 +637,8 @@ public interface IntStream extends BaseStream { /** * Returns an {@link OptionalInt} describing the first element of this - * stream (in the encounter order), or an empty {@code OptionalInt} if the - * stream is empty. If the stream has no encounter order, then any element - * may be returned. + * stream, or an empty {@code OptionalInt} if the stream is empty. If the + * stream has no encounter order, then any element may be returned. * *

    This is a short-circuiting * terminal operation. @@ -609,8 +658,8 @@ public interface IntStream extends BaseStream { *

    The behavior of this operation is explicitly nondeterministic; it is * free to select any element in the stream. This is to allow for maximal * performance in parallel operations; the cost is that multiple invocations - * on the same source may not return the same result. (If the first element - * in the encounter order is desired, use {@link #findFirst()} instead.) + * on the same source may not return the same result. (If a stable result + * is desired, use {@link #findFirst()} instead.) * * @return an {@code OptionalInt} describing some element of this stream, or * an empty {@code OptionalInt} if the stream is empty @@ -622,6 +671,9 @@ public interface IntStream extends BaseStream { * Returns a {@code LongStream} consisting of the elements of this stream, * converted to {@code long}. * + *

    This is an intermediate + * operation. + * * @return a {@code LongStream} consisting of the elements of this stream, * converted to {@code long} */ @@ -631,6 +683,9 @@ public interface IntStream extends BaseStream { * Returns a {@code DoubleStream} consisting of the elements of this stream, * converted to {@code double}. * + *

    This is an intermediate + * operation. + * * @return a {@code DoubleStream} consisting of the elements of this stream, * converted to {@code double} */ @@ -640,6 +695,9 @@ public interface IntStream extends BaseStream { * Returns a {@code Stream} consisting of the elements of this stream, * each boxed to an {@code Integer}. * + *

    This is an intermediate + * operation. + * * @return a {@code Stream} consistent of the elements of this stream, * each boxed to an {@code Integer} */ @@ -688,7 +746,7 @@ public interface IntStream extends BaseStream { } /** - * Returns a sequential stream whose elements are the specified values. + * Returns a sequential ordered stream whose elements are the specified values. * * @param values the elements of the new stream * @return the new stream @@ -698,7 +756,7 @@ public interface IntStream extends BaseStream { } /** - * Returns an infinite sequential {@code IntStream} produced by iterative + * Returns an infinite sequential ordered {@code IntStream} produced by iterative * application of a function {@code f} to an initial element {@code seed}, * producing a {@code Stream} consisting of {@code seed}, {@code f(seed)}, * {@code f(f(seed))}, etc. @@ -736,8 +794,8 @@ public interface IntStream extends BaseStream { } /** - * Returns a sequential {@code IntStream} where each element is - * generated by an {@code IntSupplier}. This is suitable for generating + * Returns a sequential stream where each element is generated by + * the provided {@code IntSupplier}. This is suitable for generating * constant streams, streams of random elements, etc. * * @param s the {@code IntSupplier} for generated elements @@ -750,7 +808,7 @@ public interface IntStream extends BaseStream { } /** - * Returns a sequential {@code IntStream} from {@code startInclusive} + * Returns a sequential ordered {@code IntStream} from {@code startInclusive} * (inclusive) to {@code endExclusive} (exclusive) by an incremental step of * {@code 1}. * @@ -776,7 +834,7 @@ public interface IntStream extends BaseStream { } /** - * Returns a sequential {@code IntStream} from {@code startInclusive} + * Returns a sequential ordered {@code IntStream} from {@code startInclusive} * (inclusive) to {@code endInclusive} (inclusive) by an incremental step of * {@code 1}. * @@ -802,16 +860,16 @@ public interface IntStream extends BaseStream { } /** - * Creates a lazy concatenated {@code IntStream} whose elements are all the - * elements of a first {@code IntStream} succeeded by all the elements of the - * second {@code IntStream}. The resulting stream is ordered if both + * Creates a lazily concatenated stream whose elements are all the + * elements of the first stream followed by all the elements of the + * second stream. The resulting stream is ordered if both * of the input streams are ordered, and parallel if either of the input * streams is parallel. When the resulting stream is closed, the close * handlers for both input streams are invoked. * * @param a the first stream - * @param b the second stream to concatenate on to end of the first stream - * @return the concatenation of the two streams + * @param b the second stream + * @return the concatenation of the two input streams */ public static IntStream concat(IntStream a, IntStream b) { Objects.requireNonNull(a); @@ -826,9 +884,9 @@ public interface IntStream extends BaseStream { /** * A mutable builder for an {@code IntStream}. * - *

    A stream builder has a lifecycle, where it starts in a building - * phase, during which elements can be added, and then transitions to a - * built phase, after which elements may not be added. The built phase + *

    A stream builder has a lifecycle, which starts in a building + * phase, during which elements can be added, and then transitions to a built + * phase, after which elements may not be added. The built phase * begins when the {@link #build()} method is called, which creates an * ordered stream whose elements are the elements that were added to the * stream builder, in the order they were added. diff --git a/jdk/src/share/classes/java/util/stream/LongPipeline.java b/jdk/src/share/classes/java/util/stream/LongPipeline.java index a59ec3f5f00..5ed030e02a1 100644 --- a/jdk/src/share/classes/java/util/stream/LongPipeline.java +++ b/jdk/src/share/classes/java/util/stream/LongPipeline.java @@ -330,8 +330,8 @@ abstract class LongPipeline } @Override - public final LongStream peek(LongConsumer consumer) { - Objects.requireNonNull(consumer); + public final LongStream peek(LongConsumer action) { + Objects.requireNonNull(action); return new StatelessOp(this, StreamShape.LONG_VALUE, 0) { @Override @@ -339,7 +339,7 @@ abstract class LongPipeline return new Sink.ChainedLong(sink) { @Override public void accept(long t) { - consumer.accept(t); + action.accept(t); downstream.accept(t); } }; @@ -455,14 +455,14 @@ abstract class LongPipeline } @Override - public final R collect(Supplier resultFactory, + public final R collect(Supplier supplier, ObjLongConsumer accumulator, BiConsumer combiner) { BinaryOperator operator = (left, right) -> { combiner.accept(left, right); return left; }; - return evaluate(ReduceOps.makeLong(resultFactory, accumulator, operator)); + return evaluate(ReduceOps.makeLong(supplier, accumulator, operator)); } @Override diff --git a/jdk/src/share/classes/java/util/stream/LongStream.java b/jdk/src/share/classes/java/util/stream/LongStream.java index e64c67204dc..ca61d2f200e 100644 --- a/jdk/src/share/classes/java/util/stream/LongStream.java +++ b/jdk/src/share/classes/java/util/stream/LongStream.java @@ -24,7 +24,11 @@ */ package java.util.stream; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Arrays; +import java.util.Collection; import java.util.LongSummaryStatistics; import java.util.Objects; import java.util.OptionalDouble; @@ -32,6 +36,7 @@ import java.util.OptionalLong; import java.util.PrimitiveIterator; import java.util.Spliterator; import java.util.Spliterators; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.function.LongBinaryOperator; @@ -46,40 +51,87 @@ import java.util.function.ObjLongConsumer; import java.util.function.Supplier; /** - * A sequence of primitive long elements supporting sequential and parallel - * bulk operations. Streams support lazy intermediate operations (transforming - * a stream to another stream) such as {@code filter} and {@code map}, and terminal - * operations (consuming the contents of a stream to produce a result or - * side-effect), such as {@code forEach}, {@code findFirst}, and {@code - * iterator}. Once an operation has been performed on a stream, it - * is considered consumed and no longer usable for other operations. + * A sequence of elements supporting sequential and parallel aggregate + * operations. The following example illustrates an aggregate operation using + * {@link Stream} and {@link LongStream}: * - *

    For sequential stream pipelines, all operations are performed in the - * encounter order of the pipeline - * source, if the pipeline source has a defined encounter order. + *

    {@code
    + *     long sum = widgets.stream()
    + *                       .filter(w -> w.getColor() == RED)
    + *                       .mapToLong(w -> w.getWeight())
    + *                       .sum();
    + * }
    * - *

    For parallel stream pipelines, unless otherwise specified, intermediate - * stream operations preserve the - * encounter order of their source, and terminal operations - * respect the encounter order of their source, if the source - * has an encounter order. Provided that and parameters to stream operations - * satisfy the non-interference - * requirements, and excepting differences arising from the absence of - * a defined encounter order, the result of a stream pipeline should be the - * stable across multiple executions of the same operations on the same source. - * However, the timing and thread in which side-effects occur (for those - * operations which are allowed to produce side-effects, such as - * {@link #forEach(LongConsumer)}), are explicitly nondeterministic for parallel - * execution of stream pipelines. + * In this example, {@code widgets} is a {@code Collection}. We create + * a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()}, + * filter it to produce a stream containing only the red widgets, and then + * transform it into a stream of {@code long} values representing the weight of + * each red widget. Then this stream is summed to produce a total weight. * - *

    Unless otherwise noted, passing a {@code null} argument to any stream - * method may result in a {@link NullPointerException}. + *

    To perform a computation, stream + * operations are composed into a + * stream pipeline. A stream pipeline consists of a source (which + * might be an array, a collection, a generator function, an IO channel, + * etc), zero or more intermediate operations (which transform a + * stream into another stream, such as {@link LongStream#filter(LongPredicate)}), and a + * terminal operation (which produces a result or side-effect, such + * as {@link LongStream#sum()} or {@link LongStream#forEach(LongConsumer)}). + * Streams are lazy; computation on the source data is only performed when the + * terminal operation is initiated, and source elements are consumed only + * as needed. * - * @apiNote - * Streams are not data structures; they do not manage the storage for their - * elements, nor do they support access to individual elements. However, - * you can use the {@link #iterator()} or {@link #spliterator()} operations to - * perform a controlled traversal. + *

    Collections and streams, while bearing some superficial similarities, + * have different goals. Collections are primarily concerned with the efficient + * management of, and access to, their elements. By contrast, streams do not + * provide a means to directly access or manipulate their elements, and are + * instead concerned with declaratively describing their source and the + * computational operations which will be performed in aggregate on that source. + * However, if the provided stream operations do not offer the desired + * functionality, the {@link #iterator()} and {@link #spliterator()} operations + * can be used to perform a controlled traversal. + * + *

    A stream pipeline, like the "widgets" example above, can be viewed as + * a query on the stream source. Unless the source was explicitly + * designed for concurrent modification (such as a {@link ConcurrentHashMap}), + * unpredictable or erroneous behavior may result from modifying the stream + * source while it is being queried. + * + *

    Most stream operations accept parameters that describe user-specified + * behavior, such as the lambda expression {@code w -> w.getWeight()} passed to + * {@code mapToLong} in the example above. Such parameters are always instances + * of a functional interface such + * as {@link java.util.function.Function}, and are often lambda expressions or + * method references. These parameters can never be null, should not modify the + * stream source, and should be + * effectively stateless + * (their result should not depend on any state that might change during + * execution of the stream pipeline.) + * + *

    A stream should be operated on (invoking an intermediate or terminal stream + * operation) only once. This rules out, for example, "forked" streams, where + * the same source feeds two or more pipelines, or multiple traversals of the + * same stream. A stream implementation may throw {@link IllegalStateException} + * if it detects that the stream is being reused. However, since some stream + * operations may return their receiver rather than a new stream object, it may + * not be possible to detect reuse in all cases. + * + *

    Streams have a {@link #close()} method and implement {@link AutoCloseable}, + * but nearly all stream instances do not actually need to be closed after use. + * Generally, only streams whose source is an IO channel (such as those returned + * by {@link Files#lines(Path, Charset)}) will require closing. Most streams + * are backed by collections, arrays, or generating functions, which require no + * special resource management. (If a stream does require closing, it can be + * declared as a resource in a {@code try}-with-resources statement.) + * + *

    Stream pipelines may execute either sequentially or in + * parallel. This + * execution mode is a property of the stream. Streams are created + * with an initial choice of sequential or parallel execution. (For example, + * {@link Collection#stream() Collection.stream()} creates a sequential stream, + * and {@link Collection#parallelStream() Collection.parallelStream()} creates + * a parallel one.) This choice of execution mode may be modified by the + * {@link #sequential()} or {@link #parallel()} methods, and may be queried with + * the {@link #isParallel()} method. * * @since 1.8 * @see java.util.stream @@ -160,22 +212,13 @@ public interface LongStream extends BaseStream { /** * Returns a stream consisting of the results of replacing each element of * this stream with the contents of the stream produced by applying the - * provided mapping function to each element. + * provided mapping function to each element. (If the result of the mapping + * function is {@code null}, this is treated as if the result was an empty + * stream.) * *

    This is an intermediate * operation. * - * @apiNote - * The {@code flatMap()} operation has the effect of applying a one-to-many - * tranformation to the elements of the stream, and then flattening the - * resulting elements into a new stream. For example, if {@code orders} - * is a stream of purchase orders, and each purchase order contains a - * collection of line items, then the following produces a stream of line - * items: - *

    {@code
    -     *     orderStream.flatMap(order -> order.getLineItems().stream())...
    -     * }
    - * * @param mapper a * non-interfering, stateless function to apply to * each element which produces an {@code LongStream} of new @@ -224,18 +267,18 @@ public interface LongStream extends BaseStream { *
    {@code
          *     list.stream()
          *         .filter(filteringFunction)
    -     *         .peek(e -> {System.out.println("Filtered value: " + e); });
    +     *         .peek(e -> System.out.println("Filtered value: " + e));
          *         .map(mappingFunction)
    -     *         .peek(e -> {System.out.println("Mapped value: " + e); });
    +     *         .peek(e -> System.out.println("Mapped value: " + e));
          *         .collect(Collectors.toLongSummaryStastistics());
          * }
    * - * @param consumer a - * non-interfering action to perform on the elements as - * they are consumed from the stream + * @param action a + * non-interfering action to perform on the elements as + * they are consumed from the stream * @return the new stream */ - LongStream peek(LongConsumer consumer); + LongStream peek(LongConsumer action); /** * Returns a stream consisting of the elements of this stream, truncated @@ -252,8 +295,8 @@ public interface LongStream extends BaseStream { /** * Returns a stream consisting of the remaining elements of this stream - * after indexing {@code startInclusive} elements into the stream. If the - * {@code startInclusive} index lies past the end of this stream then an + * after discarding the first {@code startInclusive} elements of the stream. + * If this stream contains fewer than {@code startInclusive} elements then an * empty stream will be returned. * *

    This is a stateful @@ -267,10 +310,10 @@ public interface LongStream extends BaseStream { /** * Returns a stream consisting of the remaining elements of this stream - * after indexing {@code startInclusive} elements into the stream and - * truncated to contain no more than {@code endExclusive - startInclusive} - * elements. If the {@code startInclusive} index lies past the end - * of this stream then an empty stream will be returned. + * after discarding the first {@code startInclusive} elements and truncating + * the result to be no longer than {@code endExclusive - startInclusive} + * elements in length. If this stream contains fewer than + * {@code startInclusive} elements then an empty stream will be returned. * *

    This is a short-circuiting * stateful intermediate operation. @@ -419,12 +462,12 @@ public interface LongStream extends BaseStream { /** * Performs a mutable * reduction operation on the elements of this stream. A mutable - * reduction is one in which the reduced value is a mutable value holder, + * reduction is one in which the reduced value is a mutable result container, * such as an {@code ArrayList}, and elements are incorporated by updating - * the state of the result, rather than by replacing the result. This + * the state of the result rather than by replacing the result. This * produces a result equivalent to: *

    {@code
    -     *     R result = resultFactory.get();
    +     *     R result = supplier.get();
          *     for (long element : this stream)
          *         accumulator.accept(result, element);
          *     return result;
    @@ -437,10 +480,9 @@ public interface LongStream extends BaseStream {
          * operation.
          *
          * @param  type of the result
    -     * @param resultFactory a function that creates a new result container.
    -     *                      For a parallel execution, this function may be
    -     *                      called multiple times and must return a fresh value
    -     *                      each time.
    +     * @param supplier a function that creates a new result container. For a
    +     *                 parallel execution, this function may be called
    +     *                 multiple times and must return a fresh value each time.
          * @param accumulator an associative
          *                    non-interfering,
          *                    stateless function for incorporating an additional
    @@ -452,18 +494,21 @@ public interface LongStream extends BaseStream {
          * @return the result of the reduction
          * @see Stream#collect(Supplier, BiConsumer, BiConsumer)
          */
    -     R collect(Supplier resultFactory,
    +     R collect(Supplier supplier,
                       ObjLongConsumer accumulator,
                       BiConsumer combiner);
     
         /**
          * Returns the sum of elements in this stream.  This is a special case
    -     * of a reduction
    +     * of a reduction
          * and is equivalent to:
          * 
    {@code
          *     return reduce(0, Long::sum);
          * }
    * + *

    This is a terminal + * operation. + * * @return the sum of elements in this stream */ long sum(); @@ -471,7 +516,7 @@ public interface LongStream extends BaseStream { /** * Returns an {@code OptionalLong} describing the minimum element of this * stream, or an empty optional if this stream is empty. This is a special - * case of a reduction + * case of a reduction * and is equivalent to: *

    {@code
          *     return reduce(Long::min);
    @@ -479,7 +524,6 @@ public interface LongStream extends BaseStream {
          *
          * 

    This is a terminal operation. * - * @return an {@code OptionalLong} containing the minimum element of this * stream, or an empty {@code OptionalLong} if the stream is empty */ @@ -488,7 +532,7 @@ public interface LongStream extends BaseStream { /** * Returns an {@code OptionalLong} describing the maximum element of this * stream, or an empty optional if this stream is empty. This is a special - * case of a reduction + * case of a reduction * and is equivalent to: *

    {@code
          *     return reduce(Long::max);
    @@ -504,7 +548,7 @@ public interface LongStream extends BaseStream {
     
         /**
          * Returns the count of elements in this stream.  This is a special case of
    -     * a reduction and is
    +     * a reduction and is
          * equivalent to:
          * 
    {@code
          *     return map(e -> 1L).sum();
    @@ -520,7 +564,10 @@ public interface LongStream extends BaseStream {
          * Returns an {@code OptionalDouble} describing the arithmetic mean of elements of
          * this stream, or an empty optional if this stream is empty.  This is a
          * special case of a
    -     * reduction.
    +     * reduction.
    +     *
    +     * 

    This is a terminal + * operation. * * @return an {@code OptionalDouble} containing the average element of this * stream, or an empty optional if the stream is empty @@ -530,7 +577,10 @@ public interface LongStream extends BaseStream { /** * Returns a {@code LongSummaryStatistics} describing various summary data * about the elements of this stream. This is a special case of a - * reduction. + * reduction. + * + *

    This is a terminal + * operation. * * @return a {@code LongSummaryStatistics} describing various summary data * about the elements of this stream @@ -587,9 +637,8 @@ public interface LongStream extends BaseStream { /** * Returns an {@link OptionalLong} describing the first element of this - * stream (in the encounter order), or an empty {@code OptionalLong} if the - * stream is empty. If the stream has no encounter order, then any element - * may be returned. + * stream, or an empty {@code OptionalLong} if the stream is empty. If the + * stream has no encounter order, then any element may be returned. * *

    This is a short-circuiting * terminal operation. @@ -609,8 +658,8 @@ public interface LongStream extends BaseStream { *

    The behavior of this operation is explicitly nondeterministic; it is * free to select any element in the stream. This is to allow for maximal * performance in parallel operations; the cost is that multiple invocations - * on the same source may not return the same result. (If the first element - * in the encounter order is desired, use {@link #findFirst()} instead.) + * on the same source may not return the same result. (If a stable result + * is desired, use {@link #findFirst()} instead.) * * @return an {@code OptionalLong} describing some element of this stream, * or an empty {@code OptionalLong} if the stream is empty @@ -622,6 +671,9 @@ public interface LongStream extends BaseStream { * Returns a {@code DoubleStream} consisting of the elements of this stream, * converted to {@code double}. * + *

    This is an intermediate + * operation. + * * @return a {@code DoubleStream} consisting of the elements of this stream, * converted to {@code double} */ @@ -631,6 +683,9 @@ public interface LongStream extends BaseStream { * Returns a {@code Stream} consisting of the elements of this stream, * each boxed to a {@code Long}. * + *

    This is an intermediate + * operation. + * * @return a {@code Stream} consistent of the elements of this stream, * each boxed to {@code Long} */ @@ -679,7 +734,7 @@ public interface LongStream extends BaseStream { } /** - * Returns a sequential stream whose elements are the specified values. + * Returns a sequential ordered stream whose elements are the specified values. * * @param values the elements of the new stream * @return the new stream @@ -689,7 +744,7 @@ public interface LongStream extends BaseStream { } /** - * Returns an infinite sequential {@code LongStream} produced by iterative + * Returns an infinite sequential ordered {@code LongStream} produced by iterative * application of a function {@code f} to an initial element {@code seed}, * producing a {@code Stream} consisting of {@code seed}, {@code f(seed)}, * {@code f(f(seed))}, etc. @@ -727,9 +782,9 @@ public interface LongStream extends BaseStream { } /** - * Returns a sequential {@code LongStream} where each element is generated - * by a {@code LongSupplier}. This is suitable for generating constant - * streams, streams of random elements, etc. + * Returns a sequential stream where each element is generated by + * the provided {@code LongSupplier}. This is suitable for generating + * constant streams, streams of random elements, etc. * * @param s the {@code LongSupplier} for generated elements * @return a new sequential {@code LongStream} @@ -741,7 +796,7 @@ public interface LongStream extends BaseStream { } /** - * Returns a sequential {@code LongStream} from {@code startInclusive} + * Returns a sequential ordered {@code LongStream} from {@code startInclusive} * (inclusive) to {@code endExclusive} (exclusive) by an incremental step of * {@code 1}. * @@ -774,7 +829,7 @@ public interface LongStream extends BaseStream { } /** - * Returns a sequential {@code LongStream} from {@code startInclusive} + * Returns a sequential ordered {@code LongStream} from {@code startInclusive} * (inclusive) to {@code endInclusive} (inclusive) by an incremental step of * {@code 1}. * @@ -808,16 +863,16 @@ public interface LongStream extends BaseStream { } /** - * Creates a lazy concatenated {@code LongStream} whose elements are all the - * elements of a first {@code LongStream} succeeded by all the elements of the - * second {@code LongStream}. The resulting stream is ordered if both + * Creates a lazily concatenated stream whose elements are all the + * elements of the first stream followed by all the elements of the + * second stream. The resulting stream is ordered if both * of the input streams are ordered, and parallel if either of the input * streams is parallel. When the resulting stream is closed, the close * handlers for both input streams are invoked. * * @param a the first stream - * @param b the second stream to concatenate on to end of the first stream - * @return the concatenation of the two streams + * @param b the second stream + * @return the concatenation of the two input streams */ public static LongStream concat(LongStream a, LongStream b) { Objects.requireNonNull(a); @@ -832,9 +887,9 @@ public interface LongStream extends BaseStream { /** * A mutable builder for a {@code LongStream}. * - *

    A stream builder has a lifecycle, where it starts in a building - * phase, during which elements can be added, and then transitions to a - * built phase, after which elements may not be added. The built phase + *

    A stream builder has a lifecycle, which starts in a building + * phase, during which elements can be added, and then transitions to a built + * phase, after which elements may not be added. The built phase begins * begins when the {@link #build()} method is called, which creates an * ordered stream whose elements are the elements that were added to the * stream builder, in the order they were added. diff --git a/jdk/src/share/classes/java/util/stream/PipelineHelper.java b/jdk/src/share/classes/java/util/stream/PipelineHelper.java index 6824e3b3179..f510131d6ec 100644 --- a/jdk/src/share/classes/java/util/stream/PipelineHelper.java +++ b/jdk/src/share/classes/java/util/stream/PipelineHelper.java @@ -28,7 +28,7 @@ import java.util.Spliterator; import java.util.function.IntFunction; /** - * Helper class for executing + * Helper class for executing * stream pipelines, capturing all of the information about a stream * pipeline (output shape, intermediate operations, stream flags, parallelism, * etc) in one place. diff --git a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java index 42d711f4b2b..9d6aa59c8a7 100644 --- a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java +++ b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java @@ -170,6 +170,7 @@ abstract class ReferencePipeline } @Override + @SuppressWarnings("unchecked") public void accept(P_OUT u) { if (predicate.test(u)) downstream.accept(u); @@ -263,6 +264,7 @@ abstract class ReferencePipeline } @Override + @SuppressWarnings("unchecked") public void accept(P_OUT u) { try (Stream result = mapper.apply(u)) { // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it @@ -360,16 +362,17 @@ abstract class ReferencePipeline } @Override - public final Stream peek(Consumer tee) { - Objects.requireNonNull(tee); + public final Stream peek(Consumer action) { + Objects.requireNonNull(action); return new StatelessOp(this, StreamShape.REFERENCE, 0) { @Override Sink opWrapSink(int flags, Sink sink) { return new Sink.ChainedReference(sink) { @Override + @SuppressWarnings("unchecked") public void accept(P_OUT u) { - tee.accept(u); + action.accept(u); downstream.accept(u); } }; @@ -515,10 +518,10 @@ abstract class ReferencePipeline } @Override - public final R collect(Supplier resultFactory, + public final R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) { - return evaluate(ReduceOps.makeRef(resultFactory, accumulator, combiner)); + return evaluate(ReduceOps.makeRef(supplier, accumulator, combiner)); } @Override diff --git a/jdk/src/share/classes/java/util/stream/Stream.java b/jdk/src/share/classes/java/util/stream/Stream.java index 715729f24a7..4a9f05f5103 100644 --- a/jdk/src/share/classes/java/util/stream/Stream.java +++ b/jdk/src/share/classes/java/util/stream/Stream.java @@ -24,13 +24,18 @@ */ package java.util.stream; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Arrays; +import java.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.Objects; import java.util.Optional; import java.util.Spliterator; import java.util.Spliterators; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.BinaryOperator; @@ -44,51 +49,90 @@ import java.util.function.ToIntFunction; import java.util.function.ToLongFunction; import java.util.function.UnaryOperator; -// @@@ Specification to-do list @@@ -// - Describe the difference between sequential and parallel streams -// - More general information about reduce, better definitions for associativity, more description of -// how reduce employs parallelism, more examples -// - Role of stream flags in various operations, specifically ordering -// - Whether each op preserves encounter order -// @@@ Specification to-do list @@@ - /** - * A sequence of elements supporting sequential and parallel bulk operations. - * Streams support lazy intermediate operations (transforming a stream to - * another stream) such as {@code filter} and {@code map}, and terminal - * operations (consuming the contents of a stream to produce a result or - * side-effect), such as {@code forEach}, {@code findFirst}, and {@code - * iterator}. Once an operation has been performed on a stream, it - * is considered consumed and no longer usable for other operations. + * A sequence of elements supporting sequential and parallel aggregate + * operations. The following example illustrates an aggregate operation using + * {@link Stream} and {@link IntStream}: * - *

    For sequential stream pipelines, all operations are performed in the - * encounter order of the pipeline - * source, if the pipeline source has a defined encounter order. + *

    {@code
    + *     int sum = widgets.stream()
    + *                      .filter(w -> w.getColor() == RED)
    + *                      .mapToInt(w -> w.getWeight())
    + *                      .sum();
    + * }
    * - *

    For parallel stream pipelines, unless otherwise specified, intermediate - * stream operations preserve the - * encounter order of their source, and terminal operations - * respect the encounter order of their source, if the source - * has an encounter order. Provided that and parameters to stream operations - * satisfy the non-interference - * requirements, and excepting differences arising from the absence of - * a defined encounter order, the result of a stream pipeline should be the - * stable across multiple executions of the same operations on the same source. - * However, the timing and thread in which side-effects occur (for those - * operations which are allowed to produce side-effects, such as - * {@link #forEach(Consumer)}), are explicitly nondeterministic for parallel - * execution of stream pipelines. + * In this example, {@code widgets} is a {@code Collection}. We create + * a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()}, + * filter it to produce a stream containing only the red widgets, and then + * transform it into a stream of {@code int} values representing the weight of + * each red widget. Then this stream is summed to produce a total weight. * - *

    Unless otherwise noted, passing a {@code null} argument to any stream - * method may result in a {@link NullPointerException}. + *

    To perform a computation, stream + * operations are composed into a + * stream pipeline. A stream pipeline consists of a source (which + * might be an array, a collection, a generator function, an I/O channel, + * etc), zero or more intermediate operations (which transform a + * stream into another stream, such as {@link Stream#filter(Predicate)}), and a + * terminal operation (which produces a result or side-effect, such + * as {@link Stream#count()} or {@link Stream#forEach(Consumer)}). + * Streams are lazy; computation on the source data is only performed when the + * terminal operation is initiated, and source elements are consumed only + * as needed. * - * @apiNote - * Streams are not data structures; they do not manage the storage for their - * elements, nor do they support access to individual elements. However, - * you can use the {@link #iterator()} or {@link #spliterator()} operations to - * perform a controlled traversal. + *

    Collections and streams, while bearing some superficial similarities, + * have different goals. Collections are primarily concerned with the efficient + * management of, and access to, their elements. By contrast, streams do not + * provide a means to directly access or manipulate their elements, and are + * instead concerned with declaratively describing their source and the + * computational operations which will be performed in aggregate on that source. + * However, if the provided stream operations do not offer the desired + * functionality, the {@link #iterator()} and {@link #spliterator()} operations + * can be used to perform a controlled traversal. * - * @param type of elements + *

    A stream pipeline, like the "widgets" example above, can be viewed as + * a query on the stream source. Unless the source was explicitly + * designed for concurrent modification (such as a {@link ConcurrentHashMap}), + * unpredictable or erroneous behavior may result from modifying the stream + * source while it is being queried. + * + *

    Most stream operations accept parameters that describe user-specified + * behavior, such as the lambda expression {@code w -> w.getWeight()} passed to + * {@code mapToInt} in the example above. Such parameters are always instances + * of a functional interface such + * as {@link java.util.function.Function}, and are often lambda expressions or + * method references. These parameters can never be null, should not modify the + * stream source, and should be + * effectively stateless + * (their result should not depend on any state that might change during + * execution of the stream pipeline.) + * + *

    A stream should be operated on (invoking an intermediate or terminal stream + * operation) only once. This rules out, for example, "forked" streams, where + * the same source feeds two or more pipelines, or multiple traversals of the + * same stream. A stream implementation may throw {@link IllegalStateException} + * if it detects that the stream is being reused. However, since some stream + * operations may return their receiver rather than a new stream object, it may + * not be possible to detect reuse in all cases. + * + *

    Streams have a {@link #close()} method and implement {@link AutoCloseable}, + * but nearly all stream instances do not actually need to be closed after use. + * Generally, only streams whose source is an IO channel (such as those returned + * by {@link Files#lines(Path, Charset)}) will require closing. Most streams + * are backed by collections, arrays, or generating functions, which require no + * special resource management. (If a stream does require closing, it can be + * declared as a resource in a {@code try}-with-resources statement.) + * + *

    Stream pipelines may execute either sequentially or in + * parallel. This + * execution mode is a property of the stream. Streams are created + * with an initial choice of sequential or parallel execution. (For example, + * {@link Collection#stream() Collection.stream()} creates a sequential stream, + * and {@link Collection#parallelStream() Collection.parallelStream()} creates + * a parallel one.) This choice of execution mode may be modified by the + * {@link #sequential()} or {@link #parallel()} methods, and may be queried with + * the {@link #isParallel()} method. + * + * @param the type of the stream elements * @since 1.8 * @see java.util.stream */ @@ -168,9 +212,9 @@ public interface Stream extends BaseStream> { /** * Returns a stream consisting of the results of replacing each element of * this stream with the contents of the stream produced by applying the - * provided mapping function to each element. If the result of the mapping - * function is {@code null}, this is treated as if the result is an empty - * stream. + * provided mapping function to each element. (If the result of the mapping + * function is {@code null}, this is treated as if the result was an empty + * stream.) * *

    This is an intermediate * operation. @@ -197,9 +241,9 @@ public interface Stream extends BaseStream> { /** * Returns an {@code IntStream} consisting of the results of replacing each * element of this stream with the contents of the stream produced by - * applying the provided mapping function to each element. If the result of - * the mapping function is {@code null}, this is treated as if the result is - * an empty stream. + * applying the provided mapping function to each element. (If the result + * of the mapping function is {@code null}, this is treated as if the result + * was an empty stream.) * *

    This is an intermediate * operation. @@ -214,9 +258,9 @@ public interface Stream extends BaseStream> { /** * Returns a {@code LongStream} consisting of the results of replacing each * element of this stream with the contents of the stream produced - * by applying the provided mapping function to each element. If the result - * of the mapping function is {@code null}, this is treated as if the - * result is an empty stream. + * by applying the provided mapping function to each element. (If the result + * of the mapping function is {@code null}, this is treated as if the result + * was an empty stream.) * *

    This is an intermediate * operation. @@ -231,9 +275,9 @@ public interface Stream extends BaseStream> { /** * Returns a {@code DoubleStream} consisting of the results of replacing each * element of this stream with the contents of the stream produced - * by applying the provided mapping function to each element. If the result + * by applying the provided mapping function to each element. (If the result * of the mapping function is {@code null}, this is treated as if the result - * is an empty stream. + * was an empty stream.) * *

    This is an intermediate * operation. @@ -260,7 +304,7 @@ public interface Stream extends BaseStream> { * Returns a stream consisting of the elements of this stream, sorted * according to natural order. If the elements of this stream are not * {@code Comparable}, a {@code java.lang.ClassCastException} may be thrown - * when the stream pipeline is executed. + * when the terminal operation is executed. * *

    This is a stateful * intermediate operation. @@ -301,18 +345,18 @@ public interface Stream extends BaseStream> { *

    {@code
          *     list.stream()
          *         .filter(filteringFunction)
    -     *         .peek(e -> {System.out.println("Filtered value: " + e); });
    +     *         .peek(e -> System.out.println("Filtered value: " + e));
          *         .map(mappingFunction)
    -     *         .peek(e -> {System.out.println("Mapped value: " + e); });
    +     *         .peek(e -> System.out.println("Mapped value: " + e));
          *         .collect(Collectors.intoList());
          * }
    * - * @param consumer a + * @param action a * non-interfering action to perform on the elements as * they are consumed from the stream * @return the new stream */ - Stream peek(Consumer consumer); + Stream peek(Consumer action); /** * Returns a stream consisting of the elements of this stream, truncated @@ -329,8 +373,8 @@ public interface Stream extends BaseStream> { /** * Returns a stream consisting of the remaining elements of this stream - * after indexing {@code startInclusive} elements into the stream. If the - * {@code startInclusive} index lies past the end of this stream then an + * after discarding the first {@code startInclusive} elements of the stream. + * If this stream contains fewer than {@code startInclusive} elements then an * empty stream will be returned. * *

    This is a stateful @@ -344,10 +388,10 @@ public interface Stream extends BaseStream> { /** * Returns a stream consisting of the remaining elements of this stream - * after indexing {@code startInclusive} elements into the stream and - * truncated to contain no more than {@code endExclusive - startInclusive} - * elements. If the {@code startInclusive} index lies past the end - * of this stream then an empty stream will be returned. + * after discarding the first {@code startInclusive} elements and truncating + * the result to be no longer than {@code endExclusive - startInclusive} + * elements in length. If this stream contains fewer than + * {@code startInclusive} elements then an empty stream will be returned. * *

    This is a short-circuiting * stateful intermediate operation. @@ -405,11 +449,23 @@ public interface Stream extends BaseStream> { /** * Returns an array containing the elements of this stream, using the - * provided {@code generator} function to allocate the returned array. + * provided {@code generator} function to allocate the returned array, as + * well as any additional arrays that might be required for a partitioned + * execution or for resizing. * *

    This is a terminal * operation. * + * @apiNote + * The generator function takes an integer, which is the size of the + * desired array, and produces an array of the desired size. This can be + * concisely expressed with an array constructor reference: + *

    {@code
    +     *     Person[] men = people.stream()
    +     *                          .filter(p -> p.getGender() == MALE)
    +     *                          .toArray(Person[]::new);
    +     * }
    + * * @param the element type of the resulting array * @param generator a function which produces a new array of the desired * type and the provided length @@ -451,7 +507,7 @@ public interface Stream extends BaseStream> { * Integer sum = integers.reduce(0, (a, b) -> a+b); * }
    * - * or more compactly: + * or: * *
    {@code
          *     Integer sum = integers.reduce(0, Integer::sum);
    @@ -501,7 +557,8 @@ public interface Stream extends BaseStream> {
          * @param accumulator an associative
          *                    non-interfering,
          *                    stateless function for combining two values
    -     * @return the result of the reduction
    +     * @return an {@link Optional} describing the result of the reduction
    +     * @throws NullPointerException if the result of the reduction is null
          * @see #reduce(Object, BinaryOperator)
          * @see #min(java.util.Comparator)
          * @see #max(java.util.Comparator)
    @@ -511,7 +568,7 @@ public interface Stream extends BaseStream> {
         /**
          * Performs a reduction on the
          * elements of this stream, using the provided identity, accumulation
    -     * function, and a combining functions.  This is equivalent to:
    +     * function, and combining functions.  This is equivalent to:
          * 
    {@code
          *     U result = identity;
          *     for (T element : this stream)
    @@ -537,8 +594,8 @@ public interface Stream extends BaseStream> {
          * by an explicit combination of {@code map} and {@code reduce} operations.
          * The {@code accumulator} function acts as a fused mapper and accumulator,
          * which can sometimes be more efficient than separate mapping and reduction,
    -     * such as in the case where knowing the previously reduced value allows you
    -     * to avoid some computation.
    +     * such as when knowing the previously reduced value allows you to avoid
    +     * some computation.
          *
          * @param  The type of the result
          * @param identity the identity value for the combiner function
    @@ -561,12 +618,12 @@ public interface Stream extends BaseStream> {
         /**
          * Performs a mutable
          * reduction operation on the elements of this stream.  A mutable
    -     * reduction is one in which the reduced value is a mutable value holder,
    +     * reduction is one in which the reduced value is a mutable result container,
          * such as an {@code ArrayList}, and elements are incorporated by updating
    -     * the state of the result, rather than by replacing the result.  This
    +     * the state of the result rather than by replacing the result.  This
          * produces a result equivalent to:
          * 
    {@code
    -     *     R result = resultFactory.get();
    +     *     R result = supplier.get();
          *     for (T element : this stream)
          *         accumulator.accept(result, element);
          *     return result;
    @@ -579,10 +636,11 @@ public interface Stream extends BaseStream> {
          * operation.
          *
          * @apiNote There are many existing classes in the JDK whose signatures are
    -     * a good match for use as arguments to {@code collect()}.  For example,
    -     * the following will accumulate strings into an ArrayList:
    +     * well-suited for use with method references as arguments to {@code collect()}.
    +     * For example, the following will accumulate strings into an {@code ArrayList}:
          * 
    {@code
    -     *     List asList = stringStream.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
    +     *     List asList = stringStream.collect(ArrayList::new, ArrayList::add,
    +     *                                                ArrayList::addAll);
          * }
    * *

    The following will take a stream of strings and concatenates them into a @@ -594,10 +652,9 @@ public interface Stream extends BaseStream> { * }

    * * @param type of the result - * @param resultFactory a function that creates a new result container. - * For a parallel execution, this function may be - * called multiple times and must return a fresh value - * each time. + * @param supplier a function that creates a new result container. For a + * parallel execution, this function may be called + * multiple times and must return a fresh value each time. * @param accumulator an associative * non-interfering, * stateless function for incorporating an additional @@ -608,24 +665,24 @@ public interface Stream extends BaseStream> { * must be compatible with the accumulator function * @return the result of the reduction */ - R collect(Supplier resultFactory, + R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner); /** * Performs a mutable * reduction operation on the elements of this stream using a - * {@code Collector} object to describe the reduction. A {@code Collector} + * {@code Collector}. A {@code Collector} * encapsulates the functions used as arguments to * {@link #collect(Supplier, BiConsumer, BiConsumer)}, allowing for reuse of - * collection strategies, and composition of collect operations such as + * collection strategies and composition of collect operations such as * multiple-level grouping or partitioning. * *

    This is a terminal * operation. * *

    When executed in parallel, multiple intermediate results may be - * instantiated, populated, and merged, so as to maintain isolation of + * instantiated, populated, and merged so as to maintain isolation of * mutable data structures. Therefore, even when executed in parallel * with non-thread-safe data structures (such as {@code ArrayList}), no * additional synchronization is needed for a parallel reduction. @@ -638,16 +695,16 @@ public interface Stream extends BaseStream> { * *

    The following will classify {@code Person} objects by city: *

    {@code
    -     *     Map> peopleByCity
    -     *         = personStream.collect(Collectors.groupBy(Person::getCity));
    +     *     Map> peopleByCity
    +     *         = personStream.collect(Collectors.groupingBy(Person::getCity));
          * }
    * *

    The following will classify {@code Person} objects by state and city, * cascading two {@code Collector}s together: *

    {@code
    -     *     Map>> peopleByStateAndCity
    -     *         = personStream.collect(Collectors.groupBy(Person::getState,
    -     *                                                   Collectors.groupBy(Person::getCity)));
    +     *     Map>> peopleByStateAndCity
    +     *         = personStream.collect(Collectors.groupingBy(Person::getState,
    +     *                                                      Collectors.groupingBy(Person::getCity)));
          * }
    * * @param the type of the result @@ -662,7 +719,7 @@ public interface Stream extends BaseStream> { /** * Returns the minimum element of this stream according to the provided * {@code Comparator}. This is a special case of a - * reduction. + * reduction. * *

    This is a terminal operation. * @@ -671,13 +728,14 @@ public interface Stream extends BaseStream> { * elements of this stream * @return an {@code Optional} describing the minimum element of this stream, * or an empty {@code Optional} if the stream is empty + * @throws NullPointerException if the minimum element is null */ Optional min(Comparator comparator); /** * Returns the maximum element of this stream according to the provided * {@code Comparator}. This is a special case of a - * reduction. + * reduction. * *

    This is a terminal * operation. @@ -687,12 +745,13 @@ public interface Stream extends BaseStream> { * elements of this stream * @return an {@code Optional} describing the maximum element of this stream, * or an empty {@code Optional} if the stream is empty + * @throws NullPointerException if the maximum element is null */ Optional max(Comparator comparator); /** * Returns the count of elements in this stream. This is a special case of - * a reduction and is + * a reduction and is * equivalent to: *

    {@code
          *     return mapToLong(e -> 1L).sum();
    @@ -753,10 +812,9 @@ public interface Stream extends BaseStream> {
         boolean noneMatch(Predicate predicate);
     
         /**
    -     * Returns an {@link Optional} describing the first element of this stream
    -     * (in the encounter order), or an empty {@code Optional} if the stream is
    -     * empty.  If the stream has no encounter order, then any element may be
    -     * returned.
    +     * Returns an {@link Optional} describing the first element of this stream,
    +     * or an empty {@code Optional} if the stream is empty.  If the stream has
    +     * no encounter order, then any element may be returned.
          *
          * 

    This is a short-circuiting * terminal operation. @@ -777,8 +835,8 @@ public interface Stream extends BaseStream> { *

    The behavior of this operation is explicitly nondeterministic; it is * free to select any element in the stream. This is to allow for maximal * performance in parallel operations; the cost is that multiple invocations - * on the same source may not return the same result. (If the first element - * in the encounter order is desired, use {@link #findFirst()} instead.) + * on the same source may not return the same result. (If a stable result + * is desired, use {@link #findFirst()} instead.) * * @return an {@code Optional} describing some element of this stream, or an * empty {@code Optional} if the stream is empty @@ -821,20 +879,20 @@ public interface Stream extends BaseStream> { } /** - * Returns a sequential stream whose elements are the specified values. + * Returns a sequential ordered stream whose elements are the specified values. * * @param the type of stream elements * @param values the elements of the new stream * @return the new stream */ @SafeVarargs - @SuppressWarnings("varargs") // Creating a stream from an array is safe + @SuppressWarnings("varargs") public static Stream of(T... values) { return Arrays.stream(values); } /** - * Returns an infinite sequential {@code Stream} produced by iterative + * Returns an infinite sequential ordered {@code Stream} produced by iterative * application of a function {@code f} to an initial element {@code seed}, * producing a {@code Stream} consisting of {@code seed}, {@code f(seed)}, * {@code f(f(seed))}, etc. @@ -872,8 +930,8 @@ public interface Stream extends BaseStream> { } /** - * Returns a sequential {@code Stream} where each element is - * generated by a {@code Supplier}. This is suitable for generating + * Returns a sequential stream where each element is generated by + * the provided {@code Supplier}. This is suitable for generating * constant streams, streams of random elements, etc. * * @param the type of stream elements @@ -887,17 +945,16 @@ public interface Stream extends BaseStream> { } /** - * Creates a lazy concatenated {@code Stream} whose elements are all the - * elements of a first {@code Stream} succeeded by all the elements of the - * second {@code Stream}. The resulting stream is ordered if both + * Creates a lazily concatenated stream whose elements are all the + * elements of the first stream followed by all the elements of the + * second stream. The resulting stream is ordered if both * of the input streams are ordered, and parallel if either of the input * streams is parallel. When the resulting stream is closed, the close * handlers for both input streams are invoked. * * @param The type of stream elements * @param a the first stream - * @param b the second stream to concatenate on to end of the first - * stream + * @param b the second stream * @return the concatenation of the two input streams */ public static Stream concat(Stream a, Stream b) { @@ -917,7 +974,7 @@ public interface Stream extends BaseStream> { * {@code Builder} (without the copying overhead that comes from using * an {@code ArrayList} as a temporary buffer.) * - *

    A {@code Stream.Builder} has a lifecycle, where it starts in a building + *

    A stream builder has a lifecycle, which starts in a building * phase, during which elements can be added, and then transitions to a built * phase, after which elements may not be added. The built phase begins * when the {@link #build()} method is called, which creates an ordered diff --git a/jdk/src/share/classes/java/util/stream/StreamSpliterators.java b/jdk/src/share/classes/java/util/stream/StreamSpliterators.java index 4a62803b56b..f7b78422ebe 100644 --- a/jdk/src/share/classes/java/util/stream/StreamSpliterators.java +++ b/jdk/src/share/classes/java/util/stream/StreamSpliterators.java @@ -1456,4 +1456,5 @@ class StreamSpliterators { } } } -} \ No newline at end of file +} + diff --git a/jdk/src/share/classes/java/util/stream/StreamSupport.java b/jdk/src/share/classes/java/util/stream/StreamSupport.java index f6e04b0a51a..6feadd1db21 100644 --- a/jdk/src/share/classes/java/util/stream/StreamSupport.java +++ b/jdk/src/share/classes/java/util/stream/StreamSupport.java @@ -32,12 +32,8 @@ import java.util.function.Supplier; * Low-level utility methods for creating and manipulating streams. * *

    This class is mostly for library writers presenting stream views - * of their data structures; most static stream methods for end users are in - * {@link Streams}. - * - *

    Unless otherwise stated, streams are created as sequential - * streams. A sequential stream can be transformed into a parallel stream by - * calling the {@code parallel()} method on the created stream. + * of data structures; most static stream methods intended for end users are in + * the various {@code Stream} classes. * * @since 1.8 */ @@ -80,7 +76,7 @@ public final class StreamSupport { * {@code Supplier} of {@code Spliterator}. * *

    The {@link Supplier#get()} method will be invoked on the supplier no - * more than once, and after the terminal operation of the stream pipeline + * more than once, and only after the terminal operation of the stream pipeline * commences. * *

    For spliterators that report a characteristic of {@code IMMUTABLE} @@ -88,7 +84,7 @@ public final class StreamSupport { * late-binding, it is likely * more efficient to use {@link #stream(java.util.Spliterator, boolean)} * instead. - * The use of a {@code Supplier} in this form provides a level of + *

    The use of a {@code Supplier} in this form provides a level of * indirection that reduces the scope of potential interference with the * source. Since the supplier is only invoked after the terminal operation * commences, any modifications to the source up to the start of the @@ -148,7 +144,7 @@ public final class StreamSupport { * {@code Supplier} of {@code Spliterator.OfInt}. * *

    The {@link Supplier#get()} method will be invoked on the supplier no - * more than once, and after the terminal operation of the stream pipeline + * more than once, and only after the terminal operation of the stream pipeline * commences. * *

    For spliterators that report a characteristic of {@code IMMUTABLE} @@ -156,7 +152,7 @@ public final class StreamSupport { * late-binding, it is likely * more efficient to use {@link #intStream(java.util.Spliterator.OfInt, boolean)} * instead. - * The use of a {@code Supplier} in this form provides a level of + *

    The use of a {@code Supplier} in this form provides a level of * indirection that reduces the scope of potential interference with the * source. Since the supplier is only invoked after the terminal operation * commences, any modifications to the source up to the start of the @@ -215,7 +211,7 @@ public final class StreamSupport { * {@code Supplier} of {@code Spliterator.OfLong}. * *

    The {@link Supplier#get()} method will be invoked on the supplier no - * more than once, and after the terminal operation of the stream pipeline + * more than once, and only after the terminal operation of the stream pipeline * commences. * *

    For spliterators that report a characteristic of {@code IMMUTABLE} @@ -223,7 +219,7 @@ public final class StreamSupport { * late-binding, it is likely * more efficient to use {@link #longStream(java.util.Spliterator.OfLong, boolean)} * instead. - * The use of a {@code Supplier} in this form provides a level of + *

    The use of a {@code Supplier} in this form provides a level of * indirection that reduces the scope of potential interference with the * source. Since the supplier is only invoked after the terminal operation * commences, any modifications to the source up to the start of the @@ -282,7 +278,7 @@ public final class StreamSupport { * {@code Supplier} of {@code Spliterator.OfDouble}. * *

    The {@link Supplier#get()} method will be invoked on the supplier no - * more than once, and after the terminal operation of the stream pipeline + * more than once, and only after the terminal operation of the stream pipeline * commences. * *

    For spliterators that report a characteristic of {@code IMMUTABLE} @@ -290,7 +286,7 @@ public final class StreamSupport { * late-binding, it is likely * more efficient to use {@link #doubleStream(java.util.Spliterator.OfDouble, boolean)} * instead. - * The use of a {@code Supplier} in this form provides a level of + *

    The use of a {@code Supplier} in this form provides a level of * indirection that reduces the scope of potential interference with the * source. Since the supplier is only invoked after the terminal operation * commences, any modifications to the source up to the start of the diff --git a/jdk/src/share/classes/java/util/stream/package-info.java b/jdk/src/share/classes/java/util/stream/package-info.java index 46d033e38cd..2c01847ace3 100644 --- a/jdk/src/share/classes/java/util/stream/package-info.java +++ b/jdk/src/share/classes/java/util/stream/package-info.java @@ -24,347 +24,484 @@ */ /** - *

    java.util.stream

    - * - * Classes to support functional-style operations on streams of values, as in the following: + * Classes to support functional-style operations on streams of elements, such + * as map-reduce transformations on collections. For example: * *
    {@code
    - *     int sumOfWeights = blocks.stream().filter(b -> b.getColor() == RED)
    - *                                       .mapToInt(b -> b.getWeight())
    - *                                       .sum();
    + *     int sum = widgets.stream()
    + *                      .filter(b -> b.getColor() == RED)
    + *                      .mapToInt(b -> b.getWeight())
    + *                      .sum();
      * }
    * - *

    Here we use {@code blocks}, which might be a {@code Collection}, as a source for a stream, - * and then perform a filter-map-reduce ({@code sum()} is an example of a reduction - * operation) on the stream to obtain the sum of the weights of the red blocks. + *

    Here we use {@code widgets}, a {@code Collection}, + * as a source for a stream, and then perform a filter-map-reduce on the stream + * to obtain the sum of the weights of the red widgets. (Summation is an + * example of a reduction + * operation.) * - *

    The key abstraction used in this approach is {@link java.util.stream.Stream}, as well as its primitive - * specializations {@link java.util.stream.IntStream}, {@link java.util.stream.LongStream}, - * and {@link java.util.stream.DoubleStream}. Streams differ from Collections in several ways: + *

    The key abstraction introduced in this package is stream. The + * classes {@link java.util.stream.Stream}, {@link java.util.stream.IntStream}, + * {@link java.util.stream.LongStream}, and {@link java.util.stream.DoubleStream} + * are streams over objects and the primitive {@code int}, {@code long} and + * {@code double} types. Streams differ from collections in several ways: * *

      - *
    • No storage. A stream is not a data structure that stores elements; instead, they - * carry values from a source (which could be a data structure, a generator, an IO channel, etc) - * through a pipeline of computational operations.
    • - *
    • Functional in nature. An operation on a stream produces a result, but does not modify - * its underlying data source. For example, filtering a {@code Stream} produces a new {@code Stream}, - * rather than removing elements from the underlying source.
    • - *
    • Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, - * can be implemented lazily, exposing opportunities for optimization. (For example, "find the first - * {@code String} matching a pattern" need not examine all the input strings.) Stream operations - * are divided into intermediate ({@code Stream}-producing) operations and terminal (value-producing) - * operations; all intermediate operations are lazy.
    • - *
    • Possibly unbounded. While collections have a finite size, streams need not. Operations - * such as {@code limit(n)} or {@code findFirst()} can allow computations on infinite streams - * to complete in finite time.
    • + *
    • No storage. A stream is not a data structure that stores elements; + * instead, it conveys elements from a source such as a data structure, + * an array, a generator function, or an I/O channel, through a pipeline of + * computational operations.
    • + *
    • Functional in nature. An operation on a stream produces a result, + * but does not modify its source. For example, filtering a {@code Stream} + * obtained from a collection produces a new {@code Stream} without the + * filtered elements, rather than removing elements from the source + * collection.
    • + *
    • Laziness-seeking. Many stream operations, such as filtering, mapping, + * or duplicate removal, can be implemented lazily, exposing opportunities + * for optimization. For example, "find the first {@code String} with + * three consecutive vowels" need not examine all the input strings. + * Stream operations are divided into intermediate ({@code Stream}-producing) + * operations and terminal (value- or side-effect-producing) operations. + * Intermediate operations are always lazy.
    • + *
    • Possibly unbounded. While collections have a finite size, streams + * need not. Short-circuting operations such as {@code limit(n)} or + * {@code findFirst()} can allow computations on infinite streams to + * complete in finite time.
    • + *
    • Consumable. The elements of a stream are only visited once during + * the life of a stream. Like an {@link java.util.Iterator}, a new stream + * must be generated to revisit the same elements of the source. + *
    • *
    * - *

    Stream pipelines

    + * Streams can be obtained in a number of ways. Some examples include: + *
      + *
    • From a {@link java.util.Collection} via the {@code stream()} and + * {@code parallelStream()} methods;
    • + *
    • From an array via {@link java.util.Arrays#stream(Object[])};
    • + *
    • From static factory methods on the stream classes, such as + * {@link java.util.stream.Stream#of(Object[])}, + * {@link java.util.stream.IntStream#range(int, int)} + * or {@link java.util.stream.Stream#iterate(Object, UnaryOperator)};
    • + *
    • The lines of a file can be obtained from {@link java.io.BufferedReader#lines()};
    • + *
    • Streams of file paths can be obtained from methods in {@link java.nio.file.Files};
    • + *
    • Streams of random numbers can be obtained from {@link java.util.Random#ints()};
    • + *
    • Numerous other stream-bearing methods in the JDK, including + * {@link java.util.BitSet#stream()}, + * {@link java.util.regex.Pattern#splitAsStream(java.lang.CharSequence)}, + * and {@link java.util.jar.JarFile#stream()}.
    • + *
    * - *

    Streams are used to create pipelines of operations. A - * complete stream pipeline has several components: a source (which may be a {@code Collection}, - * an array, a generator function, or an IO channel); zero or more intermediate operations - * such as {@code Stream.filter} or {@code Stream.map}; and a terminal operation such - * as {@code Stream.forEach} or {@code java.util.stream.Stream.reduce}. Stream operations may take as parameters - * function values (which are often lambda expressions, but could be method references - * or objects) which parameterize the behavior of the operation, such as a {@code Predicate} - * passed to the {@code Stream#filter} method. + *

    Additional stream sources can be provided by third-party libraries using + * these techniques. * - *

    Intermediate operations return a new {@code Stream}. They are lazy; executing an - * intermediate operation such as {@link java.util.stream.Stream#filter Stream.filter} does - * not actually perform any filtering, instead creating a new {@code Stream} that, when - * traversed, contains the elements of the initial {@code Stream} that match the - * given {@code Predicate}. Consuming elements from the stream source does not - * begin until the terminal operation is executed. + *

    Stream operations and pipelines

    * - *

    Terminal operations consume the {@code Stream} and produce a result or a side-effect. - * After a terminal operation is performed, the stream can no longer be used and you must - * return to the data source, or select a new data source, to get a new stream. For example, - * obtaining the sum of weights of all red blocks, and then of all blue blocks, requires a - * filter-map-reduce on two different streams: - *

    {@code
    - *     int sumOfRedWeights  = blocks.stream().filter(b -> b.getColor() == RED)
    - *                                           .mapToInt(b -> b.getWeight())
    - *                                           .sum();
    - *     int sumOfBlueWeights = blocks.stream().filter(b -> b.getColor() == BLUE)
    - *                                           .mapToInt(b -> b.getWeight())
    - *                                           .sum();
    - * }
    + *

    Stream operations are + * divided into intermediate and terminal operations, and are + * combined to form stream pipelines. A stream pipeline consists of a + * source (such as a {@code Collection}, an array, a generator function, or an + * I/O channel); followed by zero or more intermediate operations such + * as {@code Stream.filter} or {@code Stream.map}; and a terminal + * operation such as {@code Stream.forEach} or {@code Stream.reduce}. * - *

    However, there are other techniques that allow you to obtain both results in a single - * pass if multiple traversal is impractical or inefficient. TODO provide link + *

    Intermediate operations return a new stream. They are always + * lazy; executing an intermediate operation such as + * {@code filter()} does not actually perform any filtering, but instead + * creates a new stream that, when traversed, contains the elements of + * the initial stream that match the given predicate. Traversal + * of the pipeline source does not begin until the terminal operation of the + * pipeline is executed. * - *

    Stream operations

    + *

    Terminal operations, such as {@code Stream.forEach} or + * {@code IntStream.sum}, may traverse the stream to produce a result or a + * side-effect. After the terminal operation is performed, the stream pipeline + * is considered consumed, and can no longer be used; if you need to traverse + * the same data source again, you must return to the data source to get a new + * stream. In almost all cases, terminal operations are eager, + * completing their traversal of the data source and processing of the pipeline + * before returning. Only the terminal operations {@code iterator()} and + * {@code spliterator()} are not; these are provided as an "escape hatch" to enable + * arbitrary client-controlled pipeline traversals in the event that the + * existing operations are not sufficient to the task. * - *

    Intermediate stream operation (such as {@code filter} or {@code sorted}) always produce a - * new {@code Stream}, and are alwayslazy. Executing a lazy operations does not - * trigger processing of the stream contents; all processing is deferred until the terminal - * operation commences. Processing streams lazily allows for significant efficiencies; in a - * pipeline such as the filter-map-sum example above, filtering, mapping, and addition can be - * fused into a single pass, with minimal intermediate state. Laziness also enables us to avoid - * examining all the data when it is not necessary; for operations such as "find the first - * string longer than 1000 characters", one need not examine all the input strings, just enough - * to find one that has the desired characteristics. (This behavior becomes even more important - * when the input stream is infinite and not merely large.) + *

    Processing streams lazily allows for significant efficiencies; in a + * pipeline such as the filter-map-sum example above, filtering, mapping, and + * summing can be fused into a single pass on the data, with minimal + * intermediate state. Laziness also allows avoiding examining all the data + * when it is not necessary; for operations such as "find the first string + * longer than 1000 characters", it is only necessary to examine just enough + * strings to find one that has the desired characteristics without examining + * all of the strings available from the source. (This behavior becomes even + * more important when the input stream is infinite and not merely large.) * - *

    Intermediate operations are further divided into stateless and stateful - * operations. Stateless operations retain no state from previously seen values when processing - * a new value; examples of stateless intermediate operations include {@code filter} and - * {@code map}. Stateful operations may incorporate state from previously seen elements in - * processing new values; examples of stateful intermediate operations include {@code distinct} - * and {@code sorted}. Stateful operations may need to process the entire input before - * producing a result; for example, one cannot produce any results from sorting a stream until - * one has seen all elements of the stream. As a result, under parallel computation, some - * pipelines containing stateful intermediate operations have to be executed in multiple passes. - * Pipelines containing exclusively stateless intermediate operations can be processed in a - * single pass, whether sequential or parallel. + *

    Intermediate operations are further divided into stateless + * and stateful operations. Stateless operations, such as {@code filter} + * and {@code map}, retain no state from previously seen element when processing + * a new element -- each element can be processed + * independently of operations on other elements. Stateful operations, such as + * {@code distinct} and {@code sorted}, may incorporate state from previously + * seen elements when processing new elements. * - *

    Further, some operations are deemed short-circuiting operations. An intermediate - * operation is short-circuiting if, when presented with infinite input, it may produce a - * finite stream as a result. A terminal operation is short-circuiting if, when presented with - * infinite input, it may terminate in finite time. (Having a short-circuiting operation is a - * necessary, but not sufficient, condition for the processing of an infinite stream to - * terminate normally in finite time.) + *

    Stateful operations may need to process the entire input + * before producing a result. For example, one cannot produce any results from + * sorting a stream until one has seen all elements of the stream. As a result, + * under parallel computation, some pipelines containing stateful intermediate + * operations may require multiple passes on the data or may need to buffer + * significant data. Pipelines containing exclusively stateless intermediate + * operations can be processed in a single pass, whether sequential or parallel, + * with minimal data buffering. * - * Terminal operations (such as {@code forEach} or {@code findFirst}) are always eager - * (they execute completely before returning), and produce a non-{@code Stream} result, such - * as a primitive value or a {@code Collection}, or have side-effects. + *

    Further, some operations are deemed short-circuiting operations. + * An intermediate operation is short-circuiting if, when presented with + * infinite input, it may produce a finite stream as a result. A terminal + * operation is short-circuiting if, when presented with infinite input, it may + * terminate in finite time. Having a short-circuiting operation in the pipeline + * is a necessary, but not sufficient, condition for the processing of an infinite + * stream to terminate normally in finite time. * *

    Parallelism

    * - *

    By recasting aggregate operations as a pipeline of operations on a stream of values, many - * aggregate operations can be more easily parallelized. A {@code Stream} can execute either - * in serial or in parallel. When streams are created, they are either created as sequential - * or parallel streams; the parallel-ness of streams can also be switched by the - * {@link java.util.stream Stream#sequential()} and {@link java.util.stream.Stream#parallel()} - * operations. The {@code Stream} implementations in the JDK create serial streams unless - * parallelism is explicitly requested. For example, {@code Collection} has methods + *

    Processing elements with an explicit {@code for-}loop is inherently serial. + * Streams facilitate parallel execution by reframing the computation as a pipeline of + * aggregate operations, rather than as imperative operations on each individual + * element. All streams operations can execute either in serial or in parallel. + * The stream implementations in the JDK create serial streams unless parallelism is + * explicitly requested. For example, {@code Collection} has methods * {@link java.util.Collection#stream} and {@link java.util.Collection#parallelStream}, - * which produce sequential and parallel streams respectively; other stream-bearing methods - * such as {@link java.util.stream.IntStream#range(int, int)} produce sequential - * streams but these can be efficiently parallelized by calling {@code parallel()} on the - * result. The set of operations on serial and parallel streams is identical. To execute the - * "sum of weights of blocks" query in parallel, we would do: + * which produce sequential and parallel streams respectively; other + * stream-bearing methods such as {@link java.util.stream.IntStream#range(int, int)} + * produce sequential streams but these streams can be efficiently parallelized by + * invoking their {@link java.util.stream.BaseStream#parallel()} method. + * To execute the prior "sum of weights of widgets" query in parallel, we would + * do: * *

    {@code
    - *     int sumOfWeights = blocks.parallelStream().filter(b -> b.getColor() == RED)
    - *                                               .mapToInt(b -> b.getWeight())
    - *                                               .sum();
    + *     int sumOfWeights = widgets.}{@code parallelStream()}{@code .filter(b -> b.getColor() == RED)
    + *                                                .mapToInt(b -> b.getWeight())
    + *                                                .sum();
      * }
    * - *

    The only difference between the serial and parallel versions of this example code is - * the creation of the initial {@code Stream}. Whether a {@code Stream} will execute in serial - * or parallel can be determined by the {@code Stream#isParallel} method. When the terminal - * operation is initiated, the entire stream pipeline is either executed sequentially or in - * parallel, determined by the last operation that affected the stream's serial-parallel - * orientation (which could be the stream source, or the {@code sequential()} or - * {@code parallel()} methods.) + *

    The only difference between the serial and parallel versions of this + * example is the creation of the initial stream, using "{@code parallelStream()}" + * instead of "{@code stream()}". When the terminal operation is initiated, + * the stream pipeline is executed sequentially or in parallel depending on the + * orientation of the stream on which it is invoked. Whether a stream will execute in serial or + * parallel can be determined with the {@code isParallel()} method, and the + * orientation of a stream can be modified with the + * {@link java.util.stream.BaseStream#sequential()} and + * {@link java.util.stream.BaseStream#parallel()} operations. When the terminal + * operation is initiated, the stream pipeline is executed sequentially or in + * parallel depending on the mode of the stream on which it is invoked. * - *

    In order for the results of parallel operations to be deterministic and consistent with - * their serial equivalent, the function values passed into the various stream operations should - * be stateless. + *

    Except for operations identified as explicitly nondeterministic, such + * as {@code findAny()}, whether a stream executes sequentially or in parallel + * should not change the result of the computation. * - *

    Ordering

    - * - *

    Streams may or may not have an encounter order. An encounter - * order specifies the order in which elements are provided by the stream to the - * operations pipeline. Whether or not there is an encounter order depends on - * the source, the intermediate operations, and the terminal operation. - * Certain stream sources (such as {@code List} or arrays) are intrinsically - * ordered, whereas others (such as {@code HashSet}) are not. Some intermediate - * operations may impose an encounter order on an otherwise unordered stream, - * such as {@link java.util.stream.Stream#sorted()}, and others may render an - * ordered stream unordered (such as {@link java.util.stream.Stream#unordered()}). - * Some terminal operations may ignore encounter order, such as - * {@link java.util.stream.Stream#forEach}. - * - *

    If a Stream is ordered, most operations are constrained to operate on the - * elements in their encounter order; if the source of a stream is a {@code List} - * containing {@code [1, 2, 3]}, then the result of executing {@code map(x -> x*2)} - * must be {@code [2, 4, 6]}. However, if the source has no defined encounter - * order, than any of the six permutations of the values {@code [2, 4, 6]} would - * be a valid result. Many operations can still be efficiently parallelized even - * under ordering constraints. - * - *

    For sequential streams, ordering is only relevant to the determinism - * of operations performed repeatedly on the same source. (An {@code ArrayList} - * is constrained to iterate elements in order; a {@code HashSet} is not, and - * repeated iteration might produce a different order.) - * - *

    For parallel streams, relaxing the ordering constraint can enable - * optimized implementation for some operations. For example, duplicate - * filtration on an ordered stream must completely process the first partition - * before it can return any elements from a subsequent partition, even if those - * elements are available earlier. On the other hand, without the constraint of - * ordering, duplicate filtration can be done more efficiently by using - * a shared {@code ConcurrentHashSet}. There will be cases where the stream - * is structurally ordered (the source is ordered and the intermediate - * operations are order-preserving), but the user does not particularly care - * about the encounter order. In some cases, explicitly de-ordering the stream - * with the {@link java.util.stream.Stream#unordered()} method may result in - * improved parallel performance for some stateful or terminal operations. + *

    Most stream operations accept parameters that describe user-specified + * behavior, which are often lambda expressions. To preserve correct behavior, + * these behavioral parameters must be non-interfering, and in + * most cases must be stateless. Such parameters are always instances + * of a functional interface such + * as {@link java.util.function.Function}, and are often lambda expressions or + * method references. * *

    Non-interference

    * - * The {@code java.util.stream} package enables you to execute possibly-parallel - * bulk-data operations over a variety of data sources, including even non-thread-safe - * collections such as {@code ArrayList}. This is possible only if we can - * prevent interference with the data source during the execution of a - * stream pipeline. (Execution begins when the terminal operation is invoked, and ends - * when the terminal operation completes.) For most data sources, preventing interference - * means ensuring that the data source is not modified at all during the execution - * of the stream pipeline. (Some data sources, such as concurrent collections, are - * specifically designed to handle concurrent modification.) + * Streams enable you to execute possibly-parallel aggregate operations over a + * variety of data sources, including even non-thread-safe collections such as + * {@code ArrayList}. This is possible only if we can prevent + * interference with the data source during the execution of a stream + * pipeline. Except for the escape-hatch operations {@code iterator()} and + * {@code spliterator()}, execution begins when the terminal operation is + * invoked, and ends when the terminal operation completes. For most data + * sources, preventing interference means ensuring that the data source is + * not modified at all during the execution of the stream pipeline. + * The notable exception to this are streams whose sources are concurrent + * collections, which are specifically designed to handle concurrent modification. * - *

    Accordingly, lambda expressions (or other objects implementing the appropriate functional - * interface) passed to stream methods should never modify the stream's data source. An - * implementation is said to interfere with the data source if it modifies, or causes - * to be modified, the stream's data source. The need for non-interference applies to all - * pipelines, not just parallel ones. Unless the stream source is concurrent, modifying a - * stream's data source during execution of a stream pipeline can cause exceptions, incorrect - * answers, or nonconformant results. + *

    Accordingly, behavioral parameters passed to stream methods should never + * modify the stream's data source. An implementation is said to + * interfere with the data source if it modifies, or causes to be + * modified, the stream's data source. The need for non-interference applies + * to all pipelines, not just parallel ones. Unless the stream source is + * concurrent, modifying a stream's data source during execution of a stream + * pipeline can cause exceptions, incorrect answers, or nonconformant behavior. + * + *

    Results may be nondeterministic or incorrect if the behavioral + * parameters of stream operations are stateful. A stateful lambda + * (or other object implementing the appropriate functional interface) is one + * whose result depends on any state which might change during the execution + * of the stream pipeline. An example of a stateful lambda is: * - *

    Further, results may be nondeterministic or incorrect if the lambda expressions passed to - * stream operations are stateful. A stateful lambda (or other object implementing the - * appropriate functional interface) is one whose result depends on any state which might change - * during the execution of the stream pipeline. An example of a stateful lambda is: *

    {@code
      *     Set seen = Collections.synchronizedSet(new HashSet<>());
      *     stream.parallel().map(e -> { if (seen.add(e)) return 0; else return e; })...
      * }
    - * Here, if the mapping operation is performed in parallel, the results for the same input - * could vary from run to run, due to thread scheduling differences, whereas, with a stateless - * lambda expression the results would always be the same. + * + * Here, if the mapping operation is performed in parallel, the results for the + * same input could vary from run to run, due to thread scheduling differences, + * whereas, with a stateless lambda expression the results would always be the + * same. + * + * For well-behaved stream sources, the source can be modified before the + * terminal operation commences and those modifications will be reflected in + * the covered elements. For example, consider the following code: + * + *
    {@code
    + *     List l = new ArrayList(Arrays.asList("one", "two"));
    + *     Stream sl = l.stream();
    + *     l.add("three");
    + *     String s = sl.collect(joining(" "));
    + * }
    + * + * First a list is created consisting of two strings: "one"; and "two". Then a + * stream is created from that list. Next the list is modified by adding a third + * string: "three". Finally the elements of the stream are collected and joined + * together. Since the list was modified before the terminal {@code collect} + * operation commenced the result will be a string of "one two three". All the + * streams returned from JDK collections, and most other JDK classes, + * are well-behaved in this manner; for streams generated by other libraries, see + * Low-level stream + * construction for requirements for building well-behaved streams. + * + *

    Some streams, particularly those whose stream sources are concurrent, can + * tolerate concurrent modification during execution of a stream pipeline. + * However, in no case -- even if the stream source is concurrent -- should + * behavioral parameters to stream operations modify the stream source. Modifying + * the stream source from within the stream source may cause pipeline execution + * to fail to terminate, produce inaccurate results, or throw exceptions. + * The following example shows inappropriate interference with the source: + *

    {@code
    + *     // Don't do this!
    + *     List l = new ArrayList(Arrays.asList("one", "two"));
    + *     Stream sl = l.stream();
    + *     String s = sl.peek(s -> l.add("BAD LAMBDA")).collect(joining(" "));
    + * }
    * *

    Side-effects

    * + * Side-effects in behavioral parameters to stream operations are, in general, + * discouraged, as they can often lead to unwitting violations of the + * statelessness requirement, as well as other thread-safety hazards. Many + * computations where one might be tempted to use side effects can be more + * safely and efficiently expressed without side-effects, such as using + * reduction instead of mutable + * accumulators. However, side-effects such as using {@code println()} for debugging + * purposes are usually harmless. A small number of stream operations, such as + * {@code forEach()} and {@code peek()}, can operate only via side-effects; + * these should be used with care. + * + *

    As an example of how to transform a stream pipeline that inappropriately + * uses side-effects to one that does not, the following code searches a stream + * of strings for those matching a given regular expression, and puts the + * matches in a list. + * + *

    {@code
    + *     ArrayList results = new ArrayList<>();
    + *     stream.filter(s -> pattern.matcher(s).matches())
    + *           .forEach(s -> results.add(s));  // Unnecessary use of side-effects!
    + * }
    + * + * This code unnecessarily uses side-effects. If executed in parallel, the + * non-thread-safety of {@code ArrayList} would cause incorrect results, and + * adding needed synchronization would cause contention, undermining the + * benefit of parallelism. Furthermore, using side-effects here is completely + * unnecessary; the {@code forEach()} can simply be replaced with a reduction + * operation that is safer, more efficient, and more amenable to + * parallelization: + * + *
    {@code
    + *     Listresults =
    + *         stream.filter(s -> pattern.matcher(s).matches())
    + *               .collect(Collectors.toList());  // No side-effects!
    + * }
    + * + *

    Ordering

    + * + *

    Streams may or may not have a defined encounter order. Whether + * or not a stream has an encounter order depends on the source and the + * intermediate operations. Certain stream sources (such as {@code List} or + * arrays) are intrinsically ordered, whereas others (such as {@code HashSet}) + * are not. Some intermediate operations, such as {@code sorted()}, may impose + * an encounter order on an otherwise unordered stream, and others may render an + * ordered stream unordered, such as {@link java.util.stream.BaseStream#unordered()}. + * Further, some terminal operations may ignore encounter order, such as + * {@code forEach()}. + * + *

    If a stream is ordered, most operations are constrained to operate on the + * elements in their encounter order; if the source of a stream is a {@code List} + * containing {@code [1, 2, 3]}, then the result of executing {@code map(x -> x*2)} + * must be {@code [2, 4, 6]}. However, if the source has no defined encounter + * order, then any permutation of the values {@code [2, 4, 6]} would be a valid + * result. + * + *

    For sequential streams, the presence or absence of an encounter order does + * not affect performance, only determinism. If a stream is ordered, repeated + * execution of identical stream pipelines on an identical source will produce + * an identical result; if it is not ordered, repeated execution might produce + * different results. + * + *

    For parallel streams, relaxing the ordering constraint can sometimes enable + * more efficient execution. Certain aggregate operations, + * such as filtering duplicates ({@code distinct()}) or grouped reductions + * ({@code Collectors.groupingBy()}) can be implemented more efficiently if ordering of elements + * is not relevant. Similarly, operations that are intrinsically tied to encounter order, + * such as {@code limit()}, may require + * buffering to ensure proper ordering, undermining the benefit of parallelism. + * In cases where the stream has an encounter order, but the user does not + * particularly care about that encounter order, explicitly de-ordering + * the stream with {@link java.util.stream.BaseStream#unordered() unordered()} may + * improve parallel performance for some stateful or terminal operations. + * However, most stream pipelines, such as the "sum of weight of blocks" example + * above, still parallelize efficiently even under ordering constraints. + * *

    Reduction operations

    * - * A reduction operation takes a stream of elements and processes them in a way - * that reduces to a single value or summary description, such as finding the sum or maximum - * of a set of numbers. (In more complex scenarios, the reduction operation might need to - * extract data from the elements before reducing that data to a single value, such as - * finding the sum of weights of a set of blocks. This would require extracting the weight - * from each block before summing up the weights.) + * A reduction operation (also called a fold) takes a sequence + * of input elements and combines them into a single summary result by repeated + * application of a combining operation, such as finding the sum or maximum of + * a set of numbers, or accumulating elements into a list. The streams classes have + * multiple forms of general reduction operations, called + * {@link java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduce()} + * and {@link java.util.stream.Stream#collect(java.util.stream.Collector) collect()}, + * as well as multiple specialized reduction forms such as + * {@link java.util.stream.IntStream#sum() sum()}, {@link java.util.stream.IntStream#max() max()}, + * or {@link java.util.stream.IntStream#count() count()}. * - *

    Of course, such operations can be readily implemented as simple sequential loops, as in: + *

    Of course, such operations can be readily implemented as simple sequential + * loops, as in: *

    {@code
      *    int sum = 0;
      *    for (int x : numbers) {
      *       sum += x;
      *    }
      * }
    - * However, there may be a significant advantage to preferring a {@link java.util.stream.Stream#reduce reduce operation} - * over a mutative accumulation such as the above -- a properly constructed reduce operation is - * inherently parallelizable so long as the - * {@link java.util.function.BinaryOperator reduction operaterator} - * has the right characteristics. Specifically the operator must be - * associative. For example, given a - * stream of numbers for which we want to find the sum, we can write: + * However, there are good reasons to prefer a reduce operation + * over a mutative accumulation such as the above. Not only is a reduction + * "more abstract" -- it operates on the stream as a whole rather than individual + * elements -- but a properly constructed reduce operation is inherently + * parallelizable, so long as the function(s) used to process the elements + * are associative and + * stateless. + * For example, given a stream of numbers for which we want to find the sum, we + * can write: *
    {@code
    - *    int sum = numbers.reduce(0, (x,y) -> x+y);
    + *    int sum = numbers.stream().reduce(0, (x,y) -> x+y);
      * }
    - * or more succinctly: + * or: *
    {@code
    - *    int sum = numbers.reduce(0, Integer::sum);
    + *    int sum = numbers.stream().reduce(0, Integer::sum);
      * }
    * - *

    (The primitive specializations of {@link java.util.stream.Stream}, such as - * {@link java.util.stream.IntStream}, even have convenience methods for common reductions, - * such as {@link java.util.stream.IntStream#sum() sum} and {@link java.util.stream.IntStream#max() max}, - * which are implemented as simple wrappers around reduce.) - * - *

    Reduction parallellizes well since the implementation of {@code reduce} can operate on - * subsets of the stream in parallel, and then combine the intermediate results to get the final - * correct answer. Even if you were to use a parallelizable form of the - * {@link java.util.stream.Stream#forEach(Consumer) forEach()} method - * in place of the original for-each loop above, you would still have to provide thread-safe - * updates to the shared accumulating variable {@code sum}, and the required synchronization - * would likely eliminate any performance gain from parallelism. Using a {@code reduce} method - * instead removes all of the burden of parallelizing the reduction operation, and the library - * can provide an efficient parallel implementation with no additional synchronization needed. - * - *

    The "blocks" examples shown earlier shows how reduction combines with other operations - * to replace for loops with bulk operations. If {@code blocks} is a collection of {@code Block} - * objects, which have a {@code getWeight} method, we can find the heaviest block with: + *

    These reduction operations can run safely in parallel with almost no + * modification: *

    {@code
    - *     OptionalInt heaviest = blocks.stream()
    - *                                  .mapToInt(Block::getWeight)
    - *                                  .reduce(Integer::max);
    + *    int sum = numbers.parallelStream().reduce(0, Integer::sum);
      * }
    * - *

    In its more general form, a {@code reduce} operation on elements of type {@code } - * yielding a result of type {@code } requires three parameters: + *

    Reduction parallellizes well because the implementation + * can operate on subsets of the data in parallel, and then combine the + * intermediate results to get the final correct answer. (Even if the language + * had a "parallel for-each" construct, the mutative accumulation approach would + * still required the developer to provide + * thread-safe updates to the shared accumulating variable {@code sum}, and + * the required synchronization would then likely eliminate any performance gain from + * parallelism.) Using {@code reduce()} instead removes all of the + * burden of parallelizing the reduction operation, and the library can provide + * an efficient parallel implementation with no additional synchronization + * required. + * + *

    The "widgets" examples shown earlier shows how reduction combines with + * other operations to replace for loops with bulk operations. If {@code widgets} + * is a collection of {@code Widget} objects, which have a {@code getWeight} method, + * we can find the heaviest widget with: + *

    {@code
    + *     OptionalInt heaviest = widgets.parallelStream()
    + *                                   .mapToInt(Widget::getWeight)
    + *                                   .max();
    + * }
    + * + *

    In its more general form, a {@code reduce} operation on elements of type + * {@code } yielding a result of type {@code } requires three parameters: *

    {@code
      *  U reduce(U identity,
    - *              BiFunction accumlator,
    + *              BiFunction accumulator,
      *              BinaryOperator combiner);
      * }
    - * Here, the identity element is both an initial seed for the reduction, and a default - * result if there are no elements. The accumulator function takes a partial result and - * the next element, and produce a new partial result. The combiner function combines - * the partial results of two accumulators to produce a new partial result, and eventually the - * final result. + * Here, the identity element is both an initial seed value for the reduction + * and a default result if there are no input elements. The accumulator + * function takes a partial result and the next element, and produces a new + * partial result. The combiner function combines two partial results + * to produce a new partial result. (The combiner is necessary in parallel + * reductions, where the input is partitioned, a partial accumulation computed + * for each partition, and then the partial results are combined to produce a + * final result.) * - *

    This form is a generalization of the two-argument form, and is also a generalization of - * the map-reduce construct illustrated above. If we wanted to re-cast the simple {@code sum} - * example using the more general form, {@code 0} would be the identity element, while - * {@code Integer::sum} would be both the accumulator and combiner. For the sum-of-weights - * example, this could be re-cast as: + *

    More formally, the {@code identity} value must be an identity for + * the combiner function. This means that for all {@code u}, + * {@code combiner.apply(identity, u)} is equal to {@code u}. Additionally, the + * {@code combiner} function must be associative and + * must be compatible with the {@code accumulator} function: for all {@code u} + * and {@code t}, {@code combiner.apply(u, accumulator.apply(identity, t))} must + * be {@code equals()} to {@code accumulator.apply(u, t)}. + * + *

    The three-argument form is a generalization of the two-argument form, + * incorporating a mapping step into the accumulation step. We could + * re-cast the simple sum-of-weights example using the more general form as + * follows: *

    {@code
    - *     int sumOfWeights = blocks.stream().reduce(0,
    - *                                               (sum, b) -> sum + b.getWeight())
    - *                                               Integer::sum);
    + *     int sumOfWeights = widgets.stream()
    + *                               .reduce(0,
    + *                                       (sum, b) -> sum + b.getWeight())
    + *                                       Integer::sum);
      * }
    - * though the map-reduce form is more readable and generally preferable. The generalized form - * is provided for cases where significant work can be optimized away by combining mapping and - * reducing into a single function. + * though the explicit map-reduce form is more readable and therefore should + * usually be preferred. The generalized form is provided for cases where + * significant work can be optimized away by combining mapping and reducing + * into a single function. * - *

    More formally, the {@code identity} value must be an identity for the combiner - * function. This means that for all {@code u}, {@code combiner.apply(identity, u)} is equal - * to {@code u}. Additionally, the {@code combiner} function must be - * associative and must be compatible with the {@code accumulator} - * function; for all {@code u} and {@code t}, the following must hold: - *

    {@code
    - *     combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)
    - * }
    + *

    Mutable reduction

    * - *

    Mutable Reduction

    - * - * A mutable reduction operation is similar to an ordinary reduction, in that it reduces - * a stream of values to a single value, but instead of producing a distinct single-valued result, it - * mutates a general result container, such as a {@code Collection} or {@code StringBuilder}, + * A mutable reduction operation accumulates input elements into a + * mutable result container, such as a {@code Collection} or {@code StringBuilder}, * as it processes the elements in the stream. * - *

    For example, if we wanted to take a stream of strings and concatenate them into a single - * long string, we could achieve this with ordinary reduction: + *

    If we wanted to take a stream of strings and concatenate them into a + * single long string, we could achieve this with ordinary reduction: *

    {@code
      *     String concatenated = strings.reduce("", String::concat)
      * }
    * - * We would get the desired result, and it would even work in parallel. However, we might not - * be happy about the performance! Such an implementation would do a great deal of string - * copying, and the run time would be O(n^2) in the number of elements. A more - * performant approach would be to accumulate the results into a {@link java.lang.StringBuilder}, which - * is a mutable container for accumulating strings. We can use the same technique to + *

    We would get the desired result, and it would even work in parallel. However, + * we might not be happy about the performance! Such an implementation would do + * a great deal of string copying, and the run time would be O(n^2) in + * the number of characters. A more performant approach would be to accumulate + * the results into a {@link java.lang.StringBuilder}, which is a mutable + * container for accumulating strings. We can use the same technique to * parallelize mutable reduction as we do with ordinary reduction. * - *

    The mutable reduction operation is called {@link java.util.stream.Stream#collect(Collector) collect()}, as it - * collects together the desired results into a result container such as {@code StringBuilder}. - * A {@code collect} operation requires three things: a factory function which will construct - * new instances of the result container, an accumulating function that will update a result - * container by incorporating a new element, and a combining function that can take two - * result containers and merge their contents. The form of this is very similar to the general + *

    The mutable reduction operation is called + * {@link java.util.stream.Stream#collect(Collector) collect()}, + * as it collects together the desired results into a result container such + * as a {@code Collection}. + * A {@code collect} operation requires three functions: + * a factory function to construct new instances of the result container, an + * accumulator function to incorporate an input element into a result + * container, and a combining function to merge the contents of one result + * container into another. The form of this is very similar to the general * form of ordinary reduction: *

    {@code
      *  R collect(Supplier resultFactory,
      *               BiConsumer accumulator,
      *               BiConsumer combiner);
      * }
    - * As with {@code reduce()}, the benefit of expressing {@code collect} in this abstract way is - * that it is directly amenable to parallelization: we can accumulate partial results in parallel - * and then combine them. For example, to collect the String representations of the elements - * in a stream into an {@code ArrayList}, we could write the obvious sequential for-each form: + *

    As with {@code reduce()}, a benefit of expressing {@code collect} in this + * abstract way is that it is directly amenable to parallelization: we can + * accumulate partial results in parallel and then combine them, so long as the + * accumulation and combining functions satisfy the appropriate requirements. + * For example, to collect the String representations of the elements in a + * stream into an {@code ArrayList}, we could write the obvious sequential + * for-each form: *

    {@code
      *     ArrayList strings = new ArrayList<>();
      *     for (T element : stream) {
    @@ -377,92 +514,107 @@
      *                                                (c, e) -> c.add(e.toString()),
      *                                                (c1, c2) -> c1.addAll(c2));
      * }
    - * or, noting that we have buried a mapping operation inside the accumulator function, more - * succinctly as: + * or, pulling the mapping operation out of the accumulator function, we could + * express it more succinctly as: *
    {@code
    - *     ArrayList strings = stream.map(Object::toString)
    - *                                       .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
    + *     List strings = stream.map(Object::toString)
    + *                                  .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
      * }
    - * Here, our supplier is just the {@link java.util.ArrayList#ArrayList() ArrayList constructor}, the - * accumulator adds the stringified element to an {@code ArrayList}, and the combiner simply - * uses {@link java.util.ArrayList#addAll addAll} to copy the strings from one container into the other. + * Here, our supplier is just the {@link java.util.ArrayList#ArrayList() + * ArrayList constructor}, the accumulator adds the stringified element to an + * {@code ArrayList}, and the combiner simply uses {@link java.util.ArrayList#addAll addAll} + * to copy the strings from one container into the other. * - *

    As with the regular reduction operation, the ability to parallelize only comes if an - * associativity condition is met. The {@code combiner} is associative - * if for result containers {@code r1}, {@code r2}, and {@code r3}: + *

    The three aspects of {@code collect} -- supplier, accumulator, and combiner -- + * are tightly coupled. We can use the abstraction of + * of a {@link java.util.stream.Collector} to capture all three aspects. + * The above example for collecting strings into a {@code List} can be rewritten + * using a standard {@code Collector} as: *

    {@code
    - *    combiner.accept(r1, r2);
    - *    combiner.accept(r1, r3);
    - * }
    - * is equivalent to - *
    {@code
    - *    combiner.accept(r2, r3);
    - *    combiner.accept(r1, r2);
    - * }
    - * where equivalence means that {@code r1} is left in the same state (according to the meaning - * of {@link java.lang.Object#equals equals} for the element types). Similarly, the {@code resultFactory} - * must act as an identity with respect to the {@code combiner} so that for any result - * container {@code r}: - *
    {@code
    - *     combiner.accept(r, resultFactory.get());
    - * }
    - * does not modify the state of {@code r} (again according to the meaning of - * {@link java.lang.Object#equals equals}). Finally, the {@code accumulator} and {@code combiner} must be - * compatible such that for a result container {@code r} and element {@code t}: - *
    {@code
    - *    r2 = resultFactory.get();
    - *    accumulator.accept(r2, t);
    - *    combiner.accept(r, r2);
    - * }
    - * is equivalent to: - *
    {@code
    - *    accumulator.accept(r,t);
    - * }
    - * where equivalence means that {@code r} is left in the same state (again according to the - * meaning of {@link java.lang.Object#equals equals}). - * - *

    The three aspects of {@code collect}: supplier, accumulator, and combiner, are often very - * tightly coupled, and it is convenient to introduce the notion of a {@link java.util.stream.Collector} as - * being an object that embodies all three aspects. There is a {@link java.util.stream.Stream#collect(Collector) collect} - * method that simply takes a {@code Collector} and returns the resulting container. - * The above example for collecting strings into a {@code List} can be rewritten using a - * standard {@code Collector} as: - *

    {@code
    - *     ArrayList strings = stream.map(Object::toString)
    - *                                       .collect(Collectors.toList());
    + *     List strings = stream.map(Object::toString)
    + *                                  .collect(Collectors.toList());
      * }
    * - *

    Reduction, Concurrency, and Ordering

    + *

    Packaging mutable reductions into a Collector has another advantage: + * composability. The class {@link java.util.stream.Collectors} contains a + * number of predefined factories for collectors, including combinators + * that transform one collector into another. For example, suppose we have a + * collector that computes the sum of the salaries of a stream of + * employees, as follows: * - * With some complex reduction operations, for example a collect that produces a - * {@code Map}, such as: + *

    {@code
    + *     Collector summingSalaries
    + *         = Collectors.summingInt(Employee::getSalary);
    + * } 
    + * + * (The {@code ?} for the second type parameter merely indicates that we don't + * care about the intermediate representation used by this collector.) + * If we wanted to create a collector to tabulate the sum of salaries by + * department, we could reuse {@code summingSalaries} using + * {@link java.util.stream.Collectors#groupingBy(java.util.function.Function, java.util.stream.Collector) groupingBy}: + * + *
    {@code
    + *     Map salariesByDept
    + *         = employees.stream().collect(Collectors.groupingBy(Employee::getDepartment,
    + *                                                            summingSalaries));
    + * } 
    + * + *

    As with the regular reduction operation, {@code collect()} operations can + * only be parallelized if appropriate conditions are met. For any partially accumulated result, + * combining it with an empty result container must produce an equivalent + * result. That is, for a partially accumulated result {@code p} that is the + * result of any series of accumulator and combiner invocations, {@code p} must + * be equivalent to {@code combiner.apply(p, supplier.get())}. + * + *

    Further, however the computation is split, it must produce an equivalent + * result. For any input elements {@code t1} and {@code t2}, the results + * {@code r1} and {@code r2} in the computation below must be equivalent: + *

    {@code
    + *     A a1 = supplier.get();
    + *     accumulator.accept(a1, t1);
    + *     accumulator.accept(a1, t2);
    + *     R r1 = finisher.apply(a1);  // result without splitting
    + *
    + *     A a2 = supplier.get();
    + *     accumulator.accept(a2, t1);
    + *     A a3 = supplier.get();
    + *     accumulator.accept(a3, t2);
    + *     R r2 = finisher.apply(combiner.apply(a2, a3));  // result with splitting
    + * } 
    + * + *

    Here, equivalence generally means according to {@link java.lang.Object#equals(Object)}. + * but in some cases equivalence may be relaxed to account for differences in + * order. + * + *

    Reduction, concurrency, and ordering

    + * + * With some complex reduction operations, for example a {@code collect()} that + * produces a {@code Map}, such as: *
    {@code
      *     Map> salesByBuyer
      *         = txns.parallelStream()
      *               .collect(Collectors.groupingBy(Transaction::getBuyer));
      * }
    - * (where {@link java.util.stream.Collectors#groupingBy} is a utility function - * that returns a {@link java.util.stream.Collector} for grouping sets of elements based on some key) * it may actually be counterproductive to perform the operation in parallel. * This is because the combining step (merging one {@code Map} into another by key) * can be expensive for some {@code Map} implementations. * *

    Suppose, however, that the result container used in this reduction * was a concurrently modifiable collection -- such as a - * {@link java.util.concurrent.ConcurrentHashMap ConcurrentHashMap}. In that case, - * the parallel invocations of the accumulator could actually deposit their results - * concurrently into the same shared result container, eliminating the need for the combiner to - * merge distinct result containers. This potentially provides a boost - * to the parallel execution performance. We call this a concurrent reduction. + * {@link java.util.concurrent.ConcurrentHashMap}. In that case, the parallel + * invocations of the accumulator could actually deposit their results + * concurrently into the same shared result container, eliminating the need for + * the combiner to merge distinct result containers. This potentially provides + * a boost to the parallel execution performance. We call this a concurrent + * reduction. * - *

    A {@link java.util.stream.Collector} that supports concurrent reduction is marked with the - * {@link java.util.stream.Collector.Characteristics#CONCURRENT} characteristic. - * Having a concurrent collector is a necessary condition for performing a - * concurrent reduction, but that alone is not sufficient. If you imagine multiple - * accumulators depositing results into a shared container, the order in which - * results are deposited is non-deterministic. Consequently, a concurrent reduction - * is only possible if ordering is not important for the stream being processed. - * The {@link java.util.stream.Stream#collect(Collector)} + *

    A {@link java.util.stream.Collector} that supports concurrent reduction is + * marked with the {@link java.util.stream.Collector.Characteristics#CONCURRENT} + * characteristic. However, a concurrent collection also has a downside. If + * multiple threads are depositing results concurrently into a shared container, + * the order in which results are deposited is non-deterministic. Consequently, + * a concurrent reduction is only possible if ordering is not important for the + * stream being processed. The {@link java.util.stream.Stream#collect(Collector)} * implementation will only perform a concurrent reduction if *

      *
    • The stream is parallel;
    • @@ -472,15 +624,16 @@ *
    • Either the stream is unordered, or the collector has the * {@link java.util.stream.Collector.Characteristics#UNORDERED} characteristic. *
    - * For example: + * You can ensure the stream is unordered by using the + * {@link java.util.stream.BaseStream#unordered()} method. For example: *
    {@code
      *     Map> salesByBuyer
      *         = txns.parallelStream()
      *               .unordered()
      *               .collect(groupingByConcurrent(Transaction::getBuyer));
      * }
    - * (where {@link java.util.stream.Collectors#groupingByConcurrent} is the concurrent companion - * to {@code groupingBy}). + * (where {@link java.util.stream.Collectors#groupingByConcurrent} is the + * concurrent equivalent of {@code groupingBy}). * *

    Note that if it is important that the elements for a given key appear in the * order they appear in the source, then we cannot use a concurrent reduction, @@ -488,79 +641,77 @@ * be constrained to implement either a sequential reduction or a merge-based * parallel reduction. * - *

    Associativity

    + *

    Associativity

    * - * An operator or function {@code op} is associative if the following holds: + * An operator or function {@code op} is associative if the following + * holds: *
    {@code
      *     (a op b) op c == a op (b op c)
      * }
    - * The importance of this to parallel evaluation can be seen if we expand this to four terms: + * The importance of this to parallel evaluation can be seen if we expand this + * to four terms: *
    {@code
      *     a op b op c op d == (a op b) op (c op d)
      * }
    - * So we can evaluate {@code (a op b)} in parallel with {@code (c op d)} and then invoke {@code op} on - * the results. - * TODO what does associative mean for mutative combining functions? - * FIXME: we described mutative associativity above. + * So we can evaluate {@code (a op b)} in parallel with {@code (c op d)}, and + * then invoke {@code op} on the results. * - *

    Stream sources

    - * TODO where does this section go? + *

    Examples of associative operations include numeric addition, min, and max, + * and string concatenation. * - * XXX - change to section to stream construction gradually introducing more - * complex ways to construct - * - construction from Collection - * - construction from Iterator - * - construction from array - * - construction from generators - * - construction from spliterator + *

    Low-level stream construction

    * - * XXX - the following is quite low-level but important aspect of stream constriction + * So far, all the stream examples have used methods like + * {@link java.util.Collection#stream()} or {@link java.util.Arrays#stream(Object[])} + * to obtain a stream. How are those stream-bearing methods implemented? * - *

    A pipeline is initially constructed from a spliterator (see {@link java.util.Spliterator}) supplied by a stream source. - * The spliterator covers elements of the source and provides element traversal operations - * for a possibly-parallel computation. See methods on {@link java.util.stream.Streams} for construction - * of pipelines using spliterators. + *

    The class {@link java.util.stream.StreamSupport} has a number of low-level + * methods for creating a stream, all using some form of a {@link java.util.Spliterator}. + * A spliterator is the parallel analogue of an {@link java.util.Iterator}; it + * describes a (possibly infinite) collection of elements, with support for + * sequentially advancing, bulk traversal, and splitting off some portion of the + * input into another spliterator which can be processed in parallel. At the + * lowest level, all streams are driven by a spliterator. * - *

    A source may directly supply a spliterator. If so, the spliterator is traversed, split, or queried - * for estimated size after, and never before, the terminal operation commences. It is strongly recommended - * that the spliterator report a characteristic of {@code IMMUTABLE} or {@code CONCURRENT}, or be - * late-binding and not bind to the elements it covers until traversed, split or queried for - * estimated size. + *

    There are a number of implementation choices in implementing a spliterator, + * nearly all of which are tradeoffs between simplicity of implementation and + * runtime performance of streams using that spliterator. The simplest, but + * least performant, way to create a spliterator is to create one from an iterator + * using {@link java.util.Spliterators#spliteratorUnknownSize(java.util.Iterator, int)}. + * While such a spliterator will work, it will likely offer poor parallel + * performance, since we have lost sizing information (how big is the underlying + * data set), as well as being constrained to a simplistic splitting algorithm. * - *

    If a source cannot directly supply a recommended spliterator then it may indirectly supply a spliterator - * using a {@code Supplier}. The spliterator is obtained from the supplier after, and never before, the terminal + *

    A higher-quality spliterator will provide balanced and known-size splits, + * accurate sizing information, and a number of other + * {@link java.util.Spliterator#characteristics() characteristics} of the + * spliterator or data that can be used by implementations to optimize + * execution. + * + *

    Spliterators for mutable data sources have an additional challenge; timing + * of binding to the data, since the data could change between the time the + * spliterator is created and the time the stream pipeline is executed. Ideally, + * a spliterator for a stream would report a characteristic of {@code IMMUTABLE} + * or {@code CONCURRENT}; if not it should be late-binding. + * If a source cannot directly supply a recommended spliterator, it may + * indirectly supply a spliterator using a {@code Supplier}, and construct a + * stream via the {@code Supplier}-accepting versions of + * {@link java.util.stream.StreamSupport#stream(Supplier, int, boolean) stream()}. + * The spliterator is obtained from the supplier only after the terminal * operation of the stream pipeline commences. * - *

    Such requirements significantly reduce the scope of potential interference to the interval starting - * with the commencing of the terminal operation and ending with the producing a result or side-effect. See - * Non-Interference for - * more details. + *

    These requirements significantly reduce the scope of potential interference + * between mutations of the stream source and execution of stream pipelines. + * Streams based on spliterators with the desired characteristics, or those using + * the Supplier-based factory forms, are immune to modifications of the data + * source prior to commencement of the terminal operation (provided the behavioral + * parameters to the stream operations meet the required criteria for non-interference + * and statelessness). See Non-Interference + * for more details. * - * XXX - move the following to the non-interference section - * - *

    A source can be modified before the terminal operation commences and those modifications will be reflected in - * the covered elements. Afterwards, and depending on the properties of the source, further modifications - * might not be reflected and the throwing of a {@code ConcurrentModificationException} may occur. - * - *

    For example, consider the following code: - *

    {@code
    - *     List l = new ArrayList(Arrays.asList("one", "two"));
    - *     Stream sl = l.stream();
    - *     l.add("three");
    - *     String s = sl.collect(joining(" "));
    - * }
    - * First a list is created consisting of two strings: "one"; and "two". Then a stream is created from that list. - * Next the list is modified by adding a third string: "three". Finally the elements of the stream are collected - * and joined together. Since the list was modified before the terminal {@code collect} operation commenced - * the result will be a string of "one two three". However, if the list is modified after the terminal operation - * commences, as in: - *
    {@code
    - *     List l = new ArrayList(Arrays.asList("one", "two"));
    - *     Stream sl = l.stream();
    - *     String s = sl.peek(s -> l.add("BAD LAMBDA")).collect(joining(" "));
    - * }
    - * then a {@code ConcurrentModificationException} will be thrown since the {@code peek} operation will attempt - * to add the string "BAD LAMBDA" to the list after the terminal operation has commenced. + * @since 1.8 */ - package java.util.stream; + +import java.util.function.BinaryOperator; +import java.util.function.UnaryOperator; From a3b1359af5a40a1cd1901f491bc7ebf2c7f2b6e0 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Sun, 8 Sep 2013 11:54:21 +0100 Subject: [PATCH 0263/1294] 8024398: javac, compiler crashes with try with empty body Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Lower.java | 46 ++++++++--------- .../test/tools/javac/T8024398/NPETryTest.java | 49 +++++++++++++++++++ 2 files changed, 73 insertions(+), 22 deletions(-) create mode 100644 langtools/test/tools/javac/T8024398/NPETryTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 7094d64b19c..5926a1b68c1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -3829,30 +3829,32 @@ public class Lower extends TreeTranslator { @Override public void visitTry(JCTry tree) { - if (tree.resources.isEmpty()) { - /* special case of try without catchers and with finally emtpy. - * Don't give it a try, translate only the body. - */ - if (tree.catchers.isEmpty() && - tree.finalizer.getStatements().isEmpty()) { - result = translate(tree.body); - } else { - /* also if the body is empty we only need to generate the finalizer - * provided that it's not empty. - */ - if (tree.body.getStatements().isEmpty()) { - if (tree.finalizer.getStatements().isEmpty()) { - result = translate(tree.body); - } else { - result = translate(tree.finalizer); - } - } else { - super.visitTry(tree); - } - } - } else { + if (tree.resources.nonEmpty()) { result = makeTwrTry(tree); + return; } + + boolean hasBody = tree.body.getStatements().nonEmpty(); + boolean hasCatchers = tree.catchers.nonEmpty(); + boolean hasFinally = tree.finalizer != null && + tree.finalizer.getStatements().nonEmpty(); + + if (!hasCatchers && !hasFinally) { + result = translate(tree.body); + return; + } + + if (!hasBody) { + if (hasFinally) { + result = translate(tree.finalizer); + } else { + result = translate(tree.body); + } + return; + } + + // no optimizations possible + super.visitTry(tree); } /************************************************************************** diff --git a/langtools/test/tools/javac/T8024398/NPETryTest.java b/langtools/test/tools/javac/T8024398/NPETryTest.java new file mode 100644 index 00000000000..7d5b11fb6e0 --- /dev/null +++ b/langtools/test/tools/javac/T8024398/NPETryTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 8024398 + * @summary javac, compiler crashes with try with empty body + * @compile NPETryTest.java + */ + +public class NPETryTest { + void m() + { + /* This is the statement provoking the error the rest are provided as + * additional tests + */ + try {} + catch (Exception e) {} + + try {} + catch (Exception e) {} + finally {} + + try {} + finally {} + } +} From 5df75e001d5282e64036a739ac03b18ae5637c7d Mon Sep 17 00:00:00 2001 From: Andreas Lundblad Date: Mon, 9 Sep 2013 09:58:20 +0200 Subject: [PATCH 0264/1294] 8022260: Rename javac.code.Annotations to javac.code.SymbolMetadata Reviewed-by: jfranck, jjg --- .../com/sun/tools/javac/code/Symbol.java | 14 +++++----- .../{Annotations.java => SymbolMetadata.java} | 26 +++++++++---------- langtools/test/tools/javac/lib/DPrinter.java | 14 +++++----- 3 files changed, 27 insertions(+), 27 deletions(-) rename langtools/src/share/classes/com/sun/tools/javac/code/{Annotations.java => SymbolMetadata.java} (94%) diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index 64c117cb2bc..d7552ee2a9e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -98,9 +98,9 @@ public abstract class Symbol implements Element { // /** The attributes of this symbol are contained in this - * Annotations. The Annotations instance is NOT immutable. + * SymbolMetadata. The SymbolMetadata instance is NOT immutable. */ - protected Annotations annotations; + protected SymbolMetadata annotations; /** An accessor method for the attributes of this symbol. * Attributes of class symbols should be accessed through the accessor @@ -217,19 +217,19 @@ public abstract class Symbol implements Element { public void setTypeAttributes(List a) { if (annotations != null || a.nonEmpty()) { if (annotations == null) - annotations = new Annotations(this); + annotations = new SymbolMetadata(this); annotations.setTypeAttributes(a); } } - private Annotations initedAnnos() { + private SymbolMetadata initedAnnos() { if (annotations == null) - annotations = new Annotations(this); + annotations = new SymbolMetadata(this); return annotations; } /** This method is intended for debugging only. */ - public Annotations getAnnotations() { + public SymbolMetadata getAnnotations() { return annotations; } @@ -852,7 +852,7 @@ public abstract class Symbol implements Element { private void mergeAttributes() { if (annotations == null && package_info.annotations != null) { - annotations = new Annotations(this); + annotations = new SymbolMetadata(this); annotations.setAttributes(package_info.annotations); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java similarity index 94% rename from langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java rename to langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java index 5be0865c042..42564f67ed3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java @@ -57,7 +57,7 @@ import static com.sun.tools.javac.code.Kinds.PCK; * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list * of attributes (and this moves out of the IN_PROGRESS state). * - * "unnamed" this Annotations contains some attributes, possibly the final set. + * "unnamed" this SymbolMetadata contains some attributes, possibly the final set. * While in this state you can only prepend or append to the attributes not set * it directly. You can also move back to the IN_PROGRESS state using reset(). * @@ -65,7 +65,7 @@ import static com.sun.tools.javac.code.Kinds.PCK; * on this, you do so at your own risk. This code and its internal interfaces * are subject to change or deletion without notice. */ -public class Annotations { +public class SymbolMetadata { private static final List DECL_NOT_STARTED = List.of(null); private static final List DECL_IN_PROGRESS = List.of(null); @@ -94,11 +94,11 @@ public class Annotations { private List clinit_type_attributes = List.nil(); /* - * The Symbol this Annotations instance belongs to + * The Symbol this SymbolMetadata instance belongs to */ private final Symbol sym; - public Annotations(Symbol sym) { + public SymbolMetadata(Symbol sym) { this.sym = sym; } @@ -147,7 +147,7 @@ public class Annotations { clinit_type_attributes = a; } - public void setAttributes(Annotations other) { + public void setAttributes(SymbolMetadata other) { if (other == null) { throw new NullPointerException(); } @@ -221,7 +221,7 @@ public class Annotations { return buf.reverse(); } - public Annotations reset() { + public SymbolMetadata reset() { attributes = DECL_IN_PROGRESS; return this; } @@ -240,7 +240,7 @@ public class Annotations { return attributes == DECL_IN_PROGRESS; } - public Annotations append(List l) { + public SymbolMetadata append(List l) { attributes = filterDeclSentinels(attributes); if (l.isEmpty()) { @@ -253,7 +253,7 @@ public class Annotations { return this; } - public Annotations appendUniqueTypes(List l) { + public SymbolMetadata appendUniqueTypes(List l) { if (l.isEmpty()) { ; // no-op } else if (type_attributes.isEmpty()) { @@ -269,7 +269,7 @@ public class Annotations { return this; } - public Annotations appendInitTypeAttributes(List l) { + public SymbolMetadata appendInitTypeAttributes(List l) { if (l.isEmpty()) { ; // no-op } else if (init_type_attributes.isEmpty()) { @@ -280,7 +280,7 @@ public class Annotations { return this; } - public Annotations appendClassInitTypeAttributes(List l) { + public SymbolMetadata appendClassInitTypeAttributes(List l) { if (l.isEmpty()) { ; // no-op } else if (clinit_type_attributes.isEmpty()) { @@ -291,7 +291,7 @@ public class Annotations { return this; } - public Annotations prepend(List l) { + public SymbolMetadata prepend(List l) { attributes = filterDeclSentinels(attributes); if (l.isEmpty()) { @@ -367,7 +367,7 @@ public class Annotations { type_attributes = result.reverse(); - Assert.check(Annotations.this.getTypePlaceholders().isEmpty()); + Assert.check(SymbolMetadata.this.getTypePlaceholders().isEmpty()); } else { Assert.check(!pendingCompletion()); @@ -391,7 +391,7 @@ public class Annotations { attributes = result.reverse(); - Assert.check(Annotations.this.getPlaceholders().isEmpty()); + Assert.check(SymbolMetadata.this.getPlaceholders().isEmpty()); } } finally { log.useSource(oldSource); diff --git a/langtools/test/tools/javac/lib/DPrinter.java b/langtools/test/tools/javac/lib/DPrinter.java index 8df4881cba4..8e67826c641 100644 --- a/langtools/test/tools/javac/lib/DPrinter.java +++ b/langtools/test/tools/javac/lib/DPrinter.java @@ -49,7 +49,7 @@ import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskListener; import com.sun.source.util.Trees; import com.sun.tools.javac.api.JavacTrees; -import com.sun.tools.javac.code.Annotations; +import com.sun.tools.javac.code.SymbolMetadata; import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Kinds; @@ -186,21 +186,21 @@ public class DPrinter { FULL }; - public void printAnnotations(String label, Annotations annotations) { + public void printAnnotations(String label, SymbolMetadata annotations) { printAnnotations(label, annotations, Details.FULL); } - protected void printAnnotations(String label, Annotations annotations, Details details) { + protected void printAnnotations(String label, SymbolMetadata annotations, Details details) { if (annotations == null) { printNull(label); } else { // no SUMMARY format currently available to use // use reflection to get at private fields - Object DECL_NOT_STARTED = getField(null, Annotations.class, "DECL_NOT_STARTED"); - Object DECL_IN_PROGRESS = getField(null, Annotations.class, "DECL_IN_PROGRESS"); - Object attributes = getField(annotations, Annotations.class, "attributes"); - Object type_attributes = getField(annotations, Annotations.class, "type_attributes"); + Object DECL_NOT_STARTED = getField(null, SymbolMetadata.class, "DECL_NOT_STARTED"); + Object DECL_IN_PROGRESS = getField(null, SymbolMetadata.class, "DECL_IN_PROGRESS"); + Object attributes = getField(annotations, SymbolMetadata.class, "attributes"); + Object type_attributes = getField(annotations, SymbolMetadata.class, "type_attributes"); if (!showEmptyItems) { if (attributes instanceof List && ((List) attributes).isEmpty() From 972efc6f0a9dff15c6f1c9fb57e7fe796baa300f Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Mon, 9 Sep 2013 10:01:09 +0100 Subject: [PATCH 0265/1294] 8023478: Test fails with HS crash in GCNotifier Reviewed-by: sla --- hotspot/src/share/vm/services/gcNotifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/services/gcNotifier.cpp b/hotspot/src/share/vm/services/gcNotifier.cpp index 7d1fe5d8944..1025072339a 100644 --- a/hotspot/src/share/vm/services/gcNotifier.cpp +++ b/hotspot/src/share/vm/services/gcNotifier.cpp @@ -209,7 +209,7 @@ void GCNotifier::sendNotificationInternal(TRAPS) { GCNotificationRequest *request = getRequest(); if (request != NULL) { NotificationMark nm(request); - Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, THREAD); + Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, CHECK); Handle objName = java_lang_String::create_from_str(request->gcManager->name(), CHECK); Handle objAction = java_lang_String::create_from_str(request->gcAction, CHECK); From 51205b7e55b87c3a4087055aff0448a5d4a10840 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Mon, 9 Sep 2013 17:14:51 +0400 Subject: [PATCH 0266/1294] 8024413: Add tests for issues JDK-8002077 and JDK-7199708 Reviewed-by: malenkov, leonidr --- .../JFileChooser/7199708/bug7199708.java | 158 ++++++++++++++++++ .../JFileChooser/8002077/bug8002077.java | 82 +++++++++ 2 files changed, 240 insertions(+) create mode 100644 jdk/test/javax/swing/JFileChooser/7199708/bug7199708.java create mode 100644 jdk/test/javax/swing/JFileChooser/8002077/bug8002077.java diff --git a/jdk/test/javax/swing/JFileChooser/7199708/bug7199708.java b/jdk/test/javax/swing/JFileChooser/7199708/bug7199708.java new file mode 100644 index 00000000000..339c6553a18 --- /dev/null +++ b/jdk/test/javax/swing/JFileChooser/7199708/bug7199708.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Component; +import java.awt.Container; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.File; +import java.io.IOException; +import javax.swing.JFileChooser; +import javax.swing.SwingUtilities; + +import java.nio.file.Files; +import javax.swing.AbstractButton; +import javax.swing.JTable; +import javax.swing.UIManager; +import sun.awt.SunToolkit; + +/** + * @test + * @bug 7199708 + * @author Alexander Scherbatiy + * @summary FileChooser crashs when opening large folder + * @run main bug7199708 + */ +public class bug7199708 { + + private static int FILE_NUMBER = 30000; + private static volatile JFileChooser fileChooser; + private static volatile int locationX; + private static volatile int locationY; + private static volatile int width; + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + + final File folder = createLargeFolder(); + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + fileChooser = new JFileChooser(folder); + fileChooser.showSaveDialog(null); + } + }); + + toolkit.realSync(); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + final String detailsTooltip = UIManager.getString("FileChooser." + + "detailsViewButtonToolTipText", fileChooser.getLocale()); + + doAction(fileChooser, new ComponentAction() { + @Override + public boolean accept(Component component) { + return (component instanceof AbstractButton) + && detailsTooltip.equals( + ((AbstractButton) component).getToolTipText()); + } + + @Override + public void perform(Component component) { + ((AbstractButton) component).doClick(); + } + }); + + doAction(fileChooser, new ComponentAction() { + @Override + public boolean accept(Component component) { + return (component instanceof JTable); + } + + @Override + public void perform(Component component) { + Point tableLocation = component.getLocationOnScreen(); + locationX = (int) tableLocation.getX(); + locationY = (int) tableLocation.getY(); + width = (int) fileChooser.getBounds().getWidth(); + } + }); + } + }); + + toolkit.realSync(); + + int d = 25; + for (int i = 0; i < width / d; i++) { + robot.mouseMove(locationX + i * d, locationY + 5); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + } + + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + } + + static void doAction(Component component, ComponentAction action) { + if (action.accept(component)) { + action.perform(component); + } else if (component instanceof Container) { + for (Component comp : ((Container) component).getComponents()) { + doAction(comp, action); + } + } + } + + private static File createLargeFolder() { + try { + + File largeFolder = Files.createTempDirectory("large_folder").toFile(); + largeFolder.deleteOnExit(); + + for (int i = 0; i < FILE_NUMBER; i++) { + File file = new File(largeFolder, "File_" + i + ".txt"); + file.createNewFile(); + file.deleteOnExit(); + } + return largeFolder; + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + interface ComponentAction { + + boolean accept(Component component); + + void perform(Component component); + } +} diff --git a/jdk/test/javax/swing/JFileChooser/8002077/bug8002077.java b/jdk/test/javax/swing/JFileChooser/8002077/bug8002077.java new file mode 100644 index 00000000000..ea1470d4ed5 --- /dev/null +++ b/jdk/test/javax/swing/JFileChooser/8002077/bug8002077.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.KeyEvent; +import javax.swing.JFileChooser; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; +import sun.awt.SunToolkit; + +/** + * @test + * @bug 8002077 + * @author Alexander Scherbatiy + * @summary Possible mnemonic issue on JFileChooser Save button on nimbus L&F + * @library ../../regtesthelpers/ + * @build Util + * @run main bug8002077 + */ +public class bug8002077 { + + private static volatile int fileChooserState = JFileChooser.ERROR_OPTION; + + public static void main(String[] args) throws Exception { + for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + UIManager.setLookAndFeel(info.getClassName()); + runTest(); + break; + } + } + } + + private static void runTest() throws Exception { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + fileChooserState = new JFileChooser().showSaveDialog(null); + } + }); + toolkit.realSync(); + + Util.hitMnemonics(robot, KeyEvent.VK_N); + toolkit.realSync(); + + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + toolkit.realSync(); + + Util.hitMnemonics(robot, KeyEvent.VK_S); + toolkit.realSync(); + + if (fileChooserState != JFileChooser.APPROVE_OPTION) { + throw new RuntimeException("Save button is not pressed!"); + } + } +} From dfacc4e2721d0f6891c1f380cfdd7009587e7957 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Mon, 9 Sep 2013 18:34:12 +0400 Subject: [PATCH 0267/1294] 8020060: MoleculeViewerTest demo doesn't work due to SecurityPermissions Reviewed-by: malenkov, erikj --- jdk/makefiles/CompileDemos.gmk | 8 +++----- jdk/src/share/demo/applets/MoleculeViewer/XYZApp.java | 2 +- .../share/demo/applets/MoleculeViewer/example1.html | 6 +++--- .../share/demo/applets/MoleculeViewer/example2.html | 6 +++--- .../share/demo/applets/MoleculeViewer/example3.html | 10 +++++----- jdk/src/share/demo/applets/WireFrame/ThreeD.java | 2 +- jdk/src/share/demo/applets/WireFrame/example1.html | 2 +- jdk/src/share/demo/applets/WireFrame/example2.html | 2 +- jdk/src/share/demo/applets/WireFrame/example3.html | 2 +- jdk/src/share/demo/applets/WireFrame/example4.html | 2 +- 10 files changed, 20 insertions(+), 22 deletions(-) diff --git a/jdk/makefiles/CompileDemos.gmk b/jdk/makefiles/CompileDemos.gmk index 0a093b586a9..6cd5dd4df0d 100644 --- a/jdk/makefiles/CompileDemos.gmk +++ b/jdk/makefiles/CompileDemos.gmk @@ -65,14 +65,10 @@ $(eval $(call SetupAppletDemo,DitherTest)) $(eval $(call SetupAppletDemo,DrawTest)) $(eval $(call SetupAppletDemo,Fractal)) $(eval $(call SetupAppletDemo,GraphicsTest)) -$(eval $(call SetupAppletDemo,MoleculeViewer)) $(eval $(call SetupAppletDemo,NervousText)) $(eval $(call SetupAppletDemo,SimpleGraph)) $(eval $(call SetupAppletDemo,SortDemo)) $(eval $(call SetupAppletDemo,SpreadSheet)) -# Build WireFrame without a server since it -# has a class Matrix3D that also exists in MoleculeViewer. -$(eval $(call SetupAppletDemo,WireFrame,true)) ifndef OPENJDK $(eval $(call SetupAppletDemo,Animator,,closed/)) @@ -83,7 +79,7 @@ endif ################################################################################################## -PATTERNS_TO_COPY=.html .txt .properties .js .gif .jpg .theme .data .opt README .c .h .png .ttf +PATTERNS_TO_COPY=.html .txt .properties .js .gif .jpg .theme .data .opt README .c .h .png .ttf .xyz .obj define SetupDemo # Param 1 = Name of the demo @@ -161,6 +157,8 @@ $(JDK_OUTPUTDIR)/demo/jfc/CodePointIM/_the.services : \ BUILD_DEMOS+=$(JDK_OUTPUTDIR)/demo/jfc/CodePointIM/_the.services +$(eval $(call SetupDemo,MoleculeViewer,applets,,XYZChemModel,,,example*.html XYZApp.java)) +$(eval $(call SetupDemo,WireFrame,applets,,ThreeD,,,example*.html ThreeD.java)) $(eval $(call SetupDemo,FileChooserDemo,jfc,,FileChooserDemo,,,README*)) $(eval $(call SetupDemo,Font2DTest,jfc,,Font2DTest,,,*.html *.txt)) $(eval $(call SetupDemo,Metalworks,jfc,,Metalworks,,,README*)) diff --git a/jdk/src/share/demo/applets/MoleculeViewer/XYZApp.java b/jdk/src/share/demo/applets/MoleculeViewer/XYZApp.java index 5ee3afe38ab..78c816a52a2 100644 --- a/jdk/src/share/demo/applets/MoleculeViewer/XYZApp.java +++ b/jdk/src/share/demo/applets/MoleculeViewer/XYZApp.java @@ -348,7 +348,7 @@ public class XYZApp extends Applet implements Runnable, MouseListener, InputStream is = null; try { Thread.currentThread().setPriority(Thread.MIN_PRIORITY); - is = new URL(getDocumentBase(), mdname).openStream(); + is = getClass().getResourceAsStream(mdname); XYZChemModel m = new XYZChemModel(is); Atom.setApplet(this); md = m; diff --git a/jdk/src/share/demo/applets/MoleculeViewer/example1.html b/jdk/src/share/demo/applets/MoleculeViewer/example1.html index de2e84b0943..f87aee60fe8 100644 --- a/jdk/src/share/demo/applets/MoleculeViewer/example1.html +++ b/jdk/src/share/demo/applets/MoleculeViewer/example1.html @@ -2,10 +2,10 @@ MoleculeViewer (example 1) - +

    MoleculeViewer (example 1)


    - + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag! @@ -13,7 +13,7 @@
    The source. - + diff --git a/jdk/src/share/demo/applets/MoleculeViewer/example2.html b/jdk/src/share/demo/applets/MoleculeViewer/example2.html index bb8f93a0b31..8468cc816b5 100644 --- a/jdk/src/share/demo/applets/MoleculeViewer/example2.html +++ b/jdk/src/share/demo/applets/MoleculeViewer/example2.html @@ -2,10 +2,10 @@ MoleculeViewer (example 2) - +

    MoleculeViewer (example 2)


    - + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag! @@ -13,4 +13,4 @@
    The source. - + diff --git a/jdk/src/share/demo/applets/MoleculeViewer/example3.html b/jdk/src/share/demo/applets/MoleculeViewer/example3.html index 952bc8d5cbd..c5673ea91a9 100644 --- a/jdk/src/share/demo/applets/MoleculeViewer/example3.html +++ b/jdk/src/share/demo/applets/MoleculeViewer/example3.html @@ -5,25 +5,25 @@

    MoleculeViewer (example 3)


    - + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag!

    - + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag!

    - + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag!

    - + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag! @@ -31,5 +31,5 @@
    The source. - + diff --git a/jdk/src/share/demo/applets/WireFrame/ThreeD.java b/jdk/src/share/demo/applets/WireFrame/ThreeD.java index 935ca0a99c7..321729ae61c 100644 --- a/jdk/src/share/demo/applets/WireFrame/ThreeD.java +++ b/jdk/src/share/demo/applets/WireFrame/ThreeD.java @@ -416,7 +416,7 @@ public class ThreeD extends Applet InputStream is = null; try { Thread.currentThread().setPriority(Thread.MIN_PRIORITY); - is = new URL(getDocumentBase(), mdname).openStream(); + is = getClass().getResourceAsStream(mdname); Model3D m = new Model3D(is); md = m; m.findBB(); diff --git a/jdk/src/share/demo/applets/WireFrame/example1.html b/jdk/src/share/demo/applets/WireFrame/example1.html index 1992ee53a26..6cc9c552e32 100644 --- a/jdk/src/share/demo/applets/WireFrame/example1.html +++ b/jdk/src/share/demo/applets/WireFrame/example1.html @@ -5,7 +5,7 @@

    3D Model: Cube


    - + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag! diff --git a/jdk/src/share/demo/applets/WireFrame/example2.html b/jdk/src/share/demo/applets/WireFrame/example2.html index eec2b1d429f..fb59eff3f82 100644 --- a/jdk/src/share/demo/applets/WireFrame/example2.html +++ b/jdk/src/share/demo/applets/WireFrame/example2.html @@ -5,7 +5,7 @@

    3D Model: Dinosaur


    - + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag! diff --git a/jdk/src/share/demo/applets/WireFrame/example3.html b/jdk/src/share/demo/applets/WireFrame/example3.html index 2b49d118ec7..4e4f5f186df 100644 --- a/jdk/src/share/demo/applets/WireFrame/example3.html +++ b/jdk/src/share/demo/applets/WireFrame/example3.html @@ -5,7 +5,7 @@

    3D Model: Hughes


    - + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag! diff --git a/jdk/src/share/demo/applets/WireFrame/example4.html b/jdk/src/share/demo/applets/WireFrame/example4.html index faf409254a1..664ee1eaa94 100644 --- a/jdk/src/share/demo/applets/WireFrame/example4.html +++ b/jdk/src/share/demo/applets/WireFrame/example4.html @@ -5,7 +5,7 @@

    3D Model: knoxS


    - + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag! From 0b67400c6f97e46c879a4c421572afce37072751 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Mon, 9 Sep 2013 20:10:41 +0530 Subject: [PATCH 0268/1294] 8024180: Incorrect handling of expression and parent scope in 'with' statements Reviewed-by: jlaskey, hannesw --- .../api/scripting/NashornScriptEngine.java | 15 ++-- .../api/scripting/ScriptObjectMirror.java | 20 +++-- .../jdk/nashorn/internal/objects/Global.java | 22 ++++- .../jdk/nashorn/internal/runtime/Context.java | 2 +- .../internal/runtime/GlobalObject.java | 12 +++ .../internal/runtime/NativeJavaPackage.java | 2 +- .../internal/runtime/ScriptObject.java | 70 ++++------------ .../internal/runtime/ScriptRuntime.java | 60 ++------------ .../nashorn/internal/runtime/WithObject.java | 82 +++++++++++-------- .../runtime/resources/Messages.properties | 1 + .../script/basic/8024180/global_var_delete.js | 50 +++++++++++ .../8024180/global_var_delete.js.EXPECTED | 2 + .../script/basic/8024180/global_var_shadow.js | 45 ++++++++++ .../8024180/global_var_shadow.js.EXPECTED | 2 + .../basic/8024180/scope_no_such_prop.js | 51 ++++++++++++ .../8024180/scope_no_such_prop.js.EXPECTED | 2 + .../basic/8024180/with_expr_prop_add.js | 47 +++++++++++ .../8024180/with_expr_prop_add.js.EXPECTED | 2 + .../basic/8024180/with_expr_proto_prop_add.js | 49 +++++++++++ .../with_expr_proto_prop_add.js.EXPECTED | 2 + .../script/basic/8024180/with_java_object.js | 36 ++++++++ .../8024180/with_java_object.js.EXPECTED | 1 + .../nashorn/internal/runtime/ContextTest.java | 3 +- 23 files changed, 415 insertions(+), 163 deletions(-) create mode 100644 nashorn/test/script/basic/8024180/global_var_delete.js create mode 100644 nashorn/test/script/basic/8024180/global_var_delete.js.EXPECTED create mode 100644 nashorn/test/script/basic/8024180/global_var_shadow.js create mode 100644 nashorn/test/script/basic/8024180/global_var_shadow.js.EXPECTED create mode 100644 nashorn/test/script/basic/8024180/scope_no_such_prop.js create mode 100644 nashorn/test/script/basic/8024180/scope_no_such_prop.js.EXPECTED create mode 100644 nashorn/test/script/basic/8024180/with_expr_prop_add.js create mode 100644 nashorn/test/script/basic/8024180/with_expr_prop_add.js.EXPECTED create mode 100644 nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js create mode 100644 nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED create mode 100644 nashorn/test/script/basic/8024180/with_java_object.js create mode 100644 nashorn/test/script/basic/8024180/with_java_object.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 9745d432783..ce42a46c7b5 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -315,7 +315,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C final ScriptObjectMirror mirror = (ScriptObjectMirror)thiz; realSelf = mirror.getScriptObject(); realGlobal = mirror.getHomeGlobal(); - if (! realGlobal.isOfContext(nashornContext)) { + if (! isOfContext(realGlobal, nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } } else if (thiz instanceof ScriptObject) { @@ -326,7 +326,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C throw new IllegalArgumentException(getMessage("no.current.nashorn.global")); } - if (! realGlobal.isOfContext(nashornContext)) { + if (! isOfContext(realGlobal, nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } } @@ -394,7 +394,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C // Retrieve nashorn Global object from a given ScriptObjectMirror private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) { ScriptObject sobj = mirror.getScriptObject(); - if (sobj instanceof GlobalObject && sobj.isOfContext(nashornContext)) { + if (sobj instanceof GlobalObject && isOfContext(sobj, nashornContext)) { return sobj; } @@ -470,7 +470,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ScriptObjectMirror selfMirror = null; if (selfObject instanceof ScriptObjectMirror) { selfMirror = (ScriptObjectMirror)selfObject; - if (! selfMirror.getHomeGlobal().isOfContext(nashornContext)) { + if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } } else if (selfObject instanceof ScriptObject) { @@ -481,7 +481,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C throw new IllegalArgumentException(getMessage("no.current.nashorn.global")); } - if (! oldGlobal.isOfContext(nashornContext)) { + if (! isOfContext(oldGlobal, nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } @@ -617,4 +617,9 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } return true; } + + private static boolean isOfContext(final ScriptObject global, final Context context) { + assert global instanceof GlobalObject: "Not a Global object"; + return ((GlobalObject)global).isOfContext(context); + } } diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java index 99ce73c1ca1..e8546cd6ce7 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java @@ -42,6 +42,7 @@ import java.util.Set; import java.util.concurrent.Callable; import javax.script.Bindings; import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.GlobalObject; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; @@ -62,6 +63,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { private final ScriptObject sobj; private final ScriptObject global; + private final boolean strict; @Override public boolean equals(final Object other) { @@ -101,7 +103,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { final Object val = functionName == null? sobj : sobj.get(functionName); if (val instanceof ScriptFunction) { final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; - return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); + return wrap(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { return ((ScriptObjectMirror)val).call(null, args); } @@ -131,7 +133,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { final Object val = functionName == null? sobj : sobj.get(functionName); if (val instanceof ScriptFunction) { final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; - return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global); + return wrap(ScriptRuntime.construct((ScriptFunction)val, unwrapArray(modArgs, global)), global); } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { return ((ScriptObjectMirror)val).newObject(null, args); } @@ -197,7 +199,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { public void setSlot(final int index, final Object value) { inGlobal(new Callable() { @Override public Void call() { - sobj.set(index, unwrap(value, global), global.isStrictContext()); + sobj.set(index, unwrap(value, global), strict); return null; } }); @@ -209,7 +211,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { public void clear() { inGlobal(new Callable() { @Override public Object call() { - sobj.clear(); + sobj.clear(strict); return null; } }); @@ -292,7 +294,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { return inGlobal(new Callable() { @Override public Object call() { final Object modValue = globalChanged? wrap(value, oldGlobal) : value; - return translateUndefined(wrap(sobj.put(key, unwrap(modValue, global)), global)); + return translateUndefined(wrap(sobj.put(key, unwrap(modValue, global), strict), global)); } }); } @@ -303,7 +305,6 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { final boolean globalChanged = (oldGlobal != global); inGlobal(new Callable() { @Override public Object call() { - final boolean strict = global.isStrictContext(); for (final Map.Entry entry : map.entrySet()) { final Object value = entry.getValue(); final Object modValue = globalChanged? wrap(value, oldGlobal) : value; @@ -318,7 +319,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { public Object remove(final Object key) { return inGlobal(new Callable() { @Override public Object call() { - return wrap(sobj.remove(unwrap(key, global)), global); + return wrap(sobj.remove(unwrap(key, global), strict), global); } }); } @@ -333,7 +334,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { public boolean delete(final Object key) { return inGlobal(new Callable() { @Override public Boolean call() { - return sobj.delete(unwrap(key, global)); + return sobj.delete(unwrap(key, global), strict); } }); } @@ -637,10 +638,11 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { ScriptObjectMirror(final ScriptObject sobj, final ScriptObject global) { assert sobj != null : "ScriptObjectMirror on null!"; - assert global != null : "null global for ScriptObjectMirror!"; + assert global instanceof GlobalObject : "global is not a GlobalObject"; this.sobj = sobj; this.global = global; + this.strict = ((GlobalObject)global).isStrictContext(); } // accessors for script engine diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java index 6d7be378be6..b7a902b745e 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java @@ -412,6 +412,14 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // initialized by nasgen private static PropertyMap $nasgenmap$; + // context to which this global belongs to + private final Context context; + + @Override + protected Context getContext() { + return context; + } + // performs initialization checks for Global constructor and returns the // PropertyMap, if everything is fine. private static PropertyMap checkAndGetMap(final Context context) { @@ -439,7 +447,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { */ public Global(final Context context) { super(checkAndGetMap(context)); - this.setContext(context); + this.context = context; this.setIsScope(); final int cacheSize = context.getEnv()._class_cache_size; @@ -481,6 +489,16 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // GlobalObject interface implementation + @Override + public boolean isOfContext(final Context context) { + return this.context == context; + } + + @Override + public boolean isStrictContext() { + return context.getEnv()._strict; + } + @Override public void initBuiltinObjects() { if (this.builtinObject != null) { @@ -1765,7 +1783,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // do not fill $ENV if we have a security manager around // Retrieve current state of ENV variables. final ScriptObject env = newObject(); - env.putAll(System.getenv()); + env.putAll(System.getenv(), scriptEnv._strict); addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, env); } else { addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 2f0c95d89b9..4651b508721 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -573,7 +573,7 @@ public final class Context { setGlobalTrusted(newGlobal); final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY : ScriptObjectMirror.wrapArray(args, oldGlobal); - newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped)); + newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped), env._strict); try { // wrap objects from newGlobal's world as mirrors - but if result diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java index 087b34554bc..7e01fd6e2ea 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java @@ -36,6 +36,18 @@ import jdk.nashorn.internal.runtime.linker.InvokeByName; */ public interface GlobalObject { + /** + * Is this global of the given Context? + * @return true if this global belongs to the given Context + */ + public boolean isOfContext(Context context); + + /** + * Does this global belong to a strict Context? + * @return true if this global belongs to a strict Context + */ + public boolean isStrictContext(); + /** * Initialize standard builtin objects like "Object", "Array", "Function" etc. * as well as our extension builtin objects like "Java", "JSAdapter" as properties diff --git a/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java b/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java index 9e725e339df..99ba9e19fa5 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java @@ -198,7 +198,7 @@ public final class NativeJavaPackage extends ScriptObject { final String propertyName = desc.getNameToken(2); final String fullName = name.isEmpty() ? propertyName : name + "." + propertyName; - final Context context = getContext(); + final Context context = Context.getContextTrusted(); Class javaClass = null; try { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java index f4a7c145aa8..a4ca6017b79 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -120,9 +120,6 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr /** objects proto. */ private ScriptObject proto; - /** Context of the object, lazily cached. */ - private Context context; - /** Object flags. */ private int flags; @@ -1042,41 +1039,12 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr set(key, value, false); } - /** - * Return true if the script object context is strict - * @return true if strict context - */ - public final boolean isStrictContext() { - return getContext()._strict; - } - - /** - * Checks if this object belongs to the given context - * @param ctx context to check against - * @return true if this object belongs to the given context - */ - public final boolean isOfContext(final Context ctx) { - return context == ctx; - } - /** * Return the current context from the object's map. * @return Current context. */ - protected final Context getContext() { - if (context == null) { - context = Context.fromClass(getClass()); - } - return context; - } - - /** - * Set the current context. - * @param ctx context instance to set - */ - protected final void setContext(final Context ctx) { - ctx.getClass(); - this.context = ctx; + protected Context getContext() { + return Context.fromClass(getClass()); } /** @@ -1482,9 +1450,10 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr /** * Clears the properties from a ScriptObject * (java.util.Map-like method to help ScriptObjectMirror implementation) + * + * @param strict strict mode or not */ - public void clear() { - final boolean strict = isStrictContext(); + public void clear(final boolean strict) { final Iterator iter = propertyIterator(); while (iter.hasNext()) { delete(iter.next(), strict); @@ -1568,11 +1537,12 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * * @param key property key * @param value property value + * @param strict strict mode or not * @return oldValue if property with same key existed already */ - public Object put(final Object key, final Object value) { + public Object put(final Object key, final Object value, final boolean strict) { final Object oldValue = get(key); - set(key, value, isStrictContext()); + set(key, value, strict); return oldValue; } @@ -1582,9 +1552,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * (java.util.Map-like method to help ScriptObjectMirror implementation) * * @param otherMap a {@literal } map of properties to add + * @param strict strict mode or not */ - public void putAll(final Map otherMap) { - final boolean strict = isStrictContext(); + public void putAll(final Map otherMap, final boolean strict) { for (final Map.Entry entry : otherMap.entrySet()) { set(entry.getKey(), entry.getValue(), strict); } @@ -1595,25 +1565,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * (java.util.Map-like method to help ScriptObjectMirror implementation) * * @param key the key of the property + * @param strict strict mode or not * @return the oldValue of the removed property */ - public Object remove(final Object key) { + public Object remove(final Object key, final boolean strict) { final Object oldValue = get(key); - delete(key, isStrictContext()); + delete(key, strict); return oldValue; } - /** - * Delete a property from the ScriptObject. - * (to help ScriptObjectMirror implementation) - * - * @param key the key of the property - * @return if the delete was successful or not - */ - public boolean delete(final Object key) { - return delete(key, isStrictContext()); - } - /** * Return the size of the ScriptObject - i.e. the number of properties * it contains @@ -2333,11 +2293,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - final boolean isStrict = isStrictContext(); - if (newLength > arrayLength) { setArray(getArray().ensure(newLength - 1)); - if (getArray().canDelete(arrayLength, (newLength - 1), isStrict)) { + if (getArray().canDelete(arrayLength, (newLength - 1), false)) { setArray(getArray().delete(arrayLength, (newLength - 1))); } return; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java index 0fa0cc8a94e..aa146f1df3d 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java @@ -351,35 +351,6 @@ public final class ScriptRuntime { return global; } - /** - * Check that the target function is associated with current Context. And also make sure that 'self', if - * ScriptObject, is from current context. - * - * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve - * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker} - * for operation {@code "dyn:call"}, then using its {@link MethodHandle#invokeExact(Object...)} method instead. - * - * @param target ScriptFunction object. - * @param self Receiver in call. - * @param args Call arguments. - * @return Call result. - */ - public static Object checkAndApply(final ScriptFunction target, final Object self, final Object... args) { - final ScriptObject global = Context.getGlobalTrusted(); - assert (global instanceof GlobalObject): "No current global set"; - - if (target.getContext() != global.getContext()) { - throw new IllegalArgumentException("'target' function is not from current Context"); - } - - if (self instanceof ScriptObject && ((ScriptObject)self).getContext() != global.getContext()) { - throw new IllegalArgumentException("'self' object is not from current Context"); - } - - // all in order - call real 'apply' - return apply(target, self, args); - } - /** * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker} @@ -400,28 +371,6 @@ public final class ScriptRuntime { } } - /** - * Check that the target function is associated with current Context. - * And also make sure that 'self', if ScriptObject, is from current context. - * - * Call a function as a constructor given args. - * - * @param target ScriptFunction object. - * @param args Call arguments. - * @return Constructor call result. - */ - public static Object checkAndConstruct(final ScriptFunction target, final Object... args) { - final ScriptObject global = Context.getGlobalTrusted(); - assert (global instanceof GlobalObject): "No current global set"; - - if (target.getContext() != global.getContext()) { - throw new IllegalArgumentException("'target' function is not from current Context"); - } - - // all in order - call real 'construct' - return construct(target, args); - } - /** * Call a script function as a constructor with given args. * @@ -520,9 +469,12 @@ public final class ScriptRuntime { throw typeError(global, "cant.apply.with.to.null"); } - final ScriptObject withObject = new WithObject(scope, JSType.toScriptObject(global, expression)); + final Object wrappedExpr = JSType.toScriptObject(global, expression); + if (wrappedExpr instanceof ScriptObject) { + return new WithObject(scope, (ScriptObject)wrappedExpr); + } - return withObject; + throw typeError(global, "cant.apply.with.to.non.scriptobject"); } /** @@ -534,7 +486,7 @@ public final class ScriptRuntime { */ public static ScriptObject closeWith(final ScriptObject scope) { if (scope instanceof WithObject) { - return scope.getProto(); + return ((WithObject)scope).getParentScope(); } return scope; } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java b/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java index 46de1d13ee5..7dc8307cd91 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java @@ -30,26 +30,26 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.lang.invoke.SwitchPoint; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.support.CallSiteDescriptorFactory; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; - /** * This class supports the handling of scope in a with body. * */ public final class WithObject extends ScriptObject implements Scope { - + private static final MethodHandle WITHEXPRESSIONGUARD = findOwnMH("withExpressionGuard", boolean.class, Object.class, PropertyMap.class, SwitchPoint.class); private static final MethodHandle WITHEXPRESSIONFILTER = findOwnMH("withFilterExpression", Object.class, Object.class); private static final MethodHandle WITHSCOPEFILTER = findOwnMH("withFilterScope", Object.class, Object.class); private static final MethodHandle BIND_TO_EXPRESSION_OBJ = findOwnMH("bindToExpression", Object.class, Object.class, Object.class); private static final MethodHandle BIND_TO_EXPRESSION_FN = findOwnMH("bindToExpression", Object.class, ScriptFunction.class, Object.class); /** With expression object. */ - private final Object expression; + private final ScriptObject expression; /** * Constructor @@ -57,12 +57,13 @@ public final class WithObject extends ScriptObject implements Scope { * @param scope scope object * @param expression with expression */ - WithObject(final ScriptObject scope, final Object expression) { + WithObject(final ScriptObject scope, final ScriptObject expression) { super(scope, null); setIsScope(); this.expression = expression; } + /** * Delete a property based on a key. * @param key Any valid JavaScript value. @@ -71,15 +72,13 @@ public final class WithObject extends ScriptObject implements Scope { */ @Override public boolean delete(final Object key, final boolean strict) { - if (expression instanceof ScriptObject) { - final ScriptObject self = (ScriptObject)expression; - final String propName = JSType.toString(key); + final ScriptObject self = expression; + final String propName = JSType.toString(key); - final FindProperty find = self.findProperty(propName, true); + final FindProperty find = self.findProperty(propName, true); - if (find != null) { - return self.delete(propName, strict); - } + if (find != null) { + return self.delete(propName, strict); } return false; @@ -105,18 +104,16 @@ public final class WithObject extends ScriptObject implements Scope { name = null; } - if (expression instanceof ScriptObject) { - self = (ScriptObject)expression; - if (isNamedOperation) { - find = self.findProperty(name, true); - } + self = expression; + if (isNamedOperation) { + find = self.findProperty(name, true); + } - if (find != null) { - link = self.lookup(desc, request); + if (find != null) { + link = self.lookup(desc, request); - if (link != null) { - return fixExpressionCallSite(ndesc, link); - } + if (link != null) { + return fixExpressionCallSite(ndesc, link); } } @@ -126,7 +123,7 @@ public final class WithObject extends ScriptObject implements Scope { } if (find != null) { - return fixScopeCallSite(scope.lookup(desc, request)); + return fixScopeCallSite(scope.lookup(desc, request), name); } // the property is not found - now check for @@ -178,7 +175,7 @@ public final class WithObject extends ScriptObject implements Scope { link = scope.lookup(desc, request); if (link != null) { - return fixScopeCallSite(link); + return fixScopeCallSite(link, name); } return null; @@ -197,11 +194,9 @@ public final class WithObject extends ScriptObject implements Scope { */ @Override FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) { - if (expression instanceof ScriptObject) { - final FindProperty exprProperty = ((ScriptObject)expression).findProperty(key, deep, stopOnNonScope, start); - if(exprProperty != null) { - return exprProperty; - } + final FindProperty exprProperty = expression.findProperty(key, deep, stopOnNonScope, start); + if (exprProperty != null) { + return exprProperty; } return super.findProperty(key, deep, stopOnNonScope, start); } @@ -220,16 +215,17 @@ public final class WithObject extends ScriptObject implements Scope { * Get first parent scope that is not an instance of WithObject. */ private Scope getNonWithParent() { - ScriptObject proto = getProto(); + ScriptObject proto = getParentScope(); while (proto != null && proto instanceof WithObject) { - proto = proto.getProto(); + proto = ((WithObject)proto).getParentScope(); } assert proto instanceof Scope : "with scope without parent scope"; return (Scope) proto; } + private static GuardedInvocation fixReceiverType(final GuardedInvocation link, final MethodHandle filter) { // The receiver may be an Object or a ScriptObject. final MethodType invType = link.getInvocation().type(); @@ -256,9 +252,13 @@ public final class WithObject extends ScriptObject implements Scope { filterGuard(link, WITHEXPRESSIONFILTER)); } - private static GuardedInvocation fixScopeCallSite(final GuardedInvocation link) { + private GuardedInvocation fixScopeCallSite(final GuardedInvocation link, final String name) { final GuardedInvocation newLink = fixReceiverType(link, WITHSCOPEFILTER); - return link.replaceMethods(filter(newLink.getInvocation(), WITHSCOPEFILTER), filterGuard(newLink, WITHSCOPEFILTER)); + return link.replaceMethods(filter(newLink.getInvocation(), WITHSCOPEFILTER), + MH.guardWithTest( + expressionGuard(name), + filterGuard(newLink, WITHSCOPEFILTER), + MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class))); } private static MethodHandle filterGuard(final GuardedInvocation link, final MethodHandle filter) { @@ -279,7 +279,6 @@ public final class WithObject extends ScriptObject implements Scope { return ((WithObject)receiver).expression; } - @SuppressWarnings("unused") private static Object bindToExpression(final Object fn, final Object receiver) { return fn instanceof ScriptFunction ? bindToExpression((ScriptFunction) fn, receiver) : fn; @@ -289,6 +288,17 @@ public final class WithObject extends ScriptObject implements Scope { return fn.makeBoundFunction(withFilterExpression(receiver), new Object[0]); } + private MethodHandle expressionGuard(final String name) { + final PropertyMap map = expression.getMap(); + final SwitchPoint sp = map.getProtoGetSwitchPoint(expression.getProto(), name); + return MH.insertArguments(WITHEXPRESSIONGUARD, 1, map, sp); + } + + @SuppressWarnings("unused") + private static boolean withExpressionGuard(final Object receiver, final PropertyMap map, final SwitchPoint sp) { + return ((WithObject)receiver).expression.getMap() == map && (sp == null || !sp.hasBeenInvalidated()); + } + /** * Drops the WithObject wrapper from the scope. * @param receiver WithObject wrapper. @@ -302,10 +312,14 @@ public final class WithObject extends ScriptObject implements Scope { * Get the with expression for this {@code WithObject} * @return the with expression */ - public Object getExpression() { + public ScriptObject getExpression() { return expression; } + public ScriptObject getParentScope() { + return getProto(); + } + private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { return MH.findStatic(MethodHandles.lookup(), WithObject.class, name, MH.type(rtype, types)); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties index 68f68c0a25b..5115e2ce0c7 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties @@ -110,6 +110,7 @@ type.error.cannot.get.default.string=Cannot get default string value type.error.cannot.get.default.number=Cannot get default number value type.error.cant.apply.with.to.null=Cannot apply "with" to null type.error.cant.apply.with.to.undefined=Cannot apply "with" to undefined +type.error.cant.apply.with.to.non.scriptobject=Cannot apply "with" to non script object type.error.in.with.non.object=Right hand side of "in" cannot be non-Object, found {0} type.error.prototype.not.an.object="prototype" of {0} is not an Object, it is {1} type.error.cant.load.script=Cannot load script from {0} diff --git a/nashorn/test/script/basic/8024180/global_var_delete.js b/nashorn/test/script/basic/8024180/global_var_delete.js new file mode 100644 index 00000000000..f099dd33f87 --- /dev/null +++ b/nashorn/test/script/basic/8024180/global_var_delete.js @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + + +this.x = 44; + +function func() { + with({ }) { + print(x); + } +} + +func(); + +// delete global 'x' +delete this.x; + +try { + func(); +} catch(e) { + // expect ReferenceError + print(e); +} diff --git a/nashorn/test/script/basic/8024180/global_var_delete.js.EXPECTED b/nashorn/test/script/basic/8024180/global_var_delete.js.EXPECTED new file mode 100644 index 00000000000..7e54b9e6a3c --- /dev/null +++ b/nashorn/test/script/basic/8024180/global_var_delete.js.EXPECTED @@ -0,0 +1,2 @@ +44 +ReferenceError: "x" is not defined diff --git a/nashorn/test/script/basic/8024180/global_var_shadow.js b/nashorn/test/script/basic/8024180/global_var_shadow.js new file mode 100644 index 00000000000..5ba5f5e2d1d --- /dev/null +++ b/nashorn/test/script/basic/8024180/global_var_shadow.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +// global variable is shadowed by with 'expression' property +var user = { name: 'foo' }; + +function func(locals) { + with (locals) { + print(user.name); + } +} + +// global user.name 'foo' printed +func({}); + +// local user.name 'toto' printed +func({ user: { name: 'toto' } }); + diff --git a/nashorn/test/script/basic/8024180/global_var_shadow.js.EXPECTED b/nashorn/test/script/basic/8024180/global_var_shadow.js.EXPECTED new file mode 100644 index 00000000000..7f1a102b9cc --- /dev/null +++ b/nashorn/test/script/basic/8024180/global_var_shadow.js.EXPECTED @@ -0,0 +1,2 @@ +foo +toto diff --git a/nashorn/test/script/basic/8024180/scope_no_such_prop.js b/nashorn/test/script/basic/8024180/scope_no_such_prop.js new file mode 100644 index 00000000000..5973c469e0d --- /dev/null +++ b/nashorn/test/script/basic/8024180/scope_no_such_prop.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +// __noSuchProperty__ defined here confuses 'with' +// results in ReferenceError even when 'with' expression has +// the property + +load("nashorn:mozilla_compat.js") + +function func(locals) { + with (locals) { + print(user.name); + } +} + +try { + func({}); +} catch (e) { + print(e); +} + +// 'toto' expected in the call below +func({ user: { name: 'toto' } }); + diff --git a/nashorn/test/script/basic/8024180/scope_no_such_prop.js.EXPECTED b/nashorn/test/script/basic/8024180/scope_no_such_prop.js.EXPECTED new file mode 100644 index 00000000000..ad4d247ea47 --- /dev/null +++ b/nashorn/test/script/basic/8024180/scope_no_such_prop.js.EXPECTED @@ -0,0 +1,2 @@ +ReferenceError: user is not defined +toto diff --git a/nashorn/test/script/basic/8024180/with_expr_prop_add.js b/nashorn/test/script/basic/8024180/with_expr_prop_add.js new file mode 100644 index 00000000000..7c3b3a546fb --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_expr_prop_add.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +var obj = {}; +var x = "global x"; + +// adding property to 'with' xpression object should reflect +// as variable inside the 'with' block. +function func() { + with(obj) { + for (i = 0; i < 2; i++) { + print(x); + if (i == 0) { + obj.x = "obj.x"; + } + } + } +} + +func(); diff --git a/nashorn/test/script/basic/8024180/with_expr_prop_add.js.EXPECTED b/nashorn/test/script/basic/8024180/with_expr_prop_add.js.EXPECTED new file mode 100644 index 00000000000..4139e361961 --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_expr_prop_add.js.EXPECTED @@ -0,0 +1,2 @@ +global x +obj.x diff --git a/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js b/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js new file mode 100644 index 00000000000..a6a17e7071b --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +var p = { }; +var obj = Object.create(p); + +var x = "global x"; + +// adding property to __proto__ of 'with' expression should +// reflect as a variable immediately. +function func() { + with(obj) { + for (i = 0; i < 2; i++) { + print(x); + if (i == 0) { + p.x = "p.x"; + } + } + } +} + +func(); diff --git a/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED b/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED new file mode 100644 index 00000000000..aa6d3681c18 --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED @@ -0,0 +1,2 @@ +global x +p.x diff --git a/nashorn/test/script/basic/8024180/with_java_object.js b/nashorn/test/script/basic/8024180/with_java_object.js new file mode 100644 index 00000000000..32db2a5c3e0 --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_java_object.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +// TypeError for with expression being non script object +try { + with(new java.lang.Object()) {} +} catch (e) { + print(e); +} diff --git a/nashorn/test/script/basic/8024180/with_java_object.js.EXPECTED b/nashorn/test/script/basic/8024180/with_java_object.js.EXPECTED new file mode 100644 index 00000000000..3f0facfade1 --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_java_object.js.EXPECTED @@ -0,0 +1 @@ +TypeError: Cannot apply "with" to non script object diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java index 16165ce704d..1b21c23f404 100644 --- a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java +++ b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java @@ -64,6 +64,7 @@ public class ContextTest { final Options options = new Options(""); final ErrorManager errors = new ErrorManager(); final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader()); + final boolean strict = cx.getEnv()._strict; final ScriptObject oldGlobal = Context.getGlobal(); Context.setGlobal(cx.createGlobal()); @@ -95,7 +96,7 @@ public class ContextTest { assertEquals(sobj.size(), 2); // add property - sobj.put("zee", "hello"); + sobj.put("zee", "hello", strict); assertEquals(sobj.get("zee"), "hello"); assertEquals(sobj.size(), 3); From 1704a9454c687cbcfb493646308261609bcd164e Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Mon, 9 Sep 2013 16:32:08 +0100 Subject: [PATCH 0269/1294] 8024154: Fix for 8016177: structural most specific and stuckness breaks 6 langtools tests Reviewed-by: jjg, jfranck --- .../tools/javac/lambda/MethodReference41.java | 26 ++----------------- .../tools/javac/lambda/MethodReference41.out | 6 ++--- .../tools/javac/lambda/MethodReference42.java | 26 ++----------------- .../tools/javac/lambda/MethodReference42.out | 6 ++--- .../tools/javac/lambda/MethodReference43.java | 26 ++----------------- .../tools/javac/lambda/MethodReference43.out | 8 +++--- .../tools/javac/lambda/MethodReference44.java | 26 ++----------------- .../tools/javac/lambda/MethodReference44.out | 6 ++--- .../tools/javac/lambda/MethodReference46.java | 26 ++----------------- .../tools/javac/lambda/MethodReference46.out | 6 ++--- .../tools/javac/lambda/MethodReference48.java | 26 ++----------------- .../tools/javac/lambda/MethodReference48.out | 4 +-- 12 files changed, 30 insertions(+), 162 deletions(-) diff --git a/langtools/test/tools/javac/lambda/MethodReference41.java b/langtools/test/tools/javac/lambda/MethodReference41.java index 836dce0f1cb..a3a8bddb605 100644 --- a/langtools/test/tools/javac/lambda/MethodReference41.java +++ b/langtools/test/tools/javac/lambda/MethodReference41.java @@ -1,33 +1,11 @@ /* - * Copyright (c) 2012, 2013, 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 + * @test /nodynamiccopyright/ * @bug 8003280 * @summary Add lambda tests * check that diamond inference is applied when using raw constructor reference qualifier * @compile/fail/ref=MethodReference41.out -XDrawDiagnostics MethodReference41.java */ + public class MethodReference41 { interface SAM1 { diff --git a/langtools/test/tools/javac/lambda/MethodReference41.out b/langtools/test/tools/javac/lambda/MethodReference41.out index f4a60cb3ba6..a501b109bd3 100644 --- a/langtools/test/tools/javac/lambda/MethodReference41.out +++ b/langtools/test/tools/javac/lambda/MethodReference41.out @@ -1,4 +1,4 @@ -MethodReference41.java:60:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference41.SAM1, @1819, kindname.class, MethodReference41, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.String, kindname.class, MethodReference41.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)))) -MethodReference41.java:62:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference41.SAM3, @1863, kindname.class, MethodReference41, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference41.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) -MethodReference41.java:63:9: compiler.err.ref.ambiguous: m4, kindname.method, m4(MethodReference41.SAM2), MethodReference41, kindname.method, m4(MethodReference41.SAM3), MethodReference41 +MethodReference41.java:38:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference41.SAM1, @767, kindname.class, MethodReference41, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.String, kindname.class, MethodReference41.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)))) +MethodReference41.java:40:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference41.SAM3, @811, kindname.class, MethodReference41, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference41.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) +MethodReference41.java:41:9: compiler.err.ref.ambiguous: m4, kindname.method, m4(MethodReference41.SAM2), MethodReference41, kindname.method, m4(MethodReference41.SAM3), MethodReference41 3 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference42.java b/langtools/test/tools/javac/lambda/MethodReference42.java index 957dc024902..61bef68c770 100644 --- a/langtools/test/tools/javac/lambda/MethodReference42.java +++ b/langtools/test/tools/javac/lambda/MethodReference42.java @@ -1,33 +1,11 @@ /* - * Copyright (c) 2012, 2013, 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 + * @test /nodynamiccopyright/ * @bug 8003280 * @summary Add lambda tests * check that diamond inference is applied when using raw constructor reference qualifier * @compile/fail/ref=MethodReference42.out -XDrawDiagnostics MethodReference42.java */ + public class MethodReference42 { static class SuperFoo { } diff --git a/langtools/test/tools/javac/lambda/MethodReference42.out b/langtools/test/tools/javac/lambda/MethodReference42.out index 70ec85a352e..ab324c44665 100644 --- a/langtools/test/tools/javac/lambda/MethodReference42.out +++ b/langtools/test/tools/javac/lambda/MethodReference42.out @@ -1,4 +1,4 @@ -MethodReference42.java:60:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference42.SAM1, @1851, kindname.class, MethodReference42, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number)) -MethodReference42.java:62:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference42.SAM3, @1895, kindname.class, MethodReference42, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Number)) -MethodReference42.java:63:9: compiler.err.ref.ambiguous: m4, kindname.method, m4(MethodReference42.SAM2), MethodReference42, kindname.method, m4(MethodReference42.SAM3), MethodReference42 +MethodReference42.java:38:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference42.SAM1, @811, kindname.class, MethodReference42, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number)) +MethodReference42.java:40:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference42.SAM3, @855, kindname.class, MethodReference42, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Number)) +MethodReference42.java:41:9: compiler.err.ref.ambiguous: m4, kindname.method, m4(MethodReference42.SAM2), MethodReference42, kindname.method, m4(MethodReference42.SAM3), MethodReference42 3 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference43.java b/langtools/test/tools/javac/lambda/MethodReference43.java index 53cf98c702f..99fbc3d5dd4 100644 --- a/langtools/test/tools/javac/lambda/MethodReference43.java +++ b/langtools/test/tools/javac/lambda/MethodReference43.java @@ -1,33 +1,11 @@ /* - * Copyright (c) 2012, 2013, 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 + * @test /nodynamiccopyright/ * @bug 8003280 * @summary Add lambda tests * check that diamond inference is applied when using raw constructor reference qualifier * @compile/fail/ref=MethodReference43.out -XDrawDiagnostics MethodReference43.java */ + public class MethodReference43 { interface SAM1 { diff --git a/langtools/test/tools/javac/lambda/MethodReference43.out b/langtools/test/tools/javac/lambda/MethodReference43.out index e1e0461d80f..dfe70b3c1f8 100644 --- a/langtools/test/tools/javac/lambda/MethodReference43.out +++ b/langtools/test/tools/javac/lambda/MethodReference43.out @@ -1,5 +1,5 @@ -MethodReference43.java:67:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference43.SAM1, @1937, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.String, kindname.class, MethodReference43.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)))) -MethodReference43.java:69:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference43.SAM3, @1981, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference43.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) -MethodReference43.java:71:9: compiler.err.ref.ambiguous: m5, kindname.method, m5(MethodReference43.SAM3), MethodReference43, kindname.method, m5(MethodReference43.SAM4), MethodReference43 -MethodReference43.java:71:11: compiler.err.cant.apply.symbol: kindname.method, m5, MethodReference43.SAM3, @2025, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference43.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) +MethodReference43.java:45:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference43.SAM1, @897, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.String, kindname.class, MethodReference43.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)))) +MethodReference43.java:47:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference43.SAM3, @941, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference43.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) +MethodReference43.java:49:9: compiler.err.ref.ambiguous: m5, kindname.method, m5(MethodReference43.SAM3), MethodReference43, kindname.method, m5(MethodReference43.SAM4), MethodReference43 +MethodReference43.java:49:11: compiler.err.cant.apply.symbol: kindname.method, m5, MethodReference43.SAM3, @985, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference43.Foo, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) 4 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference44.java b/langtools/test/tools/javac/lambda/MethodReference44.java index be96ad2987b..3a62d84657a 100644 --- a/langtools/test/tools/javac/lambda/MethodReference44.java +++ b/langtools/test/tools/javac/lambda/MethodReference44.java @@ -1,33 +1,11 @@ /* - * Copyright (c) 2012, 2013, 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 + * @test /nodynamiccopyright/ * @bug 8003280 * @summary Add lambda tests * check that generic method reference is inferred when type parameters are omitted * @compile/fail/ref=MethodReference44.out -XDrawDiagnostics MethodReference44.java */ + public class MethodReference44 { static class SuperFoo { } diff --git a/langtools/test/tools/javac/lambda/MethodReference44.out b/langtools/test/tools/javac/lambda/MethodReference44.out index dbf1a394fde..56c991c21f9 100644 --- a/langtools/test/tools/javac/lambda/MethodReference44.out +++ b/langtools/test/tools/javac/lambda/MethodReference44.out @@ -1,4 +1,4 @@ -MethodReference44.java:62:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference44.SAM1, @1904, kindname.class, MethodReference44, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number)) -MethodReference44.java:64:11: compiler.err.cant.apply.symbol: kindname.method, g3, MethodReference44.SAM3, @1972, kindname.class, MethodReference44, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Number)) -MethodReference44.java:65:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference44.SAM2), MethodReference44, kindname.method, g4(MethodReference44.SAM3), MethodReference44 +MethodReference44.java:40:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference44.SAM1, @864, kindname.class, MethodReference44, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number)) +MethodReference44.java:42:11: compiler.err.cant.apply.symbol: kindname.method, g3, MethodReference44.SAM3, @932, kindname.class, MethodReference44, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Number)) +MethodReference44.java:43:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference44.SAM2), MethodReference44, kindname.method, g4(MethodReference44.SAM3), MethodReference44 3 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference46.java b/langtools/test/tools/javac/lambda/MethodReference46.java index 0a9d42b8414..ee83739fcac 100644 --- a/langtools/test/tools/javac/lambda/MethodReference46.java +++ b/langtools/test/tools/javac/lambda/MethodReference46.java @@ -1,33 +1,11 @@ /* - * Copyright (c) 2012, 2013, 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 + * @test /nodynamiccopyright/ * @bug 8003280 * @summary Add lambda tests * check that generic method reference is inferred when type parameters are omitted * @compile/fail/ref=MethodReference46.out -XDrawDiagnostics MethodReference46.java */ + public class MethodReference46 { interface SAM1 { diff --git a/langtools/test/tools/javac/lambda/MethodReference46.out b/langtools/test/tools/javac/lambda/MethodReference46.out index 544affbd675..7d409282749 100644 --- a/langtools/test/tools/javac/lambda/MethodReference46.out +++ b/langtools/test/tools/javac/lambda/MethodReference46.out @@ -1,4 +1,4 @@ -MethodReference46.java:62:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference46.SAM1, @1849, kindname.class, MethodReference46, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m, X, java.lang.String, kindname.class, MethodReference46, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)))) -MethodReference46.java:64:11: compiler.err.cant.apply.symbol: kindname.method, g3, MethodReference46.SAM3, @1917, kindname.class, MethodReference46, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m, X, java.lang.Object, kindname.class, MethodReference46, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) -MethodReference46.java:65:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference46.SAM2), MethodReference46, kindname.method, g4(MethodReference46.SAM3), MethodReference46 +MethodReference46.java:40:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference46.SAM1, @809, kindname.class, MethodReference46, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m, X, java.lang.String, kindname.class, MethodReference46, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)))) +MethodReference46.java:42:11: compiler.err.cant.apply.symbol: kindname.method, g3, MethodReference46.SAM3, @877, kindname.class, MethodReference46, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m, X, java.lang.Object, kindname.class, MethodReference46, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number)))) +MethodReference46.java:43:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference46.SAM2), MethodReference46, kindname.method, g4(MethodReference46.SAM3), MethodReference46 3 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference48.java b/langtools/test/tools/javac/lambda/MethodReference48.java index 5247f4adb3b..153ec900700 100644 --- a/langtools/test/tools/javac/lambda/MethodReference48.java +++ b/langtools/test/tools/javac/lambda/MethodReference48.java @@ -1,33 +1,11 @@ /* - * Copyright (c) 2012, 2013, 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 + * @test /nodynamiccopyright/ * @bug 8003280 * @summary Add lambda tests * check that raw qualifier in unbound method reference is inferred from descriptor * @compile/fail/ref=MethodReference48.out -XDrawDiagnostics MethodReference48.java */ + public class MethodReference48 { static class Foo { diff --git a/langtools/test/tools/javac/lambda/MethodReference48.out b/langtools/test/tools/javac/lambda/MethodReference48.out index 732649e51f0..41b8a6be69f 100644 --- a/langtools/test/tools/javac/lambda/MethodReference48.out +++ b/langtools/test/tools/javac/lambda/MethodReference48.out @@ -1,3 +1,3 @@ -MethodReference48.java:60:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference48.SAM1, @1909, kindname.class, MethodReference48, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: java.lang.String, MethodReference48.Foo))) -MethodReference48.java:63:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference48.SAM2), MethodReference48, kindname.method, g4(MethodReference48.SAM3), MethodReference48 +MethodReference48.java:38:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference48.SAM1, @869, kindname.class, MethodReference48, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: java.lang.String, MethodReference48.Foo))) +MethodReference48.java:41:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference48.SAM2), MethodReference48, kindname.method, g4(MethodReference48.SAM3), MethodReference48 2 errors From 126ef9ca4e234847859d86792797defbc273e4df Mon Sep 17 00:00:00 2001 From: James Laskey Date: Mon, 9 Sep 2013 13:35:35 -0300 Subject: [PATCH 0270/1294] 8024397: Nashorn FX Libraries need to be finalized Reviewed-by: sundar, hannesw, lagergren --- .../internal/runtime/resources/fx/base.js | 322 ++++++-------- .../internal/runtime/resources/fx/fxml.js | 10 +- .../internal/runtime/resources/fx/graphics.js | 411 +----------------- .../internal/runtime/resources/fx/media.js | 25 +- .../internal/runtime/resources/fx/swing.js | 9 +- .../internal/runtime/resources/fx/swt.js | 9 +- .../internal/runtime/resources/fx/web.js | 16 +- 7 files changed, 153 insertions(+), 649 deletions(-) diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/base.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/base.js index 00559129298..b0bfc3fb1ee 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/base.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/base.js @@ -23,204 +23,126 @@ * questions. */ -Scene = Java.type("javafx.scene.Scene"); -Group = Java.type("javafx.scene.Group"); -Stage = Java.type("javafx.stage.Stage"); +var JFX_BASE_CLASSES = []; +var JFX_GRAPHICS_CLASSES = []; +var JFX_CONTROLS_CLASSES = []; +var JFX_FXML_CLASSES = []; +var JFX_WEB_CLASSES = []; +var JFX_MEDIA_CLASSES = []; +var JFX_SWING_CLASSES = []; +var JFX_SWT_CLASSES = []; -Binding = Java.type("javafx.beans.binding.Binding"); -Bindings = Java.type("javafx.beans.binding.Bindings"); -BooleanBinding = Java.type("javafx.beans.binding.BooleanBinding"); -BooleanExpression = Java.type("javafx.beans.binding.BooleanExpression"); -DoubleBinding = Java.type("javafx.beans.binding.DoubleBinding"); -DoubleExpression = Java.type("javafx.beans.binding.DoubleExpression"); -FloatBinding = Java.type("javafx.beans.binding.FloatBinding"); -FloatExpression = Java.type("javafx.beans.binding.FloatExpression"); -IntegerBinding = Java.type("javafx.beans.binding.IntegerBinding"); -IntegerExpression = Java.type("javafx.beans.binding.IntegerExpression"); -ListBinding = Java.type("javafx.beans.binding.ListBinding"); -ListExpression = Java.type("javafx.beans.binding.ListExpression"); -LongBinding = Java.type("javafx.beans.binding.LongBinding"); -LongExpression = Java.type("javafx.beans.binding.LongExpression"); -MapBinding = Java.type("javafx.beans.binding.MapBinding"); -MapExpression = Java.type("javafx.beans.binding.MapExpression"); -NumberBinding = Java.type("javafx.beans.binding.NumberBinding"); -NumberExpression = Java.type("javafx.beans.binding.NumberExpression"); -NumberExpressionBase = Java.type("javafx.beans.binding.NumberExpressionBase"); -ObjectBinding = Java.type("javafx.beans.binding.ObjectBinding"); -ObjectExpression = Java.type("javafx.beans.binding.ObjectExpression"); -SetBinding = Java.type("javafx.beans.binding.SetBinding"); -SetExpression = Java.type("javafx.beans.binding.SetExpression"); -StringBinding = Java.type("javafx.beans.binding.StringBinding"); -StringExpression = Java.type("javafx.beans.binding.StringExpression"); -When = Java.type("javafx.beans.binding.When"); -DefaultProperty = Java.type("javafx.beans.DefaultProperty"); -InvalidationListener = Java.type("javafx.beans.InvalidationListener"); -Observable = Java.type("javafx.beans.Observable"); -JavaBeanBooleanProperty = Java.type("javafx.beans.property.adapter.JavaBeanBooleanProperty"); -JavaBeanBooleanPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanBooleanPropertyBuilder"); -JavaBeanDoubleProperty = Java.type("javafx.beans.property.adapter.JavaBeanDoubleProperty"); -JavaBeanDoublePropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanDoublePropertyBuilder"); -JavaBeanFloatProperty = Java.type("javafx.beans.property.adapter.JavaBeanFloatProperty"); -JavaBeanFloatPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanFloatPropertyBuilder"); -JavaBeanIntegerProperty = Java.type("javafx.beans.property.adapter.JavaBeanIntegerProperty"); -JavaBeanIntegerPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanIntegerPropertyBuilder"); -JavaBeanLongProperty = Java.type("javafx.beans.property.adapter.JavaBeanLongProperty"); -JavaBeanLongPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanLongPropertyBuilder"); -JavaBeanObjectProperty = Java.type("javafx.beans.property.adapter.JavaBeanObjectProperty"); -JavaBeanObjectPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanObjectPropertyBuilder"); -JavaBeanProperty = Java.type("javafx.beans.property.adapter.JavaBeanProperty"); -JavaBeanStringProperty = Java.type("javafx.beans.property.adapter.JavaBeanStringProperty"); -JavaBeanStringPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanStringPropertyBuilder"); -ReadOnlyJavaBeanBooleanProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanBooleanProperty"); -ReadOnlyJavaBeanBooleanPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanBooleanPropertyBuilder"); -ReadOnlyJavaBeanDoubleProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanDoubleProperty"); -ReadOnlyJavaBeanDoublePropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanDoublePropertyBuilder"); -ReadOnlyJavaBeanFloatProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanFloatProperty"); -ReadOnlyJavaBeanFloatPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanFloatPropertyBuilder"); -ReadOnlyJavaBeanIntegerProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanIntegerProperty"); -ReadOnlyJavaBeanIntegerPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanIntegerPropertyBuilder"); -ReadOnlyJavaBeanLongProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanLongProperty"); -ReadOnlyJavaBeanLongPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanLongPropertyBuilder"); -ReadOnlyJavaBeanObjectProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanObjectProperty"); -ReadOnlyJavaBeanObjectPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanObjectPropertyBuilder"); -ReadOnlyJavaBeanProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanProperty"); -ReadOnlyJavaBeanStringProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanStringProperty"); -ReadOnlyJavaBeanStringPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanStringPropertyBuilder"); -BooleanProperty = Java.type("javafx.beans.property.BooleanProperty"); -BooleanPropertyBase = Java.type("javafx.beans.property.BooleanPropertyBase"); -DoubleProperty = Java.type("javafx.beans.property.DoubleProperty"); -DoublePropertyBase = Java.type("javafx.beans.property.DoublePropertyBase"); -FloatProperty = Java.type("javafx.beans.property.FloatProperty"); -FloatPropertyBase = Java.type("javafx.beans.property.FloatPropertyBase"); -IntegerProperty = Java.type("javafx.beans.property.IntegerProperty"); -IntegerPropertyBase = Java.type("javafx.beans.property.IntegerPropertyBase"); -ListProperty = Java.type("javafx.beans.property.ListProperty"); -ListPropertyBase = Java.type("javafx.beans.property.ListPropertyBase"); -LongProperty = Java.type("javafx.beans.property.LongProperty"); -LongPropertyBase = Java.type("javafx.beans.property.LongPropertyBase"); -MapProperty = Java.type("javafx.beans.property.MapProperty"); -MapPropertyBase = Java.type("javafx.beans.property.MapPropertyBase"); -ObjectProperty = Java.type("javafx.beans.property.ObjectProperty"); -ObjectPropertyBase = Java.type("javafx.beans.property.ObjectPropertyBase"); -Property = Java.type("javafx.beans.property.Property"); -ReadOnlyBooleanProperty = Java.type("javafx.beans.property.ReadOnlyBooleanProperty"); -ReadOnlyBooleanPropertyBase = Java.type("javafx.beans.property.ReadOnlyBooleanPropertyBase"); -ReadOnlyBooleanWrapper = Java.type("javafx.beans.property.ReadOnlyBooleanWrapper"); -ReadOnlyDoubleProperty = Java.type("javafx.beans.property.ReadOnlyDoubleProperty"); -ReadOnlyDoublePropertyBase = Java.type("javafx.beans.property.ReadOnlyDoublePropertyBase"); -ReadOnlyDoubleWrapper = Java.type("javafx.beans.property.ReadOnlyDoubleWrapper"); -ReadOnlyFloatProperty = Java.type("javafx.beans.property.ReadOnlyFloatProperty"); -ReadOnlyFloatPropertyBase = Java.type("javafx.beans.property.ReadOnlyFloatPropertyBase"); -ReadOnlyFloatWrapper = Java.type("javafx.beans.property.ReadOnlyFloatWrapper"); -ReadOnlyIntegerProperty = Java.type("javafx.beans.property.ReadOnlyIntegerProperty"); -ReadOnlyIntegerPropertyBase = Java.type("javafx.beans.property.ReadOnlyIntegerPropertyBase"); -ReadOnlyIntegerWrapper = Java.type("javafx.beans.property.ReadOnlyIntegerWrapper"); -ReadOnlyListProperty = Java.type("javafx.beans.property.ReadOnlyListProperty"); -ReadOnlyListPropertyBase = Java.type("javafx.beans.property.ReadOnlyListPropertyBase"); -ReadOnlyListWrapper = Java.type("javafx.beans.property.ReadOnlyListWrapper"); -ReadOnlyLongProperty = Java.type("javafx.beans.property.ReadOnlyLongProperty"); -ReadOnlyLongPropertyBase = Java.type("javafx.beans.property.ReadOnlyLongPropertyBase"); -ReadOnlyLongWrapper = Java.type("javafx.beans.property.ReadOnlyLongWrapper"); -ReadOnlyMapProperty = Java.type("javafx.beans.property.ReadOnlyMapProperty"); -ReadOnlyMapPropertyBase = Java.type("javafx.beans.property.ReadOnlyMapPropertyBase"); -ReadOnlyMapWrapper = Java.type("javafx.beans.property.ReadOnlyMapWrapper"); -ReadOnlyObjectProperty = Java.type("javafx.beans.property.ReadOnlyObjectProperty"); -ReadOnlyObjectPropertyBase = Java.type("javafx.beans.property.ReadOnlyObjectPropertyBase"); -ReadOnlyObjectWrapper = Java.type("javafx.beans.property.ReadOnlyObjectWrapper"); -ReadOnlyProperty = Java.type("javafx.beans.property.ReadOnlyProperty"); -ReadOnlySetProperty = Java.type("javafx.beans.property.ReadOnlySetProperty"); -ReadOnlySetPropertyBase = Java.type("javafx.beans.property.ReadOnlySetPropertyBase"); -ReadOnlySetWrapper = Java.type("javafx.beans.property.ReadOnlySetWrapper"); -ReadOnlyStringProperty = Java.type("javafx.beans.property.ReadOnlyStringProperty"); -ReadOnlyStringPropertyBase = Java.type("javafx.beans.property.ReadOnlyStringPropertyBase"); -ReadOnlyStringWrapper = Java.type("javafx.beans.property.ReadOnlyStringWrapper"); -SetProperty = Java.type("javafx.beans.property.SetProperty"); -SetPropertyBase = Java.type("javafx.beans.property.SetPropertyBase"); -SimpleBooleanProperty = Java.type("javafx.beans.property.SimpleBooleanProperty"); -SimpleDoubleProperty = Java.type("javafx.beans.property.SimpleDoubleProperty"); -SimpleFloatProperty = Java.type("javafx.beans.property.SimpleFloatProperty"); -SimpleIntegerProperty = Java.type("javafx.beans.property.SimpleIntegerProperty"); -SimpleListProperty = Java.type("javafx.beans.property.SimpleListProperty"); -SimpleLongProperty = Java.type("javafx.beans.property.SimpleLongProperty"); -SimpleMapProperty = Java.type("javafx.beans.property.SimpleMapProperty"); -SimpleObjectProperty = Java.type("javafx.beans.property.SimpleObjectProperty"); -SimpleSetProperty = Java.type("javafx.beans.property.SimpleSetProperty"); -SimpleStringProperty = Java.type("javafx.beans.property.SimpleStringProperty"); -StringProperty = Java.type("javafx.beans.property.StringProperty"); -StringPropertyBase = Java.type("javafx.beans.property.StringPropertyBase"); -ChangeListener = Java.type("javafx.beans.value.ChangeListener"); -ObservableBooleanValue = Java.type("javafx.beans.value.ObservableBooleanValue"); -ObservableDoubleValue = Java.type("javafx.beans.value.ObservableDoubleValue"); -ObservableFloatValue = Java.type("javafx.beans.value.ObservableFloatValue"); -ObservableIntegerValue = Java.type("javafx.beans.value.ObservableIntegerValue"); -ObservableListValue = Java.type("javafx.beans.value.ObservableListValue"); -ObservableLongValue = Java.type("javafx.beans.value.ObservableLongValue"); -ObservableMapValue = Java.type("javafx.beans.value.ObservableMapValue"); -ObservableNumberValue = Java.type("javafx.beans.value.ObservableNumberValue"); -ObservableObjectValue = Java.type("javafx.beans.value.ObservableObjectValue"); -ObservableSetValue = Java.type("javafx.beans.value.ObservableSetValue"); -ObservableStringValue = Java.type("javafx.beans.value.ObservableStringValue"); -ObservableValue = Java.type("javafx.beans.value.ObservableValue"); -ObservableValueBase = Java.type("javafx.beans.value.ObservableValueBase"); -WeakChangeListener = Java.type("javafx.beans.value.WeakChangeListener"); -WritableBooleanValue = Java.type("javafx.beans.value.WritableBooleanValue"); -WritableDoubleValue = Java.type("javafx.beans.value.WritableDoubleValue"); -WritableFloatValue = Java.type("javafx.beans.value.WritableFloatValue"); -WritableIntegerValue = Java.type("javafx.beans.value.WritableIntegerValue"); -WritableListValue = Java.type("javafx.beans.value.WritableListValue"); -WritableLongValue = Java.type("javafx.beans.value.WritableLongValue"); -WritableMapValue = Java.type("javafx.beans.value.WritableMapValue"); -WritableNumberValue = Java.type("javafx.beans.value.WritableNumberValue"); -WritableObjectValue = Java.type("javafx.beans.value.WritableObjectValue"); -WritableSetValue = Java.type("javafx.beans.value.WritableSetValue"); -WritableStringValue = Java.type("javafx.beans.value.WritableStringValue"); -WritableValue = Java.type("javafx.beans.value.WritableValue"); -WeakInvalidationListener = Java.type("javafx.beans.WeakInvalidationListener"); -WeakListener = Java.type("javafx.beans.WeakListener"); -FXCollections = Java.type("javafx.collections.FXCollections"); -ListChangeListener = Java.type("javafx.collections.ListChangeListener"); -ListChangeListener$Change = Java.type("javafx.collections.ListChangeListener$Change"); -MapChangeListener = Java.type("javafx.collections.MapChangeListener"); -MapChangeListener$Change = Java.type("javafx.collections.MapChangeListener$Change"); -ModifiableObservableListBase = Java.type("javafx.collections.ModifiableObservableListBase"); -ObservableList = Java.type("javafx.collections.ObservableList"); -ObservableListBase = Java.type("javafx.collections.ObservableListBase"); -ObservableMap = Java.type("javafx.collections.ObservableMap"); -ObservableSet = Java.type("javafx.collections.ObservableSet"); -SetChangeListener = Java.type("javafx.collections.SetChangeListener"); -SetChangeListener$Change = Java.type("javafx.collections.SetChangeListener$Change"); -WeakListChangeListener = Java.type("javafx.collections.WeakListChangeListener"); -WeakMapChangeListener = Java.type("javafx.collections.WeakMapChangeListener"); -WeakSetChangeListener = Java.type("javafx.collections.WeakSetChangeListener"); -ActionEvent = Java.type("javafx.event.ActionEvent"); -Event = Java.type("javafx.event.Event"); -EventDispatchChain = Java.type("javafx.event.EventDispatchChain"); -EventDispatcher = Java.type("javafx.event.EventDispatcher"); -EventHandler = Java.type("javafx.event.EventHandler"); -EventTarget = Java.type("javafx.event.EventTarget"); -EventType = Java.type("javafx.event.EventType"); -WeakEventHandler = Java.type("javafx.event.WeakEventHandler"); -Builder = Java.type("javafx.util.Builder"); -BuilderFactory = Java.type("javafx.util.BuilderFactory"); -Callback = Java.type("javafx.util.Callback"); -BigDecimalStringConverter = Java.type("javafx.util.converter.BigDecimalStringConverter"); -BigIntegerStringConverter = Java.type("javafx.util.converter.BigIntegerStringConverter"); -BooleanStringConverter = Java.type("javafx.util.converter.BooleanStringConverter"); -ByteStringConverter = Java.type("javafx.util.converter.ByteStringConverter"); -CharacterStringConverter = Java.type("javafx.util.converter.CharacterStringConverter"); -CurrencyStringConverter = Java.type("javafx.util.converter.CurrencyStringConverter"); -DateStringConverter = Java.type("javafx.util.converter.DateStringConverter"); -DateTimeStringConverter = Java.type("javafx.util.converter.DateTimeStringConverter"); -DefaultStringConverter = Java.type("javafx.util.converter.DefaultStringConverter"); -DoubleStringConverter = Java.type("javafx.util.converter.DoubleStringConverter"); -FloatStringConverter = Java.type("javafx.util.converter.FloatStringConverter"); -FormatStringConverter = Java.type("javafx.util.converter.FormatStringConverter"); -IntegerStringConverter = Java.type("javafx.util.converter.IntegerStringConverter"); -LongStringConverter = Java.type("javafx.util.converter.LongStringConverter"); -NumberStringConverter = Java.type("javafx.util.converter.NumberStringConverter"); -PercentageStringConverter = Java.type("javafx.util.converter.PercentageStringConverter"); -ShortStringConverter = Java.type("javafx.util.converter.ShortStringConverter"); -TimeStringConverter = Java.type("javafx.util.converter.TimeStringConverter"); -Duration = Java.type("javafx.util.Duration"); -Pair = Java.type("javafx.util.Pair"); -StringConverter = Java.type("javafx.util.StringConverter"); +function LOAD_FX_CLASSES(clsList) { + + for each (var cls in clsList) { + // Ex. Stage = Java.type("javafx.stage.Stage"); + this[cls[cls.length - 1]] = Java.type(cls.join(".")); + } +} + +(function() { + var System = Java.type("java.lang.System"); + var ZipFile = Java.type("java.util.zip.ZipFile"); + + var SUFFIX_LENGTH = ".class".length; + + try { + var jfxrtJar = new ZipFile(System.getProperty("java.home") + "/lib/ext/jfxrt.jar"); + } catch (ex) { + throw new Error("JavaFX runtime not found"); + } + + var entries = jfxrtJar.entries(); + + while (entries.hasMoreElements()) { + var entry = entries.nextElement(); + + if (entry.isDirectory()) { + continue; + } + + var name = entry.name; + + if (!name.endsWith(".class")) { + continue; + } + + name = name.substring(0, name.length - SUFFIX_LENGTH); + cls = name.split("/"); + + if (cls[0] != "javafx") { + continue; + } + + var last = cls[cls.length - 1]; + var nested = last.lastIndexOf("$"); + + // If class name ends with $nnn + if (nested != -1 && !(last.substring(nested) - 0)) { + continue; + } + + switch (cls[1]) { + case "stage": + if (cls[2] == "Stage") { + JFX_BASE_CLASSES.push(cls); + } else { + JFX_GRAPHICS_CLASSES.push(cls); + } + break; + + case "scene": + switch (cls[2]) { + case "Scene": + case "Group": + JFX_BASE_CLASSES.push(cls); + break; + + case "chart": + case "control": + JFX_CONTROLS_CLASSES.push(cls); + break; + + case "web": + JFX_WEB_CLASSES.push(cls); + break; + + case "media": + JFX_MEDIA_CLASSES.push(cls); + break; + + default: + JFX_GRAPHICS_CLASSES.push(cls); + break; + } + break; + + case "beans": + case "collections": + case "events": + case "util": + JFX_BASE_CLASSES.push(cls); + break; + + case "animation": + case "application": + case "concurrent": + case "css": + case "geometry": + JFX_GRAPHICS_CLASSES.push(cls); + break; + + case "fxml": + JFX_FXML_CLASSES.push(cls); + break; + + case "embed": + if (cls[2] == "swing") { + JFX_SWING_CLASSES.push(cls); + } else { + JFX_SWT_CLASSES.push(cls); + } + break; + } + } +})(); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js index bc018a9ece3..0ce18168ce6 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js @@ -23,8 +23,8 @@ * questions. */ -FXML = Java.type("javafx.fxml.FXML"); -FXMLLoader = Java.type("javafx.fxml.FXMLLoader"); -Initializable = Java.type("javafx.fxml.Initializable"); -JavaFXBuilderFactory = Java.type("javafx.fxml.JavaFXBuilderFactory"); -LoadException = Java.type("javafx.fxml.LoadException"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_FXML_CLASSES); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js index 72f55cd1926..f41661fa9e1 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js @@ -23,409 +23,10 @@ * questions. */ -Animation = Java.type("javafx.animation.Animation"); -Animation$Status = Java.type("javafx.animation.Animation$Status"); -AnimationBuilder = Java.type("javafx.animation.AnimationBuilder"); -AnimationTimer = Java.type("javafx.animation.AnimationTimer"); -FadeTransition = Java.type("javafx.animation.FadeTransition"); -FadeTransitionBuilder = Java.type("javafx.animation.FadeTransitionBuilder"); -FillTransition = Java.type("javafx.animation.FillTransition"); -FillTransitionBuilder = Java.type("javafx.animation.FillTransitionBuilder"); -Interpolatable = Java.type("javafx.animation.Interpolatable"); -Interpolator = Java.type("javafx.animation.Interpolator"); -KeyFrame = Java.type("javafx.animation.KeyFrame"); -KeyValue = Java.type("javafx.animation.KeyValue"); -ParallelTransition = Java.type("javafx.animation.ParallelTransition"); -ParallelTransitionBuilder = Java.type("javafx.animation.ParallelTransitionBuilder"); -PathTransition = Java.type("javafx.animation.PathTransition"); -PathTransition$OrientationType = Java.type("javafx.animation.PathTransition$OrientationType"); -PathTransitionBuilder = Java.type("javafx.animation.PathTransitionBuilder"); -PauseTransition = Java.type("javafx.animation.PauseTransition"); -PauseTransitionBuilder = Java.type("javafx.animation.PauseTransitionBuilder"); -RotateTransition = Java.type("javafx.animation.RotateTransition"); -RotateTransitionBuilder = Java.type("javafx.animation.RotateTransitionBuilder"); -ScaleTransition = Java.type("javafx.animation.ScaleTransition"); -ScaleTransitionBuilder = Java.type("javafx.animation.ScaleTransitionBuilder"); -SequentialTransition = Java.type("javafx.animation.SequentialTransition"); -SequentialTransitionBuilder = Java.type("javafx.animation.SequentialTransitionBuilder"); -StrokeTransition = Java.type("javafx.animation.StrokeTransition"); -StrokeTransitionBuilder = Java.type("javafx.animation.StrokeTransitionBuilder"); -Timeline = Java.type("javafx.animation.Timeline"); -TimelineBuilder = Java.type("javafx.animation.TimelineBuilder"); -Transition = Java.type("javafx.animation.Transition"); -TransitionBuilder = Java.type("javafx.animation.TransitionBuilder"); -TranslateTransition = Java.type("javafx.animation.TranslateTransition"); -TranslateTransitionBuilder = Java.type("javafx.animation.TranslateTransitionBuilder"); -Application = Java.type("javafx.application.Application"); -Application$Parameters = Java.type("javafx.application.Application$Parameters"); -ConditionalFeature = Java.type("javafx.application.ConditionalFeature"); -HostServices = Java.type("javafx.application.HostServices"); -Platform = Java.type("javafx.application.Platform"); -Preloader = Java.type("javafx.application.Preloader"); -Preloader$ErrorNotification = Java.type("javafx.application.Preloader$ErrorNotification"); -Preloader$PreloaderNotification = Java.type("javafx.application.Preloader$PreloaderNotification"); -Preloader$ProgressNotification = Java.type("javafx.application.Preloader$ProgressNotification"); -Preloader$StateChangeNotification = Java.type("javafx.application.Preloader$StateChangeNotification"); -Preloader$StateChangeNotification$Type = Java.type("javafx.application.Preloader$StateChangeNotification$Type"); -ScheduledService = Java.type("javafx.concurrent.ScheduledService"); -Service = Java.type("javafx.concurrent.Service"); -Task = Java.type("javafx.concurrent.Task"); -Worker = Java.type("javafx.concurrent.Worker"); -Worker$State = Java.type("javafx.concurrent.Worker$State"); -WorkerStateEvent = Java.type("javafx.concurrent.WorkerStateEvent"); -CssMetaData = Java.type("javafx.css.CssMetaData"); -FontCssMetaData = Java.type("javafx.css.FontCssMetaData"); -ParsedValue = Java.type("javafx.css.ParsedValue"); -PseudoClass = Java.type("javafx.css.PseudoClass"); -SimpleStyleableBooleanProperty = Java.type("javafx.css.SimpleStyleableBooleanProperty"); -SimpleStyleableDoubleProperty = Java.type("javafx.css.SimpleStyleableDoubleProperty"); -SimpleStyleableFloatProperty = Java.type("javafx.css.SimpleStyleableFloatProperty"); -SimpleStyleableIntegerProperty = Java.type("javafx.css.SimpleStyleableIntegerProperty"); -SimpleStyleableLongProperty = Java.type("javafx.css.SimpleStyleableLongProperty"); -SimpleStyleableObjectProperty = Java.type("javafx.css.SimpleStyleableObjectProperty"); -SimpleStyleableStringProperty = Java.type("javafx.css.SimpleStyleableStringProperty"); -Styleable = Java.type("javafx.css.Styleable"); -StyleableBooleanProperty = Java.type("javafx.css.StyleableBooleanProperty"); -StyleableDoubleProperty = Java.type("javafx.css.StyleableDoubleProperty"); -StyleableFloatProperty = Java.type("javafx.css.StyleableFloatProperty"); -StyleableIntegerProperty = Java.type("javafx.css.StyleableIntegerProperty"); -StyleableLongProperty = Java.type("javafx.css.StyleableLongProperty"); -StyleableObjectProperty = Java.type("javafx.css.StyleableObjectProperty"); -StyleableProperty = Java.type("javafx.css.StyleableProperty"); -StyleableStringProperty = Java.type("javafx.css.StyleableStringProperty"); -StyleConverter = Java.type("javafx.css.StyleConverter"); -StyleOrigin = Java.type("javafx.css.StyleOrigin"); -BoundingBox = Java.type("javafx.geometry.BoundingBox"); -BoundingBoxBuilder = Java.type("javafx.geometry.BoundingBoxBuilder"); -Bounds = Java.type("javafx.geometry.Bounds"); -Dimension2D = Java.type("javafx.geometry.Dimension2D"); -Dimension2DBuilder = Java.type("javafx.geometry.Dimension2DBuilder"); -HorizontalDirection = Java.type("javafx.geometry.HorizontalDirection"); -HPos = Java.type("javafx.geometry.HPos"); -Insets = Java.type("javafx.geometry.Insets"); -InsetsBuilder = Java.type("javafx.geometry.InsetsBuilder"); -NodeOrientation = Java.type("javafx.geometry.NodeOrientation"); -Orientation = Java.type("javafx.geometry.Orientation"); -Point2D = Java.type("javafx.geometry.Point2D"); -Point2DBuilder = Java.type("javafx.geometry.Point2DBuilder"); -Point3D = Java.type("javafx.geometry.Point3D"); -Point3DBuilder = Java.type("javafx.geometry.Point3DBuilder"); -Pos = Java.type("javafx.geometry.Pos"); -Rectangle2D = Java.type("javafx.geometry.Rectangle2D"); -Rectangle2DBuilder = Java.type("javafx.geometry.Rectangle2DBuilder"); -Side = Java.type("javafx.geometry.Side"); -VerticalDirection = Java.type("javafx.geometry.VerticalDirection"); -VPos = Java.type("javafx.geometry.VPos"); -Collation = Java.type("javafx.print.Collation"); -JobSettings = Java.type("javafx.print.JobSettings"); -PageLayout = Java.type("javafx.print.PageLayout"); -PageOrientation = Java.type("javafx.print.PageOrientation"); -PageRange = Java.type("javafx.print.PageRange"); -Paper = Java.type("javafx.print.Paper"); -Paper$Units = Java.type("javafx.print.Paper$Units"); -PaperSource = Java.type("javafx.print.PaperSource"); -PrintColor = Java.type("javafx.print.PrintColor"); -Printer = Java.type("javafx.print.Printer"); -Printer$MarginType = Java.type("javafx.print.Printer$MarginType"); -PrinterAttributes = Java.type("javafx.print.PrinterAttributes"); -PrinterJob = Java.type("javafx.print.PrinterJob"); -PrinterJob$JobStatus = Java.type("javafx.print.PrinterJob$JobStatus"); -PrintQuality = Java.type("javafx.print.PrintQuality"); -PrintResolution = Java.type("javafx.print.PrintResolution"); -PrintSides = Java.type("javafx.print.PrintSides"); -AmbientLight = Java.type("javafx.scene.AmbientLight"); -//AmbientLightBuilder = Java.type("javafx.scene.AmbientLightBuilder"); -CacheHint = Java.type("javafx.scene.CacheHint"); -Camera = Java.type("javafx.scene.Camera"); -//CameraBuilder = Java.type("javafx.scene.CameraBuilder"); -Canvas = Java.type("javafx.scene.canvas.Canvas"); -CanvasBuilder = Java.type("javafx.scene.canvas.CanvasBuilder"); -GraphicsContext = Java.type("javafx.scene.canvas.GraphicsContext"); -Cursor = Java.type("javafx.scene.Cursor"); -DepthTest = Java.type("javafx.scene.DepthTest"); -Blend = Java.type("javafx.scene.effect.Blend"); -BlendBuilder = Java.type("javafx.scene.effect.BlendBuilder"); -BlendMode = Java.type("javafx.scene.effect.BlendMode"); -Bloom = Java.type("javafx.scene.effect.Bloom"); -BloomBuilder = Java.type("javafx.scene.effect.BloomBuilder"); -BlurType = Java.type("javafx.scene.effect.BlurType"); -BoxBlur = Java.type("javafx.scene.effect.BoxBlur"); -BoxBlurBuilder = Java.type("javafx.scene.effect.BoxBlurBuilder"); -ColorAdjust = Java.type("javafx.scene.effect.ColorAdjust"); -ColorAdjustBuilder = Java.type("javafx.scene.effect.ColorAdjustBuilder"); -ColorInput = Java.type("javafx.scene.effect.ColorInput"); -ColorInputBuilder = Java.type("javafx.scene.effect.ColorInputBuilder"); -DisplacementMap = Java.type("javafx.scene.effect.DisplacementMap"); -DisplacementMapBuilder = Java.type("javafx.scene.effect.DisplacementMapBuilder"); -DropShadow = Java.type("javafx.scene.effect.DropShadow"); -DropShadowBuilder = Java.type("javafx.scene.effect.DropShadowBuilder"); -Effect = Java.type("javafx.scene.effect.Effect"); -FloatMap = Java.type("javafx.scene.effect.FloatMap"); -FloatMapBuilder = Java.type("javafx.scene.effect.FloatMapBuilder"); -GaussianBlur = Java.type("javafx.scene.effect.GaussianBlur"); -GaussianBlurBuilder = Java.type("javafx.scene.effect.GaussianBlurBuilder"); -Glow = Java.type("javafx.scene.effect.Glow"); -GlowBuilder = Java.type("javafx.scene.effect.GlowBuilder"); -ImageInput = Java.type("javafx.scene.effect.ImageInput"); -ImageInputBuilder = Java.type("javafx.scene.effect.ImageInputBuilder"); -InnerShadow = Java.type("javafx.scene.effect.InnerShadow"); -InnerShadowBuilder = Java.type("javafx.scene.effect.InnerShadowBuilder"); -Light = Java.type("javafx.scene.effect.Light"); -Light$Distant = Java.type("javafx.scene.effect.Light$Distant"); -Light$Point = Java.type("javafx.scene.effect.Light$Point"); -Light$Spot = Java.type("javafx.scene.effect.Light$Spot"); -LightBuilder = Java.type("javafx.scene.effect.LightBuilder"); -Lighting = Java.type("javafx.scene.effect.Lighting"); -LightingBuilder = Java.type("javafx.scene.effect.LightingBuilder"); -MotionBlur = Java.type("javafx.scene.effect.MotionBlur"); -MotionBlurBuilder = Java.type("javafx.scene.effect.MotionBlurBuilder"); -PerspectiveTransform = Java.type("javafx.scene.effect.PerspectiveTransform"); -PerspectiveTransformBuilder = Java.type("javafx.scene.effect.PerspectiveTransformBuilder"); -Reflection = Java.type("javafx.scene.effect.Reflection"); -ReflectionBuilder = Java.type("javafx.scene.effect.ReflectionBuilder"); -SepiaTone = Java.type("javafx.scene.effect.SepiaTone"); -SepiaToneBuilder = Java.type("javafx.scene.effect.SepiaToneBuilder"); -Shadow = Java.type("javafx.scene.effect.Shadow"); -ShadowBuilder = Java.type("javafx.scene.effect.ShadowBuilder"); -//Group = Java.type("javafx.scene.Group"); -GroupBuilder = Java.type("javafx.scene.GroupBuilder"); -Image = Java.type("javafx.scene.image.Image"); -ImageView = Java.type("javafx.scene.image.ImageView"); -ImageViewBuilder = Java.type("javafx.scene.image.ImageViewBuilder"); -PixelFormat = Java.type("javafx.scene.image.PixelFormat"); -PixelFormat$Type = Java.type("javafx.scene.image.PixelFormat$Type"); -PixelReader = Java.type("javafx.scene.image.PixelReader"); -PixelWriter = Java.type("javafx.scene.image.PixelWriter"); -WritableImage = Java.type("javafx.scene.image.WritableImage"); -WritablePixelFormat = Java.type("javafx.scene.image.WritablePixelFormat"); -ImageCursor = Java.type("javafx.scene.ImageCursor"); -ImageCursorBuilder = Java.type("javafx.scene.ImageCursorBuilder"); -Clipboard = Java.type("javafx.scene.input.Clipboard"); -ClipboardContent = Java.type("javafx.scene.input.ClipboardContent"); -ClipboardContentBuilder = Java.type("javafx.scene.input.ClipboardContentBuilder"); -ContextMenuEvent = Java.type("javafx.scene.input.ContextMenuEvent"); -DataFormat = Java.type("javafx.scene.input.DataFormat"); -Dragboard = Java.type("javafx.scene.input.Dragboard"); -DragEvent = Java.type("javafx.scene.input.DragEvent"); -GestureEvent = Java.type("javafx.scene.input.GestureEvent"); -InputEvent = Java.type("javafx.scene.input.InputEvent"); -//InputEventBuilder = Java.type("javafx.scene.input.InputEventBuilder"); -InputMethodEvent = Java.type("javafx.scene.input.InputMethodEvent"); -InputMethodHighlight = Java.type("javafx.scene.input.InputMethodHighlight"); -InputMethodRequests = Java.type("javafx.scene.input.InputMethodRequests"); -InputMethodTextRun = Java.type("javafx.scene.input.InputMethodTextRun"); -//InputMethodTextRunBuilder = Java.type("javafx.scene.input.InputMethodTextRunBuilder"); -KeyCharacterCombination = Java.type("javafx.scene.input.KeyCharacterCombination"); -KeyCharacterCombinationBuilder = Java.type("javafx.scene.input.KeyCharacterCombinationBuilder"); -KeyCode = Java.type("javafx.scene.input.KeyCode"); -KeyCodeCombination = Java.type("javafx.scene.input.KeyCodeCombination"); -KeyCodeCombinationBuilder = Java.type("javafx.scene.input.KeyCodeCombinationBuilder"); -KeyCombination = Java.type("javafx.scene.input.KeyCombination"); -KeyCombination$Modifier = Java.type("javafx.scene.input.KeyCombination$Modifier"); -KeyCombination$ModifierValue = Java.type("javafx.scene.input.KeyCombination$ModifierValue"); -KeyEvent = Java.type("javafx.scene.input.KeyEvent"); -Mnemonic = Java.type("javafx.scene.input.Mnemonic"); -MnemonicBuilder = Java.type("javafx.scene.input.MnemonicBuilder"); -MouseButton = Java.type("javafx.scene.input.MouseButton"); -MouseDragEvent = Java.type("javafx.scene.input.MouseDragEvent"); -MouseEvent = Java.type("javafx.scene.input.MouseEvent"); -PickResult = Java.type("javafx.scene.input.PickResult"); -RotateEvent = Java.type("javafx.scene.input.RotateEvent"); -ScrollEvent = Java.type("javafx.scene.input.ScrollEvent"); -ScrollEvent$HorizontalTextScrollUnits = Java.type("javafx.scene.input.ScrollEvent$HorizontalTextScrollUnits"); -ScrollEvent$VerticalTextScrollUnits = Java.type("javafx.scene.input.ScrollEvent$VerticalTextScrollUnits"); -SwipeEvent = Java.type("javafx.scene.input.SwipeEvent"); -TouchEvent = Java.type("javafx.scene.input.TouchEvent"); -TouchPoint = Java.type("javafx.scene.input.TouchPoint"); -TouchPoint$State = Java.type("javafx.scene.input.TouchPoint$State"); -//TouchPointBuilder = Java.type("javafx.scene.input.TouchPointBuilder"); -TransferMode = Java.type("javafx.scene.input.TransferMode"); -ZoomEvent = Java.type("javafx.scene.input.ZoomEvent"); -AnchorPane = Java.type("javafx.scene.layout.AnchorPane"); -AnchorPaneBuilder = Java.type("javafx.scene.layout.AnchorPaneBuilder"); -Background = Java.type("javafx.scene.layout.Background"); -//BackgroundBuilder = Java.type("javafx.scene.layout.BackgroundBuilder"); -BackgroundFill = Java.type("javafx.scene.layout.BackgroundFill"); -//BackgroundFillBuilder = Java.type("javafx.scene.layout.BackgroundFillBuilder"); -BackgroundImage = Java.type("javafx.scene.layout.BackgroundImage"); -//BackgroundImageBuilder = Java.type("javafx.scene.layout.BackgroundImageBuilder"); -BackgroundPosition = Java.type("javafx.scene.layout.BackgroundPosition"); -//BackgroundPositionBuilder = Java.type("javafx.scene.layout.BackgroundPositionBuilder"); -BackgroundRepeat = Java.type("javafx.scene.layout.BackgroundRepeat"); -BackgroundSize = Java.type("javafx.scene.layout.BackgroundSize"); -//BackgroundSizeBuilder = Java.type("javafx.scene.layout.BackgroundSizeBuilder"); -Border = Java.type("javafx.scene.layout.Border"); -//BorderBuilder = Java.type("javafx.scene.layout.BorderBuilder"); -BorderImage = Java.type("javafx.scene.layout.BorderImage"); -//BorderImageBuilder = Java.type("javafx.scene.layout.BorderImageBuilder"); -BorderPane = Java.type("javafx.scene.layout.BorderPane"); -BorderPaneBuilder = Java.type("javafx.scene.layout.BorderPaneBuilder"); -BorderRepeat = Java.type("javafx.scene.layout.BorderRepeat"); -BorderStroke = Java.type("javafx.scene.layout.BorderStroke"); -//BorderStrokeBuilder = Java.type("javafx.scene.layout.BorderStrokeBuilder"); -BorderStrokeStyle = Java.type("javafx.scene.layout.BorderStrokeStyle"); -//BorderStrokeStyleBuilder = Java.type("javafx.scene.layout.BorderStrokeStyleBuilder"); -BorderWidths = Java.type("javafx.scene.layout.BorderWidths"); -//BorderWidthsBuilder = Java.type("javafx.scene.layout.BorderWidthsBuilder"); -ColumnConstraints = Java.type("javafx.scene.layout.ColumnConstraints"); -ColumnConstraintsBuilder = Java.type("javafx.scene.layout.ColumnConstraintsBuilder"); -ConstraintsBase = Java.type("javafx.scene.layout.ConstraintsBase"); -CornerRadii = Java.type("javafx.scene.layout.CornerRadii"); -FlowPane = Java.type("javafx.scene.layout.FlowPane"); -FlowPaneBuilder = Java.type("javafx.scene.layout.FlowPaneBuilder"); -GridPane = Java.type("javafx.scene.layout.GridPane"); -GridPaneBuilder = Java.type("javafx.scene.layout.GridPaneBuilder"); -HBox = Java.type("javafx.scene.layout.HBox"); -HBoxBuilder = Java.type("javafx.scene.layout.HBoxBuilder"); -Pane = Java.type("javafx.scene.layout.Pane"); -PaneBuilder = Java.type("javafx.scene.layout.PaneBuilder"); -Priority = Java.type("javafx.scene.layout.Priority"); -Region = Java.type("javafx.scene.layout.Region"); -RegionBuilder = Java.type("javafx.scene.layout.RegionBuilder"); -RowConstraints = Java.type("javafx.scene.layout.RowConstraints"); -RowConstraintsBuilder = Java.type("javafx.scene.layout.RowConstraintsBuilder"); -StackPane = Java.type("javafx.scene.layout.StackPane"); -StackPaneBuilder = Java.type("javafx.scene.layout.StackPaneBuilder"); -TilePane = Java.type("javafx.scene.layout.TilePane"); -TilePaneBuilder = Java.type("javafx.scene.layout.TilePaneBuilder"); -VBox = Java.type("javafx.scene.layout.VBox"); -VBoxBuilder = Java.type("javafx.scene.layout.VBoxBuilder"); -LightBase = Java.type("javafx.scene.LightBase"); -//LightBaseBuilder = Java.type("javafx.scene.LightBaseBuilder"); -Node = Java.type("javafx.scene.Node"); -NodeBuilder = Java.type("javafx.scene.NodeBuilder"); -Color = Java.type("javafx.scene.paint.Color"); -ColorBuilder = Java.type("javafx.scene.paint.ColorBuilder"); -CycleMethod = Java.type("javafx.scene.paint.CycleMethod"); -ImagePattern = Java.type("javafx.scene.paint.ImagePattern"); -ImagePatternBuilder = Java.type("javafx.scene.paint.ImagePatternBuilder"); -LinearGradient = Java.type("javafx.scene.paint.LinearGradient"); -LinearGradientBuilder = Java.type("javafx.scene.paint.LinearGradientBuilder"); -Material = Java.type("javafx.scene.paint.Material"); -Paint = Java.type("javafx.scene.paint.Paint"); -PhongMaterial = Java.type("javafx.scene.paint.PhongMaterial"); -//PhongMaterialBuilder = Java.type("javafx.scene.paint.PhongMaterialBuilder"); -RadialGradient = Java.type("javafx.scene.paint.RadialGradient"); -RadialGradientBuilder = Java.type("javafx.scene.paint.RadialGradientBuilder"); -Stop = Java.type("javafx.scene.paint.Stop"); -StopBuilder = Java.type("javafx.scene.paint.StopBuilder"); -ParallelCamera = Java.type("javafx.scene.ParallelCamera"); -//ParallelCameraBuilder = Java.type("javafx.scene.ParallelCameraBuilder"); -Parent = Java.type("javafx.scene.Parent"); -ParentBuilder = Java.type("javafx.scene.ParentBuilder"); -PerspectiveCamera = Java.type("javafx.scene.PerspectiveCamera"); -PerspectiveCameraBuilder = Java.type("javafx.scene.PerspectiveCameraBuilder"); -PointLight = Java.type("javafx.scene.PointLight"); -//PointLightBuilder = Java.type("javafx.scene.PointLightBuilder"); -//Scene = Java.type("javafx.scene.Scene"); -SceneBuilder = Java.type("javafx.scene.SceneBuilder"); -Arc = Java.type("javafx.scene.shape.Arc"); -ArcBuilder = Java.type("javafx.scene.shape.ArcBuilder"); -ArcTo = Java.type("javafx.scene.shape.ArcTo"); -ArcToBuilder = Java.type("javafx.scene.shape.ArcToBuilder"); -ArcType = Java.type("javafx.scene.shape.ArcType"); -Box = Java.type("javafx.scene.shape.Box"); -//BoxBuilder = Java.type("javafx.scene.shape.BoxBuilder"); -Circle = Java.type("javafx.scene.shape.Circle"); -CircleBuilder = Java.type("javafx.scene.shape.CircleBuilder"); -ClosePath = Java.type("javafx.scene.shape.ClosePath"); -ClosePathBuilder = Java.type("javafx.scene.shape.ClosePathBuilder"); -CubicCurve = Java.type("javafx.scene.shape.CubicCurve"); -CubicCurveBuilder = Java.type("javafx.scene.shape.CubicCurveBuilder"); -CubicCurveTo = Java.type("javafx.scene.shape.CubicCurveTo"); -CubicCurveToBuilder = Java.type("javafx.scene.shape.CubicCurveToBuilder"); -CullFace = Java.type("javafx.scene.shape.CullFace"); -Cylinder = Java.type("javafx.scene.shape.Cylinder"); -//CylinderBuilder = Java.type("javafx.scene.shape.CylinderBuilder"); -DrawMode = Java.type("javafx.scene.shape.DrawMode"); -Ellipse = Java.type("javafx.scene.shape.Ellipse"); -EllipseBuilder = Java.type("javafx.scene.shape.EllipseBuilder"); -FillRule = Java.type("javafx.scene.shape.FillRule"); -HLineTo = Java.type("javafx.scene.shape.HLineTo"); -HLineToBuilder = Java.type("javafx.scene.shape.HLineToBuilder"); -Line = Java.type("javafx.scene.shape.Line"); -LineBuilder = Java.type("javafx.scene.shape.LineBuilder"); -LineTo = Java.type("javafx.scene.shape.LineTo"); -LineToBuilder = Java.type("javafx.scene.shape.LineToBuilder"); -Mesh = Java.type("javafx.scene.shape.Mesh"); -MeshView = Java.type("javafx.scene.shape.MeshView"); -//MeshViewBuilder = Java.type("javafx.scene.shape.MeshViewBuilder"); -MoveTo = Java.type("javafx.scene.shape.MoveTo"); -MoveToBuilder = Java.type("javafx.scene.shape.MoveToBuilder"); -Path = Java.type("javafx.scene.shape.Path"); -PathBuilder = Java.type("javafx.scene.shape.PathBuilder"); -PathElement = Java.type("javafx.scene.shape.PathElement"); -PathElementBuilder = Java.type("javafx.scene.shape.PathElementBuilder"); -Polygon = Java.type("javafx.scene.shape.Polygon"); -PolygonBuilder = Java.type("javafx.scene.shape.PolygonBuilder"); -Polyline = Java.type("javafx.scene.shape.Polyline"); -PolylineBuilder = Java.type("javafx.scene.shape.PolylineBuilder"); -QuadCurve = Java.type("javafx.scene.shape.QuadCurve"); -QuadCurveBuilder = Java.type("javafx.scene.shape.QuadCurveBuilder"); -QuadCurveTo = Java.type("javafx.scene.shape.QuadCurveTo"); -QuadCurveToBuilder = Java.type("javafx.scene.shape.QuadCurveToBuilder"); -Rectangle = Java.type("javafx.scene.shape.Rectangle"); -RectangleBuilder = Java.type("javafx.scene.shape.RectangleBuilder"); -Shape = Java.type("javafx.scene.shape.Shape"); -Shape3D = Java.type("javafx.scene.shape.Shape3D"); -//Shape3DBuilder = Java.type("javafx.scene.shape.Shape3DBuilder"); -ShapeBuilder = Java.type("javafx.scene.shape.ShapeBuilder"); -Sphere = Java.type("javafx.scene.shape.Sphere"); -//SphereBuilder = Java.type("javafx.scene.shape.SphereBuilder"); -StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap"); -StrokeLineJoin = Java.type("javafx.scene.shape.StrokeLineJoin"); -StrokeType = Java.type("javafx.scene.shape.StrokeType"); -SVGPath = Java.type("javafx.scene.shape.SVGPath"); -SVGPathBuilder = Java.type("javafx.scene.shape.SVGPathBuilder"); -TriangleMesh = Java.type("javafx.scene.shape.TriangleMesh"); -VLineTo = Java.type("javafx.scene.shape.VLineTo"); -VLineToBuilder = Java.type("javafx.scene.shape.VLineToBuilder"); -SnapshotParameters = Java.type("javafx.scene.SnapshotParameters"); -SnapshotParametersBuilder = Java.type("javafx.scene.SnapshotParametersBuilder"); -SnapshotResult = Java.type("javafx.scene.SnapshotResult"); -SubScene = Java.type("javafx.scene.SubScene"); -//SubSceneBuilder = Java.type("javafx.scene.SubSceneBuilder"); -Font = Java.type("javafx.scene.text.Font"); -FontBuilder = Java.type("javafx.scene.text.FontBuilder"); -FontPosture = Java.type("javafx.scene.text.FontPosture"); -FontSmoothingType = Java.type("javafx.scene.text.FontSmoothingType"); -FontWeight = Java.type("javafx.scene.text.FontWeight"); -Text = Java.type("javafx.scene.text.Text"); -TextAlignment = Java.type("javafx.scene.text.TextAlignment"); -TextBoundsType = Java.type("javafx.scene.text.TextBoundsType"); -TextBuilder = Java.type("javafx.scene.text.TextBuilder"); -TextFlow = Java.type("javafx.scene.text.TextFlow"); -//TextFlowBuilder = Java.type("javafx.scene.text.TextFlowBuilder"); -Affine = Java.type("javafx.scene.transform.Affine"); -AffineBuilder = Java.type("javafx.scene.transform.AffineBuilder"); -MatrixType = Java.type("javafx.scene.transform.MatrixType"); -NonInvertibleTransformException = Java.type("javafx.scene.transform.NonInvertibleTransformException"); -Rotate = Java.type("javafx.scene.transform.Rotate"); -RotateBuilder = Java.type("javafx.scene.transform.RotateBuilder"); -Scale = Java.type("javafx.scene.transform.Scale"); -ScaleBuilder = Java.type("javafx.scene.transform.ScaleBuilder"); -Shear = Java.type("javafx.scene.transform.Shear"); -ShearBuilder = Java.type("javafx.scene.transform.ShearBuilder"); -Transform = Java.type("javafx.scene.transform.Transform"); -//TransformBuilder = Java.type("javafx.scene.transform.TransformBuilder"); -TransformChangedEvent = Java.type("javafx.scene.transform.TransformChangedEvent"); -Translate = Java.type("javafx.scene.transform.Translate"); -TranslateBuilder = Java.type("javafx.scene.transform.TranslateBuilder"); -DirectoryChooser = Java.type("javafx.stage.DirectoryChooser"); -DirectoryChooserBuilder = Java.type("javafx.stage.DirectoryChooserBuilder"); -FileChooser = Java.type("javafx.stage.FileChooser"); -FileChooser$ExtensionFilter = Java.type("javafx.stage.FileChooser$ExtensionFilter"); -FileChooserBuilder = Java.type("javafx.stage.FileChooserBuilder"); -Modality = Java.type("javafx.stage.Modality"); -Popup = Java.type("javafx.stage.Popup"); -PopupBuilder = Java.type("javafx.stage.PopupBuilder"); -PopupWindow = Java.type("javafx.stage.PopupWindow"); -PopupWindowBuilder = Java.type("javafx.stage.PopupWindowBuilder"); -Screen = Java.type("javafx.stage.Screen"); -//Stage = Java.type("javafx.stage.Stage"); -StageBuilder = Java.type("javafx.stage.StageBuilder"); -StageStyle = Java.type("javafx.stage.StageStyle"); -Window = Java.type("javafx.stage.Window"); -WindowBuilder = Java.type("javafx.stage.WindowBuilder"); -WindowEvent = Java.type("javafx.stage.WindowEvent"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_GRAPHICS_CLASSES); + diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/media.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/media.js index 7cc7887b3a8..29640255ba8 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/media.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/media.js @@ -23,23 +23,8 @@ * questions. */ -AudioClip = Java.type("javafx.scene.media.AudioClip"); -AudioClipBuilder = Java.type("javafx.scene.media.AudioClipBuilder"); -AudioEqualizer = Java.type("javafx.scene.media.AudioEqualizer"); -AudioSpectrumListener = Java.type("javafx.scene.media.AudioSpectrumListener"); -AudioTrack = Java.type("javafx.scene.media.AudioTrack"); -EqualizerBand = Java.type("javafx.scene.media.EqualizerBand"); -Media = Java.type("javafx.scene.media.Media"); -MediaBuilder = Java.type("javafx.scene.media.MediaBuilder"); -MediaErrorEvent = Java.type("javafx.scene.media.MediaErrorEvent"); -MediaException = Java.type("javafx.scene.media.MediaException"); -MediaException$Type = Java.type("javafx.scene.media.MediaException$Type"); -MediaMarkerEvent = Java.type("javafx.scene.media.MediaMarkerEvent"); -MediaPlayer = Java.type("javafx.scene.media.MediaPlayer"); -MediaPlayer$Status = Java.type("javafx.scene.media.MediaPlayer$Status"); -MediaPlayerBuilder = Java.type("javafx.scene.media.MediaPlayerBuilder"); -MediaView = Java.type("javafx.scene.media.MediaView"); -MediaViewBuilder = Java.type("javafx.scene.media.MediaViewBuilder"); -SubtitleTrack = Java.type("javafx.scene.media.SubtitleTrack"); -Track = Java.type("javafx.scene.media.Track"); -VideoTrack = Java.type("javafx.scene.media.VideoTrack"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_MEDIA_CLASSES); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swing.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swing.js index 241205d1282..e4021af9d49 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swing.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swing.js @@ -23,7 +23,8 @@ * questions. */ -JFXPanel = Java.type("javafx.embed.swing.JFXPanel"); -JFXPanelBuilder = Java.type("javafx.embed.swing.JFXPanelBuilder"); -SwingFXUtils = Java.type("javafx.embed.swing.SwingFXUtils"); -SwingNode = Java.type("javafx.embed.swing.SwingNode"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_SWING_CLASSES); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swt.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swt.js index 82197c71198..144bcd5de71 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swt.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swt.js @@ -23,7 +23,8 @@ * questions. */ -CustomTransfer = Java.type("javafx.embed.swt.CustomTransfer"); -//CustomTransferBuilder = Java.type("javafx.embed.swt.CustomTransferBuilder"); -FXCanvas = Java.type("javafx.embed.swt.FXCanvas"); -SWTFXUtils = Java.type("javafx.embed.swt.SWTFXUtils"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_SWT_CLASSES); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/web.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/web.js index 606c3c315a9..fa66cb25788 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/web.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/web.js @@ -23,14 +23,8 @@ * questions. */ -HTMLEditor = Java.type("javafx.scene.web.HTMLEditor"); -//HTMLEditorBuilder = Java.type("javafx.scene.web.HTMLEditorBuilder"); -PopupFeatures = Java.type("javafx.scene.web.PopupFeatures"); -PromptData = Java.type("javafx.scene.web.PromptData"); -//PromptDataBuilder = Java.type("javafx.scene.web.PromptDataBuilder"); -WebEngine = Java.type("javafx.scene.web.WebEngine"); -WebEngineBuilder = Java.type("javafx.scene.web.WebEngineBuilder"); -WebEvent = Java.type("javafx.scene.web.WebEvent"); -WebHistory = Java.type("javafx.scene.web.WebHistory"); -WebView = Java.type("javafx.scene.web.WebView"); -WebViewBuilder = Java.type("javafx.scene.web.WebViewBuilder"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_WEB_CLASSES); From cda1bfff5ae59c540fe2854bd8d6c7f3defe02d5 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Mon, 9 Sep 2013 21:03:07 +0400 Subject: [PATCH 0271/1294] 8023042: Inaccuracy in documentation in a sound area Reviewed-by: prr --- jdk/src/share/classes/javax/sound/sampled/AudioFileFormat.java | 2 +- jdk/src/share/classes/javax/sound/sampled/AudioFormat.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/javax/sound/sampled/AudioFileFormat.java b/jdk/src/share/classes/javax/sound/sampled/AudioFileFormat.java index d1216e207a7..659399e616f 100644 --- a/jdk/src/share/classes/javax/sound/sampled/AudioFileFormat.java +++ b/jdk/src/share/classes/javax/sound/sampled/AudioFileFormat.java @@ -57,7 +57,7 @@ import java.util.Map; * be used in implementations: * *

    Error Summary " + + "
    ErrorDescription
    " + + "ClassError
    - * + * * * * diff --git a/jdk/src/share/classes/javax/sound/sampled/AudioFormat.java b/jdk/src/share/classes/javax/sound/sampled/AudioFormat.java index 2e679784ea3..4a267cf6b6d 100644 --- a/jdk/src/share/classes/javax/sound/sampled/AudioFormat.java +++ b/jdk/src/share/classes/javax/sound/sampled/AudioFormat.java @@ -85,7 +85,7 @@ import java.util.Map; * service providers should use, if applicable: * *
    Audio File Format Property KeysAudio File Format Properties
    Property keyValue type
    - * + * * * * From 76033b1a3738d01a7778b2e595df222a1370b34a Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Mon, 9 Sep 2013 14:44:37 -0400 Subject: [PATCH 0272/1294] 8023167: JVM allows duplicate Runtime[In]VisibleTypeAnnotations attributes in ClassFile/field_info/method_info structures Add checks for duplicates and issue errors when detected. Reviewed-by: coleenp, zgu --- .../share/vm/classfile/classFileParser.cpp | 71 +++++++++++++++---- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 0705c5f14d6..7b79a1ab274 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -888,6 +888,7 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count, int runtime_visible_type_annotations_length = 0; u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_type_annotations_exists = false; while (attributes_count--) { cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length u2 attribute_name_index = cfs->get_u2_fast(); @@ -946,15 +947,27 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count, assert(runtime_invisible_annotations != NULL, "null invisible annotations"); cfs->skip_u1(runtime_invisible_annotations_length, CHECK); } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { + if (runtime_visible_type_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleTypeAnnotations attributes for field in class file %s", CHECK); + } runtime_visible_type_annotations_length = attribute_length; runtime_visible_type_annotations = cfs->get_u1_buffer(); assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); - } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { - runtime_invisible_type_annotations_length = attribute_length; - runtime_invisible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); + } else if (attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { + if (runtime_invisible_type_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleTypeAnnotations attributes for field in class file %s", CHECK); + } else { + runtime_invisible_type_annotations_exists = true; + } + if (PreserveAllAnnotations) { + runtime_invisible_type_annotations_length = attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + } + cfs->skip_u1(attribute_length, CHECK); } else { cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes } @@ -2060,6 +2073,7 @@ methodHandle ClassFileParser::parse_method(bool is_interface, int runtime_visible_type_annotations_length = 0; u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_type_annotations_exists = false; u1* annotation_default = NULL; int annotation_default_length = 0; @@ -2316,16 +2330,30 @@ methodHandle ClassFileParser::parse_method(bool is_interface, assert(annotation_default != NULL, "null annotation default"); cfs->skip_u1(annotation_default_length, CHECK_(nullHandle)); } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { + if (runtime_visible_type_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleTypeAnnotations attributes for method in class file %s", + CHECK_(nullHandle)); + } runtime_visible_type_annotations_length = method_attribute_length; runtime_visible_type_annotations = cfs->get_u1_buffer(); assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); // No need for the VM to parse Type annotations cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle)); - } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { - runtime_invisible_type_annotations_length = method_attribute_length; - runtime_invisible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { + if (runtime_invisible_type_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleTypeAnnotations attributes for method in class file %s", + CHECK_(nullHandle)); + } else { + runtime_invisible_type_annotations_exists = true; + } + if (PreserveAllAnnotations) { + runtime_invisible_type_annotations_length = method_attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + } + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); } else { // Skip unknown attributes cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); @@ -2818,6 +2846,7 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio int runtime_visible_type_annotations_length = 0; u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_type_annotations_exists = false; u1* inner_classes_attribute_start = NULL; u4 inner_classes_attribute_length = 0; u2 enclosing_method_class_index = 0; @@ -2921,16 +2950,28 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio parsed_bootstrap_methods_attribute = true; parse_classfile_bootstrap_methods_attribute(attribute_length, CHECK); } else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) { + if (runtime_visible_type_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleTypeAnnotations attributes in class file %s", CHECK); + } runtime_visible_type_annotations_length = attribute_length; runtime_visible_type_annotations = cfs->get_u1_buffer(); assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); // No need for the VM to parse Type annotations cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); - } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_type_annotations()) { - runtime_invisible_type_annotations_length = attribute_length; - runtime_invisible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); + } else if (tag == vmSymbols::tag_runtime_invisible_type_annotations()) { + if (runtime_invisible_type_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleTypeAnnotations attributes in class file %s", CHECK); + } else { + runtime_invisible_type_annotations_exists = true; + } + if (PreserveAllAnnotations) { + runtime_invisible_type_annotations_length = attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + } + cfs->skip_u1(attribute_length, CHECK); } else { // Unknown attribute cfs->skip_u1(attribute_length, CHECK); From 5b76a0d2165048cdfbebdc44a6c2d182bf5637c3 Mon Sep 17 00:00:00 2001 From: Eric McCorkle Date: Mon, 9 Sep 2013 16:26:55 -0400 Subject: [PATCH 0273/1294] 8022322: Reject default and static methods in annotation Causes javac to reject static and default method declarations inside an annotation Reviewed-by: jjg --- .../share/classes/com/sun/tools/javac/code/Flags.java | 3 ++- .../share/classes/com/sun/tools/javac/comp/Check.java | 9 ++++++--- .../test/tools/javac/annotations/neg/NoDefault.java | 9 +++++++++ .../test/tools/javac/annotations/neg/NoDefault.out | 3 +++ .../tools/javac/annotations/neg/NoDefaultAbstract.java | 9 +++++++++ .../tools/javac/annotations/neg/NoDefaultAbstract.out | 2 ++ .../test/tools/javac/annotations/neg/NoStatic.java | 10 ++++++++++ .../test/tools/javac/annotations/neg/NoStatic.out | 3 +++ .../tools/javac/annotations/neg/NoStaticAbstract.java | 10 ++++++++++ .../tools/javac/annotations/neg/NoStaticAbstract.out | 2 ++ 10 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 langtools/test/tools/javac/annotations/neg/NoDefault.java create mode 100644 langtools/test/tools/javac/annotations/neg/NoDefault.out create mode 100644 langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.java create mode 100644 langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.out create mode 100644 langtools/test/tools/javac/annotations/neg/NoStatic.java create mode 100644 langtools/test/tools/javac/annotations/neg/NoStatic.out create mode 100644 langtools/test/tools/javac/annotations/neg/NoStaticAbstract.java create mode 100644 langtools/test/tools/javac/annotations/neg/NoStaticAbstract.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java index b2da2807363..3a4084ed2a8 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java @@ -97,7 +97,6 @@ public class Flags { public static final int MANDATED = 1<<15; public static final int StandardFlags = 0x0fff; - public static final int ModifierFlags = StandardFlags & ~INTERFACE; // Because the following access flags are overloaded with other // bit positions, we translate them when reading and writing class @@ -287,7 +286,9 @@ public class Flags { SYNCHRONIZED | FINAL | STRICTFP; public static final long ExtendedStandardFlags = (long)StandardFlags | DEFAULT, + ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT, InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT, + AnnotationTypeElementMask = FINAL | ABSTRACT | PUBLIC | STRICTFP, LocalVarFlags = FINAL | PARAMETER; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 5529627ed90..59d6c7b4468 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -1050,6 +1050,7 @@ public class Check { long checkFlags(DiagnosticPosition pos, long flags, Symbol sym, JCTree tree) { long mask; long implicit = 0; + switch (sym.kind) { case VAR: if (sym.owner.kind != TYP) @@ -1070,7 +1071,10 @@ public class Check { } else mask = ConstructorFlags; } else if ((sym.owner.flags_field & INTERFACE) != 0) { - if ((flags & (DEFAULT | STATIC)) != 0) { + if ((sym.owner.flags_field & ANNOTATION) != 0) { + mask = AnnotationTypeElementMask; + implicit = PUBLIC | ABSTRACT; + } else if ((flags & (DEFAULT | STATIC)) != 0) { mask = InterfaceMethodMask; implicit = PUBLIC; if ((flags & DEFAULT) != 0) { @@ -1079,8 +1083,7 @@ public class Check { } else { mask = implicit = InterfaceMethodFlags; } - } - else { + } else { mask = MethodFlags; } // Imply STRICTFP if owner has STRICTFP set. diff --git a/langtools/test/tools/javac/annotations/neg/NoDefault.java b/langtools/test/tools/javac/annotations/neg/NoDefault.java new file mode 100644 index 00000000000..282bc98bf3a --- /dev/null +++ b/langtools/test/tools/javac/annotations/neg/NoDefault.java @@ -0,0 +1,9 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8022322 + * @summary Default methods are not allowed in an annotation. + * @compile/fail/ref=NoDefault.out -XDrawDiagnostics NoDefault.java + */ +@interface NoDefault { + default int m() {return 0;} +} diff --git a/langtools/test/tools/javac/annotations/neg/NoDefault.out b/langtools/test/tools/javac/annotations/neg/NoDefault.out new file mode 100644 index 00000000000..ffcbf823351 --- /dev/null +++ b/langtools/test/tools/javac/annotations/neg/NoDefault.out @@ -0,0 +1,3 @@ +NoDefault.java:8:17: compiler.err.mod.not.allowed.here: default +NoDefault.java:8:21: compiler.err.intf.meth.cant.have.body +2 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.java b/langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.java new file mode 100644 index 00000000000..6c288810fe1 --- /dev/null +++ b/langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.java @@ -0,0 +1,9 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8022322 + * @summary Default methods are not allowed in an annotation. + * @compile/fail/ref=NoDefaultAbstract.out -XDrawDiagnostics NoDefaultAbstract.java + */ +@interface NoDefaultAbstract { + default int m(); +} diff --git a/langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.out b/langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.out new file mode 100644 index 00000000000..ea445c68e13 --- /dev/null +++ b/langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.out @@ -0,0 +1,2 @@ +NoDefaultAbstract.java:8:17: compiler.err.mod.not.allowed.here: default +1 error diff --git a/langtools/test/tools/javac/annotations/neg/NoStatic.java b/langtools/test/tools/javac/annotations/neg/NoStatic.java new file mode 100644 index 00000000000..3a62dc7c748 --- /dev/null +++ b/langtools/test/tools/javac/annotations/neg/NoStatic.java @@ -0,0 +1,10 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8022322 + * @summary Static methods are not allowed in an annotation. + * @compile/fail/ref=NoStatic.out -XDrawDiagnostics NoStatic.java + */ + +@interface NoStatic { + static int m() {return 0;} +} diff --git a/langtools/test/tools/javac/annotations/neg/NoStatic.out b/langtools/test/tools/javac/annotations/neg/NoStatic.out new file mode 100644 index 00000000000..8d9d3131915 --- /dev/null +++ b/langtools/test/tools/javac/annotations/neg/NoStatic.out @@ -0,0 +1,3 @@ +NoStatic.java:9:16: compiler.err.mod.not.allowed.here: static +NoStatic.java:9:20: compiler.err.intf.meth.cant.have.body +2 errors diff --git a/langtools/test/tools/javac/annotations/neg/NoStaticAbstract.java b/langtools/test/tools/javac/annotations/neg/NoStaticAbstract.java new file mode 100644 index 00000000000..af27fa75b9a --- /dev/null +++ b/langtools/test/tools/javac/annotations/neg/NoStaticAbstract.java @@ -0,0 +1,10 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8022322 + * @summary Static methods are not allowed in an annotation. + * @compile/fail/ref=NoStaticAbstract.out -XDrawDiagnostics NoStaticAbstract.java + */ + +@interface NoStaticAbstract { + static int m(); +} diff --git a/langtools/test/tools/javac/annotations/neg/NoStaticAbstract.out b/langtools/test/tools/javac/annotations/neg/NoStaticAbstract.out new file mode 100644 index 00000000000..694cea1771f --- /dev/null +++ b/langtools/test/tools/javac/annotations/neg/NoStaticAbstract.out @@ -0,0 +1,2 @@ +NoStaticAbstract.java:9:16: compiler.err.mod.not.allowed.here: static +1 error From b03e5fc290b9d39ced09836a2c63948f2a81c372 Mon Sep 17 00:00:00 2001 From: Brian Goetz Date: Mon, 9 Sep 2013 17:11:55 -0400 Subject: [PATCH 0274/1294] 8015322: Javac template test framework Putback of the javac template test framework from the Lambda repository Reviewed-by: jjg --- langtools/README | 2 +- langtools/test/lib/combo/TEST.properties | 4 + .../combo/tools/javac/combo/Diagnostics.java | 82 ++ .../javac/combo/JavacTemplateTestBase.java | 362 ++++++ .../lib/combo/tools/javac/combo/Template.java | 112 ++ .../combo/tools/javac/combo/TemplateTest.java | 94 ++ .../template_tests/BridgeMethodTestCase.java | 421 +++++++ .../BridgeMethodsTemplateTest.java | 1082 +++++++++++++++++ .../bridge/template_tests/TEST.properties | 7 + 9 files changed, 2165 insertions(+), 1 deletion(-) create mode 100644 langtools/test/lib/combo/TEST.properties create mode 100644 langtools/test/lib/combo/tools/javac/combo/Diagnostics.java create mode 100644 langtools/test/lib/combo/tools/javac/combo/JavacTemplateTestBase.java create mode 100644 langtools/test/lib/combo/tools/javac/combo/Template.java create mode 100644 langtools/test/lib/combo/tools/javac/combo/TemplateTest.java create mode 100644 langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodTestCase.java create mode 100644 langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodsTemplateTest.java create mode 100644 langtools/test/tools/javac/lambda/bridge/template_tests/TEST.properties diff --git a/langtools/README b/langtools/README index bc8873178ef..94beb071e92 100644 --- a/langtools/README +++ b/langtools/README @@ -32,7 +32,7 @@ tests that the compiler performs according to the specifications in JLS and JVMS. In addition, there is a substantial collection of regression and unit -tests for all the tools in the maain langtools test/ directory. +tests for all the tools in the main langtools test/ directory. Finally, there is a small set of tests to do basic validation of a build of the langtools workspace for use by JDK. These tests check the contents diff --git a/langtools/test/lib/combo/TEST.properties b/langtools/test/lib/combo/TEST.properties new file mode 100644 index 00000000000..341ff2af467 --- /dev/null +++ b/langtools/test/lib/combo/TEST.properties @@ -0,0 +1,4 @@ +# This file identifies root(s) of the test-ng hierarchy. + + +TestNG.dirs = . diff --git a/langtools/test/lib/combo/tools/javac/combo/Diagnostics.java b/langtools/test/lib/combo/tools/javac/combo/Diagnostics.java new file mode 100644 index 00000000000..6f1774d6572 --- /dev/null +++ b/langtools/test/lib/combo/tools/javac/combo/Diagnostics.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, 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. + */ +package tools.javac.combo; + +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.util.ArrayList; +import java.util.List; + +import static java.util.stream.Collectors.toList; + +/** +* A container for compiler diagnostics, separated into errors and warnings, + * used by JavacTemplateTestBase. + * + * @author Brian Goetz +*/ +public class Diagnostics implements javax.tools.DiagnosticListener { + + protected List> diags = new ArrayList<>(); + protected boolean foundErrors = false; + + public void report(Diagnostic diagnostic) { + diags.add(diagnostic); + foundErrors = foundErrors || diagnostic.getKind() == Diagnostic.Kind.ERROR; + } + + /** Were there any errors found? */ + public boolean errorsFound() { + return foundErrors; + } + + /** Get all diagnostic keys */ + public List keys() { + return diags.stream() + .map(Diagnostic::getCode) + .collect(toList()); + } + + /** Do the diagnostics contain the specified error key? */ + public boolean containsErrorKey(String key) { + return diags.stream() + .filter(d -> d.getKind() == Diagnostic.Kind.ERROR) + .anyMatch(d -> d.getCode().equals(key)); + } + + /** Get the error keys */ + public List errorKeys() { + return diags.stream() + .filter(d -> d.getKind() == Diagnostic.Kind.ERROR) + .map(Diagnostic::getCode) + .collect(toList()); + } + + public String toString() { return keys().toString(); } + + /** Clear all diagnostic state */ + public void reset() { + diags.clear(); + foundErrors = false; + } +} diff --git a/langtools/test/lib/combo/tools/javac/combo/JavacTemplateTestBase.java b/langtools/test/lib/combo/tools/javac/combo/JavacTemplateTestBase.java new file mode 100644 index 00000000000..e2a8bd7cac3 --- /dev/null +++ b/langtools/test/lib/combo/tools/javac/combo/JavacTemplateTestBase.java @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2013, 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. + */ +package tools.javac.combo; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +import com.sun.source.util.JavacTask; +import com.sun.tools.javac.util.Pair; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static org.testng.Assert.fail; + +/** + * Base class for template-driven TestNG javac tests that support on-the-fly + * source file generation, compilation, classloading, execution, and separate + * compilation. + * + *

    Manages a set of templates (which have embedded tags of the form + * {@code #\{NAME\}}), source files (which are also templates), and compile + * options. Test cases can register templates and source files, cause them to + * be compiled, validate whether the set of diagnostic messages output by the + * compiler is correct, and optionally load and run the compiled classes. + * + * @author Brian Goetz + */ +@Test +public abstract class JavacTemplateTestBase { + private static final Set suiteErrors = Collections.synchronizedSet(new HashSet<>()); + private static final AtomicInteger counter = new AtomicInteger(); + private static final File root = new File("gen"); + private static final File nullDir = new File("empty"); + + protected final Map templates = new HashMap<>(); + protected final Diagnostics diags = new Diagnostics(); + protected final List> sourceFiles = new ArrayList<>(); + protected final List compileOptions = new ArrayList<>(); + protected final List classpaths = new ArrayList<>(); + protected final Template.Resolver defaultResolver = new MapResolver(templates); + + private Template.Resolver currentResolver = defaultResolver; + + /** Add a template with a specified name */ + protected void addTemplate(String name, Template t) { + templates.put(name, t); + } + + /** Add a template with a specified name */ + protected void addTemplate(String name, String s) { + templates.put(name, new StringTemplate(s)); + } + + /** Add a source file */ + protected void addSourceFile(String name, Template t) { + sourceFiles.add(new Pair<>(name, t)); + } + + /** Add a File to the class path to be used when loading classes; File values + * will generally be the result of a previous call to {@link #compile()}. + * This enables testing of separate compilation scenarios if the class path + * is set up properly. + */ + protected void addClassPath(File path) { + classpaths.add(path); + } + + /** + * Add a set of compilation command-line options + */ + protected void addCompileOptions(String... opts) { + Collections.addAll(compileOptions, opts); + } + + /** Reset the compile options to the default (empty) value */ + protected void resetCompileOptions() { compileOptions.clear(); } + + /** Remove all templates */ + protected void resetTemplates() { templates.clear(); } + + /** Remove accumulated diagnostics */ + protected void resetDiagnostics() { diags.reset(); } + + /** Remove all source files */ + protected void resetSourceFiles() { sourceFiles.clear(); } + + /** Remove registered class paths */ + protected void resetClassPaths() { classpaths.clear(); } + + // Before each test method, reset everything + @BeforeMethod + public void reset() { + resetCompileOptions(); + resetDiagnostics(); + resetSourceFiles(); + resetTemplates(); + resetClassPaths(); + } + + // After each test method, if the test failed, capture source files and diagnostics and put them in the log + @AfterMethod + public void copyErrors(ITestResult result) { + if (!result.isSuccess()) { + suiteErrors.addAll(diags.errorKeys()); + + List list = new ArrayList<>(); + Collections.addAll(list, result.getParameters()); + list.add("Test case: " + getTestCaseDescription()); + for (Pair e : sourceFiles) + list.add("Source file " + e.fst + ": " + e.snd); + if (diags.errorsFound()) + list.add("Compile diagnostics: " + diags.toString()); + result.setParameters(list.toArray(new Object[list.size()])); + } + } + + @AfterSuite + // After the suite is done, dump any errors to output + public void dumpErrors() { + if (!suiteErrors.isEmpty()) + System.err.println("Errors found in test suite: " + suiteErrors); + } + + /** + * Get a description of this test case; since test cases may be combinatorially + * generated, this should include all information needed to describe the test case + */ + protected String getTestCaseDescription() { + return this.toString(); + } + + /** Assert that all previous calls to compile() succeeded */ + protected void assertCompileSucceeded() { + if (diags.errorsFound()) + fail("Expected successful compilation"); + } + + /** + * If the provided boolean is true, assert all previous compiles succeeded, + * otherwise assert that a compile failed. + * */ + protected void assertCompileSucceededIff(boolean b) { + if (b) + assertCompileSucceeded(); + else + assertCompileFailed(); + } + + /** Assert that a previous call to compile() failed */ + protected void assertCompileFailed() { + if (!diags.errorsFound()) + fail("Expected failed compilation"); + } + + /** Assert that a previous call to compile() failed with a specific error key */ + protected void assertCompileFailed(String message) { + if (!diags.errorsFound()) + fail("Expected failed compilation: " + message); + } + + /** Assert that a previous call to compile() failed with all of the specified error keys */ + protected void assertCompileErrors(String... keys) { + if (!diags.errorsFound()) + fail("Expected failed compilation"); + for (String k : keys) + if (!diags.containsErrorKey(k)) + fail("Expected compilation error " + k); + } + + /** Convert an object, which may be a Template or a String, into a Template */ + protected Template asTemplate(Object o) { + if (o instanceof Template) + return (Template) o; + else if (o instanceof String) + return new StringTemplate((String) o); + else + return new StringTemplate(o.toString()); + } + + /** Compile all registered source files */ + protected void compile() throws IOException { + compile(false); + } + + /** Compile all registered source files, optionally generating class files + * and returning a File describing the directory to which they were written */ + protected File compile(boolean generate) throws IOException { + List files = new ArrayList<>(); + for (Pair e : sourceFiles) + files.add(new FileAdapter(e.fst, asTemplate(e.snd))); + return compile(classpaths, files, generate); + } + + /** Compile all registered source files, using the provided list of class paths + * for finding required classfiles, optionally generating class files + * and returning a File describing the directory to which they were written */ + protected File compile(List classpaths, boolean generate) throws IOException { + List files = new ArrayList<>(); + for (Pair e : sourceFiles) + files.add(new FileAdapter(e.fst, asTemplate(e.snd))); + return compile(classpaths, files, generate); + } + + private File compile(List classpaths, List files, boolean generate) throws IOException { + JavaCompiler systemJavaCompiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = systemJavaCompiler.getStandardFileManager(null, null, null); + if (classpaths.size() > 0) + fm.setLocation(StandardLocation.CLASS_PATH, classpaths); + JavacTask ct = (JavacTask) systemJavaCompiler.getTask(null, fm, diags, compileOptions, null, files); + if (generate) { + File destDir = new File(root, Integer.toString(counter.incrementAndGet())); + // @@@ Assert that this directory didn't exist, or start counter at max+1 + destDir.mkdirs(); + fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir)); + ct.generate(); + return destDir; + } + else { + ct.analyze(); + return nullDir; + } + } + + /** Load the given class using the provided list of class paths */ + protected Class loadClass(String className, File... destDirs) { + try { + List list = new ArrayList<>(); + for (File f : destDirs) + list.add(new URL("file:" + f.toString().replace("\\", "/") + "/")); + return Class.forName(className, true, new URLClassLoader(list.toArray(new URL[list.size()]))); + } catch (ClassNotFoundException | MalformedURLException e) { + throw new RuntimeException("Error loading class " + className, e); + } + } + + /** An implementation of Template which is backed by a String */ + protected class StringTemplate implements Template { + protected final String template; + + public StringTemplate(String template) { + this.template = template; + } + + public String expand(String selector) { + return Behavior.expandTemplate(template, currentResolver); + } + + public String toString() { + return expand(""); + } + + public StringTemplate with(final String key, final String value) { + return new StringTemplateWithResolver(template, new KeyResolver(key, value)); + } + + } + + /** An implementation of Template which is backed by a String and which + * encapsulates a Resolver for resolving embedded tags. */ + protected class StringTemplateWithResolver extends StringTemplate { + private final Resolver localResolver; + + public StringTemplateWithResolver(String template, Resolver localResolver) { + super(template); + this.localResolver = localResolver; + } + + @Override + public String expand(String selector) { + Resolver saved = currentResolver; + currentResolver = new ChainedResolver(currentResolver, localResolver); + try { + return super.expand(selector); + } + finally { + currentResolver = saved; + } + } + + @Override + public StringTemplate with(String key, String value) { + return new StringTemplateWithResolver(template, new ChainedResolver(localResolver, new KeyResolver(key, value))); + } + } + + /** A Resolver which uses a Map to resolve tags */ + private class KeyResolver implements Template.Resolver { + private final String key; + private final String value; + + public KeyResolver(String key, String value) { + this.key = key; + this.value = value; + } + + @Override + public Template lookup(String k) { + return key.equals(k) ? new StringTemplate(value) : null; + } + } + + private class FileAdapter extends SimpleJavaFileObject { + private final String filename; + private final Template template; + + public FileAdapter(String filename, Template template) { + super(URI.create("myfo:/" + filename), Kind.SOURCE); + this.template = template; + this.filename = filename; + } + + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return toString(); + } + + public String toString() { + return Template.Behavior.expandTemplate(template.expand(filename), defaultResolver); + } + } +} diff --git a/langtools/test/lib/combo/tools/javac/combo/Template.java b/langtools/test/lib/combo/tools/javac/combo/Template.java new file mode 100644 index 00000000000..8ad4d72edcb --- /dev/null +++ b/langtools/test/lib/combo/tools/javac/combo/Template.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013, 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. + */ +package tools.javac.combo; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A template into which tags of the form {@code #\{KEY\}} or + * {@code #\{KEY.SUBKEY\}} can be expanded. + */ +public interface Template { + String expand(String selector); + + interface Resolver { + public Template lookup(String key); + } + + public static class Behavior { + /* Looks for expandable keys. An expandable key can take the form: + * #{MAJOR} + * #{MAJOR.MINOR} + * where MAJOR can be IDENTIFIER or IDENTIFIER[NUMERIC_INDEX] + * and MINOR can be an identifier + */ + private static final Pattern pattern = Pattern.compile("#\\{([A-Z_][A-Z0-9_]*(?:\\[\\d+\\])?)(?:\\.([A-Z_][A-Z0-9_]*))?\\}"); + + public static String expandTemplate(String template, final Map vars) { + return expandTemplate(template, new MapResolver(vars)); + } + + public static String expandTemplate(String template, Resolver res) { + CharSequence in = template; + StringBuffer out = new StringBuffer(); + while (true) { + boolean more = false; + Matcher m = pattern.matcher(in); + while (m.find()) { + String major = m.group(1); + String minor = m.group(2); + Template key = res.lookup(major); + if (key == null) + throw new IllegalStateException("Unknown major key " + major); + + String replacement = key.expand(minor == null ? "" : minor); + more |= pattern.matcher(replacement).find(); + m.appendReplacement(out, replacement); + } + m.appendTail(out); + if (!more) + return out.toString(); + else { + in = out; + out = new StringBuffer(); + } + } + } + + } +} + +class MapResolver implements Template.Resolver { + private final Map vars; + + public MapResolver(Map vars) {this.vars = vars;} + + public Template lookup(String key) { + return vars.get(key); + } +} + +class ChainedResolver implements Template.Resolver { + private final Template.Resolver upstreamResolver, thisResolver; + + public ChainedResolver(Template.Resolver upstreamResolver, Template.Resolver thisResolver) { + this.upstreamResolver = upstreamResolver; + this.thisResolver = thisResolver; + } + + public Template.Resolver getUpstreamResolver() { + return upstreamResolver; + } + + @Override + public Template lookup(String key) { + Template result = thisResolver.lookup(key); + if (result == null) + result = upstreamResolver.lookup(key); + return result; + } +} diff --git a/langtools/test/lib/combo/tools/javac/combo/TemplateTest.java b/langtools/test/lib/combo/tools/javac/combo/TemplateTest.java new file mode 100644 index 00000000000..356456872dd --- /dev/null +++ b/langtools/test/lib/combo/tools/javac/combo/TemplateTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013, 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. + * + */ +package tools.javac.combo; + +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.testng.Assert.assertEquals; + +/** + * TemplateTest + */ +@Test +public class TemplateTest { + Map vars = new HashMap<>(); + + @BeforeTest + void before() { vars.clear(); } + + private void assertTemplate(String expected, String template) { + String result = Template.Behavior.expandTemplate(template, vars); + assertEquals(result, expected, "for " + template); + } + + private String dotIf(String s) { + return s == null || s.isEmpty() ? "" : "." + s; + } + + public void testTemplateExpansion() { + vars.put("A", s -> "a" + dotIf(s)); + vars.put("B", s -> "b" + dotIf(s)); + vars.put("C", s -> "#{A}#{B}"); + vars.put("D", s -> "#{A" + dotIf(s) + "}#{B" + dotIf(s) + "}"); + vars.put("_D", s -> "d"); + + assertTemplate("", ""); + assertTemplate("foo", "foo"); + assertTemplate("a", "#{A}"); + assertTemplate("a", "#{A.}"); + assertTemplate("a.FOO", "#{A.FOO}"); + assertTemplate("aa", "#{A}#{A}"); + assertTemplate("ab", "#{C}"); + assertTemplate("ab", "#{C.FOO}"); + assertTemplate("ab", "#{C.}"); + assertTemplate("a.FOOb.FOO", "#{D.FOO}"); + assertTemplate("ab", "#{D}"); + assertTemplate("d", "#{_D}"); + assertTemplate("#{A", "#{A"); + } + + public void testIndexedTemplate() { + vars.put("A[0]", s -> "a" ); + vars.put("A[1]", s -> "b" ); + vars.put("A[2]", s -> "c" ); + vars.put("X", s -> "0"); + assertTemplate("a", "#{A[0]}"); + assertTemplate("b", "#{A[1]}"); + assertTemplate("c", "#{A[2]}"); + } + + public void testAngleBrackets() { + vars.put("X", s -> "xyz"); + assertTemplate("List ls = xyz;", "List ls = #{X};"); + } + + @Test(expectedExceptions = IllegalStateException.class ) + public void testUnknownKey() { + assertTemplate("#{Q}", "#{Q}"); + } +} diff --git a/langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodTestCase.java b/langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodTestCase.java new file mode 100644 index 00000000000..964a59658b1 --- /dev/null +++ b/langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodTestCase.java @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringJoiner; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import tools.javac.combo.*; + +import static org.testng.Assert.fail; + +/** + * BridgeMethodTestCase -- used for asserting linkage to bridges under separate compilation. + * + * Example test case: + * public void test1() throws IOException, ReflectiveOperationException { + * compileSpec("C(Bc1(A))"); + * assertLinkage("C", LINKAGE_ERROR, "B1"); + * recompileSpec("C(Bc1(Ac0))", "A"); + * assertLinkage("C", "A0", "B1"); + * } + * + * This compiles A, B, and C, asserts that C.m()Object does not exist, asserts + * that C.m()Number eventually invokes B.m()Number, recompiles B, and then asserts + * that the result of calling C.m()Object now arrives at A. + * + * @author Brian Goetz + */ + +@Test +public abstract class BridgeMethodTestCase extends JavacTemplateTestBase { + + private static final String TYPE_LETTERS = "ABCDIJK"; + + private static final String BASE_INDEX_CLASS = "class C0 {\n" + + " int val;\n" + + " C0(int val) { this.val = val; }\n" + + " public int getVal() { return val; }\n" + + "}\n"; + private static final String INDEX_CLASS_TEMPLATE = "class C#ID extends C#PREV {\n" + + " C#ID(int val) { super(val); }\n" + + "}\n"; + + + + protected static String LINKAGE_ERROR = "-1"; + + private List compileDirs = new ArrayList<>(); + + /** + * Compile all the classes in a class spec, and put them on the classpath. + * + * The spec is the specification for a nest of classes, using the following notation + * A, B represent abstract classes + * C represents a concrete class + * I, J, K represent interfaces + * Lowercase 'c' following a class means that the method m() is concrete + * Lowercase 'a' following a class or interface means that the method m() is abstract + * Lowercase 'd' following an interface means that the method m() is default + * A number 0, 1, or 2 following the lowercase letter indicates the return type of that method + * 0 = Object, 1 = Number, 2 = Integer (these form an inheritance chain so bridges are generated) + * A classes supertypes follow its method spec, in parentheses + * Examples: + * C(Ia0, Jd0) -- C extends I and J, I has abstract m()Object, J has default m()Object + * Cc1(Ia0) -- C has concrete m()Number, extends I with abstract m()Object + * If a type must appear multiple times, its full spec must be in the first occurrence + * Example: + * C(I(Kd0), J(K)) + */ + protected void compileSpec(String spec) throws IOException { + compileSpec(spec, false); + } + + /** + * Compile all the classes in a class spec, and assert that there were compilation errors. + */ + protected void compileSpec(String spec, String... errorKeys) throws IOException { + compileSpec(spec, false, errorKeys); + } + + protected void compileSpec(String spec, boolean debug, String... errorKeys) throws IOException { + ClassModel cm = new Parser(spec).parseClassModel(); + for (int i = 0; i <= cm.maxIndex() ; i++) { + if (debug) System.out.println(indexClass(i)); + addSourceFile(String.format("C%d.java", i), new StringTemplate(indexClass(i))); + } + for (Map.Entry e : classes(cm).entrySet()) { + if (debug) System.out.println(e.getValue().toSource()); + addSourceFile(e.getKey() + ".java", new StringTemplate(e.getValue().toSource())); + } + compileDirs.add(compile(true)); + resetSourceFiles(); + if (errorKeys.length == 0) + assertCompileSucceeded(); + else + assertCompileErrors(errorKeys); + } + + /** + * Recompile only a subset of classes in the class spec, as named by names, + * and put them on the classpath such that they shadow earlier versions of that class. + */ + protected void recompileSpec(String spec, String... names) throws IOException { + List nameList = Arrays.asList(names); + ClassModel cm = new Parser(spec).parseClassModel(); + for (int i = 0; i <= cm.maxIndex() ; i++) { + addSourceFile(String.format("C%d.java", i), new StringTemplate(indexClass(i))); + } + for (Map.Entry e : classes(cm).entrySet()) + if (nameList.contains(e.getKey())) + addSourceFile(e.getKey() + ".java", new StringTemplate(e.getValue().toSource())); + compileDirs.add(compile(Arrays.asList(classPaths()), true)); + resetSourceFiles(); + assertCompileSucceeded(); + } + + protected void assertLinkage(String name, String... expected) throws ReflectiveOperationException { + for (int i=0; i classes(ClassModel cm) { + HashMap m = new HashMap<>(); + classesHelper(cm, m); + return m; + } + + private String indexClass(int index) { + if (index == 0) { + return BASE_INDEX_CLASS; + } else { + return INDEX_CLASS_TEMPLATE + .replace("#ID", String.valueOf(index)) + .replace("#PREV", String.valueOf(index - 1)); + } + } + + private static String overrideName(int index) { + return "C" + index; + } + + private void classesHelper(ClassModel cm, Map m) { + if (!m.containsKey(cm.name)) + m.put(cm.name, cm); + for (ClassModel s : cm.supertypes) + classesHelper(s, m); + } + + private static String fromNum(int num) { + return String.format("%c%d", TYPE_LETTERS.charAt(num / 10), num % 10); + } + + private static int toNum(String name, int index) { + return 10*(TYPE_LETTERS.indexOf(name.charAt(0))) + index; + } + + private static int toNum(String string) { + return 10*(TYPE_LETTERS.indexOf(string.charAt(0))) + Integer.parseInt(string.substring(1, 2)); + } + + private int invoke(String name, int index) throws ReflectiveOperationException { + File[] files = classPaths(); + Class clazz = loadClass(name, files); + Method[] ms = clazz.getMethods(); + for (Method m : ms) { + if (m.getName().equals("m") && m.getReturnType().getName().equals(overrideName(index))) { + m.setAccessible(true); + Object instance = clazz.newInstance(); + Object c0 = m.invoke(instance); + Method getVal = c0.getClass().getMethod("getVal"); + getVal.setAccessible(true); + return (int)getVal.invoke(c0); + } + } + throw new NoSuchMethodError("cannot find method m()" + index + " in class " + name); + } + + private File[] classPaths() { + File[] files = new File[compileDirs.size()]; + for (int i=0; i supertypes; + private final MethodType methodType; + private final int methodIndex; + + private ClassModel(String name, + boolean anInterface, + List supertypes, + MethodType methodType, + int methodIndex) { + this.name = name; + isInterface = anInterface; + this.supertypes = supertypes; + this.methodType = methodType; + this.methodIndex = methodIndex; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(name); + if (methodType != null) { + sb.append(methodType.designator); + sb.append(methodIndex); + } + if (!supertypes.isEmpty()) { + sb.append("("); + for (int i=0; i 0) + sb.append(","); + sb.append(supertypes.get(i).toString()); + } + sb.append(")"); + } + return sb.toString(); + } + + int maxIndex() { + int maxSoFar = methodIndex; + for (ClassModel cm : supertypes) { + maxSoFar = Math.max(cm.maxIndex(), maxSoFar); + } + return maxSoFar; + } + + public String toSource() { + String extendsClause = ""; + String implementsClause = ""; + String methodBody = ""; + boolean isAbstract = "AB".contains(name); + + for (ClassModel s : supertypes) { + if (!s.isInterface) { + extendsClause = String.format("extends %s", s.name); + break; + } + } + + StringJoiner sj = new StringJoiner(", "); + for (ClassModel s : supertypes) + if (s.isInterface) + sj.add(s.name); + if (sj.length() > 0) { + if (isInterface) + implementsClause = "extends " + sj.toString(); + else + implementsClause = "implements " + sj.toString(); + } + if (methodType != null) { + switch (methodType) { + case ABSTRACT: + methodBody = String.format("public abstract %s m();", overrideName(methodIndex)); + break; + case CONCRETE: + methodBody = String.format("public %s m() { return new %s(%d); };", + overrideName(methodIndex), overrideName(methodIndex), toNum(name, methodIndex)); + break; + case DEFAULT: + methodBody = String.format("public default %s m() { return new %s(%d); };", + overrideName(methodIndex), overrideName(methodIndex), toNum(name, methodIndex)); + break; + + } + } + + return String.format("public %s %s %s %s %s { %s }", isAbstract ? "abstract" : "", + isInterface ? "interface" : "class", + name, extendsClause, implementsClause, methodBody); + } + } + + private static class Parser { + private final String input; + private final char[] chars; + private int index; + + private Parser(String s) { + input = s; + chars = s.toCharArray(); + } + + private char peek() { + return index < chars.length ? chars[index] : 0; + } + + private boolean peek(String validChars) { + return validChars.indexOf(peek()) >= 0; + } + + private char advanceIf(String validChars) { + if (peek(validChars)) + return chars[index++]; + else + return 0; + } + + private char advanceIfDigit() { + return advanceIf("0123456789"); + } + + private int index() { + StringBuilder buf = new StringBuilder(); + char c = advanceIfDigit(); + while (c != 0) { + buf.append(c); + c = advanceIfDigit(); + } + return Integer.valueOf(buf.toString()); + } + + private char advance() { + return chars[index++]; + } + + private char expect(String validChars) { + char c = advanceIf(validChars); + if (c == 0) + throw new IllegalArgumentException(String.format("Expecting %s at position %d of %s", validChars, index, input)); + return c; + } + + public ClassModel parseClassModel() { + List supers = new ArrayList<>(); + char name = expect(TYPE_LETTERS); + boolean isInterface = "IJK".indexOf(name) >= 0; + ClassModel.MethodType methodType = peek(isInterface ? "ad" : "ac") ? ClassModel.MethodType.find(advance()) : null; + int methodIndex = 0; + if (methodType != null) { + methodIndex = index(); + } + if (peek() == '(') { + advance(); + supers.add(parseClassModel()); + while (peek() == ',') { + advance(); + supers.add(parseClassModel()); + } + expect(")"); + } + return new ClassModel(new String(new char[]{ name }), isInterface, supers, methodType, methodIndex); + } + } +} diff --git a/langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodsTemplateTest.java b/langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodsTemplateTest.java new file mode 100644 index 00000000000..028602ea057 --- /dev/null +++ b/langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodsTemplateTest.java @@ -0,0 +1,1082 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +import java.io.IOException; + +import org.testng.annotations.Test; + +/** + * BridgeMethodsTemplateTest + * + * @author Brian Goetz + */ +@Test +public class BridgeMethodsTemplateTest extends BridgeMethodTestCase { + + /* + * Cc1(A) -> Cc1(Ac0) + * + * 0*: Inherited from A + * 1: Declared in C + */ + public void test1() throws IOException, ReflectiveOperationException { + compileSpec("Cc1(A)"); + assertLinkage("C", LINKAGE_ERROR, "C1"); + recompileSpec("Cc1(Ac0)", "A"); + assertLinkage("C", "A0", "C1"); + } + + /* + * Cc1(I) -> Cc1(Id0) + * + * 0*: Inherited default from I + * 1: Declared in C + */ + public void test2() throws IOException, ReflectiveOperationException { + compileSpec("Cc1(I)"); + assertLinkage("C", LINKAGE_ERROR, "C1"); + recompileSpec("Cc1(Id0)", "I"); + assertLinkage("C", "I0", "C1"); + } + + /* + * C(Bc1(A)) -> C(Bc1(Ac0)) + * + * 0*: Inherited from A + * 1: Inherited from B + */ + public void test3() throws IOException, ReflectiveOperationException { + compileSpec("C(Bc1(A))"); + assertLinkage("C", LINKAGE_ERROR, "B1"); + recompileSpec("C(Bc1(Ac0))", "A"); + assertLinkage("C", "A0", "B1"); + } + + /* + * C(B(Ac0)) -> C(Bc1(Ac0)) + * + * 0: Inherited from B (through bridge) + * 1: Inherited from B + */ + public void test4() throws IOException, ReflectiveOperationException { + compileSpec("C(B(Ac0))"); + assertLinkage("C", "A0", LINKAGE_ERROR); + recompileSpec("C(Bc1(Ac0))", "B"); + assertLinkage("C", "B1", "B1"); + } + + /* + * C(B(A)) -> C(Bc1(Ac0)) + * + * 0: Inherited from B (through bridge) + * 1: Inherited from B + */ + public void test5() throws IOException, ReflectiveOperationException { + compileSpec("C(B(A))"); + assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR); + recompileSpec("C(Bc1(Ac0))", "A", "B"); + assertLinkage("C", "B1", "B1"); + } + + /* + * C(Ac1(I)) -> C(Ac1(Id0)) + * + * 0*: Inherited default from I + * 1: Inherited from A + */ + public void test6() throws IOException, ReflectiveOperationException { + compileSpec("C(Ac1(I))"); + assertLinkage("C", LINKAGE_ERROR, "A1"); + recompileSpec("C(Ac1(Id0))", "I"); + assertLinkage("C", "I0", "A1"); + } + + /* + * C(A(Id0)) -> C(Ac1(Id0)) + * + * 0: Inherited from A (through bridge) + * 1: Inherited from A + */ + public void test7() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Id0))"); + assertLinkage("C", "I0", LINKAGE_ERROR); + recompileSpec("C(Ac1(Id0))", "A"); + assertLinkage("C", "A1", "A1"); + } + + /* + * C(A(I)) -> C(Ac1(Id0)) + * + * 0*: Inherited from A (through bridge) + * 1*: Inherited from A + */ + public void test8() throws IOException, ReflectiveOperationException { + compileSpec("C(A(I))"); + assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR); + recompileSpec("C(Ac1(Id0))", "A", "I"); + assertLinkage("C", "A1", "A1"); + } + + /* + * C(Id1(J)) -> C(Id1(Jd0)) + * + * 0*: Inherited default from J + * 1: Inherited default from I + */ + public void test9() throws IOException, ReflectiveOperationException { + compileSpec("C(Id1(J))"); + assertLinkage("C", LINKAGE_ERROR, "I1"); + recompileSpec("C(Id1(Jd0))", "J"); + assertLinkage("C", "J0", "I1"); + } + + /* + * C(I(Jd0)) -> C(Id1(Jd0)) + * + * 0: Inherited default from I (through bridge) + * 1: Inherited default from I + */ + public void test10() throws IOException, ReflectiveOperationException { + compileSpec("C(I(Jd0))"); + assertLinkage("C", "J0", LINKAGE_ERROR); + recompileSpec("C(Id1(Jd0))", "I"); + assertLinkage("C", "I1", "I1"); + } + + /* + * C(I(J)) -> C(Id1(Jd0)) + * + * 0: Inherited default from I (through bridge) + * 1: Inherited default from I + */ + public void test11() throws IOException, ReflectiveOperationException { + compileSpec("C(I(J))"); + assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR); + recompileSpec("C(Id1(Jd0))", "I", "J"); + assertLinkage("C", "I1", "I1"); + } + + /* + * Cc2(B(Ac0)) -> Cc2(Bc1(Ac0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited from B + * 2: Declared in C + */ + public void test12() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(B(Ac0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Bc1(Ac0))", "B"); + assertLinkage("C", "C2", "B1", "C2"); + } + + /* + * Cc2(B(Aa0)) -> Cc2(Bc1(Aa0)) + * + * 0: Bridge in C (through bridge) + * 1*: Inherited from B + * 2: Declared in C + */ + public void test13() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(B(Aa0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Bc1(Aa0))", "B"); + assertLinkage("C", "C2", "B1", "C2"); + } + + /* + * Cc2(Bc1(A)) -> Cc2(Bc1(Ac0)) + * + * 0*: Inherited from A + * 1: Declared in C (through bridge) + * 2: Declared in C + */ + public void test14() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(Bc1(A))"); + assertLinkage("C", LINKAGE_ERROR, "C2", "C2"); + recompileSpec("Cc2(Bc1(Ac0))", "A"); + assertLinkage("C", "A0", "C2", "C2"); + } + + /* + * Cc2(Ba1(A)) -> Cc2(Ba1(Ac0)) + * + * 0*: Inherited from A + * 1: Declared in C (through bridge) + * 2: Declared in C + */ + public void test15() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(Ba1(A))"); + assertLinkage("C", LINKAGE_ERROR, "C2", "C2"); + recompileSpec("Cc2(Ba1(Ac0))", "A"); + assertLinkage("C", "A0", "C2", "C2"); + } + + /* + * Cc2(B(A)) -> Cc2(Bc1(Ac0)) + * + * 0*: Inherited from B (through bridge) + * 1*: Inherited from B + * 2: Declared in C + */ + public void test16() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(B(A))"); + assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Bc1(Ac0))", "B", "A"); + assertLinkage("C", "B1", "B1", "C2"); + } + + /* + * Cc2(A(Id0)) -> Cc2(Ac1(Id0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited from A + * 2: Declared in C + */ + public void test17() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(A(Id0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Ac1(Id0))", "A"); + assertLinkage("C", "C2", "A1", "C2"); + } + + /* + * Cc2(A(Ia0)) -> Cc2(Ac1(Ia0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited from A + * 2: Declared in C + */ + public void test18() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(A(Ia0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Ac1(Ia0))", "A"); + assertLinkage("C", "C2", "A1", "C2"); + } + + /* + * Cc2(Ac1(I)) -> Cc2(Ac1(Id0)) + * + * 0*: Inherited from I + * 1: Declared in C (through bridge) + * 2: Declared in C + */ + public void test19() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(Ac1(I))"); + assertLinkage("C", LINKAGE_ERROR, "C2", "C2"); + recompileSpec("Cc2(Ac1(Id0))", "I"); + assertLinkage("C", "I0", "C2", "C2"); + } + + /* + * Cc2(Aa1(I)) -> Cc2(Aa1(Id0)) + * + * 0*: Inherited from I + * 1: Declared in C (through bridge) + * 2: Declared in C + */ + public void test20() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(Aa1(I))"); + assertLinkage("C", LINKAGE_ERROR, "C2", "C2"); + recompileSpec("Cc2(Aa1(Id0))", "I"); + assertLinkage("C", "I0", "C2", "C2"); + } + + /* + * Cc2(A(I)) -> Cc2(Ac1(Id0)) + * + * 0*: Inherited from A (through bridge) + * 1*: Inherited from A + * 2: Declared in C + */ + public void test21() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(A(I))"); + assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Ac1(Id0))", "A", "I"); + assertLinkage("C", "A1", "A1", "C2"); + } + + /* + * Cc2(J(Id0)) -> Cc2(Jd1(Id0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited default from J + * 2: Declared in C + */ + public void test22() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(J(Id0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Jd1(Id0))", "J"); + assertLinkage("C", "C2", "J1", "C2"); + } + + /* + * Cc2(J(Ia0)) -> Cc2(Jd1(Ia0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited default from J + * 2: Declared in C + */ + public void test23() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(J(Ia0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Jd1(Ia0))", "J"); + assertLinkage("C", "C2", "J1", "C2"); + } + + /* + * Cc2(Jd1(I)) -> Cc2(Jd1(Id0)) + * + * 0*: Inherited default from I + * 1: Declared in C (through bridge) + * 2: Declared in C + */ + public void test24() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(Jd1(I))"); + assertLinkage("C", LINKAGE_ERROR, "C2", "C2"); + recompileSpec("Cc2(Jd1(Id0))", "I"); + assertLinkage("C", "I0", "C2", "C2"); + } + + /* + * Cc2(Ja1(I)) -> Cc2(Ja1(Id0)) + * + * 0*: Inherited default from I + * 1: Declared in C (through bridge) + * 2: Declared in C + */ + public void test25() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(Ja1(I))"); + assertLinkage("C", LINKAGE_ERROR, "C2", "C2"); + recompileSpec("Cc2(Ja1(Id0))", "I"); + assertLinkage("C", "I0", "C2", "C2"); + } + + /* + * Cc2(J(I)) -> Cc2(Jd1(Id0)) + * + * 0*: Inherited default from J (through bridge) + * 1*: Inherited default from J + * 2: Declared in C + */ + public void test26() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(J(I))"); + assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Jd1(Id0))", "J", "I"); + assertLinkage("C", "J1", "J1", "C2"); + } + + /* + * C(Ac1, I) -> C(Ac1, Id0) + * + * 0*: Inherited default from I + * 1: Inherited from A + */ + public void test27() throws IOException, ReflectiveOperationException { + compileSpec("C(Ac1,I)"); + assertLinkage("C", LINKAGE_ERROR, "A1"); + recompileSpec("C(Ac1,Id0)", "I"); + assertLinkage("C", "I0", "A1"); + } + + /* + * C(A, Id0) -> C(Ac1, Id0) + * + * 0*: Inherited default from I + * 1: Inherited from A + */ + public void test28() throws IOException, ReflectiveOperationException { + compileSpec("C(A,Id0)"); + assertLinkage("C", "I0", LINKAGE_ERROR); + recompileSpec("C(Ac1,Id0)", "A"); + assertLinkage("C", "I0", "A1"); + } + + /* + * C(A, I) -> C(Ac1, Id0) + * + * 0*: Inherited default from I + * 1: Inherited from A + */ + public void test29() throws IOException, ReflectiveOperationException { + compileSpec("C(A,I)"); + assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR); + recompileSpec("C(Ac1,Id0)", "A", "I"); + assertLinkage("C", "I0", "A1"); + } + + /* + * Cc2(Ac1, I) -> Cc2(Ac1, Id0) + * + * 0*: Inherited default from I + * 1: Declared in C (through bridge) + * 2: Declared in C + */ + public void test30() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(Ac1,I)"); + assertLinkage("C", LINKAGE_ERROR, "C2", "C2"); + recompileSpec("Cc2(Ac1,Id0)", "I"); + assertLinkage("C", "I0", "C2", "C2"); + } + + /* + * Cc2(Aa1, I) -> Cc2(Aa1, Id0) + * + * 0*: Inherited default from I + * 1: Declared in C (through bridge) + * 2: Declared in C + */ + public void test31() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(Aa1,I)"); + assertLinkage("C", LINKAGE_ERROR, "C2", "C2"); + recompileSpec("Cc2(Aa1,Id0)", "I"); + assertLinkage("C", "I0", "C2", "C2"); + } + + /* + * Cc2(A, Id0) -> Cc2(Ac1, Id0) + * + * 0: Declared in C (through bridge) + * 1*: Inherited from A + * 2: Declared in C + */ + public void test32() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(A,Id0)"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Ac1,Id0)", "A"); + assertLinkage("C", "C2", "A1", "C2"); + } + + /* + * Cc2(A, Ia0) -> Cc2(Ac1, Ia0) + * + * 0: Declared in C (through bridge) + * 1*: Inherited from A + * 2: Declared in C + */ + public void test33() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(A,Ia0)"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Ac1,Ia0)", "A"); + assertLinkage("C", "C2", "A1", "C2"); + } + + /* + * Cc2(A, I) -> Cc2(Ac1, Id0) + * + * 0*: Inherited from A + * 1*: Inherited default from I + * 2: Declared in C + */ + public void test34() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(A,I)"); + assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Ac1,Id0)", "A", "I"); + assertLinkage("C", "I0", "A1", "C2"); + } + + /* + * Cc2(Id0, J) -> Cc2(Id0, Jd1) + * + * 0: Declared in C (through bridge) + * 1*: Inherited default from J + * 2: Declared in C + */ + public void test35() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(Id0,J)"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Id0,Jd1)", "J"); + assertLinkage("C", "C2", "J1", "C2"); + } + + /* + * Cc2(Ia0, J) -> Cc2(Ia0, Jd1) + * + * 0: Declared in C (through bridge) + * 1*: Inherited default from J + * 2: Declared in C + */ + public void test36() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(Ia0,J)"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Ia0,Jd1)", "J"); + assertLinkage("C", "C2", "J1", "C2"); + } + + /* + * Cc2(I, J) -> Cc2(Id0, Jd1) + * + * 0*: Inherited default from I + * 1*: Inherited default from J + * 2: Declared in C + */ + public void test37() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(I,J)"); + assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Id0,Jd1)", "I", "J"); + assertLinkage("C", "I0", "J1", "C2"); + } + + /* + * C(A(Id0), J(Id0)) -> C(Ac1(Id0), J(Id0)) + * + * 0: Inherited default from I + * 0*: Inherited from A (through bridge) + * 1*: Inherited from A + */ + public void test38() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Id0),J(Id0))"); + assertLinkage("C", "I0", LINKAGE_ERROR); + recompileSpec("C(Ac1(Id0),J(Id0))", "A"); + assertLinkage("C", "A1", "A1"); + } + + /* + * C(A(Id0), J(Id0)) -> C(A(Id0), Jd1(Id0)) + * + * 0: Inherited default from I + * 0: Inherited default from J (through bridge) + * 1*: Inherited default from J + */ + public void test39() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Id0),J(Id0))"); + assertLinkage("C", "I0", LINKAGE_ERROR); + recompileSpec("C(A(Id0),Jd1(Id0))", "J"); + assertLinkage("C", "J1", "J1"); + } + + /* + * C(A(Id0), J(Id0)) -> C(Ac2(Id0), Jd1(Id0)) + * + * 0: Inherited default from I + * 0*: Inherited from A (new bridge in A beats new bridge in J) + * 1*: Inherited default from J + * 2: Inherited from A + */ + public void test40() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Id0),J(Id0))"); + assertLinkage("C", "I0", LINKAGE_ERROR); + recompileSpec("C(Ac2(Id0),Jd1(Id0))", "A", "J"); + assertLinkage("C", "A2", "J1", "A2"); + } + + /* + * C(J(Id0), K(Id0)) -> C(Jd1(Id0), K(Id0)) + * + * 0: Inherited from I + * 0*: Inherited default from J (through bridge) + * 1: Inherited default from J + */ + public void test41() throws IOException, ReflectiveOperationException { + compileSpec("C(J(Id0),K(Id0))"); + assertLinkage("C", "I0", LINKAGE_ERROR); + recompileSpec("C(Jd1(Id0),K(Id0))", "J"); + assertLinkage("C", "J1", "J1"); + } + + /* + * C(Ac2(Id0), J(Id0)) -> C(Ac2(Id0), Jd1(Id0)) + * + * 0: Inherited from A (bridge in A beats new bridge in J) + * 1*: Inherited default from J + * 2: Inherited from A + */ + public void test42() throws IOException, ReflectiveOperationException { + compileSpec("C(Ac2(Id0),J(Id0))"); + assertLinkage("C", "A2", LINKAGE_ERROR, "A2"); + recompileSpec("C(Ac2(Id0),Jd1(Id0))", "J"); + assertLinkage("C", "A2", "J1", "A2"); + } + + /* + * C(Ac2(Ia0), J(Ia0)) -> C(Ac2(Ia0), Jd1(Ia0)) + * + * 0: Inherited from A (bridge in A beats new bridge in J) + * 1*: Inherited default from J + * 2: Inherited from A + */ + public void test43() throws IOException, ReflectiveOperationException { + compileSpec("C(Ac2(Ia0),J(Ia0))"); + assertLinkage("C", "A2", LINKAGE_ERROR, "A2"); + recompileSpec("C(Ac2(Ia0),Jd1(Ia0))", "J"); + assertLinkage("C", "A2", "J1", "A2"); + } + + /* + * C(A(Id0), Jd1(Id0)) -> C(Ac2(Id0), Jd1(Id0)) + * + * 0: Inherited from J + * 0*: Inherited from A (new bridge in A beats bridge in J) + * 1: Inherited default from J + * 2*: Inherited from A + */ + public void test44() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Id0),Jd1(Id0))"); + assertLinkage("C", "J1", "J1", LINKAGE_ERROR); + recompileSpec("C(Ac2(Id0),Jd1(Id0))", "A"); + assertLinkage("C", "A2", "J1", "A2"); + } + + /* + * C(A(Ia0), Jd1(Ia0)) -> C(Ac2(Ia0), Jd1(Ia0)) + * + * 0: Inherited from J + * 0*: Inherited from A (new bridge in A beats bridge in J) + * 1: Inherited default from J + * 2*: Inherited from A + */ + public void test45() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Ia0),Jd1(Ia0))"); + assertLinkage("C", "J1", "J1", LINKAGE_ERROR); + recompileSpec("C(Ac2(Ia0),Jd1(Ia0))", "A"); + assertLinkage("C", "A2", "J1", "A2"); + } + + /* + * Cc2(A(Id0), J(Id0)) -> Cc2(Ac1(Id0), J(Id0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited from A + * 2: Declared in C + */ + public void test46() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(A(Id0),J(Id0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Ac1(Id0),J(Id0))", "A"); + assertLinkage("C", "C2", "A1", "C2"); + } + + /* + * Cc2(A(Ia0), J(Ia0)) -> Cc2(Ac1(Ia0), J(Ia0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited from A + * 2: Declared in C + */ + public void test47() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(A(Ia0),J(Ia0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Ac1(Ia0),J(Ia0))", "A"); + assertLinkage("C", "C2", "A1", "C2"); + } + + /* + * Cc2(A(Id0), J(Id0)) -> Cc2(A(Id0), Jd1(Id0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited default from J + * 2: Declared in C + */ + public void test48() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(A(Id0),J(Id0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(A(Id0),Jd1(Id0))", "J"); + assertLinkage("C", "C2", "J1", "C2"); + } + + /* + * Cc2(A(Ia0), J(Ia0)) -> Cc2(A(Ia0), Jd1(Ia0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited default from J + * 2: Declared in C + */ + public void test49() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(A(Ia0),J(Ia0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(A(Ia0),Jd1(Ia0))", "J"); + assertLinkage("C", "C2", "J1", "C2"); + } + + + /* + * Cc3(A(Id0), J(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0)) + * + * 0: Bridge in C + * 1*: Inherited from A + * 2*: Inherited default from J + * 3: Declared in C + */ + public void test50() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(A(Id0),J(Id0))"); + assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "A", "J"); + assertLinkage("C", "C3", "A1", "J2", "C3"); + } + + /* + * Cc3(A(Ia0), J(Ia0)) -> Cc3(Ac1(Ia0), Jd2(Ia0)) + * + * 0: Bridge in C + * 1*: Inherited from A + * 2*: Inherited default from J + * 3: Declared in C + */ + public void test51() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(A(Ia0),J(Ia0))"); + assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "A", "J"); + assertLinkage("C", "C3", "A1", "J2", "C3"); + } + + /* + * Cc2(J(Id0), K(Id0)) -> Cc2(Jd1(Id0), K(Id0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited default from J + * 2: Declared in C + */ + public void test52() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(J(Id0),K(Id0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Jd1(Id0),K(Id0))", "J"); + assertLinkage("C", "C2", "J1", "C2"); + } + + /* + * Cc2(J(Ia0), K(Ia0)) -> Cc2(Jd1(Ia0), K(Ia0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited default from J + * 2: Declared in C + */ + public void test53() throws IOException, ReflectiveOperationException { + compileSpec("Cc2(J(Ia0),K(Ia0))"); + assertLinkage("C", "C2", LINKAGE_ERROR, "C2"); + recompileSpec("Cc2(Jd1(Ia0),K(Ia0))", "J"); + assertLinkage("C", "C2", "J1", "C2"); + } + + /* + * Cc3(J(Id0), K(Id0)) -> Cc3(Jd1(Id0), Kd2(Id0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited default from J + * 2*: Inherited default from K + * 3: Declared in C + */ + public void test54() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(J(Id0),K(Id0))"); + assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "J", "K"); + assertLinkage("C", "C3", "J1", "K2", "C3"); + } + + /* + * Cc3(J(Ia0), K(Ia0)) -> Cc3(Jd1(Ia0), Kd2(Ia0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited default from J + * 2*: Inherited default from K + * 3: Declared in C + */ + public void test55() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(J(Ia0),K(Ia0))"); + assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "J", "K"); + assertLinkage("C", "C3", "J1", "K2", "C3"); + } + + /* + * Cc3(Ac1(Id0), J(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0)) + * + * 0: Declared in C (through bridge) + * 1: Declared in C (through bridge) + * 2*: Inherited default from J + * 3: Declared in C + */ + public void test56() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(Ac1(Id0),J(Id0))"); + assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "J"); + assertLinkage("C", "C3", "C3", "J2", "C3"); + } + + /* + * Cc3(Ac1(Ia0), J(Ia0)) -> Cc3(Ac1(Ia0), Jd2(Ia0)) + * + * 0: Declared in C (through bridge) + * 1: Declared in C (through bridge) + * 2*: Inherited default from J + * 3: Declared in C + */ + public void test57() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(Ac1(Ia0),J(Ia0))"); + assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "J"); + assertLinkage("C", "C3", "C3", "J2", "C3"); + } + + /* + * Cc3(Aa1(Id0), J(Id0)) -> Cc3(Aa1(Id0), Jd2(Id0)) + * + * 0: Declared in C (through bridge) + * 1: Declared in C (through bridge) + * 2*: Inherited default from J + * 3: Declared in C + */ + public void test58() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(Aa1(Id0),J(Id0))"); + assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Aa1(Id0),Jd2(Id0))", "J"); + assertLinkage("C", "C3", "C3", "J2", "C3"); + } + + /* + * Cc3(Aa1(Ia0), J(Ia0)) -> Cc3(Aa1(Ia0), Jd2(Ia0)) + * + * 0: Declared in C (through bridge) + * 1: Declared in C (through bridge) + * 2*: Inherited default from J + * 3: Declared in C + */ + public void test59() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(Aa1(Ia0),J(Ia0))"); + assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Aa1(Ia0),Jd2(Ia0))", "J"); + assertLinkage("C", "C3", "C3", "J2", "C3"); + } + + /* + * Cc3(A(Id0), Jd2(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited from A + * 2: Declared in C (through bridge) + * 3: Declared in C + */ + public void test60() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(A(Id0),Jd2(Id0))"); + assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3"); + recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "A"); + assertLinkage("C", "C3", "A1", "C3", "C3"); + } + + /* + * Cc3(A(Im0), Jd2(Ia0)) -> Cc3(Ac1(Im0), Jd2(Ia0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited from A + * 2: Declared in C (through bridge) + * 3: Declared in C + */ + public void test61() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(A(Ia0),Jd2(Ia0))"); + assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3"); + recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "A"); + assertLinkage("C", "C3", "A1", "C3", "C3"); + } + + /* + * Cc3(A(Im0), Ja2(Id0)) -> Cc3(Ac1(Id0), Ja2(Id0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited from A + * 2: Declared in C (through bridge) + * 3: Declared in C + */ + public void test62() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(A(Id0),Ja2(Id0))"); + assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3"); + recompileSpec("Cc3(Ac1(Id0),Ja2(Id0))", "A"); + assertLinkage("C", "C3", "A1", "C3", "C3"); + } + + /* + * Cc3(A(Im0), Ja2(Ia0)) -> Cc3(Ac1(Ia0), Ja2(Ia0)) + * + * 0: Declared in C (through bridge) + * 1*: Inherited from A + * 2: Declared in C (through bridge) + * 3: Declared in C + */ + public void test63() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(A(Ia0),Ja2(Ia0))"); + assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3"); + recompileSpec("Cc3(Ac1(Ia0),Ja2(Ia0))", "A"); + assertLinkage("C", "C3", "A1", "C3", "C3"); + } + + /* + * Cc3(Jd1(Id0), K(Id0)) -> Cc3(Jd1(Id0), Kd2(Id0)) + * + * 0: Declared in C (through bridge) + * 1: Declared in C (through bridge) + * 2*: Inherited default from K + * 3: Declared in C + */ + public void test64() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(Jd1(Id0),K(Id0))"); + assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "K"); + assertLinkage("C", "C3", "C3", "K2", "C3"); + } + + /* + * Cc3(Jd1(Ia0), K(Ia0)) -> Cc3(Jd1(Ia0), Kd2(Ia0)) + * + * 0: Declared in C (through bridge) + * 1: Declared in C (through bridge) + * 2*: Inherited default from K + * 3: Declared in C + */ + public void test65() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(Jd1(Ia0),K(Ia0))"); + assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "K"); + assertLinkage("C", "C3", "C3", "K2", "C3"); + } + + /* + * Cc3(Ja1(Id0), K(Id0)) -> Cc3(Ja1(Id0), Kd2(Id0)) + * + * 0: Declared in C (through bridge) + * 1: Declared in C (through bridge) + * 2*: Inherited default from K + * 3: Declared in C + */ + public void test66() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(Jd1(Id0),K(Id0))"); + assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "K"); + assertLinkage("C", "C3", "C3", "K2", "C3"); + } + + /* + * Cc3(Ja1(Ia0), K(Ia0)) -> Cc3(Ja1(Ia0), Kd2(Ia0)) + * + * 0: Declared in C (through bridge) + * 1: Declared in C (through bridge) + * 2*: Inherited default from K + * 3: Declared in C + */ + public void test67() throws IOException, ReflectiveOperationException { + compileSpec("Cc3(Jd1(Ia0),K(Ia0))"); + assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3"); + recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "K"); + assertLinkage("C", "C3", "C3", "K2", "C3"); + } + + // Dan's set A + public void testA1() throws IOException, ReflectiveOperationException { + compileSpec("C(Id0)"); + assertLinkage("C", "I0"); + } + + public void testA2() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Id0))"); + assertLinkage("C", "I0"); + } + + public void testA3() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Id0),J)"); + assertLinkage("C", "I0"); + } + + public void testA4() throws IOException, ReflectiveOperationException { + compileSpec("D(C(Id0),Jd0(Id0))"); + assertLinkage("D", "J0"); + assertLinkage("C", "I0"); + } + + public void testA5() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Id0),Jd0)", + "compiler.err.types.incompatible.unrelated.defaults"); + } + + public void testA6() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Ia0,Jd0))", + "compiler.err.does.not.override.abstract", + "compiler.err.types.incompatible.abstract.default"); + } + + public void testA7() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Id0,Jd0))", + "compiler.err.types.incompatible.unrelated.defaults"); + } + + public void testA8() throws IOException, ReflectiveOperationException { + compileSpec("C(A(Ia0),J)", "compiler.err.does.not.override.abstract"); + } + + public void testA9() throws IOException, ReflectiveOperationException { + compileSpec("C(Ac0(Id0))"); + assertLinkage("C", "A0"); + } + + public void testA10() throws IOException, ReflectiveOperationException { + compileSpec("C(Aa0,I)", "compiler.err.does.not.override.abstract"); + } + + public void testA11() throws IOException, ReflectiveOperationException { + compileSpec("C(Ac0,Id0)"); + assertLinkage("C", "A0"); + } + + // Dan's set B + + /* B1 can't be done, needs a second concrete class D + public void testB1() throws IOException, ReflectiveOperationException { + compileSpec("Cc1(Dc0)"); + assertLinkage("C", "C1", "C1"); + assertLinkage("D", "A0", LINKAGE_ERROR); + } + */ + + public void testB2() throws IOException, ReflectiveOperationException { + compileSpec("Cc1(Ac0)"); + assertLinkage("C", "C1", "C1"); + } + + //??? B3 seems to suggest that we should create an abstract class + //public void testB3() throws IOException, ReflectiveOperationException { + // compileSpec("Ba1(Cc0)"); + // assertLinkage("B", "C0", "A1"); + //} + + // B4 needs too many classes + + public void testB5() throws IOException, ReflectiveOperationException { + compileSpec("Cc1(Aa1(Id0))"); + assertLinkage("C", "C1", "C1"); + } + + public void testB6() throws IOException, ReflectiveOperationException { + compileSpec("C(Ac1(Id0))"); + assertLinkage("C", "A1", "A1"); + } + + public void testB7() throws IOException, ReflectiveOperationException { + compileSpec("Cc1(Id0)"); + assertLinkage("C", "C1", "C1"); + } + + public void testB8() throws IOException, ReflectiveOperationException { + compileSpec("C(Jd1(Id0))"); + assertLinkage("C", "J1", "J1"); + } + + // B9 needs too many classes + + // The rest of Dan's tests need generics +} diff --git a/langtools/test/tools/javac/lambda/bridge/template_tests/TEST.properties b/langtools/test/tools/javac/lambda/bridge/template_tests/TEST.properties new file mode 100644 index 00000000000..9e96df01db6 --- /dev/null +++ b/langtools/test/tools/javac/lambda/bridge/template_tests/TEST.properties @@ -0,0 +1,7 @@ +# This file identifies root(s) of the test-ng hierarchy. + + + +TestNG.dirs = . + +lib.dirs = /lib/combo From 810c76f567e5d568686a71c19c192f7a344d73cc Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 9 Sep 2013 17:36:23 -0700 Subject: [PATCH 0275/1294] 8006972: jtreg test fails: test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java Reviewed-by: darcy --- .../TestMissingElement.java | 18 +++++++-- .../TestMissingElement/TestMissingElement.ref | 38 +++++++++---------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java index 2ddcd10bd26..644ec9d5b17 100644 --- a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java +++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java @@ -31,6 +31,7 @@ * @compile/fail/ref=TestMissingElement.ref -proc:only -XprintRounds -XDrawDiagnostics -processor TestMissingElement InvalidSource.java */ +import java.io.PrintWriter; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.element.*; @@ -38,7 +39,18 @@ import javax.lang.model.type.*; import javax.lang.model.util.*; import static javax.tools.Diagnostic.Kind.*; +import com.sun.tools.javac.processing.JavacProcessingEnvironment; +import com.sun.tools.javac.util.Log; + public class TestMissingElement extends JavacTestingAbstractProcessor { + private PrintWriter out; + + @Override + public void init(ProcessingEnvironment env) { + super.init(env); + out = ((JavacProcessingEnvironment) env).getContext().get(Log.outKey); + } + @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { for (TypeElement te: ElementFilter.typesIn(roundEnv.getRootElements())) { @@ -70,13 +82,13 @@ public class TestMissingElement extends JavacTestingAbstractProcessor { } private void checkInterfaces(TypeElement te, String expect) { - System.err.println("check interfaces: " + te + " -- " + expect); + out.println("check interfaces: " + te + " -- " + expect); String found = asString(te.getInterfaces(), ", "); checkEqual("interfaces", te, found, expect); } private void checkSupertype(TypeElement te, String expect) { - System.err.println("check supertype: " + te + " -- " + expect); + out.println("check supertype: " + te + " -- " + expect); String found = asString(te.getSuperclass()); checkEqual("supertype", te, found, expect); } @@ -85,7 +97,7 @@ public class TestMissingElement extends JavacTestingAbstractProcessor { if (found.equals(expect)) { // messager.printMessage(NOTE, "expected " + label + " found: " + expect, te); } else { - System.err.println("unexpected " + label + ": " + te + "\n" + out.println("unexpected " + label + ": " + te + "\n" + " found: " + found + "\n" + "expect: " + expect); messager.printMessage(ERROR, "unexpected " + label + " found: " + found + "; expected: " + expect, te); diff --git a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref index 4c31a101dbb..d71a2cce8ba 100644 --- a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref +++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref @@ -2,6 +2,24 @@ Round 1: input files: {ExpectInterfaces, ExpectSupertype, OK, InvalidSource} annotations: [ExpectSupertype, ExpectInterfaces] last round: false +check supertype: InvalidSource.TestClassMissingClassA -- !:empty clss A! +check supertype: InvalidSource.TestClassMissingClassAB -- !:empty clss (pkg A).B! +check supertype: InvalidSource.TestClassMissingClass_juA -- !:empty clss (pkg java.util).A! +check supertype: InvalidSource.TestClassTMissingClassAT -- !:empty clss A! +check interfaces: InvalidSource.TestClassMissingIntfA -- !:empty intf A! +check interfaces: InvalidSource.TestClassMissingIntfAB -- !:empty intf (pkg A).B! +check interfaces: InvalidSource.TestClassMissingIntfAOK -- !:empty intf A!, intf OK +check interfaces: InvalidSource.TestClassOKMissingIntfA -- intf OK, !:empty intf A! +check interfaces: InvalidSource.TestClassMissingIntfA_B -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestIntfMissingIntfA -- !:empty intf A! +check interfaces: InvalidSource.TestIntfMissingIntfAOK -- !:empty intf A!, intf OK +check interfaces: InvalidSource.TestIntfOKMissingIntfA -- intf OK, !:empty intf A! +check interfaces: InvalidSource.TestIntfMissingIntfAB -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestClassTMissingIntfAT -- !:empty intf A! +check interfaces: InvalidSource.TestClassTMissingIntfAT_B -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestIntfTMissingIntfAT -- !:empty intf A! +check interfaces: InvalidSource.TestIntfTMissingIntfAT_B -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestClassListMissingX -- intf (pkg java.util).List Round 2: input files: {} annotations: [] @@ -28,22 +46,4 @@ InvalidSource.java:100:49: compiler.err.cant.resolve.location: kindname.class, A InvalidSource.java:103:51: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) InvalidSource.java:103:57: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, InvalidSource, null) InvalidSource.java:106:58: compiler.err.cant.resolve.location: kindname.class, X, , , (compiler.misc.location: kindname.class, InvalidSource, null) -22 errors -check supertype: InvalidSource.TestClassMissingClassA -- !:empty clss A! -check supertype: InvalidSource.TestClassMissingClassAB -- !:empty clss (pkg A).B! -check supertype: InvalidSource.TestClassMissingClass_juA -- !:empty clss (pkg java.util).A! -check supertype: InvalidSource.TestClassTMissingClassAT -- !:empty clss A! -check interfaces: InvalidSource.TestClassMissingIntfA -- !:empty intf A! -check interfaces: InvalidSource.TestClassMissingIntfAB -- !:empty intf (pkg A).B! -check interfaces: InvalidSource.TestClassMissingIntfAOK -- !:empty intf A!, intf OK -check interfaces: InvalidSource.TestClassOKMissingIntfA -- intf OK, !:empty intf A! -check interfaces: InvalidSource.TestClassMissingIntfA_B -- !:empty intf A!, !:empty intf B! -check interfaces: InvalidSource.TestIntfMissingIntfA -- !:empty intf A! -check interfaces: InvalidSource.TestIntfMissingIntfAOK -- !:empty intf A!, intf OK -check interfaces: InvalidSource.TestIntfOKMissingIntfA -- intf OK, !:empty intf A! -check interfaces: InvalidSource.TestIntfMissingIntfAB -- !:empty intf A!, !:empty intf B! -check interfaces: InvalidSource.TestClassTMissingIntfAT -- !:empty intf A! -check interfaces: InvalidSource.TestClassTMissingIntfAT_B -- !:empty intf A!, !:empty intf B! -check interfaces: InvalidSource.TestIntfTMissingIntfAT -- !:empty intf A! -check interfaces: InvalidSource.TestIntfTMissingIntfAT_B -- !:empty intf A!, !:empty intf B! -check interfaces: InvalidSource.TestClassListMissingX -- intf (pkg java.util).List \ No newline at end of file +22 errors \ No newline at end of file From a9e5e17bd2827d68e0121b1c615b9c3144ad64e2 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Mon, 9 Sep 2013 23:13:45 +0200 Subject: [PATCH 0276/1294] 8019521: Enhanced rethrow disabled in lambdas Fixing effectively final detection inside lambdas, small cleanup related to thrown types detection in lambdas Reviewed-by: mcimadamore, jjg --- .../com/sun/tools/javac/comp/Attr.java | 20 ++++++------ .../com/sun/tools/javac/comp/Flow.java | 32 ++++++++++++++++--- .../com/sun/tools/javac/tree/JCTree.java | 1 - .../javac/lambda/EffectivelyFinalThrows.java | 25 +++++++++++++++ 4 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 langtools/test/tools/javac/lambda/EffectivelyFinalThrows.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 434f0b3815b..c09ab8907a2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2418,9 +2418,17 @@ public class Attr extends JCTree.Visitor { preFlow(that); flow.analyzeLambda(env, that, make, isSpeculativeRound); - checkLambdaCompatible(that, lambdaType, resultInfo.checkContext, isSpeculativeRound); + checkLambdaCompatible(that, lambdaType, resultInfo.checkContext); if (!isSpeculativeRound) { + //add thrown types as bounds to the thrown types free variables if needed: + if (resultInfo.checkContext.inferenceContext().free(lambdaType.getThrownTypes())) { + List inferredThrownTypes = flow.analyzeLambdaThrownTypes(env, that, make); + List thrownTypes = resultInfo.checkContext.inferenceContext().asFree(lambdaType.getThrownTypes()); + + chk.unhandled(inferredThrownTypes, thrownTypes); + } + checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, currentTarget); } result = check(that, currentTarget, VAL, resultInfo); @@ -2587,10 +2595,9 @@ public class Attr extends JCTree.Visitor { * Lambda compatibility. Check that given return types, thrown types, parameter types * are compatible with the expected functional interface descriptor. This means that: * (i) parameter types must be identical to those of the target descriptor; (ii) return - * types must be compatible with the return type of the expected descriptor; - * (iii) finish inference of thrown types if required. + * types must be compatible with the return type of the expected descriptor. */ - private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext, boolean speculativeAttr) { + private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext) { Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType()); //return values have already been checked - but if lambda has no return @@ -2607,11 +2614,6 @@ public class Attr extends JCTree.Visitor { if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) { checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda")); } - - if (!speculativeAttr) { - List thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes()); - chk.unhandled(tree.inferredThrownTypes == null ? List.nil() : tree.inferredThrownTypes, thrownTypes); - } } private Env lambdaEnv(JCLambda that, Env env) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index e488d45b0c0..466436b6b9e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -224,7 +224,6 @@ public class Flow { } try { new AliveAnalyzer().analyzeTree(env, that, make); - new LambdaFlowAnalyzer().analyzeTree(env, that, make); } finally { if (!speculative) { log.popDiagnosticHandler(diagHandler); @@ -232,6 +231,23 @@ public class Flow { } } + public List analyzeLambdaThrownTypes(Env env, JCLambda that, TreeMaker make) { + //we need to disable diagnostics temporarily; the problem is that if + //a lambda expression contains e.g. an unreachable statement, an error + //message will be reported and will cause compilation to skip the flow analyis + //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis + //related errors, which will allow for more errors to be detected + Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); + try { + new AssignAnalyzer().analyzeTree(env, that, make); + LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer(); + flowAnalyzer.analyzeTree(env, that, make); + return flowAnalyzer.inferredThrownTypes; + } finally { + log.popDiagnosticHandler(diagHandler); + } + } + /** * Definite assignment scan mode */ @@ -1318,27 +1334,35 @@ public class Flow { * Specialized pass that performs inference of thrown types for lambdas. */ class LambdaFlowAnalyzer extends FlowAnalyzer { + List inferredThrownTypes; + boolean inLambda; @Override public void visitLambda(JCLambda tree) { - if (tree.type != null && - tree.type.isErroneous()) { + if ((tree.type != null && + tree.type.isErroneous()) || inLambda) { return; } List prevCaught = caught; List prevThrown = thrown; ListBuffer prevPending = pendingExits; + inLambda = true; try { pendingExits = ListBuffer.lb(); caught = List.of(syms.throwableType); thrown = List.nil(); scan(tree.body); - tree.inferredThrownTypes = thrown; + inferredThrownTypes = thrown; } finally { pendingExits = prevPending; caught = prevCaught; thrown = prevThrown; + inLambda = false; } } + @Override + public void visitClassDef(JCClassDecl tree) { + //skip + } } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java index a0581cce87a..d1d71080027 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -1596,7 +1596,6 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public List params; public JCTree body; public boolean canCompleteNormally = true; - public List inferredThrownTypes; public ParameterKind paramKind; public JCLambda(List params, diff --git a/langtools/test/tools/javac/lambda/EffectivelyFinalThrows.java b/langtools/test/tools/javac/lambda/EffectivelyFinalThrows.java new file mode 100644 index 00000000000..54183173f3a --- /dev/null +++ b/langtools/test/tools/javac/lambda/EffectivelyFinalThrows.java @@ -0,0 +1,25 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8019521 + * @summary Check that enhanced rethrow/effectivelly final works correctly inside lambdas + * @compile EffectivelyFinalThrows.java + */ + +class EffectivelyFinalThrows { + interface SAM { + public void t() throws E; + } + void test(SAM s) throws E { + s.t(); + } + void test2(SAM s) throws Checked { + test(() -> { + try { + s.t(); + } catch (Throwable t) { + throw t; + } + }); + } + static class Checked extends Exception {} +} From 4d99afea082e01c35984e24eb11fbd00327b9f4f Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Tue, 10 Sep 2013 07:51:37 +0200 Subject: [PATCH 0277/1294] 8024473: Remove unused macro: IRT_ENTRY_FOR_NMETHOD Removed unused macro Reviewed-by: kvn, adlertz --- hotspot/src/share/vm/runtime/interfaceSupport.hpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.hpp b/hotspot/src/share/vm/runtime/interfaceSupport.hpp index f995a4ee714..4d2ca5137ea 100644 --- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp +++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp @@ -471,16 +471,6 @@ class RuntimeHistogramElement : public HistogramElement { VM_ENTRY_BASE(result_type, header, thread) \ debug_only(VMEntryWrapper __vew;) -// Another special case for nmethod_entry_point so the nmethod that the -// interpreter is about to branch to doesn't get flushed before as we -// branch to it's interpreter_entry_point. Skip stress testing here too. -// Also we don't allow async exceptions because it is just too painful. -#define IRT_ENTRY_FOR_NMETHOD(result_type, header) \ - result_type header { \ - nmethodLocker _nmlock(nm); \ - ThreadInVMfromJavaNoAsyncException __tiv(thread); \ - VM_ENTRY_BASE(result_type, header, thread) - #define IRT_END } From 1a1a6829fa23915704ca46b69bbec1b8be8e3930 Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Tue, 10 Sep 2013 11:00:21 +0400 Subject: [PATCH 0278/1294] 8024381: The test for 8020210 does not have @bug tag Reviewed-by: anthony, serb --- .../java/awt/Window/MaximizeOffscreen/MaximizeOffscreenTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/test/java/awt/Window/MaximizeOffscreen/MaximizeOffscreenTest.java b/jdk/test/java/awt/Window/MaximizeOffscreen/MaximizeOffscreenTest.java index 014637acec0..78155f3b9b3 100644 --- a/jdk/test/java/awt/Window/MaximizeOffscreen/MaximizeOffscreenTest.java +++ b/jdk/test/java/awt/Window/MaximizeOffscreen/MaximizeOffscreenTest.java @@ -23,6 +23,7 @@ /** * @test @summary JVM crash if the frame maximized from offscreen + * @bug 8020210 * @author Petr Pchelko * @library ../../regtesthelpers * @build Util From 92bfcc0db031964ec2e6466d88a5cb016d55d2da Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Tue, 10 Sep 2013 14:33:48 +0400 Subject: [PATCH 0279/1294] 8021253: JFileChooser does not react on pressing enter since java 7 Reviewed-by: malenkov --- .../classes/javax/swing/JFileChooser.java | 18 ++- .../JFileChooser/8021253/bug8021253.java | 113 ++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 jdk/test/javax/swing/JFileChooser/8021253/bug8021253.java diff --git a/jdk/src/share/classes/javax/swing/JFileChooser.java b/jdk/src/share/classes/javax/swing/JFileChooser.java index e053b7af081..61806b439b8 100644 --- a/jdk/src/share/classes/javax/swing/JFileChooser.java +++ b/jdk/src/share/classes/javax/swing/JFileChooser.java @@ -362,6 +362,7 @@ public class JFileChooser extends JComponent implements Accessible { */ protected void setup(FileSystemView view) { installShowFilesListener(); + installHierarchyListener(); if(view == null) { view = FileSystemView.getFileSystemView(); @@ -374,6 +375,22 @@ public class JFileChooser extends JComponent implements Accessible { enableEvents(AWTEvent.MOUSE_EVENT_MASK); } + private void installHierarchyListener() { + addHierarchyListener(new HierarchyListener() { + @Override + public void hierarchyChanged(HierarchyEvent e) { + if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) + == HierarchyEvent.PARENT_CHANGED) { + JFileChooser fc = JFileChooser.this; + JRootPane rootPane = SwingUtilities.getRootPane(fc); + if (rootPane != null) { + rootPane.setDefaultButton(fc.getUI().getDefaultButton(fc)); + } + } + } + }); + } + private void installShowFilesListener() { // Track native setting for showing hidden files Toolkit tk = Toolkit.getDefaultToolkit(); @@ -801,7 +818,6 @@ public class JFileChooser extends JComponent implements Accessible { dialog.getRootPane().setWindowDecorationStyle(JRootPane.FILE_CHOOSER_DIALOG); } } - dialog.getRootPane().setDefaultButton(ui.getDefaultButton(this)); dialog.pack(); dialog.setLocationRelativeTo(parent); diff --git a/jdk/test/javax/swing/JFileChooser/8021253/bug8021253.java b/jdk/test/javax/swing/JFileChooser/8021253/bug8021253.java new file mode 100644 index 00000000000..5e833926a00 --- /dev/null +++ b/jdk/test/javax/swing/JFileChooser/8021253/bug8021253.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.io.IOException; +import java.awt.BorderLayout; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import sun.awt.SunToolkit; + +/** + * @test + * @bug 8021253 + * @author Alexander Scherbatiy + * @summary JFileChooser does not react on pressing enter since java 7 + * @run main bug8021253 + */ + +public class bug8021253 { + + private static volatile boolean defaultKeyPressed; + private static JFileChooser fileChooser; + private static File file; + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + + toolkit.realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + fileChooser.setSelectedFile(file); + } + }); + + toolkit.realSync(); + + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + toolkit.realSync(); + + if (!defaultKeyPressed) { + throw new RuntimeException("Default button is not pressed"); + } + } + + private static void createAndShowGUI() { + + file = getTempFile(); + + final JFrame frame = new JFrame("Test"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(200, 300); + + fileChooser = new JFileChooser(file.getParentFile()); + fileChooser.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + defaultKeyPressed = true; + frame.dispose(); + } + }); + + frame.getContentPane().add(BorderLayout.CENTER, fileChooser); + frame.setSize(fileChooser.getPreferredSize()); + frame.setVisible(true); + } + + private static File getTempFile() { + try { + File temp = File.createTempFile("test", ".txt"); + temp.deleteOnExit(); + return temp; + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} From fae7d60062ef1378fc5b35a85f77022b56f3aa4c Mon Sep 17 00:00:00 2001 From: Andreas Lundblad Date: Tue, 10 Sep 2013 13:47:51 +0200 Subject: [PATCH 0280/1294] 8005222: Fixed bugs should have tests with bugid in @bug tag Reviewed-by: jfranck, jjg --- .../javac/defaultMethods/ClassReaderTest/ClassReaderTest.java | 3 ++- langtools/test/tools/javac/defaultMethods/Neg01.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg02.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg03.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg04.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg05.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg06.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg07.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg08.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg09.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg10.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg11.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg12.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg13.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg14.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg15.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Neg16.java | 4 ++-- langtools/test/tools/javac/defaultMethods/Pos01.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos02.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos04.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos05.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos06.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos07.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos08.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos10.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos11.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos12.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos13.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos14.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos15.java | 3 ++- langtools/test/tools/javac/defaultMethods/Pos16.java | 3 ++- .../test/tools/javac/defaultMethods/TestDefaultBody.java | 3 ++- .../tools/javac/defaultMethods/TestNoBridgeOnDefaults.java | 3 ++- .../tools/javac/defaultMethods/crossCompile/CrossCompile.java | 3 ++- .../test/tools/javac/defaultMethods/separate/Separate.java | 3 ++- .../javac/defaultMethods/super/TestDefaultSuperCall.java | 2 +- langtools/test/tools/javac/lambda/EffectivelyFinalTest.java | 2 +- 37 files changed, 72 insertions(+), 53 deletions(-) diff --git a/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java index 0e533acbe6f..491486f106e 100644 --- a/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java +++ b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that default methods don't cause ClassReader to complete classes recursively * @author Maurizio Cimadamore * @compile pkg/Foo.java diff --git a/langtools/test/tools/javac/defaultMethods/Neg01.java b/langtools/test/tools/javac/defaultMethods/Neg01.java index bbf1aba7eaa..0457b5de9bc 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg01.java +++ b/langtools/test/tools/javac/defaultMethods/Neg01.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary negative test for ambiguous defaults * @compile/fail/ref=Neg01.out -XDrawDiagnostics Neg01.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg02.java b/langtools/test/tools/javac/defaultMethods/Neg02.java index deb35a19d78..2ba1319ae96 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg02.java +++ b/langtools/test/tools/javac/defaultMethods/Neg02.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that ill-formed MI hierarchies do not compile * @compile/fail/ref=Neg02.out -XDrawDiagnostics Neg02.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg03.java b/langtools/test/tools/javac/defaultMethods/Neg03.java index ba6262c853b..2a1fbe48df2 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg03.java +++ b/langtools/test/tools/javac/defaultMethods/Neg03.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that re-abstraction works properly * @compile/fail/ref=Neg03.out -XDrawDiagnostics Neg03.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg04.java b/langtools/test/tools/javac/defaultMethods/Neg04.java index a057f35d620..c1abcfad8f3 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg04.java +++ b/langtools/test/tools/javac/defaultMethods/Neg04.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that default method must have most specific return type * @compile/fail/ref=Neg04.out -XDrawDiagnostics Neg04.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg05.java b/langtools/test/tools/javac/defaultMethods/Neg05.java index 3550c497241..8be5cf59019 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg05.java +++ b/langtools/test/tools/javac/defaultMethods/Neg05.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that abstract methods are compatible with inherited defaults * @compile/fail/ref=Neg05.out -XDrawDiagnostics Neg05.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg06.java b/langtools/test/tools/javac/defaultMethods/Neg06.java index 602ece8166f..23a757f5791 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg06.java +++ b/langtools/test/tools/javac/defaultMethods/Neg06.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary flow analysis is not run on inlined default bodies * @compile/fail/ref=Neg06.out -XDrawDiagnostics Neg06.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg07.java b/langtools/test/tools/javac/defaultMethods/Neg07.java index c11f3157b22..763a253623a 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg07.java +++ b/langtools/test/tools/javac/defaultMethods/Neg07.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that default overrides are properly type-checked * @compile/fail/ref=Neg07.out -XDrawDiagnostics Neg07.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg08.java b/langtools/test/tools/javac/defaultMethods/Neg08.java index 5e3ef07e719..b6eb221c1e2 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg08.java +++ b/langtools/test/tools/javac/defaultMethods/Neg08.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that default overrides are properly type-checked * @compile/fail/ref=Neg08.out -XDrawDiagnostics Neg08.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg09.java b/langtools/test/tools/javac/defaultMethods/Neg09.java index cabda07c321..dc7801a0a2c 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg09.java +++ b/langtools/test/tools/javac/defaultMethods/Neg09.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that default overrides are properly type-checked * @compile/fail/ref=Neg09.out -Werror -Xlint:unchecked -XDrawDiagnostics Neg09.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg10.java b/langtools/test/tools/javac/defaultMethods/Neg10.java index 3ecb1af86e1..188fd7f0747 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg10.java +++ b/langtools/test/tools/javac/defaultMethods/Neg10.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that default overrides are properly type-checked * @compile/fail/ref=Neg10.out -Werror -Xlint:unchecked -XDrawDiagnostics Neg10.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg11.java b/langtools/test/tools/javac/defaultMethods/Neg11.java index acf88f65ef2..c3b35b68b38 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg11.java +++ b/langtools/test/tools/javac/defaultMethods/Neg11.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that default overrides are properly type-checked * @compile/fail/ref=Neg11.out -XDrawDiagnostics Neg11.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg12.java b/langtools/test/tools/javac/defaultMethods/Neg12.java index e61245bf7e3..267dc86f70e 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg12.java +++ b/langtools/test/tools/javac/defaultMethods/Neg12.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that abstract methods are discarded in overload resolution diags * @compile/fail/ref=Neg12.out -XDrawDiagnostics Neg12.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg13.java b/langtools/test/tools/javac/defaultMethods/Neg13.java index e512cc3a65b..a166adab3f1 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg13.java +++ b/langtools/test/tools/javac/defaultMethods/Neg13.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that default method overriding object members are flagged as error * @compile/fail/ref=Neg13.out -XDrawDiagnostics Neg13.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg14.java b/langtools/test/tools/javac/defaultMethods/Neg14.java index 9c3c6a69e3c..842b51607a1 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg14.java +++ b/langtools/test/tools/javac/defaultMethods/Neg14.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that a class cannot have two sibling interfaces with a default and abstract method * @compile/fail/ref=Neg14.out -XDrawDiagnostics Neg14.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg15.java b/langtools/test/tools/javac/defaultMethods/Neg15.java index 7c42167d75f..1845733fe91 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg15.java +++ b/langtools/test/tools/javac/defaultMethods/Neg15.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that level skipping in default super calls is correctly rejected * @compile/fail/ref=Neg15.out -XDrawDiagnostics Neg15.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Neg16.java b/langtools/test/tools/javac/defaultMethods/Neg16.java index 1022fda22c8..cb5ce4930f5 100644 --- a/langtools/test/tools/javac/defaultMethods/Neg16.java +++ b/langtools/test/tools/javac/defaultMethods/Neg16.java @@ -1,5 +1,5 @@ -/* - * @test /nodynamiccopyright/ +/* @test /nodynamiccopyright/ + * @bug 7192246 * @summary check that level skipping in default super calls is correctly rejected * @compile/fail/ref=Neg16.out -XDrawDiagnostics Neg16.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Pos01.java b/langtools/test/tools/javac/defaultMethods/Pos01.java index 13fa6b47e83..30a3e3179f0 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos01.java +++ b/langtools/test/tools/javac/defaultMethods/Pos01.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary basic test for default methods * @author Maurizio Cimadamore */ diff --git a/langtools/test/tools/javac/defaultMethods/Pos02.java b/langtools/test/tools/javac/defaultMethods/Pos02.java index 597e7f50c79..5b71e36f8bd 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos02.java +++ b/langtools/test/tools/javac/defaultMethods/Pos02.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary test for explicit resolution of ambiguous default methods * @author Maurizio Cimadamore * @compile Pos02.java diff --git a/langtools/test/tools/javac/defaultMethods/Pos04.java b/langtools/test/tools/javac/defaultMethods/Pos04.java index 3cc0cd4c4c5..e238e280dd5 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos04.java +++ b/langtools/test/tools/javac/defaultMethods/Pos04.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary test for overriding with default method * @author Maurizio Cimadamore * @compile Pos04.java diff --git a/langtools/test/tools/javac/defaultMethods/Pos05.java b/langtools/test/tools/javac/defaultMethods/Pos05.java index 92a7eaccc9c..181ce39d4ab 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos05.java +++ b/langtools/test/tools/javac/defaultMethods/Pos05.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that indirectly inherited default methods are discovered during resolution * @author Maurizio Cimadamore * @compile Pos05.java diff --git a/langtools/test/tools/javac/defaultMethods/Pos06.java b/langtools/test/tools/javac/defaultMethods/Pos06.java index 3263e9276e2..15bcec46e4c 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos06.java +++ b/langtools/test/tools/javac/defaultMethods/Pos06.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that well-formed MI hierarchies behaves well w.r.t. method resolution (i.e. no ambiguities) * @author Maurizio Cimadamore * @compile Pos06.java diff --git a/langtools/test/tools/javac/defaultMethods/Pos07.java b/langtools/test/tools/javac/defaultMethods/Pos07.java index 6e1c2308bb5..a48e8ba3993 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos07.java +++ b/langtools/test/tools/javac/defaultMethods/Pos07.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that compilation order does not matter * @author Maurizio Cimadamore * @compile Pos07.java diff --git a/langtools/test/tools/javac/defaultMethods/Pos08.java b/langtools/test/tools/javac/defaultMethods/Pos08.java index b12486a7f8b..78bc0792257 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos08.java +++ b/langtools/test/tools/javac/defaultMethods/Pos08.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that common overrider solves default method conflicts * @author Maurizio Cimadamore * @compile Pos08.java diff --git a/langtools/test/tools/javac/defaultMethods/Pos10.java b/langtools/test/tools/javac/defaultMethods/Pos10.java index 7f0039a685b..b4c6546fa2f 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos10.java +++ b/langtools/test/tools/javac/defaultMethods/Pos10.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that type-variables in generic extension decl can be accessed from default impl * @author Maurizio Cimadamore * @compile Pos10.java diff --git a/langtools/test/tools/javac/defaultMethods/Pos11.java b/langtools/test/tools/javac/defaultMethods/Pos11.java index 91b83ccbb1c..3d6305e3be1 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos11.java +++ b/langtools/test/tools/javac/defaultMethods/Pos11.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary complex test with conflict resolution via overriding * @author Brian Goetz * @compile Pos11.java diff --git a/langtools/test/tools/javac/defaultMethods/Pos12.java b/langtools/test/tools/javac/defaultMethods/Pos12.java index 4db7f3ca182..56d2d0ea5a5 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos12.java +++ b/langtools/test/tools/javac/defaultMethods/Pos12.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that 'this' can be used from within an extension method * @compile Pos12.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Pos13.java b/langtools/test/tools/javac/defaultMethods/Pos13.java index b9acba34b44..e267f4a3ecd 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos13.java +++ b/langtools/test/tools/javac/defaultMethods/Pos13.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary qualified 'this' inside default method causes StackOverflowException * @compile Pos13.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Pos14.java b/langtools/test/tools/javac/defaultMethods/Pos14.java index d8ac04af981..07801d35529 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos14.java +++ b/langtools/test/tools/javac/defaultMethods/Pos14.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that overload resolution selects most specific signature * @compile Pos14.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Pos15.java b/langtools/test/tools/javac/defaultMethods/Pos15.java index a2dad21b237..b1a3281c583 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos15.java +++ b/langtools/test/tools/javac/defaultMethods/Pos15.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that overload resolution selects most specific signature * @compile Pos15.java */ diff --git a/langtools/test/tools/javac/defaultMethods/Pos16.java b/langtools/test/tools/javac/defaultMethods/Pos16.java index eca63b94faf..0d9a2b1da55 100644 --- a/langtools/test/tools/javac/defaultMethods/Pos16.java +++ b/langtools/test/tools/javac/defaultMethods/Pos16.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary 'class wins' should not short-circuit overload resolution * @compile Pos16.java */ diff --git a/langtools/test/tools/javac/defaultMethods/TestDefaultBody.java b/langtools/test/tools/javac/defaultMethods/TestDefaultBody.java index be3f6bfbf94..7f1be065bd1 100644 --- a/langtools/test/tools/javac/defaultMethods/TestDefaultBody.java +++ b/langtools/test/tools/javac/defaultMethods/TestDefaultBody.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that code attributed for default methods is correctly generated */ diff --git a/langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java b/langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java index 328629c51e7..ab464b70314 100644 --- a/langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java +++ b/langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that javac does not generate bridge methods for defaults */ diff --git a/langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java b/langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java index de51d4afacd..6a6f9a12e49 100644 --- a/langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java +++ b/langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary check that clinit in interface doesn't cause spurious default method diagnostics * @compile -source 1.4 -target 1.4 Clinit.java * @compile CrossCompile.java diff --git a/langtools/test/tools/javac/defaultMethods/separate/Separate.java b/langtools/test/tools/javac/defaultMethods/separate/Separate.java index 7dcf4e3ac2b..513fc996a9a 100644 --- a/langtools/test/tools/javac/defaultMethods/separate/Separate.java +++ b/langtools/test/tools/javac/defaultMethods/separate/Separate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 7192246 * @summary smoke test for separate compilation of default methods * @author Maurizio Cimadamore * @compile pkg1/A.java diff --git a/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java b/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java index 9c3a513c90f..1fbeed6d5c2 100644 --- a/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java +++ b/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8006694 + * @bug 7192246 8006694 * @summary Automatic test for checking correctness of default super/this resolution * temporarily workaround combo tests are causing time out in several platforms * @library ../../lib diff --git a/langtools/test/tools/javac/lambda/EffectivelyFinalTest.java b/langtools/test/tools/javac/lambda/EffectivelyFinalTest.java index 9d1dff9b6e4..c701b3ca6d0 100644 --- a/langtools/test/tools/javac/lambda/EffectivelyFinalTest.java +++ b/langtools/test/tools/javac/lambda/EffectivelyFinalTest.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8003280 + * @bug 7175538 8003280 * @summary Add lambda tests * Integrate effectively final check with DA/DU analysis * @compile/fail/ref=EffectivelyFinalTest01.out -XDrawDiagnostics EffectivelyFinalTest.java From 08f8d373f0e21c381a580b746c8422dc663ec747 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Tue, 10 Sep 2013 05:46:37 -0700 Subject: [PATCH 0281/1294] 8024515: ProblemList.txt updates to exclude tests that fail with hs25-b49 Reviewed-by: alanb, chegar --- jdk/test/ProblemList.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 1f594fe3d3b..92340c6a19a 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -166,6 +166,13 @@ demo/jvmti/hprof/MonitorTest.java generic-all # 8021186 jdk/lambda/vm/DefaultMethodsTest.java generic-all +# 8024423 - JVMTI: GetLoadedClasses doesn't enumerate anonymous classes +demo/jvmti/hprof/HeapAllTest.java generic-all +demo/jvmti/hprof/HeapBinaryFormatTest.java generic-all +demo/jvmti/hprof/HeapDumpTest.java generic-all +demo/jvmti/hprof/OptionsTest.java generic-all +demo/jvmti/hprof/StackMapTableTest.java generic-all + ############################################################################ # jdk_net From 1568ef9e858faf9b996765c090503d5b1d17b3f7 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 10 Sep 2013 17:06:38 +0400 Subject: [PATCH 0282/1294] 7057770: (spec)Scrollbar spec should specify that unit increment & decrement functionality may not be present Reviewed-by: alexsch --- jdk/src/share/classes/java/awt/Scrollbar.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jdk/src/share/classes/java/awt/Scrollbar.java b/jdk/src/share/classes/java/awt/Scrollbar.java index b6a581d96a8..8ecf5783057 100644 --- a/jdk/src/share/classes/java/awt/Scrollbar.java +++ b/jdk/src/share/classes/java/awt/Scrollbar.java @@ -715,6 +715,9 @@ public class Scrollbar extends Component implements Adjustable, Accessible { * The unit increment must be greater than zero. * Attepts to set the unit increment to a value lower than 1 * will result in a value of 1 being set. + *

    + * In some operating systems, this property + * can be ignored by the underlying controls. * * @param v the amount by which to increment or decrement * the scroll bar's value @@ -752,6 +755,9 @@ public class Scrollbar extends Component implements Adjustable, Accessible { * scroll bar, generally through a mouse or keyboard gesture * that the scroll bar receives as an adjustment event. * The unit increment must be greater than zero. + *

    + * In some operating systems, this property + * can be ignored by the underlying controls. * * @return the unit increment of this scroll bar * @see java.awt.Scrollbar#setUnitIncrement From 4ac63f2df40430b2ec25c44c9659661fc2b209cf Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 10 Sep 2013 17:12:32 +0400 Subject: [PATCH 0283/1294] 8024407: [macosx] javax/swing/JScrollBar/7163696/Test7163696.java failed intermittently on macos Reviewed-by: alexsch --- jdk/test/javax/swing/JScrollBar/7163696/Test7163696.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jdk/test/javax/swing/JScrollBar/7163696/Test7163696.java b/jdk/test/javax/swing/JScrollBar/7163696/Test7163696.java index 922bf2e4963..759012ebe74 100644 --- a/jdk/test/javax/swing/JScrollBar/7163696/Test7163696.java +++ b/jdk/test/javax/swing/JScrollBar/7163696/Test7163696.java @@ -59,7 +59,8 @@ public class Test7163696 implements Runnable { UIManager.setLookAndFeel(info.getClassName()); SwingUtilities.invokeAndWait(this); - toolkit.realSync(500); // after creation + toolkit.realSync(); // after creation + Thread.sleep(1000); Point point = this.bar.getLocation(); SwingUtilities.convertPointToScreen(point, this.bar); @@ -69,7 +70,8 @@ public class Test7163696 implements Runnable { robot.mousePress(InputEvent.BUTTON1_MASK); robot.mouseRelease(InputEvent.BUTTON1_MASK); - toolkit.realSync(500); // before validation + toolkit.realSync(); // before validation + Thread.sleep(1000); SwingUtilities.invokeAndWait(this); if (this.bar != null) { From de5e0f4b27daf5e87ef58f3821bf1b35b28561a5 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 10 Sep 2013 16:47:40 +0100 Subject: [PATCH 0284/1294] 8024414: javac, should facilitate the use of the bootstrap compiler for debugging Reviewed-by: jjg --- langtools/make/netbeans/langtools/build.xml | 29 +++++-- .../make/tools/anttasks/SelectToolTask.java | 86 +++++++++++++++---- 2 files changed, 90 insertions(+), 25 deletions(-) diff --git a/langtools/make/netbeans/langtools/build.xml b/langtools/make/netbeans/langtools/build.xml index dd2caf9e3bc..cbb007057cc 100644 --- a/langtools/make/netbeans/langtools/build.xml +++ b/langtools/make/netbeans/langtools/build.xml @@ -1,6 +1,6 @@ @@ -136,9 +145,9 @@ - + - + @@ -207,6 +216,7 @@ @@ -216,6 +226,7 @@ @@ -226,10 +237,12 @@ + + - + diff --git a/langtools/make/tools/anttasks/SelectToolTask.java b/langtools/make/tools/anttasks/SelectToolTask.java index fb2cf49e312..5897398d173 100644 --- a/langtools/make/tools/anttasks/SelectToolTask.java +++ b/langtools/make/tools/anttasks/SelectToolTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ import java.io.Reader; import java.io.Writer; import java.util.ArrayList; import java.util.Arrays; +import java.util.EnumSet; import java.util.List; import java.util.Properties; import javax.swing.JButton; @@ -71,6 +72,31 @@ import org.apache.tools.ant.Task; * is invoked to allow the user to set or reset values for use in property mode. */ public class SelectToolTask extends Task { + + enum ToolChoices { + NONE(""), + JAVAC("javac"), + JAVADOC("javadoc"), + JAVAH("javah"), + JAVAP("javap"); + + String toolName; + boolean bootstrap; + + ToolChoices(String toolName) { + this(toolName, false); + } + + ToolChoices(String toolName, boolean boostrap) { + this.toolName = toolName; + } + + @Override + public String toString() { + return toolName; + } + } + /** * Set the location of the private properties file used to keep the retain * user preferences for this repository. @@ -96,6 +122,14 @@ public class SelectToolTask extends Task { this.argsProperty = argsProperty; } + /** + * Set the name of the property which will be set to the execution args of the + * selected tool, if any. The args default to an empty string. + */ + public void setBootstrapProperty(String bootstrapProperty) { + this.bootstrapProperty = bootstrapProperty; + } + /** * Specify whether or not to pop up a dialog if the user has not specified * a default value for a property. @@ -110,6 +144,7 @@ public class SelectToolTask extends Task { Properties props = readProperties(propertyFile); toolName = props.getProperty("tool.name"); + toolBootstrap = props.getProperty("tool.bootstrap") != null; if (toolName != null) { toolArgs = props.getProperty(toolName + ".args", ""); } @@ -123,6 +158,8 @@ public class SelectToolTask extends Task { // finally, return required values, if any if (toolProperty != null && !(toolName == null || toolName.equals(""))) { p.setProperty(toolProperty, toolName); + if (toolBootstrap) + p.setProperty(bootstrapProperty, "true"); if (argsProperty != null && toolArgs != null) p.setProperty(argsProperty, toolArgs); @@ -134,14 +171,20 @@ public class SelectToolTask extends Task { JOptionPane p = createPane(guiProps); p.createDialog("Select Tool").setVisible(true); - toolName = (String) toolChoice.getSelectedItem(); + toolName = ((ToolChoices)toolChoice.getSelectedItem()).toolName; toolArgs = argsField.getText(); - + toolBootstrap = bootstrapCheckbox.isSelected(); if (defaultCheck.isSelected()) { if (toolName.equals("")) { fileProps.remove("tool.name"); + fileProps.remove("tool.bootstrap"); } else { fileProps.put("tool.name", toolName); + if (toolBootstrap) { + fileProps.put("tool.bootstrap", "true"); + } else { + fileProps.remove("tool.bootstrap"); + } fileProps.put(toolName + ".args", toolArgs); } writeProperties(propertyFile, fileProps); @@ -154,32 +197,38 @@ public class SelectToolTask extends Task { lc.insets.right = 10; lc.insets.bottom = 3; GridBagConstraints fc = new GridBagConstraints(); - fc.anchor = GridBagConstraints.WEST; fc.gridx = 1; - fc.gridwidth = GridBagConstraints.REMAINDER; + fc.gridwidth = GridBagConstraints.NONE; fc.insets.bottom = 3; + JPanel toolPane = new JPanel(new GridBagLayout()); + JLabel toolLabel = new JLabel("Tool:"); body.add(toolLabel, lc); - String[] toolChoices = { "apt", "javac", "javadoc", "javah", "javap" }; - if (true || toolProperty == null) { - // include empty value in setup mode - List l = new ArrayList(Arrays.asList(toolChoices)); - l.add(0, ""); - toolChoices = l.toArray(new String[l.size()]); - } - toolChoice = new JComboBox(toolChoices); + EnumSet toolChoices = toolProperty == null ? + EnumSet.allOf(ToolChoices.class) : EnumSet.range(ToolChoices.JAVAC, ToolChoices.JAVAP); + toolChoice = new JComboBox(toolChoices.toArray()); if (toolName != null) - toolChoice.setSelectedItem(toolName); + toolChoice.setSelectedItem(ToolChoices.valueOf(toolName.toUpperCase())); toolChoice.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { - String tn = (String) e.getItem(); + String tn = ((ToolChoices)e.getItem()).toolName; argsField.setText(getDefaultArgsForTool(props, tn)); if (toolProperty != null) okButton.setEnabled(!tn.equals("")); } }); - body.add(toolChoice, fc); + GridBagConstraints checkConstraint = new GridBagConstraints(); + fc.anchor = GridBagConstraints.EAST; + + GridBagConstraints toolConstraint = new GridBagConstraints(); + fc.anchor = GridBagConstraints.WEST; + + toolPane.add(toolChoice, toolConstraint); + bootstrapCheckbox = new JCheckBox("bootstrap", toolBootstrap); + toolPane.add(bootstrapCheckbox, checkConstraint); + + body.add(toolPane, fc); argsField = new JTextField(getDefaultArgsForTool(props, toolName), 40); if (toolProperty == null || argsProperty != null) { @@ -190,7 +239,7 @@ public class SelectToolTask extends Task { public void focusGained(FocusEvent e) { } public void focusLost(FocusEvent e) { - String toolName = (String) toolChoice.getSelectedItem(); + String toolName = ((ToolChoices)toolChoice.getSelectedItem()).toolName; if (toolName.length() > 0) props.put(toolName + ".args", argsField.getText()); } @@ -271,16 +320,19 @@ public class SelectToolTask extends Task { // Ant task parameters private boolean askIfUnset; private String toolProperty; + private String bootstrapProperty; private String argsProperty; private File propertyFile; // GUI components private JComboBox toolChoice; + private JCheckBox bootstrapCheckbox; private JTextField argsField; private JCheckBox defaultCheck; private JButton okButton; // Result values for the client private String toolName; + private boolean toolBootstrap; private String toolArgs; } From e9128877e71931d06ef3533468ca03fa1c075e1a Mon Sep 17 00:00:00 2001 From: Leonid Romanov Date: Tue, 10 Sep 2013 20:42:15 +0400 Subject: [PATCH 0285/1294] 8003901: [macosx] Need test for JDK-8002114 Reviewed-by: anthony, serb --- .../ActionListenerCalledTwiceTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java b/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java index 4b78bb98a0e..69a42d7834b 100644 --- a/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java +++ b/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java @@ -35,12 +35,13 @@ import java.awt.event.*; import javax.swing.*; public class ActionListenerCalledTwiceTest { - static String menuItems[] = { "Item1", "Item2", "Item3", "Item4" }; + static String menuItems[] = { "Item1", "Item2", "Item3", "Item4", "Item5" }; static KeyStroke keyStrokes[] = { KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.META_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.SHIFT_MASK), - KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.META_MASK) + KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.META_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_MASK) }; static volatile int listenerCallCounter = 0; From 12d6f7df9b842422444c3245a2f39959f64b1f55 Mon Sep 17 00:00:00 2001 From: James Laskey Date: Tue, 10 Sep 2013 14:21:28 -0300 Subject: [PATCH 0286/1294] 8024539: FX Libraries update missing file Reviewed-by: sundar --- .../internal/runtime/resources/fx/controls.js | 244 +----------------- 1 file changed, 5 insertions(+), 239 deletions(-) diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/controls.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/controls.js index 6a2a89c400c..ca3f284c8e3 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/controls.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/controls.js @@ -23,242 +23,8 @@ * questions. */ -AreaChart = Java.type("javafx.scene.chart.AreaChart"); -AreaChartBuilder = Java.type("javafx.scene.chart.AreaChartBuilder"); -Axis = Java.type("javafx.scene.chart.Axis"); -Axis$TickMark = Java.type("javafx.scene.chart.Axis$TickMark"); -AxisBuilder = Java.type("javafx.scene.chart.AxisBuilder"); -BarChart = Java.type("javafx.scene.chart.BarChart"); -BarChartBuilder = Java.type("javafx.scene.chart.BarChartBuilder"); -BubbleChart = Java.type("javafx.scene.chart.BubbleChart"); -BubbleChartBuilder = Java.type("javafx.scene.chart.BubbleChartBuilder"); -CategoryAxis = Java.type("javafx.scene.chart.CategoryAxis"); -CategoryAxisBuilder = Java.type("javafx.scene.chart.CategoryAxisBuilder"); -Chart = Java.type("javafx.scene.chart.Chart"); -ChartBuilder = Java.type("javafx.scene.chart.ChartBuilder"); -LineChart = Java.type("javafx.scene.chart.LineChart"); -LineChartBuilder = Java.type("javafx.scene.chart.LineChartBuilder"); -NumberAxis = Java.type("javafx.scene.chart.NumberAxis"); -NumberAxis$DefaultFormatter = Java.type("javafx.scene.chart.NumberAxis$DefaultFormatter"); -NumberAxisBuilder = Java.type("javafx.scene.chart.NumberAxisBuilder"); -PieChart = Java.type("javafx.scene.chart.PieChart"); -PieChart$Data = Java.type("javafx.scene.chart.PieChart$Data"); -PieChartBuilder = Java.type("javafx.scene.chart.PieChartBuilder"); -ScatterChart = Java.type("javafx.scene.chart.ScatterChart"); -ScatterChartBuilder = Java.type("javafx.scene.chart.ScatterChartBuilder"); -StackedAreaChart = Java.type("javafx.scene.chart.StackedAreaChart"); -StackedAreaChartBuilder = Java.type("javafx.scene.chart.StackedAreaChartBuilder"); -StackedBarChart = Java.type("javafx.scene.chart.StackedBarChart"); -StackedBarChartBuilder = Java.type("javafx.scene.chart.StackedBarChartBuilder"); -ValueAxis = Java.type("javafx.scene.chart.ValueAxis"); -ValueAxisBuilder = Java.type("javafx.scene.chart.ValueAxisBuilder"); -XYChart = Java.type("javafx.scene.chart.XYChart"); -XYChart$Data = Java.type("javafx.scene.chart.XYChart$Data"); -XYChart$Series = Java.type("javafx.scene.chart.XYChart$Series"); -XYChartBuilder = Java.type("javafx.scene.chart.XYChartBuilder"); -Accordion = Java.type("javafx.scene.control.Accordion"); -AccordionBuilder = Java.type("javafx.scene.control.AccordionBuilder"); -Button = Java.type("javafx.scene.control.Button"); -ButtonBase = Java.type("javafx.scene.control.ButtonBase"); -ButtonBaseBuilder = Java.type("javafx.scene.control.ButtonBaseBuilder"); -ButtonBuilder = Java.type("javafx.scene.control.ButtonBuilder"); -Cell = Java.type("javafx.scene.control.Cell"); -CheckBoxListCell = Java.type("javafx.scene.control.cell.CheckBoxListCell"); -CheckBoxListCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxListCellBuilder"); -CheckBoxTableCell = Java.type("javafx.scene.control.cell.CheckBoxTableCell"); -CheckBoxTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTableCellBuilder"); -CheckBoxTreeCell = Java.type("javafx.scene.control.cell.CheckBoxTreeCell"); -CheckBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeCellBuilder"); -CheckBoxTreeTableCell = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCell"); -//CheckBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCellBuilder"); -ChoiceBoxListCell = Java.type("javafx.scene.control.cell.ChoiceBoxListCell"); -ChoiceBoxListCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxListCellBuilder"); -ChoiceBoxTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTableCell"); -ChoiceBoxTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTableCellBuilder"); -ChoiceBoxTreeCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCell"); -ChoiceBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCellBuilder"); -ChoiceBoxTreeTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCell"); -//ChoiceBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCellBuilder"); -ComboBoxListCell = Java.type("javafx.scene.control.cell.ComboBoxListCell"); -ComboBoxListCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxListCellBuilder"); -ComboBoxTableCell = Java.type("javafx.scene.control.cell.ComboBoxTableCell"); -ComboBoxTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTableCellBuilder"); -ComboBoxTreeCell = Java.type("javafx.scene.control.cell.ComboBoxTreeCell"); -ComboBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeCellBuilder"); -ComboBoxTreeTableCell = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCell"); -//ComboBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCellBuilder"); -MapValueFactory = Java.type("javafx.scene.control.cell.MapValueFactory"); -ProgressBarTableCell = Java.type("javafx.scene.control.cell.ProgressBarTableCell"); -ProgressBarTreeTableCell = Java.type("javafx.scene.control.cell.ProgressBarTreeTableCell"); -PropertyValueFactory = Java.type("javafx.scene.control.cell.PropertyValueFactory"); -PropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.PropertyValueFactoryBuilder"); -TextFieldListCell = Java.type("javafx.scene.control.cell.TextFieldListCell"); -TextFieldListCellBuilder = Java.type("javafx.scene.control.cell.TextFieldListCellBuilder"); -TextFieldTableCell = Java.type("javafx.scene.control.cell.TextFieldTableCell"); -TextFieldTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTableCellBuilder"); -TextFieldTreeCell = Java.type("javafx.scene.control.cell.TextFieldTreeCell"); -TextFieldTreeCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeCellBuilder"); -TextFieldTreeTableCell = Java.type("javafx.scene.control.cell.TextFieldTreeTableCell"); -//TextFieldTreeTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeTableCellBuilder"); -TreeItemPropertyValueFactory = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactory"); -//TreeItemPropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactoryBuilder"); -CellBuilder = Java.type("javafx.scene.control.CellBuilder"); -CheckBox = Java.type("javafx.scene.control.CheckBox"); -CheckBoxBuilder = Java.type("javafx.scene.control.CheckBoxBuilder"); -CheckBoxTreeItem = Java.type("javafx.scene.control.CheckBoxTreeItem"); -CheckBoxTreeItem$TreeModificationEvent = Java.type("javafx.scene.control.CheckBoxTreeItem$TreeModificationEvent"); -CheckBoxTreeItemBuilder = Java.type("javafx.scene.control.CheckBoxTreeItemBuilder"); -CheckMenuItem = Java.type("javafx.scene.control.CheckMenuItem"); -CheckMenuItemBuilder = Java.type("javafx.scene.control.CheckMenuItemBuilder"); -ChoiceBox = Java.type("javafx.scene.control.ChoiceBox"); -ChoiceBoxBuilder = Java.type("javafx.scene.control.ChoiceBoxBuilder"); -ColorPicker = Java.type("javafx.scene.control.ColorPicker"); -ColorPickerBuilder = Java.type("javafx.scene.control.ColorPickerBuilder"); -ComboBox = Java.type("javafx.scene.control.ComboBox"); -ComboBoxBase = Java.type("javafx.scene.control.ComboBoxBase"); -ComboBoxBaseBuilder = Java.type("javafx.scene.control.ComboBoxBaseBuilder"); -ComboBoxBuilder = Java.type("javafx.scene.control.ComboBoxBuilder"); -ContentDisplay = Java.type("javafx.scene.control.ContentDisplay"); -ContextMenu = Java.type("javafx.scene.control.ContextMenu"); -ContextMenuBuilder = Java.type("javafx.scene.control.ContextMenuBuilder"); -Control = Java.type("javafx.scene.control.Control"); -ControlBuilder = Java.type("javafx.scene.control.ControlBuilder"); -CustomMenuItem = Java.type("javafx.scene.control.CustomMenuItem"); -CustomMenuItemBuilder = Java.type("javafx.scene.control.CustomMenuItemBuilder"); -FocusModel = Java.type("javafx.scene.control.FocusModel"); -Hyperlink = Java.type("javafx.scene.control.Hyperlink"); -HyperlinkBuilder = Java.type("javafx.scene.control.HyperlinkBuilder"); -IndexedCell = Java.type("javafx.scene.control.IndexedCell"); -IndexedCellBuilder = Java.type("javafx.scene.control.IndexedCellBuilder"); -IndexRange = Java.type("javafx.scene.control.IndexRange"); -IndexRangeBuilder = Java.type("javafx.scene.control.IndexRangeBuilder"); -Label = Java.type("javafx.scene.control.Label"); -LabelBuilder = Java.type("javafx.scene.control.LabelBuilder"); -Labeled = Java.type("javafx.scene.control.Labeled"); -LabeledBuilder = Java.type("javafx.scene.control.LabeledBuilder"); -ListCell = Java.type("javafx.scene.control.ListCell"); -ListCellBuilder = Java.type("javafx.scene.control.ListCellBuilder"); -ListView = Java.type("javafx.scene.control.ListView"); -ListView$EditEvent = Java.type("javafx.scene.control.ListView$EditEvent"); -ListViewBuilder = Java.type("javafx.scene.control.ListViewBuilder"); -Menu = Java.type("javafx.scene.control.Menu"); -MenuBar = Java.type("javafx.scene.control.MenuBar"); -MenuBarBuilder = Java.type("javafx.scene.control.MenuBarBuilder"); -MenuBuilder = Java.type("javafx.scene.control.MenuBuilder"); -MenuButton = Java.type("javafx.scene.control.MenuButton"); -MenuButtonBuilder = Java.type("javafx.scene.control.MenuButtonBuilder"); -MenuItem = Java.type("javafx.scene.control.MenuItem"); -MenuItemBuilder = Java.type("javafx.scene.control.MenuItemBuilder"); -MultipleSelectionModel = Java.type("javafx.scene.control.MultipleSelectionModel"); -MultipleSelectionModelBuilder = Java.type("javafx.scene.control.MultipleSelectionModelBuilder"); -OverrunStyle = Java.type("javafx.scene.control.OverrunStyle"); -Pagination = Java.type("javafx.scene.control.Pagination"); -PaginationBuilder = Java.type("javafx.scene.control.PaginationBuilder"); -PasswordField = Java.type("javafx.scene.control.PasswordField"); -PasswordFieldBuilder = Java.type("javafx.scene.control.PasswordFieldBuilder"); -PopupControl = Java.type("javafx.scene.control.PopupControl"); -PopupControlBuilder = Java.type("javafx.scene.control.PopupControlBuilder"); -ProgressBar = Java.type("javafx.scene.control.ProgressBar"); -ProgressBarBuilder = Java.type("javafx.scene.control.ProgressBarBuilder"); -ProgressIndicator = Java.type("javafx.scene.control.ProgressIndicator"); -ProgressIndicatorBuilder = Java.type("javafx.scene.control.ProgressIndicatorBuilder"); -RadioButton = Java.type("javafx.scene.control.RadioButton"); -RadioButtonBuilder = Java.type("javafx.scene.control.RadioButtonBuilder"); -RadioMenuItem = Java.type("javafx.scene.control.RadioMenuItem"); -RadioMenuItemBuilder = Java.type("javafx.scene.control.RadioMenuItemBuilder"); -ResizeFeaturesBase = Java.type("javafx.scene.control.ResizeFeaturesBase"); -//ResizeFeaturesBaseBuilder = Java.type("javafx.scene.control.ResizeFeaturesBaseBuilder"); -ScrollBar = Java.type("javafx.scene.control.ScrollBar"); -ScrollBarBuilder = Java.type("javafx.scene.control.ScrollBarBuilder"); -ScrollPane = Java.type("javafx.scene.control.ScrollPane"); -ScrollPane$ScrollBarPolicy = Java.type("javafx.scene.control.ScrollPane$ScrollBarPolicy"); -ScrollPaneBuilder = Java.type("javafx.scene.control.ScrollPaneBuilder"); -ScrollToEvent = Java.type("javafx.scene.control.ScrollToEvent"); -SelectionMode = Java.type("javafx.scene.control.SelectionMode"); -SelectionModel = Java.type("javafx.scene.control.SelectionModel"); -Separator = Java.type("javafx.scene.control.Separator"); -SeparatorBuilder = Java.type("javafx.scene.control.SeparatorBuilder"); -SeparatorMenuItem = Java.type("javafx.scene.control.SeparatorMenuItem"); -SeparatorMenuItemBuilder = Java.type("javafx.scene.control.SeparatorMenuItemBuilder"); -SingleSelectionModel = Java.type("javafx.scene.control.SingleSelectionModel"); -Skin = Java.type("javafx.scene.control.Skin"); -SkinBase = Java.type("javafx.scene.control.SkinBase"); -//SkinBaseBuilder = Java.type("javafx.scene.control.SkinBaseBuilder"); -Skinnable = Java.type("javafx.scene.control.Skinnable"); -Slider = Java.type("javafx.scene.control.Slider"); -SliderBuilder = Java.type("javafx.scene.control.SliderBuilder"); -SortEvent = Java.type("javafx.scene.control.SortEvent"); -SplitMenuButton = Java.type("javafx.scene.control.SplitMenuButton"); -SplitMenuButtonBuilder = Java.type("javafx.scene.control.SplitMenuButtonBuilder"); -SplitPane = Java.type("javafx.scene.control.SplitPane"); -SplitPane$Divider = Java.type("javafx.scene.control.SplitPane$Divider"); -SplitPaneBuilder = Java.type("javafx.scene.control.SplitPaneBuilder"); -Tab = Java.type("javafx.scene.control.Tab"); -TabBuilder = Java.type("javafx.scene.control.TabBuilder"); -TableCell = Java.type("javafx.scene.control.TableCell"); -TableCellBuilder = Java.type("javafx.scene.control.TableCellBuilder"); -TableColumn = Java.type("javafx.scene.control.TableColumn"); -TableColumn$CellDataFeatures = Java.type("javafx.scene.control.TableColumn$CellDataFeatures"); -TableColumn$CellEditEvent = Java.type("javafx.scene.control.TableColumn$CellEditEvent"); -TableColumn$SortType = Java.type("javafx.scene.control.TableColumn$SortType"); -TableColumnBase = Java.type("javafx.scene.control.TableColumnBase"); -//TableColumnBaseBuilder = Java.type("javafx.scene.control.TableColumnBaseBuilder"); -TableColumnBuilder = Java.type("javafx.scene.control.TableColumnBuilder"); -TableFocusModel = Java.type("javafx.scene.control.TableFocusModel"); -TablePosition = Java.type("javafx.scene.control.TablePosition"); -TablePositionBase = Java.type("javafx.scene.control.TablePositionBase"); -TableRow = Java.type("javafx.scene.control.TableRow"); -TableRowBuilder = Java.type("javafx.scene.control.TableRowBuilder"); -TableSelectionModel = Java.type("javafx.scene.control.TableSelectionModel"); -//TableSelectionModelBuilder = Java.type("javafx.scene.control.TableSelectionModelBuilder"); -TableView = Java.type("javafx.scene.control.TableView"); -TableView$ResizeFeatures = Java.type("javafx.scene.control.TableView$ResizeFeatures"); -TableView$TableViewFocusModel = Java.type("javafx.scene.control.TableView$TableViewFocusModel"); -TableView$TableViewSelectionModel = Java.type("javafx.scene.control.TableView$TableViewSelectionModel"); -TableViewBuilder = Java.type("javafx.scene.control.TableViewBuilder"); -TabPane = Java.type("javafx.scene.control.TabPane"); -TabPane$TabClosingPolicy = Java.type("javafx.scene.control.TabPane$TabClosingPolicy"); -TabPaneBuilder = Java.type("javafx.scene.control.TabPaneBuilder"); -TextArea = Java.type("javafx.scene.control.TextArea"); -TextAreaBuilder = Java.type("javafx.scene.control.TextAreaBuilder"); -TextField = Java.type("javafx.scene.control.TextField"); -TextFieldBuilder = Java.type("javafx.scene.control.TextFieldBuilder"); -TextInputControl = Java.type("javafx.scene.control.TextInputControl"); -TextInputControl$Content = Java.type("javafx.scene.control.TextInputControl$Content"); -TextInputControlBuilder = Java.type("javafx.scene.control.TextInputControlBuilder"); -TitledPane = Java.type("javafx.scene.control.TitledPane"); -TitledPaneBuilder = Java.type("javafx.scene.control.TitledPaneBuilder"); -Toggle = Java.type("javafx.scene.control.Toggle"); -ToggleButton = Java.type("javafx.scene.control.ToggleButton"); -ToggleButtonBuilder = Java.type("javafx.scene.control.ToggleButtonBuilder"); -ToggleGroup = Java.type("javafx.scene.control.ToggleGroup"); -ToggleGroupBuilder = Java.type("javafx.scene.control.ToggleGroupBuilder"); -ToolBar = Java.type("javafx.scene.control.ToolBar"); -ToolBarBuilder = Java.type("javafx.scene.control.ToolBarBuilder"); -Tooltip = Java.type("javafx.scene.control.Tooltip"); -TooltipBuilder = Java.type("javafx.scene.control.TooltipBuilder"); -TreeCell = Java.type("javafx.scene.control.TreeCell"); -TreeCellBuilder = Java.type("javafx.scene.control.TreeCellBuilder"); -TreeItem = Java.type("javafx.scene.control.TreeItem"); -TreeItem$TreeModificationEvent = Java.type("javafx.scene.control.TreeItem$TreeModificationEvent"); -TreeItemBuilder = Java.type("javafx.scene.control.TreeItemBuilder"); -TreeSortMode = Java.type("javafx.scene.control.TreeSortMode"); -TreeTableCell = Java.type("javafx.scene.control.TreeTableCell"); -//TreeTableCellBuilder = Java.type("javafx.scene.control.TreeTableCellBuilder"); -TreeTableColumn = Java.type("javafx.scene.control.TreeTableColumn"); -TreeTableColumn$CellDataFeatures = Java.type("javafx.scene.control.TreeTableColumn$CellDataFeatures"); -TreeTableColumn$CellEditEvent = Java.type("javafx.scene.control.TreeTableColumn$CellEditEvent"); -TreeTableColumn$SortType = Java.type("javafx.scene.control.TreeTableColumn$SortType"); -//TreeTableColumnBuilder = Java.type("javafx.scene.control.TreeTableColumnBuilder"); -TreeTablePosition = Java.type("javafx.scene.control.TreeTablePosition"); -TreeTableRow = Java.type("javafx.scene.control.TreeTableRow"); -//TreeTableRowBuilder = Java.type("javafx.scene.control.TreeTableRowBuilder"); -TreeTableView = Java.type("javafx.scene.control.TreeTableView"); -TreeTableView$EditEvent = Java.type("javafx.scene.control.TreeTableView$EditEvent"); -TreeTableView$ResizeFeatures = Java.type("javafx.scene.control.TreeTableView$ResizeFeatures"); -TreeTableView$TreeTableViewFocusModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewFocusModel"); -TreeTableView$TreeTableViewSelectionModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewSelectionModel"); -//TreeTableViewBuilder = Java.type("javafx.scene.control.TreeTableViewBuilder"); -TreeView = Java.type("javafx.scene.control.TreeView"); -TreeView$EditEvent = Java.type("javafx.scene.control.TreeView$EditEvent"); -TreeViewBuilder = Java.type("javafx.scene.control.TreeViewBuilder"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_CONTROLS_CLASSES); From 47f48cad92630ada6ccd34d7d7aa2b6191cb1bf9 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Tue, 10 Sep 2013 21:54:14 +0400 Subject: [PATCH 0287/1294] 8024511: Crash during color profile destruction Reviewed-by: vadim, prr --- .../share/native/sun/java2d/cmm/lcms/LCMS.c | 2 +- .../cmm/ProfileOp/DisposalCrashTest.java | 83 +++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 jdk/test/sun/java2d/cmm/ProfileOp/DisposalCrashTest.java diff --git a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c index 13030cc41d5..b2c4fce4229 100644 --- a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c @@ -307,7 +307,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative if (sProf.lcmsPf != NULL) { // register the disposer record sProf.lcmsPf->pf = pf; - Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sProf.j); + Disposer_AddRecord(env, disposerRef, LCMS_freeProfile, sProf.j); } else { cmsCloseProfile(pf); } diff --git a/jdk/test/sun/java2d/cmm/ProfileOp/DisposalCrashTest.java b/jdk/test/sun/java2d/cmm/ProfileOp/DisposalCrashTest.java new file mode 100644 index 00000000000..ab8527d76da --- /dev/null +++ b/jdk/test/sun/java2d/cmm/ProfileOp/DisposalCrashTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013, 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 8024511 + * @summary Verifies that instances of color profiles are destroyed correctly. + * A crash during profile destruction indicates failure. + * + * @run main DisposalCrashTest + */ + +import static java.awt.color.ColorSpace.*; +import java.awt.color.ICC_Profile; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.Vector; + +public class DisposalCrashTest { + + static final ReferenceQueue queue = new ReferenceQueue<>(); + static final Vector> v = new Vector<>(); + + public static void main(String[] args) { + int[] ids = new int[]{ + CS_sRGB, CS_CIEXYZ, CS_GRAY, CS_LINEAR_RGB, CS_PYCC + }; + + for (int id : ids) { + ICC_Profile p = getCopyOf(id); + } + + while (!v.isEmpty()) { + System.gc(); + System.out.println("."); + try { + Thread.sleep(500); + } catch (InterruptedException e) {}; + + final Reference ref = queue.poll(); + System.out.println("Got reference: " + ref); + + v.remove(ref); + } + + System.out.println("Test PASSED."); + } + + private static ICC_Profile getCopyOf(int id) { + ICC_Profile std = ICC_Profile.getInstance(id); + + byte[] data = std.getData(); + + ICC_Profile p = ICC_Profile.getInstance(data); + + WeakReference ref = new WeakReference<>(p, queue); + + v.add(ref); + + return p; + } +} From f0e77ac67f03c437020a14081b54bb2cce168ded Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Tue, 10 Sep 2013 14:51:48 -0700 Subject: [PATCH 0288/1294] 8001107: @Stable annotation for constant folding of lazily evaluated variables Co-authored-by: John Rose Reviewed-by: rbackman, twisti, kvn --- hotspot/src/share/vm/ci/ciArray.cpp | 79 ++++++++++++++++ hotspot/src/share/vm/ci/ciArray.hpp | 19 +++- hotspot/src/share/vm/ci/ciConstant.hpp | 15 +++- hotspot/src/share/vm/ci/ciField.cpp | 20 +++-- hotspot/src/share/vm/ci/ciField.hpp | 6 +- hotspot/src/share/vm/ci/ciFlags.hpp | 1 + hotspot/src/share/vm/ci/ciInstance.cpp | 2 + hotspot/src/share/vm/ci/ciTypeArray.cpp | 7 +- .../share/vm/classfile/classFileParser.cpp | 6 ++ .../share/vm/classfile/classFileParser.hpp | 18 +++- hotspot/src/share/vm/classfile/vmSymbols.hpp | 1 + hotspot/src/share/vm/oops/fieldInfo.hpp | 8 ++ hotspot/src/share/vm/opto/c2_globals.hpp | 3 + hotspot/src/share/vm/opto/compile.cpp | 17 +++- hotspot/src/share/vm/opto/compile.hpp | 12 ++- hotspot/src/share/vm/opto/graphKit.cpp | 18 ++-- hotspot/src/share/vm/opto/graphKit.hpp | 3 + hotspot/src/share/vm/opto/library_call.cpp | 5 ++ hotspot/src/share/vm/opto/memnode.cpp | 90 +++++++++++++++---- hotspot/src/share/vm/opto/parse.hpp | 2 +- hotspot/src/share/vm/opto/parse3.cpp | 71 +++++++-------- hotspot/src/share/vm/opto/type.cpp | 79 ++++++++++++++-- hotspot/src/share/vm/opto/type.hpp | 15 +++- hotspot/src/share/vm/runtime/globals.hpp | 3 + .../src/share/vm/utilities/accessFlags.hpp | 3 + 25 files changed, 419 insertions(+), 84 deletions(-) diff --git a/hotspot/src/share/vm/ci/ciArray.cpp b/hotspot/src/share/vm/ci/ciArray.cpp index 584b1aeb50f..fdcc63a0dec 100644 --- a/hotspot/src/share/vm/ci/ciArray.cpp +++ b/hotspot/src/share/vm/ci/ciArray.cpp @@ -24,13 +24,92 @@ #include "precompiled.hpp" #include "ci/ciArray.hpp" +#include "ci/ciArrayKlass.hpp" +#include "ci/ciConstant.hpp" #include "ci/ciKlass.hpp" #include "ci/ciUtilities.hpp" +#include "oops/objArrayOop.hpp" +#include "oops/typeArrayOop.hpp" // ciArray // // This class represents an arrayOop in the HotSpot virtual // machine. +static BasicType fixup_element_type(BasicType bt) { + if (bt == T_ARRAY) return T_OBJECT; + if (bt == T_BOOLEAN) return T_BYTE; + return bt; +} + +ciConstant ciArray::element_value_impl(BasicType elembt, + arrayOop ary, + int index) { + if (ary == NULL) + return ciConstant(); + assert(ary->is_array(), ""); + if (index < 0 || index >= ary->length()) + return ciConstant(); + ArrayKlass* ak = (ArrayKlass*) ary->klass(); + BasicType abt = ak->element_type(); + if (fixup_element_type(elembt) != + fixup_element_type(abt)) + return ciConstant(); + switch (elembt) { + case T_ARRAY: + case T_OBJECT: + { + assert(ary->is_objArray(), ""); + objArrayOop objary = (objArrayOop) ary; + oop elem = objary->obj_at(index); + ciEnv* env = CURRENT_ENV; + ciObject* box = env->get_object(elem); + return ciConstant(T_OBJECT, box); + } + } + assert(ary->is_typeArray(), ""); + typeArrayOop tary = (typeArrayOop) ary; + jint value = 0; + switch (elembt) { + case T_LONG: return ciConstant(tary->long_at(index)); + case T_FLOAT: return ciConstant(tary->float_at(index)); + case T_DOUBLE: return ciConstant(tary->double_at(index)); + default: return ciConstant(); + case T_BYTE: value = tary->byte_at(index); break; + case T_BOOLEAN: value = tary->byte_at(index) & 1; break; + case T_SHORT: value = tary->short_at(index); break; + case T_CHAR: value = tary->char_at(index); break; + case T_INT: value = tary->int_at(index); break; + } + return ciConstant(elembt, value); +} + +// ------------------------------------------------------------------ +// ciArray::element_value +// +// Current value of an element. +// Returns T_ILLEGAL if there is no element at the given index. +ciConstant ciArray::element_value(int index) { + BasicType elembt = element_basic_type(); + GUARDED_VM_ENTRY( + return element_value_impl(elembt, get_arrayOop(), index); + ) +} + +// ------------------------------------------------------------------ +// ciArray::element_value_by_offset +// +// Current value of an element at the specified offset. +// Returns T_ILLEGAL if there is no element at the given offset. +ciConstant ciArray::element_value_by_offset(intptr_t element_offset) { + BasicType elembt = element_basic_type(); + intptr_t shift = exact_log2(type2aelembytes(elembt)); + intptr_t header = arrayOopDesc::base_offset_in_bytes(elembt); + intptr_t index = (element_offset - header) >> shift; + intptr_t offset = header + ((intptr_t)index << shift); + if (offset != element_offset || index != (jint)index) + return ciConstant(); + return element_value((jint) index); +} // ------------------------------------------------------------------ // ciArray::print_impl diff --git a/hotspot/src/share/vm/ci/ciArray.hpp b/hotspot/src/share/vm/ci/ciArray.hpp index 440e407a510..c5c86265d61 100644 --- a/hotspot/src/share/vm/ci/ciArray.hpp +++ b/hotspot/src/share/vm/ci/ciArray.hpp @@ -25,6 +25,8 @@ #ifndef SHARE_VM_CI_CIARRAY_HPP #define SHARE_VM_CI_CIARRAY_HPP +#include "ci/ciArrayKlass.hpp" +#include "ci/ciConstant.hpp" #include "ci/ciObject.hpp" #include "oops/arrayOop.hpp" #include "oops/objArrayOop.hpp" @@ -45,15 +47,30 @@ protected: ciArray(ciKlass* klass, int len) : ciObject(klass), _length(len) {} - arrayOop get_arrayOop() { return (arrayOop)get_oop(); } + arrayOop get_arrayOop() const { return (arrayOop)get_oop(); } const char* type_string() { return "ciArray"; } void print_impl(outputStream* st); + ciConstant element_value_impl(BasicType elembt, arrayOop ary, int index); + public: int length() { return _length; } + // Convenience routines. + ciArrayKlass* array_type() { return klass()->as_array_klass(); } + ciType* element_type() { return array_type()->element_type(); } + BasicType element_basic_type() { return element_type()->basic_type(); } + + // Current value of an element. + // Returns T_ILLEGAL if there is no element at the given index. + ciConstant element_value(int index); + + // Current value of an element at the specified offset. + // Returns T_ILLEGAL if there is no element at the given offset. + ciConstant element_value_by_offset(intptr_t element_offset); + // What kind of ciObject is this? bool is_array() { return true; } bool is_java_object() { return true; } diff --git a/hotspot/src/share/vm/ci/ciConstant.hpp b/hotspot/src/share/vm/ci/ciConstant.hpp index 8cdc893fd2b..7a72a7de1e5 100644 --- a/hotspot/src/share/vm/ci/ciConstant.hpp +++ b/hotspot/src/share/vm/ci/ciConstant.hpp @@ -41,7 +41,6 @@ private: union { jint _int; jlong _long; - jint _long_half[2]; jfloat _float; jdouble _double; ciObject* _object; @@ -111,6 +110,20 @@ public: return _value._object; } + bool is_null_or_zero() const { + if (!is_java_primitive(basic_type())) { + return as_object()->is_null_object(); + } else if (type2size[basic_type()] == 1) { + // treat float bits as int, to avoid comparison with -0 and NaN + return (_value._int == 0); + } else if (type2size[basic_type()] == 2) { + // treat double bits as long, to avoid comparison with -0 and NaN + return (_value._long == 0); + } else { + return false; + } + } + // Debugging output void print(); }; diff --git a/hotspot/src/share/vm/ci/ciField.cpp b/hotspot/src/share/vm/ci/ciField.cpp index fe967554c3a..1a711ae522a 100644 --- a/hotspot/src/share/vm/ci/ciField.cpp +++ b/hotspot/src/share/vm/ci/ciField.cpp @@ -189,12 +189,14 @@ void ciField::initialize_from(fieldDescriptor* fd) { _holder = CURRENT_ENV->get_instance_klass(fd->field_holder()); // Check to see if the field is constant. - if (_holder->is_initialized() && this->is_final()) { + bool is_final = this->is_final(); + bool is_stable = FoldStableValues && this->is_stable(); + if (_holder->is_initialized() && (is_final || is_stable)) { if (!this->is_static()) { // A field can be constant if it's a final static field or if // it's a final non-static field of a trusted class (classes in // java.lang.invoke and sun.invoke packages and subpackages). - if (trust_final_non_static_fields(_holder)) { + if (is_stable || trust_final_non_static_fields(_holder)) { _is_constant = true; return; } @@ -227,7 +229,6 @@ void ciField::initialize_from(fieldDescriptor* fd) { Handle mirror = k->java_mirror(); - _is_constant = true; switch(type()->basic_type()) { case T_BYTE: _constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset)); @@ -273,6 +274,12 @@ void ciField::initialize_from(fieldDescriptor* fd) { } } } + if (is_stable && _constant_value.is_null_or_zero()) { + // It is not a constant after all; treat it as uninitialized. + _is_constant = false; + } else { + _is_constant = true; + } } else { _is_constant = false; } @@ -373,8 +380,11 @@ void ciField::print() { tty->print(" signature="); _signature->print_symbol(); tty->print(" offset=%d type=", _offset); - if (_type != NULL) _type->print_name(); - else tty->print("(reference)"); + if (_type != NULL) + _type->print_name(); + else + tty->print("(reference)"); + tty->print(" flags=%04x", flags().as_int()); tty->print(" is_constant=%s", bool_to_str(_is_constant)); if (_is_constant && is_static()) { tty->print(" constant_value="); diff --git a/hotspot/src/share/vm/ci/ciField.hpp b/hotspot/src/share/vm/ci/ciField.hpp index ff96c99313c..81af9ca79a9 100644 --- a/hotspot/src/share/vm/ci/ciField.hpp +++ b/hotspot/src/share/vm/ci/ciField.hpp @@ -139,7 +139,10 @@ public: // non-constant fields. These are java.lang.System.in // and java.lang.System.out. Abomination. // - // Note: the check for case 4 is not yet implemented. + // A field is also considered constant if it is marked @Stable + // and is non-null (or non-zero, if a primitive). + // For non-static fields, the null/zero check must be + // arranged by the user, as constant_value().is_null_or_zero(). bool is_constant() { return _is_constant; } // Get the constant value of this field. @@ -173,6 +176,7 @@ public: bool is_protected () { return flags().is_protected(); } bool is_static () { return flags().is_static(); } bool is_final () { return flags().is_final(); } + bool is_stable () { return flags().is_stable(); } bool is_volatile () { return flags().is_volatile(); } bool is_transient () { return flags().is_transient(); } diff --git a/hotspot/src/share/vm/ci/ciFlags.hpp b/hotspot/src/share/vm/ci/ciFlags.hpp index 6dc50d25a60..87e19466f27 100644 --- a/hotspot/src/share/vm/ci/ciFlags.hpp +++ b/hotspot/src/share/vm/ci/ciFlags.hpp @@ -59,6 +59,7 @@ public: bool is_interface () const { return (_flags & JVM_ACC_INTERFACE ) != 0; } bool is_abstract () const { return (_flags & JVM_ACC_ABSTRACT ) != 0; } bool is_strict () const { return (_flags & JVM_ACC_STRICT ) != 0; } + bool is_stable () const { return (_flags & JVM_ACC_FIELD_STABLE) != 0; } // Conversion jint as_int() { return _flags; } diff --git a/hotspot/src/share/vm/ci/ciInstance.cpp b/hotspot/src/share/vm/ci/ciInstance.cpp index a74eb04f4a7..8b48b1b3706 100644 --- a/hotspot/src/share/vm/ci/ciInstance.cpp +++ b/hotspot/src/share/vm/ci/ciInstance.cpp @@ -127,6 +127,8 @@ ciConstant ciInstance::field_value(ciField* field) { ciConstant ciInstance::field_value_by_offset(int field_offset) { ciInstanceKlass* ik = klass()->as_instance_klass(); ciField* field = ik->get_field_by_offset(field_offset, false); + if (field == NULL) + return ciConstant(); // T_ILLEGAL return field_value(field); } diff --git a/hotspot/src/share/vm/ci/ciTypeArray.cpp b/hotspot/src/share/vm/ci/ciTypeArray.cpp index d4a6eff6f41..2d013e21c0e 100644 --- a/hotspot/src/share/vm/ci/ciTypeArray.cpp +++ b/hotspot/src/share/vm/ci/ciTypeArray.cpp @@ -39,5 +39,10 @@ jchar ciTypeArray::char_at(int index) { VM_ENTRY_MARK; assert(index >= 0 && index < length(), "out of range"); - return get_typeArrayOop()->char_at(index); + jchar c = get_typeArrayOop()->char_at(index); +#ifdef ASSERT + jchar d = element_value(index).as_char(); + assert(c == d, ""); +#endif //ASSERT + return c; } diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 0705c5f14d6..8972bceb434 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -1774,6 +1774,10 @@ ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_d if (_location != _in_method) break; // only allow for methods if (!privileged) break; // only allow in privileged code return _method_LambdaForm_Hidden; + case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_invoke_Stable_signature): + if (_location != _in_field) break; // only allow for fields + if (!privileged) break; // only allow in privileged code + return _field_Stable; case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_misc_Contended_signature): if (_location != _in_field && _location != _in_class) break; // only allow for fields and classes if (!EnableContended || (RestrictContended && !privileged)) break; // honor privileges @@ -1786,6 +1790,8 @@ ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_d void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) { if (is_contended()) f->set_contended_group(contended_group()); + if (is_stable()) + f->set_stable(true); } ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector() { diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp index 1b5ed30c5a6..02a4ce20dd3 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.hpp +++ b/hotspot/src/share/vm/classfile/classFileParser.hpp @@ -125,6 +125,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { _method_LambdaForm_Compiled, _method_LambdaForm_Hidden, _sun_misc_Contended, + _field_Stable, _annotation_LIMIT }; const Location _location; @@ -143,14 +144,23 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob"); _annotations_present |= nth_bit((int)id); } + + void remove_annotation(ID id) { + assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob"); + _annotations_present &= ~nth_bit((int)id); + } + // Report if the annotation is present. - bool has_any_annotations() { return _annotations_present != 0; } - bool has_annotation(ID id) { return (nth_bit((int)id) & _annotations_present) != 0; } + bool has_any_annotations() const { return _annotations_present != 0; } + bool has_annotation(ID id) const { return (nth_bit((int)id) & _annotations_present) != 0; } void set_contended_group(u2 group) { _contended_group = group; } - u2 contended_group() { return _contended_group; } + u2 contended_group() const { return _contended_group; } - bool is_contended() { return has_annotation(_sun_misc_Contended); } + bool is_contended() const { return has_annotation(_sun_misc_Contended); } + + void set_stable(bool stable) { set_annotation(_field_Stable); } + bool is_stable() const { return has_annotation(_field_Stable); } }; // This class also doubles as a holder for metadata cleanup. diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index 067cf503305..f1758f86654 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -270,6 +270,7 @@ template(java_lang_invoke_LambdaForm, "java/lang/invoke/LambdaForm") \ template(java_lang_invoke_ForceInline_signature, "Ljava/lang/invoke/ForceInline;") \ template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \ + template(sun_invoke_Stable_signature, "Lsun/invoke/Stable;") \ template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \ template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \ template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \ diff --git a/hotspot/src/share/vm/oops/fieldInfo.hpp b/hotspot/src/share/vm/oops/fieldInfo.hpp index 5da8ed9628a..6763c42d127 100644 --- a/hotspot/src/share/vm/oops/fieldInfo.hpp +++ b/hotspot/src/share/vm/oops/fieldInfo.hpp @@ -240,6 +240,14 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC { return (access_flags() & JVM_ACC_FIELD_INTERNAL) != 0; } + bool is_stable() const { + return (access_flags() & JVM_ACC_FIELD_STABLE) != 0; + } + void set_stable(bool z) { + if (z) _shorts[access_flags_offset] |= JVM_ACC_FIELD_STABLE; + else _shorts[access_flags_offset] &= ~JVM_ACC_FIELD_STABLE; + } + Symbol* lookup_symbol(int symbol_index) const { assert(is_internal(), "only internal fields"); return vmSymbols::symbol_at((vmSymbols::SID)symbol_index); diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 15d8befbbac..1ff73e7c425 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -448,6 +448,9 @@ product(bool, EliminateAutoBox, true, \ "Control optimizations for autobox elimination") \ \ + experimental(bool, UseImplicitStableValues, false, \ + "Mark well-known stable fields as such (e.g. String.value)") \ + \ product(intx, AutoBoxCacheMax, 128, \ "Sets max value cached by the java.lang.Integer autobox cache") \ \ diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index b426bcce1a2..8d7e6c9e102 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -1297,6 +1297,10 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { // Array pointers need some flattening const TypeAryPtr *ta = tj->isa_aryptr(); + if (ta && ta->is_stable()) { + // Erase stability property for alias analysis. + tj = ta = ta->cast_to_stable(false); + } if( ta && is_known_inst ) { if ( offset != Type::OffsetBot && offset > arrayOopDesc::length_offset_in_bytes() ) { @@ -1497,6 +1501,7 @@ void Compile::AliasType::Init(int i, const TypePtr* at) { _index = i; _adr_type = at; _field = NULL; + _element = NULL; _is_rewritable = true; // default const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL; if (atoop != NULL && atoop->is_known_instance()) { @@ -1615,6 +1620,16 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr && flat->is_instptr()->klass() == env()->Class_klass()) alias_type(idx)->set_rewritable(false); } + if (flat->isa_aryptr()) { +#ifdef ASSERT + const int header_size_min = arrayOopDesc::base_offset_in_bytes(T_BYTE); + // (T_BYTE has the weakest alignment and size restrictions...) + assert(flat->offset() < header_size_min, "array body reference must be OffsetBot"); +#endif + if (flat->offset() == TypePtr::OffsetBot) { + alias_type(idx)->set_element(flat->is_aryptr()->elem()); + } + } if (flat->isa_klassptr()) { if (flat->offset() == in_bytes(Klass::super_check_offset_offset())) alias_type(idx)->set_rewritable(false); @@ -1677,7 +1692,7 @@ Compile::AliasType* Compile::alias_type(ciField* field) { else t = TypeOopPtr::make_from_klass_raw(field->holder()); AliasType* atp = alias_type(t->add_offset(field->offset_in_bytes()), field); - assert(field->is_final() == !atp->is_rewritable(), "must get the rewritable bits correct"); + assert((field->is_final() || field->is_stable()) == !atp->is_rewritable(), "must get the rewritable bits correct"); return atp; } diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index 60787464bd0..8d862c24125 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -72,6 +72,7 @@ class Scope; class StartNode; class SafePointNode; class JVMState; +class Type; class TypeData; class TypePtr; class TypeOopPtr; @@ -119,6 +120,7 @@ class Compile : public Phase { int _index; // unique index, used with MergeMemNode const TypePtr* _adr_type; // normalized address type ciField* _field; // relevant instance field, or null if none + const Type* _element; // relevant array element type, or null if none bool _is_rewritable; // false if the memory is write-once only int _general_index; // if this is type is an instance, the general // type that this is an instance of @@ -129,6 +131,7 @@ class Compile : public Phase { int index() const { return _index; } const TypePtr* adr_type() const { return _adr_type; } ciField* field() const { return _field; } + const Type* element() const { return _element; } bool is_rewritable() const { return _is_rewritable; } bool is_volatile() const { return (_field ? _field->is_volatile() : false); } int general_index() const { return (_general_index != 0) ? _general_index : _index; } @@ -137,7 +140,14 @@ class Compile : public Phase { void set_field(ciField* f) { assert(!_field,""); _field = f; - if (f->is_final()) _is_rewritable = false; + if (f->is_final() || f->is_stable()) { + // In the case of @Stable, multiple writes are possible but may be assumed to be no-ops. + _is_rewritable = false; + } + } + void set_element(const Type* e) { + assert(_element == NULL, ""); + _element = e; } void print_on(outputStream* st) PRODUCT_RETURN; diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 18772dfd0a8..dcdd104ee72 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -3825,8 +3825,13 @@ Node* GraphKit::load_String_value(Node* ctrl, Node* str) { TypeAry::make(TypeInt::CHAR,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR), true, 0); int value_field_idx = C->get_alias_index(value_field_type); - return make_load(ctrl, basic_plus_adr(str, str, value_offset), - value_type, T_OBJECT, value_field_idx); + Node* load = make_load(ctrl, basic_plus_adr(str, str, value_offset), + value_type, T_OBJECT, value_field_idx); + // String.value field is known to be @Stable. + if (UseImplicitStableValues) { + load = cast_array_to_stable(load, value_type); + } + return load; } void GraphKit::store_String_offset(Node* ctrl, Node* str, Node* value) { @@ -3844,9 +3849,6 @@ void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) { const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(), false, NULL, 0); const TypePtr* value_field_type = string_type->add_offset(value_offset); - const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull, - TypeAry::make(TypeInt::CHAR,TypeInt::POS), - ciTypeArrayKlass::make(T_CHAR), true, 0); int value_field_idx = C->get_alias_index(value_field_type); store_to_memory(ctrl, basic_plus_adr(str, value_offset), value, T_OBJECT, value_field_idx); @@ -3861,3 +3863,9 @@ void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) { store_to_memory(ctrl, basic_plus_adr(str, count_offset), value, T_INT, count_field_idx); } + +Node* GraphKit::cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type) { + // Reify the property as a CastPP node in Ideal graph to comply with monotonicity + // assumption of CCP analysis. + return _gvn.transform(new(C) CastPPNode(ary, ary_type->cast_to_stable(true))); +} diff --git a/hotspot/src/share/vm/opto/graphKit.hpp b/hotspot/src/share/vm/opto/graphKit.hpp index e9d102cb6c5..1fd4e86d2e7 100644 --- a/hotspot/src/share/vm/opto/graphKit.hpp +++ b/hotspot/src/share/vm/opto/graphKit.hpp @@ -836,6 +836,9 @@ class GraphKit : public Phase { // Insert a loop predicate into the graph void add_predicate(int nargs = 0); void add_predicate_impl(Deoptimization::DeoptReason reason, int nargs); + + // Produce new array node of stable type + Node* cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type); }; // Helper class to support building of control flow branches. Upon diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 60525d73ef7..f7e09c3f89f 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -1280,6 +1280,11 @@ Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_ar const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin)); const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot); + // String.value field is known to be @Stable. + if (UseImplicitStableValues) { + target = cast_array_to_stable(target, target_type); + } + IdealKit kit(this, false, true); #define __ kit. Node* zero = __ ConI(0); diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index aa03b5ff6c5..a91c63abc9b 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -962,6 +962,19 @@ uint LoadNode::hash() const { return (uintptr_t)in(Control) + (uintptr_t)in(Memory) + (uintptr_t)in(Address); } +static bool skip_through_membars(Compile::AliasType* atp, const TypeInstPtr* tp, bool eliminate_boxing) { + if ((atp != NULL) && (atp->index() >= Compile::AliasIdxRaw)) { + bool non_volatile = (atp->field() != NULL) && !atp->field()->is_volatile(); + bool is_stable_ary = FoldStableValues && + (tp != NULL) && (tp->isa_aryptr() != NULL) && + tp->isa_aryptr()->is_stable(); + + return (eliminate_boxing && non_volatile) || is_stable_ary; + } + + return false; +} + //---------------------------can_see_stored_value------------------------------ // This routine exists to make sure this set of tests is done the same // everywhere. We need to make a coordinated change: first LoadNode::Ideal @@ -976,11 +989,9 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const { const TypeInstPtr* tp = phase->type(ld_adr)->isa_instptr(); Compile::AliasType* atp = (tp != NULL) ? phase->C->alias_type(tp) : NULL; // This is more general than load from boxing objects. - if (phase->C->eliminate_boxing() && (atp != NULL) && - (atp->index() >= Compile::AliasIdxRaw) && - (atp->field() != NULL) && !atp->field()->is_volatile()) { + if (skip_through_membars(atp, tp, phase->C->eliminate_boxing())) { uint alias_idx = atp->index(); - bool final = atp->field()->is_final(); + bool final = !atp->is_rewritable(); Node* result = NULL; Node* current = st; // Skip through chains of MemBarNodes checking the MergeMems for @@ -1015,7 +1026,6 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const { } } - // Loop around twice in the case Load -> Initialize -> Store. // (See PhaseIterGVN::add_users_to_worklist, which knows about this case.) for (int trip = 0; trip <= 1; trip++) { @@ -1577,6 +1587,40 @@ LoadNode::load_array_final_field(const TypeKlassPtr *tkls, return NULL; } +// Try to constant-fold a stable array element. +static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, BasicType loadbt) { + assert(ary->is_stable(), "array should be stable"); + + if (ary->const_oop() != NULL) { + // Decode the results of GraphKit::array_element_address. + ciArray* aobj = ary->const_oop()->as_array(); + ciConstant con = aobj->element_value_by_offset(off); + + if (con.basic_type() != T_ILLEGAL && !con.is_null_or_zero()) { + const Type* con_type = Type::make_from_constant(con); + if (con_type != NULL) { + if (con_type->isa_aryptr()) { + // Join with the array element type, in case it is also stable. + int dim = ary->stable_dimension(); + con_type = con_type->is_aryptr()->cast_to_stable(true, dim-1); + } + if (loadbt == T_NARROWOOP && con_type->isa_oopptr()) { + con_type = con_type->make_narrowoop(); + } +#ifndef PRODUCT + if (TraceIterativeGVN) { + tty->print("FoldStableValues: array element [off=%d]: con_type=", off); + con_type->dump(); tty->cr(); + } +#endif //PRODUCT + return con_type; + } + } + } + + return NULL; +} + //------------------------------Value----------------------------------------- const Type *LoadNode::Value( PhaseTransform *phase ) const { // Either input is TOP ==> the result is TOP @@ -1591,8 +1635,31 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const { Compile* C = phase->C; // Try to guess loaded type from pointer type - if (tp->base() == Type::AryPtr) { - const Type *t = tp->is_aryptr()->elem(); + if (tp->isa_aryptr()) { + const TypeAryPtr* ary = tp->is_aryptr(); + const Type *t = ary->elem(); + + // Determine whether the reference is beyond the header or not, by comparing + // the offset against the offset of the start of the array's data. + // Different array types begin at slightly different offsets (12 vs. 16). + // We choose T_BYTE as an example base type that is least restrictive + // as to alignment, which will therefore produce the smallest + // possible base offset. + const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE); + const bool off_beyond_header = ((uint)off >= (uint)min_base_off); + + // Try to constant-fold a stable array element. + if (FoldStableValues && ary->is_stable()) { + // Make sure the reference is not into the header + if (off_beyond_header && off != Type::OffsetBot) { + assert(adr->is_AddP() && adr->in(AddPNode::Offset)->is_Con(), "offset is a constant"); + const Type* con_type = fold_stable_ary_elem(ary, off, memory_type()); + if (con_type != NULL) { + return con_type; + } + } + } + // Don't do this for integer types. There is only potential profit if // the element type t is lower than _type; that is, for int types, if _type is // more restrictive than t. This only happens here if one is short and the other @@ -1613,14 +1680,7 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const { && Opcode() != Op_LoadKlass && Opcode() != Op_LoadNKlass) { // t might actually be lower than _type, if _type is a unique // concrete subclass of abstract class t. - // Make sure the reference is not into the header, by comparing - // the offset against the offset of the start of the array's data. - // Different array types begin at slightly different offsets (12 vs. 16). - // We choose T_BYTE as an example base type that is least restrictive - // as to alignment, which will therefore produce the smallest - // possible base offset. - const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE); - if ((uint)off >= (uint)min_base_off) { // is the offset beyond the header? + if (off_beyond_header) { // is the offset beyond the header? const Type* jt = t->join(_type); // In any case, do not allow the join, per se, to empty out the type. if (jt->empty() && !t->empty()) { diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp index 91025bf56fb..ea01b08475e 100644 --- a/hotspot/src/share/vm/opto/parse.hpp +++ b/hotspot/src/share/vm/opto/parse.hpp @@ -518,7 +518,7 @@ class Parse : public GraphKit { // loading from a constant field or the constant pool // returns false if push failed (non-perm field constants only, not ldcs) - bool push_constant(ciConstant con, bool require_constant = false, bool is_autobox_cache = false); + bool push_constant(ciConstant con, bool require_constant = false, bool is_autobox_cache = false, const Type* basic_type = NULL); // implementation of object creation bytecodes void emit_guard_for_new(ciInstanceKlass* klass); diff --git a/hotspot/src/share/vm/opto/parse3.cpp b/hotspot/src/share/vm/opto/parse3.cpp index 28eb0580bad..8c545f3ece5 100644 --- a/hotspot/src/share/vm/opto/parse3.cpp +++ b/hotspot/src/share/vm/opto/parse3.cpp @@ -147,7 +147,15 @@ void Parse::do_field_access(bool is_get, bool is_field) { void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) { // Does this field have a constant value? If so, just push the value. if (field->is_constant()) { - // final field + // final or stable field + const Type* stable_type = NULL; + if (FoldStableValues && field->is_stable()) { + stable_type = Type::get_const_type(field->type()); + if (field->type()->is_array_klass()) { + int stable_dimension = field->type()->as_array_klass()->dimension(); + stable_type = stable_type->is_aryptr()->cast_to_stable(true, stable_dimension); + } + } if (field->is_static()) { // final static field if (C->eliminate_boxing()) { @@ -167,11 +175,10 @@ void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) { } } } - if (push_constant(field->constant_value())) + if (push_constant(field->constant_value(), false, false, stable_type)) return; - } - else { - // final non-static field + } else { + // final or stable non-static field // Treat final non-static fields of trusted classes (classes in // java.lang.invoke and sun.invoke packages and subpackages) as // compile time constants. @@ -179,8 +186,12 @@ void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) { const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr(); ciObject* constant_oop = oop_ptr->const_oop(); ciConstant constant = field->constant_value_of(constant_oop); - if (push_constant(constant, true)) - return; + if (FoldStableValues && field->is_stable() && constant.is_null_or_zero()) { + // fall through to field load; the field is not yet initialized + } else { + if (push_constant(constant, true, false, stable_type)) + return; + } } } } @@ -301,7 +312,8 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) { // Note the presence of writes to final non-static fields, so that we // can insert a memory barrier later on to keep the writes from floating // out of the constructor. - if (is_field && field->is_final()) { + // Any method can write a @Stable field; insert memory barriers after those also. + if (is_field && (field->is_final() || field->is_stable())) { set_wrote_final(true); // Preserve allocation ptr to create precedent edge to it in membar // generated on exit from constructor. @@ -314,35 +326,21 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) { } -bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_autobox_cache) { + +bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_autobox_cache, const Type* stable_type) { + const Type* con_type = Type::make_from_constant(constant, require_constant, is_autobox_cache); switch (constant.basic_type()) { - case T_BOOLEAN: push( intcon(constant.as_boolean()) ); break; - case T_INT: push( intcon(constant.as_int()) ); break; - case T_CHAR: push( intcon(constant.as_char()) ); break; - case T_BYTE: push( intcon(constant.as_byte()) ); break; - case T_SHORT: push( intcon(constant.as_short()) ); break; - case T_FLOAT: push( makecon(TypeF::make(constant.as_float())) ); break; - case T_DOUBLE: push_pair( makecon(TypeD::make(constant.as_double())) ); break; - case T_LONG: push_pair( longcon(constant.as_long()) ); break; case T_ARRAY: - case T_OBJECT: { + case T_OBJECT: // cases: // can_be_constant = (oop not scavengable || ScavengeRootsInCode != 0) // should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2) // An oop is not scavengable if it is in the perm gen. - ciObject* oop_constant = constant.as_object(); - if (oop_constant->is_null_object()) { - push( zerocon(T_OBJECT) ); - break; - } else if (require_constant || oop_constant->should_be_constant()) { - push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache)) ); - break; - } else { - // we cannot inline the oop, but we can use it later to narrow a type - return false; - } - } - case T_ILLEGAL: { + if (stable_type != NULL && con_type != NULL && con_type->isa_oopptr()) + con_type = con_type->join(stable_type); + break; + + case T_ILLEGAL: // Invalid ciConstant returned due to OutOfMemoryError in the CI assert(C->env()->failing(), "otherwise should not see this"); // These always occur because of object types; we are going to @@ -350,17 +348,16 @@ bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_au push( zerocon(T_OBJECT) ); return false; } - default: - ShouldNotReachHere(); - return false; - } - // success + if (con_type == NULL) + // we cannot inline the oop, but we can use it later to narrow a type + return false; + + push_node(constant.basic_type(), makecon(con_type)); return true; } - //============================================================================= void Parse::do_anewarray() { bool will_link; diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index fabcf1cad16..23e84a05d77 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -189,6 +189,38 @@ const Type* Type::get_typeflow_type(ciType* type) { } +//-----------------------make_from_constant------------------------------------ +const Type* Type::make_from_constant(ciConstant constant, + bool require_constant, bool is_autobox_cache) { + switch (constant.basic_type()) { + case T_BOOLEAN: return TypeInt::make(constant.as_boolean()); + case T_CHAR: return TypeInt::make(constant.as_char()); + case T_BYTE: return TypeInt::make(constant.as_byte()); + case T_SHORT: return TypeInt::make(constant.as_short()); + case T_INT: return TypeInt::make(constant.as_int()); + case T_LONG: return TypeLong::make(constant.as_long()); + case T_FLOAT: return TypeF::make(constant.as_float()); + case T_DOUBLE: return TypeD::make(constant.as_double()); + case T_ARRAY: + case T_OBJECT: + { + // cases: + // can_be_constant = (oop not scavengable || ScavengeRootsInCode != 0) + // should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2) + // An oop is not scavengable if it is in the perm gen. + ciObject* oop_constant = constant.as_object(); + if (oop_constant->is_null_object()) { + return Type::get_zero_type(T_OBJECT); + } else if (require_constant || oop_constant->should_be_constant()) { + return TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache); + } + } + } + // Fall through to failure + return NULL; +} + + //------------------------------make------------------------------------------- // Create a simple Type, with default empty symbol sets. Then hashcons it // and look for an existing copy in the type dictionary. @@ -1824,12 +1856,12 @@ inline const TypeInt* normalize_array_size(const TypeInt* size) { } //------------------------------make------------------------------------------- -const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) { +const TypeAry* TypeAry::make(const Type* elem, const TypeInt* size, bool stable) { if (UseCompressedOops && elem->isa_oopptr()) { elem = elem->make_narrowoop(); } size = normalize_array_size(size); - return (TypeAry*)(new TypeAry(elem,size))->hashcons(); + return (TypeAry*)(new TypeAry(elem,size,stable))->hashcons(); } //------------------------------meet------------------------------------------- @@ -1850,7 +1882,8 @@ const Type *TypeAry::xmeet( const Type *t ) const { case Array: { // Meeting 2 arrays? const TypeAry *a = t->is_ary(); return TypeAry::make(_elem->meet(a->_elem), - _size->xmeet(a->_size)->is_int()); + _size->xmeet(a->_size)->is_int(), + _stable & a->_stable); } case Top: break; @@ -1863,7 +1896,7 @@ const Type *TypeAry::xmeet( const Type *t ) const { const Type *TypeAry::xdual() const { const TypeInt* size_dual = _size->dual()->is_int(); size_dual = normalize_array_size(size_dual); - return new TypeAry( _elem->dual(), size_dual); + return new TypeAry(_elem->dual(), size_dual, !_stable); } //------------------------------eq--------------------------------------------- @@ -1871,13 +1904,14 @@ const Type *TypeAry::xdual() const { bool TypeAry::eq( const Type *t ) const { const TypeAry *a = (const TypeAry*)t; return _elem == a->_elem && + _stable == a->_stable && _size == a->_size; } //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeAry::hash(void) const { - return (intptr_t)_elem + (intptr_t)_size; + return (intptr_t)_elem + (intptr_t)_size + (_stable ? 43 : 0); } //----------------------interface_vs_oop--------------------------------------- @@ -1894,6 +1928,7 @@ bool TypeAry::interface_vs_oop(const Type *t) const { //------------------------------dump2------------------------------------------ #ifndef PRODUCT void TypeAry::dump2( Dict &d, uint depth, outputStream *st ) const { + if (_stable) st->print("stable:"); _elem->dump2(d, depth, st); st->print("["); _size->dump2(d, depth, st); @@ -3457,11 +3492,39 @@ const TypeAryPtr* TypeAryPtr::cast_to_size(const TypeInt* new_size) const { assert(new_size != NULL, ""); new_size = narrow_size_type(new_size); if (new_size == size()) return this; - const TypeAry* new_ary = TypeAry::make(elem(), new_size); + const TypeAry* new_ary = TypeAry::make(elem(), new_size, is_stable()); return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id); } +//------------------------------cast_to_stable--------------------------------- +const TypeAryPtr* TypeAryPtr::cast_to_stable(bool stable, int stable_dimension) const { + if (stable_dimension <= 0 || (stable_dimension == 1 && stable == this->is_stable())) + return this; + + const Type* elem = this->elem(); + const TypePtr* elem_ptr = elem->make_ptr(); + + if (stable_dimension > 1 && elem_ptr != NULL && elem_ptr->isa_aryptr()) { + // If this is widened from a narrow oop, TypeAry::make will re-narrow it. + elem = elem_ptr = elem_ptr->is_aryptr()->cast_to_stable(stable, stable_dimension - 1); + } + + const TypeAry* new_ary = TypeAry::make(elem, size(), stable); + + return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id); +} + +//-----------------------------stable_dimension-------------------------------- +int TypeAryPtr::stable_dimension() const { + if (!is_stable()) return 0; + int dim = 1; + const TypePtr* elem_ptr = elem()->make_ptr(); + if (elem_ptr != NULL && elem_ptr->isa_aryptr()) + dim += elem_ptr->is_aryptr()->stable_dimension(); + return dim; +} + //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeAryPtr::eq( const Type *t ) const { @@ -3570,7 +3633,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { // Something like byte[int+] meets char[int+]. // This must fall to bottom, not (int[-128..65535])[int+]. instance_id = InstanceBot; - tary = TypeAry::make(Type::BOTTOM, tary->_size); + tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); } } else // Non integral arrays. // Must fall to bottom if exact klasses in upper lattice @@ -3584,7 +3647,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { (tap ->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || // 'this' is exact and super or unrelated: (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { - tary = TypeAry::make(Type::BOTTOM, tary->_size); + tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); return make( NotNull, NULL, tary, lazy_klass, false, off, InstanceBot ); } diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp index 55d98bd5e51..d4832591843 100644 --- a/hotspot/src/share/vm/opto/type.hpp +++ b/hotspot/src/share/vm/opto/type.hpp @@ -372,6 +372,10 @@ public: // Mapping from CI type system to compiler type: static const Type* get_typeflow_type(ciType* type); + static const Type* make_from_constant(ciConstant constant, + bool require_constant = false, + bool is_autobox_cache = false); + private: // support arrays static const BasicType _basic_type[]; @@ -588,8 +592,8 @@ public: //------------------------------TypeAry---------------------------------------- // Class of Array Types class TypeAry : public Type { - TypeAry( const Type *elem, const TypeInt *size) : Type(Array), - _elem(elem), _size(size) {} + TypeAry(const Type* elem, const TypeInt* size, bool stable) : Type(Array), + _elem(elem), _size(size), _stable(stable) {} public: virtual bool eq( const Type *t ) const; virtual int hash() const; // Type specific hashing @@ -599,10 +603,11 @@ public: private: const Type *_elem; // Element type of array const TypeInt *_size; // Elements in array + const bool _stable; // Are elements @Stable? friend class TypeAryPtr; public: - static const TypeAry *make( const Type *elem, const TypeInt *size); + static const TypeAry* make(const Type* elem, const TypeInt* size, bool stable = false); virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. @@ -988,6 +993,7 @@ public: const TypeAry* ary() const { return _ary; } const Type* elem() const { return _ary->_elem; } const TypeInt* size() const { return _ary->_size; } + bool is_stable() const { return _ary->_stable; } bool is_autobox_cache() const { return _is_autobox_cache; } @@ -1011,6 +1017,9 @@ public: virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. + const TypeAryPtr* cast_to_stable(bool stable, int stable_dimension = 1) const; + int stable_dimension() const; + // Convenience common pre-built types. static const TypeAryPtr *RANGE; static const TypeAryPtr *OOPS; diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index c9bcbe1f4d3..7fdf668bac5 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -3649,6 +3649,9 @@ class CommandLineFlags { experimental(bool, TrustFinalNonStaticFields, false, \ "trust final non-static declarations for constant folding") \ \ + experimental(bool, FoldStableValues, false, \ + "Private flag to control optimizations for stable variables") \ + \ develop(bool, TraceInvokeDynamic, false, \ "trace internal invoke dynamic operations") \ \ diff --git a/hotspot/src/share/vm/utilities/accessFlags.hpp b/hotspot/src/share/vm/utilities/accessFlags.hpp index 99f9a3360f8..a3d3de99c91 100644 --- a/hotspot/src/share/vm/utilities/accessFlags.hpp +++ b/hotspot/src/share/vm/utilities/accessFlags.hpp @@ -78,11 +78,13 @@ enum { JVM_ACC_FIELD_ACCESS_WATCHED = 0x00002000, // field access is watched by JVMTI JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000, // field modification is watched by JVMTI JVM_ACC_FIELD_INTERNAL = 0x00000400, // internal field, same as JVM_ACC_ABSTRACT + JVM_ACC_FIELD_STABLE = 0x00000020, // @Stable field, same as JVM_ACC_SYNCHRONIZED JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE = 0x00000800, // field has generic signature JVM_ACC_FIELD_INTERNAL_FLAGS = JVM_ACC_FIELD_ACCESS_WATCHED | JVM_ACC_FIELD_MODIFICATION_WATCHED | JVM_ACC_FIELD_INTERNAL | + JVM_ACC_FIELD_STABLE | JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE, // flags accepted by set_field_flags() @@ -148,6 +150,7 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC { { return (_flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; } bool on_stack() const { return (_flags & JVM_ACC_ON_STACK) != 0; } bool is_internal() const { return (_flags & JVM_ACC_FIELD_INTERNAL) != 0; } + bool is_stable() const { return (_flags & JVM_ACC_FIELD_STABLE) != 0; } bool field_has_generic_signature() const { return (_flags & JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE) != 0; } From ce469f1922e134ac709a9189c4328637655d5e38 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 11 Sep 2013 00:38:18 -0400 Subject: [PATCH 0289/1294] 8024256: Minimal VM build is broken with PCH disabled Reviewed-by: coleenp, twisti --- hotspot/make/excludeSrc.make | 2 +- .../share/vm/gc_implementation/shared/allocationStats.hpp | 6 ++---- .../share/vm/gc_implementation/shared/hSpaceCounters.hpp | 4 +--- hotspot/src/share/vm/memory/binaryTreeDictionary.cpp | 4 ++-- hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp | 5 +---- 5 files changed, 7 insertions(+), 14 deletions(-) diff --git a/hotspot/make/excludeSrc.make b/hotspot/make/excludeSrc.make index 7cc879a3d7b..c3a9b4dea0e 100644 --- a/hotspot/make/excludeSrc.make +++ b/hotspot/make/excludeSrc.make @@ -99,7 +99,7 @@ ifeq ($(INCLUDE_ALL_GCS), false) psTasks.cpp psVirtualspace.cpp psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp \ parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \ gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \ - mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp + mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp hSpaceCounters.cpp endif ifeq ($(INCLUDE_NMT), false) diff --git a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp index cf7cd3ae0f2..0fb6d7fa23e 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,11 +26,9 @@ #define SHARE_VM_GC_IMPLEMENTATION_SHARED_ALLOCATIONSTATS_HPP #include "utilities/macros.hpp" -#if INCLUDE_ALL_GCS -#include "gc_implementation/shared/gcUtil.hpp" #include "memory/allocation.hpp" #include "utilities/globalDefinitions.hpp" -#endif // INCLUDE_ALL_GCS +#include "gc_implementation/shared/gcUtil.hpp" class AllocationStats VALUE_OBJ_CLASS_SPEC { // A duration threshold (in ms) used to filter diff --git a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp index 034d319b078..0b855e7f674 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,11 +26,9 @@ #define SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP #include "utilities/macros.hpp" -#if INCLUDE_ALL_GCS #include "gc_implementation/shared/generationCounters.hpp" #include "memory/generation.hpp" #include "runtime/perfData.hpp" -#endif // INCLUDE_ALL_GCS // A HSpaceCounter is a holder class for performance counters // that track a collections (logical spaces) in a heap; diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp index 8ed2b61a921..bfe1d1b4ca8 100644 --- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,10 +33,10 @@ #include "runtime/globals.hpp" #include "utilities/ostream.hpp" #include "utilities/macros.hpp" +#include "gc_implementation/shared/spaceDecorator.hpp" #if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp" #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" -#include "gc_implementation/shared/spaceDecorator.hpp" #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" #endif // INCLUDE_ALL_GCS diff --git a/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp b/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp index 5a626ce7fa3..98d8f438ea4 100644 --- a/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp +++ b/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,10 +26,7 @@ #define SHARE_VM_UTILITIES_YIELDINGWORKGROUP_HPP #include "utilities/macros.hpp" -#if INCLUDE_ALL_GCS #include "utilities/workgroup.hpp" -#endif // INCLUDE_ALL_GCS - // Forward declarations class YieldingFlexibleWorkGang; From 86624d96d773b48cf814ed669ff4bc8aac40623c Mon Sep 17 00:00:00 2001 From: Stefan Johansson Date: Wed, 11 Sep 2013 08:57:02 +0200 Subject: [PATCH 0290/1294] 8024176: [macosx] gc/metaspace/ClassMetaspaceSizeInJmapHeap.java failed since jdk8b105, hs25b47 The code for reading compressed klass pointers in the sa-agent on Mac used readCompOopAddress instead of readCompKlassAddress, this is wrong but has been hidden because compressed oops and compressed klasses has used the same base address in the past. Reviewed-by: sla, jmasa --- .../share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java index d1b56881f13..f25d50ff23c 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java @@ -81,7 +81,7 @@ class BsdAddress implements Address { public Address getCompKlassAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException { - return debugger.readCompOopAddress(addr + offset); + return debugger.readCompKlassAddress(addr + offset); } // From bcdf7e7a4d6cd53248206e182e3c1d664d21b47e Mon Sep 17 00:00:00 2001 From: Niclas Adlertz Date: Wed, 11 Sep 2013 09:34:00 +0200 Subject: [PATCH 0291/1294] 8010941: MinJumpTableSize is set to 18, investigate if that's still optimal Lowered the MinJumpTableSize for each platform Reviewed-by: kvn --- hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp | 1 + hotspot/src/cpu/x86/vm/c2_globals_x86.hpp | 2 +- hotspot/src/share/vm/opto/c2_globals.hpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp index 093be806072..e4fe6bb00a4 100644 --- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp @@ -57,6 +57,7 @@ define_pd_global(intx, RegisterCostAreaRatio, 12000); define_pd_global(bool, UseTLAB, true); define_pd_global(bool, ResizeTLAB, true); define_pd_global(intx, LoopUnrollLimit, 60); // Design center runs on 1.3.1 +define_pd_global(intx, MinJumpTableSize, 5); // Peephole and CISC spilling both break the graph, and so makes the // scheduler sick. diff --git a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp index d49bec21fe7..a45bd9624e5 100644 --- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp @@ -30,7 +30,6 @@ // Sets the default values for platform dependent flags used by the server compiler. // (see c2_globals.hpp). Alpha-sorted. - define_pd_global(bool, BackgroundCompilation, true); define_pd_global(bool, UseTLAB, true); define_pd_global(bool, ResizeTLAB, true); @@ -52,6 +51,7 @@ define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 3); define_pd_global(intx, FLOATPRESSURE, 6); define_pd_global(intx, FreqInlineSize, 325); +define_pd_global(intx, MinJumpTableSize, 10); #ifdef AMD64 define_pd_global(intx, INTPRESSURE, 13); define_pd_global(intx, InteriorEntryAlignment, 16); diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 1ff73e7c425..cf9a82092fd 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -421,7 +421,7 @@ product(bool, UseDivMod, true, \ "Use combined DivMod instruction if available") \ \ - product(intx, MinJumpTableSize, 18, \ + product_pd(intx, MinJumpTableSize, \ "Minimum number of targets in a generated jump table") \ \ product(intx, MaxJumpTableSize, 65000, \ From 1d978716242b7d4ef33f8e82f8ce6d79f802e38b Mon Sep 17 00:00:00 2001 From: Mikael Gerdin Date: Wed, 11 Sep 2013 09:37:14 +0200 Subject: [PATCH 0292/1294] 8009561: NPG: Metaspace fragmentation when retiring a Metachunk Use best-fit block-splitting freelist allocation from the block freelist. Reviewed-by: jmasa, stefank --- hotspot/src/share/vm/memory/metaspace.cpp | 35 +++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 1c5cec84d5f..63e6be716da 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -51,7 +51,7 @@ const bool metaspace_slow_verify = false; // Parameters for stress mode testing const uint metadata_deallocate_a_lot_block = 10; const uint metadata_deallocate_a_lock_chunk = 3; -size_t const allocation_from_dictionary_limit = 64 * K; +size_t const allocation_from_dictionary_limit = 4 * K; MetaWord* last_allocated = 0; @@ -228,6 +228,10 @@ class BlockFreelist VALUE_OBJ_CLASS_SPEC { BlockTreeDictionary* _dictionary; static Metablock* initialize_free_chunk(MetaWord* p, size_t word_size); + // Only allocate and split from freelist if the size of the allocation + // is at least 1/4th the size of the available block. + const static int WasteMultiplier = 4; + // Accessors BlockTreeDictionary* dictionary() const { return _dictionary; } @@ -623,6 +627,7 @@ class SpaceManager : public CHeapObj { // Add chunk to the list of chunks in use void add_chunk(Metachunk* v, bool make_current); + void retire_current_chunk(); Mutex* lock() const { return _lock; } @@ -807,12 +812,25 @@ MetaWord* BlockFreelist::get_block(size_t word_size) { } Metablock* free_block = - dictionary()->get_chunk(word_size, FreeBlockDictionary::exactly); + dictionary()->get_chunk(word_size, FreeBlockDictionary::atLeast); if (free_block == NULL) { return NULL; } - return (MetaWord*) free_block; + const size_t block_size = free_block->size(); + if (block_size > WasteMultiplier * word_size) { + return_block((MetaWord*)free_block, block_size); + return NULL; + } + + MetaWord* new_block = (MetaWord*)free_block; + assert(block_size >= word_size, "Incorrect size of block from freelist"); + const size_t unused = block_size - word_size; + if (unused >= TreeChunk::min_size()) { + return_block(new_block + word_size, unused); + } + + return new_block; } void BlockFreelist::print_on(outputStream* st) const { @@ -2278,6 +2296,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { ChunkIndex index = ChunkManager::list_index(new_chunk->word_size()); if (index != HumongousIndex) { + retire_current_chunk(); set_current_chunk(new_chunk); new_chunk->set_next(chunks_in_use(index)); set_chunks_in_use(index, new_chunk); @@ -2313,6 +2332,16 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { } } +void SpaceManager::retire_current_chunk() { + if (current_chunk() != NULL) { + size_t remaining_words = current_chunk()->free_word_size(); + if (remaining_words >= TreeChunk::min_size()) { + block_freelists()->return_block(current_chunk()->allocate(remaining_words), remaining_words); + inc_used_metrics(remaining_words); + } + } +} + Metachunk* SpaceManager::get_new_chunk(size_t word_size, size_t grow_chunks_by_words) { From a136d0573963ee7cc319a0e4c577479479420172 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 11 Sep 2013 10:14:32 +0200 Subject: [PATCH 0293/1294] 8016825: Large pages for the heap broken on Windows for compressed oops Correctly pass the requested base address for the heap to the OS function to reserve memory. Reviewed-by: brutisso, stefank --- hotspot/src/os/windows/vm/os_windows.cpp | 68 ++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 015f94d6662..985cbd6230f 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -3189,9 +3189,12 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, boo return p_buf; } else { + if (TracePageSizes && Verbose) { + tty->print_cr("Reserving large pages in a single large chunk."); + } // normal policy just allocate it all at once DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; - char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot); + char * res = (char *)VirtualAlloc(addr, bytes, flag, prot); if (res != NULL) { address pc = CALLER_PC; MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, mtNone, pc); @@ -5714,7 +5717,66 @@ BOOL os::Advapi32Dll::AdvapiAvailable() { #endif #ifndef PRODUCT + +// test the code path in reserve_memory_special() that tries to allocate memory in a single +// contiguous memory block at a particular address. +// The test first tries to find a good approximate address to allocate at by using the same +// method to allocate some memory at any address. The test then tries to allocate memory in +// the vicinity (not directly after it to avoid possible by-chance use of that location) +// This is of course only some dodgy assumption, there is no guarantee that the vicinity of +// the previously allocated memory is available for allocation. The only actual failure +// that is reported is when the test tries to allocate at a particular location but gets a +// different valid one. A NULL return value at this point is not considered an error but may +// be legitimate. +// If -XX:+VerboseInternalVMTests is enabled, print some explanatory messages. void TestReserveMemorySpecial_test() { - // No tests available for this platform + if (!UseLargePages) { + if (VerboseInternalVMTests) { + gclog_or_tty->print("Skipping test because large pages are disabled"); + } + return; + } + // save current value of globals + bool old_use_large_pages_individual_allocation = UseLargePagesIndividualAllocation; + bool old_use_numa_interleaving = UseNUMAInterleaving; + + // set globals to make sure we hit the correct code path + UseLargePagesIndividualAllocation = UseNUMAInterleaving = false; + + // do an allocation at an address selected by the OS to get a good one. + const size_t large_allocation_size = os::large_page_size() * 4; + char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false); + if (result == NULL) { + if (VerboseInternalVMTests) { + gclog_or_tty->print("Failed to allocate control block with size "SIZE_FORMAT". Skipping remainder of test.", + large_allocation_size); + } + } else { + os::release_memory_special(result, large_allocation_size); + + // allocate another page within the recently allocated memory area which seems to be a good location. At least + // we managed to get it once. + const size_t expected_allocation_size = os::large_page_size(); + char* expected_location = result + os::large_page_size(); + char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false); + if (actual_location == NULL) { + if (VerboseInternalVMTests) { + gclog_or_tty->print("Failed to allocate any memory at "PTR_FORMAT" size "SIZE_FORMAT". Skipping remainder of test.", + expected_location, large_allocation_size); + } + } else { + // release memory + os::release_memory_special(actual_location, expected_allocation_size); + // only now check, after releasing any memory to avoid any leaks. + assert(actual_location == expected_location, + err_msg("Failed to allocate memory at requested location "PTR_FORMAT" of size "SIZE_FORMAT", is "PTR_FORMAT" instead", + expected_location, expected_allocation_size, actual_location)); + } + } + + // restore globals + UseLargePagesIndividualAllocation = old_use_large_pages_individual_allocation; + UseNUMAInterleaving = old_use_numa_interleaving; } -#endif +#endif // PRODUCT + From 87a98b7267958dc8046ff36226083785fa442f36 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 11 Sep 2013 10:19:16 +0200 Subject: [PATCH 0294/1294] 8021823: G1: Concurrent marking crashes with -XX:ObjectAlignmentInBytes>=32 in 64bit VMs Correctly calculate the initialization value for the shift between object start and bitmap bit in the G1 mark bitmaps. Reviewed-by: tonyp --- .../gc_implementation/g1/concurrentMark.cpp | 5 +- hotspot/test/gc/TestObjectAlignment.java | 65 +++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 hotspot/test/gc/TestObjectAlignment.java diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 04f8ccd0fc7..77f08f0d3a3 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -481,9 +481,8 @@ uint ConcurrentMark::scale_parallel_threads(uint n_par_threads) { ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) : _g1h(g1h), - _markBitMap1(MinObjAlignment - 1), - _markBitMap2(MinObjAlignment - 1), - + _markBitMap1(log2_intptr(MinObjAlignment)), + _markBitMap2(log2_intptr(MinObjAlignment)), _parallel_marking_threads(0), _max_parallel_marking_threads(0), _sleep_factor(0.0), diff --git a/hotspot/test/gc/TestObjectAlignment.java b/hotspot/test/gc/TestObjectAlignment.java new file mode 100644 index 00000000000..8cfc9709f16 --- /dev/null +++ b/hotspot/test/gc/TestObjectAlignment.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013, 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 TestObjectAlignment + * @key gc + * @bug 8021823 + * @summary G1: Concurrent marking crashes with -XX:ObjectAlignmentInBytes>=32 in 64bit VMs + * @library /testlibrary + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=8 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=16 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=64 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=128 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=256 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=8 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=16 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=64 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=128 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=256 + */ + +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.OutputAnalyzer; + +public class TestObjectAlignment { + + public static byte[] garbage; + + private static boolean runsOn32bit() { + return System.getProperty("sun.arch.data.model").equals("32"); + } + + public static void main(String[] args) throws Exception { + if (runsOn32bit()) { + // 32 bit VMs do not allow setting ObjectAlignmentInBytes, so there is nothing to test. We still get called. + return; + } + for (int i = 0; i < 10; i++) { + garbage = new byte[1000]; + System.gc(); + } + } +} From ab77668a9abf26425fdf61369192ab042d5f1e72 Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Wed, 11 Sep 2013 10:27:25 +0200 Subject: [PATCH 0295/1294] 8024130: We no longer need slots for temporaries in self-assign indices Reviewed-by: jlaskey, lagergren --- .../jdk/nashorn/internal/codegen/Attr.java | 40 ++----------------- 1 file changed, 3 insertions(+), 37 deletions(-) diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index 294300626d2..88e904dcf58 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -886,10 +886,9 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveDECINC(final UnaryNode unaryNode) { // @see assignOffset - final UnaryNode newUnaryNode = unaryNode.setRHS(ensureAssignmentSlots(unaryNode.rhs())); final Type type = arithType(); - newType(newUnaryNode.rhs().getSymbol(), type); - return end(ensureSymbol(type, newUnaryNode)); + newType(unaryNode.rhs().getSymbol(), type); + return end(ensureSymbol(type, unaryNode)); } @Override @@ -1574,39 +1573,6 @@ final class Attr extends NodeOperatorVisitor { return newInternal(lc.getCurrentFunction().uniqueName(EXCEPTION_PREFIX.symbolName()), Type.typeFor(EXCEPTION_PREFIX.type())); } - /** - * In an assignment, recursively make sure that there are slots for - * everything that has to be laid out as temporary storage, which is the - * case if we are assign-op:ing a BaseNode subclass. This has to be - * recursive to handle things like multi dimensional arrays as lhs - * - * see NASHORN-258 - * - * @param assignmentDest the destination node of the assignment, e.g. lhs for binary nodes - */ - private Expression ensureAssignmentSlots(final Expression assignmentDest) { - final LexicalContext attrLexicalContext = lc; - return (Expression)assignmentDest.accept(new NodeVisitor(new LexicalContext()) { - @Override - public Node leaveIndexNode(final IndexNode indexNode) { - assert indexNode.getSymbol().isTemp(); - final Expression index = indexNode.getIndex(); - //only temps can be set as needing slots. the others will self resolve - //it is illegal to take a scope var and force it to be a slot, that breaks - Symbol indexSymbol = index.getSymbol(); - if (indexSymbol.isTemp() && !indexSymbol.isConstant() && !indexSymbol.hasSlot()) { - if(indexSymbol.isShared()) { - indexSymbol = temporarySymbols.createUnshared(indexSymbol); - } - indexSymbol.setNeedsSlot(true); - attrLexicalContext.getCurrentBlock().putSymbol(attrLexicalContext, indexSymbol); - return indexNode.setIndex(index.setSymbol(attrLexicalContext, indexSymbol)); - } - return indexNode; - } - }); - } - /** * Return the type that arithmetic ops should use. Until we have implemented better type * analysis (range based) or overflow checks that are fast enough for int arithmetic, @@ -1704,7 +1670,7 @@ final class Attr extends NodeOperatorVisitor { newType(lhs.getSymbol(), destType); //may not narrow if dest is already wider than destType // ensureSymbol(destType, binaryNode); //for OP= nodes, the node can carry a narrower types than its lhs rhs. This is perfectly fine - return end(ensureSymbol(destType, ensureAssignmentSlots(binaryNode))); + return end(ensureSymbol(destType, binaryNode)); } private Expression ensureSymbol(final Type type, final Expression expr) { From eaa4cfd4a7c29b81b55422f0b013d28061236172 Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Wed, 11 Sep 2013 14:30:17 +0400 Subject: [PATCH 0296/1294] 8024056: runtime/InitialThreadOverflow/testme.sh fails On some macines gcc not able to link cxx program Reviewed-by: dholmes --- hotspot/test/runtime/InitialThreadOverflow/testme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/test/runtime/InitialThreadOverflow/testme.sh b/hotspot/test/runtime/InitialThreadOverflow/testme.sh index 015a6bd43b1..b7154dc2abd 100644 --- a/hotspot/test/runtime/InitialThreadOverflow/testme.sh +++ b/hotspot/test/runtime/InitialThreadOverflow/testme.sh @@ -43,9 +43,9 @@ then exit 0 fi -gcc_cmd=`which gcc` -if [ "x$gcc_cmd" == "x" ]; then - echo "WARNING: gcc not found. Cannot execute test." 2>&1 +gcc_cmd=`which g++` +if [ "x$gcc_cmd" = "x" ]; then + echo "WARNING: g++ not found. Cannot execute test." 2>&1 exit 0; fi From 1b72835883920aa57a33a7b0da3d6a9dd072bf58 Mon Sep 17 00:00:00 2001 From: Eric McCorkle Date: Wed, 11 Sep 2013 08:30:58 -0400 Subject: [PATCH 0297/1294] 8024510: lib/combo/tools/javac/combo/TemplateTest.java fails Edit regex in Template to allow "MAJOR." pattern. Reviewed-by: briangoetz --- .../lib/combo/tools/javac/combo/Template.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/langtools/test/lib/combo/tools/javac/combo/Template.java b/langtools/test/lib/combo/tools/javac/combo/Template.java index 8ad4d72edcb..ad8aeb9f956 100644 --- a/langtools/test/lib/combo/tools/javac/combo/Template.java +++ b/langtools/test/lib/combo/tools/javac/combo/Template.java @@ -40,11 +40,22 @@ public interface Template { public static class Behavior { /* Looks for expandable keys. An expandable key can take the form: * #{MAJOR} + * #{MAJOR.} * #{MAJOR.MINOR} - * where MAJOR can be IDENTIFIER or IDENTIFIER[NUMERIC_INDEX] - * and MINOR can be an identifier + * where MAJOR can be IDENTIFIER or IDENTIFIER[NUMERIC_INDEX] + * and MINOR can be an identifier. + * + * The ability to have an empty minor is provided on the + * assumption that some tests that can be written with this + * will find it useful to make a distinction akin to + * distinguishing F from F(), where F is a function pointer, + * and also cases of #{FOO.#{BAR}}, where BAR expands to an + * empty string. + * + * However, this being a general-purpose framework, the exact + * use is left up to the test writers. */ - private static final Pattern pattern = Pattern.compile("#\\{([A-Z_][A-Z0-9_]*(?:\\[\\d+\\])?)(?:\\.([A-Z_][A-Z0-9_]*))?\\}"); + private static final Pattern pattern = Pattern.compile("#\\{([A-Z_][A-Z0-9_]*(?:\\[\\d+\\])?)(?:\\.([A-Z0-9_]*))?\\}"); public static String expandTemplate(String template, final Map vars) { return expandTemplate(template, new MapResolver(vars)); From 962008f22b4767fa6c87a36119bc3f2fdbbe397c Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 11 Sep 2013 16:25:02 +0200 Subject: [PATCH 0298/1294] 8010722: assert: failed: heap size is too big for compressed oops Use conservative assumptions of required alignment for the various garbage collector components into account when determining the maximum heap size that supports compressed oops. Using this conservative value avoids several circular dependencies in the calculation. Reviewed-by: stefank, dholmes --- hotspot/src/os/bsd/vm/os_bsd.cpp | 2 - hotspot/src/os/linux/vm/os_linux.cpp | 2 - hotspot/src/os/solaris/vm/os_solaris.cpp | 4 +- hotspot/src/os/windows/vm/os_windows.cpp | 2 - .../gc_implementation/g1/g1CollectedHeap.cpp | 4 + .../gc_implementation/g1/g1CollectedHeap.hpp | 3 + .../vm/gc_implementation/g1/heapRegion.cpp | 6 +- .../vm/gc_implementation/g1/heapRegion.hpp | 4 +- .../parallelScavenge/parallelScavengeHeap.hpp | 7 +- .../src/share/vm/memory/collectorPolicy.cpp | 47 ++--- .../src/share/vm/memory/collectorPolicy.hpp | 6 +- .../src/share/vm/memory/genCollectedHeap.hpp | 7 +- hotspot/src/share/vm/memory/universe.cpp | 3 + hotspot/src/share/vm/prims/whitebox.cpp | 8 + hotspot/src/share/vm/runtime/arguments.cpp | 39 +++- hotspot/src/share/vm/runtime/arguments.hpp | 12 +- hotspot/src/share/vm/runtime/os.cpp | 5 + hotspot/src/share/vm/runtime/os.hpp | 8 + hotspot/src/share/vm/runtime/thread.cpp | 5 + .../arguments/TestUseCompressedOopsErgo.java | 50 +++++ .../TestUseCompressedOopsErgoTools.java | 179 ++++++++++++++++++ .../whitebox/sun/hotspot/WhiteBox.java | 2 + 22 files changed, 363 insertions(+), 42 deletions(-) create mode 100644 hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java create mode 100644 hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp index 6b636d379de..58c961b43eb 100644 --- a/hotspot/src/os/bsd/vm/os_bsd.cpp +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp @@ -3589,8 +3589,6 @@ jint os::init_2(void) #endif } - os::large_page_init(); - // initialize suspend/resume support - must do this before signal_sets_init() if (SR_initialize() != 0) { perror("SR_initialize failed"); diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 70837a850d8..5b3d6b31116 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -4755,8 +4755,6 @@ jint os::init_2(void) #endif } - os::large_page_init(); - // initialize suspend/resume support - must do this before signal_sets_init() if (SR_initialize() != 0) { perror("SR_initialize failed"); diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index c3e6e879077..8e5984ffa3d 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -5178,9 +5178,7 @@ jint os::init_2(void) { if(Verbose && PrintMiscellaneous) tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); #endif -} - - os::large_page_init(); + } // Check minimum allowable stack size for thread creation and to initialize // the java system classes, including StackOverflowError - depends on page diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 985cbd6230f..e55281af4c9 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -3920,8 +3920,6 @@ jint os::init_2(void) { #endif } - os::large_page_init(); - // Setup Windows Exceptions // for debugging float code generation bugs diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index bd01ec3b602..1d8ff8a26dc 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2191,6 +2191,10 @@ jint G1CollectedHeap::initialize() { return JNI_OK; } +size_t G1CollectedHeap::conservative_max_heap_alignment() { + return HeapRegion::max_region_size(); +} + void G1CollectedHeap::ref_processing_init() { // Reference processing in G1 currently works as follows: // diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index aecaa5e97ac..747b2326236 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -1092,6 +1092,9 @@ public: // specified by the policy object. jint initialize(); + // Return the (conservative) maximum heap alignment for any G1 heap + static size_t conservative_max_heap_alignment(); + // Initialize weak reference processing. virtual void ref_processing_init(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp index e66268885e3..726acbfcdc0 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -149,6 +149,10 @@ void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr, // many regions in the heap (based on the min heap size). #define TARGET_REGION_NUMBER 2048 +size_t HeapRegion::max_region_size() { + return (size_t)MAX_REGION_SIZE; +} + void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) { uintx region_size = G1HeapRegionSize; if (FLAG_IS_DEFAULT(G1HeapRegionSize)) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp index 097c0b54380..ad2b0649795 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -355,6 +355,8 @@ class HeapRegion: public G1OffsetTableContigSpace { ~((1 << (size_t) LogOfHRGrainBytes) - 1); } + static size_t max_region_size(); + // It sets up the heap region size (GrainBytes / GrainWords), as // well as other related fields that are based on the heap region // size (LogOfHRGrainBytes / LogOfHRGrainWords / diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp index 11ef5325120..4e458efa903 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp @@ -86,6 +86,11 @@ class ParallelScavengeHeap : public CollectedHeap { set_alignment(_old_gen_alignment, intra_heap_alignment()); } + // Return the (conservative) maximum heap alignment + static size_t conservative_max_heap_alignment() { + return intra_heap_alignment(); + } + // For use by VM operations enum CollectionType { Scavenge, @@ -122,7 +127,7 @@ class ParallelScavengeHeap : public CollectedHeap { // The alignment used for eden and survivors within the young gen // and for boundary between young gen and old gen. - size_t intra_heap_alignment() const { return 64 * K * HeapWordSize; } + static size_t intra_heap_alignment() { return 64 * K * HeapWordSize; } size_t capacity() const; size_t used() const; diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index 6a1967daeda..a5b4aa61894 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -145,6 +145,30 @@ void CollectorPolicy::cleared_all_soft_refs() { _all_soft_refs_clear = true; } +size_t CollectorPolicy::compute_max_alignment() { + // The card marking array and the offset arrays for old generations are + // committed in os pages as well. Make sure they are entirely full (to + // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1 + // byte entry and the os page size is 4096, the maximum heap size should + // be 512*4096 = 2MB aligned. + + // There is only the GenRemSet in Hotspot and only the GenRemSet::CardTable + // is supported. + // Requirements of any new remembered set implementations must be added here. + size_t alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable); + + // Parallel GC does its own alignment of the generations to avoid requiring a + // large page (256M on some platforms) for the permanent generation. The + // other collectors should also be updated to do their own alignment and then + // this use of lcm() should be removed. + if (UseLargePages && !UseParallelGC) { + // in presence of large pages we have to make sure that our + // alignment is large page aware + alignment = lcm(os::large_page_size(), alignment); + } + + return alignment; +} // GenCollectorPolicy methods. @@ -175,29 +199,6 @@ void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size, GCTimeRatio); } -size_t GenCollectorPolicy::compute_max_alignment() { - // The card marking array and the offset arrays for old generations are - // committed in os pages as well. Make sure they are entirely full (to - // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1 - // byte entry and the os page size is 4096, the maximum heap size should - // be 512*4096 = 2MB aligned. - size_t alignment = GenRemSet::max_alignment_constraint(rem_set_name()); - - // Parallel GC does its own alignment of the generations to avoid requiring a - // large page (256M on some platforms) for the permanent generation. The - // other collectors should also be updated to do their own alignment and then - // this use of lcm() should be removed. - if (UseLargePages && !UseParallelGC) { - // in presence of large pages we have to make sure that our - // alignment is large page aware - alignment = lcm(os::large_page_size(), alignment); - } - - assert(alignment >= min_alignment(), "Must be"); - - return alignment; -} - void GenCollectorPolicy::initialize_flags() { // All sizes must be multiples of the generation granularity. set_min_alignment((uintx) Generation::GenGrain); diff --git a/hotspot/src/share/vm/memory/collectorPolicy.hpp b/hotspot/src/share/vm/memory/collectorPolicy.hpp index 4acf7ba780c..73fd177d7ba 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.hpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp @@ -98,6 +98,9 @@ class CollectorPolicy : public CHeapObj { {} public: + // Return maximum heap alignment that may be imposed by the policy + static size_t compute_max_alignment(); + void set_min_alignment(size_t align) { _min_alignment = align; } size_t min_alignment() { return _min_alignment; } void set_max_alignment(size_t align) { _max_alignment = align; } @@ -234,9 +237,6 @@ class GenCollectorPolicy : public CollectorPolicy { // Try to allocate space by expanding the heap. virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab); - // compute max heap alignment - size_t compute_max_alignment(); - // Scale the base_size by NewRation according to // result = base_size / (NewRatio + 1) // and align by min_alignment() diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp index 9ab9d1991df..8f814132a78 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -148,6 +148,11 @@ public: return gen_policy()->size_policy(); } + // Return the (conservative) maximum heap alignment + static size_t conservative_max_heap_alignment() { + return Generation::GenGrain; + } + size_t capacity() const; size_t used() const; diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index d0f34b33ae1..54d6851d16d 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -872,6 +872,9 @@ jint Universe::initialize_heap() { // Reserve the Java heap, which is now the same for all GCs. ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { + assert(alignment <= Arguments::conservative_max_heap_alignment(), + err_msg("actual alignment "SIZE_FORMAT" must be within maximum heap alignment "SIZE_FORMAT, + alignment, Arguments::conservative_max_heap_alignment())); size_t total_reserved = align_size_up(heap_size, alignment); assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())), "heap size is too big for compressed oops"); diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp index 0f5607e22b2..6f6a2000a3f 100644 --- a/hotspot/src/share/vm/prims/whitebox.cpp +++ b/hotspot/src/share/vm/prims/whitebox.cpp @@ -33,6 +33,7 @@ #include "prims/whitebox.hpp" #include "prims/wbtestmethods/parserTests.hpp" +#include "runtime/arguments.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" @@ -94,6 +95,11 @@ WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name)) return closure.found(); WB_END +WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) { + return (jlong)Arguments::max_heap_for_compressed_oops(); +} +WB_END + WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) { CollectorPolicy * p = Universe::heap()->collector_policy(); gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap " @@ -436,6 +442,8 @@ static JNINativeMethod methods[] = { CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", (void*) &WB_ParseCommandLine }, + {CC"getCompressedOopsMaxHeapSize", CC"()J", + (void*)&WB_GetCompressedOopsMaxHeapSize}, {CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes }, #if INCLUDE_ALL_GCS {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark}, diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index fbce8b6b695..9751c552233 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -28,6 +28,7 @@ #include "compiler/compilerOracle.hpp" #include "memory/allocation.inline.hpp" #include "memory/cardTableRS.hpp" +#include "memory/genCollectedHeap.hpp" #include "memory/referenceProcessor.hpp" #include "memory/universe.inline.hpp" #include "oops/oop.inline.hpp" @@ -54,6 +55,8 @@ #endif #if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" +#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" +#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" #endif // INCLUDE_ALL_GCS // Note: This is a special bug reporting site for the JVM @@ -90,6 +93,7 @@ char* Arguments::_java_command = NULL; SystemProperty* Arguments::_system_properties = NULL; const char* Arguments::_gc_log_filename = NULL; bool Arguments::_has_profile = false; +size_t Arguments::_conservative_max_heap_alignment = 0; uintx Arguments::_min_heap_size = 0; Arguments::Mode Arguments::_mode = _mixed; bool Arguments::_java_compiler = false; @@ -1391,10 +1395,17 @@ bool verify_object_alignment() { return true; } -inline uintx max_heap_for_compressed_oops() { +uintx Arguments::max_heap_for_compressed_oops() { // Avoid sign flip. assert(OopEncodingHeapMax > (uint64_t)os::vm_page_size(), "Unusual page size"); - LP64_ONLY(return OopEncodingHeapMax - os::vm_page_size()); + // We need to fit both the NULL page and the heap into the memory budget, while + // keeping alignment constraints of the heap. To guarantee the latter, as the + // NULL page is located before the heap, we pad the NULL page to the conservative + // maximum alignment that the GC may ever impose upon the heap. + size_t displacement_due_to_null_page = align_size_up_(os::vm_page_size(), + Arguments::conservative_max_heap_alignment()); + + LP64_ONLY(return OopEncodingHeapMax - displacement_due_to_null_page); NOT_LP64(ShouldNotReachHere(); return 0); } @@ -1475,6 +1486,23 @@ void Arguments::set_use_compressed_klass_ptrs() { #endif // !ZERO } +void Arguments::set_conservative_max_heap_alignment() { + // The conservative maximum required alignment for the heap is the maximum of + // the alignments imposed by several sources: any requirements from the heap + // itself, the collector policy and the maximum page size we may run the VM + // with. + size_t heap_alignment = GenCollectedHeap::conservative_max_heap_alignment(); +#if INCLUDE_ALL_GCS + if (UseParallelGC) { + heap_alignment = ParallelScavengeHeap::conservative_max_heap_alignment(); + } else if (UseG1GC) { + heap_alignment = G1CollectedHeap::conservative_max_heap_alignment(); + } +#endif // INCLUDE_ALL_GCS + _conservative_max_heap_alignment = MAX3(heap_alignment, os::max_page_size(), + CollectorPolicy::compute_max_alignment()); +} + void Arguments::set_ergonomics_flags() { if (os::is_server_class_machine()) { @@ -1503,6 +1531,8 @@ void Arguments::set_ergonomics_flags() { } } + set_conservative_max_heap_alignment(); + #ifndef ZERO #ifdef _LP64 set_use_compressed_oops(); @@ -3506,6 +3536,11 @@ jint Arguments::parse(const JavaVMInitArgs* args) { no_shared_spaces(); #endif // INCLUDE_CDS + return JNI_OK; +} + +jint Arguments::apply_ergo() { + // Set flags based on ergonomics. set_ergonomics_flags(); diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index 43256b75082..c2f4c9883f1 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -280,6 +280,9 @@ class Arguments : AllStatic { // Option flags static bool _has_profile; static const char* _gc_log_filename; + // Value of the conservative maximum heap alignment needed + static size_t _conservative_max_heap_alignment; + static uintx _min_heap_size; // -Xrun arguments @@ -327,6 +330,7 @@ class Arguments : AllStatic { // Garbage-First (UseG1GC) static void set_g1_gc_flags(); // GC ergonomics + static void set_conservative_max_heap_alignment(); static void set_use_compressed_oops(); static void set_use_compressed_klass_ptrs(); static void set_ergonomics_flags(); @@ -430,8 +434,10 @@ class Arguments : AllStatic { static char* SharedArchivePath; public: - // Parses the arguments + // Parses the arguments, first phase static jint parse(const JavaVMInitArgs* args); + // Apply ergonomics + static jint apply_ergo(); // Adjusts the arguments after the OS have adjusted the arguments static jint adjust_after_os(); // Check for consistency in the selection of the garbage collector. @@ -445,6 +451,10 @@ class Arguments : AllStatic { // Used by os_solaris static bool process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized); + static size_t conservative_max_heap_alignment() { return _conservative_max_heap_alignment; } + // Return the maximum size a heap with compressed oops can take + static size_t max_heap_for_compressed_oops(); + // return a char* array containing all options static char** jvm_flags_array() { return _jvm_flags_array; } static char** jvm_args_array() { return _jvm_args_array; } diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index 0c83565195c..8f49f4a2edf 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -314,6 +314,11 @@ static void signal_thread_entry(JavaThread* thread, TRAPS) { } } +void os::init_before_ergo() { + // We need to initialize large page support here because ergonomics takes some + // decisions depending on large page support and the calculated large page size. + large_page_init(); +} void os::signal_init() { if (!ReduceSignalUsage) { diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index e43d68981cb..3438badb095 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -139,7 +139,10 @@ class os: AllStatic { public: static void init(void); // Called before command line parsing + static void init_before_ergo(void); // Called after command line parsing + // before VM ergonomics processing. static jint init_2(void); // Called after command line parsing + // and VM ergonomics processing static void init_globals(void) { // Called from init_globals() in init.cpp init_globals_ext(); } @@ -254,6 +257,11 @@ class os: AllStatic { static size_t page_size_for_region(size_t region_min_size, size_t region_max_size, uint min_pages); + // Return the largest page size that can be used + static size_t max_page_size() { + // The _page_sizes array is sorted in descending order. + return _page_sizes[0]; + } // Methods for tracing page sizes returned by the above method; enabled by // TracePageSizes. The region_{min,max}_size parameters should be the values diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index d5bc3a00006..02bd4b38f24 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -3329,6 +3329,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { jint parse_result = Arguments::parse(args); if (parse_result != JNI_OK) return parse_result; + os::init_before_ergo(); + + jint ergo_result = Arguments::apply_ergo(); + if (ergo_result != JNI_OK) return ergo_result; + if (PauseAtStartup) { os::pause(); } diff --git a/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java b/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java new file mode 100644 index 00000000000..852076e768e --- /dev/null +++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2013, 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 TestUseCompressedOopsErgo + * @key gc + * @bug 8010722 + * @summary Tests ergonomics for UseCompressedOops. + * @library /testlibrary /testlibrary/whitebox + * @build TestUseCompressedOopsErgo TestUseCompressedOopsErgoTools + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseG1GC + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseParallelGC + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseParallelGC -XX:-UseParallelOldGC + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseConcMarkSweepGC + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseSerialGC + */ + +public class TestUseCompressedOopsErgo { + + public static void main(String args[]) throws Exception { + if (!TestUseCompressedOopsErgoTools.is64bitVM()) { + // this test is relevant for 64 bit VMs only + return; + } + final String[] gcFlags = args; + TestUseCompressedOopsErgoTools.checkCompressedOopsErgo(gcFlags); + } +} + diff --git a/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java b/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java new file mode 100644 index 00000000000..49d0a8a1d21 --- /dev/null +++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java @@ -0,0 +1,179 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +import sun.management.ManagementFactoryHelper; +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.ArrayList; +import java.util.Arrays; + +import com.oracle.java.testlibrary.*; +import sun.hotspot.WhiteBox; + +class DetermineMaxHeapForCompressedOops { + public static void main(String[] args) throws Exception { + WhiteBox wb = WhiteBox.getWhiteBox(); + System.out.print(wb.getCompressedOopsMaxHeapSize()); + } +} + +class TestUseCompressedOopsErgoTools { + + private static long getClassMetaspaceSize() { + HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); + + VMOption option = diagnostic.getVMOption("ClassMetaspaceSize"); + return Long.parseLong(option.getValue()); + } + + + public static long getMaxHeapForCompressedOops(String[] vmargs) throws Exception { + OutputAnalyzer output = runWhiteBoxTest(vmargs, DetermineMaxHeapForCompressedOops.class.getName(), new String[] {}, false); + return Long.parseLong(output.getStdout()); + } + + public static boolean is64bitVM() { + String val = System.getProperty("sun.arch.data.model"); + if (val == null) { + throw new RuntimeException("Could not read sun.arch.data.model"); + } + if (val.equals("64")) { + return true; + } else if (val.equals("32")) { + return false; + } + throw new RuntimeException("Unexpected value " + val + " of sun.arch.data.model"); + } + + /** + * Executes a new VM process with the given class and parameters. + * @param vmargs Arguments to the VM to run + * @param classname Name of the class to run + * @param arguments Arguments to the class + * @param useTestDotJavaDotOpts Use test.java.opts as part of the VM argument string + * @return The OutputAnalyzer with the results for the invocation. + */ + public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, String[] arguments, boolean useTestDotJavaDotOpts) throws Exception { + ArrayList finalargs = new ArrayList(); + + String[] whiteboxOpts = new String[] { + "-Xbootclasspath/a:.", + "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", + "-cp", System.getProperty("java.class.path"), + }; + + if (useTestDotJavaDotOpts) { + // System.getProperty("test.java.opts") is '' if no options is set, + // we need to skip such a result + String[] externalVMOpts = new String[0]; + if (System.getProperty("test.java.opts") != null && System.getProperty("test.java.opts").length() != 0) { + externalVMOpts = System.getProperty("test.java.opts").split(" "); + } + finalargs.addAll(Arrays.asList(externalVMOpts)); + } + + finalargs.addAll(Arrays.asList(vmargs)); + finalargs.addAll(Arrays.asList(whiteboxOpts)); + finalargs.add(classname); + finalargs.addAll(Arrays.asList(arguments)); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0])); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + return output; + } + + private static String[] join(String[] part1, String part2) { + ArrayList result = new ArrayList(); + result.addAll(Arrays.asList(part1)); + result.add(part2); + return result.toArray(new String[0]); + } + + public static void checkCompressedOopsErgo(String[] gcflags) throws Exception { + long maxHeapForCompressedOops = getMaxHeapForCompressedOops(gcflags); + + checkUseCompressedOops(gcflags, maxHeapForCompressedOops, true); + checkUseCompressedOops(gcflags, maxHeapForCompressedOops - 1, true); + checkUseCompressedOops(gcflags, maxHeapForCompressedOops + 1, false); + + // the use of HeapBaseMinAddress should not change the outcome + checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops, true); + checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops - 1, true); + checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops + 1, false); + + // use a different object alignment + maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16")); + + checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops, true); + checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops - 1, true); + checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops + 1, false); + + // use a different ClassMetaspaceSize + String classMetaspaceSizeArg = "-XX:ClassMetaspaceSize=" + 2 * getClassMetaspaceSize(); + maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, classMetaspaceSizeArg)); + + checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops, true); + checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops - 1, true); + checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops + 1, false); + } + + private static void checkUseCompressedOops(String[] args, long heapsize, boolean expectUseCompressedOops) throws Exception { + ArrayList finalargs = new ArrayList(); + finalargs.addAll(Arrays.asList(args)); + finalargs.add("-Xmx" + heapsize); + finalargs.add("-XX:+PrintFlagsFinal"); + finalargs.add("-version"); + + String output = expectValid(finalargs.toArray(new String[0])); + + boolean actualUseCompressedOops = getFlagBoolValue(" UseCompressedOops", output); + + if (expectUseCompressedOops != actualUseCompressedOops) { + throw new RuntimeException("Expected use of compressed oops: " + expectUseCompressedOops + " but was: " + actualUseCompressedOops); + } + } + + private static boolean getFlagBoolValue(String flag, String where) { + Matcher m = Pattern.compile(flag + "\\s+:?= (true|false)").matcher(where); + if (!m.find()) { + throw new RuntimeException("Could not find value for flag " + flag + " in output string"); + } + String match = m.group(1).equals("true"); + } + + private static String expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(errorcode); + return output.getStdout(); + } + + private static String expectValid(String[] flags) throws Exception { + return expect(flags, false, false, 0); + } +} + diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java index c508b8f121a..091b5f7543b 100644 --- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java +++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java @@ -61,6 +61,8 @@ public class WhiteBox { registerNatives(); } + // Get the maximum heap size supporting COOPs + public native long getCompressedOopsMaxHeapSize(); // Arguments public native void printHeapSizes(); From f2db7a5c1c703306b1c1f60beef520bffa35111c Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 11 Sep 2013 20:49:28 +0530 Subject: [PATCH 0299/1294] 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations Reviewed-by: jlaskey, hannesw --- .../jdk/nashorn/api/scripting/JSObject.java | 187 +++++++++++-- .../api/scripting/NashornScriptEngine.java | 2 +- .../api/scripting/ScriptObjectMirror.java | 178 +++++++----- .../jdk/nashorn/internal/ir/IdentNode.java | 1 + .../internal/lookup/MethodHandleFactory.java | 2 +- .../nashorn/internal/objects/NativeArray.java | 4 +- .../internal/objects/NativeFunction.java | 32 ++- .../internal/runtime/ScriptRuntime.java | 38 ++- .../runtime/arrays/ArrayLikeIterator.java | 10 +- .../runtime/arrays/IteratorAction.java | 8 +- ...rorIterator.java => JSObjectIterator.java} | 14 +- ...ator.java => ReverseJSObjectIterator.java} | 8 +- .../internal/runtime/linker/Bootstrap.java | 4 +- .../runtime/linker/JSObjectLinker.java | 74 +++-- .../api/scripting/PluggableJSObjectTest.java | 257 ++++++++++++++++++ .../api/scripting/ScriptObjectMirrorTest.java | 12 +- 16 files changed, 646 insertions(+), 185 deletions(-) rename nashorn/src/jdk/nashorn/internal/runtime/arrays/{ScriptObjectMirrorIterator.java => JSObjectIterator.java} (82%) rename nashorn/src/jdk/nashorn/internal/runtime/arrays/{ReverseScriptObjectMirrorIterator.java => ReverseJSObjectIterator.java} (83%) create mode 100644 nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java diff --git a/nashorn/src/jdk/nashorn/api/scripting/JSObject.java b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java index 4f3a8e88f93..53b5790ee3e 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/JSObject.java +++ b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java @@ -25,73 +25,210 @@ package jdk.nashorn.api.scripting; +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + /** - * netscape.javascript.JSObject-like interface for nashorn script objects. + * This is the base class for nashorn ScriptObjectMirror class. + * + * This class can also be subclassed by an arbitrary Java class. Nashorn will + * treat objects of such classes just like nashorn script objects. Usual nashorn + * operations like obj[i], obj.foo, obj.func(), delete obj.foo will be glued + * to appropriate method call of this class. */ public abstract class JSObject { /** - * Call a JavaScript function + * Call this object as a JavaScript function. This is equivalent to + * 'func.apply(thiz, args)' in JavaScript. * - * @param functionName name of function + * @param thiz 'this' object to be passed to the function * @param args arguments to method * @return result of call */ - public abstract Object call(String functionName, Object... args); + public Object call(Object thiz, Object... args) { + throw new UnsupportedOperationException("call"); + } /** - * Call a JavaScript method as a constructor. This is equivalent to - * calling new obj.Method(arg1, arg2...) in JavaScript. + * Call this 'constructor' JavaScript function to create a new object. + * This is equivalent to 'new func(arg1, arg2...)' in JavaScript. * - * @param functionName name of function * @param args arguments to method * @return result of constructor call */ - public abstract Object newObject(String functionName, Object... args); + public Object newObject(Object... args) { + throw new UnsupportedOperationException("newObject"); + } /** - * Evaluate a JavaScript expression + * Evaluate a JavaScript expression. * * @param s JavaScript expression to evaluate * @return evaluation result */ - public abstract Object eval(String s); + public Object eval(String s) { + throw new UnsupportedOperationException("eval"); + } /** - * Retrieves a named member of a JavaScript object. + * Call a JavaScript function member of this object. + * + * @param name name of the member function to call + * @param args arguments to be passed to the member function + * @return result of call + */ + public Object callMember(String name, Object... args) { + throw new UnsupportedOperationException("call"); + } + + /** + * Retrieves a named member of this JavaScript object. * * @param name of member * @return member */ - public abstract Object getMember(String name); + public Object getMember(String name) { + return null; + } /** - * Retrieves an indexed member of a JavaScript object. + * Retrieves an indexed member of this JavaScript object. * - * @param index index of member slot + * @param index index slot to retrieve * @return member */ - public abstract Object getSlot(int index); + public Object getSlot(int index) { + return null; + } /** - * Remove a named member from a JavaScript object + * Does this object have a named member? * * @param name name of member + * @return true if this object has a member of the given name */ - public abstract void removeMember(String name); + public boolean hasMember(String name) { + return false; + } /** - * Set a named member in a JavaScript object + * Does this object have a indexed property? * - * @param name name of member - * @param value value of member + * @param slot index to check + * @return true if this object has a slot */ - public abstract void setMember(String name, Object value); + public boolean hasSlot(int slot) { + return false; + } /** - * Set an indexed member in a JavaScript object + * Remove a named member from this JavaScript object * - * @param index index of member slot - * @param value value of member + * @param name name of the member */ - public abstract void setSlot(int index, Object value); + public void removeMember(String name) { + } + + /** + * Set a named member in this JavaScript object + * + * @param name name of the member + * @param value value of the member + */ + public void setMember(String name, Object value) { + } + + /** + * Set an indexed member in this JavaScript object + * + * @param index index of the member slot + * @param value value of the member + */ + public void setSlot(int index, Object value) { + } + + // property and value iteration + + /** + * Returns the set of all property names of this object. + * + * @return set of property names + */ + @SuppressWarnings("unchecked") + public Set keySet() { + return Collections.EMPTY_SET; + } + + /** + * Returns the set of all property values of this object. + * + * @return set of property values. + */ + @SuppressWarnings("unchecked") + public Collection values() { + return Collections.EMPTY_SET; + } + + // JavaScript instanceof check + + /** + * Checking whether the given object is an instance of 'this' object. + * + * @param instance instace to check + * @return true if the given 'instance' is an instance of this 'function' object + */ + public boolean isInstance(final Object instance) { + return false; + } + + /** + * Checking whether this object is an instance of the given 'clazz' object. + * + * @param clazz clazz to check + * @return true if this object is an instance of the given 'clazz' + */ + public boolean isInstanceOf(final Object clazz) { + if (clazz instanceof JSObject) { + return ((JSObject)clazz).isInstance(this); + } + + return false; + } + + /** + * ECMA [[Class]] property + * + * @return ECMA [[Class]] property value of this object + */ + public String getClassName() { + return getClass().getName(); + } + + /** + * Is this a function object? + * + * @return if this mirror wraps a ECMAScript function instance + */ + public boolean isFunction() { + return false; + } + + /** + * Is this a 'use strict' function object? + * + * @return true if this mirror represents a ECMAScript 'use strict' function + */ + public boolean isStrictFunction() { + return false; + } + + /** + * Is this an array object? + * + * @return if this mirror wraps a ECMAScript array object + */ + public boolean isArray() { + return false; + } } diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index ce42a46c7b5..45eddd117aa 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -494,7 +494,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C if (selfMirror != null) { try { - return ScriptObjectMirror.translateUndefined(selfMirror.call(name, args)); + return ScriptObjectMirror.translateUndefined(selfMirror.callMember(name, args)); } catch (final Exception e) { final Throwable cause = e.getCause(); if (cause instanceof NoSuchMethodException) { diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java index e8546cd6ce7..3a27d23e303 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java @@ -48,9 +48,7 @@ import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; /** - * Mirror object that wraps a given ScriptObject instance. User can - * access ScriptObject via the javax.script.Bindings interface or - * netscape.javascript.JSObject interface. + * Mirror object that wraps a given Nashorn Script object. */ public final class ScriptObjectMirror extends JSObject implements Bindings { private static AccessControlContext getContextAccCtxt() { @@ -90,8 +88,9 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { } // JSObject methods + @Override - public Object call(final String functionName, final Object... args) { + public Object call(final Object thiz, final Object... args) { final ScriptObject oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); @@ -100,15 +99,13 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { Context.setGlobal(global); } - final Object val = functionName == null? sobj : sobj.get(functionName); - if (val instanceof ScriptFunction) { + if (sobj instanceof ScriptFunction) { final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; - return wrap(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); - } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { - return ((ScriptObjectMirror)val).call(null, args); + final Object self = globalChanged? wrap(thiz, oldGlobal) : thiz; + return wrap(ScriptRuntime.apply((ScriptFunction)sobj, unwrap(self, global), unwrapArray(modArgs, global)), global); } - throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : "")); + throw new RuntimeException("not a function: " + toString()); } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { @@ -121,7 +118,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { } @Override - public Object newObject(final String functionName, final Object... args) { + public Object newObject(final Object... args) { final ScriptObject oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); @@ -130,15 +127,12 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { Context.setGlobal(global); } - final Object val = functionName == null? sobj : sobj.get(functionName); - if (val instanceof ScriptFunction) { + if (sobj instanceof ScriptFunction) { final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; - return wrap(ScriptRuntime.construct((ScriptFunction)val, unwrapArray(modArgs, global)), global); - } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { - return ((ScriptObjectMirror)val).newObject(null, args); + return wrap(ScriptRuntime.construct((ScriptFunction)sobj, unwrapArray(modArgs, global)), global); } - throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : "")); + throw new RuntimeException("not a constructor: " + toString()); } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { @@ -167,8 +161,40 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } + @Override + public Object callMember(final String functionName, final Object... args) { + functionName.getClass(); // null check + final ScriptObject oldGlobal = Context.getGlobal(); + final boolean globalChanged = (oldGlobal != global); + + try { + if (globalChanged) { + Context.setGlobal(global); + } + + final Object val = sobj.get(functionName); + if (val instanceof ScriptFunction) { + final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; + return wrap(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); + } else if (val instanceof JSObject && ((JSObject)val).isFunction()) { + return ((JSObject)val).call(sobj, args); + } + + throw new NoSuchMethodException("No such function " + functionName); + } catch (final RuntimeException | Error e) { + throw e; + } catch (final Throwable t) { + throw new RuntimeException(t); + } finally { + if (globalChanged) { + Context.setGlobal(oldGlobal); + } + } + } + @Override public Object getMember(final String name) { + name.getClass(); return inGlobal(new Callable() { @Override public Object call() { return wrap(sobj.get(name), global); @@ -185,13 +211,34 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } + @Override + public boolean hasMember(final String name) { + name.getClass(); + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.has(name); + } + }); + } + + @Override + public boolean hasSlot(final int slot) { + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.has(slot); + } + }); + } + @Override public void removeMember(final String name) { + name.getClass(); remove(name); } @Override public void setMember(final String name, final Object value) { + name.getClass(); put(name, value); } @@ -205,6 +252,45 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } + @Override + public boolean isInstance(final Object obj) { + if (! (obj instanceof ScriptObjectMirror)) { + return false; + } + + final ScriptObjectMirror instance = (ScriptObjectMirror)obj; + // if not belongs to my global scope, return false + if (global != instance.global) { + return false; + } + + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.isInstance(instance.sobj); + } + }); + } + + @Override + public String getClassName() { + return sobj.getClassName(); + } + + @Override + public boolean isFunction() { + return sobj instanceof ScriptFunction; + } + + @Override + public boolean isStrictFunction() { + return isFunction() && ((ScriptFunction)sobj).isStrict(); + } + + @Override + public boolean isArray() { + return sobj.isArray(); + } + // javax.script.Bindings methods @Override @@ -391,15 +477,6 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } - /** - * ECMA [[Class]] property - * - * @return ECMA [[Class]] property value of this object - */ - public String getClassName() { - return sobj.getClassName(); - } - /** * ECMA 8.12.1 [[GetOwnProperty]] (P) * @@ -506,55 +583,6 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } - // ECMAScript instanceof check - - /** - * Checking whether a script object is an instance of another by - * walking the proto chain - * - * @param instance instace to check - * @return true if 'instance' is an instance of this object - */ - public boolean isInstance(final ScriptObjectMirror instance) { - // if not belongs to my global scope, return false - if (instance == null || global != instance.global) { - return false; - } - - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.isInstance(instance.sobj); - } - }); - } - - /** - * is this a function object? - * - * @return if this mirror wraps a ECMAScript function instance - */ - public boolean isFunction() { - return sobj instanceof ScriptFunction; - } - - /** - * is this a 'use strict' function object? - * - * @return true if this mirror represents a ECMAScript 'use strict' function - */ - public boolean isStrictFunction() { - return isFunction() && ((ScriptFunction)sobj).isStrict(); - } - - /** - * is this an array object? - * - * @return if this mirror wraps a ECMAScript array object - */ - public boolean isArray() { - return sobj.isArray(); - } - /** * Utility to check if given object is ECMAScript undefined value * diff --git a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java index cec111a2cd2..4b139b255a2 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java @@ -168,6 +168,7 @@ public final class IdentNode extends Expression implements PropertyKey, TypeOver * return 3; * } * } + * * * @return true if can have callsite type */ diff --git a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java index 4d8a2977e33..34fe2eb6a87 100644 --- a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java +++ b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java @@ -565,7 +565,7 @@ public final class MethodHandleFactory { @Override public MethodHandle asSpreader(final MethodHandle handle, final Class arrayType, final int arrayLength) { - final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength); + final MethodHandle mh = super.asSpreader(handle, arrayType, arrayLength); return debug(mh, "asSpreader", handle, arrayType, arrayLength); } diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java index 54f293873ed..8cb1ded934c 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java @@ -41,7 +41,7 @@ import java.util.Iterator; import java.util.List; import java.util.concurrent.Callable; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; @@ -374,7 +374,7 @@ public final class NativeArray extends ScriptObject { public static Object isArray(final Object self, final Object arg) { return isArray(arg) || (arg == Global.instance().getArrayPrototype()) || (arg instanceof NativeRegExpExecResult) - || (arg instanceof ScriptObjectMirror && ((ScriptObjectMirror)arg).isArray()); + || (arg instanceof JSObject && ((JSObject)arg).isArray()); } /** diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java index c208a35ce7e..c77002e310b 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java @@ -30,7 +30,7 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; import java.util.List; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; @@ -88,7 +88,7 @@ public final class NativeFunction { */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object apply(final Object self, final Object thiz, final Object array) { - if (!(self instanceof ScriptFunction)) { + if (!(self instanceof ScriptFunction) && !(self instanceof JSObject)) { throw typeError("not.a.function", ScriptRuntime.safeToString(self)); } @@ -111,21 +111,27 @@ public final class NativeFunction { list.toArray(args = new Object[list.size()]); } else if (array == null || array == UNDEFINED) { args = ScriptRuntime.EMPTY_ARRAY; - } else if (array instanceof ScriptObjectMirror) { - // look for array-like ScriptObjectMirror object - final ScriptObjectMirror mirror = (ScriptObjectMirror)array; - final Object len = mirror.containsKey("length")? mirror.getMember("length") : Integer.valueOf(0); + } else if (array instanceof JSObject) { + // look for array-like JSObject object + final JSObject jsObj = (JSObject)array; + final Object len = jsObj.hasMember("length")? jsObj.getMember("length") : Integer.valueOf(0); final int n = (int)JSType.toUint32(len); args = new Object[n]; for (int i = 0; i < args.length; i++) { - args[i] = mirror.containsKey(i)? mirror.getSlot(i) : UNDEFINED; + args[i] = jsObj.hasSlot(i)? jsObj.getSlot(i) : UNDEFINED; } } else { throw typeError("function.apply.expects.array"); } - return ScriptRuntime.apply((ScriptFunction)self, thiz, args); + if (self instanceof ScriptFunction) { + return ScriptRuntime.apply((ScriptFunction)self, thiz, args); + } else if (self instanceof JSObject) { + return ((JSObject)self).call(thiz, args); + } + + throw new AssertionError("should not reach here"); } /** @@ -137,7 +143,7 @@ public final class NativeFunction { */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static Object call(final Object self, final Object... args) { - if (!(self instanceof ScriptFunction)) { + if (!(self instanceof ScriptFunction) && !(self instanceof JSObject)) { throw typeError("not.a.function", ScriptRuntime.safeToString(self)); } @@ -151,7 +157,13 @@ public final class NativeFunction { arguments = ScriptRuntime.EMPTY_ARRAY; } - return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments); + if (self instanceof ScriptFunction) { + return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments); + } else if (self instanceof JSObject) { + return ((JSObject)self).call(thiz, arguments); + } + + throw new AssertionError("should not reach here"); } /** diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java index aa146f1df3d..c9b40512009 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java @@ -43,6 +43,7 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; import jdk.internal.dynalink.beans.StaticClass; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.ir.debug.JSONWriter; @@ -190,8 +191,8 @@ public final class ScriptRuntime { case FUNCTION: if (self instanceof ScriptObject) { className = ((ScriptObject)self).getClassName(); - } else if (self instanceof ScriptObjectMirror) { - className = ((ScriptObjectMirror)self).getClassName(); + } else if (self instanceof JSObject) { + className = ((JSObject)self).getClassName(); } else { className = self.getClass().getName(); } @@ -245,8 +246,8 @@ public final class ScriptRuntime { return new RangeIterator(Array.getLength(obj)); } - if (obj instanceof ScriptObjectMirror) { - return ((ScriptObjectMirror)obj).keySet().iterator(); + if (obj instanceof JSObject) { + return ((JSObject)obj).keySet().iterator(); } if (obj instanceof List) { @@ -323,8 +324,8 @@ public final class ScriptRuntime { }; } - if (obj instanceof ScriptObjectMirror) { - return ((ScriptObjectMirror)obj).values().iterator(); + if (obj instanceof JSObject) { + return ((JSObject)obj).values().iterator(); } if (obj instanceof Map) { @@ -571,8 +572,8 @@ public final class ScriptRuntime { throw typeError("cant.get.property", safeToString(property), "null"); } else if (JSType.isPrimitive(obj)) { obj = ((ScriptObject)JSType.toScriptObject(obj)).get(property); - } else if (obj instanceof ScriptObjectMirror) { - obj = ((ScriptObjectMirror)obj).getMember(property.toString()); + } else if (obj instanceof JSObject) { + obj = ((JSObject)obj).getMember(property.toString()); } else { obj = UNDEFINED; } @@ -624,6 +625,11 @@ public final class ScriptRuntime { return ((ScriptObject) JSType.toScriptObject(obj)).delete(property, Boolean.TRUE.equals(strict)); } + if (obj instanceof JSObject) { + ((JSObject)obj).removeMember(Objects.toString(property)); + return true; + } + // if object is not reference type, vacuously delete is successful. return true; } @@ -815,6 +821,10 @@ public final class ScriptRuntime { return ((ScriptObject)obj).has(property); } + if (obj instanceof JSObject) { + return ((JSObject)obj).hasMember(Objects.toString(property)); + } + return false; } @@ -841,11 +851,13 @@ public final class ScriptRuntime { return ((StaticClass)clazz).getRepresentedClass().isInstance(obj); } - if (clazz instanceof ScriptObjectMirror) { - if (obj instanceof ScriptObjectMirror) { - return ((ScriptObjectMirror)clazz).isInstance((ScriptObjectMirror)obj); - } - return false; + if (clazz instanceof JSObject) { + return ((JSObject)clazz).isInstance(obj); + } + + // provide for reverse hook + if (obj instanceof JSObject) { + return ((JSObject)obj).isInstanceOf(clazz); } throw typeError("instanceof.on.non.object"); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java index 044b21d5879..962b1f9e031 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java @@ -27,7 +27,7 @@ package jdk.nashorn.internal.runtime.arrays; import java.util.Iterator; import java.util.List; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptObject; @@ -127,8 +127,8 @@ abstract public class ArrayLikeIterator implements Iterator { return new ScriptObjectIterator((ScriptObject)obj, includeUndefined); } - if (obj instanceof ScriptObjectMirror) { - return new ScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined); + if (obj instanceof JSObject) { + return new JSObjectIterator((JSObject)obj, includeUndefined); } if (obj instanceof List) { @@ -160,8 +160,8 @@ abstract public class ArrayLikeIterator implements Iterator { return new ReverseScriptObjectIterator((ScriptObject)obj, includeUndefined); } - if (obj instanceof ScriptObjectMirror) { - return new ReverseScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined); + if (obj instanceof JSObject) { + return new ReverseJSObjectIterator((JSObject)obj, includeUndefined); } if (obj instanceof List) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java index 9b6cbb447fe..244739b389d 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java @@ -27,7 +27,7 @@ package jdk.nashorn.internal.runtime.arrays; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptRuntime; @@ -101,9 +101,9 @@ public abstract class IteratorAction { final boolean strict; if (callbackfn instanceof ScriptFunction) { strict = ((ScriptFunction)callbackfn).isStrict(); - } else if (callbackfn instanceof ScriptObjectMirror && - ((ScriptObjectMirror)callbackfn).isFunction()) { - strict = ((ScriptObjectMirror)callbackfn).isStrictFunction(); + } else if (callbackfn instanceof JSObject && + ((JSObject)callbackfn).isFunction()) { + strict = ((JSObject)callbackfn).isStrictFunction(); } else if (Bootstrap.isDynamicMethod(callbackfn) || Bootstrap.isFunctionalInterfaceObject(callbackfn)) { strict = false; } else { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java similarity index 82% rename from nashorn/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java rename to nashorn/src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java index a7bef158f57..885c77eb570 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java @@ -26,21 +26,21 @@ package jdk.nashorn.internal.runtime.arrays; import java.util.NoSuchElementException; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.JSType; /** * Iterator over a ScriptObjectMirror */ -class ScriptObjectMirrorIterator extends ArrayLikeIterator { +class JSObjectIterator extends ArrayLikeIterator { - protected final ScriptObjectMirror obj; + protected final JSObject obj; private final long length; - ScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) { + JSObjectIterator(final JSObject obj, final boolean includeUndefined) { super(includeUndefined); this.obj = obj; - this.length = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0); + this.length = JSType.toUint32(obj.hasMember("length")? obj.getMember("length") : 0); this.index = 0; } @@ -60,7 +60,7 @@ class ScriptObjectMirrorIterator extends ArrayLikeIterator { } while (indexInArray()) { - if (obj.containsKey(index) || includeUndefined) { + if (obj.hasSlot((int)index) || includeUndefined) { break; } bumpIndex(); @@ -72,7 +72,7 @@ class ScriptObjectMirrorIterator extends ArrayLikeIterator { @Override public Object next() { if (indexInArray()) { - return obj.get(bumpIndex()); + return obj.getSlot((int)bumpIndex()); } throw new NoSuchElementException(); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java similarity index 83% rename from nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java rename to nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java index 1e3e4000cdb..84c5c46dd12 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java @@ -25,17 +25,17 @@ package jdk.nashorn.internal.runtime.arrays; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.JSType; /** * Reverse iterator over a ScriptObjectMirror */ -final class ReverseScriptObjectMirrorIterator extends ScriptObjectMirrorIterator { +final class ReverseJSObjectIterator extends JSObjectIterator { - ReverseScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) { + ReverseJSObjectIterator(final JSObject obj, final boolean includeUndefined) { super(obj, includeUndefined); - this.index = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0) - 1; + this.index = JSType.toUint32(obj.hasMember("length")? obj.getMember("length") : 0) - 1; } @Override diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java index e190224a07b..f725817af4b 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java @@ -39,7 +39,7 @@ import jdk.internal.dynalink.beans.BeansLinker; import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkerServices; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.codegen.RuntimeCallSite; import jdk.nashorn.internal.runtime.JSType; @@ -87,7 +87,7 @@ public final class Bootstrap { } return obj instanceof ScriptFunction || - ((obj instanceof ScriptObjectMirror) && ((ScriptObjectMirror)obj).isFunction()) || + ((obj instanceof JSObject) && ((JSObject)obj).isFunction()) || isDynamicMethod(obj) || isFunctionalInterfaceObject(obj) || obj instanceof StaticClass; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java index 1b7eb66b4e9..45451a8bad7 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java @@ -30,7 +30,6 @@ import jdk.nashorn.internal.lookup.MethodHandleFactory; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; -import java.util.Objects; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; @@ -88,8 +87,9 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { case "setElem": return c > 2 ? findSetMethod(desc) : findSetIndexMethod(); case "call": - case "callMethod": return findCallMethod(desc, operator); + case "callMethod": + return findCallMethodMethod(desc, operator); case "new": return findNewMethod(desc); default: @@ -98,33 +98,37 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { } private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc) { - final MethodHandle getter = MH.insertArguments(JSOBJECT_GET, 1, desc.getNameToken(2)); + final MethodHandle getter = MH.insertArguments(JSOBJECT_GETMEMBER, 1, desc.getNameToken(2)); return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD); } private static GuardedInvocation findGetIndexMethod() { - return new GuardedInvocation(JSOBJECT_GET, null, IS_JSOBJECT_GUARD); + return new GuardedInvocation(JSOBJECTLINKER_GET, null, IS_JSOBJECT_GUARD); } private static GuardedInvocation findSetMethod(final CallSiteDescriptor desc) { - final MethodHandle getter = MH.insertArguments(JSOBJECT_PUT, 1, desc.getNameToken(2)); + final MethodHandle getter = MH.insertArguments(JSOBJECT_SETMEMBER, 1, desc.getNameToken(2)); return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD); } private static GuardedInvocation findSetIndexMethod() { - return new GuardedInvocation(JSOBJECT_PUT, null, IS_JSOBJECT_GUARD); + return new GuardedInvocation(JSOBJECTLINKER_PUT, null, IS_JSOBJECT_GUARD); } - private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final String operator) { - // if operator is "call", then 'self' is a JSObject function object already. Use 'call' as the method name - final String methodName = "callMethod".equals(operator)? desc.getNameToken(2) : "call"; - MethodHandle func = MH.insertArguments(JSOBJECT_CALL, 1, methodName); + private static GuardedInvocation findCallMethodMethod(final CallSiteDescriptor desc, final String operator) { + final String methodName = desc.getNameToken(2); + MethodHandle func = MH.insertArguments(JSOBJECT_CALLMEMBER, 1, methodName); func = MH.asCollector(func, Object[].class, desc.getMethodType().parameterCount() - 1); return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD); } + private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final String operator) { + final MethodHandle func = MH.asCollector(JSOBJECT_CALL, Object[].class, desc.getMethodType().parameterCount() - 2); + return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD); + } + private static GuardedInvocation findNewMethod(final CallSiteDescriptor desc) { - MethodHandle func = MH.asCollector(JSOBJECT_NEW, Object[].class, desc.getMethodType().parameterCount() - 1); + final MethodHandle func = MH.asCollector(JSOBJECT_NEW, Object[].class, desc.getMethodType().parameterCount() - 1); return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD); } @@ -135,36 +139,30 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { @SuppressWarnings("unused") private static Object get(final Object jsobj, final Object key) { - if (key instanceof String) { - return ((JSObject)jsobj).getMember((String)key); + if (key instanceof Integer) { + return ((JSObject)jsobj).getSlot((int)(Integer)key); } else if (key instanceof Number) { final int index = getIndex((Number)key); if (index > -1) { return ((JSObject)jsobj).getSlot(index); } + } else if (key instanceof String) { + return ((JSObject)jsobj).getMember((String)key); } return null; } @SuppressWarnings("unused") private static void put(final Object jsobj, final Object key, final Object value) { - if (key instanceof String) { - ((JSObject)jsobj).setMember((String)key, value); + if (key instanceof Integer) { + ((JSObject)jsobj).setSlot((int)(Integer)key, value); } else if (key instanceof Number) { ((JSObject)jsobj).setSlot(getIndex((Number)key), value); + } else if (key instanceof String) { + ((JSObject)jsobj).setMember((String)key, value); } } - @SuppressWarnings("unused") - private static Object call(final Object jsobj, final Object method, final Object... args) { - return ((JSObject)jsobj).call(Objects.toString(method), args); - } - - @SuppressWarnings("unused") - private static Object newObject(final Object jsobj, final Object... args) { - return ((JSObject)jsobj).newObject(null, args); - } - private static int getIndex(final Number n) { final double value = n.doubleValue(); return JSType.isRepresentableAsInt(value) ? (int)value : -1; @@ -172,11 +170,17 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality(); - private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class); - private static final MethodHandle JSOBJECT_GET = findOwnMH("get", Object.class, Object.class, Object.class); - private static final MethodHandle JSOBJECT_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class); - private static final MethodHandle JSOBJECT_CALL = findOwnMH("call", Object.class, Object.class, Object.class, Object[].class); - private static final MethodHandle JSOBJECT_NEW = findOwnMH("newObject", Object.class, Object.class, Object[].class); + // method handles of the current class + private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class); + private static final MethodHandle JSOBJECTLINKER_GET = findOwnMH("get", Object.class, Object.class, Object.class); + private static final MethodHandle JSOBJECTLINKER_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class); + + // method handles of JSObject class + private static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH("getMember", Object.class, String.class); + private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH("setMember", Void.TYPE, String.class, Object.class); + private static final MethodHandle JSOBJECT_CALLMEMBER = findJSObjectMH("callMember", Object.class, String.class, Object[].class); + private static final MethodHandle JSOBJECT_CALL = findJSObjectMH("call", Object.class, Object.class, Object[].class); + private static final MethodHandle JSOBJECT_NEW = findJSObjectMH("newObject", Object.class, Object[].class); private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { final Class own = JSObjectLinker.class; @@ -187,4 +191,14 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { return MH.findVirtual(MethodHandles.lookup(), own, name, mt); } } + + private static MethodHandle findJSObjectMH(final String name, final Class rtype, final Class... types) { + final Class own = JSObject.class; + final MethodType mt = MH.type(rtype, types); + try { + return MH.findVirtual(MethodHandles.publicLookup(), own, name, mt); + } catch (final MethodHandleFactory.LookupException e) { + return MH.findVirtual(MethodHandles.lookup(), own, name, mt); + } + } } diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java new file mode 100644 index 00000000000..1b531dfc0a8 --- /dev/null +++ b/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting; + +import java.nio.IntBuffer; +import java.util.Collection; +import java.util.HashMap; +import java.util.Set; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.fail; +import org.testng.annotations.Test; + +/** + * Tests for pluggable external impls. of jdk.nashorn.api.scripting.JSObject. + * + * JDK-8024615: Refactor ScriptObjectMirror and JSObject to support external + * JSObject implementations. + */ +public class PluggableJSObjectTest { + public static class MapWrapperObject extends JSObject { + private final HashMap map = new HashMap<>(); + + public HashMap getMap() { + return map; + } + + @Override + public Object getMember(String name) { + return map.get(name); + } + + @Override + public void setMember(String name, Object value) { + map.put(name, value); + } + + @Override + public boolean hasMember(String name) { + return map.containsKey(name); + } + + @Override + public void removeMember(String name) { + map.remove(name); + } + + @Override + public Set keySet() { + return map.keySet(); + } + + @Override + public Collection values() { + return map.values(); + } + } + + @Test + // Named property access on a JSObject + public void namedAccessTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final MapWrapperObject obj = new MapWrapperObject(); + e.put("obj", obj); + obj.getMap().put("foo", "bar"); + + // property-like access on MapWrapperObject objects + assertEquals(e.eval("obj.foo"), "bar"); + e.eval("obj.foo = 'hello'"); + assertEquals(e.eval("'foo' in obj"), Boolean.TRUE); + assertEquals(e.eval("obj.foo"), "hello"); + assertEquals(obj.getMap().get("foo"), "hello"); + e.eval("delete obj.foo"); + assertFalse(obj.getMap().containsKey("foo")); + assertEquals(e.eval("'foo' in obj"), Boolean.FALSE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class BufferObject extends JSObject { + private final IntBuffer buf; + + public BufferObject(int size) { + buf = IntBuffer.allocate(size); + } + + public IntBuffer getBuffer() { + return buf; + } + + @Override + public Object getMember(String name) { + return name.equals("length")? buf.capacity() : null; + } + + @Override + public boolean hasSlot(int i) { + return i > -1 && i < buf.capacity(); + } + + @Override + public Object getSlot(int i) { + return buf.get(i); + } + + @Override + public void setSlot(int i, Object value) { + buf.put(i, ((Number)value).intValue()); + } + + @Override + public boolean isArray() { + return true; + } + } + + @Test + // array-like indexed access for a JSObject + public void indexedAccessTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final BufferObject buf = new BufferObject(2); + e.put("buf", buf); + + // array-like access on BufferObject objects + assertEquals(e.eval("buf.length"), buf.getBuffer().capacity()); + e.eval("buf[0] = 23"); + assertEquals(buf.getBuffer().get(0), 23); + assertEquals(e.eval("buf[0]"), 23); + assertEquals(e.eval("buf[1]"), 0); + buf.getBuffer().put(1, 42); + assertEquals(e.eval("buf[1]"), 42); + assertEquals(e.eval("Array.isArray(buf)"), Boolean.TRUE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class Adder extends JSObject { + @Override + public Object call(Object thiz, Object... args) { + double res = 0.0; + for (Object arg : args) { + res += ((Number)arg).doubleValue(); + } + return res; + } + + @Override + public boolean isFunction() { + return true; + } + } + + @Test + // a callable JSObject + public void callableJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.put("sum", new Adder()); + // check callability of Adder objects + assertEquals(e.eval("typeof sum"), "function"); + assertEquals(((Number)e.eval("sum(1, 2, 3, 4, 5)")).intValue(), 15); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class Factory extends JSObject { + @Override + public Object newObject(Object... args) { + return new HashMap(); + } + + @Override + public boolean isFunction() { + return true; + } + } + + @Test + // a factory JSObject + public void factoryJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.put("Factory", new Factory()); + + // check new on Factory + assertEquals(e.eval("typeof Factory"), "function"); + assertEquals(e.eval("typeof new Factory()"), "object"); + assertEquals(e.eval("(new Factory()) instanceof java.util.Map"), Boolean.TRUE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + // iteration tests + public void iteratingJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final MapWrapperObject obj = new MapWrapperObject(); + obj.setMember("foo", "hello"); + obj.setMember("bar", "world"); + e.put("obj", obj); + + // check for..in + Object val = e.eval("var str = ''; for (i in obj) str += i; str"); + assertEquals(val.toString(), "foobar"); + + // check for..each..in + val = e.eval("var str = ''; for each (i in obj) str += i; str"); + assertEquals(val.toString(), "helloworld"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } +} diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java index 75f636ae6a0..c7b40c6367f 100644 --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java @@ -140,8 +140,8 @@ public class ScriptObjectMirrorTest { fail("obj[1] != 'world'"); } - if (!obj.call("func", new Object[0]).equals("hello")) { - fail("obj.call('func') != 'hello'"); + if (!obj.callMember("func", new Object[0]).equals("hello")) { + fail("obj.func() != 'hello'"); } // try setting properties @@ -210,8 +210,8 @@ public class ScriptObjectMirrorTest { e.eval("function func() {}"); e2.put("foo", e.get("func")); - final Object e2global = e2.eval("this"); - final Object newObj = ((ScriptObjectMirror) e2global).newObject("foo"); + final ScriptObjectMirror e2global = (ScriptObjectMirror)e2.eval("this"); + final Object newObj = ((ScriptObjectMirror)e2global.getMember("foo")).newObject(); assertTrue(newObj instanceof ScriptObjectMirror); } @@ -223,8 +223,8 @@ public class ScriptObjectMirrorTest { e.eval("function func() {}"); e2.put("func", e.get("func")); - final Object e2obj = e2.eval("({ foo: func })"); - final Object newObj = ((ScriptObjectMirror) e2obj).newObject("foo"); + final ScriptObjectMirror e2obj = (ScriptObjectMirror)e2.eval("({ foo: func })"); + final Object newObj = ((ScriptObjectMirror)e2obj.getMember("foo")).newObject(); assertTrue(newObj instanceof ScriptObjectMirror); } } From 08c5ec7136bedf676b62997ac8b25fb60ea6423b Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Wed, 11 Sep 2013 12:08:34 -0400 Subject: [PATCH 0300/1294] 8024320: Add s390(x) detection to platform.m4 Reviewed-by: erikj, ihse, dsamersoff --- common/autoconf/generated-configure.sh | 26 +++++++++++++++++++++++++- common/autoconf/platform.m4 | 12 ++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 63e9354611c..7679cc5c4df 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -3818,7 +3818,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1377850299 +DATE_WHEN_GENERATED=1378914658 ############################################################################### # @@ -6775,6 +6775,18 @@ test -n "$target_alias" && VAR_CPU_BITS=64 VAR_CPU_ENDIAN=big ;; + s390) + VAR_CPU=s390 + VAR_CPU_ARCH=s390 + VAR_CPU_BITS=32 + VAR_CPU_ENDIAN=big + ;; + s390x) + VAR_CPU=s390x + VAR_CPU_ARCH=s390 + VAR_CPU_BITS=64 + VAR_CPU_ENDIAN=big + ;; sparc) VAR_CPU=sparc VAR_CPU_ARCH=sparc @@ -6883,6 +6895,18 @@ $as_echo "$OPENJDK_BUILD_OS-$OPENJDK_BUILD_CPU" >&6; } VAR_CPU_BITS=64 VAR_CPU_ENDIAN=big ;; + s390) + VAR_CPU=s390 + VAR_CPU_ARCH=s390 + VAR_CPU_BITS=32 + VAR_CPU_ENDIAN=big + ;; + s390x) + VAR_CPU=s390x + VAR_CPU_ARCH=s390 + VAR_CPU_BITS=64 + VAR_CPU_ENDIAN=big + ;; sparc) VAR_CPU=sparc VAR_CPU_ARCH=sparc diff --git a/common/autoconf/platform.m4 b/common/autoconf/platform.m4 index ed2581c1005..71ae2ceab7b 100644 --- a/common/autoconf/platform.m4 +++ b/common/autoconf/platform.m4 @@ -60,6 +60,18 @@ AC_DEFUN([PLATFORM_EXTRACT_VARS_FROM_CPU], VAR_CPU_BITS=64 VAR_CPU_ENDIAN=big ;; + s390) + VAR_CPU=s390 + VAR_CPU_ARCH=s390 + VAR_CPU_BITS=32 + VAR_CPU_ENDIAN=big + ;; + s390x) + VAR_CPU=s390x + VAR_CPU_ARCH=s390 + VAR_CPU_BITS=64 + VAR_CPU_ENDIAN=big + ;; sparc) VAR_CPU=sparc VAR_CPU_ARCH=sparc From 75b2463cdefe789fd7745eeca987de81f27cf5b1 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 11 Sep 2013 22:51:34 +0530 Subject: [PATCH 0301/1294] 8024644: PluggableJSObject.iteratingJSObjectTest fails with jdk8-tl build Reviewed-by: jlaskey, hannesw --- .../src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java index 1b531dfc0a8..acb57164029 100644 --- a/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java +++ b/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java @@ -28,6 +28,7 @@ package jdk.nashorn.api.scripting; import java.nio.IntBuffer; import java.util.Collection; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Set; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; @@ -46,7 +47,7 @@ import org.testng.annotations.Test; */ public class PluggableJSObjectTest { public static class MapWrapperObject extends JSObject { - private final HashMap map = new HashMap<>(); + private final HashMap map = new LinkedHashMap<>(); public HashMap getMap() { return map; From a357688f61daa0311edebc9cc4a96e11c749bed8 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Wed, 11 Sep 2013 14:50:11 -0700 Subject: [PATCH 0302/1294] 8015496: Information that package is deprecated is missing in profiles view Reviewed-by: jjg --- .../html/AbstractPackageIndexWriter.java | 2 +- .../doclets/formats/html/HtmlDoclet.java | 13 ++++-- .../formats/html/PackageIndexWriter.java | 12 ++++-- .../formats/html/ProfileIndexFrameWriter.java | 12 ++++-- .../formats/html/ProfileWriterImpl.java | 25 +++++++++++ .../internal/toolkit/Configuration.java | 21 +++++++++- .../TestProfilesConfiguration.java | 35 +++++++++++++++- .../profile-rtjar-includes-nopkgs.txt | 41 +++++++++++++++++++ 8 files changed, 147 insertions(+), 14 deletions(-) create mode 100644 langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes-nopkgs.txt diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java index bd84d2caf2d..91877d1cdfa 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java @@ -157,7 +157,7 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter { addAllProfilesLink(div); } body.addContent(div); - if (configuration.showProfiles) { + if (configuration.showProfiles && configuration.profilePackages.size() > 0) { Content profileSummary = configuration.getResource("doclet.Profiles"); addProfilesList(profileSummary, body); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java index 24c95876e6f..bf61cd1fae5 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java @@ -205,13 +205,20 @@ public class HtmlDoclet extends AbstractDoclet { * {@inheritDoc} */ protected void generateProfileFiles() throws Exception { - if (configuration.showProfiles) { + if (configuration.showProfiles && configuration.profilePackages.size() > 0) { ProfileIndexFrameWriter.generate(configuration); Profile prevProfile = null, nextProfile; + String profileName; for (int i = 1; i < configuration.profiles.getProfileCount(); i++) { - ProfilePackageIndexFrameWriter.generate(configuration, Profile.lookup(i).name); + profileName = Profile.lookup(i).name; + // Generate profile package pages only if there are any packages + // in a profile to be documented. The profilePackages map will not + // contain an entry for the profile if there are no packages to be documented. + if (!configuration.shouldDocumentProfile(profileName)) + continue; + ProfilePackageIndexFrameWriter.generate(configuration, profileName); PackageDoc[] packages = configuration.profilePackages.get( - Profile.lookup(i).name); + profileName); PackageDoc prev = null, next; for (int j = 0; j < packages.length; j++) { // if -nodeprecated option is set and the package is marked as diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java index 7a67b38d102..caf0e0976a6 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java @@ -130,10 +130,14 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter { String profileName; for (int i = 1; i < configuration.profiles.getProfileCount(); i++) { profileName = Profile.lookup(i).name; - Content profileLinkContent = getTargetProfileLink("classFrame", - new StringContent(profileName), profileName); - Content li = HtmlTree.LI(profileLinkContent); - ul.addContent(li); + // If the profile has valid packages to be documented, add it to the + // profiles list on overview-summary.html page. + if (configuration.shouldDocumentProfile(profileName)) { + Content profileLinkContent = getTargetProfileLink("classFrame", + new StringContent(profileName), profileName); + Content li = HtmlTree.LI(profileLinkContent); + ul.addContent(li); + } } profilesDiv.addContent(ul); Content div = HtmlTree.DIV(HtmlStyle.contentContainer, profilesDiv); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java index c7217cd5037..c5caa90a10c 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java @@ -88,8 +88,13 @@ public class ProfileIndexFrameWriter extends AbstractProfileIndexWriter { Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading); HtmlTree ul = new HtmlTree(HtmlTag.UL); ul.setTitle(profilesLabel); + String profileName; for (int i = 1; i < profiles.getProfileCount(); i++) { - ul.addContent(getProfile(i)); + profileName = (Profile.lookup(i)).name; + // If the profile has valid packages to be documented, add it to the + // left-frame generated for profile index. + if (configuration.shouldDocumentProfile(profileName)) + ul.addContent(getProfile(profileName)); } div.addContent(ul); body.addContent(div); @@ -98,13 +103,12 @@ public class ProfileIndexFrameWriter extends AbstractProfileIndexWriter { /** * Gets each profile name as a separate link. * - * @param profile the profile being documented + * @param profileName the profile being documented * @return content for the profile link */ - protected Content getProfile(int profile) { + protected Content getProfile(String profileName) { Content profileLinkContent; Content profileLabel; - String profileName = (Profile.lookup(profile)).name; profileLabel = new StringContent(profileName); profileLinkContent = getHyperLink(DocPaths.profileFrame(profileName), profileLabel, "", "packageListFrame"); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileWriterImpl.java index 5dae2e944a4..ebe8b0d1e69 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileWriterImpl.java @@ -138,6 +138,7 @@ public class ProfileWriterImpl extends HtmlDocletWriter "classFrame", new StringContent(pkg.name()), profile.name); Content heading = HtmlTree.HEADING(HtmlTag.H3, pkgName); HtmlTree li = HtmlTree.LI(HtmlStyle.blockList, heading); + addPackageDeprecationInfo(li, pkg); return li; } @@ -174,6 +175,30 @@ public class ProfileWriterImpl extends HtmlDocletWriter true, contentTree); } + /** + * Add the profile package deprecation information to the documentation tree. + * + * @param li the content tree to which the deprecation information will be added + * @param pkg the PackageDoc that is added + */ + public void addPackageDeprecationInfo(Content li, PackageDoc pkg) { + Tag[] deprs; + if (Util.isDeprecated(pkg)) { + deprs = pkg.tags("deprecated"); + HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV); + deprDiv.addStyle(HtmlStyle.deprecatedContent); + Content deprPhrase = HtmlTree.SPAN(HtmlStyle.strong, deprecatedPhrase); + deprDiv.addContent(deprPhrase); + if (deprs.length > 0) { + Tag[] commentTags = deprs[0].inlineTags(); + if (commentTags.length > 0) { + addInlineDeprecatedComment(pkg, deprs[0], deprDiv); + } + } + li.addContent(deprDiv); + } + } + /** * Get "PREV PROFILE" link in the navigation bar. * diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java index 0337840d248..940f1c91294 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java @@ -396,6 +396,9 @@ public abstract class Configuration { interimResults.put(p, new ArrayList()); for (PackageDoc pkg: packages) { + if (nodeprecated && Util.isDeprecated(pkg)) { + continue; + } // the getProfile method takes a type name, not a package name, // but isn't particularly fussy about the simple name -- so just use * int i = profiles.getProfile(pkg.name().replace(".", "/") + "/*"); @@ -409,12 +412,17 @@ public abstract class Configuration { // Build the profilePackages structure used by the doclet profilePackages = new HashMap(); List prev = Collections.emptyList(); + int size; for (Map.Entry> e: interimResults.entrySet()) { Profile p = e.getKey(); List pkgs = e.getValue(); pkgs.addAll(prev); // each profile contains all lower profiles Collections.sort(pkgs); - profilePackages.put(p.name, pkgs.toArray(new PackageDoc[pkgs.size()])); + size = pkgs.size(); + // For a profile, if there are no packages to be documented, do not add + // it to profilePackages map. + if (size > 0) + profilePackages.put(p.name, pkgs.toArray(new PackageDoc[pkgs.size()])); prev = pkgs; } @@ -718,6 +726,17 @@ public abstract class Configuration { return true; } + /** + * Check the validity of the given profile. Return false if there are no + * valid packages to be documented for the profile. + * + * @param profileName the profile that needs to be validated. + * @return true if the profile has valid packages to be documented. + */ + public boolean shouldDocumentProfile(String profileName) { + return profilePackages.containsKey(profileName); + } + /** * Check the validity of the given Source or Output File encoding on this * platform. diff --git a/langtools/test/com/sun/javadoc/testProfiles/TestProfilesConfiguration.java b/langtools/test/com/sun/javadoc/testProfiles/TestProfilesConfiguration.java index 140728e1ac5..287cca02952 100644 --- a/langtools/test/com/sun/javadoc/testProfiles/TestProfilesConfiguration.java +++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfilesConfiguration.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8006124 8009684 8015663 + * @bug 8006124 8009684 8015663 8015496 * @summary Test javadoc options support for profiles. * @author Evgeniya Stepanova * @library ../lib/ @@ -35,6 +35,7 @@ public class TestProfilesConfiguration extends JavadocTester { //Test information. private static final String BUG_ID = "8006124-8009684"; private static final String PROFILE_CONFIGURATION_BUG_ID = BUG_ID + "-3"; + private static final String NODEPR_NOPKGS_BUG_ID = BUG_ID + "-4"; //Javadoc arguments. private static final String[] ARGS3 = new String[]{ "-d", PROFILE_CONFIGURATION_BUG_ID, "-sourcepath", SRC_DIR, "-nocomment", @@ -42,6 +43,30 @@ public class TestProfilesConfiguration extends JavadocTester { "-doctitle", "Simple doctitle", "-use", "pkg3", "pkg1", "pkg2", "pkg4", "pkg5", "-packagesheader", "Simple packages header","pkgDeprecated" }; + private static final String[] ARGS4 = new String[]{ + "-d", NODEPR_NOPKGS_BUG_ID, "-sourcepath", SRC_DIR, "-nocomment", "-nodeprecated", + "-keywords", "-Xprofilespath", SRC_DIR + FS + "profile-rtjar-includes-nopkgs.txt", + "-doctitle", "Simple doctitle", "-use", "-packagesheader", "Simple packages header", + "pkg1", "pkg2", "pkg3", "pkg4", "pkg5", "pkgDeprecated" + }; + private static final String[][] NODEPR_NOPKGS_TEST = { + {NODEPR_NOPKGS_BUG_ID + FS + "overview-summary.html", + "" + }, + {NODEPR_NOPKGS_BUG_ID + FS + "profile-overview-frame.html", + "" + } + }; + private static final String[][] NODEPR_NOPKGS_NEGATED_TEST = { + {NODEPR_NOPKGS_BUG_ID + FS + "overview-summary.html", + "compact1" + } + }; + private static final String[][] PROFILES_CONFIGURATION_TEST = { //-use option test string fo profile view page {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html","
  • Use
  • " @@ -57,6 +82,12 @@ public class TestProfilesConfiguration extends JavadocTester { //-keywords option test string for profiles {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html", "" + }, + //Deprecated information on a package + {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html", + "

    pkgDeprecated

    " + NL + "
    " + + "Deprecated.
    " } }; private static final String[][] PROFILES_CONFIGURATION_NEGATED_TEST = { @@ -75,6 +106,8 @@ public class TestProfilesConfiguration extends JavadocTester { TestProfilesConfiguration tester = new TestProfilesConfiguration(); run(tester, ARGS3, PROFILES_CONFIGURATION_TEST, PROFILES_CONFIGURATION_NEGATED_TEST); + run(tester, ARGS4, NODEPR_NOPKGS_TEST, + NODEPR_NOPKGS_NEGATED_TEST); tester.printSummary(); } diff --git a/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes-nopkgs.txt b/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes-nopkgs.txt new file mode 100644 index 00000000000..c63a4e85214 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes-nopkgs.txt @@ -0,0 +1,41 @@ +PROFILE_1_RTJAR_INCLUDE_PACKAGES := + +PROFILE_1_RTJAR_INCLUDE_TYPES := + +PROFILE_1_RTJAR_EXCLUDE_TYPES := + +PROFILE_1_INCLUDE_METAINF_SERVICES := + + +PROFILE_2_RTJAR_INCLUDE_PACKAGES := \ + pkg4 \ + pkgDeprecated + +PROFILE_2_RTJAR_INCLUDE_TYPES := + +PROFILE_2_RTJAR_EXCLUDE_TYPES := \ + pkg4/Anno1Pkg4.class + +PROFILE_2_INCLUDE_METAINF_SERVICES := + + +PROFILE_3_RTJAR_INCLUDE_PACKAGES := \ + pkg5 + +PROFILE_3_RTJAR_INCLUDE_TYPES := + +PROFILE_3_RTJAR_EXCLUDE_TYPES := + +PROFILE_3_INCLUDE_METAINF_SERVICES := + + +PROFILE_4_RTJAR_INCLUDE_PACKAGES := \ + pkg1 + +PROFILE_4_RTJAR_INCLUDE_TYPES := + +PROFILE_4_RTJAR_EXCLUDE_TYPES := + +PROFILE_4_INCLUDE_METAINF_SERVICES := + + From 091edb47c5295609b2b64ef32e7075d2008b656d Mon Sep 17 00:00:00 2001 From: Bill Pittore Date: Wed, 11 Sep 2013 20:03:34 -0400 Subject: [PATCH 0303/1294] 8024007: Misc. cleanup of static agent code Minor cleanup of static agent code from 8014135 Reviewed-by: dcubed, sspitsyn --- hotspot/src/os/windows/vm/os_windows.cpp | 2 +- hotspot/src/share/vm/prims/jvmti.xml | 6 ++++-- hotspot/src/share/vm/runtime/arguments.hpp | 2 +- hotspot/src/share/vm/runtime/os.cpp | 5 +++-- hotspot/src/share/vm/runtime/thread.cpp | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 015f94d6662..d6dbde4c929 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -5429,7 +5429,7 @@ char* os::build_agent_function_name(const char *sym_name, const char *lib_name, if ((start = strrchr(lib_name, *os::file_separator())) != NULL) { lib_name = ++start; } else { - // Need to check for C: + // Need to check for drive prefix if ((start = strchr(lib_name, ':')) != NULL) { lib_name = ++start; } diff --git a/hotspot/src/share/vm/prims/jvmti.xml b/hotspot/src/share/vm/prims/jvmti.xml index 87a28ae0cfc..98a0a0640aa 100644 --- a/hotspot/src/share/vm/prims/jvmti.xml +++ b/hotspot/src/share/vm/prims/jvmti.xml @@ -458,8 +458,10 @@ the same name from being loaded dynamically.

    The VM will invoke the Agent_OnUnload_L function of the agent, if such - a function is exported, at the same point during startup as it would - have called the dynamic entry point Agent_OnUnLoad. + a function is exported, at the same point during VM execution as it would + have called the dynamic entry point Agent_OnUnLoad. A statically loaded + agent cannot be unloaded. The Agent_OnUnload_L function will still be + called to do any other agent shutdown related tasks. If a statically linked agent L exports a function called Agent_OnUnLoad_L and a function called Agent_OnUnLoad, the Agent_OnUnLoad function will be ignored. diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index 43256b75082..6b8eb305aae 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -144,7 +144,7 @@ public: void set_os_lib(void* os_lib) { _os_lib = os_lib; } AgentLibrary* next() const { return _next; } bool is_static_lib() const { return _is_static_lib; } - void set_static_lib(bool static_lib) { _is_static_lib = static_lib; } + void set_static_lib(bool is_static_lib) { _is_static_lib = is_static_lib; } bool valid() { return (_state == agent_valid); } void set_valid() { _state = agent_valid; } void set_invalid() { _state = agent_invalid; } diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index 0c83565195c..f85f1237f14 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -454,6 +454,7 @@ void* os::native_java_library() { */ void* os::find_agent_function(AgentLibrary *agent_lib, bool check_lib, const char *syms[], size_t syms_len) { + assert(agent_lib != NULL, "sanity check"); const char *lib_name; void *handle = agent_lib->os_lib(); void *entryName = NULL; @@ -484,6 +485,7 @@ bool os::find_builtin_agent(AgentLibrary *agent_lib, const char *syms[], void *proc_handle; void *save_handle; + assert(agent_lib != NULL, "sanity check"); if (agent_lib->name() == NULL) { return false; } @@ -493,14 +495,13 @@ bool os::find_builtin_agent(AgentLibrary *agent_lib, const char *syms[], // We want to look in this process' symbol table. agent_lib->set_os_lib(proc_handle); ret = find_agent_function(agent_lib, true, syms, syms_len); - agent_lib->set_os_lib(save_handle); if (ret != NULL) { // Found an entry point like Agent_OnLoad_lib_name so we have a static agent - agent_lib->set_os_lib(proc_handle); agent_lib->set_valid(); agent_lib->set_static_lib(true); return true; } + agent_lib->set_os_lib(save_handle); return false; } diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index d5bc3a00006..2745703b598 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -3714,7 +3714,7 @@ static OnLoadEntry_t lookup_on_load(AgentLibrary* agent, const char *on_load_sym const char *name = agent->name(); const char *msg = "Could not find agent library "; - // First check to see if agent is statcally linked into executable + // First check to see if agent is statically linked into executable if (os::find_builtin_agent(agent, on_load_symbols, num_symbol_entries)) { library = agent->os_lib(); } else if (agent->is_absolute_path()) { From 28d455529e7bc76985029e762442edd824125e10 Mon Sep 17 00:00:00 2001 From: Dmitry Nadezhin Date: Wed, 11 Sep 2013 17:07:35 -0700 Subject: [PATCH 0304/1294] 8010430: Math.round has surprising behavior for odd values of ulp 1 If the effective floating point exponent is zero return the significand including the implicit 1-bit. Reviewed-by: bpb, darcy, gls --- jdk/src/share/classes/java/lang/Math.java | 66 ++++++++++++++--- .../share/classes/java/lang/StrictMath.java | 4 +- jdk/test/java/lang/Math/RoundTests.java | 71 ++++++++++++++++++- 3 files changed, 126 insertions(+), 15 deletions(-) diff --git a/jdk/src/share/classes/java/lang/Math.java b/jdk/src/share/classes/java/lang/Math.java index ae83e4265ad..98e901ac942 100644 --- a/jdk/src/share/classes/java/lang/Math.java +++ b/jdk/src/share/classes/java/lang/Math.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, 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 @@ -646,7 +646,7 @@ public final class Math { /** * Returns the closest {@code int} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

    * Special cases: @@ -665,15 +665,37 @@ public final class Math { * @see java.lang.Integer#MIN_VALUE */ public static int round(float a) { - if (a != 0x1.fffffep-2f) // greatest float value less than 0.5 - return (int)floor(a + 0.5f); - else - return 0; + int intBits = Float.floatToRawIntBits(a); + int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK) + >> (FloatConsts.SIGNIFICAND_WIDTH - 1); + int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2 + + FloatConsts.EXP_BIAS) - biasedExp; + if ((shift & -32) == 0) { // shift >= 0 && shift < 32 + // a is a finite number such that pow(2,-32) <= ulp(a) < 1 + int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK) + | (FloatConsts.SIGNIF_BIT_MASK + 1)); + if (intBits < 0) { + r = -r; + } + // In the comments below each Java expression evaluates to the value + // the corresponding mathematical expression: + // (r) evaluates to a / ulp(a) + // (r >> shift) evaluates to floor(a * 2) + // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2) + // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2) + return ((r >> shift) + 1) >> 1; + } else { + // a is either + // - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2 + // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer + // - an infinity or NaN + return (int) a; + } } /** * Returns the closest {@code long} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

    Special cases: *

    • If the argument is NaN, the result is 0. @@ -692,10 +714,32 @@ public final class Math { * @see java.lang.Long#MIN_VALUE */ public static long round(double a) { - if (a != 0x1.fffffffffffffp-2) // greatest double value less than 0.5 - return (long)floor(a + 0.5d); - else - return 0; + long longBits = Double.doubleToRawLongBits(a); + long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK) + >> (DoubleConsts.SIGNIFICAND_WIDTH - 1); + long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2 + + DoubleConsts.EXP_BIAS) - biasedExp; + if ((shift & -64) == 0) { // shift >= 0 && shift < 64 + // a is a finite number such that pow(2,-64) <= ulp(a) < 1 + long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK) + | (DoubleConsts.SIGNIF_BIT_MASK + 1)); + if (longBits < 0) { + r = -r; + } + // In the comments below each Java expression evaluates to the value + // the corresponding mathematical expression: + // (r) evaluates to a / ulp(a) + // (r >> shift) evaluates to floor(a * 2) + // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2) + // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2) + return ((r >> shift) + 1) >> 1; + } else { + // a is either + // - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2 + // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer + // - an infinity or NaN + return (long) a; + } } private static final class RandomNumberGeneratorHolder { diff --git a/jdk/src/share/classes/java/lang/StrictMath.java b/jdk/src/share/classes/java/lang/StrictMath.java index 52336484e75..ae4af2bcac8 100644 --- a/jdk/src/share/classes/java/lang/StrictMath.java +++ b/jdk/src/share/classes/java/lang/StrictMath.java @@ -633,7 +633,7 @@ public final class StrictMath { /** * Returns the closest {@code int} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

      Special cases: *

      • If the argument is NaN, the result is 0. @@ -656,7 +656,7 @@ public final class StrictMath { /** * Returns the closest {@code long} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

        Special cases: *

        • If the argument is NaN, the result is 0. diff --git a/jdk/test/java/lang/Math/RoundTests.java b/jdk/test/java/lang/Math/RoundTests.java index 9994e97df85..cae190f9770 100644 --- a/jdk/test/java/lang/Math/RoundTests.java +++ b/jdk/test/java/lang/Math/RoundTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 6430675 + * @bug 6430675 8010430 * @summary Check for correct implementation of {Math, StrictMath}.round */ public class RoundTests { @@ -32,6 +32,8 @@ public class RoundTests { failures += testNearFloatHalfCases(); failures += testNearDoubleHalfCases(); + failures += testUnityULPCases(); + failures += testSpecialCases(); if (failures > 0) { System.err.println("Testing {Math, StrictMath}.round incurred " @@ -95,4 +97,69 @@ public class RoundTests { return failures; } + + private static int testUnityULPCases() { + int failures = 0; + for (float sign : new float[]{-1, 1}) { + for (float v1 : new float[]{1 << 23, 1 << 24}) { + for (int k = -5; k <= 5; k++) { + float value = (v1 + k) * sign; + float actual = Math.round(value); + failures += Tests.test("Math.round", value, actual, value); + } + } + } + + if (failures != 0) { + System.out.println(); + } + + for (double sign : new double[]{-1, 1}) { + for (double v1 : new double[]{1L << 52, 1L << 53}) { + for (int k = -5; k <= 5; k++) { + double value = (v1 + k) * sign; + double actual = Math.round(value); + failures += Tests.test("Math.round", value, actual, value); + } + } + } + + return failures; + } + + private static int testSpecialCases() { + int failures = 0; + + failures += Tests.test("Math.round", Float.NaN, Math.round(Float.NaN), 0.0F); + failures += Tests.test("Math.round", Float.POSITIVE_INFINITY, + Math.round(Float.POSITIVE_INFINITY), Integer.MAX_VALUE); + failures += Tests.test("Math.round", Float.NEGATIVE_INFINITY, + Math.round(Float.NEGATIVE_INFINITY), Integer.MIN_VALUE); + failures += Tests.test("Math.round", -(float)Integer.MIN_VALUE, + Math.round(-(float)Integer.MIN_VALUE), Integer.MAX_VALUE); + failures += Tests.test("Math.round", (float) Integer.MIN_VALUE, + Math.round((float) Integer.MIN_VALUE), Integer.MIN_VALUE); + failures += Tests.test("Math.round", 0F, Math.round(0F), 0.0F); + failures += Tests.test("Math.round", Float.MIN_VALUE, + Math.round(Float.MIN_VALUE), 0.0F); + failures += Tests.test("Math.round", -Float.MIN_VALUE, + Math.round(-Float.MIN_VALUE), 0.0F); + + failures += Tests.test("Math.round", Double.NaN, Math.round(Double.NaN), 0.0); + failures += Tests.test("Math.round", Double.POSITIVE_INFINITY, + Math.round(Double.POSITIVE_INFINITY), Long.MAX_VALUE); + failures += Tests.test("Math.round", Double.NEGATIVE_INFINITY, + Math.round(Double.NEGATIVE_INFINITY), Long.MIN_VALUE); + failures += Tests.test("Math.round", -(double)Long.MIN_VALUE, + Math.round(-(double)Long.MIN_VALUE), Long.MAX_VALUE); + failures += Tests.test("Math.round", (double) Long.MIN_VALUE, + Math.round((double) Long.MIN_VALUE), Long.MIN_VALUE); + failures += Tests.test("Math.round", 0, Math.round(0), 0.0); + failures += Tests.test("Math.round", Double.MIN_VALUE, + Math.round(Double.MIN_VALUE), 0.0); + failures += Tests.test("Math.round", -Double.MIN_VALUE, + Math.round(-Double.MIN_VALUE), 0.0); + + return failures; + } } From dfd2d9a574dc868c3a9bd0515e61b04873b358f3 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Thu, 12 Sep 2013 10:15:30 +0200 Subject: [PATCH 0305/1294] 8023476: Metaspace capacity > reserved Reviewed-by: stefank, hseigel, mgerdin --- .../share/vm/gc_interface/collectedHeap.cpp | 6 +- hotspot/src/share/vm/memory/metaspace.cpp | 85 +++++++++++-------- hotspot/src/share/vm/memory/metaspace.hpp | 58 ++++--------- .../src/share/vm/memory/metaspaceCounters.cpp | 16 ++-- 4 files changed, 80 insertions(+), 85 deletions(-) diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp index 3af380049bb..3f5364b79c0 100644 --- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp @@ -87,15 +87,15 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() { const MetaspaceSizes meta_space( MetaspaceAux::allocated_capacity_bytes(), MetaspaceAux::allocated_used_bytes(), - MetaspaceAux::reserved_in_bytes()); + MetaspaceAux::reserved_bytes()); const MetaspaceSizes data_space( MetaspaceAux::allocated_capacity_bytes(Metaspace::NonClassType), MetaspaceAux::allocated_used_bytes(Metaspace::NonClassType), - MetaspaceAux::reserved_in_bytes(Metaspace::NonClassType)); + MetaspaceAux::reserved_bytes(Metaspace::NonClassType)); const MetaspaceSizes class_space( MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType), MetaspaceAux::allocated_used_bytes(Metaspace::ClassType), - MetaspaceAux::reserved_in_bytes(Metaspace::ClassType)); + MetaspaceAux::reserved_bytes(Metaspace::ClassType)); return MetaspaceSummary(meta_space, data_space, class_space); } diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 63e6be716da..e8117f7fae9 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -177,8 +177,8 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC { void return_chunks(ChunkIndex index, Metachunk* chunks); // Total of the space in the free chunks list - size_t free_chunks_total(); - size_t free_chunks_total_in_bytes(); + size_t free_chunks_total_words(); + size_t free_chunks_total_bytes(); // Number of chunks in the free chunks list size_t free_chunks_count(); @@ -1080,12 +1080,12 @@ size_t VirtualSpaceList::used_words_sum() { // Sum used region [bottom, top) in each virtualspace allocated_by_vs += vsl->used_words_in_vs(); } - assert(allocated_by_vs >= chunk_manager()->free_chunks_total(), + assert(allocated_by_vs >= chunk_manager()->free_chunks_total_words(), err_msg("Total in free chunks " SIZE_FORMAT " greater than total from virtual_spaces " SIZE_FORMAT, - allocated_by_vs, chunk_manager()->free_chunks_total())); + allocated_by_vs, chunk_manager()->free_chunks_total_words())); size_t used = - allocated_by_vs - chunk_manager()->free_chunks_total(); + allocated_by_vs - chunk_manager()->free_chunks_total_words(); return used; } @@ -1526,7 +1526,7 @@ void Metadebug::deallocate_chunk_a_lot(SpaceManager* sm, sm->sum_count_in_chunks_in_use()); dummy_chunk->print_on(gclog_or_tty); gclog_or_tty->print_cr(" Free chunks total %d count %d", - vsl->chunk_manager()->free_chunks_total(), + vsl->chunk_manager()->free_chunks_total_words(), vsl->chunk_manager()->free_chunks_count()); } } @@ -1583,12 +1583,12 @@ bool Metadebug::test_metadata_failure() { // ChunkManager methods -size_t ChunkManager::free_chunks_total() { +size_t ChunkManager::free_chunks_total_words() { return _free_chunks_total; } -size_t ChunkManager::free_chunks_total_in_bytes() { - return free_chunks_total() * BytesPerWord; +size_t ChunkManager::free_chunks_total_bytes() { + return free_chunks_total_words() * BytesPerWord; } size_t ChunkManager::free_chunks_count() { @@ -2567,13 +2567,13 @@ size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) { return used * BytesPerWord; } -size_t MetaspaceAux::free_in_bytes(Metaspace::MetadataType mdtype) { +size_t MetaspaceAux::free_bytes_slow(Metaspace::MetadataType mdtype) { size_t free = 0; ClassLoaderDataGraphMetaspaceIterator iter; while (iter.repeat()) { Metaspace* msp = iter.get_next(); if (msp != NULL) { - free += msp->free_words(mdtype); + free += msp->free_words_slow(mdtype); } } return free * BytesPerWord; @@ -2596,34 +2596,51 @@ size_t MetaspaceAux::capacity_bytes_slow(Metaspace::MetadataType mdtype) { return capacity * BytesPerWord; } -size_t MetaspaceAux::reserved_in_bytes(Metaspace::MetadataType mdtype) { - VirtualSpaceList* list = Metaspace::get_space_list(mdtype); - return list == NULL ? 0 : list->virtual_space_total(); +size_t MetaspaceAux::capacity_bytes_slow() { +#ifdef PRODUCT + // Use allocated_capacity_bytes() in PRODUCT instead of this function. + guarantee(false, "Should not call capacity_bytes_slow() in the PRODUCT"); +#endif + size_t class_capacity = capacity_bytes_slow(Metaspace::ClassType); + size_t non_class_capacity = capacity_bytes_slow(Metaspace::NonClassType); + assert(allocated_capacity_bytes() == class_capacity + non_class_capacity, + err_msg("bad accounting: allocated_capacity_bytes() " SIZE_FORMAT + " class_capacity + non_class_capacity " SIZE_FORMAT + " class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT, + allocated_capacity_bytes(), class_capacity + non_class_capacity, + class_capacity, non_class_capacity)); + + return class_capacity + non_class_capacity; } -size_t MetaspaceAux::min_chunk_size() { return Metaspace::first_chunk_word_size(); } +size_t MetaspaceAux::reserved_bytes(Metaspace::MetadataType mdtype) { + VirtualSpaceList* list = Metaspace::get_space_list(mdtype); + return list == NULL ? 0 : list->virtual_space_total() * BytesPerWord; +} -size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) { +size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); } + +size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) { VirtualSpaceList* list = Metaspace::get_space_list(mdtype); if (list == NULL) { return 0; } ChunkManager* chunk = list->chunk_manager(); chunk->slow_verify(); - return chunk->free_chunks_total(); + return chunk->free_chunks_total_words(); } -size_t MetaspaceAux::free_chunks_total_in_bytes(Metaspace::MetadataType mdtype) { - return free_chunks_total(mdtype) * BytesPerWord; +size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) { + return free_chunks_total_words(mdtype) * BytesPerWord; } -size_t MetaspaceAux::free_chunks_total() { - return free_chunks_total(Metaspace::ClassType) + - free_chunks_total(Metaspace::NonClassType); +size_t MetaspaceAux::free_chunks_total_words() { + return free_chunks_total_words(Metaspace::ClassType) + + free_chunks_total_words(Metaspace::NonClassType); } -size_t MetaspaceAux::free_chunks_total_in_bytes() { - return free_chunks_total() * BytesPerWord; +size_t MetaspaceAux::free_chunks_total_bytes() { + return free_chunks_total_words() * BytesPerWord; } void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) { @@ -2634,14 +2651,14 @@ void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) { "(" SIZE_FORMAT ")", prev_metadata_used, allocated_used_bytes(), - reserved_in_bytes()); + reserved_bytes()); } else { gclog_or_tty->print(" " SIZE_FORMAT "K" "->" SIZE_FORMAT "K" "(" SIZE_FORMAT "K)", - prev_metadata_used / K, - allocated_used_bytes() / K, - reserved_in_bytes()/ K); + prev_metadata_used/K, + allocated_used_bytes()/K, + reserved_bytes()/K); } gclog_or_tty->print("]"); @@ -2654,14 +2671,14 @@ void MetaspaceAux::print_on(outputStream* out) { out->print_cr(" Metaspace total " SIZE_FORMAT "K, used " SIZE_FORMAT "K," " reserved " SIZE_FORMAT "K", - allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_in_bytes()/K); + allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_bytes()/K); out->print_cr(" data space " SIZE_FORMAT "K, used " SIZE_FORMAT "K," " reserved " SIZE_FORMAT "K", allocated_capacity_bytes(nct)/K, allocated_used_bytes(nct)/K, - reserved_in_bytes(nct)/K); + reserved_bytes(nct)/K); if (Metaspace::using_class_space()) { Metaspace::MetadataType ct = Metaspace::ClassType; out->print_cr(" class space " @@ -2669,17 +2686,17 @@ void MetaspaceAux::print_on(outputStream* out) { " reserved " SIZE_FORMAT "K", allocated_capacity_bytes(ct)/K, allocated_used_bytes(ct)/K, - reserved_in_bytes(ct)/K); + reserved_bytes(ct)/K); } } // Print information for class space and data space separately. // This is almost the same as above. void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) { - size_t free_chunks_capacity_bytes = free_chunks_total_in_bytes(mdtype); + size_t free_chunks_capacity_bytes = free_chunks_total_bytes(mdtype); size_t capacity_bytes = capacity_bytes_slow(mdtype); size_t used_bytes = used_bytes_slow(mdtype); - size_t free_bytes = free_in_bytes(mdtype); + size_t free_bytes = free_bytes_slow(mdtype); size_t used_and_free = used_bytes + free_bytes + free_chunks_capacity_bytes; out->print_cr(" Chunk accounting: used in chunks " SIZE_FORMAT @@ -3132,7 +3149,7 @@ size_t Metaspace::used_words_slow(MetadataType mdtype) const { } } -size_t Metaspace::free_words(MetadataType mdtype) const { +size_t Metaspace::free_words_slow(MetadataType mdtype) const { if (mdtype == ClassType) { return using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0; } else { diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 591acf30075..b51c80be0e6 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -182,9 +182,8 @@ class Metaspace : public CHeapObj { char* bottom() const; size_t used_words_slow(MetadataType mdtype) const; - size_t free_words(MetadataType mdtype) const; + size_t free_words_slow(MetadataType mdtype) const; size_t capacity_words_slow(MetadataType mdtype) const; - size_t waste_words(MetadataType mdtype) const; size_t used_bytes_slow(MetadataType mdtype) const; size_t capacity_bytes_slow(MetadataType mdtype) const; @@ -221,19 +220,14 @@ class Metaspace : public CHeapObj { }; class MetaspaceAux : AllStatic { - static size_t free_chunks_total(Metaspace::MetadataType mdtype); - - public: - // Statistics for class space and data space in metaspace. + static size_t free_chunks_total_words(Metaspace::MetadataType mdtype); // These methods iterate over the classloader data graph // for the given Metaspace type. These are slow. static size_t used_bytes_slow(Metaspace::MetadataType mdtype); - static size_t free_in_bytes(Metaspace::MetadataType mdtype); + static size_t free_bytes_slow(Metaspace::MetadataType mdtype); static size_t capacity_bytes_slow(Metaspace::MetadataType mdtype); - - // Iterates over the virtual space list. - static size_t reserved_in_bytes(Metaspace::MetadataType mdtype); + static size_t capacity_bytes_slow(); // Running sum of space in all Metachunks that has been // allocated to a Metaspace. This is used instead of @@ -263,17 +257,16 @@ class MetaspaceAux : AllStatic { } // Used by MetaspaceCounters - static size_t free_chunks_total(); - static size_t free_chunks_total_in_bytes(); - static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype); + static size_t free_chunks_total_words(); + static size_t free_chunks_total_bytes(); + static size_t free_chunks_total_bytes(Metaspace::MetadataType mdtype); static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) { return _allocated_capacity_words[mdtype]; } static size_t allocated_capacity_words() { - return _allocated_capacity_words[Metaspace::NonClassType] + - (Metaspace::using_class_space() ? - _allocated_capacity_words[Metaspace::ClassType] : 0); + return allocated_capacity_words(Metaspace::NonClassType) + + allocated_capacity_words(Metaspace::ClassType); } static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) { return allocated_capacity_words(mdtype) * BytesPerWord; @@ -286,9 +279,8 @@ class MetaspaceAux : AllStatic { return _allocated_used_words[mdtype]; } static size_t allocated_used_words() { - return _allocated_used_words[Metaspace::NonClassType] + - (Metaspace::using_class_space() ? - _allocated_used_words[Metaspace::ClassType] : 0); + return allocated_used_words(Metaspace::NonClassType) + + allocated_used_words(Metaspace::ClassType); } static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) { return allocated_used_words(mdtype) * BytesPerWord; @@ -301,31 +293,17 @@ class MetaspaceAux : AllStatic { static size_t free_bytes(Metaspace::MetadataType mdtype); // Total capacity in all Metaspaces - static size_t capacity_bytes_slow() { -#ifdef PRODUCT - // Use allocated_capacity_bytes() in PRODUCT instead of this function. - guarantee(false, "Should not call capacity_bytes_slow() in the PRODUCT"); -#endif - size_t class_capacity = capacity_bytes_slow(Metaspace::ClassType); - size_t non_class_capacity = capacity_bytes_slow(Metaspace::NonClassType); - assert(allocated_capacity_bytes() == class_capacity + non_class_capacity, - err_msg("bad accounting: allocated_capacity_bytes() " SIZE_FORMAT - " class_capacity + non_class_capacity " SIZE_FORMAT - " class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT, - allocated_capacity_bytes(), class_capacity + non_class_capacity, - class_capacity, non_class_capacity)); - - return class_capacity + non_class_capacity; + static size_t reserved_bytes(Metaspace::MetadataType mdtype); + static size_t reserved_bytes() { + return reserved_bytes(Metaspace::ClassType) + + reserved_bytes(Metaspace::NonClassType); } - // Total space reserved in all Metaspaces - static size_t reserved_in_bytes() { - return reserved_in_bytes(Metaspace::ClassType) + - reserved_in_bytes(Metaspace::NonClassType); + static size_t min_chunk_size_words(); + static size_t min_chunk_size_bytes() { + return min_chunk_size_words() * BytesPerWord; } - static size_t min_chunk_size(); - // Print change in used metadata. static void print_metaspace_change(size_t prev_metadata_used); static void print_on(outputStream * out); diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.cpp b/hotspot/src/share/vm/memory/metaspaceCounters.cpp index 32eda2b4ed8..6f443466ffb 100644 --- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp +++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp @@ -71,7 +71,7 @@ size_t MetaspaceCounters::calculate_capacity() { // 2) unused space at the end of each Metachunk // 3) space in the freelist size_t total_capacity = MetaspaceAux::allocated_capacity_bytes() - + MetaspaceAux::free_bytes() + MetaspaceAux::free_chunks_total_in_bytes(); + + MetaspaceAux::free_bytes() + MetaspaceAux::free_chunks_total_bytes(); return total_capacity; } @@ -79,9 +79,9 @@ void MetaspaceCounters::initialize_performance_counters() { if (UsePerfData) { assert(_perf_counters == NULL, "Should only be initialized once"); - size_t min_capacity = MetaspaceAux::min_chunk_size(); + size_t min_capacity = MetaspaceAux::min_chunk_size_bytes(); size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_in_bytes(); + size_t max_capacity = MetaspaceAux::reserved_bytes(); size_t used = MetaspaceAux::allocated_used_bytes(); _perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, capacity, max_capacity, used); @@ -93,7 +93,7 @@ void MetaspaceCounters::update_performance_counters() { assert(_perf_counters != NULL, "Should be initialized"); size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_in_bytes(); + size_t max_capacity = MetaspaceAux::reserved_bytes(); size_t used = MetaspaceAux::allocated_used_bytes(); _perf_counters->update(capacity, max_capacity, used); @@ -105,7 +105,7 @@ MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL; size_t CompressedClassSpaceCounters::calculate_capacity() { return MetaspaceAux::allocated_capacity_bytes(_class_type) + MetaspaceAux::free_bytes(_class_type) + - MetaspaceAux::free_chunks_total_in_bytes(_class_type); + MetaspaceAux::free_chunks_total_bytes(_class_type); } void CompressedClassSpaceCounters::update_performance_counters() { @@ -113,7 +113,7 @@ void CompressedClassSpaceCounters::update_performance_counters() { assert(_perf_counters != NULL, "Should be initialized"); size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type); + size_t max_capacity = MetaspaceAux::reserved_bytes(_class_type); size_t used = MetaspaceAux::allocated_used_bytes(_class_type); _perf_counters->update(capacity, max_capacity, used); @@ -126,9 +126,9 @@ void CompressedClassSpaceCounters::initialize_performance_counters() { const char* ns = "compressedclassspace"; if (UseCompressedClassPointers) { - size_t min_capacity = MetaspaceAux::min_chunk_size(); + size_t min_capacity = MetaspaceAux::min_chunk_size_bytes(); size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type); + size_t max_capacity = MetaspaceAux::reserved_bytes(_class_type); size_t used = MetaspaceAux::allocated_used_bytes(_class_type); _perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity, max_capacity, used); From 8a515de48c15b44fbbe2abef6bc50b4391d93788 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Thu, 12 Sep 2013 10:15:54 +0200 Subject: [PATCH 0306/1294] 8024638: Count and expose the amount of committed memory in the metaspaces Reviewed-by: brutisso, ehelin --- hotspot/src/share/vm/memory/metaspace.cpp | 182 +++++++++++++----- hotspot/src/share/vm/memory/metaspace.hpp | 7 +- hotspot/src/share/vm/prims/jni.cpp | 4 + hotspot/src/share/vm/runtime/virtualspace.cpp | 139 +++++++++++++ hotspot/src/share/vm/runtime/virtualspace.hpp | 13 +- 5 files changed, 289 insertions(+), 56 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index e8117f7fae9..1dd97842eb4 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -291,6 +291,10 @@ class VirtualSpaceNode : public CHeapObj { MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); } MetaWord* end() const { return (MetaWord*) _virtual_space.high(); } + size_t reserved_words() const { return _virtual_space.reserved_size() / BytesPerWord; } + size_t expanded_words() const { return _virtual_space.committed_size() / BytesPerWord; } + size_t committed_words() const { return _virtual_space.actual_committed_size() / BytesPerWord; } + // address of next available space in _virtual_space; // Accessors VirtualSpaceNode* next() { return _next; } @@ -327,12 +331,10 @@ class VirtualSpaceNode : public CHeapObj { // Allocate a chunk from the virtual space and return it. Metachunk* get_chunk_vs(size_t chunk_word_size); - Metachunk* get_chunk_vs_with_expand(size_t chunk_word_size); // Expands/shrinks the committed space in a virtual space. Delegates // to Virtualspace bool expand_by(size_t words, bool pre_touch = false); - bool shrink_by(size_t words); // In preparation for deleting this node, remove all the chunks // in the node from any freelist. @@ -340,8 +342,6 @@ class VirtualSpaceNode : public CHeapObj { #ifdef ASSERT // Debug support - static void verify_virtual_space_total(); - static void verify_virtual_space_count(); void mangle(); #endif @@ -429,8 +429,11 @@ class VirtualSpaceList : public CHeapObj { bool _is_class; bool can_grow() const { return !is_class() || !UseCompressedClassPointers; } - // Sum of space in all virtual spaces and number of virtual spaces - size_t _virtual_space_total; + // Sum of reserved and committed memory in the virtual spaces + size_t _reserved_words; + size_t _committed_words; + + // Number of virtual spaces size_t _virtual_space_count; ~VirtualSpaceList(); @@ -444,7 +447,7 @@ class VirtualSpaceList : public CHeapObj { _current_virtual_space = v; } - void link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size); + void link_vs(VirtualSpaceNode* new_entry); // Get another virtual space and add it to the list. This // is typically prompted by a failed attempt to allocate a chunk @@ -461,6 +464,8 @@ class VirtualSpaceList : public CHeapObj { size_t grow_chunks_by_words, size_t medium_chunk_bunch); + bool expand_by(VirtualSpaceNode* node, size_t word_size, bool pre_touch = false); + // Get the first chunk for a Metaspace. Used for // special cases such as the boot class loader, reflection // class loader and anonymous class loader. @@ -476,10 +481,15 @@ class VirtualSpaceList : public CHeapObj { // Allocate the first virtualspace. void initialize(size_t word_size); - size_t virtual_space_total() { return _virtual_space_total; } + size_t reserved_words() { return _reserved_words; } + size_t reserved_bytes() { return reserved_words() * BytesPerWord; } + size_t committed_words() { return _committed_words; } + size_t committed_bytes() { return committed_words() * BytesPerWord; } - void inc_virtual_space_total(size_t v); - void dec_virtual_space_total(size_t v); + void inc_reserved_words(size_t v); + void dec_reserved_words(size_t v); + void inc_committed_words(size_t v); + void dec_committed_words(size_t v); void inc_virtual_space_count(); void dec_virtual_space_count(); @@ -901,15 +911,6 @@ bool VirtualSpaceNode::expand_by(size_t words, bool pre_touch) { return result; } -// Shrink the virtual space (commit more of the reserved space) -bool VirtualSpaceNode::shrink_by(size_t words) { - size_t bytes = words * BytesPerWord; - virtual_space()->shrink_by(bytes); - return true; -} - -// Add another chunk to the chunk list. - Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) { assert_lock_strong(SpaceManager::expand_lock()); Metachunk* result = take_from_committed(chunk_word_size); @@ -919,23 +920,6 @@ Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) { return result; } -Metachunk* VirtualSpaceNode::get_chunk_vs_with_expand(size_t chunk_word_size) { - assert_lock_strong(SpaceManager::expand_lock()); - - Metachunk* new_chunk = get_chunk_vs(chunk_word_size); - - if (new_chunk == NULL) { - // Only a small part of the virtualspace is committed when first - // allocated so committing more here can be expected. - size_t page_size_words = os::vm_page_size() / BytesPerWord; - size_t aligned_expand_vs_by_words = align_size_up(chunk_word_size, - page_size_words); - expand_by(aligned_expand_vs_by_words, false); - new_chunk = get_chunk_vs(chunk_word_size); - } - return new_chunk; -} - bool VirtualSpaceNode::initialize() { if (!_rs.is_reserved()) { @@ -995,13 +979,22 @@ VirtualSpaceList::~VirtualSpaceList() { } } -void VirtualSpaceList::inc_virtual_space_total(size_t v) { +void VirtualSpaceList::inc_reserved_words(size_t v) { assert_lock_strong(SpaceManager::expand_lock()); - _virtual_space_total = _virtual_space_total + v; + _reserved_words = _reserved_words + v; } -void VirtualSpaceList::dec_virtual_space_total(size_t v) { +void VirtualSpaceList::dec_reserved_words(size_t v) { assert_lock_strong(SpaceManager::expand_lock()); - _virtual_space_total = _virtual_space_total - v; + _reserved_words = _reserved_words - v; +} + +void VirtualSpaceList::inc_committed_words(size_t v) { + assert_lock_strong(SpaceManager::expand_lock()); + _committed_words = _committed_words + v; +} +void VirtualSpaceList::dec_committed_words(size_t v) { + assert_lock_strong(SpaceManager::expand_lock()); + _committed_words = _committed_words - v; } void VirtualSpaceList::inc_virtual_space_count() { @@ -1052,7 +1045,8 @@ void VirtualSpaceList::purge() { } vsl->purge(chunk_manager()); - dec_virtual_space_total(vsl->reserved()->word_size()); + dec_reserved_words(vsl->reserved_words()); + dec_committed_words(vsl->committed_words()); dec_virtual_space_count(); purged_vsl = vsl; delete vsl; @@ -1106,7 +1100,8 @@ VirtualSpaceList::VirtualSpaceList(size_t word_size ) : _is_class(false), _virtual_space_list(NULL), _current_virtual_space(NULL), - _virtual_space_total(0), + _reserved_words(0), + _committed_words(0), _virtual_space_count(0) { MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); @@ -1123,7 +1118,8 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) : _is_class(true), _virtual_space_list(NULL), _current_virtual_space(NULL), - _virtual_space_total(0), + _reserved_words(0), + _committed_words(0), _virtual_space_count(0) { MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); @@ -1133,7 +1129,7 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) : _chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk); _chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk); assert(succeeded, " VirtualSpaceList initialization should not fail"); - link_vs(class_entry, rs.size()/BytesPerWord); + link_vs(class_entry); } size_t VirtualSpaceList::free_bytes() { @@ -1156,21 +1152,23 @@ bool VirtualSpaceList::grow_vs(size_t vs_word_size) { delete new_entry; return false; } else { + assert(new_entry->reserved_words() == vs_word_size, "Must be"); // ensure lock-free iteration sees fully initialized node OrderAccess::storestore(); - link_vs(new_entry, vs_word_size); + link_vs(new_entry); return true; } } -void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size) { +void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry) { if (virtual_space_list() == NULL) { set_virtual_space_list(new_entry); } else { current_virtual_space()->set_next(new_entry); } set_current_virtual_space(new_entry); - inc_virtual_space_total(vs_word_size); + inc_reserved_words(new_entry->reserved_words()); + inc_committed_words(new_entry->committed_words()); inc_virtual_space_count(); #ifdef ASSERT new_entry->mangle(); @@ -1181,6 +1179,20 @@ void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size) } } +bool VirtualSpaceList::expand_by(VirtualSpaceNode* node, size_t word_size, bool pre_touch) { + size_t before = node->committed_words(); + + bool result = node->expand_by(word_size, pre_touch); + + size_t after = node->committed_words(); + + // after and before can be the same if the memory was pre-committed. + assert(after >= before, "Must be"); + inc_committed_words(after - before); + + return result; +} + Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, size_t grow_chunks_by_words, size_t medium_chunk_bunch) { @@ -1204,7 +1216,7 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, size_t aligned_expand_vs_by_words = align_size_up(expand_vs_by_words, page_size_words); bool vs_expanded = - current_virtual_space()->expand_by(aligned_expand_vs_by_words, false); + expand_by(current_virtual_space(), aligned_expand_vs_by_words); if (!vs_expanded) { // Should the capacity of the metaspaces be expanded for // this allocation? If it's the virtual space for classes and is @@ -1215,7 +1227,14 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, MAX2((size_t)VirtualSpaceSize, aligned_expand_vs_by_words); if (grow_vs(grow_vs_words)) { // Got it. It's on the list now. Get a chunk from it. - next = current_virtual_space()->get_chunk_vs_with_expand(grow_chunks_by_words); + assert(current_virtual_space()->expanded_words() == 0, + "New virtuals space nodes should not have expanded"); + + size_t grow_chunks_by_words_aligned = align_size_up(grow_chunks_by_words, + page_size_words); + // We probably want to expand by aligned_expand_vs_by_words here. + expand_by(current_virtual_space(), grow_chunks_by_words_aligned); + next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); } } else { // Allocation will fail and induce a GC @@ -1325,7 +1344,7 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) { // reserved space, because this is a larger space prereserved for compressed // class pointers. if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) { - size_t real_allocated = Metaspace::space_list()->virtual_space_total() + + size_t real_allocated = Metaspace::space_list()->reserved_words() + MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); if (real_allocated >= MaxMetaspaceSize) { return false; @@ -2615,7 +2634,12 @@ size_t MetaspaceAux::capacity_bytes_slow() { size_t MetaspaceAux::reserved_bytes(Metaspace::MetadataType mdtype) { VirtualSpaceList* list = Metaspace::get_space_list(mdtype); - return list == NULL ? 0 : list->virtual_space_total() * BytesPerWord; + return list == NULL ? 0 : list->reserved_bytes(); +} + +size_t MetaspaceAux::committed_bytes(Metaspace::MetadataType mdtype) { + VirtualSpaceList* list = Metaspace::get_space_list(mdtype); + return list == NULL ? 0 : list->committed_bytes(); } size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); } @@ -3357,3 +3381,59 @@ void Metaspace::dump(outputStream* const out) const { class_vsm()->dump(out); } } + +/////////////// Unit tests /////////////// + +#ifndef PRODUCT + +class MetaspaceAuxTest : AllStatic { + public: + static void test_reserved() { + size_t reserved = MetaspaceAux::reserved_bytes(); + + assert(reserved > 0, "assert"); + + size_t committed = MetaspaceAux::committed_bytes(); + assert(committed <= reserved, "assert"); + + size_t reserved_metadata = MetaspaceAux::reserved_bytes(Metaspace::NonClassType); + assert(reserved_metadata > 0, "assert"); + assert(reserved_metadata <= reserved, "assert"); + + if (UseCompressedClassPointers) { + size_t reserved_class = MetaspaceAux::reserved_bytes(Metaspace::ClassType); + assert(reserved_class > 0, "assert"); + assert(reserved_class < reserved, "assert"); + } + } + + static void test_committed() { + size_t committed = MetaspaceAux::committed_bytes(); + + assert(committed > 0, "assert"); + + size_t reserved = MetaspaceAux::reserved_bytes(); + assert(committed <= reserved, "assert"); + + size_t committed_metadata = MetaspaceAux::committed_bytes(Metaspace::NonClassType); + assert(committed_metadata > 0, "assert"); + assert(committed_metadata <= committed, "assert"); + + if (UseCompressedClassPointers) { + size_t committed_class = MetaspaceAux::committed_bytes(Metaspace::ClassType); + assert(committed_class > 0, "assert"); + assert(committed_class < committed, "assert"); + } + } + + static void test() { + test_reserved(); + test_committed(); + } +}; + +void MetaspaceAux_test() { + MetaspaceAuxTest::test(); +} + +#endif diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index b51c80be0e6..242fa61b1cc 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -292,13 +292,18 @@ class MetaspaceAux : AllStatic { static size_t free_bytes(); static size_t free_bytes(Metaspace::MetadataType mdtype); - // Total capacity in all Metaspaces static size_t reserved_bytes(Metaspace::MetadataType mdtype); static size_t reserved_bytes() { return reserved_bytes(Metaspace::ClassType) + reserved_bytes(Metaspace::NonClassType); } + static size_t committed_bytes(Metaspace::MetadataType mdtype); + static size_t committed_bytes() { + return committed_bytes(Metaspace::ClassType) + + committed_bytes(Metaspace::NonClassType); + } + static size_t min_chunk_size_words(); static size_t min_chunk_size_bytes() { return min_chunk_size_words() * BytesPerWord; diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index ea44e2c6679..16457a8cd6e 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -5048,12 +5048,16 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) { // Forward declaration void TestReservedSpace_test(); void TestReserveMemorySpecial_test(); +void TestVirtualSpace_test(); +void MetaspaceAux_test(); void execute_internal_vm_tests() { if (ExecuteInternalVMTests) { tty->print_cr("Running internal VM tests"); run_unit_test(TestReservedSpace_test()); run_unit_test(TestReserveMemorySpecial_test()); + run_unit_test(TestVirtualSpace_test()); + run_unit_test(MetaspaceAux_test()); run_unit_test(GlobalDefinitions::test_globals()); run_unit_test(GCTimerAllTest::all()); run_unit_test(arrayOopDesc::test_max_array_length()); diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp index 9e01fe0292f..b7724a6a082 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.cpp +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp @@ -453,6 +453,42 @@ size_t VirtualSpace::uncommitted_size() const { return reserved_size() - committed_size(); } +size_t VirtualSpace::actual_committed_size() const { + // Special VirtualSpaces commit all reserved space up front. + if (special()) { + return reserved_size(); + } + + size_t committed_low = pointer_delta(_lower_high, _low_boundary, sizeof(char)); + size_t committed_middle = pointer_delta(_middle_high, _lower_high_boundary, sizeof(char)); + size_t committed_high = pointer_delta(_upper_high, _middle_high_boundary, sizeof(char)); + +#ifdef ASSERT + size_t lower = pointer_delta(_lower_high_boundary, _low_boundary, sizeof(char)); + size_t middle = pointer_delta(_middle_high_boundary, _lower_high_boundary, sizeof(char)); + size_t upper = pointer_delta(_upper_high_boundary, _middle_high_boundary, sizeof(char)); + + if (committed_high > 0) { + assert(committed_low == lower, "Must be"); + assert(committed_middle == middle, "Must be"); + } + + if (committed_middle > 0) { + assert(committed_low == lower, "Must be"); + } + if (committed_middle < middle) { + assert(committed_high == 0, "Must be"); + } + + if (committed_low < lower) { + assert(committed_high == 0, "Must be"); + assert(committed_middle == 0, "Must be"); + } +#endif + + return committed_low + committed_middle + committed_high; +} + bool VirtualSpace::contains(const void* p) const { return low() <= (const char*) p && (const char*) p < high(); @@ -910,6 +946,109 @@ void TestReservedSpace_test() { TestReservedSpace::test_reserved_space(); } +#define assert_equals(actual, expected) \ + assert(actual == expected, \ + err_msg("Got " SIZE_FORMAT " expected " \ + SIZE_FORMAT, actual, expected)); + +#define assert_ge(value1, value2) \ + assert(value1 >= value2, \ + err_msg("'" #value1 "': " SIZE_FORMAT " '" \ + #value2 "': " SIZE_FORMAT, value1, value2)); + +#define assert_lt(value1, value2) \ + assert(value1 < value2, \ + err_msg("'" #value1 "': " SIZE_FORMAT " '" \ + #value2 "': " SIZE_FORMAT, value1, value2)); + + +class TestVirtualSpace : AllStatic { + public: + static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size) { + size_t granularity = os::vm_allocation_granularity(); + size_t reserve_size_aligned = align_size_up(reserve_size, granularity); + + ReservedSpace reserved(reserve_size_aligned); + + assert(reserved.is_reserved(), "Must be"); + + VirtualSpace vs; + bool initialized = vs.initialize(reserved, 0); + assert(initialized, "Failed to initialize VirtualSpace"); + + vs.expand_by(commit_size, false); + + if (vs.special()) { + assert_equals(vs.actual_committed_size(), reserve_size_aligned); + } else { + assert_ge(vs.actual_committed_size(), commit_size); + // Approximate the commit granularity. + size_t commit_granularity = UseLargePages ? os::large_page_size() : os::vm_page_size(); + assert_lt(vs.actual_committed_size(), commit_size + commit_granularity); + } + + reserved.release(); + } + + static void test_virtual_space_actual_committed_space_one_large_page() { + if (!UseLargePages) { + return; + } + + size_t large_page_size = os::large_page_size(); + + ReservedSpace reserved(large_page_size, large_page_size, true, false); + + assert(reserved.is_reserved(), "Must be"); + + VirtualSpace vs; + bool initialized = vs.initialize(reserved, 0); + assert(initialized, "Failed to initialize VirtualSpace"); + + vs.expand_by(large_page_size, false); + + assert_equals(vs.actual_committed_size(), large_page_size); + + reserved.release(); + } + + static void test_virtual_space_actual_committed_space() { + test_virtual_space_actual_committed_space(4 * K, 0); + test_virtual_space_actual_committed_space(4 * K, 4 * K); + test_virtual_space_actual_committed_space(8 * K, 0); + test_virtual_space_actual_committed_space(8 * K, 4 * K); + test_virtual_space_actual_committed_space(8 * K, 8 * K); + test_virtual_space_actual_committed_space(12 * K, 0); + test_virtual_space_actual_committed_space(12 * K, 4 * K); + test_virtual_space_actual_committed_space(12 * K, 8 * K); + test_virtual_space_actual_committed_space(12 * K, 12 * K); + test_virtual_space_actual_committed_space(64 * K, 0); + test_virtual_space_actual_committed_space(64 * K, 32 * K); + test_virtual_space_actual_committed_space(64 * K, 64 * K); + test_virtual_space_actual_committed_space(2 * M, 0); + test_virtual_space_actual_committed_space(2 * M, 4 * K); + test_virtual_space_actual_committed_space(2 * M, 64 * K); + test_virtual_space_actual_committed_space(2 * M, 1 * M); + test_virtual_space_actual_committed_space(2 * M, 2 * M); + test_virtual_space_actual_committed_space(10 * M, 0); + test_virtual_space_actual_committed_space(10 * M, 4 * K); + test_virtual_space_actual_committed_space(10 * M, 8 * K); + test_virtual_space_actual_committed_space(10 * M, 1 * M); + test_virtual_space_actual_committed_space(10 * M, 2 * M); + test_virtual_space_actual_committed_space(10 * M, 5 * M); + test_virtual_space_actual_committed_space(10 * M, 10 * M); + } + + static void test_virtual_space() { + test_virtual_space_actual_committed_space(); + test_virtual_space_actual_committed_space_one_large_page(); + } +}; + +void TestVirtualSpace_test() { + TestVirtualSpace::test_virtual_space(); +} + #endif // PRODUCT #endif diff --git a/hotspot/src/share/vm/runtime/virtualspace.hpp b/hotspot/src/share/vm/runtime/virtualspace.hpp index bca9b6c14fc..938a71a4a43 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.hpp +++ b/hotspot/src/share/vm/runtime/virtualspace.hpp @@ -183,11 +183,16 @@ class VirtualSpace VALUE_OBJ_CLASS_SPEC { // Destruction ~VirtualSpace(); - // Testers (all sizes are byte sizes) - size_t committed_size() const; - size_t reserved_size() const; + // Reserved memory + size_t reserved_size() const; + // Actually committed OS memory + size_t actual_committed_size() const; + // Memory used/expanded in this virtual space + size_t committed_size() const; + // Memory left to use/expand in this virtual space size_t uncommitted_size() const; - bool contains(const void* p) const; + + bool contains(const void* p) const; // Operations // returns true on success, false otherwise From e6f97e8fc5b628f13af8a19f75734613a56932b7 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Thu, 12 Sep 2013 10:38:17 +0200 Subject: [PATCH 0307/1294] 8024467: Update autoconf-config.guess to autoconf 2.69 Reviewed-by: erikj --- .../autoconf/build-aux/autoconf-config.guess | 551 +++++++++--------- 1 file changed, 275 insertions(+), 276 deletions(-) diff --git a/common/autoconf/build-aux/autoconf-config.guess b/common/autoconf/build-aux/autoconf-config.guess index 3aa7f690629..15ee4389269 100644 --- a/common/autoconf/build-aux/autoconf-config.guess +++ b/common/autoconf/build-aux/autoconf-config.guess @@ -26,10 +26,10 @@ # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 -# Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. -timestamp='2008-01-23' +timestamp='2012-02-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -42,9 +42,7 @@ timestamp='2008-01-23' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -52,16 +50,16 @@ timestamp='2008-01-23' # the same distribution terms that you use for the rest of that program. -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` @@ -81,8 +79,9 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -169,7 +168,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -195,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null + | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? @@ -205,7 +204,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in fi ;; *) - os=netbsd + os=netbsd ;; esac # The OS release @@ -248,7 +247,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on @@ -294,7 +293,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead @@ -320,7 +322,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo s390-ibm-zvmoe exit ;; *:OS400:*:*) - echo powerpc-ibm-os400 + echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} @@ -349,14 +351,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize @@ -400,23 +421,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; @@ -486,8 +507,8 @@ EOF echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ @@ -500,7 +521,7 @@ EOF else echo i586-dg-dgux${UNAME_RELEASE} fi - exit ;; + exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; @@ -557,7 +578,7 @@ EOF echo rs6000-ibm-aix3.2 fi exit ;; - *:AIX:*:[456]) + *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 @@ -600,52 +621,52 @@ EOF 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac + esac ;; + esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + sed 's/^ //' << EOF >$dummy.c - #define _HPUX_SOURCE - #include - #include + #define _HPUX_SOURCE + #include + #include - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa @@ -665,7 +686,7 @@ EOF # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null + grep -q __LP64__ then HP_ARCH="hppa2.0w" else @@ -736,22 +757,22 @@ EOF exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit ;; + exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit ;; + exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit ;; + exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit ;; + exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit ;; + exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; @@ -775,14 +796,14 @@ EOF exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} @@ -794,13 +815,12 @@ EOF echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) @@ -809,19 +829,22 @@ EOF *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - *:Interix*:[3456]*) - case ${UNAME_MACHINE} in + *:Interix*:*) + case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; - EM64T | authenticamd) + authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) @@ -831,6 +854,9 @@ EOF [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we @@ -860,92 +886,13 @@ EOF i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-gnu - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - fi - exit ;; - avr32*:Linux:*:*) + aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; @@ -955,11 +902,90 @@ EOF EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in @@ -968,14 +994,17 @@ EOF *) echo hppa-unknown-linux-gnu ;; esac exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu @@ -983,78 +1012,18 @@ EOF sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^LIBC/{ - s: ::g - p - }'`" - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both @@ -1062,11 +1031,11 @@ EOF echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. + # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) @@ -1083,7 +1052,7 @@ EOF i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) @@ -1098,7 +1067,7 @@ EOF fi exit ;; i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. + # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; @@ -1126,10 +1095,13 @@ EOF exit ;; pc:*:*:*) # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; @@ -1164,8 +1136,18 @@ EOF /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; @@ -1178,7 +1160,7 @@ EOF rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) @@ -1198,10 +1180,10 @@ EOF echo ns32k-sni-sysv fi exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm @@ -1227,11 +1209,11 @@ EOF exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv${UNAME_RELEASE} else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv${UNAME_RELEASE} fi - exit ;; + exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; @@ -1241,6 +1223,9 @@ EOF BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; @@ -1267,12 +1252,17 @@ EOF exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build - echo "int main(){}" > $dummy.c - if test "`$CC_FOR_BUILD -o $dummy $dummy.c; file $dummy | grep -c x86_64`" = 1 ; then - UNAME_PROCESSOR=x86_64 - fi case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} @@ -1288,6 +1278,9 @@ EOF *:QNX:*:4*) echo i386-pc-qnx exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; @@ -1333,13 +1326,13 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; @@ -1354,6 +1347,12 @@ EOF i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 @@ -1376,11 +1375,11 @@ main () #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else - "" + "" #endif - ); exit (0); + ); exit (0); #endif #endif From df8c6df8a8c87f5b81774c1c7531d32aea0c5fa2 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Thu, 12 Sep 2013 10:42:19 +0200 Subject: [PATCH 0308/1294] 8010185: Build should support --with-override-nashorn Reviewed-by: erikj --- common/autoconf/generated-configure.sh | 21 +++++++++++++++++++-- common/autoconf/source-dirs.m4 | 13 ++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 7679cc5c4df..373f03fa2b1 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -1031,6 +1031,7 @@ with_override_corba with_override_jaxp with_override_jaxws with_override_hotspot +with_override_nashorn with_override_jdk with_import_hotspot with_msvcr_dll @@ -1784,6 +1785,7 @@ Optional Packages: --with-override-jaxp use this jaxp dir for the build --with-override-jaxws use this jaxws dir for the build --with-override-hotspot use this hotspot dir for the build + --with-override-nashorn use this nashorn dir for the build --with-override-jdk use this jdk dir for the build --with-import-hotspot import hotspot binaries from this jdk image or hotspot build dist dir instead of building from @@ -3818,7 +3820,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1378914658 +DATE_WHEN_GENERATED=1378975246 ############################################################################### # @@ -16102,6 +16104,10 @@ if test "x$with_add_source_root" != x; then test -f $with_add_source_root/hotspot/make/Makefile; then as_fn_error $? "Your add source root seems to contain a full hotspot repo! An add source root should only contain additional sources." "$LINENO" 5 fi + if test -f $with_add_source_root/nashorn/makefiles/Makefile || \ + test -f $with_add_source_root/nashorn/make/Makefile; then + as_fn_error $? "Your add source root seems to contain a full nashorn repo! An add source root should only contain additional sources." "$LINENO" 5 + fi if test -f $with_add_source_root/jdk/makefiles/Makefile || \ test -f $with_add_source_root/jdk/make/Makefile; then as_fn_error $? "Your add source root seems to contain a full JDK repo! An add source root should only contain additional sources." "$LINENO" 5 @@ -16137,6 +16143,10 @@ if test "x$with_override_source_root" != x; then test -f $with_override_source_root/hotspot/make/Makefile; then as_fn_error $? "Your override source root seems to contain a full hotspot repo! An override source root should only contain sources that override." "$LINENO" 5 fi + if test -f $with_override_source_root/nashorn/makefiles/Makefile || \ + test -f $with_override_source_root/nashorn/make/Makefile; then + as_fn_error $? "Your override source root seems to contain a full nashorn repo! An override source root should only contain sources that override." "$LINENO" 5 + fi if test -f $with_override_source_root/jdk/makefiles/Makefile || \ test -f $with_override_source_root/jdk/make/Makefile; then as_fn_error $? "Your override source root seems to contain a full JDK repo! An override source root should only contain sources that override." "$LINENO" 5 @@ -16199,6 +16209,13 @@ fi +# Check whether --with-override-nashorn was given. +if test "${with_override_nashorn+set}" = set; then : + withval=$with_override_nashorn; +fi + + + # Check whether --with-override-jdk was given. if test "${with_override_jdk+set}" = set; then : withval=$with_override_jdk; @@ -16276,7 +16293,7 @@ if test "x$with_override_nashorn" != x; then cd "$with_override_nashorn" NASHORN_TOPDIR="`pwd`" cd "$CURDIR" - if ! test -f $NASHORN_TOPDIR/makefiles/BuildNashorn.gmk; then + if ! test -f $NASHORN_TOPDIR/makefiles/Makefile; then as_fn_error $? "You have to override nashorn with a full nashorn repo!" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if nashorn should be overridden" >&5 diff --git a/common/autoconf/source-dirs.m4 b/common/autoconf/source-dirs.m4 index bb0aba1b826..e040cc82f69 100644 --- a/common/autoconf/source-dirs.m4 +++ b/common/autoconf/source-dirs.m4 @@ -101,6 +101,10 @@ if test "x$with_add_source_root" != x; then test -f $with_add_source_root/hotspot/make/Makefile; then AC_MSG_ERROR([Your add source root seems to contain a full hotspot repo! An add source root should only contain additional sources.]) fi + if test -f $with_add_source_root/nashorn/makefiles/Makefile || \ + test -f $with_add_source_root/nashorn/make/Makefile; then + AC_MSG_ERROR([Your add source root seems to contain a full nashorn repo! An add source root should only contain additional sources.]) + fi if test -f $with_add_source_root/jdk/makefiles/Makefile || \ test -f $with_add_source_root/jdk/make/Makefile; then AC_MSG_ERROR([Your add source root seems to contain a full JDK repo! An add source root should only contain additional sources.]) @@ -136,6 +140,10 @@ if test "x$with_override_source_root" != x; then test -f $with_override_source_root/hotspot/make/Makefile; then AC_MSG_ERROR([Your override source root seems to contain a full hotspot repo! An override source root should only contain sources that override.]) fi + if test -f $with_override_source_root/nashorn/makefiles/Makefile || \ + test -f $with_override_source_root/nashorn/make/Makefile; then + AC_MSG_ERROR([Your override source root seems to contain a full nashorn repo! An override source root should only contain sources that override.]) + fi if test -f $with_override_source_root/jdk/makefiles/Makefile || \ test -f $with_override_source_root/jdk/make/Makefile; then AC_MSG_ERROR([Your override source root seems to contain a full JDK repo! An override source root should only contain sources that override.]) @@ -177,6 +185,9 @@ AC_ARG_WITH(override-jaxws, [AS_HELP_STRING([--with-override-jaxws], AC_ARG_WITH(override-hotspot, [AS_HELP_STRING([--with-override-hotspot], [use this hotspot dir for the build])]) +AC_ARG_WITH(override-nashorn, [AS_HELP_STRING([--with-override-nashorn], + [use this nashorn dir for the build])]) + AC_ARG_WITH(override-jdk, [AS_HELP_STRING([--with-override-jdk], [use this jdk dir for the build])]) @@ -241,7 +252,7 @@ if test "x$with_override_nashorn" != x; then cd "$with_override_nashorn" NASHORN_TOPDIR="`pwd`" cd "$CURDIR" - if ! test -f $NASHORN_TOPDIR/makefiles/BuildNashorn.gmk; then + if ! test -f $NASHORN_TOPDIR/makefiles/Makefile; then AC_MSG_ERROR([You have to override nashorn with a full nashorn repo!]) fi AC_MSG_CHECKING([if nashorn should be overridden]) From 57ed4a7edfffd59a2e0ba1961ffff876d0f7430a Mon Sep 17 00:00:00 2001 From: Vadim Pakhnushev Date: Thu, 12 Sep 2013 12:12:13 +0200 Subject: [PATCH 0309/1294] 8008022: Upgrade Direct X SDK used to build JDK Reviewed-by: erikj, prr, ihse --- Makefile | 12 - README-builds.html | 23 -- common/autoconf/generated-configure.sh | 451 +------------------------ common/autoconf/spec.gmk.in | 4 - common/autoconf/toolchain.m4 | 1 - common/autoconf/toolchain_windows.m4 | 58 ---- 6 files changed, 1 insertion(+), 548 deletions(-) diff --git a/Makefile b/Makefile index f7b9d1b35e3..2ef4bb99853 100644 --- a/Makefile +++ b/Makefile @@ -404,7 +404,6 @@ COMPILER_PATH.desc = Compiler install directory CACERTS_FILE.desc = Location of certificates file DEVTOOLS_PATH.desc = Directory containing zip and gnumake CUPS_HEADERS_PATH.desc = Include directory location for CUPS header files -DXSDK_PATH.desc = Root directory of DirectX SDK # Make variables to print out (description and value) VARIABLE_PRINTVAL_LIST += \ @@ -429,17 +428,6 @@ VARIABLE_CHECKDIR_LIST += \ VARIABLE_CHECKFIL_LIST += \ CACERTS_FILE -# Some are windows specific -ifeq ($(PLATFORM), windows) - -VARIABLE_PRINTVAL_LIST += \ - DXSDK_PATH - -VARIABLE_CHECKDIR_LIST += \ - DXSDK_PATH - -endif - # For pattern rules below, so all are treated the same DO_PRINTVAL_LIST=$(VARIABLE_PRINTVAL_LIST:%=%.printval) DO_CHECKDIR_LIST=$(VARIABLE_CHECKDIR_LIST:%=%.checkdir) diff --git a/README-builds.html b/README-builds.html index 71c05c0fbf4..14796a27e87 100644 --- a/README-builds.html +++ b/README-builds.html @@ -444,10 +444,6 @@ Install Visual Studio 2010
        • -
        • - Install the - Microsoft DirectX SDK -

    - - - - "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + ""}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + "

    DEFAULT_NAME

    " + NL + "
    public static final java." +
    +            "lang.String DEFAULT_NAME
    "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", + "
  • Summary: 
  • " + NL + "
  • Field | 
  • "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", + "
  • Detail: 
  • " + NL + "
  • Field | 
  • "}, + }; private static final String[][] NEGATED_TEST = { {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", "
    " + NL + NL + "

    " + NL + NL + "

    " + diff --git a/langtools/test/com/sun/javadoc/testAnnotationTypes/pkg/AnnotationTypeField.java b/langtools/test/com/sun/javadoc/testAnnotationTypes/pkg/AnnotationTypeField.java new file mode 100644 index 00000000000..1dabafcc8db --- /dev/null +++ b/langtools/test/com/sun/javadoc/testAnnotationTypes/pkg/AnnotationTypeField.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, 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. + */ + +package pkg; + +import java.lang.annotation.*; + +/** + * This is just a test for annotation type fields. + */ +@Documented public @interface AnnotationTypeField { + String DEFAULT_NAME = "test"; + + String name() default DEFAULT_NAME; +} diff --git a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java index e16fd5450f2..ad0e024bfe6 100644 --- a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java +++ b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java @@ -155,13 +155,13 @@ public class TestNewLanguageFeatures extends JavadocTester { //================================= //Make sure the summary links are correct. {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", - "

  • Summary: 
  • " + NL + + "
  • Summary: 
  • " + NL + "
  • Field | 
  • " + NL + "
  • " + "Required | 
  • " + NL + "
  • " + "Optional
  • "}, //Make sure the detail links are correct. {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", - "
  • Detail: 
  • " + NL + + "
  • Detail: 
  • " + NL + "
  • Field | 
  • " + NL + "
  • Element
  • "}, //Make sure the heading is correct. {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", From 2be05076f8f9f4c589730cd174f85e656fcca7fb Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Wed, 18 Sep 2013 22:47:06 -0700 Subject: [PATCH 0422/1294] 8024096: some javadoc tests may contain false positive results Reviewed-by: jjg --- .../com/sun/javadoc/lib/JavadocTester.java | 77 ++++++++++++++++++- .../testDocFileDir/TestDocFileDir.java | 30 +++----- .../sun/javadoc/testEncoding/EncodeTest.java | 6 +- .../javadoc/testEncoding/TestEncoding.java | 8 +- .../testMethodTypes/TestMethodTypes.java | 6 +- .../javadoc/testProfiles/TestProfiles.java | 31 +++----- 6 files changed, 104 insertions(+), 54 deletions(-) diff --git a/langtools/test/com/sun/javadoc/lib/JavadocTester.java b/langtools/test/com/sun/javadoc/lib/JavadocTester.java index 23b8c80482e..e5af454fee8 100644 --- a/langtools/test/com/sun/javadoc/lib/JavadocTester.java +++ b/langtools/test/com/sun/javadoc/lib/JavadocTester.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,6 +57,7 @@ public abstract class JavadocTester { protected static final String SRC_DIR = System.getProperty("test.src", "."); protected static final String JAVA_VERSION = System.getProperty("java.version"); protected static final String[][] NO_TEST = new String[][] {}; + protected static final String[] NO_FILE_TEST = new String[] {}; /** * Use this as the file name in the test array when you want to search @@ -165,6 +166,26 @@ public abstract class JavadocTester { return returnCode; } + /** + * Execute the tests. + * + * @param tester the tester to execute + * @param args the arguments to pass to Javadoc + * @param testArray the array of tests + * @param negatedTestArray the array of negated tests + * @param fileTestArray the array of file tests + * @param negatedFileTestArray the array of negated file tests + * @return the return code for the execution of Javadoc + */ + public static int run(JavadocTester tester, String[] args, + String[][] testArray, String[][] negatedTestArray, String[] fileTestArray, + String[] negatedFileTestArray) { + int returnCode = tester.runJavadoc(args); + tester.runTestsOnHTML(testArray, negatedTestArray); + tester.runTestsOnFile(fileTestArray, negatedFileTestArray); + return returnCode; + } + /** * Execute Javadoc using the default doclet. * @@ -243,6 +264,19 @@ public abstract class JavadocTester { runTestsOnHTML(negatedTestArray, true); } + /** + * Run array of tests on the generated files. + * This method accepts a fileTestArray for testing if a file is generated + * and a negatedFileTestArray for testing if a file is not found. + * + * @param testArray the array of file tests + * @param negatedTestArray the array of negated file tests + */ + public void runTestsOnFile(String[] fileTestArray, String[] negatedFileTestArray) { + runTestsOnFile(fileTestArray, false); + runTestsOnFile(negatedFileTestArray, true); + } + /** * Run the array of tests on the resulting HTML. * @@ -265,9 +299,11 @@ public abstract class JavadocTester { fileString = readFileToString(testArray[i][0]); } catch (Error e) { if (isNegated) { - numTestsPassed += 1; - System.out.println("Passed\n not found:\n" - + stringToFind + " in non-existent " + testArray[i][0] + "\n"); + System.out.println( "FAILED" + "\n" + + "for bug " + getBugId() + + " (" + getBugName() + ") " + + "due to " + + e + "\n"); continue; } throw e; @@ -290,6 +326,39 @@ public abstract class JavadocTester { } } + /** + * Run the array of file tests on the generated files. + * + * @param testArray the array of file tests + * @param isNegated true if test is negated; false otherwise + */ + private void runTestsOnFile(String[] testArray, boolean isNegated) { + String fileName; + String failedString; + String passedString; + for (int i = 0; i < testArray.length; i++) { + numTestsRun++; + fileName = testArray[i]; + failedString = "FAILED" + "\n" + + "for bug " + getBugId() + " (" + getBugName() + ") " + + "file (" + fileName + ") found" + "\n"; + passedString = "Passed" + "\n" + + "file (" + fileName + ") not found" + "\n"; + System.out.print("Running subtest #" + numTestsRun + "... "); + try { + File file = new File(fileName); + if ((file.exists() && !isNegated) || (!file.exists() && isNegated)) { + numTestsPassed += 1; + System.out.println(passedString); + } else { + System.out.println(failedString); + } + } catch (Error e) { + System.err.println(e); + } + } + } + /** * Iterate through the list of given file pairs and diff each file. * diff --git a/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java b/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java index c5dd3468443..1d1be4e5e02 100644 --- a/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java +++ b/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ import java.io.File; /* * @test - * @bug 4258405 4973606 + * @bug 4258405 4973606 8024096 * @summary This test verifies that the doc-file directory does not * get overwritten when the sourcepath is equal to the destination * directory. @@ -47,25 +47,17 @@ public class TestDocFileDir extends JavadocTester { }; private static final String[][] NEGATED_TEST1 = NO_TEST; - private static final String[][] TEST2 = { - {BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-used1" + + private static final String[] FILE_TEST2 = { + BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-used1" + FS + "testfile.txt", - "passed" - }, - {BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-used2" + - FS + "testfile.txt", - "passed" - }, + BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-used2" + + FS + "testfile.txt" }; - private static final String[][] NEGATED_TEST2 = { - {BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-excluded1" + + private static final String[] FILE_NEGATED_TEST2 = { + BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-excluded1" + FS + "testfile.txt", - "passed" - }, - {BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-excluded2" + - FS + "testfile.txt", - "passed" - }, + BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-excluded2" + + FS + "testfile.txt" }; private static final String[][] TEST0 = { @@ -106,7 +98,7 @@ public class TestDocFileDir extends JavadocTester { run(tester, ARGS0, TEST0, NEGATED_TEST0); copyDir(SRC_DIR + FS + "pkg", BUG_ID + "-1"); run(tester, ARGS1, TEST1, NEGATED_TEST1); - run(tester, ARGS2, TEST2, NEGATED_TEST2); + run(tester, ARGS2, NO_TEST, NO_TEST, FILE_TEST2, FILE_NEGATED_TEST2); tester.printSummary(); } diff --git a/langtools/test/com/sun/javadoc/testEncoding/EncodeTest.java b/langtools/test/com/sun/javadoc/testEncoding/EncodeTest.java index 3fa762d5bf6..393ba8f5de2 100644 --- a/langtools/test/com/sun/javadoc/testEncoding/EncodeTest.java +++ b/langtools/test/com/sun/javadoc/testEncoding/EncodeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,9 @@ /** - * ɿ ! + * Testing en\u00e7\u00f4ded string. + * In the encoded comment string, Unicode U+00E7 is "Latin small letter C with cedilla" + * and Unicode U+00F4 is "Latin small letter O with circumflex" */ public class EncodeTest { } diff --git a/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java b/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java index 0e9f1b6f101..db627b69156 100644 --- a/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java +++ b/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4661481 + * @bug 4661481 8024096 * @summary This test determines if the value of the -encoding option is * properly passed from Javadoc to the source file parser. * @author jamieh @@ -40,12 +40,12 @@ public class TestEncoding extends JavadocTester { //If ??? is found in the output, the source file was not read with the correct encoding setting. private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "EncodeTest.html", "???"} + {BUG_ID + FS + "EncodeTest.html", "??"} }; private static final String[] ARGS = new String[] { "-d", BUG_ID, "-sourcepath", SRC_DIR, - "-encoding", "SJIS", SRC_DIR + FS + "EncodeTest.java" + "-encoding", "iso-8859-1", SRC_DIR + FS + "EncodeTest.java" }; /** diff --git a/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java b/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java index 634ee4e4407..b0b79de0981 100644 --- a/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java +++ b/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8002304 + * @bug 8002304 8024096 * @summary Test for various method types in the method summary table * @author Bhavesh Patel * @library ../lib/ @@ -107,7 +107,7 @@ public class TestMethodTypes extends JavadocTester { "" }, - {BUG_ID + FS + "pkg" + FS + "D.html", + {BUG_ID + FS + "pkg1" + FS + "D.html", "" }, diff --git a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java index 8dda141791c..4dd70ea2359 100644 --- a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java +++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8006124 8009684 8016921 8023700 + * @bug 8006124 8009684 8016921 8023700 8024096 * @summary Test javadoc support for profiles. * @author Bhavesh Patel, Evgeniya Stepanova * @library ../lib/ @@ -187,26 +187,6 @@ public class TestProfiles extends JavadocTester { } }; private static final String[][] PACKAGES_NEGATED_TEST = { - {PACKAGE_BUG_ID + FS + "profile-overview-frame.html", - "All Packages" - }, - {PACKAGE_BUG_ID + FS + "compact2-frame.html", - "" - + "All PackagesAll Profiles" - }, - {PACKAGE_BUG_ID + FS + "pkg2" + FS + "compact2-package-frame.html", - "" - + "compact2 - pkg2" - }, - {PACKAGE_BUG_ID + FS + "compact2-summary.html", - "

    Profile compact2

    " - }, - {PACKAGE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html", - "
    compact3
    " - }, {PACKAGE_BUG_ID + FS + "overview-frame.html", "All Profiles" @@ -222,6 +202,13 @@ public class TestProfiles extends JavadocTester { "" } }; + private static final String[] PACKAGES_NEGATED_FILE_TEST = { + PACKAGE_BUG_ID + FS + "profile-overview-frame.html", + PACKAGE_BUG_ID + FS + "compact2-frame.html", + PACKAGE_BUG_ID + FS + "pkg2" + FS + "compact2-package-frame.html", + PACKAGE_BUG_ID + FS + "compact2-summary.html", + PACKAGE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html" + }; /** * The entry point of the test. @@ -231,7 +218,7 @@ public class TestProfiles extends JavadocTester { public static void main(String[] args) { TestProfiles tester = new TestProfiles(); run(tester, ARGS1, PROFILES_TEST, PROFILES_NEGATED_TEST); - run(tester, ARGS2, PACKAGES_TEST, PACKAGES_NEGATED_TEST); + run(tester, ARGS2, PACKAGES_TEST, PACKAGES_NEGATED_TEST, NO_FILE_TEST, PACKAGES_NEGATED_FILE_TEST); tester.printSummary(); } From c2859f0bcad87c0bc9ba3fd23953ec4ccb00999d Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 19 Sep 2013 13:34:01 +0530 Subject: [PATCH 0423/1294] 8025048: true as case label results in ClassCastException Reviewed-by: lagergren --- .../jdk/nashorn/internal/codegen/Attr.java | 6 ++-- nashorn/test/script/basic/JDK-8025048-2.js | 36 +++++++++++++++++++ nashorn/test/script/basic/JDK-8025048.js | 36 +++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025048-2.js create mode 100644 nashorn/test/script/basic/JDK-8025048.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index 813d3fc9083..55355c3efc8 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -807,9 +807,11 @@ final class Attr extends NodeOperatorVisitor { type = Type.OBJECT; } - type = Type.widest(type, newCaseNode.getTest().getType()); - if (type.isBoolean()) { + final Type newCaseType = newCaseNode.getTest().getType(); + if (newCaseType.isBoolean()) { type = Type.OBJECT; //booleans and integers aren't assignment compatible + } else { + type = Type.widest(type, newCaseType); } } diff --git a/nashorn/test/script/basic/JDK-8025048-2.js b/nashorn/test/script/basic/JDK-8025048-2.js new file mode 100644 index 00000000000..c11816bad53 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025048-2.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8025048: true as case label results in ClassCastException + * + * @test + * @run + */ + +function func(x) { + switch(x) { + case 8: break; case false: + } +} + diff --git a/nashorn/test/script/basic/JDK-8025048.js b/nashorn/test/script/basic/JDK-8025048.js new file mode 100644 index 00000000000..75838a987d6 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025048.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8025048: true as case label results in ClassCastException + * + * @test + * @run + */ + +function func(x) { + switch(x) { + case 8: break; case true: + } +} + From ca51d27ee3acebaf0475d789b58d3f1c4358c46b Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Thu, 19 Sep 2013 17:05:32 +0400 Subject: [PATCH 0424/1294] 8017248: Compiler Diacritics Issue Reviewed-by: naoto --- .../sun/tools/javac/file/RegularFileObject.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java b/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java index d99d729ac2c..055977f172e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java @@ -40,6 +40,7 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharsetDecoder; import javax.tools.JavaFileObject; +import java.text.Normalizer; /** * A subclass of JavaFileObject representing regular files. @@ -57,6 +58,7 @@ class RegularFileObject extends BaseFileObject { private String name; final File file; private Reference absFileRef; + final static boolean isMacOS = System.getProperty("os.name", "").contains("OS X"); public RegularFileObject(JavacFileManager fileManager, File f) { this(fileManager, f.getName(), f); @@ -180,7 +182,19 @@ class RegularFileObject extends BaseFileObject { if (name.equals(n)) { return true; } - if (name.equalsIgnoreCase(n)) { + if (isMacOS && Normalizer.isNormalized(name, Normalizer.Form.NFD) + && Normalizer.isNormalized(n, Normalizer.Form.NFC)) { + // On Mac OS X it is quite possible to file name and class + // name normalized in a different way - in that case we have to normalize file name + // to the Normal Form Compised (NFC) + String normName = Normalizer.normalize(name, Normalizer.Form.NFC); + if (normName.equals(n)) { + this.name = normName; + return true; + } + } + + if (name.equalsIgnoreCase(n)) { try { // allow for Windows return file.getCanonicalFile().getName().equals(n); From 3d49dcdd9a8e5989b0bdbc6af6736f7064442b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Thu, 19 Sep 2013 15:39:01 +0200 Subject: [PATCH 0425/1294] 8023154: compileAllTests fails with: 2 tests failed to compile Reviewed-by: sundar, jlaskey --- nashorn/make/build-benchmark.xml | 8 ++++---- nashorn/make/build.xml | 14 ++++++++------ nashorn/make/project.properties | 7 ++++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/nashorn/make/build-benchmark.xml b/nashorn/make/build-benchmark.xml index f1ce180a844..8f2296b028e 100644 --- a/nashorn/make/build-benchmark.xml +++ b/nashorn/make/build-benchmark.xml @@ -329,7 +329,7 @@ fork="true" dir="."> - + @@ -357,7 +357,7 @@ classpath="${run.test.classpath}" fork="true" dir="."> - + @@ -391,7 +391,7 @@ fork="true" dir="."> - + @@ -415,7 +415,7 @@ classpath="${run.test.classpath}" fork="true" dir="."> - + diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml index 73644a6b523..4bc1a398b4d 100644 --- a/nashorn/make/build.xml +++ b/nashorn/make/build.xml @@ -66,6 +66,8 @@ + + @@ -320,7 +322,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -336,7 +338,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -352,7 +354,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -369,7 +371,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -387,7 +389,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { description="Run the shell with a sample script"> - + @@ -397,7 +399,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { description="Debug the shell with a sample script"> - + diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties index 5523f6cbab8..e6eea02eaa9 100644 --- a/nashorn/make/project.properties +++ b/nashorn/make/project.properties @@ -216,13 +216,14 @@ run.test.classpath=\ src.dir=src test.src.dir=test/src +# -Xmx is used for all tests, -Xms only for octane benchmark run.test.xmx=3G run.test.xms=2G run.test.user.language=tr run.test.user.country=TR -run.test.jvmargs.common=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError +run.test.jvmargs.common=-server -XX:+TieredCompilation -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError #-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M # -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods @@ -231,12 +232,12 @@ run.test.jvmargs.common=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -Dfil run.test.jvmargs.main=${run.test.jvmargs.common} -ea #-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M -run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.common} +run.test.jvmargs.octane.main=${run.test.jvmargs.common} run.test.jvmsecurityargs=-Xverify:all -Djava.security.properties=${basedir}/make/java.security.override -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy # VM options for script tests with @fork option -test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} ${run.test.jvmsecurityargs} +test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} # path of rhino.jar for benchmarks rhino.jar= From a1f3a95880318c32169ff89dc8784a0dfc629eec Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Thu, 19 Sep 2013 11:04:23 -0400 Subject: [PATCH 0426/1294] 8024517: runtime/CDSCompressedKPtrs/XShareAuto.java failed with RuntimeException Make sure CDS is off by default when running server compiler. Reviewed-by: dholmes, coleenp --- hotspot/src/share/vm/runtime/arguments.cpp | 22 +++++++++++-------- .../CDSCompressedKPtrs/XShareAuto.java | 11 ++-------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 78b8338265d..36827a518cf 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1096,6 +1096,7 @@ void Arguments::set_mode_flags(Mode mode) { } } +#if defined(COMPILER2) || defined(_LP64) || !INCLUDE_CDS // Conflict: required to use shared spaces (-Xshare:on), but // incompatible command line options were chosen. @@ -1108,6 +1109,7 @@ static void no_shared_spaces() { FLAG_SET_DEFAULT(UseSharedSpaces, false); } } +#endif void Arguments::set_tiered_flags() { // With tiered, set default policy to AdvancedThresholdPolicy, which is 3. @@ -1492,16 +1494,18 @@ void Arguments::set_ergonomics_flags() { FLAG_SET_ERGO(bool, UseParallelGC, true); } } - // Shared spaces work fine with other GCs but causes bytecode rewriting - // to be disabled, which hurts interpreter performance and decreases - // server performance. On server class machines, keep the default - // off unless it is asked for. Future work: either add bytecode rewriting - // at link time, or rewrite bytecodes in non-shared methods. - if (!DumpSharedSpaces && !RequireSharedSpaces && - (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) { - no_shared_spaces(); - } } +#ifdef COMPILER2 + // Shared spaces work fine with other GCs but causes bytecode rewriting + // to be disabled, which hurts interpreter performance and decreases + // server performance. When -server is specified, keep the default off + // unless it is asked for. Future work: either add bytecode rewriting + // at link time, or rewrite bytecodes in non-shared methods. + if (!DumpSharedSpaces && !RequireSharedSpaces && + (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) { + no_shared_spaces(); + } +#endif #ifndef ZERO #ifdef _LP64 diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java index 7f36977ec70..9bd68e11733 100644 --- a/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java +++ b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java @@ -33,16 +33,9 @@ import com.oracle.java.testlibrary.*; public class XShareAuto { public static void main(String[] args) throws Exception { - if (!Platform.is64bit()) { - System.out.println("ObjectAlignmentInBytes for CDS is only " + - "supported on 64bit platforms; this plaform is " + - System.getProperty("sun.arch.data.model")); - System.out.println("Skipping the test"); - return; - } ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", - "-Xshare:dump"); + "-server", "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("Loading classes to share"); output.shouldHaveExitValue(0); From 1c9e7a8edc07aa9038adca1cd97d9e98a36c7b15 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Thu, 19 Sep 2013 17:05:08 +0200 Subject: [PATCH 0427/1294] 8022567: Javac Should Generate Warnings For Raw Array Type Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Check.java | 18 ++++++++++++------ .../tools/javac/warnings/6747671/T6747671.java | 9 ++++++++- .../tools/javac/warnings/6747671/T6747671.out | 4 +++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 5f6d1886bd8..d3f94fdba82 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -1245,6 +1245,7 @@ public class Check { */ class Validator extends JCTree.Visitor { + boolean checkRaw; boolean isOuter; Env env; @@ -1254,7 +1255,7 @@ public class Check { @Override public void visitTypeArray(JCArrayTypeTree tree) { - tree.elemtype.accept(this); + validateTree(tree.elemtype, checkRaw, isOuter); } @Override @@ -1345,15 +1346,20 @@ public class Check { } public void validateTree(JCTree tree, boolean checkRaw, boolean isOuter) { - try { - if (tree != null) { - this.isOuter = isOuter; + if (tree != null) { + boolean prevCheckRaw = this.checkRaw; + this.checkRaw = checkRaw; + this.isOuter = isOuter; + + try { tree.accept(this); if (checkRaw) checkRaw(tree, env); + } catch (CompletionFailure ex) { + completionError(tree.pos(), ex); + } finally { + this.checkRaw = prevCheckRaw; } - } catch (CompletionFailure ex) { - completionError(tree.pos(), ex); } } diff --git a/langtools/test/tools/javac/warnings/6747671/T6747671.java b/langtools/test/tools/javac/warnings/6747671/T6747671.java index c8060a06afd..2bb67ac132f 100644 --- a/langtools/test/tools/javac/warnings/6747671/T6747671.java +++ b/langtools/test/tools/javac/warnings/6747671/T6747671.java @@ -1,6 +1,6 @@ /** * @test /nodynamiccopyright/ - * @bug 6747671 + * @bug 6747671 8022567 * @summary -Xlint:rawtypes * @compile/ref=T6747671.out -XDrawDiagnostics -Xlint:rawtypes T6747671.java */ @@ -32,4 +32,11 @@ class T6747671 { A a2 = new A() {};//raw warning (2) a2.new Z() {};//raw warning } + + @TA B @TA[] arr = new @TA B @TA [0];//JDK-8022567: raw warning (2) + Class classes1;//no warning + Class[] classes2;//no warning + + @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE) + @interface TA { } } diff --git a/langtools/test/tools/javac/warnings/6747671/T6747671.out b/langtools/test/tools/javac/warnings/6747671/T6747671.out index 43069572c62..518804d68b5 100644 --- a/langtools/test/tools/javac/warnings/6747671/T6747671.out +++ b/langtools/test/tools/javac/warnings/6747671/T6747671.out @@ -7,4 +7,6 @@ T6747671.java:29:28: compiler.warn.raw.class.use: T6747671.B, T6747671.B T6747671.java:32:9: compiler.warn.raw.class.use: T6747671.A, T6747671.A T6747671.java:32:20: compiler.warn.raw.class.use: T6747671.A, T6747671.A T6747671.java:33:16: compiler.warn.raw.class.use: T6747671.A.Z, T6747671.A.Z -9 warnings +T6747671.java:36:9: compiler.warn.raw.class.use: @T6747671.TA T6747671.B, T6747671.B +T6747671.java:36:27: compiler.warn.raw.class.use: T6747671.B, T6747671.B +11 warnings From 5db62ec900bbdb41ba2a927eb41787326ae382f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20=C3=96hrstr=C3=B6m?= Date: Thu, 19 Sep 2013 08:26:26 -0700 Subject: [PATCH 0428/1294] 8024609: sjavac assertion fails during call to BuildState.collectArtifacts Reviewed-by: jjg --- .../classes/com/sun/tools/sjavac/BuildState.java | 16 ++++++++++------ .../share/classes/com/sun/tools/sjavac/Main.java | 8 ++++---- .../com/sun/tools/sjavac/server/JavacServer.java | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java b/langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java index 9b90950290c..43606b2b715 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -81,12 +81,13 @@ public class BuildState { } /** - * Collect all packages, sources and artifacts for all modules - * into the build state. + * Store references to all packages, sources and artifacts for all modules + * into the build state. I.e. flatten the module tree structure + * into global maps stored in the BuildState for easy access. * * @param m The set of modules. */ - public void collectPackagesSourcesAndArtifacts(Map m) { + public void flattenPackagesSourcesAndArtifacts(Map m) { modules = m; // Extract all the found packages. for (Module i : modules.values()) { @@ -121,11 +122,12 @@ public class BuildState { } /** - * Collect all the artifacts of all modules and packages. + * Store references to all artifacts found in the module tree into the maps + * stored in the build state. * * @param m The set of modules. */ - public void collectArtifacts(Map m) { + public void flattenArtifacts(Map m) { modules = m; // Extract all the found packages. for (Module i : modules.values()) { @@ -270,6 +272,8 @@ public class BuildState { Module mnew = findModuleFromPackageName(pkg); Package pprev = prev.packages().get(pkg); mnew.addPackage(pprev); + // Do not forget to update the flattened data. + packages.put(pkg, pprev); } } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java index f0ed51432ee..183ebb56e27 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java @@ -274,7 +274,7 @@ public class Main { // findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true); // Add the set of sources to the build database. - javac_state.now().collectPackagesSourcesAndArtifacts(modules); + javac_state.now().flattenPackagesSourcesAndArtifacts(modules); javac_state.now().checkInternalState("checking sources", false, sources); javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to); javac_state.setVisibleSources(sources_to_link_to); @@ -311,7 +311,7 @@ public class Main { Map generated_sources = new HashMap(); Source.scanRoot(gensrc_dir, Util.set(".java"), null, null, null, null, generated_sources, modules, current_module, false, true, false); - javac_state.now().collectPackagesSourcesAndArtifacts(modules); + javac_state.now().flattenPackagesSourcesAndArtifacts(modules); // Recheck the the source files and their timestamps again. javac_state.checkSourceStatus(true); @@ -336,8 +336,8 @@ public class Main { // Only update the state if the compile went well. if (rc[0]) { javac_state.save(); - // Collect all the artifacts. - javac_state.now().collectArtifacts(modules); + // Reflatten only the artifacts. + javac_state.now().flattenArtifacts(modules); // Remove artifacts that were generated during the last compile, but not this one. javac_state.removeSuperfluousArtifacts(recently_compiled); } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java index 2e59f275fd8..66e3022a76e 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java @@ -464,7 +464,7 @@ public class JavacServer { PrintStream err) { int rc = -3; try { - int port = portFile.getPort(); + int port = portFile.containsPortInfo() ? portFile.getPort() : 0; if (port == 0) { return ERROR_BUT_TRY_AGAIN; } From d6f64ae0092a69677ea4ec58865b63396330e25f Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 19 Sep 2013 21:20:47 +0530 Subject: [PATCH 0429/1294] 8025080: Object literal getter, setter function with number format property name results in ClassFormatError Reviewed-by: lagergren, hannesw --- .../nashorn/internal/ir/debug/JSONWriter.java | 3 +- .../jdk/nashorn/internal/parser/Parser.java | 5 ++- nashorn/test/script/basic/JDK-8025080.js | 43 +++++++++++++++++++ .../test/script/basic/JDK-8025080.js.EXPECTED | 4 ++ .../basic/parser/objectLitExpr.js.EXPECTED | 10 +---- 5 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025080.js create mode 100644 nashorn/test/script/basic/JDK-8025080.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java index dabc7e36bf1..4702057a34c 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java +++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java @@ -410,7 +410,8 @@ public final class JSONWriter extends NodeVisitor { comma(); property("id"); - if (functionNode.isAnonymous()) { + final FunctionNode.Kind kind = functionNode.getKind(); + if (functionNode.isAnonymous() || kind == FunctionNode.Kind.GETTER || kind == FunctionNode.Kind.SETTER) { nullValue(); } else { functionNode.getIdent().accept(this); diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index d051917149e..9663401ff5e 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -59,6 +59,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import jdk.internal.dynalink.support.NameCodec; import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.codegen.Namespace; import jdk.nashorn.internal.ir.AccessNode; @@ -2108,7 +2109,7 @@ loop: case "get": final PropertyKey getIdent = propertyName(); final String getterName = getIdent.getPropertyName(); - final IdentNode getNameNode = new IdentNode(((Node)getIdent).getToken(), finish, "get " + getterName); + final IdentNode getNameNode = new IdentNode(((Node)getIdent).getToken(), finish, "get " + NameCodec.encode(getterName)); expect(LPAREN); expect(RPAREN); functionNode = functionBody(getSetToken, getNameNode, new ArrayList(), FunctionNode.Kind.GETTER); @@ -2117,7 +2118,7 @@ loop: case "set": final PropertyKey setIdent = propertyName(); final String setterName = setIdent.getPropertyName(); - final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, "set " + setterName); + final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, "set " + NameCodec.encode(setterName)); expect(LPAREN); final IdentNode argIdent = getIdent(); verifyStrictIdent(argIdent, "setter argument"); diff --git a/nashorn/test/script/basic/JDK-8025080.js b/nashorn/test/script/basic/JDK-8025080.js new file mode 100644 index 00000000000..1ea46efa530 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025080.js @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8025080: Object literal getter, setter function with number format property name results in ClassFormatError + * + * @test + * @run + */ + +var obj = { + get 1e81() { print("1e81 getter"); }, + set 1e81(x) { print("1e81 setter"); }, + get 3.14e-2() { print("3.14e-2 getter");}, + set 3.14e-2(x) { print("3.14e-2 setter"); } +}; + +obj[1e81]; +obj[1e81] = 23; + +obj[3.14e-2]; +obj[3.14e-2] = 42; + diff --git a/nashorn/test/script/basic/JDK-8025080.js.EXPECTED b/nashorn/test/script/basic/JDK-8025080.js.EXPECTED new file mode 100644 index 00000000000..e19e8ae9621 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025080.js.EXPECTED @@ -0,0 +1,4 @@ +1e81 getter +1e81 setter +3.14e-2 getter +3.14e-2 setter diff --git a/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED b/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED index 067c506ab95..7968d9a4a0f 100644 --- a/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED +++ b/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED @@ -126,10 +126,7 @@ }, "value": { "type": "FunctionExpression", - "id": { - "type": "Identifier", - "name": "get x" - }, + "id": null, "params": [], "defaults": [], "rest": null, @@ -157,10 +154,7 @@ }, "value": { "type": "FunctionExpression", - "id": { - "type": "Identifier", - "name": "get y" - }, + "id": null, "params": [], "defaults": [], "rest": null, From ff9c0f87c4dd3f17fb075bc0cba65b3dd4762c5c Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:36:42 -0700 Subject: [PATCH 0430/1294] Added tag jdk8-b108 for changeset 345aa6f8d18a --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index d83fa5ca611..fbcdb0977c0 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -229,3 +229,4 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103 5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105 8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106 0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107 +9286a6e61291246d88af713f1ef79adeea30fe2e jdk8-b108 From 62ae29e3cad403385213865a0a1c920643d91482 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:36:44 -0700 Subject: [PATCH 0431/1294] Added tag jdk8-b108 for changeset 78407de2df2f --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index e24845b3555..7271ad7b3fa 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -229,3 +229,4 @@ d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104 4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105 2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106 23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107 +a4bb3b4500164748a9c33b2283cfda76d89f25ab jdk8-b108 From 6e53556facbfe6dbcaa9107947b8d65d137c0f0b Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:36:51 -0700 Subject: [PATCH 0432/1294] Added tag jdk8-b108 for changeset be8d551c4d00 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 370ade6688d..024f5b4d0ee 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -377,3 +377,4 @@ aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106 50794d8ac11c9579b41dec4de23b808fef9f34a1 hs25-b49 5b7f90aab3ad25a25b75b7b2bb18d5ae23d8231c jdk8-b107 a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50 +85072013aad46050a362d10ab78e963121c8014c jdk8-b108 From bfcf677949ddfc9881716d2e57a4512304bb989a Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:37:02 -0700 Subject: [PATCH 0433/1294] Added tag jdk8-b108 for changeset 261ae91f2b65 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index e136f4f7d31..f3166e9d9df 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -229,3 +229,4 @@ a22fe9bd01e6c7e7ddc7995dfc9471711692b8d1 jdk8-b104 09a46ec11f880154886c70be03aff5ab2ddf0ab7 jdk8-b105 d3be8e3b429df917e72c1c23e7920c651219b587 jdk8-b106 d6a32e3831aab20a9a3bc78cdc0a60aaad725c6c jdk8-b107 +8ade3eed63da87067a7137c111f684a821e9e531 jdk8-b108 From e8367de47cb63d71d4b42083feb2cc65a29e8cd5 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:37:05 -0700 Subject: [PATCH 0434/1294] Added tag jdk8-b108 for changeset 815fb8808c4b --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 164a718d39c..6a23622251b 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -229,3 +229,4 @@ b1fb4612a2caea52b5661b87509e560fa044b194 jdk8-b98 88390df7ed2cf128298a02c5e6d978f0a603cd58 jdk8-b105 6908370afe834ff01739e8ec992d4246c74b7e6e jdk8-b106 e3c9328f75638289a342ce15fbe532f05078946e jdk8-b107 +d1ea68556fd7925a3c7078dd9f77c6ca73d5aa9e jdk8-b108 From f0b751a85487dc289e5bd6635fa68041611c9fdd Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:37:13 -0700 Subject: [PATCH 0435/1294] Added tag jdk8-b108 for changeset f45d281bd0de --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 3e3a625970b..6eef7251ea8 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -229,3 +229,4 @@ f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104 1fe211ae3d2b8cc2dfc4f58d9a6eb96418679672 jdk8-b105 c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106 eea685b9ccaa1980e0a7e07d6a3a84bcc7e9ab82 jdk8-b107 +006aaa5f069e7dd98fccdc696866c9f8582c087c jdk8-b108 From cb06edc1bf96e8683ce735eb0da0da771bf996b0 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:37:26 -0700 Subject: [PATCH 0436/1294] Added tag jdk8-b108 for changeset 669e1adcbf50 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index f3ac2a1e9ab..2210809d462 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -229,3 +229,4 @@ dd4a00c220c6e14d9b2ce93a2bd436a1d04f0d03 jdk8-b104 375834b5cf086dd7ce9e49f602d81bb51d3e0fa9 jdk8-b105 fcd768844b9926c5f994292ec6350c20cc7c0f76 jdk8-b106 3f274927ec1863544b8214262ab02b7de2970da6 jdk8-b107 +252f872b8a2f81a416f9127e77924ca56a4578b0 jdk8-b108 From 1c1306bb1d06768a13f1b9daad7727829c6507a3 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:37:28 -0700 Subject: [PATCH 0437/1294] Added tag jdk8-b108 for changeset 3afa46cd7e01 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 05fbb43822b..10aa318ed1d 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -217,3 +217,4 @@ afc100513451d22f0b8135999d6eb52f36df3d36 jdk8-b104 f484bfb624dd06683cb33b524700a5dd4927a82b jdk8-b105 bf70cbd2c8369fd97ffdfcbe1a80dbc2797408ee jdk8-b106 f35e1255024b66f7cf82517798f45f6e194e5567 jdk8-b107 +445ad3f6d3b4ba62ebc483323e1919110a304053 jdk8-b108 From 996bf0feefdb5384f74e44e3713dfea4dc7154ef Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 19 Sep 2013 23:48:37 +0530 Subject: [PATCH 0438/1294] 8025090: 'while' statement with 'test' using var before being declared in body results in VerifyError Reviewed-by: jlaskey --- .../jdk/nashorn/internal/ir/WhileNode.java | 9 +++-- nashorn/test/script/basic/JDK-8025090.js | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025090.js diff --git a/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java index 3c0046c0879..97e7ca54fc1 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java @@ -79,13 +79,12 @@ public final class WhileNode extends LoopNode { if (visitor.enterWhileNode(this)) { if (isDoWhile()) { return visitor.leaveWhileNode( - setTest(lc, (Expression)test.accept(visitor)). - setBody(lc, (Block)body.accept(visitor))); + setBody(lc, (Block)body.accept(visitor)). + setTest(lc, (Expression)test.accept(visitor))); } return visitor.leaveWhileNode( - setBody(lc, (Block)body.accept(visitor)). - setTest(lc, (Expression)test.accept(visitor))); - + setTest(lc, (Expression)test.accept(visitor)). + setBody(lc, (Block)body.accept(visitor))); } return this; } diff --git a/nashorn/test/script/basic/JDK-8025090.js b/nashorn/test/script/basic/JDK-8025090.js new file mode 100644 index 00000000000..8e42099cf47 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025090.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8025090: 'while' statement with 'test' using var before being declared in body results in VerifyError + * + * @test + * @run + */ + +// The following used to result in VerifyError +function f() { + while (x += 2) { var x = 44 } +} + From 721272b6c0d7cf5690561c5ae75fef3127ef7abc Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Thu, 19 Sep 2013 22:33:21 +0400 Subject: [PATCH 0439/1294] 7144065: [macosx] Orphaned Choice popup window Reviewed-by: anthony, serb --- .../classes/sun/lwawt/LWChoicePeer.java | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java b/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java index dc781d3d682..c90300e8dcf 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,13 +26,13 @@ package sun.lwawt; -import java.awt.Choice; -import java.awt.Point; +import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.peer.ChoicePeer; -import javax.swing.JComboBox; +import javax.accessibility.Accessible; +import javax.swing.*; final class LWChoicePeer extends LWComponentPeer> implements ChoicePeer, ItemListener { @@ -159,5 +159,32 @@ final class LWChoicePeer extends LWComponentPeer> } super.setSelectedItem(anObject); } + + @Override + public void firePopupMenuWillBecomeVisible() { + super.firePopupMenuWillBecomeVisible(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JPopupMenu popupMenu = getPopupMenu(); + if (popupMenu != null) { + if (popupMenu.getInvoker() != LWChoicePeer.this.getTarget()) { + popupMenu.setVisible(false); + popupMenu.show(LWChoicePeer.this.getTarget(), 0, 0); + } + } + } + }); + } + + private JPopupMenu getPopupMenu() { + for (int i = 0; i < getAccessibleContext().getAccessibleChildrenCount(); i++) { + Accessible child = getAccessibleContext().getAccessibleChild(i); + if (child instanceof JPopupMenu) { + return (JPopupMenu) child; + } + } + return null; + } } } From bf404f9ad8af77e55156e84c1765fb5cfd38813b Mon Sep 17 00:00:00 2001 From: Leonid Romanov Date: Thu, 19 Sep 2013 23:46:15 +0400 Subject: [PATCH 0440/1294] 7129133: [macosx] Accelerators are displayed as Meta instead of the Command symbol Reviewed-by: anthony, serb --- jdk/makefiles/GensrcProperties.gmk | 7 ++ .../sun/awt/resources/awtosx.properties | 71 +++++++++++++++++++ .../classes/sun/lwawt/macosx/LWCToolkit.java | 23 +++++- jdk/src/share/classes/java/awt/Toolkit.java | 24 +++++++ .../share/classes/sun/awt/AWTAccessor.java | 27 +++++++ .../ToolkitPropertyTest/bug7129133.java | 50 +++++++++++++ 6 files changed, 199 insertions(+), 3 deletions(-) create mode 100644 jdk/src/macosx/classes/sun/awt/resources/awtosx.properties create mode 100644 jdk/test/java/awt/Toolkit/ToolkitPropertyTest/bug7129133.java diff --git a/jdk/makefiles/GensrcProperties.gmk b/jdk/makefiles/GensrcProperties.gmk index 3ef3a538475..1e29376f6ad 100644 --- a/jdk/makefiles/GensrcProperties.gmk +++ b/jdk/makefiles/GensrcProperties.gmk @@ -253,6 +253,13 @@ ifeq ($(OPENJDK_TARGET_OS),windows) $(call CacheFind,$(JDK_TOPDIR)/src/windows/classes/sun/awt/windows)),\ ListResourceBundle,%zh_TW,%zh_HK)) endif +# os x specific awt properties +ifeq ($(OPENJDK_TARGET_OS),macosx) +$(eval $(call add_properties_to_compile,SUN_AWT,\ + $(filter $(JDK_TOPDIR)/src/macosx/classes/sun/awt/resources/%.properties,\ + $(call CacheFind,$(JDK_TOPDIR)/src/macosx/classes/sun/awt/resources)),\ + ListResourceBundle)) +endif #sun/launcher/resources $(eval $(call add_properties_to_compile,SUN_LAUNCHER,\ diff --git a/jdk/src/macosx/classes/sun/awt/resources/awtosx.properties b/jdk/src/macosx/classes/sun/awt/resources/awtosx.properties new file mode 100644 index 00000000000..bfc3bd01b3b --- /dev/null +++ b/jdk/src/macosx/classes/sun/awt/resources/awtosx.properties @@ -0,0 +1,71 @@ +# +# OS X specific AWT properties +# + +# Modifier names +AWT.shift=\u21e7 +AWT.control=\u2303 +AWT.alt=\u2325 +AWT.meta=\u2318 +AWT.altGraph=\u2325 + +# Key names +AWT.enter=\u23ce +AWT.backSpace=\u232b +AWT.tab=\u21e5 +AWT.cancel=\u238b +AWT.clear=\u2327 +AWT.capsLock=\u21ea +AWT.escape=\u238b +AWT.space=\u2423 +AWT.pgup=\u21de +AWT.pgdn=\u21df +AWT.end=\u2198 +AWT.home=\u2196 +AWT.left=\u2190 +AWT.up=\u2191 +AWT.right=\u2192 +AWT.down=\u2193 +AWT.comma=, +AWT.period=. +AWT.slash=/ +AWT.semicolon=; +AWT.equals=\u003d +AWT.openBracket=[ +AWT.backSlash=\\ +AWT.closeBracket=] +AWT.multiply=\u2328 * +AWT.add=\u2328 + +AWT.separator=\u2328 , +AWT.separater=\u2328 , +AWT.subtract=\u2328 - +AWT.decimal=\u2328 . +AWT.divide=\u2328 / +AWT.delete=\u2326 +AWT.printScreen=\u2399 +AWT.backQuote=` +AWT.quote=' +AWT.ampersand=& +AWT.asterisk=* +AWT.quoteDbl=" +AWT.Less=< +AWT.greater=> +AWT.braceLeft=[ +AWT.braceRight=] +AWT.at=@ +AWT.colon=: +AWT.circumflex=^ +AWT.dollar=$ +AWT.euro=\u20ac +AWT.exclamationMark=! +AWT.invertedExclamationMark=\u00a1 +AWT.leftParenthesis=( +AWT.numberSign=# +AWT.plus=+ +AWT.minus=- +AWT.rightParenthesis=) +AWT.underscore=_ + +# Numeric Keypad +AWT.numpad=\u2328 + diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index cf395f3ab86..d698845e558 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -44,6 +44,8 @@ import sun.lwawt.*; import sun.lwawt.LWWindowPeer.PeerType; import sun.security.action.GetBooleanAction; +import sun.util.CoreResourceBundleControl; + class NamedCursor extends Cursor { NamedCursor(String name) { super(name); @@ -67,13 +69,28 @@ public final class LWCToolkit extends LWToolkit { static { System.err.flush(); - java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { - public Object run() { + + ResourceBundle platformResources = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public ResourceBundle run() { + ResourceBundle platformResources = null; + try { + platformResources = + ResourceBundle.getBundle("sun.awt.resources.awtosx", + CoreResourceBundleControl.getRBControlInstance()); + } catch (MissingResourceException e) { + // No resource file; defaults will be used. + } + System.loadLibrary("awt"); System.loadLibrary("fontmanager"); - return null; + + return platformResources; } }); + + AWTAccessor.getToolkitAccessor().setPlatformResources(platformResources); + if (!GraphicsEnvironment.isHeadless()) { initIDs(); } diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java index ac2dc2244b8..6b669d33677 100644 --- a/jdk/src/share/classes/java/awt/Toolkit.java +++ b/jdk/src/share/classes/java/awt/Toolkit.java @@ -56,6 +56,7 @@ import sun.awt.HeadlessToolkit; import sun.awt.NullComponentPeer; import sun.awt.PeerEvent; import sun.awt.SunToolkit; +import sun.awt.AWTAccessor; import sun.security.util.SecurityConstants; import sun.util.CoreResourceBundleControl; @@ -1599,6 +1600,12 @@ public abstract class Toolkit { * here, so that only one copy is maintained. */ private static ResourceBundle resources; + private static ResourceBundle platformResources; + + // called by platform toolkit + private static void setPlatformResources(ResourceBundle bundle) { + platformResources = bundle; + } /** * Initialize JNI field and method ids @@ -1647,6 +1654,14 @@ public abstract class Toolkit { } static { + AWTAccessor.setToolkitAccessor( + new AWTAccessor.ToolkitAccessor() { + @Override + public void setPlatformResources(ResourceBundle bundle) { + Toolkit.setPlatformResources(bundle); + } + }); + java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Void run() { @@ -1674,6 +1689,15 @@ public abstract class Toolkit { * This method returns defaultValue if the property is not found. */ public static String getProperty(String key, String defaultValue) { + // first try platform specific bundle + if (platformResources != null) { + try { + return platformResources.getString(key); + } + catch (MissingResourceException e) {} + } + + // then shared one if (resources != null) { try { return resources.getString(key); diff --git a/jdk/src/share/classes/sun/awt/AWTAccessor.java b/jdk/src/share/classes/sun/awt/AWTAccessor.java index 2b7f73ccd31..d604768f5df 100644 --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java @@ -39,6 +39,7 @@ import java.lang.reflect.InvocationTargetException; import java.security.AccessControlContext; import java.io.File; +import java.util.ResourceBundle; import java.util.Vector; /** @@ -704,6 +705,13 @@ public final class AWTAccessor { boolean isSequencedEvent(AWTEvent event); } + /* + * An accessor for the Toolkit class + */ + public interface ToolkitAccessor { + void setPlatformResources(ResourceBundle bundle); + } + /* * Accessor instances are initialized in the static initializers of * corresponding AWT classes by using setters defined below. @@ -731,6 +739,7 @@ public final class AWTAccessor { private static TrayIconAccessor trayIconAccessor; private static DefaultKeyboardFocusManagerAccessor defaultKeyboardFocusManagerAccessor; private static SequencedEventAccessor sequencedEventAccessor; + private static ToolkitAccessor toolkitAccessor; /* * Set an accessor object for the java.awt.Component class. @@ -1124,4 +1133,22 @@ public final class AWTAccessor { // (so not a single instance of the event has been created). return sequencedEventAccessor; } + + /* + * Set an accessor object for the java.awt.Toolkit class. + */ + public static void setToolkitAccessor(ToolkitAccessor ta) { + toolkitAccessor = ta; + } + + /* + * Get the accessor object for the java.awt.Toolkit class. + */ + public static ToolkitAccessor getToolkitAccessor() { + if (toolkitAccessor == null) { + unsafe.ensureClassInitialized(Toolkit.class); + } + + return toolkitAccessor; + } } diff --git a/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/bug7129133.java b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/bug7129133.java new file mode 100644 index 00000000000..4578798066e --- /dev/null +++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/bug7129133.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, 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 7129133 + * @summary [macosx] Accelerators are displayed as Meta instead of the Command symbol + * @author leonid.romanov@oracle.com + * @run main bug7129133 + */ + +import java.awt.*; + +public class bug7129133 { + public static void main(String[] args) throws Exception { + if (sun.awt.OSInfo.getOSType() != sun.awt.OSInfo.OSType.MACOSX) { + System.out.println("This test is for MacOS only. Automatically passed on other platforms."); + return; + } + + Toolkit.getDefaultToolkit(); + + String cmdSymbol = "\u2318"; + String val = Toolkit.getProperty("AWT.meta", "Meta"); + + if (!val.equals(cmdSymbol)) { + throw new Exception("Wrong property value for AWT.meta. Expected: " + cmdSymbol + ", actual: " + val); + } + } +} From e3d450e3d306cdcd8f2c3762239e96b21d31176c Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Thu, 19 Sep 2013 20:57:37 +0100 Subject: [PATCH 0441/1294] 8024437: Inferring the exception thrown: sometimes fails to compile Reviewed-by: jjg --- .../com/sun/tools/javac/code/Flags.java | 2 +- .../com/sun/tools/javac/jvm/ClassReader.java | 7 ++ .../ExceptionInferenceFromClassFileTest.java | 74 +++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java index 3a4084ed2a8..2f59cfab7fd 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java @@ -261,7 +261,7 @@ public class Flags { public static final long SIGNATURE_POLYMORPHIC = 1L<<46; /** - * Flag that marks inference variables used in a 'throws' clause + * Flag that indicates that an inference variable is used in a 'throws' clause. */ public static final long THROWS = 1L<<47; diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index d3d9d302f1e..1b57b13cf36 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -56,6 +56,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTag.CLASS; +import static com.sun.tools.javac.code.TypeTag.TYPEVAR; import static com.sun.tools.javac.jvm.ClassFile.*; import static com.sun.tools.javac.jvm.ClassFile.Version.*; @@ -703,6 +704,12 @@ public class ClassReader { sigp++; thrown = thrown.prepend(sigToType()); } + // if there is a typevar in the throws clause we should state it. + for (List l = thrown; l.nonEmpty(); l = l.tail) { + if (l.head.hasTag(TYPEVAR)) { + l.head.tsym.flags_field |= THROWS; + } + } return new MethodType(argtypes, restype, thrown.reverse(), diff --git a/langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java b/langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java new file mode 100644 index 00000000000..250b18a0614 --- /dev/null +++ b/langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 8024437 + * @summary Inferring the exception thrown by a lambda: sometimes fails to compile + * @library /tools/javac/lib + * @build ToolBox + * @run main ExceptionInferenceFromClassFileTest + */ + +import java.nio.file.Files; +import java.nio.file.Paths; + +public class ExceptionInferenceFromClassFileTest { + + static final String ABSrc = + "class B {\n" + + " public static void t(A a) throws E {\n" + + " a.run();\n" + + " }\n" + + "}\n" + + + "interface A {\n" + + " void run() throws E;\n" + + "}"; + + static final String CSrc = + "class C {\n" + + " public void d() {\n" + + " B.t(null);\n" + + " }\n" + + "}"; + + public static void main(String[] args) throws Exception { + Files.createDirectory(Paths.get("out")); + + ToolBox.JavaToolArgs compileABParams = + new ToolBox.JavaToolArgs() + .setOptions("-d", "out") + .setSources(ABSrc); + ToolBox.javac(compileABParams); + + ToolBox.JavaToolArgs compileCParams = + new ToolBox.JavaToolArgs() + .setOptions("-d", "out", "-cp", "out") + .setSources(CSrc); + ToolBox.javac(compileCParams); + } + +} From 8b909ba5580011b7d810eef7cf9781dc83a1d6b3 Mon Sep 17 00:00:00 2001 From: Werner Dietl Date: Thu, 19 Sep 2013 19:18:37 -0700 Subject: [PATCH 0442/1294] 8025110: TreeCopier does not correctly copy LabeledStatementTree Reviewed-by: jjg --- .../src/share/classes/com/sun/tools/javac/tree/TreeCopier.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java index aa2ce423b4b..1ccbb53518e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java @@ -234,7 +234,7 @@ public class TreeCopier

    implements TreeVisitor { public JCTree visitLabeledStatement(LabeledStatementTree node, P p) { JCLabeledStatement t = (JCLabeledStatement) node; JCStatement body = copy(t.body, p); - return M.at(t.pos).Labelled(t.label, t.body); + return M.at(t.pos).Labelled(t.label, body); } public JCTree visitLiteral(LiteralTree node, P p) { From 337cfe593f82a081b9a21e11b3e1449f28931e15 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 20 Sep 2013 12:56:07 +0530 Subject: [PATCH 0443/1294] 8025111: undefined or null 'with' expression in empty with block should throw TypeError Reviewed-by: lagergren, hannesw --- .../internal/codegen/CodeGenerator.java | 9 +++- nashorn/test/script/basic/JDK-8025111.js | 48 +++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025111.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 6307e2f9dbe..d16a1e5ba1f 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -2174,8 +2174,9 @@ final class CodeGenerator extends NodeOperatorVisitor Date: Fri, 20 Sep 2013 10:53:28 +0200 Subject: [PATCH 0444/1294] 8024974: Incorrect use of GC_locker::is_active() SymbolTable and StringTable can make calls to GC_locker::is_active() outside a safepoint. This isn't safe because the GC_locker active state (lock count) is only updated at a safepoint and only remains valid as long as _needs_gc is true. However, outside a safepoint_needs_gc can change to false at any time, which makes it impossible to do a correct call to is_active() in that context. In this case these calls can just be removed since the input argument to basic_add() should never be on the heap and so there's no need to check the GC_locker state. This change also adjusts the assert() in is_active() to makes sure all calls to this function are always done under a safepoint. Reviewed-by: brutisso, dcubed --- hotspot/src/share/vm/classfile/symbolTable.cpp | 4 ++-- hotspot/src/share/vm/memory/gcLocker.cpp | 2 +- hotspot/src/share/vm/memory/gcLocker.hpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index c00e9581759..d0d33d878fe 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -341,7 +341,7 @@ Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) { Symbol* SymbolTable::basic_add(int index_arg, u1 *name, int len, unsigned int hashValue_arg, bool c_heap, TRAPS) { - assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), + assert(!Universe::heap()->is_in_reserved(name), "proposed name of symbol must be stable"); // Don't allow symbols to be created which cannot fit in a Symbol*. @@ -685,7 +685,7 @@ oop StringTable::intern(Handle string_or_null, jchar* name, if (found_string != NULL) return found_string; debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); - assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), + assert(!Universe::heap()->is_in_reserved(name), "proposed name of symbol must be stable"); Handle string; diff --git a/hotspot/src/share/vm/memory/gcLocker.cpp b/hotspot/src/share/vm/memory/gcLocker.cpp index eda728b7047..1b0c94ee171 100644 --- a/hotspot/src/share/vm/memory/gcLocker.cpp +++ b/hotspot/src/share/vm/memory/gcLocker.cpp @@ -122,7 +122,7 @@ void GC_locker::jni_unlock(JavaThread* thread) { // strictly needed. It's added here to make it clear that // the GC will NOT be performed if any other caller // of GC_locker::lock() still needs GC locked. - if (!is_active()) { + if (!is_active_internal()) { _doing_gc = true; { // Must give up the lock while at a safepoint diff --git a/hotspot/src/share/vm/memory/gcLocker.hpp b/hotspot/src/share/vm/memory/gcLocker.hpp index 8ede8fb275b..45b8a8f89e7 100644 --- a/hotspot/src/share/vm/memory/gcLocker.hpp +++ b/hotspot/src/share/vm/memory/gcLocker.hpp @@ -88,7 +88,7 @@ class GC_locker: public AllStatic { public: // Accessors static bool is_active() { - assert(_needs_gc || SafepointSynchronize::is_at_safepoint(), "only read at safepoint"); + assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint"); return is_active_internal(); } static bool needs_gc() { return _needs_gc; } From bbb009b580e819519598c582446b6db98f5950e5 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 20 Sep 2013 11:00:38 +0200 Subject: [PATCH 0445/1294] 8025059: Metspace::should_expand mixes bytes and words in check against MaxMetaspaceSize Reviewed-by: coleenp, brutisso, mgerdin, jmasa --- hotspot/src/share/vm/memory/metaspace.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index c12c0b8637b..0a741d674ca 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -1342,8 +1342,9 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) { // reserved space, because this is a larger space prereserved for compressed // class pointers. if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) { - size_t real_allocated = Metaspace::space_list()->reserved_words() + - MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); + size_t nonclass_allocated = MetaspaceAux::reserved_bytes(Metaspace::NonClassType); + size_t class_allocated = MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); + size_t real_allocated = nonclass_allocated + class_allocated; if (real_allocated >= MaxMetaspaceSize) { return false; } From 82156b393c325e6778983623c5e8f0ed74589694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Fri, 20 Sep 2013 12:11:08 +0200 Subject: [PATCH 0446/1294] 8022587: ClassCache is not optimal and leaks Source instances Reviewed-by: lagergren, attila --- .../jdk/nashorn/internal/objects/Global.java | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java index b7a902b745e..161909bb3f6 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java @@ -33,6 +33,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.reflect.Field; import java.util.Arrays; @@ -691,17 +692,41 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { * Cache for compiled script classes. */ @SuppressWarnings("serial") - private static class ClassCache extends LinkedHashMap>> { + private static class ClassCache extends LinkedHashMap { private final int size; + private final ReferenceQueue> queue; ClassCache(int size) { super(size, 0.75f, true); this.size = size; + this.queue = new ReferenceQueue<>(); + } + + void cache(final Source source, final Class clazz) { + put(source, new ClassReference(clazz, queue, source)); } @Override - protected boolean removeEldestEntry(final Map.Entry>> eldest) { - return size() >= size; + protected boolean removeEldestEntry(final Map.Entry eldest) { + return size() > size; + } + + @Override + public ClassReference get(Object key) { + for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) { + remove(ref.source); + } + return super.get(key); + } + + } + + private static class ClassReference extends SoftReference> { + private final Source source; + + ClassReference(final Class clazz, final ReferenceQueue> queue, final Source source) { + super(clazz, queue); + this.source = source; } } @@ -709,22 +734,14 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { @Override public Class findCachedClass(final Source source) { assert classCache != null : "Class cache used without being initialized"; - SoftReference> ref = classCache.get(source); - if (ref != null) { - final Class clazz = ref.get(); - if (clazz == null) { - classCache.remove(source); - } - return clazz; - } - - return null; + ClassReference ref = classCache.get(source); + return ref != null ? ref.get() : null; } @Override public void cacheClass(final Source source, final Class clazz) { assert classCache != null : "Class cache used without being initialized"; - classCache.put(source, new SoftReference>(clazz)); + classCache.cache(source, clazz); } private static T getLazilyCreatedValue(final Object key, final Callable creator, final Map map) { From 62b5b716a0e3e5f6ad6f5137b0673e9446d4672f Mon Sep 17 00:00:00 2001 From: Vera Akulova Date: Fri, 20 Sep 2013 17:07:11 +0400 Subject: [PATCH 0447/1294] 7124314: [TEST_BUG] [macosx] Aqua LAF: JTree doesn't select element by keyboards left and right keys Reviewed-by: alexsch, serb --- .../javax/swing/JTree/4927934/bug4927934.java | 247 ++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 jdk/test/javax/swing/JTree/4927934/bug4927934.java diff --git a/jdk/test/javax/swing/JTree/4927934/bug4927934.java b/jdk/test/javax/swing/JTree/4927934/bug4927934.java new file mode 100644 index 00000000000..b242e57ce46 --- /dev/null +++ b/jdk/test/javax/swing/JTree/4927934/bug4927934.java @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2013, 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 4927934 + @summary JTree traversal is unlike Native windows tree traversal + @author Andrey Pikalev + @run main bug4927934 +*/ + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.tree.*; +import java.awt.*; +import java.awt.event.*; +import java.lang.reflect.InvocationTargetException; +import sun.awt.*; + +public class bug4927934 implements TreeSelectionListener, TreeExpansionListener, FocusListener { + + final static Object listener = new bug4927934(); + + static boolean focusGained = false; + public static boolean selectionChanged = false; + public static boolean treeExpanded = false; + public static boolean treeCollapsed = false; + + static JFrame frame; + static JTree tree; + static Robot robot; + + public static void main(String args[]) throws Exception { + UIManager.setLookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel()); + + robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame = new JFrame(); + + DefaultMutableTreeNode root = new DefaultMutableTreeNode("root"); + createNodes(root); + tree = new JTree(root); + JScrollPane scrollPane = new JScrollPane(tree); + frame.getContentPane().add(scrollPane); + + tree.addFocusListener((FocusListener)listener); + tree.addTreeSelectionListener((TreeSelectionListener)listener); + tree.addTreeExpansionListener((TreeExpansionListener)listener); + + frame.setSize(300, 300); + frame.setVisible(true); + } + }); + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(); + Thread.sleep(1000); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + tree.requestFocus(); + } + }); + + synchronized(listener) { + if (!focusGained) { + System.out.println("waiting focusGained..."); + try { + listener.wait(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + // GO TO RIGHT + selectionChanged = false; + hitKey(KeyEvent.VK_RIGHT); + toolkit.realSync(); + if (!checkSelectionChanged(tree, 0)) { + throw new RuntimeException("Root should be selected"); + } + + selectionChanged = false; + hitKey(KeyEvent.VK_RIGHT); + toolkit.realSync(); + if (!checkSelectionChanged(tree, 1)) { + throw new RuntimeException("Node should be selected"); + } + + treeExpanded = false; + hitKey(KeyEvent.VK_RIGHT); + toolkit.realSync(); + if (!isTreeExpanded()) { + throw new RuntimeException("Node should be expanded"); + } + + selectionChanged = false; + hitKey(KeyEvent.VK_RIGHT); + toolkit.realSync(); + if (!checkSelectionChanged(tree, 2)) { + throw new RuntimeException("Leaf1 should be selected"); + } + + selectionChanged = false; + hitKey(KeyEvent.VK_RIGHT); + toolkit.realSync(); + if (!checkSelectionChanged(tree, 2)) { + throw new RuntimeException("Leaf1 should be selected"); + } + + // GO TO LEFT + selectionChanged = false; + hitKey(KeyEvent.VK_LEFT); + toolkit.realSync(); + if (!checkSelectionChanged(tree, 1)) { + throw new RuntimeException("Node should be selected"); + } + + treeCollapsed = false; + hitKey(KeyEvent.VK_LEFT); + if (!isTreeCollapsed()) { + throw new RuntimeException("Node should be collapsed"); + } + + selectionChanged = false; + hitKey(KeyEvent.VK_LEFT); + toolkit.realSync(); + if (!checkSelectionChanged(tree, 0)) { + throw new RuntimeException("Root should be selected"); + } + + treeCollapsed = false; + hitKey(KeyEvent.VK_LEFT); + toolkit.realSync(); + if (!isTreeCollapsed()) { + throw new RuntimeException("Root should be collapsed"); + } + } + + + synchronized public void focusLost(FocusEvent e) { + } + + synchronized public void focusGained(FocusEvent e) { + focusGained = true; + System.out.println("focusGained"); + listener.notifyAll(); + } + + private static void createNodes(DefaultMutableTreeNode root) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode("Node"); + node.add(new DefaultMutableTreeNode("Leaf1")); + node.add(new DefaultMutableTreeNode("Leaf2")); + root.add(node); + root.add(new DefaultMutableTreeNode("Leaf3")); + } + + synchronized public void valueChanged(TreeSelectionEvent e) { + selectionChanged = true; + System.out.println("selectionChanged"); + notifyAll(); + } + + synchronized public void treeCollapsed(TreeExpansionEvent e) { + System.out.println("treeCollapsed"); + treeCollapsed = true; + notifyAll(); + } + + synchronized public void treeExpanded(TreeExpansionEvent e) { + System.out.println("treeExpanded"); + treeExpanded = true; + notifyAll(); + } + + private static void hitKey(int key) { + System.out.println("key " + key + " pressed"); + robot.keyPress(key); + robot.keyRelease(key); + } + + private static boolean checkSelectionChanged(JTree tree, int shouldBeSel) { + synchronized(listener) { + if (!selectionChanged) { + System.out.println("waiting for selectionChanged..."); + try { + listener.wait(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + int selRow = tree.getLeadSelectionRow(); + System.out.println("Selected row: " + selRow); + return selRow == shouldBeSel; + } + + private static boolean isTreeExpanded() { + synchronized(listener) { + if (!treeExpanded) { + System.out.println("waiting for treeExpanded..."); + try { + listener.wait(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + return treeExpanded; + } + + private static boolean isTreeCollapsed() { + synchronized(listener) { + if (!treeCollapsed) { + System.out.println("waiting for treeCollapsed..."); + try { + listener.wait(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + return treeCollapsed; + } +} From ae556f32b9924a73631e3b369e8e7402c485af73 Mon Sep 17 00:00:00 2001 From: Vera Akulova Date: Fri, 20 Sep 2013 17:16:45 +0400 Subject: [PATCH 0448/1294] 8017180: [macosx] [TEST_BUG] alt-key doesn't work on macos for menu Reviewed-by: alexsch, serb --- .../KeyEventForBadFocusOwnerTest.java | 144 ++++++++++++++++++ .../swing/JMenuItem/4171437/bug4171437.java | 108 +++++++++++++ .../swing/JPopupMenu/4458079/bug4458079.java | 110 +++++++++++++ 3 files changed, 362 insertions(+) create mode 100644 jdk/test/java/awt/Focus/KeyEventForBadFocusOwnerTest/KeyEventForBadFocusOwnerTest.java create mode 100644 jdk/test/javax/swing/JMenuItem/4171437/bug4171437.java create mode 100644 jdk/test/javax/swing/JPopupMenu/4458079/bug4458079.java diff --git a/jdk/test/java/awt/Focus/KeyEventForBadFocusOwnerTest/KeyEventForBadFocusOwnerTest.java b/jdk/test/java/awt/Focus/KeyEventForBadFocusOwnerTest/KeyEventForBadFocusOwnerTest.java new file mode 100644 index 00000000000..d0280374879 --- /dev/null +++ b/jdk/test/java/awt/Focus/KeyEventForBadFocusOwnerTest/KeyEventForBadFocusOwnerTest.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013, 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 4476629 + @library ../../../../javax/swing/regtesthelpers + @build Util + @summary KeyEvents dispatched to old focus owner that is no longer showing + @author son@sparc.spb.su: area=awt.focus + @run main KeyEventForBadFocusOwnerTest +*/ + +/** + * KeyEventForBadFocusOwnerTest.java + * + * summary: KeyEvents dispatched to old focus owner that is no longer showing + */ + + +import java.awt.Robot; +import java.awt.Toolkit; + +import java.awt.event.*; + +import javax.swing.*; +import javax.swing.event.*; +import sun.awt.SunToolkit; + +public class KeyEventForBadFocusOwnerTest { + final static String ITEM_ONE_TEXT = "one"; + final static String ITEM_TWO_TEXT = "two"; + + volatile static boolean itemOneSelected = false; + volatile static boolean itemTwoSelected = false; + volatile static boolean unexpectedItemSelected = false; + + static Robot robot; + static SunToolkit toolkit; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + JFrame frame = new JFrame("TEST"); + JMenuBar mb = new JMenuBar(); + JMenu one = new JMenu(ITEM_ONE_TEXT); + JMenu two = new JMenu(ITEM_TWO_TEXT); + + mb.add(one); + mb.add(two); + + ActionListener al = new ActionListener() { + public void actionPerformed(ActionEvent ae) { + String itemText = ((JMenuItem)ae.getSource()).getText(); + System.out.println("--> " + itemText); + unexpectedItemSelected = true; + } + }; + one.setMnemonic(KeyEvent.VK_O); + JMenuItem item = new JMenuItem("one 1"); + item.setMnemonic(KeyEvent.VK_O); + item.addActionListener(al); + one.add(item); + one.add("two"); + one.add("three"); + + two.setMnemonic(KeyEvent.VK_T); + item = new JMenuItem("two 2"); + item.setMnemonic(KeyEvent.VK_T); + item.addActionListener(al); + two.add(item); + two.add("three"); + two.add("four"); + + PopupMenuListener popupMenuListener = new PopupMenuListener() { + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + System.out.print(e); + System.out.print(e.getSource()); + String itemText = ((JPopupMenu)e.getSource()).getName(); + System.out.println("Menu " + itemText + "is opened."); + switch(itemText) { + case ITEM_ONE_TEXT: + itemOneSelected = true; + break; + case ITEM_TWO_TEXT: + itemTwoSelected = true; + break; + } + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {} + public void popupMenuCanceled(PopupMenuEvent e) {} + }; + one.getPopupMenu().setName(ITEM_ONE_TEXT); + two.getPopupMenu().setName(ITEM_TWO_TEXT); + one.getPopupMenu().addPopupMenuListener(popupMenuListener); + two.getPopupMenu().addPopupMenuListener(popupMenuListener); + frame.setJMenuBar(mb); + frame.setSize(100,100); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.pack(); + frame.setVisible(true); + } + }); + + toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(); + + robot = new Robot(); + robot.setAutoDelay(100); + + Util.hitMnemonics(robot, KeyEvent.VK_O); + Util.hitMnemonics(robot, KeyEvent.VK_T); + + toolkit.realSync(); + Thread.sleep(1000); // workaround for MacOS + + if (unexpectedItemSelected) { + throw new Exception("Test failed. KeyEvent dispatched to old focus owner. "); + } + if (!itemOneSelected || !itemTwoSelected) { + throw new Exception("Not all expected events were received"); + } + } +} diff --git a/jdk/test/javax/swing/JMenuItem/4171437/bug4171437.java b/jdk/test/javax/swing/JMenuItem/4171437/bug4171437.java new file mode 100644 index 00000000000..378bd2a3c66 --- /dev/null +++ b/jdk/test/javax/swing/JMenuItem/4171437/bug4171437.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013, 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 4171437 + @library ../../regtesthelpers + @build Util + @author Georges Saab + @run main bug4171437 +*/ +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; +import javax.swing.*; +import javax.swing.event.*; +import sun.awt.SunToolkit; + +public class bug4171437 { + static volatile boolean closeActivated = false; + static volatile boolean customActivated = false; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(); + + Robot robot = new Robot(); + robot.setAutoDelay(50); + + Util.hitMnemonics(robot, KeyEvent.VK_F); + Util.hitKeys(robot, KeyEvent.VK_C); + + toolkit.realSync(); + Thread.sleep(1000); + + if (!closeActivated || customActivated) { + throw new RuntimeException("Didn't pass the muster"); + } + } + public static void createAndShowGUI() { + JMenuBar menubar = new JMenuBar(); + + JMenu fileMenu = new JMenu("File"); + fileMenu.setMnemonic('f'); + + JMenuItem fmi1 = new JMenuItem(); + fmi1 = new JMenuItem("Open"); + JMenuItem fmi2 = new JMenuItem(); + fmi2 = new JMenuItem("Close"); + fmi2.setMnemonic('c'); + fmi2.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + closeActivated = true; + } + }); + + fileMenu.add( fmi1); + fileMenu.add( fmi2); + + menubar.add( fileMenu); + + JMenu custom = new JMenu("Custom"); + custom.setMnemonic('c'); + JMenuItem cmi = new JMenuItem(); + cmi = new JMenuItem("Properties"); + cmi.setMnemonic('p'); + custom.add( cmi); + custom.addMenuListener(new MenuListener() { + public void menuSelected(MenuEvent e) { + customActivated = true; + } + public void menuDeselected(MenuEvent e) {} + public void menuCanceled(MenuEvent e) {} + }); + menubar.add( custom); + + JFrame frame = new JFrame(); + frame.setJMenuBar( menubar); + frame.setSize(300, 300); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.pack(); + frame.setVisible(true); + } +} diff --git a/jdk/test/javax/swing/JPopupMenu/4458079/bug4458079.java b/jdk/test/javax/swing/JPopupMenu/4458079/bug4458079.java new file mode 100644 index 00000000000..a9807d316c1 --- /dev/null +++ b/jdk/test/javax/swing/JPopupMenu/4458079/bug4458079.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013, 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 4458079 + @library ../../regtesthelpers + @build Util + @summary Tests calling removeAll() from PopupMenuListener + @author Peter Zhelezniakov + @run main bug4458079 +*/ +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.*; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import sun.awt.SunToolkit; + +public class bug4458079 extends JFrame implements PopupMenuListener { + public JMenu menu; + + static volatile boolean itemASelected = false; + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + new bug4458079().createAndShowGUI(); + } + }); + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(); + + Robot robot = new Robot(); + robot.setAutoDelay(50); + + Util.hitMnemonics(robot, KeyEvent.VK_M); + + toolkit.realSync(); + Thread.sleep(1000); + + Util.hitKeys(robot, KeyEvent.VK_DOWN); + Util.hitKeys(robot, KeyEvent.VK_ENTER); + + toolkit.realSync(); + Thread.sleep(1000); + + if (!itemASelected) { + throw new RuntimeException("Test failed: arrow key traversal in JMenu broken!"); + } + } + public void createAndShowGUI() { + JMenuBar bar = new JMenuBar(); + menu = new JMenu("Menu"); + menu.add(new JMenuItem("1")); + menu.add(new JMenuItem("2")); + menu.setMnemonic(KeyEvent.VK_M); + menu.getPopupMenu().addPopupMenuListener(this); + bar.add(menu); + + setJMenuBar(bar); + getContentPane().add(new JButton("")); + setSize(300, 300); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + pack(); + setVisible(true); + } + + public void rebuildMenu() { + menu.removeAll(); + final String itemCommand = "A"; + JMenuItem item = new JMenuItem(itemCommand); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JMenuItem item = ((JMenuItem)e.getSource()); + if (e.getActionCommand() == itemCommand) { + itemASelected = true; + } + } + }); + menu.add(item); + menu.add(new JMenuItem("B")); + } + + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + rebuildMenu(); + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {} + public void popupMenuCanceled(PopupMenuEvent e) {} +} From ec5e07f810933f5fdbda6729a1ed609f5f600c14 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Fri, 20 Sep 2013 09:30:02 -0400 Subject: [PATCH 0449/1294] 8022887: Assertion hit while using class and redefining it with RedefineClasses simultaneously Need to refetch each method from InstanceKlass after all safepoints. Removed leaky PreviousVersionInfo code. Reviewed-by: dcubed, sspitsyn --- .../src/share/vm/memory/metaspaceShared.cpp | 5 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 157 +++++------------- hotspot/src/share/vm/oops/instanceKlass.hpp | 71 ++------ hotspot/src/share/vm/prims/jvm.cpp | 117 ++++++------- hotspot/src/share/vm/prims/jvmtiImpl.cpp | 78 ++++----- .../share/vm/prims/jvmtiRedefineClasses.cpp | 39 ++--- hotspot/src/share/vm/runtime/handles.hpp | 4 +- .../src/share/vm/runtime/handles.inline.hpp | 2 + 8 files changed, 169 insertions(+), 304 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp index 2a9873957a8..ef51c926662 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp @@ -103,9 +103,10 @@ static void calculate_fingerprints() { if (k->oop_is_instance()) { InstanceKlass* ik = InstanceKlass::cast(k); for (int i = 0; i < ik->methods()->length(); i++) { - ResourceMark rm; Method* m = ik->methods()->at(i); - (new Fingerprinter(m))->fingerprint(); + Fingerprinter fp(m); + // The side effect of this call sets method's fingerprint field. + fp.fingerprint(); } } } diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 29c77a07ccb..6e932830b3a 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -2847,24 +2847,17 @@ void InstanceKlass::print_on(outputStream* st) const { st->print(BULLET"field annotations: "); fields_annotations()->print_value_on(st); st->cr(); st->print(BULLET"field type annotations: "); fields_type_annotations()->print_value_on(st); st->cr(); { - ResourceMark rm; - // PreviousVersionInfo objects returned via PreviousVersionWalker - // contain a GrowableArray of handles. We have to clean up the - // GrowableArray _after_ the PreviousVersionWalker destructor - // has destroyed the handles. - { - bool have_pv = false; - PreviousVersionWalker pvw((InstanceKlass*)this); - for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); - pv_info != NULL; pv_info = pvw.next_previous_version()) { - if (!have_pv) - st->print(BULLET"previous version: "); - have_pv = true; - pv_info->prev_constant_pool_handle()()->print_value_on(st); - } - if (have_pv) st->cr(); - } // pvw is cleaned up - } // rm is cleaned up + bool have_pv = false; + PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this); + for (PreviousVersionNode * pv_node = pvw.next_previous_version(); + pv_node != NULL; pv_node = pvw.next_previous_version()) { + if (!have_pv) + st->print(BULLET"previous version: "); + have_pv = true; + pv_node->prev_constant_pool()->print_value_on(st); + } + if (have_pv) st->cr(); + } // pvw is cleaned up if (generic_signature() != NULL) { st->print(BULLET"generic signature: "); @@ -3392,34 +3385,34 @@ void InstanceKlass::add_previous_version(instanceKlassHandle ikh, Array* old_methods = ikh->methods(); if (cp_ref->on_stack()) { - PreviousVersionNode * pv_node = NULL; - if (emcp_method_count == 0) { + PreviousVersionNode * pv_node = NULL; + if (emcp_method_count == 0) { // non-shared ConstantPool gets a reference - pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), NULL); - RC_TRACE(0x00000400, - ("add: all methods are obsolete; flushing any EMCP refs")); - } else { - int local_count = 0; + pv_node = new PreviousVersionNode(cp_ref, NULL); + RC_TRACE(0x00000400, + ("add: all methods are obsolete; flushing any EMCP refs")); + } else { + int local_count = 0; GrowableArray* method_refs = new (ResourceObj::C_HEAP, mtClass) - GrowableArray(emcp_method_count, true); - for (int i = 0; i < old_methods->length(); i++) { - if (emcp_methods->at(i)) { - // this old method is EMCP. Save it only if it's on the stack - Method* old_method = old_methods->at(i); - if (old_method->on_stack()) { - method_refs->append(old_method); + GrowableArray(emcp_method_count, true); + for (int i = 0; i < old_methods->length(); i++) { + if (emcp_methods->at(i)) { + // this old method is EMCP. Save it only if it's on the stack + Method* old_method = old_methods->at(i); + if (old_method->on_stack()) { + method_refs->append(old_method); + } + if (++local_count >= emcp_method_count) { + // no more EMCP methods so bail out now + break; } - if (++local_count >= emcp_method_count) { - // no more EMCP methods so bail out now - break; } } - } // non-shared ConstantPool gets a reference - pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), method_refs); + pv_node = new PreviousVersionNode(cp_ref, method_refs); } // append new previous version. - _previous_versions->append(pv_node); + _previous_versions->append(pv_node); } // Since the caller is the VMThread and we are at a safepoint, this @@ -3520,6 +3513,8 @@ Method* InstanceKlass::method_with_idnum(int idnum) { return m; } } + // None found, return null for the caller to handle. + return NULL; } return m; } @@ -3536,10 +3531,9 @@ unsigned char * InstanceKlass::get_cached_class_file_bytes() { // Construct a PreviousVersionNode entry for the array hung off // the InstanceKlass. PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool, - bool prev_cp_is_weak, GrowableArray* prev_EMCP_methods) { + GrowableArray* prev_EMCP_methods) { _prev_constant_pool = prev_constant_pool; - _prev_cp_is_weak = prev_cp_is_weak; _prev_EMCP_methods = prev_EMCP_methods; } @@ -3555,99 +3549,38 @@ PreviousVersionNode::~PreviousVersionNode() { } } - -// Construct a PreviousVersionInfo entry -PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) { - _prev_constant_pool_handle = constantPoolHandle(); // NULL handle - _prev_EMCP_method_handles = NULL; - - ConstantPool* cp = pv_node->prev_constant_pool(); - assert(cp != NULL, "constant pool ref was unexpectedly cleared"); - if (cp == NULL) { - return; // robustness - } - - // make the ConstantPool* safe to return - _prev_constant_pool_handle = constantPoolHandle(cp); - - GrowableArray* method_refs = pv_node->prev_EMCP_methods(); - if (method_refs == NULL) { - // the InstanceKlass did not have any EMCP methods - return; - } - - _prev_EMCP_method_handles = new GrowableArray(10); - - int n_methods = method_refs->length(); - for (int i = 0; i < n_methods; i++) { - Method* method = method_refs->at(i); - assert (method != NULL, "method has been cleared"); - if (method == NULL) { - continue; // robustness - } - // make the Method* safe to return - _prev_EMCP_method_handles->append(methodHandle(method)); - } -} - - -// Destroy a PreviousVersionInfo -PreviousVersionInfo::~PreviousVersionInfo() { - // Since _prev_EMCP_method_handles is not C-heap allocated, we - // don't have to delete it. -} - - // Construct a helper for walking the previous versions array -PreviousVersionWalker::PreviousVersionWalker(InstanceKlass *ik) { +PreviousVersionWalker::PreviousVersionWalker(Thread* thread, InstanceKlass *ik) { + _thread = thread; _previous_versions = ik->previous_versions(); _current_index = 0; - // _hm needs no initialization _current_p = NULL; -} - - -// Destroy a PreviousVersionWalker -PreviousVersionWalker::~PreviousVersionWalker() { - // Delete the current info just in case the caller didn't walk to - // the end of the previous versions list. No harm if _current_p is - // already NULL. - delete _current_p; - - // When _hm is destroyed, all the Handles returned in - // PreviousVersionInfo objects will be destroyed. - // Also, after this destructor is finished it will be - // safe to delete the GrowableArray allocated in the - // PreviousVersionInfo objects. + _current_constant_pool_handle = constantPoolHandle(thread, ik->constants()); } // Return the interesting information for the next previous version // of the klass. Returns NULL if there are no more previous versions. -PreviousVersionInfo* PreviousVersionWalker::next_previous_version() { +PreviousVersionNode* PreviousVersionWalker::next_previous_version() { if (_previous_versions == NULL) { // no previous versions so nothing to return return NULL; } - delete _current_p; // cleanup the previous info for the caller - _current_p = NULL; // reset to NULL so we don't delete same object twice + _current_p = NULL; // reset to NULL + _current_constant_pool_handle = NULL; int length = _previous_versions->length(); while (_current_index < length) { PreviousVersionNode * pv_node = _previous_versions->at(_current_index++); - PreviousVersionInfo * pv_info = new (ResourceObj::C_HEAP, mtClass) - PreviousVersionInfo(pv_node); - constantPoolHandle cp_h = pv_info->prev_constant_pool_handle(); - assert (!cp_h.is_null(), "null cp found in previous version"); - - // The caller will need to delete pv_info when they are done with it. - _current_p = pv_info; - return pv_info; + // Save a handle to the constant pool for this previous version, + // which keeps all the methods from being deallocated. + _current_constant_pool_handle = constantPoolHandle(_thread, pv_node->prev_constant_pool()); + _current_p = pv_node; + return pv_node; } - // all of the underlying nodes' info has been deleted return NULL; } // end next_previous_version() diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 123f6b17911..4815294118e 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -1136,21 +1136,11 @@ class BreakpointInfo; // A collection point for interesting information about the previous -// version(s) of an InstanceKlass. This class uses weak references to -// the information so that the information may be collected as needed -// by the system. If the information is shared, then a regular -// reference must be used because a weak reference would be seen as -// collectible. A GrowableArray of PreviousVersionNodes is attached -// to the InstanceKlass as needed. See PreviousVersionWalker below. +// version(s) of an InstanceKlass. A GrowableArray of PreviousVersionNodes +// is attached to the InstanceKlass as needed. See PreviousVersionWalker below. class PreviousVersionNode : public CHeapObj { private: - // A shared ConstantPool is never collected so we'll always have - // a reference to it so we can update items in the cache. We'll - // have a weak reference to a non-shared ConstantPool until all - // of the methods (EMCP or obsolete) have been collected; the - // non-shared ConstantPool becomes collectible at that point. - ConstantPool* _prev_constant_pool; // regular or weak reference - bool _prev_cp_is_weak; // true if not a shared ConstantPool + ConstantPool* _prev_constant_pool; // If the previous version of the InstanceKlass doesn't have any // EMCP methods, then _prev_EMCP_methods will be NULL. If all the @@ -1159,8 +1149,8 @@ class PreviousVersionNode : public CHeapObj { GrowableArray* _prev_EMCP_methods; public: - PreviousVersionNode(ConstantPool* prev_constant_pool, bool prev_cp_is_weak, - GrowableArray* prev_EMCP_methods); + PreviousVersionNode(ConstantPool* prev_constant_pool, + GrowableArray* prev_EMCP_methods); ~PreviousVersionNode(); ConstantPool* prev_constant_pool() const { return _prev_constant_pool; @@ -1171,59 +1161,26 @@ public: }; -// A Handle-ized version of PreviousVersionNode. -class PreviousVersionInfo : public ResourceObj { - private: - constantPoolHandle _prev_constant_pool_handle; - // If the previous version of the InstanceKlass doesn't have any - // EMCP methods, then _prev_EMCP_methods will be NULL. Since the - // methods cannot be collected while we hold a handle, - // _prev_EMCP_methods should never have a length of zero. - GrowableArray* _prev_EMCP_method_handles; - -public: - PreviousVersionInfo(PreviousVersionNode *pv_node); - ~PreviousVersionInfo(); - constantPoolHandle prev_constant_pool_handle() const { - return _prev_constant_pool_handle; - } - GrowableArray* prev_EMCP_method_handles() const { - return _prev_EMCP_method_handles; - } -}; - - -// Helper object for walking previous versions. This helper cleans up -// the Handles that it allocates when the helper object is destroyed. -// The PreviousVersionInfo object returned by next_previous_version() -// is only valid until a subsequent call to next_previous_version() or -// the helper object is destroyed. +// Helper object for walking previous versions. class PreviousVersionWalker : public StackObj { private: + Thread* _thread; GrowableArray* _previous_versions; int _current_index; - // Fields for cleaning up when we are done walking the previous versions: - // A HandleMark for the PreviousVersionInfo handles: - HandleMark _hm; - // It would be nice to have a ResourceMark field in this helper also, - // but the ResourceMark code says to be careful to delete handles held - // in GrowableArrays _before_ deleting the GrowableArray. Since we - // can't guarantee the order in which the fields are destroyed, we - // have to let the creator of the PreviousVersionWalker object do - // the right thing. Also, adding a ResourceMark here causes an - // include loop. + // A pointer to the current node object so we can handle the deletes. + PreviousVersionNode* _current_p; - // A pointer to the current info object so we can handle the deletes. - PreviousVersionInfo * _current_p; + // The constant pool handle keeps all the methods in this class from being + // deallocated from the metaspace during class unloading. + constantPoolHandle _current_constant_pool_handle; public: - PreviousVersionWalker(InstanceKlass *ik); - ~PreviousVersionWalker(); + PreviousVersionWalker(Thread* thread, InstanceKlass *ik); // Return the interesting information for the next previous version // of the klass. Returns NULL if there are no more previous versions. - PreviousVersionInfo* next_previous_version(); + PreviousVersionNode* next_previous_version(); }; diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index caed2d13612..e138df82a24 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1835,16 +1835,27 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, } JVM_END -JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)) -{ - JVMWrapper("JVM_GetClassDeclaredMethods"); +static bool select_method(methodHandle method, bool want_constructor) { + if (want_constructor) { + return (method->is_initializer() && !method->is_static()); + } else { + return (!method->is_initializer() && !method->is_overpass()); + } +} + +static jobjectArray get_class_declared_methods_helper( + JNIEnv *env, + jclass ofClass, jboolean publicOnly, + bool want_constructor, + Klass* klass, TRAPS) { + JvmtiVMObjectAllocEventCollector oam; // Exclude primitive types and array types if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) { // Return empty array - oop res = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), 0, CHECK_NULL); + oop res = oopFactory::new_objArray(klass, 0, CHECK_NULL); return (jobjectArray) JNIHandles::make_local(env, res); } @@ -1855,87 +1866,67 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, Array* methods = k->methods(); int methods_length = methods->length(); + + // Save original method_idnum in case of redefinition, which can change + // the idnum of obsolete methods. The new method will have the same idnum + // but if we refresh the methods array, the counts will be wrong. + ResourceMark rm(THREAD); + GrowableArray* idnums = new GrowableArray(methods_length); int num_methods = 0; - int i; - for (i = 0; i < methods_length; i++) { + for (int i = 0; i < methods_length; i++) { methodHandle method(THREAD, methods->at(i)); - if (!method->is_initializer() && !method->is_overpass()) { + if (select_method(method, want_constructor)) { if (!publicOnly || method->is_public()) { + idnums->push(method->method_idnum()); ++num_methods; } } } // Allocate result - objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), num_methods, CHECK_NULL); + objArrayOop r = oopFactory::new_objArray(klass, num_methods, CHECK_NULL); objArrayHandle result (THREAD, r); - int out_idx = 0; - for (i = 0; i < methods_length; i++) { - methodHandle method(THREAD, methods->at(i)); - if (!method->is_initializer() && !method->is_overpass()) { - if (!publicOnly || method->is_public()) { - oop m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); - result->obj_at_put(out_idx, m); - ++out_idx; + // Now just put the methods that we selected above, but go by their idnum + // in case of redefinition. The methods can be redefined at any safepoint, + // so above when allocating the oop array and below when creating reflect + // objects. + for (int i = 0; i < num_methods; i++) { + methodHandle method(THREAD, k->method_with_idnum(idnums->at(i))); + if (method.is_null()) { + // Method may have been deleted and seems this API can handle null + // Otherwise should probably put a method that throws NSME + result->obj_at_put(i, NULL); + } else { + oop m; + if (want_constructor) { + m = Reflection::new_constructor(method, CHECK_NULL); + } else { + m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); } + result->obj_at_put(i, m); } } - assert(out_idx == num_methods, "just checking"); + return (jobjectArray) JNIHandles::make_local(env, result()); } + +JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)) +{ + JVMWrapper("JVM_GetClassDeclaredMethods"); + return get_class_declared_methods_helper(env, ofClass, publicOnly, + /*want_constructor*/ false, + SystemDictionary::reflect_Method_klass(), THREAD); +} JVM_END JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)) { JVMWrapper("JVM_GetClassDeclaredConstructors"); - JvmtiVMObjectAllocEventCollector oam; - - // Exclude primitive types and array types - if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) - || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) { - // Return empty array - oop res = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), 0 , CHECK_NULL); - return (jobjectArray) JNIHandles::make_local(env, res); - } - - instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))); - - // Ensure class is linked - k->link_class(CHECK_NULL); - - Array* methods = k->methods(); - int methods_length = methods->length(); - int num_constructors = 0; - - int i; - for (i = 0; i < methods_length; i++) { - methodHandle method(THREAD, methods->at(i)); - if (method->is_initializer() && !method->is_static()) { - if (!publicOnly || method->is_public()) { - ++num_constructors; - } - } - } - - // Allocate result - objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), num_constructors, CHECK_NULL); - objArrayHandle result(THREAD, r); - - int out_idx = 0; - for (i = 0; i < methods_length; i++) { - methodHandle method(THREAD, methods->at(i)); - if (method->is_initializer() && !method->is_static()) { - if (!publicOnly || method->is_public()) { - oop m = Reflection::new_constructor(method, CHECK_NULL); - result->obj_at_put(out_idx, m); - ++out_idx; - } - } - } - assert(out_idx == num_constructors, "just checking"); - return (jobjectArray) JNIHandles::make_local(env, result()); + return get_class_declared_methods_helper(env, ofClass, publicOnly, + /*want_constructor*/ true, + SystemDictionary::reflect_Constructor_klass(), THREAD); } JVM_END diff --git a/hotspot/src/share/vm/prims/jvmtiImpl.cpp b/hotspot/src/share/vm/prims/jvmtiImpl.cpp index 6f8b41297a4..0fcd1ba94ed 100644 --- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp +++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp @@ -273,59 +273,49 @@ void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { // add/remove breakpoint to/from versions of the method that // are EMCP. Directly or transitively obsolete methods are - // not saved in the PreviousVersionInfo. + // not saved in the PreviousVersionNodes. Thread *thread = Thread::current(); instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); Symbol* m_name = _method->name(); Symbol* m_signature = _method->signature(); - { - ResourceMark rm(thread); - // PreviousVersionInfo objects returned via PreviousVersionWalker - // contain a GrowableArray of handles. We have to clean up the - // GrowableArray _after_ the PreviousVersionWalker destructor - // has destroyed the handles. - { - // search previous versions if they exist - PreviousVersionWalker pvw((InstanceKlass *)ikh()); - for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); - pv_info != NULL; pv_info = pvw.next_previous_version()) { - GrowableArray* methods = - pv_info->prev_EMCP_method_handles(); + // search previous versions if they exist + PreviousVersionWalker pvw(thread, (InstanceKlass *)ikh()); + for (PreviousVersionNode * pv_node = pvw.next_previous_version(); + pv_node != NULL; pv_node = pvw.next_previous_version()) { + GrowableArray* methods = pv_node->prev_EMCP_methods(); - if (methods == NULL) { - // We have run into a PreviousVersion generation where - // all methods were made obsolete during that generation's - // RedefineClasses() operation. At the time of that - // operation, all EMCP methods were flushed so we don't - // have to go back any further. - // - // A NULL methods array is different than an empty methods - // array. We cannot infer any optimizations about older - // generations from an empty methods array for the current - // generation. - break; - } + if (methods == NULL) { + // We have run into a PreviousVersion generation where + // all methods were made obsolete during that generation's + // RedefineClasses() operation. At the time of that + // operation, all EMCP methods were flushed so we don't + // have to go back any further. + // + // A NULL methods array is different than an empty methods + // array. We cannot infer any optimizations about older + // generations from an empty methods array for the current + // generation. + break; + } - for (int i = methods->length() - 1; i >= 0; i--) { - methodHandle method = methods->at(i); - // obsolete methods that are running are not deleted from - // previous version array, but they are skipped here. - if (!method->is_obsolete() && - method->name() == m_name && - method->signature() == m_signature) { - RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", - meth_act == &Method::set_breakpoint ? "sett" : "clear", - method->name()->as_C_string(), - method->signature()->as_C_string())); + for (int i = methods->length() - 1; i >= 0; i--) { + Method* method = methods->at(i); + // obsolete methods that are running are not deleted from + // previous version array, but they are skipped here. + if (!method->is_obsolete() && + method->name() == m_name && + method->signature() == m_signature) { + RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", + meth_act == &Method::set_breakpoint ? "sett" : "clear", + method->name()->as_C_string(), + method->signature()->as_C_string())); - ((Method*)method()->*meth_act)(_bci); - break; - } - } + (method->*meth_act)(_bci); + break; } - } // pvw is cleaned up - } // rm is cleaned up + } + } } void JvmtiBreakpoint::set() { diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 6894ec3f1f4..60bf9c4bdb5 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -2807,28 +2807,20 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) { &trace_name_printed); } } - { - ResourceMark rm(_thread); - // PreviousVersionInfo objects returned via PreviousVersionWalker - // contain a GrowableArray of handles. We have to clean up the - // GrowableArray _after_ the PreviousVersionWalker destructor - // has destroyed the handles. - { - // the previous versions' constant pool caches may need adjustment - PreviousVersionWalker pvw(ik); - for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); - pv_info != NULL; pv_info = pvw.next_previous_version()) { - other_cp = pv_info->prev_constant_pool_handle(); - cp_cache = other_cp->cache(); - if (cp_cache != NULL) { - cp_cache->adjust_method_entries(_matching_old_methods, - _matching_new_methods, - _matching_methods_length, - &trace_name_printed); - } - } - } // pvw is cleaned up - } // rm is cleaned up + + // the previous versions' constant pool caches may need adjustment + PreviousVersionWalker pvw(_thread, ik); + for (PreviousVersionNode * pv_node = pvw.next_previous_version(); + pv_node != NULL; pv_node = pvw.next_previous_version()) { + other_cp = pv_node->prev_constant_pool(); + cp_cache = other_cp->cache(); + if (cp_cache != NULL) { + cp_cache->adjust_method_entries(_matching_old_methods, + _matching_new_methods, + _matching_methods_length, + &trace_name_printed); + } + } } } @@ -2942,10 +2934,9 @@ void VM_RedefineClasses::check_methods_and_mark_as_obsolete( // obsolete methods need a unique idnum u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum(); if (num != ConstMethod::UNSET_IDNUM) { -// u2 old_num = old_method->method_idnum(); old_method->set_method_idnum(num); -// TO DO: attach obsolete annotations to obsolete method's new idnum } + // With tracing we try not to "yack" too much. The position of // this trace assumes there are fewer obsolete methods than // EMCP methods. diff --git a/hotspot/src/share/vm/runtime/handles.hpp b/hotspot/src/share/vm/runtime/handles.hpp index dc254227971..c2ce4b38c5a 100644 --- a/hotspot/src/share/vm/runtime/handles.hpp +++ b/hotspot/src/share/vm/runtime/handles.hpp @@ -136,7 +136,7 @@ DEF_HANDLE(typeArray , is_typeArray ) // Specific Handles for different oop types #define DEF_METADATA_HANDLE(name, type) \ class name##Handle; \ - class name##Handle { \ + class name##Handle : public StackObj { \ type* _value; \ Thread* _thread; \ protected: \ @@ -175,7 +175,7 @@ DEF_METADATA_HANDLE(constantPool, ConstantPool) // Writing this class explicitly, since DEF_METADATA_HANDLE(klass) doesn't // provide the necessary Klass* <-> Klass* conversions. This Klass // could be removed when we don't have the Klass* typedef anymore. -class KlassHandle { +class KlassHandle : public StackObj { Klass* _value; protected: Klass* obj() const { return _value; } diff --git a/hotspot/src/share/vm/runtime/handles.inline.hpp b/hotspot/src/share/vm/runtime/handles.inline.hpp index 9530b127aea..5a0f3f773c2 100644 --- a/hotspot/src/share/vm/runtime/handles.inline.hpp +++ b/hotspot/src/share/vm/runtime/handles.inline.hpp @@ -79,6 +79,7 @@ inline name##Handle::name##Handle(const name##Handle &h) { \ } else { \ _thread = Thread::current(); \ } \ + assert (_thread->is_in_stack((address)this), "not on stack?"); \ _thread->metadata_handles()->push((Metadata*)_value); \ } else { \ _thread = NULL; \ @@ -95,6 +96,7 @@ inline name##Handle& name##Handle::operator=(const name##Handle &s) { \ } else { \ _thread = Thread::current(); \ } \ + assert (_thread->is_in_stack((address)this), "not on stack?"); \ _thread->metadata_handles()->push((Metadata*)_value); \ } else { \ _thread = NULL; \ From d35ad4fbafad51a3f3903aef3f6597fdf000749a Mon Sep 17 00:00:00 2001 From: Vera Akulova Date: Fri, 20 Sep 2013 17:35:45 +0400 Subject: [PATCH 0450/1294] 7124232: [TEST_BUG] [macosx] JSplitPane has wrong divider location Reviewed-by: alexsch, serb --- .../swing/JSplitPane/4816114/bug4816114.java | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 jdk/test/javax/swing/JSplitPane/4816114/bug4816114.java diff --git a/jdk/test/javax/swing/JSplitPane/4816114/bug4816114.java b/jdk/test/javax/swing/JSplitPane/4816114/bug4816114.java new file mode 100644 index 00000000000..0b3247f9746 --- /dev/null +++ b/jdk/test/javax/swing/JSplitPane/4816114/bug4816114.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013, 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 4816114 + @summary REGRESSION: Regression in divider location behavior when JSplitPane is resized + @author Andrey Pikalev + @run main bug4816114 +*/ + +import javax.swing.*; +import java.awt.*; +import java.lang.reflect.*; +import sun.awt.SunToolkit; + + +public class bug4816114 { + + JFrame fr; + JSplitPane splitPane; + + boolean[] resized = new boolean[] { false, false, false, + false, false, false }; + static int step = 0; + boolean h_passed = false; + boolean v_passed = false; + + static bug4816114 test = new bug4816114(); + + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + test.createAndShowGUI(); + } + }); + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(); + Thread.sleep(1000); + Thread.sleep(2000); + + step++; + test.doTest(150, 300); + + step++; + test.doTest(650, 300); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + test.splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); + } + }); + + step++; + test.doTest(300, 650); + + step++; + test.doTest(300, 150); + + step++; + test.doTest(300, 650); + + if ( !test.isPassed() ) { + throw new Error("The divider location is wrong."); + } + } + public void createAndShowGUI() { + fr = new JFrame("Test"); + + splitPane = new TestSplitPane(); + splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT); + splitPane.setResizeWeight(0); + splitPane.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); + + JButton leftButton = new JButton("LEFT"); + leftButton.setPreferredSize(new Dimension(300, 300)); + leftButton.setMinimumSize(new Dimension(150, 150)); + splitPane.setLeftComponent(leftButton); + + JButton rightButton = new JButton("RIGHT"); + rightButton.setPreferredSize(new Dimension(300, 300)); + rightButton.setMinimumSize(new Dimension(150, 150)); + splitPane.setRightComponent(rightButton); + + fr.getContentPane().add(splitPane, BorderLayout.CENTER); + + fr.pack(); + fr.setVisible(true); + } + + void doTest(final int width, final int height) throws InterruptedException, InvocationTargetException { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + splitPane.setPreferredSize(new Dimension(width, height)); + fr.pack(); + } + }); + + synchronized (bug4816114.this) { + while (!resized[step]) { + bug4816114.this.wait(); + } + } + } + + synchronized void setPassed(int orientation, boolean passed) { + if (orientation == JSplitPane.HORIZONTAL_SPLIT) { + this.h_passed = passed; + } + else { + this.v_passed = passed; + } + } + + synchronized boolean isPassed() { + return h_passed && v_passed; + } + + + class TestSplitPane extends JSplitPane { + public void setDividerLocation(int location) { + super.setDividerLocation(location); + + if ( splitPane.getDividerLocation() == 151 ) { + setPassed(getOrientation(), true); + } + + synchronized (bug4816114.this) { + resized[step] = true; + bug4816114.this.notifyAll(); + } + } + } +} From 9f6d1df7471c00374d81685f3dfd7a8fe3b1c978 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Fri, 20 Sep 2013 16:33:35 +0200 Subject: [PATCH 0451/1294] 8023835: TreeMaker.QualIdent() too leafy Reviewed-by: jjg --- .../com/sun/tools/javac/tree/TreeMaker.java | 1 + .../test/tools/javac/tree/MakeQualIdent.java | 77 ++++++++++++ .../test/tools/javac/tree/ScopeTest.java | 114 ++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 langtools/test/tools/javac/tree/MakeQualIdent.java create mode 100644 langtools/test/tools/javac/tree/ScopeTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java index 4e6ef7ba6ff..b39fd06471e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -946,6 +946,7 @@ public class TreeMaker implements JCTree.Factory { boolean isUnqualifiable(Symbol sym) { if (sym.name == names.empty || sym.owner == null || + sym.owner == syms.rootPackage || sym.owner.kind == MTH || sym.owner.kind == VAR) { return true; } else if (sym.kind == TYP && toplevel != null) { diff --git a/langtools/test/tools/javac/tree/MakeQualIdent.java b/langtools/test/tools/javac/tree/MakeQualIdent.java new file mode 100644 index 00000000000..e4b71179672 --- /dev/null +++ b/langtools/test/tools/javac/tree/MakeQualIdent.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013, 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 8023835 + * @summary Verify that TreeMaker.QualIdent(Symbol) field access cascade ends with + * the top-level package (when no toplevel is set in TreeMaker) + * @run main MakeQualIdent + */ + +import com.sun.source.tree.IdentifierTree; +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.Tree; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import com.sun.tools.javac.api.JavacTaskImpl; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.code.Symtab; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.util.Context; +import java.util.ArrayList; + +public class MakeQualIdent { + public static void main(String... args) throws Exception { + JavacTool tool = JavacTool.create(); + JavacTask task = tool.getTask(null, null, null, new ArrayList(), null, null); + Context ctx = ((JavacTaskImpl)task).getContext(); + TreeMaker treeMaker = TreeMaker.instance(ctx); + Symtab syms = Symtab.instance(ctx); + + String stringTree = printTree(treeMaker.QualIdent(syms.stringType.tsym)); + + if (!"java.lang.String".equals(stringTree)) { + throw new IllegalStateException(stringTree); + } + } + + private static String printTree(Tree tree) { + final StringBuilder result = new StringBuilder(); + + new TreeScanner() { + @Override public Void visitIdentifier(IdentifierTree node, Void p) { + result.append(node.getName()); + return super.visitIdentifier(node, p); + } + @Override public Void visitMemberSelect(MemberSelectTree node, Void p) { + scan(node.getExpression(), null); + result.append("."); + result.append(node.getIdentifier()); + return null; + } + }.scan(tree, null); + + return result.toString(); + } +} diff --git a/langtools/test/tools/javac/tree/ScopeTest.java b/langtools/test/tools/javac/tree/ScopeTest.java new file mode 100644 index 00000000000..5df625eacd0 --- /dev/null +++ b/langtools/test/tools/javac/tree/ScopeTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013, 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 8023835 + * @summary Verify that implicit type of lambda parameter is correctly attributed + * in Scope + * @run main ScopeTest + */ + +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.Scope; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreePath; +import com.sun.source.util.TreePathScanner; +import com.sun.source.util.Trees; +import com.sun.tools.javac.api.JavacTaskImpl; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.model.JavacTypes; +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import javax.lang.model.element.Element; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Types; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.SimpleJavaFileObject; + +public class ScopeTest { + + private static final String SOURCE_CODE = + "public class Test {\n" + + " private static void test() {\n" + + " InvokeOn f = null;\n" + + " f.run(x -> { x.correct(); });\n" + + " }\n" + + " public static final class FooBar {\n" + + " public void dontRun() { }\n" + + " }\n" + + "}\n" + + "class InvokeOn {\n" + + " public void run(I i) { }\n" + + "}\n" + + "class FooBar {\n" + + " public void correct() { }\n" + + "}\n" + + "interface I {\n" + + " public void run(FooBar f);\n" + + "}"; + + public static void main(String... args) throws Exception { + verifyLambdaScopeCorrect(""); + verifyLambdaScopeCorrect("package test;"); + } + + private static void verifyLambdaScopeCorrect(final String packageClause) throws Exception { + JavacTool tool = JavacTool.create(); + JavaFileObject source = new SimpleJavaFileObject(URI.create("mem://Test.java"), Kind.SOURCE) { + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return packageClause + SOURCE_CODE; + } + @Override public boolean isNameCompatible(String simpleName, Kind kind) { + return true; + } + }; + Iterable fos = Collections.singletonList(source); + JavacTask task = tool.getTask(null, null, null, new ArrayList(), null, fos); + final Types types = JavacTypes.instance(((JavacTaskImpl) task).getContext()); + final Trees trees = Trees.instance(task); + CompilationUnitTree cu = task.parse().iterator().next(); + + task.analyze(); + + new TreePathScanner() { + @Override public Void visitMemberSelect(MemberSelectTree node, Void p) { + if (node.getIdentifier().contentEquals("correct")) { + TypeMirror xType = trees.getTypeMirror(new TreePath(getCurrentPath(), node.getExpression())); + Scope scope = trees.getScope(getCurrentPath()); + for (Element l : scope.getLocalElements()) { + if (!l.getSimpleName().contentEquals("x")) continue; + if (!types.isSameType(xType, l.asType())) { + throw new IllegalStateException("Incorrect variable type in scope: " + l.asType() + "; should be: " + xType); + } + } + } + return super.visitMemberSelect(node, p); + } + }.scan(cu, null); + } +} From e4e708cefd1cb153188069268f3a238d8ef0dfbc Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 20 Sep 2013 18:56:41 +0400 Subject: [PATCH 0452/1294] 7024235: Nimbus L&F: wrong "packing" of a frame containing tabbed pane Reviewed-by: alexsch --- .../swing/plaf/basic/BasicTabbedPaneUI.java | 4 +- .../JTabbedPane/7024235/Test7024235.java | 114 ++++++++++++++++++ 2 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 jdk/test/javax/swing/JTabbedPane/7024235/Test7024235.java diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java index 983e173e3af..495edfb1491 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -2620,7 +2620,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { // Never move a TAB down a run if it is in the first column. // Even if there isn't enough room, moving it to a fresh // line won't help. - if (rect.x != 2 + insets.left && rect.x + rect.width > returnAt) { + if (rect.x != x && rect.x + rect.width > returnAt) { if (runCount > tabRuns.length - 1) { expandTabRunsArray(); } @@ -2648,7 +2648,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { // Never move a TAB over a run if it is in the first run. // Even if there isn't enough room, moving it to a fresh // column won't help. - if (rect.y != 2 + insets.top && rect.y + rect.height > returnAt) { + if (rect.y != y && rect.y + rect.height > returnAt) { if (runCount > tabRuns.length - 1) { expandTabRunsArray(); } diff --git a/jdk/test/javax/swing/JTabbedPane/7024235/Test7024235.java b/jdk/test/javax/swing/JTabbedPane/7024235/Test7024235.java new file mode 100644 index 00000000000..228aa008567 --- /dev/null +++ b/jdk/test/javax/swing/JTabbedPane/7024235/Test7024235.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import sun.awt.SunToolkit; + +import java.awt.Container; +import java.awt.Rectangle; +import java.awt.Toolkit; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JTabbedPane; + +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; + +/* + * @test + * @bug 7024235 + * @summary Tests JFrame.pack() with the JTabbedPane + * @author Sergey Malenkov + */ + +public class Test7024235 implements Runnable { + + private static final boolean AUTO = null != System.getProperty("test.src", null); + + public static void main(String[] args) throws Exception { + Test7024235 test = new Test7024235(); + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { + UIManager.setLookAndFeel(info.getClassName()); + + test.test(); + toolkit.realSync(); + Thread.sleep(1000); + test.test(); + } + } + + private volatile JTabbedPane pane; + private volatile boolean passed; + + public void run() { + if (this.pane == null) { + this.pane = new JTabbedPane(); + this.pane.addTab("1", new Container()); + this.pane.addTab("2", new JButton()); + this.pane.addTab("3", new JCheckBox()); + + JFrame frame = new JFrame(); + frame.add(BorderLayout.WEST, this.pane); + frame.pack(); + frame.setVisible(true); + + test("first"); + } + else { + test("second"); + if (this.passed || AUTO) { // do not close a frame for manual review + SwingUtilities.getWindowAncestor(this.pane).dispose(); + } + this.pane = null; + } + } + + private void test() throws Exception { + SwingUtilities.invokeAndWait(this); + if (!this.passed && AUTO) { // error reporting only for automatic testing + throw new Error("TEST FAILED"); + } + } + + private void test(String step) { + this.passed = true; + for (int index = 0; index < this.pane.getTabCount(); index++) { + Rectangle bounds = this.pane.getBoundsAt(index); + int centerX = bounds.x + bounds.width / 2; + int centerY = bounds.y + bounds.height / 2; + int actual = this.pane.indexAtLocation(centerX, centerY); + if (index != actual) { + System.out.println("name = " + UIManager.getLookAndFeel().getName()); + System.out.println("step = " + step); + System.out.println("index = " + index); + System.out.println("bounds = " + bounds); + System.out.println("indexAtLocation(" + centerX + "," + centerX + ") returns " + actual); + this.passed = false; + } + } + } +} From f996a92b3bf181e1e4a4cbdf6d53a1fe52b3c1d5 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 20 Sep 2013 20:55:43 +0530 Subject: [PATCH 0453/1294] 8025147: Trailing comma is not allowed in JSONArray and JSONObject Reviewed-by: hannesw, jlaskey --- .../nashorn/internal/parser/JSONParser.java | 8 ++++ .../runtime/resources/Messages.properties | 1 + nashorn/test/script/basic/JDK-8025147.js | 41 +++++++++++++++++++ .../test/script/basic/JDK-8025147.js.EXPECTED | 6 +++ 4 files changed, 56 insertions(+) create mode 100644 nashorn/test/script/basic/JDK-8025147.js create mode 100644 nashorn/test/script/basic/JDK-8025147.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java index cb14fcdf0b8..51988f6a13a 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java @@ -349,6 +349,10 @@ loop: case COMMARIGHT: next(); + // check for trailing comma - not allowed in JSON + if (type == RBRACKET) { + throw error(AbstractParser.message("trailing.comma.in.json", type.getNameOrType())); + } break; default: @@ -388,6 +392,10 @@ loop: case COMMARIGHT: next(); + // check for trailing comma - not allowed in JSON + if (type == RBRACE) { + throw error(AbstractParser.message("trailing.comma.in.json", type.getNameOrType())); + } break; default: diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties index 5115e2ce0c7..1a37ba7bf76 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties @@ -57,6 +57,7 @@ parser.error.missing.catch.or.finally=Missing catch or finally after try parser.error.regex.unsupported.flag=Unsupported RegExp flag: {0} parser.error.regex.repeated.flag=Repeated RegExp flag: {0} parser.error.regex.syntax={0} +parser.error.trailing.comma.in.json=Trailing comma is not allowed in JSON # strict mode error messages parser.error.strict.no.with="with" statement cannot be used in strict mode diff --git a/nashorn/test/script/basic/JDK-8025147.js b/nashorn/test/script/basic/JDK-8025147.js new file mode 100644 index 00000000000..905a1c9c320 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025147.js @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8025147: Trailing comma is not allowed in JSONArray and JSONObject + * + * @test + * @run + */ + +function check(str) { + try { + JSON.parse(str); + fail("should have thrown SyntaxError for " + str); + } catch (e) { + print(e); + } +} + +check("{ \"a\": 333, }"); +check("[ 4343, ]"); diff --git a/nashorn/test/script/basic/JDK-8025147.js.EXPECTED b/nashorn/test/script/basic/JDK-8025147.js.EXPECTED new file mode 100644 index 00000000000..3afb20a8204 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025147.js.EXPECTED @@ -0,0 +1,6 @@ +SyntaxError: Invalid JSON: :1:12 Trailing comma is not allowed in JSON +{ "a": 333, } + ^ +SyntaxError: Invalid JSON: :1:8 Trailing comma is not allowed in JSON +[ 4343, ] + ^ From e259f899133916dd5976e37821a52818b0960506 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 20 Sep 2013 22:37:08 +0530 Subject: [PATCH 0454/1294] 8025149: JSON.stringify does not handle 'space' argument as per the spec Reviewed-by: jlaskey, hannesw --- .../nashorn/internal/objects/NativeJSON.java | 33 +++++++------ nashorn/test/script/basic/JDK-8025149.js | 47 +++++++++++++++++++ .../test/script/basic/JDK-8025149.js.EXPECTED | 9 ++++ 3 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025149.js create mode 100644 nashorn/test/script/basic/JDK-8025149.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java index b2fa46d2b52..344b6da90d9 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java @@ -162,22 +162,27 @@ public final class NativeJSON extends ScriptObject { String gap; - if (space instanceof Number || space instanceof NativeNumber) { - int indent; - if (space instanceof NativeNumber) { - indent = ((NativeNumber)space).intValue(); + // modifiable 'space' - parameter is final + Object modSpace = space; + if (modSpace instanceof NativeNumber) { + modSpace = JSType.toNumber(JSType.toPrimitive(modSpace, Number.class)); + } else if (modSpace instanceof NativeString) { + modSpace = JSType.toString(JSType.toPrimitive(modSpace, String.class)); + } + + if (modSpace instanceof Number) { + int indent = Math.min(10, JSType.toInteger(modSpace)); + if (indent < 1) { + gap = ""; } else { - indent = ((Number)space).intValue(); + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < indent; i++) { + sb.append(' '); + } + gap = sb.toString(); } - - final StringBuilder sb = new StringBuilder(); - for (int i = 0; i < Math.min(10, indent); i++) { - sb.append(' '); - } - gap = sb.toString(); - - } else if (space instanceof String || space instanceof ConsString || space instanceof NativeString) { - final String str = (space instanceof String) ? (String)space : space.toString(); + } else if (modSpace instanceof String || modSpace instanceof ConsString) { + final String str = modSpace.toString(); gap = str.substring(0, Math.min(10, str.length())); } else { gap = ""; diff --git a/nashorn/test/script/basic/JDK-8025149.js b/nashorn/test/script/basic/JDK-8025149.js new file mode 100644 index 00000000000..b1d33a1a3ce --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025149.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8025149: JSON.stringify does not handle 'space' argument as per the spec. + * + * @test + * @run + */ + +print(JSON.stringify({ foo : 23, bar: { x : 22} }, undefined ,new Number(Infinity))); + +print(JSON.stringify({ foo : 23, bar: { x : 22} }, undefined ,new Number(-Infinity))); + +try { + JSON.stringify({},[], + (n = new Number(0), n.valueOf = function() { throw ("inside n.valueOf") }, n)); +} catch (e) { + print(e); +} + +try { + JSON.stringify({},[], + (s = new String(""), s.toString = function() { throw ("inside s.toString") }, s)); +} catch (e) { + print(e); +} diff --git a/nashorn/test/script/basic/JDK-8025149.js.EXPECTED b/nashorn/test/script/basic/JDK-8025149.js.EXPECTED new file mode 100644 index 00000000000..10fd8641cbc --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025149.js.EXPECTED @@ -0,0 +1,9 @@ +{ + "foo": 23, + "bar": { + "x": 22 + } +} +{"foo":23,"bar":{"x":22}} +inside n.valueOf +inside s.toString From 0f9d70232f18cf1b9f233c8cd22c67140f4894bb Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 20 Sep 2013 11:09:26 -0700 Subject: [PATCH 0455/1294] Added tag hs25-b51 for changeset e446e24611f9 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 024f5b4d0ee..d218a0c962d 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -378,3 +378,4 @@ aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106 5b7f90aab3ad25a25b75b7b2bb18d5ae23d8231c jdk8-b107 a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50 85072013aad46050a362d10ab78e963121c8014c jdk8-b108 +566db1b0e6efca31f181456e54c8911d0192410d hs25-b51 From c368a33bf7c9aa2b62a82937f40bbfba68ed86fc Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 20 Sep 2013 11:17:04 -0700 Subject: [PATCH 0456/1294] 8025127: new hotspot build - hs25-b52 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index fa4d6554e16..dc0872c1db3 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=51 +HS_BUILD_NUMBER=52 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From 3f2082ef809c6f4827d70ebcfeba3a36b9632e74 Mon Sep 17 00:00:00 2001 From: Bill Pittore Date: Fri, 20 Sep 2013 15:06:23 -0400 Subject: [PATCH 0457/1294] 8014911: Should use SUPPORTS_NATIVE_CX8 define to help C/C++ compiler elide blocks of code If SUPPORTS_NATIVE_CX8 true then supports_cx8() function hard coded to return 'true' Reviewed-by: kvn, twisti, dholmes --- hotspot/src/share/vm/runtime/vm_version.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/runtime/vm_version.hpp b/hotspot/src/share/vm/runtime/vm_version.hpp index c901b260de5..f03b77ca326 100644 --- a/hotspot/src/share/vm/runtime/vm_version.hpp +++ b/hotspot/src/share/vm/runtime/vm_version.hpp @@ -78,7 +78,13 @@ class Abstract_VM_Version: AllStatic { static const char* jre_release_version(); // does HW support an 8-byte compare-exchange operation? - static bool supports_cx8() {return _supports_cx8;} + static bool supports_cx8() { +#ifdef SUPPORTS_NATIVE_CX8 + return true; +#else + return _supports_cx8; +#endif + } // does HW support atomic get-and-set or atomic get-and-add? Used // to guide intrinsification decisions for Unsafe atomic ops static bool supports_atomic_getset4() {return _supports_atomic_getset4;} From 42589e0f11eac8224f59fe01496aa30a5ba4f81d Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Fri, 20 Sep 2013 18:34:00 -0400 Subject: [PATCH 0458/1294] 8014956: nashorn/api/javaaccess/MethodAccessTest.java test fails on sparc-solaris 64 Reference_map[] array had uninitialized junk that was causing a bogus bootstrap method to be found. Reviewed-by: hseigel, dcubed, sspitsyn --- hotspot/src/share/vm/oops/constantPool.cpp | 26 ++++++++-------------- hotspot/src/share/vm/oops/constantPool.hpp | 1 - 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index 8033d7e3850..82b99d5a1e2 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -108,16 +108,16 @@ objArrayOop ConstantPool::resolved_references() const { void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data, intStack reference_map, int constant_pool_map_length, - TRAPS) { + TRAPS) { // Initialized the resolved object cache. int map_length = reference_map.length(); if (map_length > 0) { // Only need mapping back to constant pool entries. The map isn't used for - // invokedynamic resolved_reference entries. The constant pool cache index - // has the mapping back to both the constant pool and to the resolved - // reference index. + // invokedynamic resolved_reference entries. For invokedynamic entries, + // the constant pool cache index has the mapping back to both the constant + // pool and to the resolved reference index. if (constant_pool_map_length > 0) { - Array* om = MetadataFactory::new_array(loader_data, map_length, CHECK); + Array* om = MetadataFactory::new_array(loader_data, constant_pool_map_length, CHECK); for (int i = 0; i < constant_pool_map_length; i++) { int x = reference_map.at(i); @@ -182,16 +182,9 @@ oop ConstantPool::lock() { int ConstantPool::cp_to_object_index(int cp_index) { // this is harder don't do this so much. - for (int i = 0; i< reference_map()->length(); i++) { - if (reference_map()->at(i) == cp_index) return i; - // Zero entry is divider between constant pool indices for strings, - // method handles and method types. After that the index is a constant - // pool cache index for invokedynamic. Stop when zero (which can never - // be a constant pool index) - if (reference_map()->at(i) == 0) break; - } - // We might not find the index. - return _no_index_sentinel; + int i = reference_map()->find(cp_index); + // We might not find the index for jsr292 call. + return (i < 0) ? _no_index_sentinel : i; } Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) { @@ -866,8 +859,7 @@ oop ConstantPool::string_at_impl(constantPoolHandle this_oop, int which, int obj // If the string has already been interned, this entry will be non-null oop str = this_oop->resolved_references()->obj_at(obj_index); if (str != NULL) return str; - - Symbol* sym = this_oop->unresolved_string_at(which); + Symbol* sym = this_oop->unresolved_string_at(which); str = StringTable::intern(sym, CHECK_(NULL)); this_oop->string_at_put(which, obj_index, str); assert(java_lang_String::is_instance(str), "must be string"); diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp index eca2dcd9c56..fb64930fb52 100644 --- a/hotspot/src/share/vm/oops/constantPool.hpp +++ b/hotspot/src/share/vm/oops/constantPool.hpp @@ -231,7 +231,6 @@ class ConstantPool : public Metadata { static int cache_offset_in_bytes() { return offset_of(ConstantPool, _cache); } static int pool_holder_offset_in_bytes() { return offset_of(ConstantPool, _pool_holder); } static int resolved_references_offset_in_bytes() { return offset_of(ConstantPool, _resolved_references); } - static int reference_map_offset_in_bytes() { return offset_of(ConstantPool, _reference_map); } // Storing constants From 22272f50435943f0404b126d1695082dbed41a1f Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Sat, 21 Sep 2013 10:09:42 +0200 Subject: [PATCH 0459/1294] 8025096: Move the ChunkManager instances out of the VirtualSpaceLists Reviewed-by: coleenp, mgerdin, jmasa --- hotspot/src/share/vm/memory/metaspace.cpp | 221 ++++++++++------------ hotspot/src/share/vm/memory/metaspace.hpp | 22 ++- 2 files changed, 116 insertions(+), 127 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 0a741d674ca..8498242e848 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" #include "gc_interface/collectedHeap.hpp" +#include "memory/allocation.hpp" #include "memory/binaryTreeDictionary.hpp" #include "memory/freeList.hpp" #include "memory/collectorPolicy.hpp" @@ -111,7 +112,7 @@ typedef class FreeList ChunkList; // Has three lists of free chunks, and a total size and // count that includes all three -class ChunkManager VALUE_OBJ_CLASS_SPEC { +class ChunkManager : public CHeapObj { // Free list of chunks of different sizes. // SpecializedChunk @@ -158,7 +159,12 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC { public: - ChunkManager() : _free_chunks_total(0), _free_chunks_count(0) {} + ChunkManager(size_t specialized_size, size_t small_size, size_t medium_size) + : _free_chunks_total(0), _free_chunks_count(0) { + _free_chunks[SpecializedIndex].set_size(specialized_size); + _free_chunks[SmallIndex].set_size(small_size); + _free_chunks[MediumIndex].set_size(medium_size); + } // add or delete (return) a chunk to the global freelist. Metachunk* chunk_freelist_allocate(size_t word_size); @@ -219,7 +225,7 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC { void locked_print_free_chunks(outputStream* st); void locked_print_sum_free_chunks(outputStream* st); - void print_on(outputStream* st); + void print_on(outputStream* st) const; }; // Used to manage the free list of Metablocks (a block corresponds @@ -276,11 +282,6 @@ class VirtualSpaceNode : public CHeapObj { // VirtualSpace Metachunk* first_chunk() { return (Metachunk*) bottom(); } - void inc_container_count(); -#ifdef ASSERT - uint container_count_slow(); -#endif - public: VirtualSpaceNode(size_t byte_size); @@ -314,8 +315,10 @@ class VirtualSpaceNode : public CHeapObj { void inc_top(size_t word_size) { _top += word_size; } uintx container_count() { return _container_count; } + void inc_container_count(); void dec_container_count(); #ifdef ASSERT + uint container_count_slow(); void verify_container_count(); #endif @@ -421,8 +424,6 @@ class VirtualSpaceList : public CHeapObj { VirtualSpaceNode* _virtual_space_list; // virtual space currently being used for allocations VirtualSpaceNode* _current_virtual_space; - // Free chunk list for all other metadata - ChunkManager _chunk_manager; // Can this virtual list allocate >1 spaces? Also, used to determine // whether to allocate unlimited small chunks in this virtual space @@ -475,7 +476,6 @@ class VirtualSpaceList : public CHeapObj { return _current_virtual_space; } - ChunkManager* chunk_manager() { return &_chunk_manager; } bool is_class() const { return _is_class; } // Allocate the first virtualspace. @@ -494,14 +494,7 @@ class VirtualSpaceList : public CHeapObj { void dec_virtual_space_count(); // Unlink empty VirtualSpaceNodes and free it. - void purge(); - - // Used and capacity in the entire list of virtual spaces. - // These are global values shared by all Metaspaces - size_t capacity_words_sum(); - size_t capacity_bytes_sum() { return capacity_words_sum() * BytesPerWord; } - size_t used_words_sum(); - size_t used_bytes_sum() { return used_words_sum() * BytesPerWord; } + void purge(ChunkManager* chunk_manager); bool contains(const void *ptr); @@ -582,18 +575,12 @@ class SpaceManager : public CHeapObj { // Type of metadata allocated. Metaspace::MetadataType _mdtype; - // Chunk related size - size_t _medium_chunk_bunch; - // List of chunks in use by this SpaceManager. Allocations // are done from the current chunk. The list is used for deallocating // chunks when the SpaceManager is freed. Metachunk* _chunks_in_use[NumberOfInUseLists]; Metachunk* _current_chunk; - // Virtual space where allocation comes from. - VirtualSpaceList* _vs_list; - // Number of small chunks to allocate to a manager // If class space manager, small chunks are unlimited static uint const _small_chunk_limit; @@ -626,7 +613,9 @@ class SpaceManager : public CHeapObj { } Metaspace::MetadataType mdtype() { return _mdtype; } - VirtualSpaceList* vs_list() const { return _vs_list; } + + VirtualSpaceList* vs_list() const { return Metaspace::get_space_list(_mdtype); } + ChunkManager* chunk_manager() const { return Metaspace::get_chunk_manager(_mdtype); } Metachunk* current_chunk() const { return _current_chunk; } void set_current_chunk(Metachunk* v) { @@ -648,18 +637,19 @@ class SpaceManager : public CHeapObj { public: SpaceManager(Metaspace::MetadataType mdtype, - Mutex* lock, - VirtualSpaceList* vs_list); + Mutex* lock); ~SpaceManager(); enum ChunkMultiples { MediumChunkMultiple = 4 }; + bool is_class() { return _mdtype == Metaspace::ClassType; } + // Accessors size_t specialized_chunk_size() { return SpecializedChunk; } - size_t small_chunk_size() { return (size_t) vs_list()->is_class() ? ClassSmallChunk : SmallChunk; } - size_t medium_chunk_size() { return (size_t) vs_list()->is_class() ? ClassMediumChunk : MediumChunk; } + size_t small_chunk_size() { return (size_t) is_class() ? ClassSmallChunk : SmallChunk; } + size_t medium_chunk_size() { return (size_t) is_class() ? ClassMediumChunk : MediumChunk; } size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; } size_t allocated_blocks_words() const { return _allocated_blocks_words; } @@ -762,7 +752,7 @@ void VirtualSpaceNode::inc_container_count() { _container_count++; assert(_container_count == container_count_slow(), err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT - "container_count_slow() " SIZE_FORMAT, + " container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); } @@ -775,7 +765,7 @@ void VirtualSpaceNode::dec_container_count() { void VirtualSpaceNode::verify_container_count() { assert(_container_count == container_count_slow(), err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT - "container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); + " container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); } #endif @@ -1020,7 +1010,7 @@ void ChunkManager::remove_chunk(Metachunk* chunk) { // Walk the list of VirtualSpaceNodes and delete // nodes with a 0 container_count. Remove Metachunks in // the node from their respective freelists. -void VirtualSpaceList::purge() { +void VirtualSpaceList::purge(ChunkManager* chunk_manager) { assert_lock_strong(SpaceManager::expand_lock()); // Don't use a VirtualSpaceListIterator because this // list is being changed and a straightforward use of an iterator is not safe. @@ -1042,7 +1032,7 @@ void VirtualSpaceList::purge() { prev_vsl->set_next(vsl->next()); } - vsl->purge(chunk_manager()); + vsl->purge(chunk_manager); dec_reserved_words(vsl->reserved_words()); dec_committed_words(vsl->committed_words()); dec_virtual_space_count(); @@ -1064,36 +1054,6 @@ void VirtualSpaceList::purge() { #endif } -size_t VirtualSpaceList::used_words_sum() { - size_t allocated_by_vs = 0; - VirtualSpaceListIterator iter(virtual_space_list()); - while (iter.repeat()) { - VirtualSpaceNode* vsl = iter.get_next(); - // Sum used region [bottom, top) in each virtualspace - allocated_by_vs += vsl->used_words_in_vs(); - } - assert(allocated_by_vs >= chunk_manager()->free_chunks_total_words(), - err_msg("Total in free chunks " SIZE_FORMAT - " greater than total from virtual_spaces " SIZE_FORMAT, - allocated_by_vs, chunk_manager()->free_chunks_total_words())); - size_t used = - allocated_by_vs - chunk_manager()->free_chunks_total_words(); - return used; -} - -// Space available in all MetadataVirtualspaces allocated -// for metadata. This is the upper limit on the capacity -// of chunks allocated out of all the MetadataVirtualspaces. -size_t VirtualSpaceList::capacity_words_sum() { - size_t capacity = 0; - VirtualSpaceListIterator iter(virtual_space_list()); - while (iter.repeat()) { - VirtualSpaceNode* vsl = iter.get_next(); - capacity += vsl->capacity_words_in_vs(); - } - return capacity; -} - VirtualSpaceList::VirtualSpaceList(size_t word_size ) : _is_class(false), _virtual_space_list(NULL), @@ -1104,10 +1064,6 @@ VirtualSpaceList::VirtualSpaceList(size_t word_size ) : MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); bool initialization_succeeded = grow_vs(word_size); - - _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk); - _chunk_manager.free_chunks(SmallIndex)->set_size(SmallChunk); - _chunk_manager.free_chunks(MediumIndex)->set_size(MediumChunk); assert(initialization_succeeded, " VirtualSpaceList initialization should not fail"); } @@ -1123,9 +1079,6 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) : Mutex::_no_safepoint_check_flag); VirtualSpaceNode* class_entry = new VirtualSpaceNode(rs); bool succeeded = class_entry->initialize(); - _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk); - _chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk); - _chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk); assert(succeeded, " VirtualSpaceList initialization should not fail"); link_vs(class_entry); } @@ -1195,15 +1148,8 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, size_t grow_chunks_by_words, size_t medium_chunk_bunch) { - // Get a chunk from the chunk freelist - Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); - - if (next != NULL) { - next->container()->inc_container_count(); - } else { - // Allocate a chunk out of the current virtual space. - next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); - } + // Allocate a chunk out of the current virtual space. + Metachunk* next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); if (next == NULL) { // Not enough room in current virtual space. Try to commit @@ -1537,15 +1483,15 @@ void Metadebug::deallocate_chunk_a_lot(SpaceManager* sm, if (dummy_chunk == NULL) { break; } - vsl->chunk_manager()->chunk_freelist_deallocate(dummy_chunk); + sm->chunk_manager()->chunk_freelist_deallocate(dummy_chunk); if (TraceMetadataChunkAllocation && Verbose) { gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ", sm->sum_count_in_chunks_in_use()); dummy_chunk->print_on(gclog_or_tty); gclog_or_tty->print_cr(" Free chunks total %d count %d", - vsl->chunk_manager()->free_chunks_total_words(), - vsl->chunk_manager()->free_chunks_count()); + sm->chunk_manager()->free_chunks_total_words(), + sm->chunk_manager()->free_chunks_count()); } } } else { @@ -1797,6 +1743,8 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { // work. chunk->set_is_free(false); #endif + chunk->container()->inc_container_count(); + slow_locked_verify(); return chunk; } @@ -1831,9 +1779,9 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { return chunk; } -void ChunkManager::print_on(outputStream* out) { +void ChunkManager::print_on(outputStream* out) const { if (PrintFLSStatistics != 0) { - humongous_dictionary()->report_statistics(); + const_cast(this)->humongous_dictionary()->report_statistics(); } } @@ -1980,8 +1928,8 @@ void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const { } } - vs_list()->chunk_manager()->locked_print_free_chunks(st); - vs_list()->chunk_manager()->locked_print_sum_free_chunks(st); + chunk_manager()->locked_print_free_chunks(st); + chunk_manager()->locked_print_sum_free_chunks(st); } size_t SpaceManager::calc_chunk_size(size_t word_size) { @@ -2085,9 +2033,7 @@ void SpaceManager::print_on(outputStream* st) const { } SpaceManager::SpaceManager(Metaspace::MetadataType mdtype, - Mutex* lock, - VirtualSpaceList* vs_list) : - _vs_list(vs_list), + Mutex* lock) : _mdtype(mdtype), _allocated_blocks_words(0), _allocated_chunks_words(0), @@ -2173,9 +2119,7 @@ SpaceManager::~SpaceManager() { MutexLockerEx fcl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); - ChunkManager* chunk_manager = vs_list()->chunk_manager(); - - chunk_manager->slow_locked_verify(); + chunk_manager()->slow_locked_verify(); dec_total_from_size_metrics(); @@ -2189,8 +2133,8 @@ SpaceManager::~SpaceManager() { // Have to update before the chunks_in_use lists are emptied // below. - chunk_manager->inc_free_chunks_total(allocated_chunks_words(), - sum_count_in_chunks_in_use()); + chunk_manager()->inc_free_chunks_total(allocated_chunks_words(), + sum_count_in_chunks_in_use()); // Add all the chunks in use by this space manager // to the global list of free chunks. @@ -2205,11 +2149,11 @@ SpaceManager::~SpaceManager() { chunk_size_name(i)); } Metachunk* chunks = chunks_in_use(i); - chunk_manager->return_chunks(i, chunks); + chunk_manager()->return_chunks(i, chunks); set_chunks_in_use(i, NULL); if (TraceMetadataChunkAllocation && Verbose) { gclog_or_tty->print_cr("updated freelist count %d %s", - chunk_manager->free_chunks(i)->count(), + chunk_manager()->free_chunks(i)->count(), chunk_size_name(i)); } assert(i != HumongousIndex, "Humongous chunks are handled explicitly later"); @@ -2246,16 +2190,16 @@ SpaceManager::~SpaceManager() { humongous_chunks->word_size(), HumongousChunkGranularity)); Metachunk* next_humongous_chunks = humongous_chunks->next(); humongous_chunks->container()->dec_container_count(); - chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); + chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks); humongous_chunks = next_humongous_chunks; } if (TraceMetadataChunkAllocation && Verbose) { gclog_or_tty->print_cr(""); gclog_or_tty->print_cr("updated dictionary count %d %s", - chunk_manager->humongous_dictionary()->total_count(), + chunk_manager()->humongous_dictionary()->total_count(), chunk_size_name(HumongousIndex)); } - chunk_manager->slow_locked_verify(); + chunk_manager()->slow_locked_verify(); } const char* SpaceManager::chunk_size_name(ChunkIndex index) const { @@ -2344,9 +2288,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { gclog_or_tty->print("SpaceManager::add_chunk: %d) ", sum_count_in_chunks_in_use()); new_chunk->print_on(gclog_or_tty); - if (vs_list() != NULL) { - vs_list()->chunk_manager()->locked_print_free_chunks(gclog_or_tty); - } + chunk_manager()->locked_print_free_chunks(gclog_or_tty); } } @@ -2362,10 +2304,14 @@ void SpaceManager::retire_current_chunk() { Metachunk* SpaceManager::get_new_chunk(size_t word_size, size_t grow_chunks_by_words) { + // Get a chunk from the chunk freelist + Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); - Metachunk* next = vs_list()->get_new_chunk(word_size, - grow_chunks_by_words, - medium_chunk_bunch()); + if (next == NULL) { + next = vs_list()->get_new_chunk(word_size, + grow_chunks_by_words, + medium_chunk_bunch()); + } if (TraceMetadataHumongousAllocation && next != NULL && SpaceManager::is_humongous(next->word_size())) { @@ -2645,13 +2591,12 @@ size_t MetaspaceAux::committed_bytes(Metaspace::MetadataType mdtype) { size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); } size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) { - VirtualSpaceList* list = Metaspace::get_space_list(mdtype); - if (list == NULL) { + ChunkManager* chunk_manager = Metaspace::get_chunk_manager(mdtype); + if (chunk_manager == NULL) { return 0; } - ChunkManager* chunk = list->chunk_manager(); - chunk->slow_verify(); - return chunk->free_chunks_total_words(); + chunk_manager->slow_verify(); + return chunk_manager->free_chunks_total_words(); } size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) { @@ -2802,9 +2747,9 @@ void MetaspaceAux::dump(outputStream* out) { } void MetaspaceAux::verify_free_chunks() { - Metaspace::space_list()->chunk_manager()->verify(); + Metaspace::chunk_manager_metadata()->verify(); if (Metaspace::using_class_space()) { - Metaspace::class_space_list()->chunk_manager()->verify(); + Metaspace::chunk_manager_class()->verify(); } } @@ -2875,6 +2820,9 @@ Metaspace::~Metaspace() { VirtualSpaceList* Metaspace::_space_list = NULL; VirtualSpaceList* Metaspace::_class_space_list = NULL; +ChunkManager* Metaspace::_chunk_manager_metadata = NULL; +ChunkManager* Metaspace::_chunk_manager_class = NULL; + #define VIRTUALSPACEMULTIPLIER 2 #ifdef _LP64 @@ -2982,6 +2930,7 @@ void Metaspace::initialize_class_space(ReservedSpace rs) { err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize)); assert(using_class_space(), "Must be using class space"); _class_space_list = new VirtualSpaceList(rs); + _chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk); } #endif @@ -3007,6 +2956,7 @@ void Metaspace::global_initialize() { // remainder is the misc code and data chunks. cds_total = FileMapInfo::shared_spaces_size(); _space_list = new VirtualSpaceList(cds_total/wordSize); + _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk); #ifdef _LP64 // Set the compressed klass pointer base so that decoding of these pointers works @@ -3074,15 +3024,30 @@ void Metaspace::global_initialize() { size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size(); // Initialize the list of virtual spaces. _space_list = new VirtualSpaceList(word_size); + _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk); } } +Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype, + size_t chunk_word_size, + size_t chunk_bunch) { + // Get a chunk from the chunk freelist + Metachunk* chunk = get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size); + if (chunk != NULL) { + return chunk; + } + + return get_space_list(mdtype)->get_initialization_chunk(chunk_word_size, chunk_bunch); +} + void Metaspace::initialize(Mutex* lock, MetaspaceType type) { assert(space_list() != NULL, "Metadata VirtualSpaceList has not been initialized"); + assert(chunk_manager_metadata() != NULL, + "Metadata ChunkManager has not been initialized"); - _vsm = new SpaceManager(NonClassType, lock, space_list()); + _vsm = new SpaceManager(NonClassType, lock); if (_vsm == NULL) { return; } @@ -3091,11 +3056,13 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) { vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size); if (using_class_space()) { - assert(class_space_list() != NULL, - "Class VirtualSpaceList has not been initialized"); + assert(class_space_list() != NULL, + "Class VirtualSpaceList has not been initialized"); + assert(chunk_manager_class() != NULL, + "Class ChunkManager has not been initialized"); // Allocate SpaceManager for classes. - _class_vsm = new SpaceManager(ClassType, lock, class_space_list()); + _class_vsm = new SpaceManager(ClassType, lock); if (_class_vsm == NULL) { return; } @@ -3104,9 +3071,9 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) { MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); // Allocate chunk for metadata objects - Metachunk* new_chunk = - space_list()->get_initialization_chunk(word_size, - vsm()->medium_chunk_bunch()); + Metachunk* new_chunk = get_initialization_chunk(NonClassType, + word_size, + vsm()->medium_chunk_bunch()); assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); if (new_chunk != NULL) { // Add to this manager's list of chunks in use and current_chunk(). @@ -3115,9 +3082,9 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) { // Allocate chunk for class metadata objects if (using_class_space()) { - Metachunk* class_chunk = - class_space_list()->get_initialization_chunk(class_word_size, - class_vsm()->medium_chunk_bunch()); + Metachunk* class_chunk = get_initialization_chunk(ClassType, + class_word_size, + class_vsm()->medium_chunk_bunch()); if (class_chunk != NULL) { class_vsm()->add_chunk(class_chunk, true); } @@ -3334,12 +3301,16 @@ void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) { } } +void Metaspace::purge(MetadataType mdtype) { + get_space_list(mdtype)->purge(get_chunk_manager(mdtype)); +} + void Metaspace::purge() { MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); - space_list()->purge(); + purge(NonClassType); if (using_class_space()) { - class_space_list()->purge(); + purge(ClassType); } } diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 242fa61b1cc..29c07e15179 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -56,12 +56,15 @@ // +-------------------+ // +class ChunkManager; class ClassLoaderData; class Metablock; +class Metachunk; class MetaWord; class Mutex; class outputStream; class SpaceManager; +class VirtualSpaceList; // Metaspaces each have a SpaceManager and allocations // are done by the SpaceManager. Allocations are done @@ -76,8 +79,6 @@ class SpaceManager; // allocate() method returns a block for use as a // quantum of metadata. -class VirtualSpaceList; - class Metaspace : public CHeapObj { friend class VMStructs; friend class SpaceManager; @@ -102,6 +103,10 @@ class Metaspace : public CHeapObj { private: void initialize(Mutex* lock, MetaspaceType type); + Metachunk* get_initialization_chunk(MetadataType mdtype, + size_t chunk_word_size, + size_t chunk_bunch); + // Align up the word size to the allocation word size static size_t align_word_size_up(size_t); @@ -134,6 +139,10 @@ class Metaspace : public CHeapObj { static VirtualSpaceList* _space_list; static VirtualSpaceList* _class_space_list; + static ChunkManager* _chunk_manager_metadata; + static ChunkManager* _chunk_manager_class; + + public: static VirtualSpaceList* space_list() { return _space_list; } static VirtualSpaceList* class_space_list() { return _class_space_list; } static VirtualSpaceList* get_space_list(MetadataType mdtype) { @@ -141,6 +150,14 @@ class Metaspace : public CHeapObj { return mdtype == ClassType ? class_space_list() : space_list(); } + static ChunkManager* chunk_manager_metadata() { return _chunk_manager_metadata; } + static ChunkManager* chunk_manager_class() { return _chunk_manager_class; } + static ChunkManager* get_chunk_manager(MetadataType mdtype) { + assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype"); + return mdtype == ClassType ? chunk_manager_class() : chunk_manager_metadata(); + } + + private: // This is used by DumpSharedSpaces only, where only _vsm is used. So we will // maintain a single list for now. void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size); @@ -199,6 +216,7 @@ class Metaspace : public CHeapObj { void dump(outputStream* const out) const; // Free empty virtualspaces + static void purge(MetadataType mdtype); static void purge(); void print_on(outputStream* st) const; From 1508b37a51e131d470c776a12f155a2a9fadbb60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Sat, 21 Sep 2013 10:11:15 +0200 Subject: [PATCH 0460/1294] 8025163: Date methods should not return -0 Reviewed-by: lagergren, jlaskey --- .../nashorn/internal/objects/NativeDate.java | 128 +++++++++--------- nashorn/test/script/basic/JDK-8025163.js | 39 ++++++ .../test/script/basic/JDK-8025163.js.EXPECTED | 8 ++ 3 files changed, 110 insertions(+), 65 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025163.js create mode 100644 nashorn/test/script/basic/JDK-8025163.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java index 859745f3dca..935285f02ad 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java @@ -75,11 +75,11 @@ public final class NativeDate extends ScriptObject { private static final int FORMAT_LOCAL_TIME = 5; // Constants defined in ECMA 15.9.1.10 - private static final double hoursPerDay = 24; - private static final double minutesPerHour = 60; - private static final double secondsPerMinute = 60; - private static final double msPerSecond = 1_000; - private static final double msPerMinute = 60_000; + private static final int hoursPerDay = 24; + private static final int minutesPerHour = 60; + private static final int secondsPerMinute = 60; + private static final int msPerSecond = 1_000; + private static final int msPerMinute = 60_000; private static final double msPerHour = 3_600_000; private static final double msPerDay = 86_400_000; @@ -926,13 +926,13 @@ public final class NativeDate extends ScriptObject { case FORMAT_DATE : case FORMAT_LOCAL_DATE_TIME: // EEE MMM dd yyyy - sb.append(weekDays[(int) weekDay(t)]) + sb.append(weekDays[weekDay(t)]) .append(' ') - .append(months[(int) monthFromTime(t)]) + .append(months[monthFromTime(t)]) .append(' '); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); sb.append(' '); - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); if (format == FORMAT_DATE) { break; } @@ -948,11 +948,11 @@ public final class NativeDate extends ScriptObject { offset = (offset / 60) * 100 + offset % 60; // HH:mm:ss GMT+HHmm - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); sb.append(" GMT") .append(offset < 0 ? '-' : '+'); zeroPad(sb, Math.abs(offset), 4); @@ -963,20 +963,20 @@ public final class NativeDate extends ScriptObject { case FORMAT_LOCAL_DATE: // yyyy-MM-dd - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); sb.append('-'); - zeroPad(sb, (int) monthFromTime(t) + 1, 2); + zeroPad(sb, monthFromTime(t) + 1, 2); sb.append('-'); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); break; case FORMAT_LOCAL_TIME: // HH:mm:ss - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); break; default: @@ -996,19 +996,19 @@ public final class NativeDate extends ScriptObject { final StringBuilder sb = new StringBuilder(29); final double t = nd.getTime(); // EEE, dd MMM yyyy HH:mm:ss z - sb.append(weekDays[(int) weekDay(t)]) + sb.append(weekDays[weekDay(t)]) .append(", "); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); sb.append(' ') - .append(months[(int) monthFromTime(t)]) + .append(months[monthFromTime(t)]) .append(' '); - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); sb.append(' '); - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); sb.append(" GMT"); return sb.toString(); } @@ -1023,19 +1023,19 @@ public final class NativeDate extends ScriptObject { final StringBuilder sb = new StringBuilder(24); final double t = nd.getTime(); // yyyy-MM-dd'T'HH:mm:ss.SSS'Z' - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); sb.append('-'); - zeroPad(sb, (int) monthFromTime(t) + 1, 2); + zeroPad(sb, monthFromTime(t) + 1, 2); sb.append('-'); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); sb.append('T'); - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); sb.append('.'); - zeroPad(sb, (int) msFromTime(t), 3); + zeroPad(sb, msFromTime(t), 3); sb.append("Z"); return sb.toString(); } @@ -1072,29 +1072,30 @@ public final class NativeDate extends ScriptObject { } // ECMA 15.9.1.3 Year Number - private static double timeFromYear(final double y) { + private static double timeFromYear(final int y) { return dayFromYear(y) * msPerDay; } - private static double yearFromTime(final double t) { - double y = Math.floor(t / (msPerDay * 365.2425)) + 1970; + // ECMA 15.9.1.3 Year Number + private static int yearFromTime(final double t) { + int y = (int) Math.floor(t / (msPerDay * 365.2425)) + 1970; final double t2 = timeFromYear(y); if (t2 > t) { y--; - } else if (t2 + msPerDay * daysInYear((int) y) <= t) { + } else if (t2 + msPerDay * daysInYear(y) <= t) { y++; } return y; } - private static double dayWithinYear(final double t, final double year) { - return day(t) - dayFromYear(year); + private static int dayWithinYear(final double t, final int year) { + return (int) (day(t) - dayFromYear(year)); } - private static double monthFromTime(final double t) { - final double year = yearFromTime(t); - final double day = dayWithinYear(t, year); - final int[] firstDay = firstDayInMonth[isLeapYear((int) year) ? 1 : 0]; + private static int monthFromTime(final double t) { + final int year = yearFromTime(t); + final int day = dayWithinYear(t, year); + final int[] firstDay = firstDayInMonth[isLeapYear(year) ? 1 : 0]; int month = 0; while (month < 11 && firstDay[month + 1] <= day) { @@ -1103,10 +1104,10 @@ public final class NativeDate extends ScriptObject { return month; } - private static double dayFromTime(final double t) { - final double year = yearFromTime(t); - final double day = dayWithinYear(t, year); - final int[] firstDay = firstDayInMonth[isLeapYear((int) year) ? 1 : 0]; + private static int dayFromTime(final double t) { + final int year = yearFromTime(t); + final int day = dayWithinYear(t, year); + final int[] firstDay = firstDayInMonth[isLeapYear(year) ? 1 : 0]; int month = 0; while (month < 11 && firstDay[month + 1] <= day) { @@ -1121,11 +1122,8 @@ public final class NativeDate extends ScriptObject { return firstDay[month]; } - private static double weekDay(final double time) { - if (isNaN(time)) { - return NaN; - } - final double day = (day(time) + 4) % 7; + private static int weekDay(final double time) { + final int day = (int) (day(time) + 4) % 7; return day < 0 ? day + 7 : day; } @@ -1140,26 +1138,26 @@ public final class NativeDate extends ScriptObject { } // ECMA 15.9.1.10 Hours, Minutes, Second, and Milliseconds - private static double hourFromTime(final double t) { - final double h = Math.floor(t / msPerHour) % hoursPerDay; + private static int hourFromTime(final double t) { + final int h = (int) (Math.floor(t / msPerHour) % hoursPerDay); return h < 0 ? h + hoursPerDay: h; } - private static double minFromTime(final double t) { - final double m = Math.floor(t / msPerMinute) % minutesPerHour; + private static int minFromTime(final double t) { + final int m = (int) (Math.floor(t / msPerMinute) % minutesPerHour); return m < 0 ? m + minutesPerHour : m; } - private static double secFromTime(final double t) { - final double s = Math.floor(t / msPerSecond) % secondsPerMinute; + private static int secFromTime(final double t) { + final int s = (int) (Math.floor(t / msPerSecond) % secondsPerMinute); return s < 0 ? s + secondsPerMinute : s; } - private static double msFromTime(final double t) { - final double m = t % msPerSecond; + private static int msFromTime(final double t) { + final int m = (int) (t % msPerSecond); return m < 0 ? m + msPerSecond : m; } - private static double valueFromTime(final int unit, final double t) { + private static int valueFromTime(final int unit, final double t) { switch (unit) { case YEAR: return yearFromTime(t); case MONTH: return monthFromTime(t); @@ -1180,12 +1178,12 @@ public final class NativeDate extends ScriptObject { // ECMA 15.9.1.12 MakeDay (year, month, date) private static double makeDay(final double year, final double month, final double date) { final double y = year + Math.floor(month / 12); - double m = month % 12; + int m = (int) (month % 12); if (m < 0) { m += 12; } - double d = Math.floor(dayFromYear(y)); - d += dayFromMonth((int) m, (int) y); + double d = dayFromYear(y); + d += dayFromMonth(m, (int) y); return d + date - 1; } @@ -1257,13 +1255,13 @@ public final class NativeDate extends ScriptObject { nullReturn = true; } - if (! nullReturn) { + if (!nullReturn && !isNaN(time)) { d[i - start] = valueFromTime(i, time); } } } - return nullReturn? null : d; + return nullReturn ? null : d; } // ECMA 15.9.1.14 TimeClip (time) diff --git a/nashorn/test/script/basic/JDK-8025163.js b/nashorn/test/script/basic/JDK-8025163.js new file mode 100644 index 00000000000..1eaa98e82c2 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025163.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8025163: Date methods should not return -0 + * + * @test + * @run + */ + +print(1 / (new Date(0, 0, 1)).getYear()); +print(1 / (new Date(1969, 1, 2)).getDay()); +print(1 / (new Date(1969, 0, 1)).getHours()); +print(1 / (new Date(1969, 0, 1)).getHours()); +print(1 / (new Date(1969, 0, 1)).getMinutes()); +print(1 / (new Date(1969, 0, 1)).getSeconds()); +print(1 / (new Date(1969, 0, 1)).getMilliseconds()); +print(1 / (new Date(1969, 0, 1)).getMilliseconds()); + diff --git a/nashorn/test/script/basic/JDK-8025163.js.EXPECTED b/nashorn/test/script/basic/JDK-8025163.js.EXPECTED new file mode 100644 index 00000000000..cde7e1933e7 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025163.js.EXPECTED @@ -0,0 +1,8 @@ +Infinity +Infinity +Infinity +Infinity +Infinity +Infinity +Infinity +Infinity From 70e873ec737ba10be69b27cface7ea50413cad10 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Sun, 22 Sep 2013 12:53:03 +0100 Subject: [PATCH 0461/1294] 8024696: Missing null check in bound method reference capture Reviewed-by: jjg, briangoetz --- .../sun/tools/javac/comp/LambdaToMethod.java | 4 ++ .../tools/javac/lambda/8023558/T8023558a.java | 8 +++- .../MethodReferenceNullCheckTest.java | 47 +++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceNullCheckTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index b2a501d27d6..d22ebfa36e3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -153,6 +153,8 @@ public class LambdaToMethod extends TreeTranslator { return instance; } + private Attr attr; + private LambdaToMethod(Context context) { diags = JCDiagnostic.Factory.instance(context); log = Log.instance(context); @@ -166,6 +168,7 @@ public class LambdaToMethod extends TreeTranslator { analyzer = new LambdaAnalyzerPreprocessor(); Options options = Options.instance(context); dumpLambdaToMethodStats = options.isSet("dumpLambdaToMethodStats"); + attr = Attr.instance(context); } // @@ -368,6 +371,7 @@ public class LambdaToMethod extends TreeTranslator { case BOUND: /** Expr :: instMethod */ init = tree.getQualifierExpression(); + init = attr.makeNullCheck(init); break; case UNBOUND: /** Type :: instMethod */ diff --git a/langtools/test/tools/javac/lambda/8023558/T8023558a.java b/langtools/test/tools/javac/lambda/8023558/T8023558a.java index 205ff9eefdc..be3ba6494f0 100644 --- a/langtools/test/tools/javac/lambda/8023558/T8023558a.java +++ b/langtools/test/tools/javac/lambda/8023558/T8023558a.java @@ -31,8 +31,14 @@ public class T8023558a { T get(); } + static class K implements SAM { + public T get() { + return (T)this; + } + } + public static void main(String[] args) { - SAM sam = new SAM() { public SAM get() { return null; } }; + SAM sam = new SAM() { public SAM get() { return new K<>(); } }; SAM temp = sam.get()::get; } } diff --git a/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceNullCheckTest.java b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceNullCheckTest.java new file mode 100644 index 00000000000..fd2bf655649 --- /dev/null +++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceNullCheckTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, 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. + */ + +/** + * @test + * @bug 8024696 + * @summary Missing null check in bound method reference capture + */ + +import com.sun.tools.javac.util.Assert; +import java.util.function.*; + +public class MethodReferenceNullCheckTest { + public static void main(String[] args) { + String s = null; + boolean npeFired = false; + try { + Supplier ss = s::isEmpty; + } catch (NullPointerException npe) { + npeFired = true; + } finally { + Assert.check(npeFired, "NPE should have been thrown"); + } + } +} From 5bc8cd08aa15355b35fd273e71d36b710ba99b43 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Sun, 22 Sep 2013 06:31:43 -0700 Subject: [PATCH 0462/1294] 6989981: jstack causes "fatal error: ExceptionMark destructor expects no pending exceptions" Reviewed-by: sla, dsamersoff --- .../src/share/vm/services/attachListener.cpp | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/services/attachListener.cpp b/hotspot/src/share/vm/services/attachListener.cpp index bf002e7fa88..e30c3eeff8c 100644 --- a/hotspot/src/share/vm/services/attachListener.cpp +++ b/hotspot/src/share/vm/services/attachListener.cpp @@ -470,7 +470,17 @@ void AttachListener::init() { vmSymbols::threadgroup_string_void_signature(), thread_group, string, - CHECK); + THREAD); + + if (HAS_PENDING_EXCEPTION) { + tty->print_cr("Exception in VM (AttachListener::init) : "); + java_lang_Throwable::print(PENDING_EXCEPTION, tty); + tty->cr(); + + CLEAR_PENDING_EXCEPTION; + + return; + } KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass()); JavaCalls::call_special(&result, @@ -479,7 +489,17 @@ void AttachListener::init() { vmSymbols::add_method_name(), vmSymbols::thread_void_signature(), thread_oop, // ARG 1 - CHECK); + THREAD); + + if (HAS_PENDING_EXCEPTION) { + tty->print_cr("Exception in VM (AttachListener::init) : "); + java_lang_Throwable::print(PENDING_EXCEPTION, tty); + tty->cr(); + + CLEAR_PENDING_EXCEPTION; + + return; + } { MutexLocker mu(Threads_lock); JavaThread* listener_thread = new JavaThread(&attach_listener_thread_entry); From 4d6a0655f9a953638db8c5a1fbf6c641dde016f6 Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Sun, 22 Sep 2013 18:49:09 +0400 Subject: [PATCH 0463/1294] 7133122: SA throws sun.jvm.hotspot.debugger.UnmappedAddressException when it should not Replace PT_LOAD segment with library segment when necessary Reviewed-by: dholmes, sla --- hotspot/agent/src/os/linux/ps_core.c | 67 ++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/hotspot/agent/src/os/linux/ps_core.c b/hotspot/agent/src/os/linux/ps_core.c index 85abab802e0..c1620407894 100644 --- a/hotspot/agent/src/os/linux/ps_core.c +++ b/hotspot/agent/src/os/linux/ps_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -698,29 +698,58 @@ err: // read segments of a shared object static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) { - int i = 0; - ELF_PHDR* phbuf; - ELF_PHDR* lib_php = NULL; + int i = 0; + ELF_PHDR* phbuf; + ELF_PHDR* lib_php = NULL; - if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) - return false; + int page_size=sysconf(_SC_PAGE_SIZE); - // we want to process only PT_LOAD segments that are not writable. - // i.e., text segments. The read/write/exec (data) segments would - // have been already added from core file segments. - for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) { - if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) { - if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL) - goto err; + if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) { + return false; + } + + // we want to process only PT_LOAD segments that are not writable. + // i.e., text segments. The read/write/exec (data) segments would + // have been already added from core file segments. + for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) { + if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) { + + uintptr_t target_vaddr = lib_php->p_vaddr + lib_base; + map_info *existing_map = core_lookup(ph, target_vaddr); + + if (existing_map == NULL){ + if (add_map_info(ph, lib_fd, lib_php->p_offset, + target_vaddr, lib_php->p_filesz) == NULL) { + goto err; + } + } else { + if ((existing_map->memsz != page_size) && + (existing_map->fd != lib_fd) && + (existing_map->memsz != lib_php->p_filesz)){ + + print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)", + target_vaddr, lib_php->p_filesz, lib_php->p_flags); + goto err; + } + + /* replace PT_LOAD segment with library segment */ + print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n", + existing_map->memsz, lib_php->p_filesz); + + existing_map->fd = lib_fd; + existing_map->offset = lib_php->p_offset; + existing_map->memsz = lib_php->p_filesz; } - lib_php++; - } + } - free(phbuf); - return true; + lib_php++; + } + + free(phbuf); + return true; err: - free(phbuf); - return false; + free(phbuf); + return false; } // process segments from interpreter (ld.so or ld-linux.so) From a2a38c6b65c0f837c3bccb3987b6243d4e189e17 Mon Sep 17 00:00:00 2001 From: Andreas Lundblad Date: Mon, 23 Sep 2013 10:10:07 +0200 Subject: [PATCH 0464/1294] 8024988: javac, LVT test harness should generate tests .class files in the scratch folder Set the CLASS_OUTPUT location to the scratch directory. Changed the argument to checkClassFile accordingly. Reviewed-by: jjg, vromero --- .../test/tools/javac/flow/LVTHarness.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/langtools/test/tools/javac/flow/LVTHarness.java b/langtools/test/tools/javac/flow/LVTHarness.java index 7794ded19dd..9aac87c4f00 100644 --- a/langtools/test/tools/javac/flow/LVTHarness.java +++ b/langtools/test/tools/javac/flow/LVTHarness.java @@ -64,6 +64,7 @@ import com.sun.tools.classfile.Method; import static javax.tools.StandardLocation.*; import static com.sun.tools.classfile.LocalVariableTable_attribute.Entry; +import static javax.tools.JavaFileObject.Kind.SOURCE; public class LVTHarness { @@ -73,10 +74,14 @@ public class LVTHarness { static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); public static void main(String[] args) throws Exception { - fm.setLocation(SOURCE_PATH, - Arrays.asList(new File(System.getProperty("test.src"), "tests"))); - for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", - Collections.singleton(JavaFileObject.Kind.SOURCE), true)) { + + String testDir = System.getProperty("test.src"); + fm.setLocation(SOURCE_PATH, Arrays.asList(new File(testDir, "tests"))); + + // Make sure classes are written to scratch dir. + fm.setLocation(CLASS_OUTPUT, Arrays.asList(new File("."))); + + for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(SOURCE), true)) { new LVTHarness(jfo).check(); } if (nerrors > 0) { @@ -86,8 +91,7 @@ public class LVTHarness { JavaFileObject jfo; - Map aliveRangeMap = - new HashMap(); + Map aliveRangeMap = new HashMap<>(); Set declaredKeys = new HashSet<>(); List seenAliveRanges = new ArrayList<>(); @@ -96,15 +100,19 @@ public class LVTHarness { } protected void check() throws Exception { - JavacTask ct = (JavacTask)comp.getTask(null, fm, null, Arrays.asList("-g"), - null, Arrays.asList(jfo)); - System.err.println("compiling code " + jfo.toString()); + + JavacTask ct = (JavacTask) comp.getTask(null, fm, null, Arrays.asList("-g"), + null, Arrays.asList(jfo)); + System.err.println("compiling code " + jfo); ct.setProcessors(Collections.singleton(new AliveRangeFinder())); if (!ct.call()) { throw new AssertionError("Error during compilation"); } - checkClassFile(new File(jfo.getName().replace(".java", ".class"))); + + File javaFile = new File(jfo.getName()); + File classFile = new File(javaFile.getName().replace(".java", ".class")); + checkClassFile(classFile); //check all candidates have been used up for (Map.Entry entry : aliveRangeMap.entrySet()) { From 48774216f24dfa733f0f53ad0730c5b20d9a06b8 Mon Sep 17 00:00:00 2001 From: Andreas Lundblad Date: Mon, 23 Sep 2013 10:42:38 +0200 Subject: [PATCH 0465/1294] 6386236: Please rename com.sun.tools.javac.util.ListBuffer.lb() Static factory method ListBuffer.lb removed. Replaced by constructor calls. Reviewed-by: jfranck, jjg --- .../sun/tools/javac/api/JavacTaskImpl.java | 2 +- .../tools/javac/code/DeferredLintHandler.java | 2 +- .../com/sun/tools/javac/code/Printer.java | 4 +-- .../com/sun/tools/javac/code/Symbol.java | 2 +- .../com/sun/tools/javac/code/Type.java | 10 +++--- .../javac/code/TypeAnnotationPosition.java | 4 +-- .../sun/tools/javac/code/TypeAnnotations.java | 12 +++---- .../com/sun/tools/javac/code/Types.java | 31 +++++++++--------- .../com/sun/tools/javac/comp/Attr.java | 16 +++++----- .../com/sun/tools/javac/comp/Check.java | 4 +-- .../sun/tools/javac/comp/DeferredAttr.java | 2 +- .../com/sun/tools/javac/comp/Flow.java | 8 ++--- .../com/sun/tools/javac/comp/Infer.java | 18 +++++------ .../sun/tools/javac/comp/LambdaToMethod.java | 32 +++++++++---------- .../com/sun/tools/javac/comp/Lower.java | 6 ++-- .../com/sun/tools/javac/comp/Resolve.java | 8 ++--- .../com/sun/tools/javac/comp/TransTypes.java | 2 +- .../com/sun/tools/javac/jvm/ClassReader.java | 9 +++--- .../com/sun/tools/javac/jvm/ClassWriter.java | 4 +-- .../classes/com/sun/tools/javac/jvm/Code.java | 2 +- .../sun/tools/javac/main/JavaCompiler.java | 17 +++++----- .../javac/model/JavacAnnoConstructs.java | 4 +-- .../sun/tools/javac/parser/JavacParser.java | 11 +++---- .../com/sun/tools/javac/parser/Tokens.java | 4 +-- .../com/sun/tools/javac/util/GraphUtils.java | 6 ++-- .../com/sun/tools/javac/util/List.java | 8 ++--- .../com/sun/tools/javac/util/ListBuffer.java | 6 +--- .../classes/com/sun/tools/javac/util/Log.java | 2 +- .../IntersectionTypeCastTest.java | 2 +- .../IntersectionTargetTypeTest.java | 4 +-- .../scope/7017664/CompoundScopeTest.java | 4 +-- .../test/tools/javac/types/TypeHarness.java | 4 +-- 32 files changed, 121 insertions(+), 129 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java index f5f5a4b120e..e0dde3de7b2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java @@ -472,7 +472,7 @@ public class JavacTaskImpl extends BasicJavacTask { for (TypeElement item: classes) set.add(item); - ListBuffer> defer = ListBuffer.>lb(); + ListBuffer> defer = new ListBuffer<>(); while (list.peek() != null) { Env env = list.remove(); ClassSymbol csym = env.enclClass.sym; diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java b/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java index 9392046bb2d..0691498aeb5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java @@ -81,7 +81,7 @@ public class DeferredLintHandler { } else { ListBuffer loggers = loggersQueue.get(currentPos); if (loggers == null) { - loggersQueue.put(currentPos, loggers = ListBuffer.lb()); + loggersQueue.put(currentPos, loggers = new ListBuffer<>()); } loggers.append(logger); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java index aa05cc29204..d46631504b2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java @@ -103,7 +103,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi * @return localized string representation */ public String visitTypes(List ts, Locale locale) { - ListBuffer sbuf = ListBuffer.lb(); + ListBuffer sbuf = new ListBuffer<>(); for (Type t : ts) { sbuf.append(visit(t, locale)); } @@ -118,7 +118,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi * @return localized string representation */ public String visitSymbols(List ts, Locale locale) { - ListBuffer sbuf = ListBuffer.lb(); + ListBuffer sbuf = new ListBuffer<>(); for (Symbol t : ts) { sbuf.append(visit(t, locale)); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index 65459ec3daf..7a65bd04b10 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -614,7 +614,7 @@ public abstract class Symbol implements Element { } public List getTypeParameters() { - ListBuffer l = ListBuffer.lb(); + ListBuffer l = new ListBuffer<>(); for (Type t : type.getTypeArguments()) { Assert.check(t.tsym.getKind() == ElementKind.TYPE_PARAMETER); l.append((TypeVariableSymbol)t.tsym); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java index fb6308ba9bd..a6e4642ce51 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java @@ -433,7 +433,7 @@ public abstract class Type implements TypeMirror { } public static List filter(List ts, Filter tf) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : ts) { if (tf.accepts(t)) { buf.append(t); @@ -1496,7 +1496,7 @@ public abstract class Type implements TypeMirror { /** get all bounds of a given kind */ public List getBounds(InferenceBound... ibs) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (InferenceBound ib : ibs) { buf.appendList(bounds.get(ib)); } @@ -1505,7 +1505,7 @@ public abstract class Type implements TypeMirror { /** get the list of declared (upper) bounds */ public List getDeclaredBounds() { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); int count = 0; for (Type b : getBounds(InferenceBound.UPPER)) { if (count++ == declaredCount) break; @@ -1565,8 +1565,8 @@ public abstract class Type implements TypeMirror { for (Map.Entry> _entry : bounds.entrySet()) { InferenceBound ib = _entry.getKey(); List prevBounds = _entry.getValue(); - ListBuffer newBounds = ListBuffer.lb(); - ListBuffer deps = ListBuffer.lb(); + ListBuffer newBounds = new ListBuffer<>(); + ListBuffer deps = new ListBuffer<>(); //step 1 - re-add bounds that are not dependent on ivars for (Type t : prevBounds) { if (!t.containsAny(instVars)) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java index 89f6ea40799..c481ea5d3e0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java @@ -304,7 +304,7 @@ public class TypeAnnotationPosition { * @param list The bytecode representation of the type path. */ public static List getTypePathFromBinary(java.util.List list) { - ListBuffer loc = ListBuffer.lb(); + ListBuffer loc = new ListBuffer<>(); Iterator iter = list.iterator(); while (iter.hasNext()) { Integer fst = iter.next(); @@ -316,7 +316,7 @@ public class TypeAnnotationPosition { } public static List getBinaryFromTypePath(java.util.List locs) { - ListBuffer loc = ListBuffer.lb(); + ListBuffer loc = new ListBuffer<>(); for (TypePathEntry tpe : locs) { loc = loc.append(tpe.tag.tag); loc = loc.append(tpe.arg); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index 642de5d4c4a..56acb0e8eb2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -233,7 +233,7 @@ public class TypeAnnotations { * When traversing the AST we keep the "frames" of visited * trees in order to determine the position of annotations. */ - private ListBuffer frames = ListBuffer.lb(); + private ListBuffer frames = new ListBuffer<>(); protected void push(JCTree t) { frames = frames.prepend(t); } protected JCTree pop() { return frames.next(); } @@ -381,7 +381,7 @@ public class TypeAnnotations { } JCArrayTypeTree arTree = arrayTypeTree(typetree); - ListBuffer depth = ListBuffer.lb(); + ListBuffer depth = new ListBuffer<>(); depth = depth.append(TypePathEntry.ARRAY); while (arType.elemtype.hasTag(TypeTag.ARRAY)) { if (arType.elemtype.isAnnotated()) { @@ -473,7 +473,7 @@ public class TypeAnnotations { // the correct nesting. // The genericLocation for the annotation. - ListBuffer depth = ListBuffer.lb(); + ListBuffer depth = new ListBuffer<>(); Type topTy = enclTy; while (enclEl != null && @@ -793,7 +793,7 @@ public class TypeAnnotations { } case ARRAY_TYPE: { - ListBuffer index = ListBuffer.lb(); + ListBuffer index = new ListBuffer<>(); index = index.append(TypePathEntry.ARRAY); List newPath = path.tail; while (true) { @@ -956,7 +956,7 @@ public class TypeAnnotations { private static void locateNestedTypes(Type type, TypeAnnotationPosition p) { // The number of "steps" to get from the full type to the // left-most outer type. - ListBuffer depth = ListBuffer.lb(); + ListBuffer depth = new ListBuffer<>(); Type encl = type.getEnclosingType(); while (encl != null && @@ -1226,7 +1226,7 @@ public class TypeAnnotations { public void visitNewArray(JCNewArray tree) { findPosition(tree, tree, tree.annotations); int dimAnnosCount = tree.dimAnnotations.size(); - ListBuffer depth = ListBuffer.lb(); + ListBuffer depth = new ListBuffer<>(); // handle annotations associated with dimensions for (int i = 0; i < dimAnnosCount; ++i) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 0d060b60bb7..996bcd88018 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -51,7 +51,6 @@ import static com.sun.tools.javac.code.Symbol.*; import static com.sun.tools.javac.code.Type.*; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.jvm.ClassFile.externalize; -import static com.sun.tools.javac.util.ListBuffer.lb; /** * Utility class containing various operations on types. @@ -411,7 +410,7 @@ public class Types { throw failure("not.a.functional.intf", origin); } - final ListBuffer abstracts = ListBuffer.lb(); + final ListBuffer abstracts = new ListBuffer<>(); for (Symbol sym : membersCache.getElements(new DescriptorFilter(origin))) { Type mtype = memberType(origin.type, sym); if (abstracts.isEmpty() || @@ -434,7 +433,7 @@ public class Types { FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList()); if (descRes == null) { //we can get here if the functional interface is ill-formed - ListBuffer descriptors = ListBuffer.lb(); + ListBuffer descriptors = new ListBuffer<>(); for (Symbol desc : abstracts) { String key = desc.type.getThrownTypes().nonEmpty() ? "descriptor.throws" : "descriptor"; @@ -596,7 +595,7 @@ public class Types { Type capturedSite = capture(site); if (capturedSite != site) { Type formalInterface = site.tsym.type; - ListBuffer typeargs = ListBuffer.lb(); + ListBuffer typeargs = new ListBuffer<>(); List actualTypeargs = site.getTypeArguments(); List capturedTypeargs = capturedSite.getTypeArguments(); //simply replace the wildcards with its bound @@ -662,7 +661,7 @@ public class Types { Assert.check(isFunctionalInterface(origin)); Symbol descSym = findDescriptorSymbol(origin); CompoundScope members = membersClosure(origin.type, false); - ListBuffer overridden = ListBuffer.lb(); + ListBuffer overridden = new ListBuffer<>(); outer: for (Symbol m2 : members.getElementsByName(descSym.name, bridgeFilter)) { if (m2 == descSym) continue; else if (descSym.overrides(m2, origin, Types.this, false)) { @@ -885,12 +884,12 @@ public class Types { private Type rewriteSupers(Type t) { if (!t.isParameterized()) return t; - ListBuffer from = lb(); - ListBuffer to = lb(); + ListBuffer from = new ListBuffer<>(); + ListBuffer to = new ListBuffer<>(); adaptSelf(t, from, to); if (from.isEmpty()) return t; - ListBuffer rewrite = lb(); + ListBuffer rewrite = new ListBuffer<>(); boolean changed = false; for (Type orig : to.toList()) { Type s = rewriteSupers(orig); @@ -2744,7 +2743,7 @@ public class Types { } public List prune(List methods) { - ListBuffer methodsMin = ListBuffer.lb(); + ListBuffer methodsMin = new ListBuffer<>(); for (MethodSymbol m1 : methods) { boolean isMin_m1 = true; for (MethodSymbol m2 : methods) { @@ -3001,7 +3000,7 @@ public class Types { List to) { if (tvars.isEmpty()) return tvars; - ListBuffer newBoundsBuf = lb(); + ListBuffer newBoundsBuf = new ListBuffer<>(); boolean changed = false; // calculate new bounds for (Type t : tvars) { @@ -3013,7 +3012,7 @@ public class Types { } if (!changed) return tvars; - ListBuffer newTvars = lb(); + ListBuffer newTvars = new ListBuffer<>(); // create new type variables without bounds for (Type t : tvars) { newTvars.append(new TypeVar(t.tsym, null, syms.botType)); @@ -3440,15 +3439,15 @@ public class Types { * compoundMin or glb. */ private List closureMin(List cl) { - ListBuffer classes = lb(); - ListBuffer interfaces = lb(); + ListBuffer classes = new ListBuffer<>(); + ListBuffer interfaces = new ListBuffer<>(); while (!cl.isEmpty()) { Type current = cl.head; if (current.isInterface()) interfaces.append(current); else classes.append(current); - ListBuffer candidates = lb(); + ListBuffer candidates = new ListBuffer<>(); for (Type t : cl.tail) { if (!isSubtypeNoCapture(current, t)) candidates.append(t); @@ -3564,7 +3563,7 @@ public class Types { } // where List erasedSupertypes(Type t) { - ListBuffer buf = lb(); + ListBuffer buf = new ListBuffer<>(); for (Type sup : closure(t)) { if (sup.hasTag(TYPEVAR)) { buf.append(sup); @@ -3914,7 +3913,7 @@ public class Types { } // where public List freshTypeVariables(List types) { - ListBuffer result = lb(); + ListBuffer result = new ListBuffer<>(); for (Type t : types) { if (t.hasTag(WILDCARD)) { t = t.unannotatedType(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index cb2337f936c..3813a6acd7a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -1724,7 +1724,7 @@ public class Attr extends JCTree.Visitor { boolean isConstructorCall = methName == names._this || methName == names._super; - ListBuffer argtypesBuf = ListBuffer.lb(); + ListBuffer argtypesBuf = new ListBuffer<>(); if (isConstructorCall) { // We are seeing a ...this(...) or ...super(...) call. // Check that this is the first statement in a constructor. @@ -1989,7 +1989,7 @@ public class Attr extends JCTree.Visitor { } // Attribute constructor arguments. - ListBuffer argtypesBuf = ListBuffer.lb(); + ListBuffer argtypesBuf = new ListBuffer<>(); int pkind = attribArgs(tree.args, localEnv, argtypesBuf); List argtypes = argtypesBuf.toList(); List typeargtypes = attribTypes(tree.typeargs, localEnv); @@ -2476,8 +2476,8 @@ public class Attr extends JCTree.Visitor { } private TypeSymbol makeNotionalInterface(IntersectionClassType ict) { - ListBuffer targs = ListBuffer.lb(); - ListBuffer supertypes = ListBuffer.lb(); + ListBuffer targs = new ListBuffer<>(); + ListBuffer supertypes = new ListBuffer<>(); for (Type i : ict.interfaces_field) { if (i.isParameterized()) { targs.appendList(i.tsym.type.allparams()); @@ -2907,7 +2907,7 @@ public class Attr extends JCTree.Visitor { } }); } else { - ListBuffer targets = ListBuffer.lb(); + ListBuffer targets = new ListBuffer<>(); if (pt.hasTag(CLASS)) { if (pt.isCompound()) { targets.append(types.removeWildcards(primaryTarget)); //this goes first @@ -3903,7 +3903,7 @@ public class Attr extends JCTree.Visitor { } public void visitTypeUnion(JCTypeUnion tree) { - ListBuffer multicatchTypes = ListBuffer.lb(); + ListBuffer multicatchTypes = new ListBuffer<>(); ListBuffer all_multicatchTypes = null; // lazy, only if needed for (JCExpression typeTree : tree.alternatives) { Type ctype = attribType(typeTree, env); @@ -3930,7 +3930,7 @@ public class Attr extends JCTree.Visitor { all_multicatchTypes.append(ctype); } else { if (all_multicatchTypes == null) { - all_multicatchTypes = ListBuffer.lb(); + all_multicatchTypes = new ListBuffer<>(); all_multicatchTypes.appendList(multicatchTypes); } all_multicatchTypes.append(ctype); @@ -4085,7 +4085,7 @@ public class Attr extends JCTree.Visitor { if (annotations.isEmpty()) return List.nil(); - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (JCAnnotation anno : annotations) { if (anno.attribute != null) { // TODO: this null-check is only needed for an obscure diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index d3f94fdba82..a9ad0a68299 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -2452,8 +2452,8 @@ public class Check { Assert.check(m.kind == MTH); List prov = types.interfaceCandidates(site, (MethodSymbol)m); if (prov.size() > 1) { - ListBuffer abstracts = ListBuffer.lb(); - ListBuffer defaults = ListBuffer.lb(); + ListBuffer abstracts = new ListBuffer<>(); + ListBuffer defaults = new ListBuffer<>(); for (MethodSymbol provSym : prov) { if ((provSym.flags() & DEFAULT) != 0) { defaults = defaults.append(provSym); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 4db110579f7..6357419cf3d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -637,7 +637,7 @@ public class DeferredAttr extends JCTree.Visitor { Env localEnv = env.dup(tree); JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv, attr.memberReferenceQualifierResult(tree)); - ListBuffer argtypes = ListBuffer.lb(); + ListBuffer argtypes = new ListBuffer<>(); for (Type t : types.findDescriptorType(pt).getParameterTypes()) { argtypes.append(Type.noType); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index 252124370e5..8c69c814965 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -713,7 +713,7 @@ public class Flow { ListBuffer prevPending = pendingExits; boolean prevAlive = alive; try { - pendingExits = ListBuffer.lb(); + pendingExits = new ListBuffer<>(); alive = true; scanStat(tree.body); tree.canCompleteNormally = alive; @@ -1265,7 +1265,7 @@ public class Flow { List prevThrown = thrown; ListBuffer prevPending = pendingExits; try { - pendingExits = ListBuffer.lb(); + pendingExits = new ListBuffer<>(); caught = tree.getDescriptorType(types).getThrownTypes(); thrown = List.nil(); scan(tree.body); @@ -1338,7 +1338,7 @@ public class Flow { ListBuffer prevPending = pendingExits; inLambda = true; try { - pendingExits = ListBuffer.lb(); + pendingExits = new ListBuffer<>(); caught = List.of(syms.throwableType); thrown = List.nil(); scan(tree.body); @@ -2030,7 +2030,7 @@ public class Flow { void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {} public void visitTry(JCTry tree) { - ListBuffer resourceVarDecls = ListBuffer.lb(); + ListBuffer resourceVarDecls = new ListBuffer<>(); final Bits uninitsTryPrev = new Bits(uninitsTry); ListBuffer

    prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index 4c9568eb32c..61f75f068fa 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -277,7 +277,7 @@ public class Infer { * Infer cyclic inference variables as described in 15.12.2.8. */ private void instantiateAsUninferredVars(List vars, InferenceContext inferenceContext) { - ListBuffer todo = ListBuffer.lb(); + ListBuffer todo = new ListBuffer<>(); //step 1 - create fresh tvars for (Type t : vars) { UndetVar uv = (UndetVar)inferenceContext.asFree(t); @@ -1832,7 +1832,7 @@ public class Infer { } private List filterVars(Filter fu) { - ListBuffer res = ListBuffer.lb(); + ListBuffer res = new ListBuffer<>(); for (Type t : undetvars) { UndetVar uv = (UndetVar)t; if (fu.accepts(uv)) { @@ -1860,7 +1860,7 @@ public class Infer { * Returns a list of free variables in a given type */ final List freeVarsIn(Type t) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type iv : inferenceVars()) { if (t.contains(iv)) { buf.add(iv); @@ -1870,11 +1870,11 @@ public class Infer { } final List freeVarsIn(List ts) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : ts) { buf.appendList(freeVarsIn(t)); } - ListBuffer buf2 = ListBuffer.lb(); + ListBuffer buf2 = new ListBuffer<>(); for (Type t : buf) { if (!buf2.contains(t)) { buf2.add(t); @@ -1893,7 +1893,7 @@ public class Infer { } final List asFree(List ts) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : ts) { buf.append(asFree(t)); } @@ -1901,7 +1901,7 @@ public class Infer { } List instTypes() { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : undetvars) { UndetVar uv = (UndetVar)t; buf.append(uv.inst != null ? uv.inst : uv.qtype); @@ -1919,7 +1919,7 @@ public class Infer { } List asInstTypes(List ts) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : ts) { buf.append(asInstType(t)); } @@ -1967,7 +1967,7 @@ public class Infer { * Save the state of this inference context */ List save() { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : undetvars) { UndetVar uv = (UndetVar)t; UndetVar uv2 = new UndetVar((TypeVar)uv.qtype, types); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index d22ebfa36e3..eb15ef65c11 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -126,7 +126,7 @@ public class LambdaToMethod extends TreeTranslator { private final VarSymbol deserParamSym; private KlassInfo(Symbol kSym) { - appendedMethodList = ListBuffer.lb(); + appendedMethodList = new ListBuffer<>(); deserializeCases = new HashMap>(); long flags = PRIVATE | STATIC | SYNTHETIC; MethodType type = new MethodType(List.of(syms.serializedLambdaType), syms.objectType, @@ -191,7 +191,7 @@ public class LambdaToMethod extends TreeTranslator { } List translate(List trees, TranslationContext newContext) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (T tree : trees) { buf.append(translate(tree, newContext)); } @@ -304,7 +304,7 @@ public class LambdaToMethod extends TreeTranslator { // * the "this" argument if it is an instance method // * enclosing locals captured by the lambda expression - ListBuffer syntheticInits = ListBuffer.lb(); + ListBuffer syntheticInits = new ListBuffer<>(); if (!sym.isStatic()) { syntheticInits.append(makeThis( @@ -469,7 +469,7 @@ public class LambdaToMethod extends TreeTranslator { } else if (isLambda_void && isTarget_Void) { //void to Void conversion: // BODY; return null; - ListBuffer stats = ListBuffer.lb(); + ListBuffer stats = new ListBuffer<>(); stats.append(make.Exec(expr)); stats.append(make.Return(make.Literal(BOT, null).setType(syms.botType))); return make.Block(0, stats.toList()); @@ -531,8 +531,8 @@ public class LambdaToMethod extends TreeTranslator { } private JCMethodDecl makeDeserializeMethod(Symbol kSym) { - ListBuffer cases = ListBuffer.lb(); - ListBuffer breaks = ListBuffer.lb(); + ListBuffer cases = new ListBuffer<>(); + ListBuffer breaks = new ListBuffer<>(); for (Map.Entry> entry : kInfo.deserializeCases.entrySet()) { JCBreak br = make.Break(null); breaks.add(br); @@ -594,11 +594,11 @@ public class LambdaToMethod extends TreeTranslator { String implMethodSignature = methodSig(types.erasure(refSym.type)); JCExpression kindTest = eqTest(syms.intType, deserGetter("getImplMethodKind", syms.intType), make.Literal(implMethodKind)); - ListBuffer serArgs = ListBuffer.lb(); + ListBuffer serArgs = new ListBuffer<>(); int i = 0; for (Type t : indyType.getParameterTypes()) { - List indexAsArg = ListBuffer.lb().append(make.Literal(i)).toList(); - List argTypes = ListBuffer.lb().append(syms.intType).toList(); + List indexAsArg = new ListBuffer().append(make.Literal(i)).toList(); + List argTypes = new ListBuffer().append(syms.intType).toList(); serArgs.add(make.TypeCast(types.erasure(t), deserGetter("getCapturedArg", syms.objectType, argTypes, indexAsArg))); ++i; } @@ -618,7 +618,7 @@ public class LambdaToMethod extends TreeTranslator { null); ListBuffer stmts = kInfo.deserializeCases.get(implMethodName); if (stmts == null) { - stmts = ListBuffer.lb(); + stmts = new ListBuffer<>(); kInfo.deserializeCases.put(implMethodName, stmts); } /**** @@ -728,8 +728,8 @@ public class LambdaToMethod extends TreeTranslator { private final JCMemberReference tree; private final ReferenceTranslationContext localContext; - private final ListBuffer args = ListBuffer.lb(); - private final ListBuffer params = ListBuffer.lb(); + private final ListBuffer args = new ListBuffer<>(); + private final ListBuffer params = new ListBuffer<>(); MemberReferenceBridger(JCMemberReference tree, ReferenceTranslationContext localContext) { this.tree = tree; @@ -934,7 +934,7 @@ public class LambdaToMethod extends TreeTranslator { typeToMethodType(tree.getDescriptorType(types))); //computed indy arg types - ListBuffer indy_args_types = ListBuffer.lb(); + ListBuffer indy_args_types = new ListBuffer<>(); for (JCExpression arg : indy_args) { indy_args_types.append(arg.type); } @@ -949,7 +949,7 @@ public class LambdaToMethod extends TreeTranslator { names.altMetafactory : names.metafactory; if (context.needsAltMetafactory()) { - ListBuffer markers = ListBuffer.lb(); + ListBuffer markers = new ListBuffer<>(); for (Type t : tree.targets.tail) { if (t.tsym != syms.serializableType.tsym) { markers.append(t.tsym); @@ -1027,7 +1027,7 @@ public class LambdaToMethod extends TreeTranslator { } //where private List bsmStaticArgToTypes(List args) { - ListBuffer argtypes = ListBuffer.lb(); + ListBuffer argtypes = new ListBuffer<>(); for (Object arg : args) { argtypes.append(bsmStaticArgToType(arg)); } @@ -1851,7 +1851,7 @@ public class LambdaToMethod extends TreeTranslator { (thisReferenced? (inInterface? DEFAULT : 0) : STATIC); //compute synthetic params - ListBuffer params = ListBuffer.lb(); + ListBuffer params = new ListBuffer<>(); // The signature of the method is augmented with the following // synthetic parameters: diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index cb054fe80f2..51588257c9b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -3725,7 +3725,7 @@ public class Lower extends TreeTranslator { (JCVariableDecl)make.VarDef(dollar_tmp, make.Literal(INT, -1)).setType(dollar_tmp.type); dollar_tmp_def.init.type = dollar_tmp.type = syms.intType; stmtList.append(dollar_tmp_def); - ListBuffer caseBuffer = ListBuffer.lb(); + ListBuffer caseBuffer = new ListBuffer<>(); // hashCode will trigger nullcheck on original switch expression JCMethodInvocation hashCodeCall = makeCall(make.Ident(dollar_s), names.hashCode, @@ -3749,7 +3749,7 @@ public class Lower extends TreeTranslator { elsepart); } - ListBuffer lb = ListBuffer.lb(); + ListBuffer lb = new ListBuffer<>(); JCBreak breakStmt = make.Break(null); breakStmt.target = switch1; lb.append(elsepart).append(breakStmt); @@ -3764,7 +3764,7 @@ public class Lower extends TreeTranslator { // with corresponding integer ones from the label to // position map. - ListBuffer lb = ListBuffer.lb(); + ListBuffer lb = new ListBuffer<>(); JCSwitch switch2 = make.Switch(make.Ident(dollar_tmp), lb.toList()); for(JCCase oneCase : caseList ) { // Rewire up old unlabeled break statements to the diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index e3c427413ec..87eb36668f4 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -213,7 +213,7 @@ public class Resolve { int pos = 0; int mostSpecificPos = -1; - ListBuffer subDiags = ListBuffer.lb(); + ListBuffer subDiags = new ListBuffer<>(); for (Candidate c : currentResolutionContext.candidates) { if (currentResolutionContext.step != c.step || (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) || @@ -783,7 +783,7 @@ public class Resolve { }; List dummyArgs(int length) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (int i = 0 ; i < length ; i++) { buf.append(Type.noType); } @@ -3173,7 +3173,7 @@ public class Resolve { } //where private List pruneInterfaces(Type t) { - ListBuffer result = ListBuffer.lb(); + ListBuffer result = new ListBuffer<>(); for (Type t1 : types.interfaces(t)) { boolean shouldAdd = true; for (Type t2 : types.interfaces(t)) { @@ -3286,7 +3286,7 @@ public class Resolve { if (argtypes == null || argtypes.isEmpty()) { return noArgs; } else { - ListBuffer diagArgs = ListBuffer.lb(); + ListBuffer diagArgs = new ListBuffer<>(); for (Type t : argtypes) { if (t.hasTag(DEFERRED)) { diagArgs.append(((DeferredAttr.DeferredType)t).tree); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java index d747a2b5156..48bd03c7a66 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -887,7 +887,7 @@ public class TransTypes extends TreeTranslator { private List addOverrideBridgesIfNeeded(DiagnosticPosition pos, final ClassSymbol c) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); if (c.isInterface() || !boundsRestricted(c)) return buf.toList(); Type t = types.supertype(c.type); diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 1b57b13cf36..397069589ff 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -1446,8 +1446,7 @@ public class ClassReader { void attachTypeAnnotations(final Symbol sym) { int numAttributes = nextChar(); if (numAttributes != 0) { - ListBuffer proxies = - ListBuffer.lb(); + ListBuffer proxies = new ListBuffer<>(); for (int i = 0; i < numAttributes; i++) proxies.append(readTypeAnnotation()); annotate.normal(new TypeAnnotationCompleter(sym, proxies.toList())); @@ -1596,7 +1595,7 @@ public class ClassReader { { // See whether there is location info and read it int len = nextByte(); - ListBuffer loc = ListBuffer.lb(); + ListBuffer loc = new ListBuffer<>(); for (int i = 0; i < len * TypeAnnotationPosition.TypePathEntry.bytesPerEntry; ++i) loc = loc.append(nextByte()); position.location = TypeAnnotationPosition.getTypePathFromBinary(loc.toList()); @@ -1946,7 +1945,7 @@ public class ClassReader { } List deproxyTypeCompoundList(List proxies) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (TypeAnnotationProxy proxy: proxies) { Attribute.Compound compound = deproxyCompound(proxy.compound); Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position); @@ -2033,7 +2032,7 @@ public class ClassReader { boolean isVarargs = (flags & VARARGS) != 0; if (isVarargs) { Type varargsElem = args.last(); - ListBuffer adjustedArgs = ListBuffer.lb(); + ListBuffer adjustedArgs = new ListBuffer<>(); for (Type t : args) { adjustedArgs.append(t != varargsElem ? t : diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index 6698c7fde27..54122430380 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -766,8 +766,8 @@ public class ClassWriter extends ClassFile { int writeTypeAnnotations(List typeAnnos, boolean inCode) { if (typeAnnos.isEmpty()) return 0; - ListBuffer visibles = ListBuffer.lb(); - ListBuffer invisibles = ListBuffer.lb(); + ListBuffer visibles = new ListBuffer<>(); + ListBuffer invisibles = new ListBuffer<>(); for (Attribute.TypeCompound tc : typeAnnos) { if (tc.hasUnknownPosition()) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java index d0ed7ec559c..6276a24ad2f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java @@ -1595,7 +1595,7 @@ public class Code { public void compressCatchTable() { - ListBuffer compressedCatchInfo = ListBuffer.lb(); + ListBuffer compressedCatchInfo = new ListBuffer<>(); List handlerPcs = List.nil(); for (char[] catchEntry : catchInfo) { handlerPcs = handlerPcs.prepend((int)catchEntry[2]); diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index ba369172f43..39a59f662ff 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -67,7 +67,6 @@ import com.sun.tools.javac.util.Log.WriterKind; import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.main.Option.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; -import static com.sun.tools.javac.util.ListBuffer.lb; /** This class could be the main entry point for GJC when GJC is used as a @@ -586,7 +585,7 @@ public class JavaCompiler { } protected final Queue stopIfError(CompileState cs, Queue queue) { - return shouldStop(cs) ? ListBuffer.lb() : queue; + return shouldStop(cs) ? new ListBuffer() : queue; } protected final List stopIfError(CompileState cs, List list) { @@ -952,7 +951,7 @@ public class JavaCompiler { return List.nil(); //parse all files - ListBuffer trees = lb(); + ListBuffer trees = new ListBuffer<>(); Set filesSoFar = new HashSet(); for (JavaFileObject fileObject : fileObjects) { if (!filesSoFar.contains(fileObject)) { @@ -1002,7 +1001,7 @@ public class JavaCompiler { // then remember the classes declared in // the original compilation units listed on the command line. if (needRootClasses || sourceOutput || stubOutput) { - ListBuffer cdefs = lb(); + ListBuffer cdefs = new ListBuffer<>(); for (JCCompilationUnit unit : roots) { for (List defs = unit.defs; defs.nonEmpty(); @@ -1226,7 +1225,7 @@ public class JavaCompiler { * @returns a list of environments for attributd classes. */ public Queue> attribute(Queue> envs) { - ListBuffer> results = lb(); + ListBuffer> results = new ListBuffer<>(); while (!envs.isEmpty()) results.append(attribute(envs.remove())); return stopIfError(CompileState.ATTR, results); @@ -1291,7 +1290,7 @@ public class JavaCompiler { * @returns the list of attributed parse trees */ public Queue> flow(Queue> envs) { - ListBuffer> results = lb(); + ListBuffer> results = new ListBuffer<>(); for (Env env: envs) { flow(env, results); } @@ -1302,7 +1301,7 @@ public class JavaCompiler { * Perform dataflow checks on an attributed parse tree. */ public Queue> flow(Env env) { - ListBuffer> results = lb(); + ListBuffer> results = new ListBuffer<>(); flow(env, results); return stopIfError(CompileState.FLOW, results); } @@ -1356,7 +1355,7 @@ public class JavaCompiler { * @returns a list containing the classes to be generated */ public Queue, JCClassDecl>> desugar(Queue> envs) { - ListBuffer, JCClassDecl>> results = lb(); + ListBuffer, JCClassDecl>> results = new ListBuffer<>(); for (Env env: envs) desugar(env, results); return stopIfError(CompileState.FLOW, results); @@ -1605,7 +1604,7 @@ public class JavaCompiler { } @Override public void visitClassDef(JCClassDecl tree) { - ListBuffer newdefs = lb(); + ListBuffer newdefs = new ListBuffer<>(); for (List it = tree.defs; it.tail != null; it = it.tail) { JCTree t = it.head; switch (t.getTag()) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java index a2cd3c55de7..c05662cbcbb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java @@ -207,7 +207,7 @@ public class JavacAnnoConstructs { Attribute[] contained0 = null; if (container != null) contained0 = unpackAttributes(container); - ListBuffer compounds = ListBuffer.lb(); + ListBuffer compounds = new ListBuffer<>(); if (contained0 != null) { for (Attribute a : contained0) if (a instanceof Attribute.Compound) @@ -328,7 +328,7 @@ public class JavacAnnoConstructs { Attribute[] contained0 = null; if (container != null) contained0 = unpackAttributes(container); - ListBuffer compounds = ListBuffer.lb(); + ListBuffer compounds = new ListBuffer<>(); if (contained0 != null) { for (Attribute a : contained0) if (a instanceof Attribute.Compound) diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java index 182f21158ca..57a492f3a3a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -48,7 +48,6 @@ import static com.sun.tools.javac.parser.Tokens.TokenKind.GT; import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT; import static com.sun.tools.javac.parser.Tokens.TokenKind.LT; import static com.sun.tools.javac.tree.JCTree.Tag.*; -import static com.sun.tools.javac.util.ListBuffer.lb; /** The parser maps a token sequence into an abstract syntax * tree. It operates by recursive descent, with code derived @@ -1767,7 +1766,7 @@ public class JavacParser implements Parser { /** Arguments = "(" [Expression { COMMA Expression }] ")" */ List arguments() { - ListBuffer args = lb(); + ListBuffer args = new ListBuffer<>(); if (token.kind == LPAREN) { nextToken(); if (token.kind != RPAREN) { @@ -1834,7 +1833,7 @@ public class JavacParser implements Parser { nextToken(); return List.nil(); } else { - ListBuffer args = ListBuffer.lb(); + ListBuffer args = new ListBuffer<>(); args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); while (token.kind == COMMA) { nextToken(); @@ -2175,7 +2174,7 @@ public class JavacParser implements Parser { ListBuffer dims = new ListBuffer(); // maintain array dimension type annotations - ListBuffer> dimAnnotations = ListBuffer.lb(); + ListBuffer> dimAnnotations = new ListBuffer<>(); dimAnnotations.append(annos); dims.append(parseExpression()); @@ -2626,7 +2625,7 @@ public class JavacParser implements Parser { } List catchTypes() { - ListBuffer catchTypes = ListBuffer.lb(); + ListBuffer catchTypes = new ListBuffer<>(); catchTypes.add(parseType()); while (token.kind == BAR) { checkMulticatch(); @@ -2708,7 +2707,7 @@ public class JavacParser implements Parser { * | { FINAL | '@' Annotation } Type VariableDeclarators */ List forInit() { - ListBuffer stats = lb(); + ListBuffer stats = new ListBuffer<>(); int pos = token.pos; if (token.kind == FINAL || token.kind == MONKEYS_AT) { return variableDeclarators(optFinal(0), parseType(), stats).toList(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java b/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java index d55defedf73..fcb19dcb5fb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -402,7 +402,7 @@ public class Tokens { if (comments == null) { return List.nil(); } else { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Comment c : comments) { if (c.getStyle() == style) { buf.add(c); diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java b/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java index aa9899ed210..f1be519d6c9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java @@ -103,8 +103,8 @@ public class GraphUtils { * directed graph in linear time. Works on TarjanNode. */ public static > List> tarjan(Iterable nodes) { - ListBuffer> cycles = ListBuffer.lb(); - ListBuffer stack = ListBuffer.lb(); + ListBuffer> cycles = new ListBuffer<>(); + ListBuffer stack = new ListBuffer<>(); int index = 0; for (N node: nodes) { if (node.index == -1) { @@ -132,7 +132,7 @@ public class GraphUtils { } if (v.lowlink == v.index) { N n; - ListBuffer cycle = ListBuffer.lb(); + ListBuffer cycle = new ListBuffer<>(); do { n = stack.remove(); n.active = false; diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/List.java b/langtools/src/share/classes/com/sun/tools/javac/util/List.java index dee69807e2c..3ba7d8b59dc 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/List.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/List.java @@ -97,7 +97,7 @@ public class List extends AbstractCollection implements java.util.List } public List intersect(List that) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (A el : this) { if (that.contains(el)) { buf.append(el); @@ -107,7 +107,7 @@ public class List extends AbstractCollection implements java.util.List } public List diff(List that) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (A el : this) { if (!that.contains(el)) { buf.append(el); @@ -120,7 +120,7 @@ public class List extends AbstractCollection implements java.util.List * Create a new list from the first {@code n} elements of this list */ public List take(int n) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); int count = 0; for (A el : this) { if (count++ == n) break; @@ -167,7 +167,7 @@ public class List extends AbstractCollection implements java.util.List } public static List from(Iterable coll) { - ListBuffer xs = ListBuffer.lb(); + ListBuffer xs = new ListBuffer<>(); for (A a : coll) { xs.append(a); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/ListBuffer.java b/langtools/src/share/classes/com/sun/tools/javac/util/ListBuffer.java index 0aa751ffe96..6d9c1ccda55 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/ListBuffer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/ListBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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,10 +40,6 @@ import java.util.NoSuchElementException; */ public class ListBuffer extends AbstractQueue { - public static ListBuffer lb() { - return new ListBuffer(); - } - public static ListBuffer of(T x) { ListBuffer lb = new ListBuffer(); lb.add(x); diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java index 5ed6d784103..d0d9d5934a6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java @@ -123,7 +123,7 @@ public class Log extends AbstractLog { * active diagnostic handler. */ public static class DeferredDiagnosticHandler extends DiagnosticHandler { - private Queue deferred = ListBuffer.lb(); + private Queue deferred = new ListBuffer<>(); private final Filter filter; public DeferredDiagnosticHandler(Log log) { diff --git a/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java b/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java index 7aea2d42476..a398ec1791b 100644 --- a/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java +++ b/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java @@ -237,7 +237,7 @@ public class IntersectionTypeCastTest } static List allCastInfo() { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (CastKind kind : CastKind.values()) { for (ClassKind clazz : ClassKind.values()) { if (kind == CastKind.INTERFACE && clazz != ClassKind.OBJECT) { diff --git a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java index 660721ec849..36e18611ba5 100644 --- a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java +++ b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -196,7 +196,7 @@ public class IntersectionTargetTypeTest { } static List allCastInfo() { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (CastKind kind : CastKind.values()) { for (TypeKind b1 : TypeKind.values()) { if (kind.nbounds == 1) { diff --git a/langtools/test/tools/javac/scope/7017664/CompoundScopeTest.java b/langtools/test/tools/javac/scope/7017664/CompoundScopeTest.java index 075a750a310..e9d44a84d41 100644 --- a/langtools/test/tools/javac/scope/7017664/CompoundScopeTest.java +++ b/langtools/test/tools/javac/scope/7017664/CompoundScopeTest.java @@ -176,7 +176,7 @@ public class CompoundScopeTest { */ void checkElems(CompoundScope cs, Filter sf) { int count = 0; - ListBuffer found = ListBuffer.lb(); + ListBuffer found = new ListBuffer<>(); List allSymbols = sf == null ? elems : filter(elems, sf); @@ -216,7 +216,7 @@ public class CompoundScopeTest { } List filter(List elems, Filter sf) { - ListBuffer res = ListBuffer.lb(); + ListBuffer res = new ListBuffer<>(); for (Symbol s : elems) { if (sf.accepts(s)) { res.append(s); diff --git a/langtools/test/tools/javac/types/TypeHarness.java b/langtools/test/tools/javac/types/TypeHarness.java index a53d94761ba..b4837907820 100644 --- a/langtools/test/tools/javac/types/TypeHarness.java +++ b/langtools/test/tools/javac/types/TypeHarness.java @@ -213,8 +213,8 @@ public class TypeHarness { /** compute a type substitution on 't' given a list of type mappings */ public Type subst(Type t, Mapping... maps) { - ListBuffer from = ListBuffer.lb(); - ListBuffer to = ListBuffer.lb(); + ListBuffer from = new ListBuffer<>(); + ListBuffer to = new ListBuffer<>(); for (Mapping tm : maps) { from.append(tm.from); to.append(tm.to); From 9ca087d6005f02a0425bcdadb6716094292161e4 Mon Sep 17 00:00:00 2001 From: Konstantin Shefov Date: Mon, 23 Sep 2013 16:14:42 +0400 Subject: [PATCH 0466/1294] 8015600: [TEST_BUG] [macosx] Test closed/javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java fails since JDK 8 b75 on MacOSX Reviewed-by: alexsch, serb --- .../basic/BasicMenuUI/4983388/bug4983388.java | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 jdk/test/javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java diff --git a/jdk/test/javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java b/jdk/test/javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java new file mode 100644 index 00000000000..a09a3480f6d --- /dev/null +++ b/jdk/test/javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, 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 4983388 8015600 + @summary shortcuts on menus do not work on JDS + @author Oleg Mokhovikov + @library ../../../../regtesthelpers + @build Util + @run main bug4983388 +*/ + +import sun.awt.*; +import java.awt.*; +import javax.swing.*; +import javax.swing.event.MenuListener; +import javax.swing.event.MenuEvent; +import java.awt.event.KeyEvent; + +public class bug4983388 { + static volatile boolean bMenuSelected = false; + + private static class TestMenuListener implements MenuListener { + public void menuCanceled(MenuEvent e) {} + public void menuDeselected(MenuEvent e) {} + public void menuSelected(MenuEvent e) { + System.out.println("menuSelected"); + bMenuSelected = true; + } + } + + private static void createAndShowGUI() { + JMenuBar menuBar = new JMenuBar(); + JMenu menu = new JMenu("File"); + menu.setMnemonic('F'); + menuBar.add(menu); + JFrame frame = new JFrame(); + frame.setJMenuBar(menuBar); + frame.pack(); + frame.setVisible(true); + MenuListener listener = new TestMenuListener(); + menu.addMenuListener(listener); + } + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); + } catch (UnsupportedLookAndFeelException | ClassNotFoundException ex) { + System.err.println("GTKLookAndFeel is not supported on this platform. Using defailt LaF for this platform."); + } + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + + Robot robot = new Robot(); + Util.hitMnemonics(robot, KeyEvent.VK_F); + + toolkit.realSync(); + + if (!bMenuSelected) { + throw new RuntimeException("shortcuts on menus do not work"); + } + } +} From cac6b55e4ee9aa39108e54c2253d412f6f199db2 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Mon, 23 Sep 2013 16:17:26 +0400 Subject: [PATCH 0467/1294] 8005255: [macosx] Cleanup warnings in sun.lwawt Reviewed-by: alexsch, anthony --- jdk/make/sun/lwawt/FILES_export_macosx.gmk | 1 - .../classes/sun/lwawt/LWButtonPeer.java | 9 +- .../classes/sun/lwawt/LWCanvasPeer.java | 6 +- .../classes/sun/lwawt/LWCheckboxPeer.java | 12 ++- .../classes/sun/lwawt/LWChoicePeer.java | 7 +- .../classes/sun/lwawt/LWComponentPeer.java | 90 ++++++++++------- .../classes/sun/lwawt/LWContainerPeer.java | 97 +++++++++---------- .../classes/sun/lwawt/LWCursorManager.java | 6 +- .../macosx/classes/sun/lwawt/LWLabelPeer.java | 4 +- .../macosx/classes/sun/lwawt/LWListPeer.java | 16 +-- .../classes/sun/lwawt/LWMouseInfoPeer.java | 9 +- .../macosx/classes/sun/lwawt/LWPanelPeer.java | 8 +- .../classes/sun/lwawt/LWRepaintArea.java | 25 +++-- .../classes/sun/lwawt/LWScrollBarPeer.java | 8 +- .../classes/sun/lwawt/LWScrollPanePeer.java | 20 ++-- .../classes/sun/lwawt/LWTextAreaPeer.java | 13 ++- .../sun/lwawt/LWTextComponentPeer.java | 11 ++- .../classes/sun/lwawt/LWTextFieldPeer.java | 11 ++- .../macosx/classes/sun/lwawt/LWToolkit.java | 14 +-- .../classes/sun/lwawt/LWWindowPeer.java | 41 +++++--- .../sun/lwawt/SelectionClearListener.java | 34 ------- 21 files changed, 237 insertions(+), 205 deletions(-) delete mode 100644 jdk/src/macosx/classes/sun/lwawt/SelectionClearListener.java diff --git a/jdk/make/sun/lwawt/FILES_export_macosx.gmk b/jdk/make/sun/lwawt/FILES_export_macosx.gmk index 0750201e9ec..7b32f911c21 100644 --- a/jdk/make/sun/lwawt/FILES_export_macosx.gmk +++ b/jdk/make/sun/lwawt/FILES_export_macosx.gmk @@ -110,7 +110,6 @@ FILES_export = \ sun/lwawt/LWWindowPeer.java \ sun/lwawt/PlatformWindow.java \ sun/lwawt/SecurityWarningWindow.java \ - sun/lwawt/SelectionClearListener.java \ sun/lwawt/macosx/CPrinterDevice.java \ sun/lwawt/macosx/CPrinterDialog.java \ sun/lwawt/macosx/CPrinterDialogPeer.java \ diff --git a/jdk/src/macosx/classes/sun/lwawt/LWButtonPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWButtonPeer.java index e5f8838c8cd..f4b46c7639a 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWButtonPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWButtonPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,10 @@ import java.awt.peer.ButtonPeer; import javax.swing.JButton; +/** + * Lightweight implementation of {@link ButtonPeer}. Delegates most of the work + * to the {@link JButton}. + */ final class LWButtonPeer extends LWComponentPeer implements ButtonPeer, ActionListener { @@ -42,7 +46,7 @@ final class LWButtonPeer extends LWComponentPeer } @Override - protected JButton createDelegate() { + JButton createDelegate() { return new JButtonDelegate(); } @@ -74,6 +78,7 @@ final class LWButtonPeer extends LWComponentPeer return true; } + @SuppressWarnings("serial")// Safe: outer class is non-serializable. private final class JButtonDelegate extends JButton { // Empty non private constructor was added because access to this diff --git a/jdk/src/macosx/classes/sun/lwawt/LWCanvasPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWCanvasPeer.java index 0c80ff0af0d..c7559c216c6 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWCanvasPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWCanvasPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,10 @@ import java.awt.peer.CanvasPeer; import javax.swing.JComponent; +/** + * Lightweight implementation of {@link CanvasPeer}. This peer is empty, because + * all the components in lwawt use graphic object from the top level window. + */ class LWCanvasPeer extends LWComponentPeer implements CanvasPeer { diff --git a/jdk/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java index de1c378b860..c3b91a2fa86 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,11 @@ import javax.swing.JRadioButton; import javax.swing.JToggleButton; import javax.swing.SwingUtilities; +/** + * Lightweight implementation of {@link CheckboxPeer}. Delegates most of the + * work to the {@link JCheckBox} and {@link JRadioButton}, which are placed + * inside an empty {@link JComponent}. + */ final class LWCheckboxPeer extends LWComponentPeer implements CheckboxPeer, ItemListener { @@ -51,12 +56,12 @@ final class LWCheckboxPeer } @Override - protected CheckboxDelegate createDelegate() { + CheckboxDelegate createDelegate() { return new CheckboxDelegate(); } @Override - protected Component getDelegateFocusOwner() { + Component getDelegateFocusOwner() { return getDelegate().getCurrentButton(); } @@ -137,6 +142,7 @@ final class LWCheckboxPeer return true; } + @SuppressWarnings("serial")// Safe: outer class is non-serializable. final class CheckboxDelegate extends JComponent { private final JCheckBox cb; diff --git a/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java b/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java index c90300e8dcf..5b78e74b6a2 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java @@ -34,6 +34,10 @@ import java.awt.peer.ChoicePeer; import javax.accessibility.Accessible; import javax.swing.*; +/** + * Lightweight implementation of {@link ChoicePeer}. Delegates most of the work + * to the {@link JComboBox}. + */ final class LWChoicePeer extends LWComponentPeer> implements ChoicePeer, ItemListener { @@ -50,7 +54,7 @@ final class LWChoicePeer extends LWComponentPeer> } @Override - protected JComboBox createDelegate() { + JComboBox createDelegate() { return new JComboBoxDelegate(); } @@ -128,6 +132,7 @@ final class LWChoicePeer extends LWComponentPeer> return true; } + @SuppressWarnings("serial")// Safe: outer class is non-serializable. private final class JComboBoxDelegate extends JComboBox { // Empty non private constructor was added because access to this diff --git a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java index 5b081b1f2f2..f6adcda7fde 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,19 +72,23 @@ public abstract class LWComponentPeer { private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWComponentPeer"); - // State lock is to be used for modifications to this - // peer's fields (e.g. bounds, background, font, etc.) - // It should be the last lock in the lock chain - private final Object stateLock = - new StringBuilder("LWComponentPeer.stateLock"); + /** + * State lock is to be used for modifications to this peer's fields (e.g. + * bounds, background, font, etc.) It should be the last lock in the lock + * chain + */ + private final Object stateLock = new Object(); - // The lock to operate with the peers hierarchy. AWT tree - // lock is not used as there are many peers related ops - // to be done on the toolkit thread, and we don't want to - // depend on a public lock on this thread - private static final Object peerTreeLock = - new StringBuilder("LWComponentPeer.peerTreeLock"); + /** + * The lock to operate with the peers hierarchy. AWT tree lock is not used + * as there are many peers related ops to be done on the toolkit thread, and + * we don't want to depend on a public lock on this thread + */ + private static final Object peerTreeLock = new Object(); + /** + * The associated AWT object. + */ private final T target; /** @@ -95,7 +99,7 @@ public abstract class LWComponentPeer * the hierarchy. The exception is LWWindowPeers: their containers are * always null */ - private final LWContainerPeer containerPeer; + private final LWContainerPeer containerPeer; /** * Handy reference to the top-level window peer. Window peer is borrowed @@ -147,11 +151,18 @@ public abstract class LWComponentPeer */ private Image backBuffer; + /** + * All Swing delegates use delegateContainer as a parent. This container + * intentionally do not use parent of the peer. + */ + @SuppressWarnings("serial")// Safe: outer class is non-serializable. private final class DelegateContainer extends Container { { enableEvents(0xFFFFFFFF); } + // Empty non private constructor was added because access to this + // class shouldn't be emulated by a synthetic accessor method. DelegateContainer() { super(); } @@ -182,7 +193,7 @@ public abstract class LWComponentPeer } } - public LWComponentPeer(T target, PlatformComponent platformComponent) { + LWComponentPeer(final T target, final PlatformComponent platformComponent) { targetPaintArea = new LWRepaintArea(); this.target = target; this.platformComponent = platformComponent; @@ -276,15 +287,18 @@ public abstract class LWComponentPeer * This method is called under getDelegateLock(). * Overridden in subclasses. */ - protected D createDelegate() { + D createDelegate() { return null; } - protected final D getDelegate() { + final D getDelegate() { return delegate; } - protected Component getDelegateFocusOwner() { + /** + * This method should be called under getDelegateLock(). + */ + Component getDelegateFocusOwner() { return getDelegate(); } @@ -356,7 +370,7 @@ public abstract class LWComponentPeer } // Just a helper method - protected final LWContainerPeer getContainerPeer() { + protected final LWContainerPeer getContainerPeer() { return containerPeer; } @@ -390,7 +404,7 @@ public abstract class LWComponentPeer protected void disposeImpl() { destroyBuffers(); - LWContainerPeer cp = getContainerPeer(); + LWContainerPeer cp = getContainerPeer(); if (cp != null) { cp.removeChildPeer(this); } @@ -462,12 +476,13 @@ public abstract class LWComponentPeer sg2d.constrain(size.x, size.y, size.width, size.height, getVisibleRegion()); } - public Region getVisibleRegion() { + Region getVisibleRegion() { return computeVisibleRect(this, getRegion()); } - static final Region computeVisibleRect(LWComponentPeer c, Region region) { - final LWContainerPeer p = c.getContainerPeer(); + static final Region computeVisibleRect(final LWComponentPeer c, + Region region) { + final LWContainerPeer p = c.getContainerPeer(); if (p != null) { final Rectangle r = c.getBounds(); region = region.getTranslatedRegion(r.x, r.y); @@ -612,7 +627,7 @@ public abstract class LWComponentPeer * @param p Point relative to the peer. * @return Cursor of the peer or null if default cursor should be used. */ - protected Cursor getCursor(final Point p) { + Cursor getCursor(final Point p) { return getTarget().getCursor(); } @@ -717,7 +732,7 @@ public abstract class LWComponentPeer @Override public void setEnabled(final boolean e) { boolean status = e; - final LWComponentPeer cp = getContainerPeer(); + final LWComponentPeer cp = getContainerPeer(); if (cp != null) { status &= cp.isEnabled(); } @@ -802,12 +817,12 @@ public abstract class LWComponentPeer } @Override - public void setZOrder(ComponentPeer above) { - LWContainerPeer cp = getContainerPeer(); + public void setZOrder(final ComponentPeer above) { + LWContainerPeer cp = getContainerPeer(); // Don't check containerPeer for null as it can only happen // for windows, but this method is overridden in // LWWindowPeer and doesn't call super() - cp.setChildPeerZOrder(this, (LWComponentPeer) above); + cp.setChildPeerZOrder(this, (LWComponentPeer) above); } @Override @@ -923,7 +938,9 @@ public abstract class LWComponentPeer LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget()); return false; } - LWWindowPeer parentPeer = (LWWindowPeer) parentWindow.getPeer(); + final LWWindowPeer parentPeer = + (LWWindowPeer) AWTAccessor.getComponentAccessor() + .getPeer(parentWindow); if (parentPeer == null) { focusLog.fine("request rejected, parentPeer is null"); LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget()); @@ -1138,7 +1155,7 @@ public abstract class LWComponentPeer } protected final void repaintParent(final Rectangle oldB) { - final LWContainerPeer cp = getContainerPeer(); + final LWContainerPeer cp = getContainerPeer(); if (cp != null) { // Repaint unobscured part of the parent cp.repaintPeer(cp.getContentSize().intersection(oldB)); @@ -1275,7 +1292,7 @@ public abstract class LWComponentPeer /** * Handler for FocusEvents. */ - protected void handleJavaFocusEvent(FocusEvent e) { + void handleJavaFocusEvent(final FocusEvent e) { // Note that the peer receives all the FocusEvents from // its lightweight children as well KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance(); @@ -1311,7 +1328,7 @@ public abstract class LWComponentPeer * Finds a top-most visible component for the given point. The location is * specified relative to the peer's parent. */ - public LWComponentPeer findPeerAt(final int x, final int y) { + LWComponentPeer findPeerAt(final int x, final int y) { final Rectangle r = getBounds(); final Region sh = getRegion(); final boolean found = isVisible() && sh.contains(x - r.x, y - r.y); @@ -1328,7 +1345,7 @@ public abstract class LWComponentPeer } public Point windowToLocal(Point p, LWWindowPeer wp) { - LWComponentPeer cp = this; + LWComponentPeer cp = this; while (cp != wp) { Rectangle cpb = cp.getBounds(); p.x -= cpb.x; @@ -1349,7 +1366,7 @@ public abstract class LWComponentPeer } public Point localToWindow(Point p) { - LWComponentPeer cp = getContainerPeer(); + LWComponentPeer cp = getContainerPeer(); Rectangle r = getBounds(); while (cp != null) { p.x += r.x; @@ -1370,7 +1387,7 @@ public abstract class LWComponentPeer repaintPeer(getSize()); } - public void repaintPeer(final Rectangle r) { + void repaintPeer(final Rectangle r) { final Rectangle toPaint = getSize().intersection(r); if (!isShowing() || toPaint.isEmpty()) { return; @@ -1389,7 +1406,7 @@ public abstract class LWComponentPeer protected final boolean isShowing() { synchronized (getPeerTreeLock()) { if (isVisible()) { - final LWContainerPeer container = getContainerPeer(); + final LWContainerPeer container = getContainerPeer(); return (container == null) || container.isShowing(); } } @@ -1397,8 +1414,7 @@ public abstract class LWComponentPeer } /** - * Paints the peer. Overridden in subclasses to delegate the actual painting - * to Swing components. + * Paints the peer. Delegate the actual painting to Swing components. */ protected final void paintPeer(final Graphics g) { final D delegate = getDelegate(); diff --git a/jdk/src/macosx/classes/sun/lwawt/LWContainerPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWContainerPeer.java index c213664b8ce..3069d3c2a3b 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWContainerPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWContainerPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,32 +41,25 @@ import java.util.List; import javax.swing.JComponent; abstract class LWContainerPeer - extends LWCanvasPeer - implements ContainerPeer -{ - // List of child peers sorted by z-order from bottom-most - // to top-most - private List childPeers = - new LinkedList(); + extends LWCanvasPeer implements ContainerPeer { - LWContainerPeer(T target, PlatformComponent platformComponent) { + /** + * List of child peers sorted by z-order from bottom-most to top-most. + */ + private final List> childPeers = new LinkedList<>(); + + LWContainerPeer(final T target, final PlatformComponent platformComponent) { super(target, platformComponent); } - void addChildPeer(LWComponentPeer child) { + final void addChildPeer(final LWComponentPeer child) { synchronized (getPeerTreeLock()) { - addChildPeer(child, childPeers.size()); + childPeers.add(childPeers.size(), child); + // TODO: repaint } } - void addChildPeer(LWComponentPeer child, int index) { - synchronized (getPeerTreeLock()) { - childPeers.add(index, child); - } - // TODO: repaint - } - - void removeChildPeer(LWComponentPeer child) { + final void removeChildPeer(final LWComponentPeer child) { synchronized (getPeerTreeLock()) { childPeers.remove(child); } @@ -74,7 +67,8 @@ abstract class LWContainerPeer } // Used by LWComponentPeer.setZOrder() - void setChildPeerZOrder(LWComponentPeer peer, LWComponentPeer above) { + final void setChildPeerZOrder(final LWComponentPeer peer, + final LWComponentPeer above) { synchronized (getPeerTreeLock()) { childPeers.remove(peer); int index = (above != null) ? childPeers.indexOf(above) : childPeers.size(); @@ -98,25 +92,27 @@ abstract class LWContainerPeer } @Override - public void beginValidate() { - // TODO: it seems that begin/endValidate() is only useful - // for heavyweight windows, when a batch movement for - // child windows occurs. That's why no-op - } - @Override - public void endValidate() { + public final void beginValidate() { // TODO: it seems that begin/endValidate() is only useful // for heavyweight windows, when a batch movement for // child windows occurs. That's why no-op } @Override - public void beginLayout() { + public final void endValidate() { + // TODO: it seems that begin/endValidate() is only useful + // for heavyweight windows, when a batch movement for + // child windows occurs. That's why no-op + } + + @Override + public final void beginLayout() { // Skip all painting till endLayout() setLayouting(true); } + @Override - public void endLayout() { + public final void endLayout() { setLayouting(false); // Post an empty event to flush all the pending target paints @@ -125,18 +121,19 @@ abstract class LWContainerPeer // ---- PEER NOTIFICATIONS ---- // - /* + /** * Returns a copy of the childPeer collection. */ - protected List getChildren() { + @SuppressWarnings("unchecked") + final List> getChildren() { synchronized (getPeerTreeLock()) { - Object copy = ((LinkedList)childPeers).clone(); - return (List)copy; + Object copy = ((LinkedList) childPeers).clone(); + return (List>) copy; } } @Override - public final Region getVisibleRegion() { + final Region getVisibleRegion() { return cutChildren(super.getVisibleRegion(), null); } @@ -144,9 +141,9 @@ abstract class LWContainerPeer * Removes bounds of children above specific child from the region. If above * is null removes all bounds of children. */ - protected final Region cutChildren(Region r, final LWComponentPeer above) { + final Region cutChildren(Region r, final LWComponentPeer above) { boolean aboveFound = above == null; - for (final LWComponentPeer child : getChildren()) { + for (final LWComponentPeer child : getChildren()) { if (!aboveFound && child == above) { aboveFound = true; continue; @@ -170,8 +167,8 @@ abstract class LWContainerPeer * specified relative to the peer's parent. */ @Override - public final LWComponentPeer findPeerAt(int x, int y) { - LWComponentPeer peer = super.findPeerAt(x, y); + final LWComponentPeer findPeerAt(int x, int y) { + LWComponentPeer peer = super.findPeerAt(x, y); final Rectangle r = getBounds(); // Translate to this container's coordinates to pass to children x -= r.x; @@ -179,7 +176,7 @@ abstract class LWContainerPeer if (peer != null && getContentSize().contains(x, y)) { synchronized (getPeerTreeLock()) { for (int i = childPeers.size() - 1; i >= 0; --i) { - LWComponentPeer p = childPeers.get(i).findPeerAt(x, y); + LWComponentPeer p = childPeers.get(i).findPeerAt(x, y); if (p != null) { peer = p; break; @@ -195,7 +192,7 @@ abstract class LWContainerPeer * peers should be repainted */ @Override - public final void repaintPeer(final Rectangle r) { + final void repaintPeer(final Rectangle r) { final Rectangle toPaint = getSize().intersection(r); if (!isShowing() || toPaint.isEmpty()) { return; @@ -208,13 +205,13 @@ abstract class LWContainerPeer repaintChildren(toPaint); } - /* - * Paints all the child peers in the straight z-order, so the - * bottom-most ones are painted first. - */ + /** + * Paints all the child peers in the straight z-order, so the + * bottom-most ones are painted first. + */ private void repaintChildren(final Rectangle r) { final Rectangle content = getContentSize(); - for (final LWComponentPeer child : getChildren()) { + for (final LWComponentPeer child : getChildren()) { final Rectangle childBounds = child.getBounds(); Rectangle toPaint = r.intersection(childBounds); toPaint = toPaint.intersection(content); @@ -223,21 +220,21 @@ abstract class LWContainerPeer } } - protected Rectangle getContentSize() { + Rectangle getContentSize() { return getSize(); } @Override public void setEnabled(final boolean e) { super.setEnabled(e); - for (final LWComponentPeer child : getChildren()) { + for (final LWComponentPeer child : getChildren()) { child.setEnabled(e && child.getTarget().isEnabled()); } } @Override public void setBackground(final Color c) { - for (final LWComponentPeer child : getChildren()) { + for (final LWComponentPeer child : getChildren()) { if (!child.getTarget().isBackgroundSet()) { child.setBackground(c); } @@ -247,7 +244,7 @@ abstract class LWContainerPeer @Override public void setForeground(final Color c) { - for (final LWComponentPeer child : getChildren()) { + for (final LWComponentPeer child : getChildren()) { if (!child.getTarget().isForegroundSet()) { child.setForeground(c); } @@ -257,7 +254,7 @@ abstract class LWContainerPeer @Override public void setFont(final Font f) { - for (final LWComponentPeer child : getChildren()) { + for (final LWComponentPeer child : getChildren()) { if (!child.getTarget().isFontSet()) { child.setFont(f); } diff --git a/jdk/src/macosx/classes/sun/lwawt/LWCursorManager.java b/jdk/src/macosx/classes/sun/lwawt/LWCursorManager.java index de1b537856a..ee9d0dd572e 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWCursorManager.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWCursorManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -32,6 +32,7 @@ import java.awt.Point; import java.util.concurrent.atomic.AtomicBoolean; +import sun.awt.AWTAccessor; import sun.awt.SunToolkit; public abstract class LWCursorManager { @@ -109,7 +110,8 @@ public abstract class LWCursorManager { cursorPos.y - p.y); } while (c != null) { - if (c.isVisible() && c.isEnabled() && (c.getPeer() != null)) { + final Object p = AWTAccessor.getComponentAccessor().getPeer(c); + if (c.isVisible() && c.isEnabled() && p != null) { break; } c = c.getParent(); diff --git a/jdk/src/macosx/classes/sun/lwawt/LWLabelPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWLabelPeer.java index 19743da74a3..68af14af333 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWLabelPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWLabelPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ final class LWLabelPeer extends LWComponentPeer } @Override - protected JLabel createDelegate() { + JLabel createDelegate() { return new JLabel(); } diff --git a/jdk/src/macosx/classes/sun/lwawt/LWListPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWListPeer.java index 5edb8e16cd0..e6e1ec38c3d 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWListPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWListPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,8 @@ import java.awt.peer.ListPeer; import java.util.Arrays; /** - * Lightweight implementation of {@link ListPeer}. + * Lightweight implementation of {@link ListPeer}. Delegates most of the work to + * the {@link JList}, which is placed inside {@link JScrollPane}. */ final class LWListPeer extends LWComponentPeer implements ListPeer { @@ -56,7 +57,7 @@ final class LWListPeer extends LWComponentPeer } @Override - protected ScrollableJList createDelegate() { + ScrollableJList createDelegate() { return new ScrollableJList(); } @@ -78,7 +79,7 @@ final class LWListPeer extends LWComponentPeer } @Override - protected Component getDelegateFocusOwner() { + Component getDelegateFocusOwner() { return getDelegate().getView(); } @@ -193,6 +194,7 @@ final class LWListPeer extends LWComponentPeer } } + @SuppressWarnings("serial")// Safe: outer class is non-serializable. final class ScrollableJList extends JScrollPane implements ListSelectionListener { private boolean skipStateChangedEvent; @@ -234,9 +236,10 @@ final class LWListPeer extends LWComponentPeer } @Override + @SuppressWarnings("unchecked") public void valueChanged(final ListSelectionEvent e) { if (!e.getValueIsAdjusting() && !isSkipStateChangedEvent()) { - final JList source = (JList) e.getSource(); + final JList source = (JList) e.getSource(); for(int i = 0 ; i < source.getModel().getSize(); i++) { final boolean wasSelected = Arrays.binarySearch(oldSelectedIndices, i) >= 0; @@ -255,6 +258,7 @@ final class LWListPeer extends LWComponentPeer } } + @SuppressWarnings("unchecked") public JList getView() { return (JList) getViewport().getView(); } @@ -289,7 +293,7 @@ final class LWListPeer extends LWComponentPeer private final class JListDelegate extends JList { JListDelegate() { - super(ScrollableJList.this.model); + super(model); } @Override diff --git a/jdk/src/macosx/classes/sun/lwawt/LWMouseInfoPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWMouseInfoPeer.java index 2cce1b17269..1920a73d3b0 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWMouseInfoPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWMouseInfoPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,10 +30,9 @@ import java.awt.Window; import java.awt.peer.MouseInfoPeer; -public class LWMouseInfoPeer implements MouseInfoPeer { +import sun.awt.AWTAccessor; - public LWMouseInfoPeer() { - } +public class LWMouseInfoPeer implements MouseInfoPeer { @Override public int fillPointWithCoords(Point point) { @@ -52,7 +51,7 @@ public class LWMouseInfoPeer implements MouseInfoPeer { return false; } - LWWindowPeer windowPeer = (LWWindowPeer)w.getPeer(); + final Object windowPeer = AWTAccessor.getComponentAccessor().getPeer(w); return LWWindowPeer.getWindowUnderCursor() == windowPeer; } diff --git a/jdk/src/macosx/classes/sun/lwawt/LWPanelPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWPanelPeer.java index 6b1f48b08ad..ef1e93e8b11 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWPanelPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWPanelPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,10 @@ import java.awt.peer.PanelPeer; import javax.swing.JPanel; +/** + * Lightweight implementation of {@link PanelPeer}. Delegates most of the work + * to the {@link JPanel}. + */ final class LWPanelPeer extends LWContainerPeer implements PanelPeer { @@ -39,7 +43,7 @@ final class LWPanelPeer extends LWContainerPeer } @Override - public JPanel createDelegate() { + JPanel createDelegate() { return new JPanel(); } } diff --git a/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java b/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java index e67b2fa435e..7b7c7e8b67d 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,39 +26,38 @@ package sun.lwawt; -import sun.awt.RepaintArea; - import java.awt.Component; import java.awt.Graphics; +import sun.awt.AWTAccessor; +import sun.awt.RepaintArea; + /** + * Emulates appearance of heavyweight components before call of the user code. + * * @author Sergey Bylokhov */ final class LWRepaintArea extends RepaintArea { @Override protected void updateComponent(final Component comp, final Graphics g) { + // We shouldn't paint native component as a result of UPDATE events, + // just flush onscreen back-buffer. if (comp != null) { super.updateComponent(comp, g); - flushBuffers((LWComponentPeer) comp.getPeer()); + LWComponentPeer.flushOnscreenGraphics(); } } @Override protected void paintComponent(final Component comp, final Graphics g) { if (comp != null) { - final LWComponentPeer peer = (LWComponentPeer) comp.getPeer(); + Object peer = AWTAccessor.getComponentAccessor().getPeer(comp); if (peer != null) { - peer.paintPeer(g); + ((LWComponentPeer) peer).paintPeer(g); } super.paintComponent(comp, g); - flushBuffers(peer); - } - } - - private static void flushBuffers(final LWComponentPeer peer) { - if (peer != null) { - peer.flushOnscreenGraphics(); + LWComponentPeer.flushOnscreenGraphics(); } } } diff --git a/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java index f5cb0d576e6..6fce0d58461 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java @@ -34,10 +34,14 @@ import java.awt.peer.ScrollbarPeer; import javax.swing.JScrollBar; +/** + * Lightweight implementation of {@link ScrollbarPeer}. Delegates most of the + * work to the {@link JScrollBar}. + */ final class LWScrollBarPeer extends LWComponentPeer implements ScrollbarPeer, AdjustmentListener { - //JScrollBar fires two changes with firePropertyChange (one for old value + // JScrollBar fires two changes with firePropertyChange (one for old value // and one for new one. // We save the last value and don't fire event if not changed. private int currentValue; @@ -48,7 +52,7 @@ final class LWScrollBarPeer extends LWComponentPeer } @Override - protected JScrollBar createDelegate() { + JScrollBar createDelegate() { return new JScrollBar(); } diff --git a/jdk/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java b/jdk/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java index 723a9dd8da7..4db7cac124a 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,10 @@ import java.awt.event.MouseWheelEvent; import java.awt.peer.ScrollPanePeer; import java.util.List; +/** + * Lightweight implementation of {@link ScrollPanePeer}. Delegates most of the + * work to the {@link JScrollPane}. + */ final class LWScrollPanePeer extends LWContainerPeer implements ScrollPanePeer, ChangeListener { @@ -41,7 +45,8 @@ final class LWScrollPanePeer extends LWContainerPeer super(target, platformComponent); } - protected JScrollPane createDelegate() { + @Override + JScrollPane createDelegate() { final JScrollPane sp = new JScrollPane(); final JPanel panel = new JPanel(); panel.setOpaque(false); @@ -72,7 +77,7 @@ final class LWScrollPanePeer extends LWContainerPeer SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - final LWComponentPeer viewPeer = getViewPeer(); + final LWComponentPeer viewPeer = getViewPeer(); if (viewPeer != null) { final Rectangle r; synchronized (getDelegateLock()) { @@ -96,14 +101,13 @@ final class LWScrollPanePeer extends LWContainerPeer } } - LWComponentPeer getViewPeer() { - List peerList = getChildren(); + LWComponentPeer getViewPeer() { + final List> peerList = getChildren(); return peerList.isEmpty() ? null : peerList.get(0); } - @Override - protected Rectangle getContentSize() { + Rectangle getContentSize() { Rectangle viewRect = getDelegate().getViewport().getViewRect(); return new Rectangle(viewRect.width, viewRect.height); } @@ -112,7 +116,7 @@ final class LWScrollPanePeer extends LWContainerPeer public void layout() { super.layout(); synchronized (getDelegateLock()) { - LWComponentPeer viewPeer = getViewPeer(); + final LWComponentPeer viewPeer = getViewPeer(); if (viewPeer != null) { Component view = getDelegate().getViewport().getView(); view.setBounds(viewPeer.getBounds()); diff --git a/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java index 98032e20c29..5db1b6ca296 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ import javax.swing.text.JTextComponent; /** * Lightweight implementation of {@link TextAreaPeer}. Delegates most of the - * work to the {@link JTextArea} inside JScrollPane. + * work to the {@link JTextArea} inside {@link JScrollPane}. */ final class LWTextAreaPeer extends LWTextComponentPeer @@ -66,7 +66,7 @@ final class LWTextAreaPeer } @Override - protected ScrollableJTextArea createDelegate() { + ScrollableJTextArea createDelegate() { return new ScrollableJTextArea(); } @@ -85,7 +85,7 @@ final class LWTextAreaPeer } @Override - protected Cursor getCursor(final Point p) { + Cursor getCursor(final Point p) { final boolean isContains; synchronized (getDelegateLock()) { isContains = getDelegate().getViewport().getBounds().contains(p); @@ -94,7 +94,7 @@ final class LWTextAreaPeer } @Override - protected Component getDelegateFocusOwner() { + Component getDelegateFocusOwner() { return getTextComponent(); } @@ -200,7 +200,7 @@ final class LWTextAreaPeer } } - @SuppressWarnings("serial") + @SuppressWarnings("serial")// Safe: outer class is non-serializable. final class ScrollableJTextArea extends JScrollPane { ScrollableJTextArea() { @@ -218,7 +218,6 @@ final class LWTextAreaPeer super.setEnabled(enabled); } - @SuppressWarnings("serial") private final class JTextAreaDelegate extends JTextArea { // Empty non private constructor was added because access to this diff --git a/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java index aab0baf43e0..860aa546610 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,11 +44,14 @@ import javax.swing.event.DocumentListener; import javax.swing.text.Document; import javax.swing.text.JTextComponent; +/** + * Lightweight implementation of {@link TextComponentPeer}. Provides useful + * methods for {@link LWTextAreaPeer} and {@link LWTextFieldPeer} + */ abstract class LWTextComponentPeer extends LWComponentPeer implements DocumentListener, TextComponentPeer, InputMethodListener { - private volatile boolean firstChangeSkipped; LWTextComponentPeer(final T target, @@ -218,14 +221,14 @@ abstract class LWTextComponentPeer implements TextFieldPeer, ActionListener { @@ -47,7 +51,7 @@ final class LWTextFieldPeer } @Override - protected JPasswordField createDelegate() { + JPasswordField createDelegate() { return new JPasswordFieldDelegate(); } @@ -107,7 +111,7 @@ final class LWTextFieldPeer * @param e the focus event */ @Override - protected void handleJavaFocusEvent(final FocusEvent e) { + void handleJavaFocusEvent(final FocusEvent e) { if (e.getID() == FocusEvent.FOCUS_LOST) { // In order to de-select the selection setCaretPosition(0); @@ -115,6 +119,7 @@ final class LWTextFieldPeer super.handleJavaFocusEvent(e); } + @SuppressWarnings("serial")// Safe: outer class is non-serializable. private final class JPasswordFieldDelegate extends JPasswordField { // Empty non private constructor was added because access to this diff --git a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java index 9765066d9d2..f98dffbf3f1 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java @@ -557,16 +557,18 @@ public abstract class LWToolkit extends SunToolkit implements Runnable { } @Override - public void grab(Window w) { - if (w.getPeer() != null) { - ((LWWindowPeer)w.getPeer()).grab(); + public void grab(final Window w) { + final Object peer = AWTAccessor.getComponentAccessor().getPeer(w); + if (peer != null) { + ((LWWindowPeer) peer).grab(); } } @Override - public void ungrab(Window w) { - if (w.getPeer() != null) { - ((LWWindowPeer)w.getPeer()).ungrab(false); + public void ungrab(final Window w) { + final Object peer = AWTAccessor.getComponentAccessor().getPeer(w); + if (peer != null) { + ((LWWindowPeer) peer).ungrab(false); } } diff --git a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java index 6000016306a..632fe844e7b 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java @@ -43,7 +43,7 @@ public class LWWindowPeer extends LWContainerPeer implements FramePeer, DialogPeer, FullScreenCapable, DisplayChangedListener, PlatformEventNotifier { - public static enum PeerType { + public enum PeerType { SIMPLEWINDOW, FRAME, DIALOG, @@ -83,15 +83,15 @@ public class LWWindowPeer // A peer where the last mouse event came to. Used by cursor manager to // find the component under cursor - private static volatile LWComponentPeer lastCommonMouseEventPeer = null; + private static volatile LWComponentPeer lastCommonMouseEventPeer; // A peer where the last mouse event came to. Used to generate // MOUSE_ENTERED/EXITED notifications - private volatile LWComponentPeer lastMouseEventPeer; + private volatile LWComponentPeer lastMouseEventPeer; // Peers where all dragged/released events should come to, // depending on what mouse button is being dragged according to Cocoa - private static LWComponentPeer mouseDownTarget[] = new LWComponentPeer[3]; + private static final LWComponentPeer[] mouseDownTarget = new LWComponentPeer[3]; // A bitmask that indicates what mouse buttons produce MOUSE_CLICKED events // on MOUSE_RELEASE. Click events are only generated if there were no drag @@ -129,7 +129,8 @@ public class LWWindowPeer this.peerType = peerType; Window owner = target.getOwner(); - LWWindowPeer ownerPeer = (owner != null) ? (LWWindowPeer)owner.getPeer() : null; + LWWindowPeer ownerPeer = owner == null ? null : + (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(owner); PlatformWindow ownerDelegate = (ownerPeer != null) ? ownerPeer.getPlatformWindow() : null; // The delegate.initialize() needs a non-null GC on X11. @@ -163,10 +164,10 @@ public class LWWindowPeer // Init warning window(for applets) SecurityWarningWindow warn = null; - if (((Window)target).getWarningString() != null) { + if (target.getWarningString() != null) { // accessSystemTray permission allows to display TrayIcon, TrayIcon tooltip // and TrayIcon balloon windows without a warning window. - if (!AWTAccessor.getWindowAccessor().isTrayIconWindow((Window)target)) { + if (!AWTAccessor.getWindowAccessor().isTrayIconWindow(target)) { LWToolkit toolkit = (LWToolkit)Toolkit.getDefaultToolkit(); warn = toolkit.createSecurityWarning(target, this); } @@ -210,6 +211,7 @@ public class LWWindowPeer } // Just a helper method + @Override public PlatformWindow getPlatformWindow() { return platformWindow; } @@ -391,7 +393,8 @@ public class LWWindowPeer @Override public void setModalBlocked(Dialog blocker, boolean blocked) { synchronized (getPeerTreeLock()) { - this.blocker = blocked ? (LWWindowPeer)blocker.getPeer() : null; + this.blocker = !blocked ? null : + (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(blocker); } platformWindow.setModalBlocked(blocked); @@ -458,6 +461,7 @@ public class LWWindowPeer textured = isTextured; } + @Override public final boolean isTranslucent() { synchronized (getStateLock()) { /* @@ -537,7 +541,8 @@ public class LWWindowPeer public void blockWindows(List windows) { //TODO: LWX will probably need some collectJavaToplevels to speed this up for (Window w : windows) { - WindowPeer wp = (WindowPeer)w.getPeer(); + WindowPeer wp = + (WindowPeer) AWTAccessor.getComponentAccessor().getPeer(w); if (wp != null) { wp.setModalBlocked((Dialog)getTarget(), true); } @@ -694,7 +699,7 @@ public class LWWindowPeer // TODO: fill "bdata" member of AWTEvent Rectangle r = getBounds(); // findPeerAt() expects parent coordinates - LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y); + LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y); if (id == MouseEvent.MOUSE_EXITED) { isMouseOver = false; @@ -743,7 +748,7 @@ public class LWWindowPeer screenX, screenY, modifiers, clickCount, popupTrigger, targetPeer); } else { - LWComponentPeer topmostTargetPeer = + LWComponentPeer topmostTargetPeer = topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null; topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y, screenX, screenY, modifiers, clickCount, popupTrigger, @@ -840,7 +845,7 @@ public class LWWindowPeer private void generateMouseEnterExitEventsForComponents(long when, int button, int x, int y, int screenX, int screenY, int modifiers, int clickCount, boolean popupTrigger, - LWComponentPeer targetPeer) { + final LWComponentPeer targetPeer) { if (!isMouseOver || targetPeer == lastMouseEventPeer) { return; @@ -899,7 +904,7 @@ public class LWWindowPeer // TODO: could we just use the last mouse event target here? Rectangle r = getBounds(); // findPeerAt() expects parent coordinates - final LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y); + final LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y); if (targetPeer == null || !targetPeer.isEnabled()) { return; } @@ -1157,8 +1162,9 @@ public class LWWindowPeer if (focusLog.isLoggable(PlatformLogger.Level.FINE)) { focusLog.fine("requesting native focus to the owner " + owner); } - LWWindowPeer currentActivePeer = (currentActive != null ? - (LWWindowPeer)currentActive.getPeer() : null); + LWWindowPeer currentActivePeer = currentActive == null ? null : + (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer( + currentActive); // Ensure the opposite is natively active and suppress sending events. if (currentActivePeer != null && currentActivePeer.platformWindow.isActive()) { @@ -1270,7 +1276,8 @@ public class LWWindowPeer while (owner != null && !(owner instanceof Frame || owner instanceof Dialog)) { owner = owner.getOwner(); } - return owner != null ? (LWWindowPeer)owner.getPeer() : null; + return owner == null ? null : + (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(owner); } /** @@ -1289,11 +1296,13 @@ public class LWWindowPeer } } + @Override public void enterFullScreenMode() { platformWindow.enterFullScreenMode(); updateSecurityWarningVisibility(); } + @Override public void exitFullScreenMode() { platformWindow.exitFullScreenMode(); updateSecurityWarningVisibility(); diff --git a/jdk/src/macosx/classes/sun/lwawt/SelectionClearListener.java b/jdk/src/macosx/classes/sun/lwawt/SelectionClearListener.java deleted file mode 100644 index 4b378484240..00000000000 --- a/jdk/src/macosx/classes/sun/lwawt/SelectionClearListener.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.lwawt; - -/* - * Every time the TextField (or TextArea) change selection, every other text components - * must immediately clear their selections. - */ -interface SelectionClearListener { - void clearSelection(); -} From eacd2bcb72f3c8bc5b17fc31dae78f06a39e3394 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Mon, 23 Sep 2013 17:27:38 +0400 Subject: [PATCH 0468/1294] 7154966: CRs found to be in Fixed state with no test and no noreg- keyword Reviewed-by: ksrini --- langtools/test/tools/javac/T7090499.java | 14 ++++++++++++++ langtools/test/tools/javac/T7090499.out | 2 ++ langtools/test/tools/javac/T7120463.java | 11 +++++++++++ langtools/test/tools/javac/T7120463.out | 3 +++ langtools/test/tools/javac/T7126754.java | 19 +++++++++++++++++++ 5 files changed, 49 insertions(+) create mode 100644 langtools/test/tools/javac/T7090499.java create mode 100644 langtools/test/tools/javac/T7090499.out create mode 100644 langtools/test/tools/javac/T7120463.java create mode 100644 langtools/test/tools/javac/T7120463.out create mode 100644 langtools/test/tools/javac/T7126754.java diff --git a/langtools/test/tools/javac/T7090499.java b/langtools/test/tools/javac/T7090499.java new file mode 100644 index 00000000000..b05cda52c4b --- /dev/null +++ b/langtools/test/tools/javac/T7090499.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7090499 + * @summary missing rawtypes warnings in anonymous inner class + * @compile/ref=T7090499.out -Xlint:rawtypes -XDrawDiagnostics T7090499.java + */ + +class T7090499 { + { + new Object() { + T7090499 x; + }; + } +} diff --git a/langtools/test/tools/javac/T7090499.out b/langtools/test/tools/javac/T7090499.out new file mode 100644 index 00000000000..54b68474f79 --- /dev/null +++ b/langtools/test/tools/javac/T7090499.out @@ -0,0 +1,2 @@ +T7090499.java:11:13: compiler.warn.raw.class.use: T7090499, T7090499 +1 warning diff --git a/langtools/test/tools/javac/T7120463.java b/langtools/test/tools/javac/T7120463.java new file mode 100644 index 00000000000..9f64a17178a --- /dev/null +++ b/langtools/test/tools/javac/T7120463.java @@ -0,0 +1,11 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7120463 + * @summary Fix method reference parser support in order to avoid ambiguities + * @compile/fail/ref=T7120463.out -XDrawDiagnostics T7120463.java + */ + +class T7120463 { + void test() { that(i < len, "oopmap"); } + void that(int i, String s) { }; +} diff --git a/langtools/test/tools/javac/T7120463.out b/langtools/test/tools/javac/T7120463.out new file mode 100644 index 00000000000..527bd52acf2 --- /dev/null +++ b/langtools/test/tools/javac/T7120463.out @@ -0,0 +1,3 @@ +T7120463.java:9:24: compiler.err.cant.resolve.location: kindname.variable, i, , , (compiler.misc.location: kindname.class, T7120463, null) +T7120463.java:9:28: compiler.err.cant.resolve.location: kindname.variable, len, , , (compiler.misc.location: kindname.class, T7120463, null) +2 errors diff --git a/langtools/test/tools/javac/T7126754.java b/langtools/test/tools/javac/T7126754.java new file mode 100644 index 00000000000..0b9d32409db --- /dev/null +++ b/langtools/test/tools/javac/T7126754.java @@ -0,0 +1,19 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7126754 + * @summary Generics compilation failure casting List to List + * @compile T7126754.java + */ + +import java.util.List; +import java.util.Set; + +public class T7126754 { + public static void main(String[] args) { + List> a = null; + List> b = a; + + List> c = null; + List> d = (List>)c; + } +} From 10ff8a3aa481e5ef72e20112c86f98520aa4eadd Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Mon, 23 Sep 2013 17:55:36 +0400 Subject: [PATCH 0469/1294] 7172833: For default java.awt.Toolkit impl methods java.awt.Toolkit.is/setDynamicLayout() are not consistent Reviewed-by: alexsch, anthony --- jdk/src/share/classes/java/awt/Toolkit.java | 9 +- .../awt/Toolkit/DynamicLayout/bug7172833.java | 314 ++++++++++++++++++ 2 files changed, 320 insertions(+), 3 deletions(-) create mode 100644 jdk/test/java/awt/Toolkit/DynamicLayout/bug7172833.java diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java index 6b669d33677..de14eef1fea 100644 --- a/jdk/src/share/classes/java/awt/Toolkit.java +++ b/jdk/src/share/classes/java/awt/Toolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2013, 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 @@ -468,7 +468,7 @@ public abstract class Toolkit { GraphicsEnvironment.checkHeadless(); } -/** + /** * Controls whether the layout of Containers is validated dynamically * during resizing, or statically, after resizing is complete. * Use {@code isDynamicLayoutActive()} to detect if this feature enabled @@ -498,9 +498,12 @@ public abstract class Toolkit { * @see java.awt.GraphicsEnvironment#isHeadless * @since 1.4 */ - public void setDynamicLayout(boolean dynamic) + public void setDynamicLayout(final boolean dynamic) throws HeadlessException { GraphicsEnvironment.checkHeadless(); + if (this != getDefaultToolkit()) { + getDefaultToolkit().setDynamicLayout(dynamic); + } } /** diff --git a/jdk/test/java/awt/Toolkit/DynamicLayout/bug7172833.java b/jdk/test/java/awt/Toolkit/DynamicLayout/bug7172833.java new file mode 100644 index 00000000000..3780b7deacc --- /dev/null +++ b/jdk/test/java/awt/Toolkit/DynamicLayout/bug7172833.java @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.InvalidDnDOperationException; +import java.awt.dnd.peer.DragSourceContextPeer; +import java.awt.font.TextAttribute; +import java.awt.im.InputMethodHighlight; +import java.awt.image.ColorModel; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.peer.*; +import java.net.URL; +import java.util.Map; +import java.util.Properties; + + +/** + * @test + * @bug 7172833 + * @summary java.awt.Toolkit methods is/setDynamicLayout() should be consistent. + * @author Sergey Bylokhov + */ +public final class bug7172833 { + + public static void main(final String[] args) throws Exception { + final StubbedToolkit t = new StubbedToolkit(); + + t.setDynamicLayout(true); + if(!t.isDynamicLayoutSet()){ + throw new RuntimeException("'true' expected but 'false' returned"); + } + + t.setDynamicLayout(false); + if(t.isDynamicLayoutSet()){ + throw new RuntimeException("'false' expected but 'true' returned"); + } + } + + static final class StubbedToolkit extends Toolkit { + + @Override + protected boolean isDynamicLayoutSet() throws HeadlessException { + return super.isDynamicLayoutSet(); + } + + @Override + protected DesktopPeer createDesktopPeer(final Desktop target) + throws HeadlessException { + return null; + } + + @Override + protected ButtonPeer createButton(final Button target) + throws HeadlessException { + return null; + } + + @Override + protected TextFieldPeer createTextField(final TextField target) + throws HeadlessException { + return null; + } + + @Override + protected LabelPeer createLabel(final Label target) throws HeadlessException { + return null; + } + + @Override + protected ListPeer createList(final List target) throws HeadlessException { + return null; + } + + @Override + protected CheckboxPeer createCheckbox(final Checkbox target) + throws HeadlessException { + return null; + } + + @Override + protected ScrollbarPeer createScrollbar(final Scrollbar target) + throws HeadlessException { + return null; + } + + @Override + protected ScrollPanePeer createScrollPane(final ScrollPane target) + throws HeadlessException { + return null; + } + + @Override + protected TextAreaPeer createTextArea(final TextArea target) + throws HeadlessException { + return null; + } + + @Override + protected ChoicePeer createChoice(final Choice target) + throws HeadlessException { + return null; + } + + @Override + protected FramePeer createFrame(final Frame target) throws HeadlessException { + return null; + } + + @Override + protected CanvasPeer createCanvas(final Canvas target) { + return null; + } + + @Override + protected PanelPeer createPanel(final Panel target) { + return null; + } + + @Override + protected WindowPeer createWindow(final Window target) + throws HeadlessException { + return null; + } + + @Override + protected DialogPeer createDialog(final Dialog target) + throws HeadlessException { + return null; + } + + @Override + protected MenuBarPeer createMenuBar(final MenuBar target) + throws HeadlessException { + return null; + } + + @Override + protected MenuPeer createMenu(final Menu target) throws HeadlessException { + return null; + } + + @Override + protected PopupMenuPeer createPopupMenu(final PopupMenu target) + throws HeadlessException { + return null; + } + + @Override + protected MenuItemPeer createMenuItem(final MenuItem target) + throws HeadlessException { + return null; + } + + @Override + protected FileDialogPeer createFileDialog(final FileDialog target) + throws HeadlessException { + return null; + } + + @Override + protected CheckboxMenuItemPeer createCheckboxMenuItem( + final CheckboxMenuItem target) throws HeadlessException { + return null; + } + + @Override + protected FontPeer getFontPeer(final String name, final int style) { + return null; + } + + @Override + public Dimension getScreenSize() throws HeadlessException { + return null; + } + + @Override + public int getScreenResolution() throws HeadlessException { + return 0; + } + + @Override + public ColorModel getColorModel() throws HeadlessException { + return null; + } + + @Override + public String[] getFontList() { + return new String[0]; + } + + @Override + public FontMetrics getFontMetrics(final Font font) { + return null; + } + + @Override + public void sync() { + + } + + @Override + public Image getImage(final String filename) { + return null; + } + + @Override + public Image getImage(final URL url) { + return null; + } + + @Override + public Image createImage(final String filename) { + return null; + } + + @Override + public Image createImage(final URL url) { + return null; + } + + @Override + public boolean prepareImage( + final Image image, final int width, final int height, + final ImageObserver observer) { + return false; + } + + @Override + public int checkImage(final Image image, final int width, final int height, + final ImageObserver observer) { + return 0; + } + + @Override + public Image createImage(final ImageProducer producer) { + return null; + } + + @Override + public Image createImage(final byte[] imagedata, final int imageoffset, + final int imagelength) { + return null; + } + + @Override + public PrintJob getPrintJob(final Frame frame, final String jobtitle, + final Properties props) { + return null; + } + + @Override + public void beep() { + + } + + @Override + public Clipboard getSystemClipboard() throws HeadlessException { + return null; + } + + @Override + protected EventQueue getSystemEventQueueImpl() { + return null; + } + + @Override + public DragSourceContextPeer createDragSourceContextPeer( + final DragGestureEvent dge) throws InvalidDnDOperationException { + return null; + } + + @Override + public boolean isModalityTypeSupported( + final Dialog.ModalityType modalityType) { + return false; + } + + @Override + public boolean isModalExclusionTypeSupported( + final Dialog.ModalExclusionType modalExclusionType) { + return false; + } + + @Override + public Map mapInputMethodHighlight( + final InputMethodHighlight highlight) throws HeadlessException { + return null; + } + } +} From e815841576eb30fe7e7b9c0582041044b8eb63e7 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Mon, 23 Sep 2013 18:29:27 +0400 Subject: [PATCH 0470/1294] 4881267: improve diagnostic for "instanceof T" for type parameter T Reviewed-by: vromero, jjg --- .../classes/com/sun/tools/javac/comp/Attr.java | 10 ++++++++-- .../classes/com/sun/tools/javac/comp/Check.java | 14 -------------- langtools/test/tools/javac/T4881267.java | 12 ++++++++++++ langtools/test/tools/javac/T4881267.out | 2 ++ 4 files changed, 22 insertions(+), 16 deletions(-) create mode 100644 langtools/test/tools/javac/T4881267.java create mode 100644 langtools/test/tools/javac/T4881267.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 3813a6acd7a..0b4db2c059f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -3102,8 +3102,14 @@ public class Attr extends JCTree.Visitor { public void visitTypeTest(JCInstanceOf tree) { Type exprtype = chk.checkNullOrRefType( tree.expr.pos(), attribExpr(tree.expr, env)); - Type clazztype = chk.checkReifiableReferenceType( - tree.clazz.pos(), attribType(tree.clazz, env)); + Type clazztype = attribType(tree.clazz, env); + if (!clazztype.hasTag(TYPEVAR)) { + clazztype = chk.checkClassOrArrayType(tree.clazz.pos(), clazztype); + } + if (!clazztype.isErroneous() && !types.isReifiable(clazztype)) { + log.error(tree.clazz.pos(), "illegal.generic.type.for.instof"); + clazztype = types.createErrorType(clazztype); + } chk.validate(tree.clazz, env, false); chk.checkCastable(tree.expr.pos(), exprtype, clazztype); result = check(tree, syms.booleanType, VAL, resultInfo); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index a9ad0a68299..453bc70edda 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -706,20 +706,6 @@ public class Check { return t; } - /** Check that type is a reifiable class, interface or array type. - * @param pos Position to be used for error reporting. - * @param t The type to be checked. - */ - Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) { - t = checkClassOrArrayType(pos, t); - if (!t.isErroneous() && !types.isReifiable(t)) { - log.error(pos, "illegal.generic.type.for.instof"); - return types.createErrorType(t); - } else { - return t; - } - } - /** Check that type is a reference type, i.e. a class, interface or array type * or a type variable. * @param pos Position to be used for error reporting. diff --git a/langtools/test/tools/javac/T4881267.java b/langtools/test/tools/javac/T4881267.java new file mode 100644 index 00000000000..33690add37b --- /dev/null +++ b/langtools/test/tools/javac/T4881267.java @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 4881267 + * @summary improve diagnostic for "instanceof T" for type parameter T + * @compile/fail/ref=T4881267.out -XDrawDiagnostics T4881267.java + */ + +class T4881267 { + void m(Object o) { + boolean b = o instanceof T; + } +} diff --git a/langtools/test/tools/javac/T4881267.out b/langtools/test/tools/javac/T4881267.out new file mode 100644 index 00000000000..01a732a612e --- /dev/null +++ b/langtools/test/tools/javac/T4881267.out @@ -0,0 +1,2 @@ +T4881267.java:10:34: compiler.err.illegal.generic.type.for.instof +1 error From 522051490c44d11e8bb241eeefc92c0e645c0a96 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Mon, 23 Sep 2013 08:56:19 -0700 Subject: [PATCH 0471/1294] 8025088: Missing cases for JVM_CONSTANT_MethodHandleInError cause crash if debugger steps into error-tagged method handle Need to refetch each method from InstanceKlass after all safepoints. Removed leaky PreviousVersionInfo code. Reviewed-by: coleenp, sspitsyn --- hotspot/src/share/vm/oops/constantPool.cpp | 14 +++++---- hotspot/src/share/vm/oops/constantPool.hpp | 36 ++++++++++++++++++---- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index 4f888eb9ca4..66493a879e1 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -1611,9 +1611,11 @@ jint ConstantPool::cpool_entry_size(jint idx) { case JVM_CONSTANT_UnresolvedClassInError: case JVM_CONSTANT_StringIndex: case JVM_CONSTANT_MethodType: + case JVM_CONSTANT_MethodTypeInError: return 3; case JVM_CONSTANT_MethodHandle: + case JVM_CONSTANT_MethodHandleInError: return 4; //tag, ref_kind, ref_index case JVM_CONSTANT_Integer: @@ -1794,8 +1796,8 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, case JVM_CONSTANT_MethodHandle: case JVM_CONSTANT_MethodHandleInError: { *bytes = JVM_CONSTANT_MethodHandle; - int kind = method_handle_ref_kind_at(idx); - idx1 = method_handle_index_at(idx); + int kind = method_handle_ref_kind_at_error_ok(idx); + idx1 = method_handle_index_at_error_ok(idx); *(bytes+1) = (unsigned char) kind; Bytes::put_Java_u2((address) (bytes+2), idx1); DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1)); @@ -1804,7 +1806,7 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, case JVM_CONSTANT_MethodType: case JVM_CONSTANT_MethodTypeInError: { *bytes = JVM_CONSTANT_MethodType; - idx1 = method_type_index_at(idx); + idx1 = method_type_index_at_error_ok(idx); Bytes::put_Java_u2((address) (bytes+1), idx1); DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1)); break; @@ -1992,12 +1994,12 @@ void ConstantPool::print_entry_on(const int index, outputStream* st) { break; case JVM_CONSTANT_MethodHandle : case JVM_CONSTANT_MethodHandleInError : - st->print("ref_kind=%d", method_handle_ref_kind_at(index)); - st->print(" ref_index=%d", method_handle_index_at(index)); + st->print("ref_kind=%d", method_handle_ref_kind_at_error_ok(index)); + st->print(" ref_index=%d", method_handle_index_at_error_ok(index)); break; case JVM_CONSTANT_MethodType : case JVM_CONSTANT_MethodTypeInError : - st->print("signature_index=%d", method_type_index_at(index)); + st->print("signature_index=%d", method_type_index_at_error_ok(index)); break; case JVM_CONSTANT_InvokeDynamic : { diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp index 93c32348573..47a51a835e2 100644 --- a/hotspot/src/share/vm/oops/constantPool.hpp +++ b/hotspot/src/share/vm/oops/constantPool.hpp @@ -474,18 +474,42 @@ class ConstantPool : public Metadata { return *int_at_addr(which); } - int method_handle_ref_kind_at(int which) { - assert(tag_at(which).is_method_handle(), "Corrupted constant pool"); + private: + int method_handle_ref_kind_at(int which, bool error_ok) { + assert(tag_at(which).is_method_handle() || + (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool"); return extract_low_short_from_int(*int_at_addr(which)); // mask out unwanted ref_index bits } - int method_handle_index_at(int which) { - assert(tag_at(which).is_method_handle(), "Corrupted constant pool"); + int method_handle_index_at(int which, bool error_ok) { + assert(tag_at(which).is_method_handle() || + (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool"); return extract_high_short_from_int(*int_at_addr(which)); // shift out unwanted ref_kind bits } - int method_type_index_at(int which) { - assert(tag_at(which).is_method_type(), "Corrupted constant pool"); + int method_type_index_at(int which, bool error_ok) { + assert(tag_at(which).is_method_type() || + (error_ok && tag_at(which).is_method_type_in_error()), "Corrupted constant pool"); return *int_at_addr(which); } + public: + int method_handle_ref_kind_at(int which) { + return method_handle_ref_kind_at(which, false); + } + int method_handle_ref_kind_at_error_ok(int which) { + return method_handle_ref_kind_at(which, true); + } + int method_handle_index_at(int which) { + return method_handle_index_at(which, false); + } + int method_handle_index_at_error_ok(int which) { + return method_handle_index_at(which, true); + } + int method_type_index_at(int which) { + return method_type_index_at(which, false); + } + int method_type_index_at_error_ok(int which) { + return method_type_index_at(which, true); + } + // Derived queries: Symbol* method_handle_name_ref_at(int which) { int member = method_handle_index_at(which); From b99f593316af3f74c9e07c1e688b1794f5993a5c Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Mon, 23 Sep 2013 21:24:34 +0400 Subject: [PATCH 0472/1294] 8019282: keyRelesed is reached even though key was NOT released Reviewed-by: serb, anthony --- jdk/make/sun/xawt/mapfile-vers | 1 + jdk/makefiles/mapfiles/libawt_xawt/mapfile-vers | 1 + jdk/src/solaris/classes/sun/awt/X11/XToolkit.java | 2 ++ jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java | 1 + jdk/src/solaris/native/sun/xawt/XlibWrapper.c | 8 ++++++-- 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/jdk/make/sun/xawt/mapfile-vers b/jdk/make/sun/xawt/mapfile-vers index 5455530cbed..e75f0c1914b 100644 --- a/jdk/make/sun/xawt/mapfile-vers +++ b/jdk/make/sun/xawt/mapfile-vers @@ -305,6 +305,7 @@ SUNWprivate_1.1 { Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap; Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard; Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode; + Java_sun_awt_X11_XlibWrapper_XkbSetDetectableAutoRepeat; Java_sun_awt_X11_XlibWrapper_XGetModifierMapping; Java_sun_awt_X11_XlibWrapper_XFreeModifiermap; Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping; diff --git a/jdk/makefiles/mapfiles/libawt_xawt/mapfile-vers b/jdk/makefiles/mapfiles/libawt_xawt/mapfile-vers index 7a1a8117a3d..a2bb9bda97b 100644 --- a/jdk/makefiles/mapfiles/libawt_xawt/mapfile-vers +++ b/jdk/makefiles/mapfiles/libawt_xawt/mapfile-vers @@ -305,6 +305,7 @@ SUNWprivate_1.1 { Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap; Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard; Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode; + Java_sun_awt_X11_XlibWrapper_XkbSetDetectableAutoRepeat; Java_sun_awt_X11_XlibWrapper_XGetModifierMapping; Java_sun_awt_X11_XlibWrapper_XFreeModifiermap; Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java index 9b4daa1cef6..7fa438f4484 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -2249,6 +2249,8 @@ public final class XToolkit extends UNIXToolkit implements Runnable { XConstants.XkbModifierMapMask | XConstants.XkbVirtualModsMask, XConstants.XkbUseCoreKbd); + + XlibWrapper.XkbSetDetectableAutoRepeat(getDisplay(), true); } } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java b/jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java index 2d8fc851d06..02a7c4b2aa4 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java @@ -509,6 +509,7 @@ static native String XSetLocaleModifiers(String modifier_list); static native long XkbGetUpdatedMap(long display, long which, long xkb); static native void XkbFreeKeyboard(long xkb, long which, boolean free_all); static native boolean XkbTranslateKeyCode(long xkb, int keycode, long mods, long mods_rtrn, long keysym_rtrn); + static native void XkbSetDetectableAutoRepeat(long display, boolean detectable); static native void XConvertCase(long keysym, diff --git a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c index da328719304..3e75f291c94 100644 --- a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c +++ b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c @@ -523,8 +523,12 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode //printf("native, output: keysym:0x%0X; mods:0x%0X\n", *(unsigned int *)jlong_to_ptr(keysym_rtrn), *(unsigned int *)jlong_to_ptr(mods_rtrn)); return b; } - - +JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbSetDetectableAutoRepeat +(JNIEnv *env, jclass clazz, jlong display, jboolean detectable) +{ + AWT_CHECK_HAVE_LOCK(); + XkbSetDetectableAutoRepeat((Display *) jlong_to_ptr(display), detectable, NULL); +} /* * Class: sun_awt_X11_XlibWrapper * Method: XNextEvent From c101eca6bb94ad082a0e961dc8e46ee076ef3b30 Mon Sep 17 00:00:00 2001 From: Eric McCorkle Date: Mon, 23 Sep 2013 15:37:59 -0400 Subject: [PATCH 0473/1294] 6499673: Assertion check for TypeVariable.getUpperBound() fails Fix TypeVariable.getUpperBound to return results as specified Reviewed-by: jjg --- .../com/sun/tools/javac/code/Type.java | 2 +- .../com/sun/tools/javac/code/Types.java | 23 ++ .../com/sun/tools/javac/model/JavacTypes.java | 6 +- .../cast/intersection/model/Model01.java | 4 +- .../cast/intersection/model/ModelChecker.java | 2 +- .../processing/model/type/BoundsTest.java | 200 ++++++++++++++++++ .../type/IntersectionPropertiesTest.java | 135 ++++++++++++ 7 files changed, 363 insertions(+), 9 deletions(-) create mode 100644 langtools/test/tools/javac/processing/model/type/BoundsTest.java create mode 100644 langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java index a6e4642ce51..699ac7ebedc 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java @@ -977,7 +977,7 @@ public abstract class Type implements TypeMirror { } public java.util.List getBounds() { - return Collections.unmodifiableList(getComponents()); + return Collections.unmodifiableList(getExplicitComponents()); } public List getComponents() { diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 996bcd88018..84eaf4a431e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -2414,6 +2414,29 @@ public class Types { } }; + public List directSupertypes(Type t) { + return directSupertypes.visit(t); + } + // where + private final UnaryVisitor> directSupertypes = new UnaryVisitor>() { + + public List visitType(final Type type, final Void ignored) { + if (!type.isCompound()) { + final Type sup = supertype(type); + return (sup == Type.noType || sup == type || sup == null) + ? interfaces(type) + : interfaces(type).prepend(sup); + } else { + return visitIntersectionType((IntersectionClassType) type); + } + } + + private List visitIntersectionType(final IntersectionClassType it) { + return it.getExplicitComponents(); + } + + }; + public boolean isDirectSuperInterface(TypeSymbol isym, TypeSymbol origin) { for (Type i2 : interfaces(origin.type)) { if (isym == i2.tsym) return true; diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java index 14e377fb37f..726264bb79c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java @@ -116,11 +116,7 @@ public class JavacTypes implements javax.lang.model.util.Types { public List directSupertypes(TypeMirror t) { validateTypeNotIn(t, EXEC_OR_PKG); - Type type = (Type) t; - Type sup = types.supertype(type); - return (sup == Type.noType || sup == type || sup == null) - ? types.interfaces(type) - : types.interfaces(type).prepend(sup); + return types.directSupertypes((Type) t); } public TypeMirror erasure(TypeMirror t) { diff --git a/langtools/test/tools/javac/cast/intersection/model/Model01.java b/langtools/test/tools/javac/cast/intersection/model/Model01.java index 21740179f49..782644726ca 100644 --- a/langtools/test/tools/javac/cast/intersection/model/Model01.java +++ b/langtools/test/tools/javac/cast/intersection/model/Model01.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8002099 + * @bug 8002099 6499673 * @summary Add support for intersection types in cast expression * @library /tools/javac/lib * @build JavacTestingAbstractProcessor ModelChecker @@ -46,7 +46,7 @@ class Test { } void test(){ - @IntersectionTypeInfo({"java.lang.Object", "Test.A", "Test.B"}) + @IntersectionTypeInfo({"Test.A", "Test.B"}) Object o = (A & B)null; } } diff --git a/langtools/test/tools/javac/cast/intersection/model/ModelChecker.java b/langtools/test/tools/javac/cast/intersection/model/ModelChecker.java index 1486d21bf1b..d2dbf697fdc 100644 --- a/langtools/test/tools/javac/cast/intersection/model/ModelChecker.java +++ b/langtools/test/tools/javac/cast/intersection/model/ModelChecker.java @@ -97,7 +97,7 @@ public class ModelChecker extends JavacTestingAbstractProcessor { } } - assertTrue(assertionCount == 10, "Expected 10 assertions - found " + assertionCount); + assertTrue(assertionCount == 9, "Expected 9 assertions - found " + assertionCount); return super.visitVariable(node, p); } } diff --git a/langtools/test/tools/javac/processing/model/type/BoundsTest.java b/langtools/test/tools/javac/processing/model/type/BoundsTest.java new file mode 100644 index 00000000000..59c73ef6a0c --- /dev/null +++ b/langtools/test/tools/javac/processing/model/type/BoundsTest.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2012, 2013, 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 6499673 + * @library /tools/javac/lib + * @build JavacTestingAbstractProcessor BoundsTest + * @run main BoundsTest + * @summary Assertion check for TypeVariable.getUpperBound() fails + */ + +import com.sun.source.util.*; +import com.sun.tools.javac.api.*; +import com.sun.tools.javac.file.*; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.type.*; +import javax.lang.model.util.ElementFilter; +import javax.lang.model.element.*; +import javax.tools.*; +import java.util.*; +import java.io.*; + +public class BoundsTest { + + private int errors = 0; + private static final String Intersection_name = "IntersectionTest.java"; + private static final String Intersection_contents = + "import java.util.List;\n" + + "import java.io.Serializable;\t" + + "public class IntersectionTest {\n" + + " void method(S s) { }\n" + + "}"; + private static final String[] Intersection_bounds = { + "java.util.List", + "java.io.Serializable" + }; + private static final String[] Intersection_supers = { + "java.util.List", + "java.io.Serializable" + }; + + private static final String Single_name = "SingleTest.java"; + private static final String Single_contents = + "import java.util.List;\n" + + "public class SingleTest {\n" + + " void method(S s) { }\n" + + "}"; + private static final String[] Single_bounds = { + "java.util.List", + }; + private static final String[] Single_supers = { + "java.lang.Object", + "java.util.Collection" + }; + + private static final String NoBounds_name = "NoBoundsTest.java"; + private static final String NoBounds_contents = + "public class NoBoundsTest {\n" + + " void method(S s) { }\n" + + "}"; + private static final String[] NoBounds_bounds = { + "java.lang.Object", + }; + private static final String[] NoBounds_supers = {}; + + private HashSet expected_bounds; + private HashSet expected_supers; + + private static final File classesdir = new File("intersectionproperties"); + private static final JavaCompiler comp = + ToolProvider.getSystemJavaCompiler(); + private static final StandardJavaFileManager fm = + comp.getStandardFileManager(null, null, null); + + public void runOne(final String Test_name, final String Test_contents, + final String[] Test_bounds, final String[] Test_supers) + throws IOException { + System.err.println("Testing " + Test_name); + expected_bounds = new HashSet(Arrays.asList(Test_bounds)); + expected_supers = new HashSet(Arrays.asList(Test_supers)); + final Iterable files = + fm.getJavaFileObjectsFromFiles(Collections.singleton(writeFile(classesdir, Test_name, Test_contents))); + final JavacTask ct = + (JavacTask)comp.getTask(null, fm, null, null, null, files); + ct.setProcessors(Collections.singleton(new TestProcessor())); + + if (!ct.call()) { + System.err.println("Compilation unexpectedly failed"); + errors++; + } + } + + public void run() throws IOException { + runOne(Intersection_name, Intersection_contents, + Intersection_bounds, Intersection_supers); + runOne(Single_name, Single_contents, + Single_bounds, Single_supers); + runOne(NoBounds_name, NoBounds_contents, + NoBounds_bounds, NoBounds_supers); + + if (0 != errors) + throw new RuntimeException(errors + " errors occurred"); + } + + public static void main(String... args) throws IOException { + new IntersectionPropertiesTest().run(); + } + + private static File writeFile(File dir, String path, String body) + throws IOException { + File f = new File(dir, path); + f.getParentFile().mkdirs(); + try (FileWriter out = new FileWriter(f)) { + out.write(body); + } + return f; + } + + private class TestProcessor extends JavacTestingAbstractProcessor { + + private Set rootElements; + + public boolean process(Set annotations, RoundEnvironment roundEnv) { + rootElements = roundEnv.getRootElements(); + if (!rootElements.isEmpty()) { + performCheck(); + } + return true; + } + + private void performCheck() { + TypeElement typeElement = (TypeElement) rootElements.iterator().next(); + ExecutableElement method = ElementFilter.methodsIn(typeElement.getEnclosedElements()).get(0); + TypeVariable typeVariable = (TypeVariable) method.getParameters().get(0).asType(); + + final TypeMirror upperBound = typeVariable.getUpperBound(); + + TypeParameterElement typeParameterElement = ((TypeParameterElement) typeVariable.asElement()); + final List bounds = typeParameterElement.getBounds(); + final List supers = processingEnv.getTypeUtils().directSupertypes(upperBound); + + final HashSet actual_bounds = new HashSet(); + final HashSet actual_supers = new HashSet(); + + for(TypeMirror ty : bounds) { + actual_bounds.add(((TypeElement)((DeclaredType)ty).asElement()).getQualifiedName()); + } + + for(TypeMirror ty : supers) { + actual_supers.add(((TypeElement)((DeclaredType)ty).asElement()).getQualifiedName()); + } + + + if (!expected_bounds.equals(actual_bounds)) { + System.err.println("Mismatched expected and actual bounds."); + System.err.println("Expected:"); + for(CharSequence tm : expected_bounds) + System.err.println(" " + tm); + System.err.println("Actual:"); + for(CharSequence tm : actual_bounds) + System.err.println(" " + tm); + errors++; + } + + if (!expected_supers.equals(actual_supers)) { + System.err.println("Mismatched expected and actual bounds."); + System.err.println("Expected:"); + for(CharSequence tm : expected_supers) + System.err.println(" " + tm); + System.err.println("Actual:"); + for(CharSequence tm : actual_supers) + System.err.println(" " + tm); + errors++; + } + } + } + +} diff --git a/langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java b/langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java new file mode 100644 index 00000000000..9beeb6392c8 --- /dev/null +++ b/langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012, 2013, 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 6499673 + * @library /tools/javac/lib + * @build JavacTestingAbstractProcessor IntersectionPropertiesTest + * @run main IntersectionPropertiesTest + * @summary Assertion check for TypeVariable.getUpperBound() fails + */ + +import com.sun.source.util.*; +import com.sun.tools.javac.api.*; +import com.sun.tools.javac.file.*; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.type.*; +import javax.lang.model.util.ElementFilter; +import javax.lang.model.element.*; +import javax.tools.*; +import java.util.*; +import java.io.*; + +public class IntersectionPropertiesTest { + + private int errors = 0; + private static final String Intersection_name = "IntersectionTest.java"; + private static final String Intersection_contents = + "import java.util.List;\n" + + "import java.io.Serializable;\t" + + "public class IntersectionTest {\n" + + " void method(S s) { }\n" + + "}"; + + private static final File classesdir = new File("intersectionproperties"); + private static final JavaCompiler comp = + ToolProvider.getSystemJavaCompiler(); + private static final StandardJavaFileManager fm = + comp.getStandardFileManager(null, null, null); + + public void runOne(final String Test_name, final String Test_contents) + throws IOException { + System.err.println("Testing " + Test_name); + final Iterable files = + fm.getJavaFileObjectsFromFiles(Collections.singleton(writeFile(classesdir, Test_name, Test_contents))); + final JavacTask ct = + (JavacTask)comp.getTask(null, fm, null, null, null, files); + ct.setProcessors(Collections.singleton(new TestProcessor())); + + if (!ct.call()) { + System.err.println("Compilation unexpectedly failed"); + errors++; + } + } + + public void run() throws IOException { + runOne(Intersection_name, Intersection_contents); + + if (0 != errors) + throw new RuntimeException(errors + " errors occurred"); + } + + public static void main(String... args) throws IOException { + new IntersectionPropertiesTest().run(); + } + + private static File writeFile(File dir, String path, String body) + throws IOException { + File f = new File(dir, path); + f.getParentFile().mkdirs(); + try (FileWriter out = new FileWriter(f)) { + out.write(body); + } + return f; + } + + private class TestProcessor extends JavacTestingAbstractProcessor { + + private Set rootElements; + + public boolean process(Set annotations, RoundEnvironment roundEnv) { + rootElements = roundEnv.getRootElements(); + if (!rootElements.isEmpty()) { + performCheck(); + } + return true; + } + + private void performCheck() { + TypeElement typeElement = (TypeElement) rootElements.iterator().next(); + ExecutableElement method = ElementFilter.methodsIn(typeElement.getEnclosedElements()).get(0); + TypeVariable typeVariable = (TypeVariable) method.getParameters().get(0).asType(); + + final TypeMirror upperBound = typeVariable.getUpperBound(); + + TypeParameterElement typeParameterElement = ((TypeParameterElement) typeVariable.asElement()); + final List bounds = typeParameterElement.getBounds(); + final HashSet actual = new HashSet(processingEnv.getTypeUtils().directSupertypes(upperBound)); + final HashSet expected = new HashSet(bounds); + if (!expected.equals(actual)) { + System.err.println("Mismatched expected and actual bounds."); + System.err.println("Expected:"); + for(TypeMirror tm : expected) + System.err.println(" " + tm); + System.err.println("Actual:"); + for(TypeMirror tm : actual) + System.err.println(" " + tm); + errors++; + } + } + + } + +} From af333dc7bb6edd73ccd992f65084d999aec18578 Mon Sep 17 00:00:00 2001 From: Yuri Nesterenko Date: Tue, 24 Sep 2013 12:25:50 +0400 Subject: [PATCH 0474/1294] 8025114: Eliminate doclint errors in java.awt.dnd package javadoc Reviewed-by: serb, alexsch --- .../java/awt/dnd/DragGestureRecognizer.java | 10 +++--- .../classes/java/awt/dnd/DragSource.java | 2 +- .../java/awt/dnd/DragSourceContext.java | 2 +- .../java/awt/dnd/DragSourceDragEvent.java | 10 +++--- .../java/awt/dnd/DragSourceDropEvent.java | 6 ++-- .../classes/java/awt/dnd/DragSourceEvent.java | 4 +-- .../classes/java/awt/dnd/DropTarget.java | 4 +-- .../java/awt/dnd/DropTargetDragEvent.java | 12 +++---- .../java/awt/dnd/DropTargetDropEvent.java | 31 +++++++++---------- 9 files changed, 40 insertions(+), 41 deletions(-) diff --git a/jdk/src/share/classes/java/awt/dnd/DragGestureRecognizer.java b/jdk/src/share/classes/java/awt/dnd/DragGestureRecognizer.java index 1f1b9a3f488..60c1876fddf 100644 --- a/jdk/src/share/classes/java/awt/dnd/DragGestureRecognizer.java +++ b/jdk/src/share/classes/java/awt/dnd/DragGestureRecognizer.java @@ -114,7 +114,7 @@ public abstract class DragGestureRecognizer implements Serializable { * @param dgl the DragGestureRecognizer * to notify when a drag gesture is detected *

    - * @throws IllegalArgumentException + * @throws IllegalArgumentException * if ds is null. */ @@ -157,7 +157,7 @@ public abstract class DragGestureRecognizer implements Serializable { * @param sa the set (logical OR) of the DnDConstants * that this Drag and Drop operation will support *

    - * @throws IllegalArgumentException + * @throws IllegalArgumentException * if ds is null. */ @@ -185,7 +185,7 @@ public abstract class DragGestureRecognizer implements Serializable { * the DragGestureRecognizer * is not associated with any Component. *

    - * @throws IllegalArgumentException + * @throws IllegalArgumentException * if ds is null. */ @@ -202,7 +202,7 @@ public abstract class DragGestureRecognizer implements Serializable { * DragGestureRecognizer will * use to process the Drag and Drop operation *

    - * @throws IllegalArgumentException + * @throws IllegalArgumentException * if ds is null. */ @@ -332,7 +332,7 @@ public abstract class DragGestureRecognizer implements Serializable { * @param dgl the DragGestureListener to unregister * from this DragGestureRecognizer *

    - * @throws IllegalArgumentException if + * @throws IllegalArgumentException if * dgl is not (equal to) the currently registered DragGestureListener. */ diff --git a/jdk/src/share/classes/java/awt/dnd/DragSource.java b/jdk/src/share/classes/java/awt/dnd/DragSource.java index bceedda646b..d44733b71d8 100644 --- a/jdk/src/share/classes/java/awt/dnd/DragSource.java +++ b/jdk/src/share/classes/java/awt/dnd/DragSource.java @@ -676,7 +676,7 @@ public class DragSource implements Serializable { * FooListeners on this * DragSource, or an empty array if no such listeners * have been added - * @exception ClassCastException if listenerType + * @exception ClassCastException if listenerType * doesn't specify a class or interface that implements * java.util.EventListener * diff --git a/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java b/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java index 77fc0e49c43..9655689a237 100644 --- a/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java +++ b/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java @@ -63,7 +63,7 @@ import java.util.TooManyListenersException; * itself between the platform and the * listeners provided by the initiator of the drag operation. *

    - *   Ctrl + Shift -> ACTION_LINK
    - *   Ctrl         -> ACTION_COPY
    - *   Shift        -> ACTION_MOVE
    + *   Ctrl + Shift -> ACTION_LINK
    + *   Ctrl         -> ACTION_COPY
    + *   Shift        -> ACTION_MOVE
      * 
    * If the user selects a drop action, the user drop action is one of * DnDConstants that represents the selected drop action if this @@ -103,7 +103,7 @@ public class DragSourceDragEvent extends DragSourceEvent { * in one event. Use of the extended modifiers is * preferred. * - * @throws IllegalArgumentException if dsc is null. + * @throws IllegalArgumentException if dsc is null. * * @see java.awt.event.InputEvent * @see DragSourceEvent#getLocation @@ -154,7 +154,7 @@ public class DragSourceDragEvent extends DragSourceEvent { * @param x the horizontal coordinate for the cursor location * @param y the vertical coordinate for the cursor location * - * @throws IllegalArgumentException if dsc is null. + * @throws IllegalArgumentException if dsc is null. * * @see java.awt.event.InputEvent * @since 1.4 diff --git a/jdk/src/share/classes/java/awt/dnd/DragSourceDropEvent.java b/jdk/src/share/classes/java/awt/dnd/DragSourceDropEvent.java index 25a7051f0a2..e1116bc68d5 100644 --- a/jdk/src/share/classes/java/awt/dnd/DragSourceDropEvent.java +++ b/jdk/src/share/classes/java/awt/dnd/DragSourceDropEvent.java @@ -63,7 +63,7 @@ public class DragSourceDropEvent extends DragSourceEvent { * @param action the drop action * @param success a boolean indicating if the drop was successful * - * @throws IllegalArgumentException if dsc is null. + * @throws IllegalArgumentException if dsc is null. * * @see DragSourceEvent#getLocation */ @@ -91,7 +91,7 @@ public class DragSourceDropEvent extends DragSourceEvent { * @param x the horizontal coordinate for the cursor location * @param y the vertical coordinate for the cursor location * - * @throws IllegalArgumentException if dsc is null. + * @throws IllegalArgumentException if dsc is null. * * @since 1.4 */ @@ -112,7 +112,7 @@ public class DragSourceDropEvent extends DragSourceEvent { * * @param dsc the DragSourceContext * - * @throws IllegalArgumentException if dsc is null. + * @throws IllegalArgumentException if dsc is null. * * @see DragSourceEvent#getLocation */ diff --git a/jdk/src/share/classes/java/awt/dnd/DragSourceEvent.java b/jdk/src/share/classes/java/awt/dnd/DragSourceEvent.java index f2616b06a3a..62ab7fcb27a 100644 --- a/jdk/src/share/classes/java/awt/dnd/DragSourceEvent.java +++ b/jdk/src/share/classes/java/awt/dnd/DragSourceEvent.java @@ -96,7 +96,7 @@ public class DragSourceEvent extends EventObject { * * @param dsc the DragSourceContext * - * @throws IllegalArgumentException if dsc is null. + * @throws IllegalArgumentException if dsc is null. * * @see #getLocation */ @@ -117,7 +117,7 @@ public class DragSourceEvent extends EventObject { * @param x the horizontal coordinate for the cursor location * @param y the vertical coordinate for the cursor location * - * @throws IllegalArgumentException if dsc is null. + * @throws IllegalArgumentException if dsc is null. * * @since 1.4 */ diff --git a/jdk/src/share/classes/java/awt/dnd/DropTarget.java b/jdk/src/share/classes/java/awt/dnd/DropTarget.java index a1fd5b56db9..4006f728c9b 100644 --- a/jdk/src/share/classes/java/awt/dnd/DropTarget.java +++ b/jdk/src/share/classes/java/awt/dnd/DropTarget.java @@ -305,7 +305,7 @@ public class DropTarget implements DropTargetListener, Serializable { *

    * @param dtl The new DropTargetListener *

    - * @throws TooManyListenersException if a + * @throws TooManyListenersException if a * DropTargetListener is already added to this * DropTarget. */ @@ -844,7 +844,7 @@ public class DropTarget implements DropTargetListener, Serializable { int actions = DnDConstants.ACTION_COPY_OR_MOVE; /** - * true if the DropTarget is accepting Drag & Drop operations. + * true if the DropTarget is accepting Drag & Drop operations. * * @serial */ diff --git a/jdk/src/share/classes/java/awt/dnd/DropTargetDragEvent.java b/jdk/src/share/classes/java/awt/dnd/DropTargetDragEvent.java index a315a6d5463..f74d0410664 100644 --- a/jdk/src/share/classes/java/awt/dnd/DropTargetDragEvent.java +++ b/jdk/src/share/classes/java/awt/dnd/DropTargetDragEvent.java @@ -49,9 +49,9 @@ import java.util.List; * source and the drop action selected by the user. The user can select a drop * action by pressing modifier keys during the drag operation: *

    - *   Ctrl + Shift -> ACTION_LINK
    - *   Ctrl         -> ACTION_COPY
    - *   Shift        -> ACTION_MOVE
    + *   Ctrl + Shift -> ACTION_LINK
    + *   Ctrl         -> ACTION_COPY
    + *   Shift        -> ACTION_MOVE
      * 
    * If the user selects a drop action, the user drop action is one of * DnDConstants that represents the selected drop action if this @@ -88,11 +88,11 @@ public class DropTargetDragEvent extends DropTargetEvent { * @param srcActions The source drop actions * * @throws NullPointerException if cursorLocn is null - * @throws IllegalArgumentException if dropAction is not one of + * @throws IllegalArgumentException if dropAction is not one of * DnDConstants. - * @throws IllegalArgumentException if srcActions is not + * @throws IllegalArgumentException if srcActions is not * a bitwise mask of DnDConstants. - * @throws IllegalArgumentException if dtc is null. + * @throws IllegalArgumentException if dtc is null. */ public DropTargetDragEvent(DropTargetContext dtc, Point cursorLocn, int dropAction, int srcActions) { diff --git a/jdk/src/share/classes/java/awt/dnd/DropTargetDropEvent.java b/jdk/src/share/classes/java/awt/dnd/DropTargetDropEvent.java index 2b36069d8ea..cb6ff209255 100644 --- a/jdk/src/share/classes/java/awt/dnd/DropTargetDropEvent.java +++ b/jdk/src/share/classes/java/awt/dnd/DropTargetDropEvent.java @@ -48,9 +48,9 @@ import java.util.List; * source and the drop action selected by the user. The user can select a drop * action by pressing modifier keys during the drag operation: *
    - *   Ctrl + Shift -> ACTION_LINK
    - *   Ctrl         -> ACTION_COPY
    - *   Shift        -> ACTION_MOVE
    + *   Ctrl + Shift -> ACTION_LINK
    + *   Ctrl         -> ACTION_COPY
    + *   Shift        -> ACTION_MOVE
      * 
    * If the user selects a drop action, the user drop action is one of * DnDConstants that represents the selected drop action if this @@ -92,13 +92,13 @@ public class DropTargetDropEvent extends DropTargetEvent { * @param dropAction the user drop action. * @param srcActions the source drop actions. * - * @throws NullPointerException + * @throws NullPointerException * if cursorLocn is null - * @throws IllegalArgumentException if dropAction is not one of - * DnDConstants. - * @throws IllegalArgumentException if srcActions is not - * a bitwise mask of DnDConstants. - * @throws IllegalArgumentException if dtc is null. + * @throws IllegalArgumentException + * if dropAction is not one of DnDConstants. + * @throws IllegalArgumentException + * if srcActions is not a bitwise mask of DnDConstants. + * @throws IllegalArgumentException if dtc is null. */ public DropTargetDropEvent(DropTargetContext dtc, Point cursorLocn, int dropAction, int srcActions) { @@ -136,13 +136,12 @@ public class DropTargetDropEvent extends DropTargetEvent { * @param srcActions the source drop actions. * @param isLocal True if the source is in the same JVM as the target * - * @throws NullPointerException if cursorLocn is - * null - * @throws IllegalArgumentException if dropAction is not one of - * DnDConstants. - * @throws IllegalArgumentException if srcActions is not - * a bitwise mask of DnDConstants. - * @throws IllegalArgumentException if dtc is null. + * @throws NullPointerException + * if cursorLocn is null + * @throws IllegalArgumentException + * if dropAction is not one of DnDConstants. + * @throws IllegalArgumentException if srcActions is not a bitwise mask of DnDConstants. + * @throws IllegalArgumentException if dtc is null. */ public DropTargetDropEvent(DropTargetContext dtc, Point cursorLocn, int dropAction, int srcActions, boolean isLocal) { From 560d55440f448b00f371f0346c4039ab4faac45b Mon Sep 17 00:00:00 2001 From: Yuri Nesterenko Date: Tue, 24 Sep 2013 16:36:00 +0400 Subject: [PATCH 0475/1294] 8025230: [cleanup] some more javadoc formatting fixes for swing Reviewed-by: alexsch --- jdk/src/share/classes/javax/swing/JPanel.java | 10 ++--- .../classes/javax/swing/JPasswordField.java | 12 ++--- .../share/classes/javax/swing/JPopupMenu.java | 16 +++---- .../classes/javax/swing/JRadioButton.java | 4 +- .../javax/swing/JRadioButtonMenuItem.java | 2 +- .../share/classes/javax/swing/JRootPane.java | 8 ++-- .../classes/javax/swing/JScrollPane.java | 8 ++-- .../share/classes/javax/swing/JSeparator.java | 8 ++-- .../share/classes/javax/swing/JSlider.java | 10 ++--- .../share/classes/javax/swing/JSpinner.java | 8 ++-- .../share/classes/javax/swing/JSplitPane.java | 20 ++++----- jdk/src/share/classes/javax/swing/JTable.java | 22 +++++----- .../share/classes/javax/swing/JTextArea.java | 44 +++++++++---------- .../share/classes/javax/swing/JTextField.java | 6 +-- .../share/classes/javax/swing/JToolBar.java | 10 ++--- .../share/classes/javax/swing/JToolTip.java | 4 +- jdk/src/share/classes/javax/swing/JTree.java | 34 +++++++------- .../share/classes/javax/swing/JViewport.java | 8 ++-- .../share/classes/javax/swing/KeyStroke.java | 10 ++--- .../classes/javax/swing/OverlayLayout.java | 4 +- .../classes/javax/swing/ProgressMonitor.java | 4 +- .../classes/javax/swing/SizeRequirements.java | 16 +++---- .../classes/javax/swing/SizeSequence.java | 18 ++++---- 23 files changed, 143 insertions(+), 143 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JPanel.java b/jdk/src/share/classes/javax/swing/JPanel.java index 288f6814013..7287a53ba27 100644 --- a/jdk/src/share/classes/javax/swing/JPanel.java +++ b/jdk/src/share/classes/javax/swing/JPanel.java @@ -127,7 +127,7 @@ public class JPanel extends JComponent implements Accessible } /** - * Returns the look and feel (L&F) object that renders this component. + * Returns the look and feel (L&amp;F) object that renders this component. * * @return the PanelUI object that renders this component * @since 1.4 @@ -138,9 +138,9 @@ public class JPanel extends JComponent implements Accessible /** - * Sets the look and feel (L&F) object that renders this component. + * Sets the look and feel (L&F) object that renders this component. * - * @param ui the PanelUI L&F object + * @param ui the PanelUI L&F object * @see UIDefaults#getUI * @since 1.4 * @beaninfo @@ -154,7 +154,7 @@ public class JPanel extends JComponent implements Accessible } /** - * Returns a string that specifies the name of the L&F class + * Returns a string that specifies the name of the L&F class * that renders this component. * * @return "PanelUI" @@ -162,7 +162,7 @@ public class JPanel extends JComponent implements Accessible * @see UIDefaults#getUI * @beaninfo * expert: true - * description: A string that specifies the name of the L&F class. + * description: A string that specifies the name of the L&F class. */ public String getUIClassID() { return uiClassID; diff --git a/jdk/src/share/classes/javax/swing/JPasswordField.java b/jdk/src/share/classes/javax/swing/JPasswordField.java index 9be54e1ffd4..1da370921da 100644 --- a/jdk/src/share/classes/javax/swing/JPasswordField.java +++ b/jdk/src/share/classes/javax/swing/JPasswordField.java @@ -101,7 +101,7 @@ public class JPasswordField extends JTextField { * number of columns. A default model is created, and the initial string * is set to null. * - * @param columns the number of columns >= 0 + * @param columns the number of columns >= 0 */ public JPasswordField(int columns) { this(null, null, columns); @@ -113,7 +113,7 @@ public class JPasswordField extends JTextField { * the default. * * @param text the text to be displayed, null if none - * @param columns the number of columns >= 0 + * @param columns the number of columns >= 0 */ public JPasswordField(String text, int columns) { this(null, text, columns); @@ -130,7 +130,7 @@ public class JPasswordField extends JTextField { * @param doc the text storage to use * @param txt the text to be displayed, null if none * @param columns the number of columns to use to calculate - * the preferred width >= 0; if columns is set to zero, the + * the preferred width >= 0; if columns is set to zero, the * preferred width will be whatever naturally results from * the component implementation */ @@ -143,7 +143,7 @@ public class JPasswordField extends JTextField { } /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "PasswordFieldUI" * @see JComponent#getUIClassID @@ -271,8 +271,8 @@ public class JPasswordField extends JTextField { * getPassword method instead. * @deprecated As of Java 2 platform v1.2, * replaced by getPassword. - * @param offs the offset >= 0 - * @param len the length >= 0 + * @param offs the offset >= 0 + * @param len the length >= 0 * @return the text * @exception BadLocationException if the offset or length are invalid */ diff --git a/jdk/src/share/classes/javax/swing/JPopupMenu.java b/jdk/src/share/classes/javax/swing/JPopupMenu.java index 10f9294649f..03532d12fde 100644 --- a/jdk/src/share/classes/javax/swing/JPopupMenu.java +++ b/jdk/src/share/classes/javax/swing/JPopupMenu.java @@ -196,7 +196,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { /** - * Returns the look and feel (L&F) object that renders this component. + * Returns the look and feel (L&F) object that renders this component. * * @return the PopupMenuUI object that renders this component */ @@ -205,9 +205,9 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { } /** - * Sets the L&F object that renders this component. + * Sets the L&F object that renders this component. * - * @param ui the new PopupMenuUI L&F object + * @param ui the new PopupMenuUI L&F object * @see UIDefaults#getUI * @beaninfo * bound: true @@ -230,7 +230,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "PopupMenuUI" * @see JComponent#getUIClassID @@ -461,7 +461,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { * * @param pos the position of the item to be removed * @exception IllegalArgumentException if the value of - * pos < 0, or if the value of + * pos < 0, or if the value of * pos is greater than the * number of items */ @@ -560,7 +560,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { * @param a the Action object to insert * @param index specifies the position at which to insert the * Action, where 0 is the first - * @exception IllegalArgumentException if index < 0 + * @exception IllegalArgumentException if index < 0 * @see Action */ public void insert(Action a, int index) { @@ -576,7 +576,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { * @param component the Component to insert * @param index specifies the position at which * to insert the component, where 0 is the first - * @exception IllegalArgumentException if index < 0 + * @exception IllegalArgumentException if index < 0 */ public void insert(Component component, int index) { if (index < 0) { @@ -1535,7 +1535,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { } /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "PopupMenuSeparatorUI" * @see JComponent#getUIClassID diff --git a/jdk/src/share/classes/javax/swing/JRadioButton.java b/jdk/src/share/classes/javax/swing/JRadioButton.java index 79dd973e436..5d594ceac65 100644 --- a/jdk/src/share/classes/javax/swing/JRadioButton.java +++ b/jdk/src/share/classes/javax/swing/JRadioButton.java @@ -193,7 +193,7 @@ public class JRadioButton extends JToggleButton implements Accessible { /** - * Returns the name of the L&F class + * Returns the name of the L&F class * that renders this component. * * @return String "RadioButtonUI" @@ -201,7 +201,7 @@ public class JRadioButton extends JToggleButton implements Accessible { * @see UIDefaults#getUI * @beaninfo * expert: true - * description: A string that specifies the name of the L&F class. + * description: A string that specifies the name of the L&F class. */ public String getUIClassID() { return uiClassID; diff --git a/jdk/src/share/classes/javax/swing/JRadioButtonMenuItem.java b/jdk/src/share/classes/javax/swing/JRadioButtonMenuItem.java index 0f05f572dba..1c4dd4c81f0 100644 --- a/jdk/src/share/classes/javax/swing/JRadioButtonMenuItem.java +++ b/jdk/src/share/classes/javax/swing/JRadioButtonMenuItem.java @@ -181,7 +181,7 @@ public class JRadioButtonMenuItem extends JMenuItem implements Accessible { } /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "RadioButtonMenuItemUI" * @see JComponent#getUIClassID diff --git a/jdk/src/share/classes/javax/swing/JRootPane.java b/jdk/src/share/classes/javax/swing/JRootPane.java index 542f7e672e3..1f41ccbfd8d 100644 --- a/jdk/src/share/classes/javax/swing/JRootPane.java +++ b/jdk/src/share/classes/javax/swing/JRootPane.java @@ -448,7 +448,7 @@ public class JRootPane extends JComponent implements Accessible { } /** - * Returns the L&F object that renders this component. + * Returns the L&F object that renders this component. * * @return LabelUI object * @since 1.3 @@ -458,9 +458,9 @@ public class JRootPane extends JComponent implements Accessible { } /** - * Sets the L&F object that renders this component. + * Sets the L&F object that renders this component. * - * @param ui the LabelUI L&F object + * @param ui the LabelUI L&F object * @see UIDefaults#getUI * @beaninfo * bound: true @@ -486,7 +486,7 @@ public class JRootPane extends JComponent implements Accessible { /** - * Returns a string that specifies the name of the L&F class + * Returns a string that specifies the name of the L&F class * that renders this component. * * @return the string "RootPaneUI" diff --git a/jdk/src/share/classes/javax/swing/JScrollPane.java b/jdk/src/share/classes/javax/swing/JScrollPane.java index 5cf91f32a6a..25918e5a3c5 100644 --- a/jdk/src/share/classes/javax/swing/JScrollPane.java +++ b/jdk/src/share/classes/javax/swing/JScrollPane.java @@ -353,7 +353,7 @@ public class JScrollPane extends JComponent implements ScrollPaneConstants, Acce /** - * Returns the look and feel (L&F) object that renders this component. + * Returns the look and feel (L&F) object that renders this component. * * @return the ScrollPaneUI object that renders this * component @@ -371,9 +371,9 @@ public class JScrollPane extends JComponent implements ScrollPaneConstants, Acce /** * Sets the ScrollPaneUI object that provides the - * look and feel (L&F) for this component. + * look and feel (L&F) for this component. * - * @param ui the ScrollPaneUI L&F object + * @param ui the ScrollPaneUI L&F object * @see #getUI */ public void setUI(ScrollPaneUI ui) { @@ -395,7 +395,7 @@ public class JScrollPane extends JComponent implements ScrollPaneConstants, Acce /** - * Returns the suffix used to construct the name of the L&F class used to + * Returns the suffix used to construct the name of the L&F class used to * render this component. * * @return the string "ScrollPaneUI" diff --git a/jdk/src/share/classes/javax/swing/JSeparator.java b/jdk/src/share/classes/javax/swing/JSeparator.java index 25567371875..8c5e14f6134 100644 --- a/jdk/src/share/classes/javax/swing/JSeparator.java +++ b/jdk/src/share/classes/javax/swing/JSeparator.java @@ -108,7 +108,7 @@ public class JSeparator extends JComponent implements SwingConstants, Accessible } /** - * Returns the L&F object that renders this component. + * Returns the L&F object that renders this component. * * @return the SeparatorUI object that renders this component */ @@ -117,9 +117,9 @@ public class JSeparator extends JComponent implements SwingConstants, Accessible } /** - * Sets the L&F object that renders this component. + * Sets the L&F object that renders this component. * - * @param ui the SeparatorUI L&F object + * @param ui the SeparatorUI L&F object * @see UIDefaults#getUI * @beaninfo * bound: true @@ -142,7 +142,7 @@ public class JSeparator extends JComponent implements SwingConstants, Accessible /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "SeparatorUI" * @see JComponent#getUIClassID diff --git a/jdk/src/share/classes/javax/swing/JSlider.java b/jdk/src/share/classes/javax/swing/JSlider.java index 94adc94df70..7a948d91b54 100644 --- a/jdk/src/share/classes/javax/swing/JSlider.java +++ b/jdk/src/share/classes/javax/swing/JSlider.java @@ -289,9 +289,9 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { /** - * Gets the UI object which implements the L&F for this component. + * Gets the UI object which implements the L&F for this component. * - * @return the SliderUI object that implements the Slider L&F + * @return the SliderUI object that implements the Slider L&F */ public SliderUI getUI() { return(SliderUI)ui; @@ -299,9 +299,9 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { /** - * Sets the UI object which implements the L&F for this component. + * Sets the UI object which implements the L&F for this component. * - * @param ui the SliderUI L&F object + * @param ui the SliderUI L&F object * @see UIDefaults#getUI * @beaninfo * bound: true @@ -330,7 +330,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return "SliderUI" * @see JComponent#getUIClassID diff --git a/jdk/src/share/classes/javax/swing/JSpinner.java b/jdk/src/share/classes/javax/swing/JSpinner.java index 9b37d07a040..d60f67cfd5e 100644 --- a/jdk/src/share/classes/javax/swing/JSpinner.java +++ b/jdk/src/share/classes/javax/swing/JSpinner.java @@ -171,7 +171,7 @@ public class JSpinner extends JComponent implements Accessible /** - * Returns the look and feel (L&F) object that renders this component. + * Returns the look and feel (L&F) object that renders this component. * * @return the SpinnerUI object that renders this component */ @@ -181,9 +181,9 @@ public class JSpinner extends JComponent implements Accessible /** - * Sets the look and feel (L&F) object that renders this component. + * Sets the look and feel (L&F) object that renders this component. * - * @param ui the SpinnerUI L&F object + * @param ui the SpinnerUI L&F object * @see UIDefaults#getUI */ public void setUI(SpinnerUI ui) { @@ -193,7 +193,7 @@ public class JSpinner extends JComponent implements Accessible /** * Returns the suffix used to construct the name of the look and feel - * (L&F) class used to render this component. + * (L&F) class used to render this component. * * @return the string "SpinnerUI" * @see JComponent#getUIClassID diff --git a/jdk/src/share/classes/javax/swing/JSplitPane.java b/jdk/src/share/classes/javax/swing/JSplitPane.java index fa773e5ae67..622c70f270b 100644 --- a/jdk/src/share/classes/javax/swing/JSplitPane.java +++ b/jdk/src/share/classes/javax/swing/JSplitPane.java @@ -359,9 +359,9 @@ public class JSplitPane extends JComponent implements Accessible /** - * Sets the L&F object that renders this component. + * Sets the L&F object that renders this component. * - * @param ui the SplitPaneUI L&F object + * @param ui the SplitPaneUI L&F object * @see UIDefaults#getUI * @beaninfo * bound: true @@ -384,7 +384,7 @@ public class JSplitPane extends JComponent implements Accessible * @return the SplitPaneUI object that renders this component * @beaninfo * expert: true - * description: The L&F object that renders this component. + * description: The L&F object that renders this component. */ public SplitPaneUI getUI() { return (SplitPaneUI)ui; @@ -392,7 +392,7 @@ public class JSplitPane extends JComponent implements Accessible /** - * Notification from the UIManager that the L&F has changed. + * Notification from the UIManager that the L&F has changed. * Replaces the current UI object with the latest version from the * UIManager. * @@ -405,14 +405,14 @@ public class JSplitPane extends JComponent implements Accessible /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "SplitPaneUI" * @see JComponent#getUIClassID * @see UIDefaults#getUI * @beaninfo * expert: true - * description: A string that specifies the name of the L&F class. + * description: A string that specifies the name of the L&F class. */ public String getUIClassID() { return uiClassID; @@ -714,7 +714,7 @@ public class JSplitPane extends JComponent implements Accessible * extra space. * * @param value as described above - * @exception IllegalArgumentException if value is < 0 or > 1 + * @exception IllegalArgumentException if value is < 0 or > 1 * @since 1.3 * @beaninfo * bound: true @@ -769,8 +769,8 @@ public class JSplitPane extends JComponent implements Accessible * @param proportionalLocation a double-precision floating point value * that specifies a percentage, from zero (top/left) to 1.0 * (bottom/right) - * @exception IllegalArgumentException if the specified location is < 0 - * or > 1.0 + * @exception IllegalArgumentException if the specified location is < 0 + * or > 1.0 * @beaninfo * description: The location of the divider. */ @@ -845,7 +845,7 @@ public class JSplitPane extends JComponent implements Accessible * location (typically a pixel count); or -1 if the UI is * null * @beaninfo - * description: The minimum location of the divider from the L&F. + * description: The minimum location of the divider from the L&F. */ public int getMinimumDividerLocation() { SplitPaneUI ui = getUI(); diff --git a/jdk/src/share/classes/javax/swing/JTable.java b/jdk/src/share/classes/javax/swing/JTable.java index bed8e5ca93e..cf477533c29 100644 --- a/jdk/src/share/classes/javax/swing/JTable.java +++ b/jdk/src/share/classes/javax/swing/JTable.java @@ -1945,7 +1945,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * Sets the table's selection mode to allow only single selections, a single * contiguous interval, or multiple intervals. *

    - * Note: + * Note: * JTable provides all the methods for handling * column and row selection. When setting states, * such as setSelectionMode, it not only @@ -2061,7 +2061,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable /** * Returns true if both row and column selection models are enabled. - * Equivalent to getRowSelectionAllowed() && + * Equivalent to getRowSelectionAllowed() && * getColumnSelectionAllowed(). * * @return true if both row and column selection models are enabled @@ -3034,7 +3034,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * adjusted. * *

    - * Note: When a JTable makes adjustments + * Note: When a JTable makes adjustments * to the widths of the columns it respects their minimum and * maximum values absolutely. It is therefore possible that, * even after this method is called, the total width of the columns @@ -3086,14 +3086,14 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * * where each individual delta[i] is calculated according to: *

    - * If (DELTA < 0) we are in shrink mode where: + * If (DELTA < 0) we are in shrink mode where: *

    *

          *                        DELTA
          *          delta[i] = ------------ * (pref[i] - min[i])
          *                     (PREF - MIN)
          * 
    - * If (DELTA > 0) we are in expand mode where: + * If (DELTA > 0) we are in expand mode where: *

    *

          *                        DELTA
    @@ -3368,7 +3368,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
          * method in order to allow the renderer's tips to be used
          * if it has text set.
          * 

    - * Note: For JTable to properly display + * Note: For JTable to properly display * tooltips of its renderers * JTable must be a registered component with the * ToolTipManager. @@ -3580,7 +3580,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable // /** - * Returns the L&F object that renders this component. + * Returns the L&F object that renders this component. * * @return the TableUI object that renders this component */ @@ -3589,9 +3589,9 @@ public class JTable extends JComponent implements TableModelListener, Scrollable } /** - * Sets the L&F object that renders this component and repaints. + * Sets the L&F object that renders this component and repaints. * - * @param ui the TableUI L&F object + * @param ui the TableUI L&F object * @see UIDefaults#getUI * @beaninfo * bound: true @@ -3607,7 +3607,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable } /** - * Notification from the UIManager that the L&F has changed. + * Notification from the UIManager that the L&F has changed. * Replaces the current UI object with the latest version from the * UIManager. * @@ -3647,7 +3647,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable } /** - * Returns the suffix used to construct the name of the L&F class used to + * Returns the suffix used to construct the name of the L&F class used to * render this component. * * @return the string "TableUI" diff --git a/jdk/src/share/classes/javax/swing/JTextArea.java b/jdk/src/share/classes/javax/swing/JTextArea.java index 2975990eb69..0af83fa9b83 100644 --- a/jdk/src/share/classes/javax/swing/JTextArea.java +++ b/jdk/src/share/classes/javax/swing/JTextArea.java @@ -155,8 +155,8 @@ public class JTextArea extends JTextComponent { * rows and columns. A default model is created, and the initial * string is null. * - * @param rows the number of rows >= 0 - * @param columns the number of columns >= 0 + * @param rows the number of rows >= 0 + * @param columns the number of columns >= 0 * @exception IllegalArgumentException if the rows or columns * arguments are negative. */ @@ -169,8 +169,8 @@ public class JTextArea extends JTextComponent { * of rows and columns. A default model is created. * * @param text the text to be displayed, or null - * @param rows the number of rows >= 0 - * @param columns the number of columns >= 0 + * @param rows the number of rows >= 0 + * @param columns the number of columns >= 0 * @exception IllegalArgumentException if the rows or columns * arguments are negative. */ @@ -195,8 +195,8 @@ public class JTextArea extends JTextComponent { * * @param doc the model to use, or create a default one if null * @param text the text to be displayed, null if none - * @param rows the number of rows >= 0 - * @param columns the number of columns >= 0 + * @param rows the number of rows >= 0 + * @param columns the number of columns >= 0 * @exception IllegalArgumentException if the rows or columns * arguments are negative. */ @@ -364,8 +364,8 @@ public class JTextArea extends JTextComponent { * Translates an offset into the components text to a * line number. * - * @param offset the offset >= 0 - * @return the line number >= 0 + * @param offset the offset >= 0 + * @return the line number >= 0 * @exception BadLocationException thrown if the offset is * less than zero or greater than the document length. */ @@ -384,7 +384,7 @@ public class JTextArea extends JTextComponent { /** * Determines the number of lines contained in the area. * - * @return the number of lines > 0 + * @return the number of lines > 0 */ public int getLineCount() { Element map = getDocument().getDefaultRootElement(); @@ -394,8 +394,8 @@ public class JTextArea extends JTextComponent { /** * Determines the offset of the start of the given line. * - * @param line the line number to translate >= 0 - * @return the offset >= 0 + * @param line the line number to translate >= 0 + * @return the offset >= 0 * @exception BadLocationException thrown if the line is * less than zero or greater or equal to the number of * lines contained in the document (as reported by @@ -417,8 +417,8 @@ public class JTextArea extends JTextComponent { /** * Determines the offset of the end of the given line. * - * @param line the line >= 0 - * @return the offset >= 0 + * @param line the line >= 0 + * @return the offset >= 0 * @exception BadLocationException Thrown if the line is * less than zero or greater or equal to the number of * lines contained in the document (as reported by @@ -446,7 +446,7 @@ public class JTextArea extends JTextComponent { * if the model is null or if the text is null or empty. * * @param str the text to insert - * @param pos the position at which to insert >= 0 + * @param pos the position at which to insert >= 0 * @exception IllegalArgumentException if pos is an * invalid position in the model * @see TextComponent#setText @@ -486,8 +486,8 @@ public class JTextArea extends JTextComponent { * does a delete if the new string is null or empty. * * @param str the text to use as the replacement - * @param start the start position >= 0 - * @param end the end position >= start + * @param start the start position >= 0 + * @param end the end position >= start * @exception IllegalArgumentException if part of the range is an * invalid position in the model * @see #insert @@ -517,7 +517,7 @@ public class JTextArea extends JTextComponent { /** * Returns the number of rows in the TextArea. * - * @return the number of rows >= 0 + * @return the number of rows >= 0 */ public int getRows() { return rows; @@ -527,7 +527,7 @@ public class JTextArea extends JTextComponent { * Sets the number of rows for this TextArea. Calls invalidate() after * setting the new value. * - * @param rows the number of rows >= 0 + * @param rows the number of rows >= 0 * @exception IllegalArgumentException if rows is less than 0 * @see #getRows * @beaninfo @@ -548,7 +548,7 @@ public class JTextArea extends JTextComponent { * Defines the meaning of the height of a row. This defaults to * the height of the font. * - * @return the height >= 1 + * @return the height >= 1 */ protected int getRowHeight() { if (rowHeight == 0) { @@ -561,7 +561,7 @@ public class JTextArea extends JTextComponent { /** * Returns the number of columns in the TextArea. * - * @return number of columns >= 0 + * @return number of columns >= 0 */ public int getColumns() { return columns; @@ -571,7 +571,7 @@ public class JTextArea extends JTextComponent { * Sets the number of columns for this TextArea. Does an invalidate() * after setting the new value. * - * @param columns the number of columns >= 0 + * @param columns the number of columns >= 0 * @exception IllegalArgumentException if columns is less than 0 * @see #getColumns * @beaninfo @@ -596,7 +596,7 @@ public class JTextArea extends JTextComponent { * character m for the font used. This method can be * redefined to be some alternative amount. * - * @return the column width >= 1 + * @return the column width >= 1 */ protected int getColumnWidth() { if (columnWidth == 0) { diff --git a/jdk/src/share/classes/javax/swing/JTextField.java b/jdk/src/share/classes/javax/swing/JTextField.java index 6451246bf3a..2fd75f0832d 100644 --- a/jdk/src/share/classes/javax/swing/JTextField.java +++ b/jdk/src/share/classes/javax/swing/JTextField.java @@ -128,7 +128,7 @@ import java.io.Serializable;   return;   }   char[] upper = str.toCharArray(); -  for (int i = 0; i < upper.length; i++) { +  for (int i = 0; i < upper.length; i++) {   upper[i] = Character.toUpperCase(upper[i]);   }   super.insertString(offs, new String(upper), a); @@ -223,10 +223,10 @@ public class JTextField extends JTextComponent implements SwingConstants { * createDefaultModel method * @param text the initial string to display, or null * @param columns the number of columns to use to calculate - * the preferred width >= 0; if columns + * the preferred width >= 0; if columns * is set to zero, the preferred width will be whatever * naturally results from the component implementation - * @exception IllegalArgumentException if columns < 0 + * @exception IllegalArgumentException if columns < 0 */ public JTextField(Document doc, String text, int columns) { if (columns < 0) { diff --git a/jdk/src/share/classes/javax/swing/JToolBar.java b/jdk/src/share/classes/javax/swing/JToolBar.java index 5ae0ff90bc2..b1a8c87c609 100644 --- a/jdk/src/share/classes/javax/swing/JToolBar.java +++ b/jdk/src/share/classes/javax/swing/JToolBar.java @@ -167,9 +167,9 @@ public class JToolBar extends JComponent implements SwingConstants, Accessible } /** - * Sets the L&F object that renders this component. + * Sets the L&F object that renders this component. * - * @param ui the ToolBarUI L&F object + * @param ui the ToolBarUI L&F object * @see UIDefaults#getUI * @beaninfo * bound: true @@ -182,7 +182,7 @@ public class JToolBar extends JComponent implements SwingConstants, Accessible } /** - * Notification from the UIFactory that the L&F has changed. + * Notification from the UIFactory that the L&F has changed. * Called to replace the UI with the latest version from the * UIFactory. * @@ -202,7 +202,7 @@ public class JToolBar extends JComponent implements SwingConstants, Accessible /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "ToolBarUI" * @see JComponent#getUIClassID @@ -613,7 +613,7 @@ public class JToolBar extends JComponent implements SwingConstants, Accessible } /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "ToolBarSeparatorUI" * @see JComponent#getUIClassID diff --git a/jdk/src/share/classes/javax/swing/JToolTip.java b/jdk/src/share/classes/javax/swing/JToolTip.java index ac79d465ef5..77b29eaed21 100644 --- a/jdk/src/share/classes/javax/swing/JToolTip.java +++ b/jdk/src/share/classes/javax/swing/JToolTip.java @@ -85,7 +85,7 @@ public class JToolTip extends JComponent implements Accessible { } /** - * Returns the L&F object that renders this component. + * Returns the L&F object that renders this component. * * @return the ToolTipUI object that renders this component */ @@ -104,7 +104,7 @@ public class JToolTip extends JComponent implements Accessible { /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "ToolTipUI" * @see JComponent#getUIClassID diff --git a/jdk/src/share/classes/javax/swing/JTree.java b/jdk/src/share/classes/javax/swing/JTree.java index 09b31da9f28..56aaca10d8e 100644 --- a/jdk/src/share/classes/javax/swing/JTree.java +++ b/jdk/src/share/classes/javax/swing/JTree.java @@ -41,7 +41,7 @@ import static sun.swing.SwingUtilities2.Section.*; /** - * + * * A control that displays a set of hierarchical data as an outline. * You can find task-oriented documentation and examples of using trees in * How to Use Trees, @@ -59,7 +59,7 @@ import static sun.swing.SwingUtilities2.Section.*; * under a collapsed ancestor. All of a viewable nodes parents * are expanded, but may or may not be displayed. A displayed node * is both viewable and in the display area, where it can be seen. - *

    + *

    * The following JTree methods use "visible" to mean "displayed": *
      *
    • isRootVisible() @@ -69,14 +69,12 @@ import static sun.swing.SwingUtilities2.Section.*; *
    • getVisibleRowCount() *
    • setVisibleRowCount() *
    - *

    * The next group of JTree methods use "visible" to mean * "viewable" (under an expanded parent): *

      *
    • isVisible() *
    • makeVisible() *
    - *

    * If you are interested in knowing when the selection changes implement * the TreeSelectionListener interface and add the instance * using the method addTreeSelectionListener. @@ -87,6 +85,7 @@ import static sun.swing.SwingUtilities2.Section.*; * If you are interested in detecting either double-click events or when * a user clicks on a node, regardless of whether or not it was selected, * we recommend you do the following: + *

    *
      * final JTree tree = ...;
      *
    @@ -114,12 +113,13 @@ import static sun.swing.SwingUtilities2.Section.*;
      * a graphic icon and text), subclass {@link TreeCellRenderer} and use
      * {@link #setCellRenderer} to tell the tree to use it. To edit such nodes,
      * subclass {@link TreeCellEditor} and use {@link #setCellEditor}.
    + * 

    *

    * Like all JComponent classes, you can use {@link InputMap} and * {@link ActionMap} * to associate an {@link Action} object with a {@link KeyStroke} * and execute the action under specified conditions. - *

    + *

    * Warning: Swing is not thread safe. For more * information see Swing's Threading @@ -133,7 +133,7 @@ import static sun.swing.SwingUtilities2.Section.*; * of all JavaBeansTM * has been added to the java.beans package. * Please see {@link java.beans.XMLEncoder}. - * + *

    * @beaninfo * attribute: isContainer false * description: A component that displays a set of hierarchical data as an outline. @@ -174,7 +174,7 @@ public class JTree extends JComponent implements Scrollable, Accessible transient protected TreeCellRenderer cellRenderer; /** - * Height to use for each display row. If this is <= 0 the renderer + * Height to use for each display row. If this is <= 0 the renderer * determines the height for each row. */ protected int rowHeight; @@ -671,7 +671,7 @@ public class JTree extends JComponent implements Scrollable, Accessible } /** - * Returns the L&F object that renders this component. + * Returns the L&F object that renders this component. * * @return the TreeUI object that renders this component */ @@ -680,11 +680,11 @@ public class JTree extends JComponent implements Scrollable, Accessible } /** - * Sets the L&F object that renders this component. + * Sets the L&F object that renders this component. *

    * This is a bound property. * - * @param ui the TreeUI L&F object + * @param ui the TreeUI L&F object * @see UIDefaults#getUI * @beaninfo * bound: true @@ -706,7 +706,7 @@ public class JTree extends JComponent implements Scrollable, Accessible } /** - * Notification from the UIManager that the L&F has changed. + * Notification from the UIManager that the L&F has changed. * Replaces the current UI object with the latest version from the * UIManager. * @@ -721,7 +721,7 @@ public class JTree extends JComponent implements Scrollable, Accessible /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "TreeUI" * @see JComponent#getUIClassID @@ -1701,7 +1701,7 @@ public class JTree extends JComponent implements Scrollable, Accessible /** * Selects the nodes corresponding to each of the specified rows * in the display. If a particular element of rows is - * < 0 or >= getRowCount, it will be ignored. + * < 0 or >= getRowCount, it will be ignored. * If none of the elements * in rows are valid rows, the selection will * be cleared. That is it will be as if clearSelection @@ -2162,8 +2162,8 @@ public class JTree extends JComponent implements Scrollable, Accessible * * @param row an integer specifying a row * @return the TreePath to the specified node, - * null if row < 0 - * or row >= getRowCount() + * null if row < 0 + * or row >= getRowCount() */ public TreePath getPathForRow(int row) { TreeUI tree = getUI(); @@ -2211,7 +2211,7 @@ public class JTree extends JComponent implements Scrollable, Accessible * Ensures that the node in the specified row is expanded and * viewable. *

    - * If row is < 0 or >= getRowCount this + * If row is < 0 or >= getRowCount this * will have no effect. * * @param row an integer specifying a display row, where 0 is the @@ -2234,7 +2234,7 @@ public class JTree extends JComponent implements Scrollable, Accessible /** * Ensures that the node in the specified row is collapsed. *

    - * If row is < 0 or >= getRowCount this + * If row is < 0 or >= getRowCount this * will have no effect. * * @param row an integer specifying a display row, where 0 is the diff --git a/jdk/src/share/classes/javax/swing/JViewport.java b/jdk/src/share/classes/javax/swing/JViewport.java index c271533e53e..7d546a88d9c 100644 --- a/jdk/src/share/classes/javax/swing/JViewport.java +++ b/jdk/src/share/classes/javax/swing/JViewport.java @@ -285,7 +285,7 @@ public class JViewport extends JComponent implements Accessible /** - * Returns the L&F object that renders this component. + * Returns the L&F object that renders this component. * * @return a ViewportUI object * @since 1.3 @@ -296,9 +296,9 @@ public class JViewport extends JComponent implements Accessible /** - * Sets the L&F object that renders this component. + * Sets the L&F object that renders this component. * - * @param ui the ViewportUI L&F object + * @param ui the ViewportUI L&F object * @see UIDefaults#getUI * @beaninfo * bound: true @@ -323,7 +323,7 @@ public class JViewport extends JComponent implements Accessible /** - * Returns a string that specifies the name of the L&F class + * Returns a string that specifies the name of the L&F class * that renders this component. * * @return the string "ViewportUI" diff --git a/jdk/src/share/classes/javax/swing/KeyStroke.java b/jdk/src/share/classes/javax/swing/KeyStroke.java index 1cf1e841bcc..9aaa15d21c6 100644 --- a/jdk/src/share/classes/javax/swing/KeyStroke.java +++ b/jdk/src/share/classes/javax/swing/KeyStroke.java @@ -284,11 +284,11 @@ public class KeyStroke extends AWTKeyStroke { * If typed, pressed or released is not specified, pressed is assumed. Here * are some examples: *

    -     *     "INSERT" => getKeyStroke(KeyEvent.VK_INSERT, 0);
    -     *     "control DELETE" => getKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK);
    -     *     "alt shift X" => getKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);
    -     *     "alt shift released X" => getKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK, true);
    -     *     "typed a" => getKeyStroke('a');
    +     *     "INSERT" => getKeyStroke(KeyEvent.VK_INSERT, 0);
    +     *     "control DELETE" => getKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK);
    +     *     "alt shift X" => getKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);
    +     *     "alt shift released X" => getKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK, true);
    +     *     "typed a" => getKeyStroke('a');
          * 
    * * In order to maintain backward-compatibility, specifying a null String, diff --git a/jdk/src/share/classes/javax/swing/OverlayLayout.java b/jdk/src/share/classes/javax/swing/OverlayLayout.java index a6fd8e86fc9..89c47c02a40 100644 --- a/jdk/src/share/classes/javax/swing/OverlayLayout.java +++ b/jdk/src/share/classes/javax/swing/OverlayLayout.java @@ -190,7 +190,7 @@ public class OverlayLayout implements LayoutManager2,Serializable { * Returns the alignment along the x axis for the container. * * @param target the container - * @return the alignment >= 0.0f && <= 1.0f + * @return the alignment >= 0.0f && <= 1.0f */ public float getLayoutAlignmentX(Container target) { checkContainer(target); @@ -202,7 +202,7 @@ public class OverlayLayout implements LayoutManager2,Serializable { * Returns the alignment along the y axis for the container. * * @param target the container - * @return the alignment >= 0.0f && <= 1.0f + * @return the alignment >= 0.0f && <= 1.0f */ public float getLayoutAlignmentY(Container target) { checkContainer(target); diff --git a/jdk/src/share/classes/javax/swing/ProgressMonitor.java b/jdk/src/share/classes/javax/swing/ProgressMonitor.java index a7be24d388b..ebfa7389018 100644 --- a/jdk/src/share/classes/javax/swing/ProgressMonitor.java +++ b/jdk/src/share/classes/javax/swing/ProgressMonitor.java @@ -251,7 +251,7 @@ public class ProgressMonitor implements Accessible /** * Indicate the progress of the operation being monitored. - * If the specified value is >= the maximum, the progress + * If the specified value is >= the maximum, the progress * monitor is closed. * @param nv an int specifying the current value, between the * maximum and minimum specified for this component @@ -302,7 +302,7 @@ public class ProgressMonitor implements Accessible /** * Indicate that the operation is complete. This happens automatically - * when the value set by setProgress is >= max, but it may be called + * when the value set by setProgress is >= max, but it may be called * earlier if the operation ends early. */ public void close() { diff --git a/jdk/src/share/classes/javax/swing/SizeRequirements.java b/jdk/src/share/classes/javax/swing/SizeRequirements.java index 6208f8a07fb..a1def55cd37 100644 --- a/jdk/src/share/classes/javax/swing/SizeRequirements.java +++ b/jdk/src/share/classes/javax/swing/SizeRequirements.java @@ -142,10 +142,10 @@ public class SizeRequirements implements Serializable { * Creates a SizeRequirements object with the specified minimum, preferred, * and maximum sizes and the specified alignment. * - * @param min the minimum size >= 0 - * @param pref the preferred size >= 0 - * @param max the maximum size >= 0 - * @param a the alignment >= 0.0f && <= 1.0f + * @param min the minimum size >= 0 + * @param pref the preferred size >= 0 + * @param max the maximum size >= 0 + * @param a the alignment >= 0.0f && <= 1.0f */ public SizeRequirements(int min, int pref, int max, float a) { minimum = min; @@ -246,7 +246,7 @@ public class SizeRequirements implements Serializable { * by invoking the getTiledSizeRequirements method. The components * will be tiled in the forward direction with offsets increasing from 0. * - * @param allocated the total span to be allocated >= 0. + * @param allocated the total span to be allocated >= 0. * @param total the total of the children requests. This argument * is optional and may be null. * @param children the size requirements for each component. @@ -282,7 +282,7 @@ public class SizeRequirements implements Serializable { * reverse direction represents components tiled from right to left * or bottom to top. * - * @param allocated the total span to be allocated >= 0. + * @param allocated the total span to be allocated >= 0. * @param total the total of the children requests. This argument * is optional and may be null. * @param children the size requirements for each component. @@ -405,7 +405,7 @@ public class SizeRequirements implements Serializable { * Normal alignment will be done with an alignment value of 0.0f * representing the left/top edge of a component. * - * @param allocated the total span to be allocated >= 0. + * @param allocated the total span to be allocated >= 0. * @param total the total of the children requests. * @param children the size requirements for each component. * @param offsets the offset from 0 for each child where @@ -441,7 +441,7 @@ public class SizeRequirements implements Serializable { * to be aligned. With reverse alignment, 0.0f represents the * right/bottom edge. * - * @param allocated the total span to be allocated >= 0. + * @param allocated the total span to be allocated >= 0. * @param total the total of the children requests. * @param children the size requirements for each component. * @param offsets the offset from 0 for each child where diff --git a/jdk/src/share/classes/javax/swing/SizeSequence.java b/jdk/src/share/classes/javax/swing/SizeSequence.java index 5ebe6dd234b..a04fe2cb867 100644 --- a/jdk/src/share/classes/javax/swing/SizeSequence.java +++ b/jdk/src/share/classes/javax/swing/SizeSequence.java @@ -78,7 +78,7 @@ package javax.swing; * *

    * - *

    Implementation Notes

    + *

    Implementation Notes

    * * Normally when storing the size and position of entries, * one would choose between @@ -145,7 +145,7 @@ public class SizeSequence { * * @param numEntries the number of sizes to track * @exception NegativeArraySizeException if - * numEntries < 0 + * numEntries < 0 */ public SizeSequence(int numEntries) { this(numEntries, 0); @@ -306,7 +306,7 @@ public class SizeSequence { /** * Returns the size of the specified entry. * If index is out of the range - * (0 <= index < getSizes().length) + * (0 <= index < getSizes().length) * the behavior is unspecified. * * @param index the index corresponding to the entry @@ -320,7 +320,7 @@ public class SizeSequence { * Sets the size of the specified entry. * Note that if the value of index * does not fall in the range: - * (0 <= index < getSizes().length) + * (0 <= index < getSizes().length) * the behavior is unspecified. * * @param index the index corresponding to the entry @@ -348,8 +348,8 @@ public class SizeSequence { * Adds a contiguous group of entries to this SizeSequence. * Note that the values of start and * length must satisfy the following - * conditions: (0 <= start < getSizes().length) - * AND (length >= 0). If these conditions are + * conditions: (0 <= start < getSizes().length) + * AND (length >= 0). If these conditions are * not met, the behavior is unspecified and an exception * may be thrown. * @@ -359,7 +359,7 @@ public class SizeSequence { * @param value the size to be assigned to each new entry * @exception ArrayIndexOutOfBoundsException if the parameters * are outside of the range: - * (0 <= start < (getSizes().length)) AND (length >= 0) + * (0 <= start < (getSizes().length)) AND (length >= 0) */ public void insertEntries(int start, int length, int value) { int sizes[] = getSizes(); @@ -383,8 +383,8 @@ public class SizeSequence { * from this SizeSequence. * Note that the values of start and * length must satisfy the following - * conditions: (0 <= start < getSizes().length) - * AND (length >= 0). If these conditions are + * conditions: (0 <= start < getSizes().length) + * AND (length >= 0). If these conditions are * not met, the behavior is unspecified and an exception * may be thrown. * From bd9ffce26767c480b4b4212d414f22bb712bb4a1 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Thu, 26 Sep 2013 12:49:45 +0200 Subject: [PATCH 0476/1294] 8014078: G1: improve remembered set summary information by providing per region type information Add memory consumption breakdown on a per region type in the G1 remembered set summary statistics. This simplifies remembered set memory consumption analysis. Reviewed-by: brutisso --- .../gc_implementation/g1/g1CollectedHeap.cpp | 7 +- .../vm/gc_implementation/g1/g1RemSet.cpp | 4 +- .../vm/gc_implementation/g1/g1RemSet.hpp | 2 +- .../gc_implementation/g1/g1RemSetSummary.cpp | 243 +++++++++++++----- .../test/gc/g1/TestSummarizeRSetStats.java | 149 +++-------- .../g1/TestSummarizeRSetStatsPerRegion.java | 55 ++++ .../gc/g1/TestSummarizeRSetStatsTools.java | 154 +++++++++++ 7 files changed, 430 insertions(+), 184 deletions(-) create mode 100644 hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java create mode 100644 hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 0ecfd3ab3bb..eff0efc6e0f 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -3681,6 +3681,11 @@ void G1CollectedHeap::gc_prologue(bool full /* Ignored */) { assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer"); // Fill TLAB's and such ensure_parsability(true); + + if (G1SummarizeRSetStats && (G1SummarizeRSetStatsPeriod > 0) && + (total_collections() % G1SummarizeRSetStatsPeriod == 0)) { + g1_rem_set()->print_periodic_summary_info("Before GC RS summary"); + } } void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) { @@ -3689,7 +3694,7 @@ void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) { (G1SummarizeRSetStatsPeriod > 0) && // we are at the end of the GC. Total collections has already been increased. ((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) { - g1_rem_set()->print_periodic_summary_info(); + g1_rem_set()->print_periodic_summary_info("After GC RS summary"); } // FIXME: what is this about? diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp index 5a1b92d3422..a8c580b60cd 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp @@ -731,12 +731,12 @@ bool G1RemSet::refine_card(jbyte* card_ptr, int worker_i, return has_refs_into_cset; } -void G1RemSet::print_periodic_summary_info() { +void G1RemSet::print_periodic_summary_info(const char* header) { G1RemSetSummary current; current.initialize(this, n_workers()); _prev_period_summary.subtract_from(¤t); - print_summary_info(&_prev_period_summary); + print_summary_info(&_prev_period_summary, header); _prev_period_summary.set(¤t); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp index 513945609fc..7c010f9daf6 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp @@ -145,7 +145,7 @@ public: virtual void print_summary_info(); // Print accumulated summary info from the last time called. - virtual void print_periodic_summary_info(); + virtual void print_periodic_summary_info(const char* header); // Prepare remembered set for verification. virtual void prepare_for_verify(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp index 4a6b37654d7..02e90d65103 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp @@ -125,25 +125,115 @@ void G1RemSetSummary::subtract_from(G1RemSetSummary* other) { _sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime; } -class HRRSStatsIter: public HeapRegionClosure { - size_t _occupied; +static double percent_of(size_t numerator, size_t denominator) { + if (denominator != 0) { + return (double)numerator / denominator * 100.0f; + } else { + return 0.0f; + } +} + +static size_t round_to_K(size_t value) { + return value / K; +} + +class RegionTypeCounter VALUE_OBJ_CLASS_SPEC { +private: + const char* _name; + + size_t _rs_mem_size; + size_t _cards_occupied; + size_t _amount; + + size_t _code_root_mem_size; + size_t _code_root_elems; + + double rs_mem_size_percent_of(size_t total) { + return percent_of(_rs_mem_size, total); + } + + double cards_occupied_percent_of(size_t total) { + return percent_of(_cards_occupied, total); + } + + double code_root_mem_size_percent_of(size_t total) { + return percent_of(_code_root_mem_size, total); + } + + double code_root_elems_percent_of(size_t total) { + return percent_of(_code_root_elems, total); + } + + size_t amount() const { return _amount; } + +public: + + RegionTypeCounter(const char* name) : _name(name), _rs_mem_size(0), _cards_occupied(0), + _amount(0), _code_root_mem_size(0), _code_root_elems(0) { } + + void add(size_t rs_mem_size, size_t cards_occupied, size_t code_root_mem_size, + size_t code_root_elems) { + _rs_mem_size += rs_mem_size; + _cards_occupied += cards_occupied; + _code_root_mem_size += code_root_mem_size; + _code_root_elems += code_root_elems; + _amount++; + } + + size_t rs_mem_size() const { return _rs_mem_size; } + size_t cards_occupied() const { return _cards_occupied; } + + size_t code_root_mem_size() const { return _code_root_mem_size; } + size_t code_root_elems() const { return _code_root_elems; } + + void print_rs_mem_info_on(outputStream * out, size_t total) { + out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name); + } + + void print_cards_occupied_info_on(outputStream * out, size_t total) { + out->print_cr(" %8d (%5.1f%%) entries by %zd %s regions", cards_occupied(), cards_occupied_percent_of(total), amount(), _name); + } + + void print_code_root_mem_info_on(outputStream * out, size_t total) { + out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", round_to_K(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name); + } + + void print_code_root_elems_info_on(outputStream * out, size_t total) { + out->print_cr(" %8d (%5.1f%%) elements by %zd %s regions", code_root_elems(), code_root_elems_percent_of(total), amount(), _name); + } +}; + + +class HRRSStatsIter: public HeapRegionClosure { +private: + RegionTypeCounter _young; + RegionTypeCounter _humonguous; + RegionTypeCounter _free; + RegionTypeCounter _old; + RegionTypeCounter _all; - size_t _total_rs_mem_sz; size_t _max_rs_mem_sz; HeapRegion* _max_rs_mem_sz_region; - size_t _total_code_root_mem_sz; + size_t total_rs_mem_sz() const { return _all.rs_mem_size(); } + size_t total_cards_occupied() const { return _all.cards_occupied(); } + + size_t max_rs_mem_sz() const { return _max_rs_mem_sz; } + HeapRegion* max_rs_mem_sz_region() const { return _max_rs_mem_sz_region; } + size_t _max_code_root_mem_sz; HeapRegion* _max_code_root_mem_sz_region; + + size_t total_code_root_mem_sz() const { return _all.code_root_mem_size(); } + size_t total_code_root_elems() const { return _all.code_root_elems(); } + + size_t max_code_root_mem_sz() const { return _max_code_root_mem_sz; } + HeapRegion* max_code_root_mem_sz_region() const { return _max_code_root_mem_sz_region; } + public: - HRRSStatsIter() : - _occupied(0), - _total_rs_mem_sz(0), - _max_rs_mem_sz(0), - _max_rs_mem_sz_region(NULL), - _total_code_root_mem_sz(0), - _max_code_root_mem_sz(0), - _max_code_root_mem_sz_region(NULL) + HRRSStatsIter() : _all("All"), _young("Young"), _humonguous("Humonguous"), + _free("Free"), _old("Old"), _max_code_root_mem_sz_region(NULL), _max_rs_mem_sz_region(NULL), + _max_rs_mem_sz(0), _max_code_root_mem_sz(0) {} bool doHeapRegion(HeapRegion* r) { @@ -156,46 +246,95 @@ public: _max_rs_mem_sz = rs_mem_sz; _max_rs_mem_sz_region = r; } - _total_rs_mem_sz += rs_mem_sz; - + size_t occupied_cards = hrrs->occupied(); size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size(); - if (code_root_mem_sz > _max_code_root_mem_sz) { - _max_code_root_mem_sz = code_root_mem_sz; + if (code_root_mem_sz > max_code_root_mem_sz()) { _max_code_root_mem_sz_region = r; } - _total_code_root_mem_sz += code_root_mem_sz; + size_t code_root_elems = hrrs->strong_code_roots_list_length(); + + RegionTypeCounter* current = NULL; + if (r->is_young()) { + current = &_young; + } else if (r->isHumongous()) { + current = &_humonguous; + } else if (r->is_empty()) { + current = &_free; + } else { + current = &_old; + } + current->add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems); + _all.add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems); - size_t occ = hrrs->occupied(); - _occupied += occ; return false; } - size_t total_rs_mem_sz() { return _total_rs_mem_sz; } - size_t max_rs_mem_sz() { return _max_rs_mem_sz; } - HeapRegion* max_rs_mem_sz_region() { return _max_rs_mem_sz_region; } - size_t total_code_root_mem_sz() { return _total_code_root_mem_sz; } - size_t max_code_root_mem_sz() { return _max_code_root_mem_sz; } - HeapRegion* max_code_root_mem_sz_region() { return _max_code_root_mem_sz_region; } - size_t occupied() { return _occupied; } + + void print_summary_on(outputStream* out) { + RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL }; + + out->print_cr("\n Current rem set statistics"); + out->print_cr(" Total per region rem sets sizes = "SIZE_FORMAT"K." + " Max = "SIZE_FORMAT"K.", + round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz())); + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { + (*current)->print_rs_mem_info_on(out, total_rs_mem_sz()); + } + + out->print_cr(" Static structures = "SIZE_FORMAT"K," + " free_lists = "SIZE_FORMAT"K.", + round_to_K(HeapRegionRemSet::static_mem_size()), + round_to_K(HeapRegionRemSet::fl_mem_size())); + + out->print_cr(" "SIZE_FORMAT" occupied cards represented.", + total_cards_occupied()); + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { + (*current)->print_cards_occupied_info_on(out, total_cards_occupied()); + } + + // Largest sized rem set region statistics + HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set(); + out->print_cr(" Region with largest rem set = "HR_FORMAT", " + "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.", + HR_FORMAT_PARAMS(max_rs_mem_sz_region()), + round_to_K(rem_set->mem_size()), + round_to_K(rem_set->occupied())); + + // Strong code root statistics + HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set(); + out->print_cr(" Total heap region code root sets sizes = "SIZE_FORMAT"K." + " Max = "SIZE_FORMAT"K.", + round_to_K(total_code_root_mem_sz()), + round_to_K(max_code_root_rem_set->strong_code_roots_mem_size())); + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { + (*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz()); + } + + out->print_cr(" "SIZE_FORMAT" code roots represented.", + total_code_root_elems()); + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { + (*current)->print_code_root_elems_info_on(out, total_code_root_elems()); + } + + out->print_cr(" Region with largest amount of code roots = "HR_FORMAT", " + "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".", + HR_FORMAT_PARAMS(max_code_root_mem_sz_region()), + round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()), + round_to_K(max_code_root_rem_set->strong_code_roots_list_length())); + } }; -double calc_percentage(size_t numerator, size_t denominator) { - if (denominator != 0) { - return (double)numerator / denominator * 100.0; - } else { - return 0.0f; - } -} - void G1RemSetSummary::print_on(outputStream* out) { - out->print_cr("\n Concurrent RS processed "SIZE_FORMAT" cards", + out->print_cr("\n Recent concurrent refinement statistics"); + out->print_cr(" Processed "SIZE_FORMAT" cards", num_concurrent_refined_cards()); out->print_cr(" Of %d completed buffers:", num_processed_buf_total()); out->print_cr(" %8d (%5.1f%%) by concurrent RS threads.", num_processed_buf_total(), - calc_percentage(num_processed_buf_rs_threads(), num_processed_buf_total())); + percent_of(num_processed_buf_rs_threads(), num_processed_buf_total())); out->print_cr(" %8d (%5.1f%%) by mutator threads.", num_processed_buf_mutator(), - calc_percentage(num_processed_buf_mutator(), num_processed_buf_total())); + percent_of(num_processed_buf_mutator(), num_processed_buf_total())); + out->print_cr(" Did %d coarsenings.", num_coarsenings()); out->print_cr(" Concurrent RS threads times (s)"); out->print(" "); for (uint i = 0; i < _num_vtimes; i++) { @@ -207,33 +346,5 @@ void G1RemSetSummary::print_on(outputStream* out) { HRRSStatsIter blk; G1CollectedHeap::heap()->heap_region_iterate(&blk); - // RemSet stats - out->print_cr(" Total heap region rem set sizes = "SIZE_FORMAT"K." - " Max = "SIZE_FORMAT"K.", - blk.total_rs_mem_sz()/K, blk.max_rs_mem_sz()/K); - out->print_cr(" Static structures = "SIZE_FORMAT"K," - " free_lists = "SIZE_FORMAT"K.", - HeapRegionRemSet::static_mem_size() / K, - HeapRegionRemSet::fl_mem_size() / K); - out->print_cr(" "SIZE_FORMAT" occupied cards represented.", - blk.occupied()); - HeapRegion* max_rs_mem_sz_region = blk.max_rs_mem_sz_region(); - HeapRegionRemSet* max_rs_rem_set = max_rs_mem_sz_region->rem_set(); - out->print_cr(" Max size region = "HR_FORMAT", " - "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.", - HR_FORMAT_PARAMS(max_rs_mem_sz_region), - (max_rs_rem_set->mem_size() + K - 1)/K, - (max_rs_rem_set->occupied() + K - 1)/K); - out->print_cr(" Did %d coarsenings.", num_coarsenings()); - // Strong code root stats - out->print_cr(" Total heap region code-root set sizes = "SIZE_FORMAT"K." - " Max = "SIZE_FORMAT"K.", - blk.total_code_root_mem_sz()/K, blk.max_code_root_mem_sz()/K); - HeapRegion* max_code_root_mem_sz_region = blk.max_code_root_mem_sz_region(); - HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region->rem_set(); - out->print_cr(" Max size region = "HR_FORMAT", " - "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".", - HR_FORMAT_PARAMS(max_code_root_mem_sz_region), - (max_code_root_rem_set->strong_code_roots_mem_size() + K - 1)/K, - (max_code_root_rem_set->strong_code_roots_list_length())); + blk.print_summary_on(out); } diff --git a/hotspot/test/gc/g1/TestSummarizeRSetStats.java b/hotspot/test/gc/g1/TestSummarizeRSetStats.java index 1990d4c6f39..e78e2df21a3 100644 --- a/hotspot/test/gc/g1/TestSummarizeRSetStats.java +++ b/hotspot/test/gc/g1/TestSummarizeRSetStats.java @@ -25,140 +25,61 @@ * @test TestSummarizeRSetStats.java * @bug 8013895 * @library /testlibrary - * @build TestSummarizeRSetStats + * @build TestSummarizeRSetStatsTools TestSummarizeRSetStats * @summary Verify output of -XX:+G1SummarizeRSetStats * @run main TestSummarizeRSetStats * * Test the output of G1SummarizeRSetStats in conjunction with G1SummarizeRSetStatsPeriod. */ -import com.oracle.java.testlibrary.*; -import java.lang.Thread; -import java.util.ArrayList; -import java.util.Arrays; - -class RunSystemGCs { - // 4M size, both are directly allocated into the old gen - static Object[] largeObject1 = new Object[1024 * 1024]; - static Object[] largeObject2 = new Object[1024 * 1024]; - - static int[] temp; - - public static void main(String[] args) { - // create some cross-references between these objects - for (int i = 0; i < largeObject1.length; i++) { - largeObject1[i] = largeObject2; - } - - for (int i = 0; i < largeObject2.length; i++) { - largeObject2[i] = largeObject1; - } - - int numGCs = Integer.parseInt(args[0]); - - if (numGCs > 0) { - // try to force a minor collection: the young gen is 4M, the - // amount of data allocated below is roughly that (4*1024*1024 + - // some header data) - for (int i = 0; i < 1024 ; i++) { - temp = new int[1024]; - } - } - - for (int i = 0; i < numGCs - 1; i++) { - System.gc(); - } - } -} - public class TestSummarizeRSetStats { - public static String runTest(String[] additionalArgs, int numGCs) throws Exception { - ArrayList finalargs = new ArrayList(); - String[] defaultArgs = new String[] { - "-XX:+UseG1GC", - "-Xmn4m", - "-Xmx20m", - "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking - "-XX:+PrintGC", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:G1HeapRegionSize=1M", - }; - - finalargs.addAll(Arrays.asList(defaultArgs)); - - if (additionalArgs != null) { - finalargs.addAll(Arrays.asList(additionalArgs)); - } - - finalargs.add(RunSystemGCs.class.getName()); - finalargs.add(String.valueOf(numGCs)); - - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - finalargs.toArray(new String[0])); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - - output.shouldHaveExitValue(0); - - String result = output.getStdout(); - return result; - } - - private static void expectStatistics(String result, int expectedCumulative, int expectedPeriodic) throws Exception { - int actualTotal = result.split("Concurrent RS processed").length - 1; - int actualCumulative = result.split("Cumulative RS summary").length - 1; - - if (expectedCumulative != actualCumulative) { - throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative); - } - - if (expectedPeriodic != (actualTotal - actualCumulative)) { - throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative)); - } - } - public static void main(String[] args) throws Exception { String result; - // no RSet statistics output - result = runTest(null, 0); - expectStatistics(result, 0, 0); + if (!TestSummarizeRSetStatsTools.testingG1GC()) { + return; + } - // no RSet statistics output - result = runTest(null, 2); - expectStatistics(result, 0, 0); + // no remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(null, 0); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0); - // no RSet statistics output - result = runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); - expectStatistics(result, 0, 0); + // no remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(null, 2); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0); - // single RSet statistics output at the end - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0); - expectStatistics(result, 1, 0); + // no remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0); - // single RSet statistics output at the end - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2); - expectStatistics(result, 1, 0); + // single remembered set summary output at the end + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0); - // single RSet statistics output - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0); - expectStatistics(result, 1, 0); + // single remembered set summary output at the end + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0); - // two times RSet statistics output - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1); - expectStatistics(result, 1, 1); + // single remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0); - // four times RSet statistics output - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); - expectStatistics(result, 1, 3); + // two times remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2); - // three times RSet statistics output - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3); - expectStatistics(result, 1, 2); + // four times remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 6); - // single RSet statistics output - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3); - expectStatistics(result, 1, 1); + // three times remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 4); + + // single remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2); } } diff --git a/hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java b/hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java new file mode 100644 index 00000000000..437cbc2c70e --- /dev/null +++ b/hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013, 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 TestSummarizeRSetStatsPerRegion.java + * @bug 8014078 + * @library /testlibrary + * @build TestSummarizeRSetStatsTools TestSummarizeRSetStatsPerRegion + * @summary Verify output of -XX:+G1SummarizeRSetStats in regards to per-region type output + * @run main TestSummarizeRSetStatsPerRegion + */ + +import com.oracle.java.testlibrary.*; +import java.lang.Thread; +import java.util.ArrayList; +import java.util.Arrays; + +public class TestSummarizeRSetStatsPerRegion { + + public static void main(String[] args) throws Exception { + String result; + + if (!TestSummarizeRSetStatsTools.testingG1GC()) { + return; + } + + // single remembered set summary output at the end + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0); + TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 0); + + // two times remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1); + TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 2); + } +} diff --git a/hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java b/hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java new file mode 100644 index 00000000000..096a7c675b5 --- /dev/null +++ b/hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * Common helpers for TestSummarizeRSetStats* tests + */ + +import sun.management.ManagementFactoryHelper; +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; + +import com.oracle.java.testlibrary.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.lang.Thread; +import java.util.ArrayList; +import java.util.Arrays; + +class VerifySummaryOutput { + // 4M size, both are directly allocated into the old gen + static Object[] largeObject1 = new Object[1024 * 1024]; + static Object[] largeObject2 = new Object[1024 * 1024]; + + static int[] temp; + + public static void main(String[] args) { + // create some cross-references between these objects + for (int i = 0; i < largeObject1.length; i++) { + largeObject1[i] = largeObject2; + } + + for (int i = 0; i < largeObject2.length; i++) { + largeObject2[i] = largeObject1; + } + + int numGCs = Integer.parseInt(args[0]); + + if (numGCs > 0) { + // try to force a minor collection: the young gen is 4M, the + // amount of data allocated below is roughly that (4*1024*1024 + + // some header data) + for (int i = 0; i < 1024 ; i++) { + temp = new int[1024]; + } + } + + for (int i = 0; i < numGCs - 1; i++) { + System.gc(); + } + } +} + +public class TestSummarizeRSetStatsTools { + + // the VM is currently run using G1GC, i.e. trying to test G1 functionality. + public static boolean testingG1GC() { + HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); + + VMOption option = diagnostic.getVMOption("UseG1GC"); + if (option.getValue().equals("false")) { + System.out.println("Skipping this test. It is only a G1 test."); + return false; + } + return true; + } + + public static String runTest(String[] additionalArgs, int numGCs) throws Exception { + ArrayList finalargs = new ArrayList(); + String[] defaultArgs = new String[] { + "-XX:+UseG1GC", + "-XX:+UseCompressedOops", + "-Xmn4m", + "-Xmx20m", + "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking + "-XX:+PrintGC", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:G1HeapRegionSize=1M", + }; + + finalargs.addAll(Arrays.asList(defaultArgs)); + + if (additionalArgs != null) { + finalargs.addAll(Arrays.asList(additionalArgs)); + } + + finalargs.add(VerifySummaryOutput.class.getName()); + finalargs.add(String.valueOf(numGCs)); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + finalargs.toArray(new String[0])); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + output.shouldHaveExitValue(0); + + String result = output.getStdout(); + return result; + } + + private static void checkCounts(int expected, int actual, String which) throws Exception { + if (expected != actual) { + throw new Exception("RSet summaries mention " + which + " regions an incorrect number of times. Expected " + expected + ", got " + actual); + } + } + + public static void expectPerRegionRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception { + expectRSetSummaries(result, expectedCumulative, expectedPeriodic); + int actualYoung = result.split("Young regions").length - 1; + int actualHumonguous = result.split("Humonguous regions").length - 1; + int actualFree = result.split("Free regions").length - 1; + int actualOther = result.split("Old regions").length - 1; + + // the strings we check for above are printed four times per summary + int expectedPerRegionTypeInfo = (expectedCumulative + expectedPeriodic) * 4; + + checkCounts(expectedPerRegionTypeInfo, actualYoung, "Young"); + checkCounts(expectedPerRegionTypeInfo, actualHumonguous, "Humonguous"); + checkCounts(expectedPerRegionTypeInfo, actualFree, "Free"); + checkCounts(expectedPerRegionTypeInfo, actualOther, "Old"); + } + + public static void expectRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception { + int actualTotal = result.split("concurrent refinement").length - 1; + int actualCumulative = result.split("Cumulative RS summary").length - 1; + + if (expectedCumulative != actualCumulative) { + throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative); + } + + if (expectedPeriodic != (actualTotal - actualCumulative)) { + throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative)); + } + } +} + From 27565b7f5d9dfcb099a4c7a95c13b48607853c7a Mon Sep 17 00:00:00 2001 From: Mikael Gerdin Date: Fri, 27 Sep 2013 10:23:12 +0200 Subject: [PATCH 0477/1294] 8025279: metaspace/flags/maxMetaspaceSize throws OOM: out of Compressed Klass space Only put "Compressed class space" as OOM cause if actually using Compressed class space Reviewed-by: jwilhelm, stefank, ehelin, coleenp --- hotspot/src/share/vm/memory/metaspace.cpp | 8 ++++---- hotspot/src/share/vm/memory/metaspace.hpp | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 06f3d09378a..7b9144942d9 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -3104,7 +3104,7 @@ size_t Metaspace::align_word_size_up(size_t word_size) { MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { // DumpSharedSpaces doesn't use class metadata area (yet) // Also, don't use class_vsm() unless UseCompressedClassPointers is true. - if (mdtype == ClassType && using_class_space()) { + if (is_class_space_allocation(mdtype)) { return class_vsm()->allocate(word_size); } else { return vsm()->allocate(word_size); @@ -3252,8 +3252,8 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, MetaspaceAux::dump(gclog_or_tty); } // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support - const char* space_string = (mdtype == ClassType) ? "Compressed class space" : - "Metadata space"; + const char* space_string = is_class_space_allocation(mdtype) ? "Compressed class space" : + "Metadata space"; report_java_out_of_memory(space_string); if (JvmtiExport::should_post_resource_exhausted()) { @@ -3261,7 +3261,7 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR, space_string); } - if (mdtype == ClassType) { + if (is_class_space_allocation(mdtype)) { THROW_OOP_0(Universe::out_of_memory_error_class_metaspace()); } else { THROW_OOP_0(Universe::out_of_memory_error_metaspace()); diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 29c07e15179..925d9c140d6 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -235,6 +235,9 @@ class Metaspace : public CHeapObj { return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces); } + static bool is_class_space_allocation(MetadataType mdType) { + return mdType == ClassType && using_class_space(); + } }; class MetaspaceAux : AllStatic { From b8363e6615bcc65a4aa3c1fe4799dcebb18dedbb Mon Sep 17 00:00:00 2001 From: Mikael Gerdin Date: Tue, 24 Sep 2013 14:46:29 +0200 Subject: [PATCH 0478/1294] 8025305: Cleanup CardTableModRefBS usage in G1 Move some G1 specific code from CardTableModRefBS to G1SATBCardTableModRefBS. Reviewed-by: brutisso, tschatzl, ehelin --- .../g1/concurrentMark.inline.hpp | 2 +- .../vm/gc_implementation/g1/g1CardCounts.cpp | 4 +- .../gc_implementation/g1/g1CollectedHeap.cpp | 46 ++++++---------- .../gc_implementation/g1/g1CollectedHeap.hpp | 12 +++-- .../g1/g1CollectedHeap.inline.hpp | 2 +- .../vm/gc_implementation/g1/g1EvacFailure.hpp | 4 +- .../vm/gc_implementation/g1/g1MarkSweep.cpp | 2 +- .../vm/gc_implementation/g1/g1RemSet.cpp | 11 ++-- .../g1/g1SATBCardTableModRefBS.cpp | 21 ++++++++ .../g1/g1SATBCardTableModRefBS.hpp | 36 +++++++++++++ .../src/share/vm/memory/cardTableModRefBS.cpp | 54 ------------------- .../src/share/vm/memory/cardTableModRefBS.hpp | 24 --------- 12 files changed, 90 insertions(+), 128 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp index d962842b39a..ea45f2d6466 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp @@ -81,7 +81,7 @@ inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr, size_t* marked_bytes_array, BitMap* task_card_bm) { G1CollectedHeap* g1h = _g1h; - CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set()); + CardTableModRefBS* ct_bs = g1h->g1_barrier_set(); HeapWord* start = mr.start(); HeapWord* end = mr.end(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp index 31972bf3c4e..59041d34ae2 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp @@ -65,9 +65,7 @@ void G1CardCounts::initialize() { // threshold limit is no more than this. guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity"); - ModRefBarrierSet* bs = _g1h->mr_bs(); - guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition"); - _ct_bs = (CardTableModRefBS*)bs; + _ct_bs = _g1h->g1_barrier_set(); _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start()); // Allocate/Reserve the counts table diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index eff0efc6e0f..b5ea461690c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -125,10 +125,8 @@ class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { int _histo[256]; public: ClearLoggedCardTableEntryClosure() : - _calls(0) + _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) { - _g1h = G1CollectedHeap::heap(); - _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); for (int i = 0; i < 256; i++) _histo[i] = 0; } bool do_card_ptr(jbyte* card_ptr, int worker_i) { @@ -158,11 +156,8 @@ class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure { CardTableModRefBS* _ctbs; public: RedirtyLoggedCardTableEntryClosure() : - _calls(0) - { - _g1h = G1CollectedHeap::heap(); - _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); - } + _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {} + bool do_card_ptr(jbyte* card_ptr, int worker_i) { if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { _calls++; @@ -478,7 +473,7 @@ bool G1CollectedHeap::is_scavengable(const void* p) { void G1CollectedHeap::check_ct_logs_at_safepoint() { DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); - CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); + CardTableModRefBS* ct_bs = g1_barrier_set(); // Count the dirty cards at the start. CountNonCleanMemRegionClosure count1(this); @@ -1205,7 +1200,7 @@ public: }; void G1CollectedHeap::clear_rsets_post_compaction() { - PostMCRemSetClearClosure rs_clear(this, mr_bs()); + PostMCRemSetClearClosure rs_clear(this, g1_barrier_set()); heap_region_iterate(&rs_clear); } @@ -2045,20 +2040,13 @@ jint G1CollectedHeap::initialize() { // Create the gen rem set (and barrier set) for the entire reserved region. _rem_set = collector_policy()->create_rem_set(_reserved, 2); set_barrier_set(rem_set()->bs()); - if (barrier_set()->is_a(BarrierSet::ModRef)) { - _mr_bs = (ModRefBarrierSet*)_barrier_set; - } else { - vm_exit_during_initialization("G1 requires a mod ref bs."); + if (!barrier_set()->is_a(BarrierSet::G1SATBCTLogging)) { + vm_exit_during_initialization("G1 requires a G1SATBLoggingCardTableModRefBS"); return JNI_ENOMEM; } // Also create a G1 rem set. - if (mr_bs()->is_a(BarrierSet::CardTableModRef)) { - _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs()); - } else { - vm_exit_during_initialization("G1 requires a cardtable mod ref bs."); - return JNI_ENOMEM; - } + _g1_rem_set = new G1RemSet(this, g1_barrier_set()); // Carve out the G1 part of the heap. @@ -4555,7 +4543,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num) : _g1h(g1h), _refs(g1h->task_queue(queue_num)), _dcq(&g1h->dirty_card_queue_set()), - _ct_bs((CardTableModRefBS*)_g1h->barrier_set()), + _ct_bs(g1h->g1_barrier_set()), _g1_rem(g1h->g1_rem_set()), _hash_seed(17), _queue_num(queue_num), _term_attempts(0), @@ -5984,11 +5972,11 @@ void G1CollectedHeap::update_sets_after_freeing_regions(size_t pre_used, } class G1ParCleanupCTTask : public AbstractGangTask { - CardTableModRefBS* _ct_bs; + G1SATBCardTableModRefBS* _ct_bs; G1CollectedHeap* _g1h; HeapRegion* volatile _su_head; public: - G1ParCleanupCTTask(CardTableModRefBS* ct_bs, + G1ParCleanupCTTask(G1SATBCardTableModRefBS* ct_bs, G1CollectedHeap* g1h) : AbstractGangTask("G1 Par Cleanup CT Task"), _ct_bs(ct_bs), _g1h(g1h) { } @@ -6011,9 +5999,9 @@ public: #ifndef PRODUCT class G1VerifyCardTableCleanup: public HeapRegionClosure { G1CollectedHeap* _g1h; - CardTableModRefBS* _ct_bs; + G1SATBCardTableModRefBS* _ct_bs; public: - G1VerifyCardTableCleanup(G1CollectedHeap* g1h, CardTableModRefBS* ct_bs) + G1VerifyCardTableCleanup(G1CollectedHeap* g1h, G1SATBCardTableModRefBS* ct_bs) : _g1h(g1h), _ct_bs(ct_bs) { } virtual bool doHeapRegion(HeapRegion* r) { if (r->is_survivor()) { @@ -6027,7 +6015,7 @@ public: void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) { // All of the region should be clean. - CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); MemRegion mr(hr->bottom(), hr->end()); ct_bs->verify_not_dirty_region(mr); } @@ -6040,13 +6028,13 @@ void G1CollectedHeap::verify_dirty_region(HeapRegion* hr) { // not dirty that area (one less thing to have to do while holding // a lock). So we can only verify that [bottom(),pre_dummy_top()] // is dirty. - CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); MemRegion mr(hr->bottom(), hr->pre_dummy_top()); ct_bs->verify_dirty_region(mr); } void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) { - CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) { verify_dirty_region(hr); } @@ -6058,7 +6046,7 @@ void G1CollectedHeap::verify_dirty_young_regions() { #endif void G1CollectedHeap::cleanUpCardTable() { - CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); double start = os::elapsedTime(); { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 747b2326236..3a6a0c5f37e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -31,6 +31,7 @@ #include "gc_implementation/g1/g1HRPrinter.hpp" #include "gc_implementation/g1/g1MonitoringSupport.hpp" #include "gc_implementation/g1/g1RemSet.hpp" +#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/g1YCTypes.hpp" #include "gc_implementation/g1/heapRegionSeq.hpp" #include "gc_implementation/g1/heapRegionSets.hpp" @@ -791,8 +792,6 @@ protected: // The g1 remembered set of the heap. G1RemSet* _g1_rem_set; - // And it's mod ref barrier set, used to track updates for the above. - ModRefBarrierSet* _mr_bs; // A set of cards that cover the objects for which the Rsets should be updated // concurrently after the collection. @@ -1127,7 +1126,6 @@ public: // The rem set and barrier set. G1RemSet* g1_rem_set() const { return _g1_rem_set; } - ModRefBarrierSet* mr_bs() const { return _mr_bs; } unsigned get_gc_time_stamp() { return _gc_time_stamp; @@ -1346,6 +1344,10 @@ public: virtual bool is_in_closed_subset(const void* p) const; + G1SATBCardTableModRefBS* g1_barrier_set() { + return (G1SATBCardTableModRefBS*) barrier_set(); + } + // This resets the card table to all zeros. It is used after // a collection pause which used the card table to claim cards. void cleanUpCardTable(); @@ -1875,7 +1877,7 @@ protected: G1CollectedHeap* _g1h; RefToScanQueue* _refs; DirtyCardQueue _dcq; - CardTableModRefBS* _ct_bs; + G1SATBCardTableModRefBS* _ct_bs; G1RemSet* _g1_rem; G1ParGCAllocBufferContainer _surviving_alloc_buffer; @@ -1914,7 +1916,7 @@ protected: void add_to_undo_waste(size_t waste) { _undo_waste += waste; } DirtyCardQueue& dirty_card_queue() { return _dcq; } - CardTableModRefBS* ctbs() { return _ct_bs; } + G1SATBCardTableModRefBS* ctbs() { return _ct_bs; } template void immediate_rs_update(HeapRegion* from, T* p, int tid) { if (!from->is_survivor()) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp index 20eb1693c43..5cd3f7f21cd 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp @@ -134,7 +134,7 @@ G1CollectedHeap::dirty_young_block(HeapWord* start, size_t word_size) { assert(containing_hr->is_in(end - 1), "it should also contain end - 1"); MemRegion mr(start, end); - ((CardTableModRefBS*)_g1h->barrier_set())->dirty(mr); + g1_barrier_set()->dirty(mr); } inline RefToScanQueue* G1CollectedHeap::task_queue(int i) const { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp index 84d998265a9..1333f287047 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp @@ -41,11 +41,11 @@ class UpdateRSetDeferred : public OopsInHeapRegionClosure { private: G1CollectedHeap* _g1; DirtyCardQueue *_dcq; - CardTableModRefBS* _ct_bs; + G1SATBCardTableModRefBS* _ct_bs; public: UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) : - _g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) {} + _g1(g1), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {} virtual void do_oop(narrowOop* p) { do_oop_work(p); } virtual void do_oop( oop* p) { do_oop_work(p); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp index 74aabc1298d..87650103d60 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp @@ -220,7 +220,7 @@ class G1PrepareCompactClosure: public HeapRegionClosure { public: G1PrepareCompactClosure(CompactibleSpace* cs) : _g1h(G1CollectedHeap::heap()), - _mrbs(G1CollectedHeap::heap()->mr_bs()), + _mrbs(_g1h->g1_barrier_set()), _cp(NULL, cs, cs->initialize_threshold()), _humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp index a8c580b60cd..0e06c472ffa 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp @@ -109,7 +109,7 @@ class ScanRSClosure : public HeapRegionClosure { CodeBlobToOopClosure* _code_root_cl; G1BlockOffsetSharedArray* _bot_shared; - CardTableModRefBS *_ct_bs; + G1SATBCardTableModRefBS *_ct_bs; double _strong_code_root_scan_time_sec; int _worker_i; @@ -130,7 +130,7 @@ public: { _g1h = G1CollectedHeap::heap(); _bot_shared = _g1h->bot_shared(); - _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set()); + _ct_bs = _g1h->g1_barrier_set(); _block_size = MAX2(G1RSetScanBlockSize, 1); } @@ -505,12 +505,7 @@ public: ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) : _g1h(G1CollectedHeap::heap()), _region_bm(region_bm), _card_bm(card_bm), - _ctbs(NULL) - { - ModRefBarrierSet* bs = _g1h->mr_bs(); - guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition"); - _ctbs = (CardTableModRefBS*)bs; - } + _ctbs(_g1h->g1_barrier_set()) {} bool doHeapRegion(HeapRegion* r) { if (!r->continuesHumongous()) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp index 218be0c0e40..48c737e74ab 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp @@ -64,6 +64,27 @@ G1SATBCardTableModRefBS::write_ref_array_pre_work(T* dst, int count) { } } +bool G1SATBCardTableModRefBS::mark_card_deferred(size_t card_index) { + jbyte val = _byte_map[card_index]; + // It's already processed + if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { + return false; + } + // Cached bit can be installed either on a clean card or on a claimed card. + jbyte new_val = val; + if (val == clean_card_val()) { + new_val = (jbyte)deferred_card_val(); + } else { + if (val & claimed_card_val()) { + new_val = val | (jbyte)deferred_card_val(); + } + } + if (new_val != val) { + Atomic::cmpxchg(new_val, &_byte_map[card_index], val); + } + return true; +} + G1SATBCardTableLoggingModRefBS:: G1SATBCardTableLoggingModRefBS(MemRegion whole_heap, int max_covered_regions) : diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp index 6f887583cab..4e807348102 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp @@ -89,6 +89,42 @@ public: write_ref_array_pre_work(dst, count); } } + +/* + Claimed and deferred bits are used together in G1 during the evacuation + pause. These bits can have the following state transitions: + 1. The claimed bit can be put over any other card state. Except that + the "dirty -> dirty and claimed" transition is checked for in + G1 code and is not used. + 2. Deferred bit can be set only if the previous state of the card + was either clean or claimed. mark_card_deferred() is wait-free. + We do not care if the operation is be successful because if + it does not it will only result in duplicate entry in the update + buffer because of the "cache-miss". So it's not worth spinning. + */ + + bool is_card_claimed(size_t card_index) { + jbyte val = _byte_map[card_index]; + return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val(); + } + + void set_card_claimed(size_t card_index) { + jbyte val = _byte_map[card_index]; + if (val == clean_card_val()) { + val = (jbyte)claimed_card_val(); + } else { + val |= (jbyte)claimed_card_val(); + } + _byte_map[card_index] = val; + } + + bool mark_card_deferred(size_t card_index); + + bool is_card_deferred(size_t card_index) { + jbyte val = _byte_map[card_index]; + return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val(); + } + }; // Adds card-table logging to the post-barrier. diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp index 82336503eb4..5e9d843ff52 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp @@ -423,60 +423,6 @@ void CardTableModRefBS::write_ref_field_work(void* field, oop newVal) { inline_write_ref_field(field, newVal); } -/* - Claimed and deferred bits are used together in G1 during the evacuation - pause. These bits can have the following state transitions: - 1. The claimed bit can be put over any other card state. Except that - the "dirty -> dirty and claimed" transition is checked for in - G1 code and is not used. - 2. Deferred bit can be set only if the previous state of the card - was either clean or claimed. mark_card_deferred() is wait-free. - We do not care if the operation is be successful because if - it does not it will only result in duplicate entry in the update - buffer because of the "cache-miss". So it's not worth spinning. - */ - - -bool CardTableModRefBS::claim_card(size_t card_index) { - jbyte val = _byte_map[card_index]; - assert(val != dirty_card_val(), "Shouldn't claim a dirty card"); - while (val == clean_card_val() || - (val & (clean_card_mask_val() | claimed_card_val())) != claimed_card_val()) { - jbyte new_val = val; - if (val == clean_card_val()) { - new_val = (jbyte)claimed_card_val(); - } else { - new_val = val | (jbyte)claimed_card_val(); - } - jbyte res = Atomic::cmpxchg(new_val, &_byte_map[card_index], val); - if (res == val) { - return true; - } - val = res; - } - return false; -} - -bool CardTableModRefBS::mark_card_deferred(size_t card_index) { - jbyte val = _byte_map[card_index]; - // It's already processed - if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { - return false; - } - // Cached bit can be installed either on a clean card or on a claimed card. - jbyte new_val = val; - if (val == clean_card_val()) { - new_val = (jbyte)deferred_card_val(); - } else { - if (val & claimed_card_val()) { - new_val = val | (jbyte)deferred_card_val(); - } - } - if (new_val != val) { - Atomic::cmpxchg(new_val, &_byte_map[card_index], val); - } - return true; -} void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp, MemRegion mr, diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp index 6b5de2a4460..cadb4cb88aa 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp @@ -339,34 +339,10 @@ public: _byte_map[card_index] = dirty_card_val(); } - bool is_card_claimed(size_t card_index) { - jbyte val = _byte_map[card_index]; - return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val(); - } - - void set_card_claimed(size_t card_index) { - jbyte val = _byte_map[card_index]; - if (val == clean_card_val()) { - val = (jbyte)claimed_card_val(); - } else { - val |= (jbyte)claimed_card_val(); - } - _byte_map[card_index] = val; - } - - bool claim_card(size_t card_index); - bool is_card_clean(size_t card_index) { return _byte_map[card_index] == clean_card_val(); } - bool is_card_deferred(size_t card_index) { - jbyte val = _byte_map[card_index]; - return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val(); - } - - bool mark_card_deferred(size_t card_index); - // Card marking array base (adjusted for heap low boundary) // This would be the 0th element of _byte_map, if the heap started at 0x0. // But since the heap starts at some higher address, this points to somewhere From cde6d64f602ad01e860dd867ac2c8c0e84a4c4c2 Mon Sep 17 00:00:00 2001 From: Yuri Nesterenko Date: Tue, 24 Sep 2013 17:04:47 +0400 Subject: [PATCH 0479/1294] 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes Reviewed-by: alexsch --- jdk/src/share/classes/javax/swing/JLayer.java | 38 ++--- .../share/classes/javax/swing/RowFilter.java | 4 +- .../classes/javax/swing/plaf/TextUI.java | 18 +-- .../javax/swing/plaf/basic/BasicTextUI.java | 28 ++-- .../javax/swing/text/AttributeSet.java | 2 +- .../swing/text/BadLocationException.java | 4 +- .../classes/javax/swing/text/BoxView.java | 46 +++--- .../share/classes/javax/swing/text/Caret.java | 10 +- .../javax/swing/text/ComponentView.java | 12 +- .../javax/swing/text/CompositeView.java | 64 ++++---- .../javax/swing/text/DefaultEditorKit.java | 12 +- .../javax/swing/text/DefaultHighlighter.java | 16 +- .../swing/text/DefaultStyledDocument.java | 40 ++--- .../classes/javax/swing/text/Document.java | 20 +-- .../javax/swing/text/DocumentFilter.java | 12 +- .../classes/javax/swing/text/EditorKit.java | 14 +- .../classes/javax/swing/text/FieldView.java | 10 +- .../classes/javax/swing/text/FlowView.java | 26 ++-- .../classes/javax/swing/text/GapContent.java | 22 +-- .../classes/javax/swing/text/GlyphView.java | 52 +++---- .../classes/javax/swing/text/Highlighter.java | 16 +- .../classes/javax/swing/text/IconView.java | 10 +- .../javax/swing/text/NavigationFilter.java | 8 +- .../javax/swing/text/ParagraphView.java | 18 +-- .../javax/swing/text/PasswordView.java | 34 ++--- .../javax/swing/text/PlainDocument.java | 2 +- .../classes/javax/swing/text/PlainView.java | 44 +++--- .../classes/javax/swing/text/Position.java | 2 +- .../javax/swing/text/StringContent.java | 30 ++-- .../javax/swing/text/StyleContext.java | 4 +- .../javax/swing/text/StyledDocument.java | 16 +- .../javax/swing/text/StyledEditorKit.java | 2 +- .../classes/javax/swing/text/TabExpander.java | 6 +- .../classes/javax/swing/text/TabableView.java | 10 +- .../classes/javax/swing/text/TableView.java | 12 +- .../classes/javax/swing/text/Utilities.java | 64 ++++---- .../share/classes/javax/swing/text/View.java | 26 ++-- .../javax/swing/text/WrappedPlainView.java | 36 ++--- .../classes/javax/swing/text/ZoneView.java | 12 +- .../javax/swing/text/html/BlockView.java | 6 +- .../classes/javax/swing/text/html/CSS.java | 2 +- .../javax/swing/text/html/FormView.java | 2 +- .../javax/swing/text/html/HTMLDocument.java | 139 +++++++++--------- 43 files changed, 476 insertions(+), 475 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JLayer.java b/jdk/src/share/classes/javax/swing/JLayer.java index 2341c502e04..b0f3894ba70 100644 --- a/jdk/src/share/classes/javax/swing/JLayer.java +++ b/jdk/src/share/classes/javax/swing/JLayer.java @@ -44,16 +44,16 @@ import java.security.PrivilegedAction; * {@code JLayer} is a universal decorator for Swing components * which enables you to implement various advanced painting effects as well as * receive notifications of all {@code AWTEvent}s generated within its borders. - *

    + *

    * {@code JLayer} delegates the handling of painting and input events to a * {@link javax.swing.plaf.LayerUI} object, which performs the actual decoration. - *

    + *

    * The custom painting implemented in the {@code LayerUI} and events notification * work for the JLayer itself and all its subcomponents. * This combination enables you to enrich existing components * by adding new advanced functionality such as temporary locking of a hierarchy, * data tips for compound components, enhanced mouse scrolling etc and so on. - *

    + *

    * {@code JLayer} is a good solution if you only need to do custom painting * over compound component or catch input events from its subcomponents. *

    @@ -202,7 +202,7 @@ public final class JLayer
     
         /**
          * Returns the {@code JLayer}'s view component or {@code null}.
    -     * 
    This is a bound property. + *
    This is a bound property. * * @return the {@code JLayer}'s view component * or {@code null} if none exists @@ -215,7 +215,7 @@ public final class JLayer /** * Sets the {@code JLayer}'s view component, which can be {@code null}. - *
    This is a bound property. + *
    This is a bound property. * * @param view the view component for this {@code JLayer} * @@ -257,7 +257,7 @@ public final class JLayer /** * Returns the {@code JLayer}'s glassPane component or {@code null}. - *
    This is a bound property. + *
    This is a bound property. * * @return the {@code JLayer}'s glassPane component * or {@code null} if none exists @@ -270,7 +270,7 @@ public final class JLayer /** * Sets the {@code JLayer}'s glassPane component, which can be {@code null}. - *
    This is a bound property. + *
    This is a bound property. * * @param glassPane the glassPane component of this {@code JLayer} * @@ -309,7 +309,7 @@ public final class JLayer /** * Sets the layout manager for this container. This method is * overridden to prevent the layout manager from being set. - *

    Note: If {@code mgr} is non-{@code null}, this + *

    Note: If {@code mgr} is non-{@code null}, this * method will throw an exception as layout managers are not supported on * a {@code JLayer}. * @@ -327,7 +327,7 @@ public final class JLayer * of this component from becoming complex enough to inhibit * subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border, * add it to a {@code JPanel} that has a border. - *

    Note: If {@code border} is non-{@code null}, this + *

    Note: If {@code border} is non-{@code null}, this * method will throw an exception as borders are not supported on * a {@code JLayer}. * @@ -471,11 +471,11 @@ public final class JLayer * defined by the specified event mask parameter * to be delivered to the * {@link LayerUI#eventDispatched(AWTEvent, JLayer)} method. - *

    + *

    * Events are delivered provided that {@code LayerUI} is set * for this {@code JLayer} and the {@code JLayer} * is displayable. - *

    + *

    * The following example shows how to correctly use this method * in the {@code LayerUI} implementations: *

    @@ -519,10 +519,10 @@ public final class JLayer
         /**
          * Returns the bitmap of event mask to receive by this {@code JLayer}
          * and its {@code LayerUI}.
    -     * 

    + *

    * It means that {@link javax.swing.plaf.LayerUI#eventDispatched(AWTEvent, JLayer)} method * will only receive events that match the event mask. - *

    + *

    * By default {@code JLayer} receives no events. * * @return the bitmask of event types to receive for this {@code JLayer} @@ -543,7 +543,7 @@ public final class JLayer /** * Returns the preferred size of the viewport for a view component. - *

    + *

    * If the view component of this layer implements {@link Scrollable}, this method delegates its * implementation to the view component. * @@ -562,7 +562,7 @@ public final class JLayer * Returns a scroll increment, which is required for components * that display logical rows or columns in order to completely expose * one block of rows or columns, depending on the value of orientation. - *

    + *

    * If the view component of this layer implements {@link Scrollable}, this method delegates its * implementation to the view component. * @@ -584,7 +584,7 @@ public final class JLayer * Returns {@code false} to indicate that the height of the viewport does not * determine the height of the layer, unless the preferred height * of the layer is smaller than the height of the viewport. - *

    + *

    * If the view component of this layer implements {@link Scrollable}, this method delegates its * implementation to the view component. * @@ -603,7 +603,7 @@ public final class JLayer * Returns {@code false} to indicate that the width of the viewport does not * determine the width of the layer, unless the preferred width * of the layer is smaller than the width of the viewport. - *

    + *

    * If the view component of this layer implements {@link Scrollable}, this method delegates its * implementation to the view component. * @@ -624,10 +624,10 @@ public final class JLayer * one new row or column, depending on the value of orientation. * Ideally, components should handle a partially exposed row or column * by returning the distance required to completely expose the item. - *

    + *

    * Scrolling containers, like {@code JScrollPane}, will use this method * each time the user requests a unit scroll. - *

    + *

    * If the view component of this layer implements {@link Scrollable}, this method delegates its * implementation to the view component. * diff --git a/jdk/src/share/classes/javax/swing/RowFilter.java b/jdk/src/share/classes/javax/swing/RowFilter.java index 219601f1ea2..6d9fc7f33f8 100644 --- a/jdk/src/share/classes/javax/swing/RowFilter.java +++ b/jdk/src/share/classes/javax/swing/RowFilter.java @@ -357,7 +357,7 @@ public abstract class RowFilter { * * @param index the index of the value to get * @return value at the specified index - * @throws IndexOutOfBoundsException if index < 0 or + * @throws IndexOutOfBoundsException if index < 0 or * >= getValueCount */ public abstract Object getValue(int index); @@ -376,7 +376,7 @@ public abstract class RowFilter { * * @param index the index of the value to get * @return {@code non-null} string at the specified index - * @throws IndexOutOfBoundsException if index < 0 || + * @throws IndexOutOfBoundsException if index < 0 || * >= getValueCount */ public String getStringValue(int index) { diff --git a/jdk/src/share/classes/javax/swing/plaf/TextUI.java b/jdk/src/share/classes/javax/swing/plaf/TextUI.java index 6459b29adb3..5d55124ed90 100644 --- a/jdk/src/share/classes/javax/swing/plaf/TextUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/TextUI.java @@ -42,7 +42,7 @@ public abstract class TextUI extends ComponentUI * Converts the given location in the model to a place in * the view coordinate system. * - * @param pos the local location in the model to translate >= 0 + * @param pos the local location in the model to translate >= 0 * @return the coordinates as a rectangle * @exception BadLocationException if the given position does not * represent a valid location in the associated document @@ -53,7 +53,7 @@ public abstract class TextUI extends ComponentUI * Converts the given location in the model to a place in * the view coordinate system. * - * @param pos the local location in the model to translate >= 0 + * @param pos the local location in the model to translate >= 0 * @return the coordinates as a rectangle * @exception BadLocationException if the given position does not * represent a valid location in the associated document @@ -67,7 +67,7 @@ public abstract class TextUI extends ComponentUI * @param pt the location in the view to translate. This * should be in the same coordinate system as the mouse * events. - * @return the offset from the start of the document >= 0 + * @return the offset from the start of the document >= 0 */ public abstract int viewToModel(JTextComponent t, Point pt); @@ -84,7 +84,7 @@ public abstract class TextUI extends ComponentUI * character in the model * * @return the location within the model that best represents the - * given point in the view >= 0 + * given point in the view >= 0 */ public abstract int viewToModel(JTextComponent t, Point pt, Position.Bias[] biasReturn); @@ -96,7 +96,7 @@ public abstract class TextUI extends ComponentUI * might not allow access to some of the locations in the model. * * @param t the text component for which this UI is installed - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param b the bias for the position * @param direction the direction from the current position that can * be thought of as the arrow keys typically found on a keyboard. @@ -117,8 +117,8 @@ public abstract class TextUI extends ComponentUI * Causes the portion of the view responsible for the * given part of the model to be repainted. * - * @param p0 the beginning of the range >= 0 - * @param p1 the end of the range >= p0 + * @param p0 the beginning of the range >= 0 + * @param p1 the end of the range >= p0 */ public abstract void damageRange(JTextComponent t, int p0, int p1); @@ -126,8 +126,8 @@ public abstract class TextUI extends ComponentUI * Causes the portion of the view responsible for the * given part of the model to be repainted. * - * @param p0 the beginning of the range >= 0 - * @param p1 the end of the range >= p0 + * @param p0 the beginning of the range >= 0 + * @param p1 the end of the range >= p0 */ public abstract void damageRange(JTextComponent t, int p0, int p1, Position.Bias firstBias, diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java index 3cfedb8bd34..b00bcda30be 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java @@ -1012,7 +1012,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * this translation to be computed. * * @param tc the text component for which this UI is installed - * @param pos the local location in the model to translate >= 0 + * @param pos the local location in the model to translate >= 0 * @return the coordinates as a rectangle, null if the model is not painted * @exception BadLocationException if the given position does not * represent a valid location in the associated document @@ -1029,7 +1029,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * this translation to be computed. * * @param tc the text component for which this UI is installed - * @param pos the local location in the model to translate >= 0 + * @param pos the local location in the model to translate >= 0 * @return the coordinates as a rectangle, null if the model is not painted * @exception BadLocationException if the given position does not * represent a valid location in the associated document @@ -1066,7 +1066,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * @param tc the text component for which this UI is installed * @param pt the location in the view to translate. This * should be in the same coordinate system as the mouse events. - * @return the offset from the start of the document >= 0, + * @return the offset from the start of the document >= 0, * -1 if not painted * @see TextUI#viewToModel */ @@ -1083,7 +1083,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * @param tc the text component for which this UI is installed * @param pt the location in the view to translate. This * should be in the same coordinate system as the mouse events. - * @return the offset from the start of the document >= 0, + * @return the offset from the start of the document >= 0, * -1 if the component doesn't yet have a positive size. * @see TextUI#viewToModel */ @@ -1141,8 +1141,8 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * the view is not currently painted. * * @param tc the text component for which this UI is installed - * @param p0 the beginning of the range >= 0 - * @param p1 the end of the range >= p0 + * @param p0 the beginning of the range >= 0 + * @param p1 the end of the range >= p0 * @see TextUI#damageRange */ public void damageRange(JTextComponent tc, int p0, int p1) { @@ -1153,8 +1153,8 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * Causes the portion of the view responsible for the * given part of the model to be repainted. * - * @param p0 the beginning of the range >= 0 - * @param p1 the end of the range >= p0 + * @param p0 the beginning of the range >= 0 + * @param p1 the end of the range >= p0 */ public void damageRange(JTextComponent t, int p0, int p1, Position.Bias p0Bias, Position.Bias p1Bias) { @@ -1271,8 +1271,8 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * it is unable to represent the part of the element. * * @param elem the element - * @param p0 the starting offset >= 0 - * @param p1 the ending offset >= p0 + * @param p0 the starting offset >= 0 + * @param p1 the ending offset >= p0 * @return the view */ public View create(Element elem, int p0, int p1) { @@ -1471,7 +1471,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * the model. This is implemented to return the index of the only * child. * - * @param pos the position >= 0 + * @param pos the position >= 0 * @return index of the view representing the given position, or * -1 if no view represents that position * @since 1.3 @@ -1515,11 +1515,11 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * Provides a mapping from the document model coordinate space * to the coordinate space of the view mapped to it. * - * @param p0 the position to convert >= 0 + * @param p0 the position to convert >= 0 * @param b0 the bias toward the previous character or the * next character represented by p0, in case the * position is a boundary of two views. - * @param p1 the position to convert >= 0 + * @param p1 the position to convert >= 0 * @param b1 the bias toward the previous character or the * next character represented by p1, in case the * position is a boundary of two views. @@ -1561,7 +1561,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory { * they might not be in the same order found in the model, or they just * might not allow access to some of the locations in the model. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param a the allocated region to render into * @param direction the direction from the current position that can * be thought of as the arrow keys typically found on a keyboard. diff --git a/jdk/src/share/classes/javax/swing/text/AttributeSet.java b/jdk/src/share/classes/javax/swing/text/AttributeSet.java index 07ff04bdb39..659136d9648 100644 --- a/jdk/src/share/classes/javax/swing/text/AttributeSet.java +++ b/jdk/src/share/classes/javax/swing/text/AttributeSet.java @@ -71,7 +71,7 @@ public interface AttributeSet { * This interface is the type signature that is expected * to be present on any attribute key that contributes to * character level presentation. This would be any attribute - * that applies to a so-called run of + * that applies to a so-called run of * style. */ public interface CharacterAttribute { diff --git a/jdk/src/share/classes/javax/swing/text/BadLocationException.java b/jdk/src/share/classes/javax/swing/text/BadLocationException.java index 783996a1c7c..c900e61cf7e 100644 --- a/jdk/src/share/classes/javax/swing/text/BadLocationException.java +++ b/jdk/src/share/classes/javax/swing/text/BadLocationException.java @@ -46,7 +46,7 @@ public class BadLocationException extends Exception * Creates a new BadLocationException object. * * @param s a string indicating what was wrong with the arguments - * @param offs offset within the document that was requested >= 0 + * @param offs offset within the document that was requested >= 0 */ public BadLocationException(String s, int offs) { super(s); @@ -56,7 +56,7 @@ public class BadLocationException extends Exception /** * Returns the offset into the document that was not legal. * - * @return the offset >= 0 + * @return the offset >= 0 */ public int offsetRequested() { return offs; diff --git a/jdk/src/share/classes/javax/swing/text/BoxView.java b/jdk/src/share/classes/javax/swing/text/BoxView.java index 54b52f32be3..250bf43de33 100644 --- a/jdk/src/share/classes/javax/swing/text/BoxView.java +++ b/jdk/src/share/classes/javax/swing/text/BoxView.java @@ -154,7 +154,7 @@ public class BoxView extends CompositeView { * * @param g the graphics context * @param alloc the allocated region to paint into - * @param index the child index, >= 0 && < getViewCount() + * @param index the child index, >= 0 && < getViewCount() */ protected void paintChild(Graphics g, Rectangle alloc, int index) { View child = getView(index); @@ -170,9 +170,9 @@ public class BoxView extends CompositeView { * will have an offset and span of 0. * * @param index the starting index into the child views to insert - * the new views; this should be a value >= 0 and <= getViewCount + * the new views; this should be a value >= 0 and <= getViewCount * @param length the number of existing child views to remove; - * This should be a value >= 0 and <= (getViewCount() - offset) + * This should be a value >= 0 and <= (getViewCount() - offset) * @param elems the child views to add; this value can be * nullto indicate no children are being added * (useful to remove) @@ -390,8 +390,8 @@ public class BoxView extends CompositeView { * information. This is implemented to call the * layout method with the sizes inside of the insets. * - * @param width the width >= 0 - * @param height the height >= 0 + * @param width the width >= 0 + * @param height the height >= 0 */ public void setSize(float width, float height) { layout(Math.max(0, (int)(width - getLeftInset() - getRightInset())), @@ -442,7 +442,7 @@ public class BoxView extends CompositeView { * null if the layout is invalid, * otherwise the superclass behavior is executed. * - * @param index the index of the child, >= 0 && < getViewCount() + * @param index the index of the child, >= 0 && > getViewCount() * @param a the allocation to this view * @return the allocation to the child; or null * if a is null; @@ -469,7 +469,7 @@ public class BoxView extends CompositeView { * to the coordinate space of the view mapped to it. This makes * sure the allocation is valid before calling the superclass. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param a the allocated region to render into * @return the bounding box of the given position * @exception BadLocationException if the given position does @@ -488,11 +488,11 @@ public class BoxView extends CompositeView { * Provides a mapping from the view coordinate space to the logical * coordinate space of the model. * - * @param x x coordinate of the view location to convert >= 0 - * @param y y coordinate of the view location to convert >= 0 + * @param x x coordinate of the view location to convert >= 0 + * @param y y coordinate of the view location to convert >= 0 * @param a the allocated region to render into * @return the location within the model that best represents the - * given point in the view >= 0 + * given point in the view >= 0 * @see View#viewToModel */ public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) { @@ -513,7 +513,7 @@ public class BoxView extends CompositeView { * * @param axis may be either View.X_AXIS * or View.Y_AXIS - * @return the desired alignment >= 0.0f && <= 1.0f; this should + * @return the desired alignment >= 0.0f && <= 1.0f; this should * be a value between 0.0 and 1.0 where 0 indicates alignment at the * origin and 1.0 indicates alignment to the full span * away from the origin; an alignment of 0.5 would be the @@ -535,7 +535,7 @@ public class BoxView extends CompositeView { * * @param axis may be either View.X_AXIS * or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0; + * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view @@ -558,7 +558,7 @@ public class BoxView extends CompositeView { * * @param axis may be either View.X_AXIS * or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0; + * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view @@ -581,7 +581,7 @@ public class BoxView extends CompositeView { * * @param axis may be either View.X_AXIS * or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0; + * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view @@ -613,8 +613,8 @@ public class BoxView extends CompositeView { /** * Determines if a point falls before an allocated region. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >= 0 + * @param y the Y coordinate >= 0 * @param innerAlloc the allocated region; this is the area * inside of the insets * @return true if the point lies before the region else false @@ -630,8 +630,8 @@ public class BoxView extends CompositeView { /** * Determines if a point falls after an allocated region. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >= 0 + * @param y the Y coordinate >= 0 * @param innerAlloc the allocated region; this is the area * inside of the insets * @return true if the point lies after the region else false @@ -647,8 +647,8 @@ public class BoxView extends CompositeView { /** * Fetches the child view at the given coordinates. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >= 0 + * @param y the Y coordinate >= 0 * @param alloc the parents inner allocation on entry, which should * be changed to the childs allocation on exit * @return the view @@ -688,7 +688,7 @@ public class BoxView extends CompositeView { * Allocates a region for a child view. * * @param index the index of the child view to - * allocate, >= 0 && < getViewCount() + * allocate, >= 0 && < getViewCount() * @param alloc the allocated region */ protected void childAllocation(int index, Rectangle alloc) { @@ -701,8 +701,8 @@ public class BoxView extends CompositeView { /** * Perform layout on the box * - * @param width the width (inside of the insets) >= 0 - * @param height the height (inside of the insets) >= 0 + * @param width the width (inside of the insets) >= 0 + * @param height the height (inside of the insets) >= 0 */ protected void layout(int width, int height) { setSpanOnAxis(X_AXIS, width); diff --git a/jdk/src/share/classes/javax/swing/text/Caret.java b/jdk/src/share/classes/javax/swing/text/Caret.java index fc089b9bffb..7083a6a6cc0 100644 --- a/jdk/src/share/classes/javax/swing/text/Caret.java +++ b/jdk/src/share/classes/javax/swing/text/Caret.java @@ -149,7 +149,7 @@ public interface Caret { * and how fast the caret blinks, commonly used as one * way to attract attention to the caret. * - * @param rate the delay in milliseconds >= 0. If this is + * @param rate the delay in milliseconds >=0. If this is * zero the caret will not blink. */ public void setBlinkRate(int rate); @@ -159,7 +159,7 @@ public interface Caret { * and how fast the caret blinks, commonly used as one * way to attract attention to the caret. * - * @return the delay in milliseconds >= 0. If this is + * @return the delay in milliseconds >=0. If this is * zero the caret will not blink. */ public int getBlinkRate(); @@ -167,7 +167,7 @@ public interface Caret { /** * Fetches the current position of the caret. * - * @return the position >= 0 + * @return the position >=0 */ public int getDot(); @@ -176,7 +176,7 @@ public interface Caret { * is a selection, the mark will not be the same as * the dot. * - * @return the position >= 0 + * @return the position >=0 */ public int getMark(); @@ -197,7 +197,7 @@ public interface Caret { * leaving behind the mark. This is useful for * making selections. * - * @param dot the new position to move the caret to >= 0 + * @param dot the new position to move the caret to >=0 */ public void moveDot(int dot); diff --git a/jdk/src/share/classes/javax/swing/text/ComponentView.java b/jdk/src/share/classes/javax/swing/text/ComponentView.java index a6f546fb185..760856af012 100644 --- a/jdk/src/share/classes/javax/swing/text/ComponentView.java +++ b/jdk/src/share/classes/javax/swing/text/ComponentView.java @@ -125,7 +125,7 @@ public class ComponentView extends View { * axis of interest. * * @param axis may be either View.X_AXIS or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0. + * @return the span the view would like to be rendered into >=0. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. @@ -153,7 +153,7 @@ public class ComponentView extends View { * axis of interest. * * @param axis may be either View.X_AXIS or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0. + * @return the span the view would like to be rendered into >=0. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. @@ -181,7 +181,7 @@ public class ComponentView extends View { * axis of interest. * * @param axis may be either View.X_AXIS or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0. + * @return the span the view would like to be rendered into >=0. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. @@ -319,7 +319,7 @@ public class ComponentView extends View { * Provides a mapping from the coordinate space of the model to * that of the view. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >=0 * @param a the allocated region to render into * @return the bounding box of the given position is returned * @exception BadLocationException if the given position does not @@ -344,8 +344,8 @@ public class ComponentView extends View { * Provides a mapping from the view coordinate space to the logical * coordinate space of the model. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >=0 + * @param y the Y coordinate >=0 * @param a the allocated region to render into * @return the location within the model that best represents * the given point in the view diff --git a/jdk/src/share/classes/javax/swing/text/CompositeView.java b/jdk/src/share/classes/javax/swing/text/CompositeView.java index dc8627b2086..0af70dd335a 100644 --- a/jdk/src/share/classes/javax/swing/text/CompositeView.java +++ b/jdk/src/share/classes/javax/swing/text/CompositeView.java @@ -143,7 +143,7 @@ public abstract class CompositeView extends View { /** * Returns the number of child views of this view. * - * @return the number of views >= 0 + * @return the number of views >= 0 * @see #getView */ public int getViewCount() { @@ -153,7 +153,7 @@ public abstract class CompositeView extends View { /** * Returns the n-th view in this container. * - * @param n the number of the desired view, >= 0 && < getViewCount() + * @param n the number of the desired view, >= 0 && < getViewCount() * @return the view at index n */ public View getView(int n) { @@ -169,9 +169,9 @@ public abstract class CompositeView extends View { * may be garbage collected. * * @param offset the starting index into the child views to insert - * the new views; >= 0 and <= getViewCount + * the new views; >= 0 and <= getViewCount * @param length the number of existing child views to remove; - * this should be a value >= 0 and <= (getViewCount() - offset) + * this should be a value >= 0 and <= (getViewCount() - offset) * @param views the child views to add; this value can be * null * to indicate no children are being added (useful to remove) @@ -223,7 +223,7 @@ public abstract class CompositeView extends View { * render into. This enables finding out where various views * are located. * - * @param index the index of the child, >= 0 && < getViewCount() + * @param index the index of the child, >= 0 && < getViewCount() * @param a the allocation to this view * @return the allocation to the child */ @@ -237,7 +237,7 @@ public abstract class CompositeView extends View { * Provides a mapping from the document model coordinate space * to the coordinate space of the view mapped to it. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param a the allocated region to render into * @param b a bias value of either Position.Bias.Forward * or Position.Bias.Backward @@ -280,13 +280,13 @@ public abstract class CompositeView extends View { * Provides a mapping from the document model coordinate space * to the coordinate space of the view mapped to it. * - * @param p0 the position to convert >= 0 + * @param p0 the position to convert >= 0 * @param b0 the bias toward the previous character or the * next character represented by p0, in case the * position is a boundary of two views; either * Position.Bias.Forward or * Position.Bias.Backward - * @param p1 the position to convert >= 0 + * @param p1 the position to convert >= 0 * @param b1 the bias toward the previous character or the * next character represented by p1, in case the * position is a boundary of two views @@ -378,13 +378,13 @@ public abstract class CompositeView extends View { * Provides a mapping from the view coordinate space to the logical * coordinate space of the model. * - * @param x x coordinate of the view location to convert >= 0 - * @param y y coordinate of the view location to convert >= 0 + * @param x x coordinate of the view location to convert >= 0 + * @param y y coordinate of the view location to convert >= 0 * @param a the allocated region to render into * @param bias either Position.Bias.Forward or * Position.Bias.Backward * @return the location within the model that best represents the - * given point in the view >= 0 + * given point in the view >= 0 * @see View#viewToModel */ public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) { @@ -436,7 +436,7 @@ public abstract class CompositeView extends View { * This is a convenience method for {@link #getNextNorthSouthVisualPositionFrom} * and {@link #getNextEastWestVisualPositionFrom}. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param b a bias value of either Position.Bias.Forward * or Position.Bias.Backward * @param a the allocated region to render into @@ -484,7 +484,7 @@ public abstract class CompositeView extends View { * getViewIndexByPosition * method for backward compatibility. * - * @param pos the position >= 0 + * @param pos the position >= 0 * @return index of the view representing the given position, or * -1 if no view represents that position * @since 1.3 @@ -505,8 +505,8 @@ public abstract class CompositeView extends View { /** * Tests whether a point lies before the rectangle range. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >= 0 + * @param y the Y coordinate >= 0 * @param alloc the rectangle * @return true if the point is before the specified range */ @@ -515,8 +515,8 @@ public abstract class CompositeView extends View { /** * Tests whether a point lies after the rectangle range. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >= 0 + * @param y the Y coordinate >= 0 * @param alloc the rectangle * @return true if the point is after the specified range */ @@ -525,8 +525,8 @@ public abstract class CompositeView extends View { /** * Fetches the child view at the given coordinates. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >= 0 + * @param y the Y coordinate >= 0 * @param alloc the parent's allocation on entry, which should * be changed to the child's allocation on exit * @return the child view @@ -536,7 +536,7 @@ public abstract class CompositeView extends View { /** * Returns the allocation for a given child. * - * @param index the index of the child, >= 0 && < getViewCount() + * @param index the index of the child, >= 0 && < getViewCount() * @param a the allocation to the interior of the box on entry, * and the allocation of the child view at the index on exit. */ @@ -547,7 +547,7 @@ public abstract class CompositeView extends View { * the model. This is implemented to fetch the view in the case * where there is a child view for each child element. * - * @param pos the position >= 0 + * @param pos the position >= 0 * @param a the allocation to the interior of the box on entry, * and the allocation of the view containing the position on exit * @return the view representing the given position, or @@ -570,7 +570,7 @@ public abstract class CompositeView extends View { * the model. This is implemented to fetch the view in the case * where there is a child view for each child element. * - * @param pos the position >= 0 + * @param pos the position >= 0 * @return index of the view representing the given position, or * -1 if no view represents that position */ @@ -639,10 +639,10 @@ public abstract class CompositeView extends View { /** * Sets the insets for the view. * - * @param top the top inset >= 0 - * @param left the left inset >= 0 - * @param bottom the bottom inset >= 0 - * @param right the right inset >= 0 + * @param top the top inset >= 0 + * @param left the left inset >= 0 + * @param bottom the bottom inset >= 0 + * @param right the right inset >= 0 */ protected void setInsets(short top, short left, short bottom, short right) { this.top = top; @@ -654,7 +654,7 @@ public abstract class CompositeView extends View { /** * Gets the left inset. * - * @return the inset >= 0 + * @return the inset >= 0 */ protected short getLeftInset() { return left; @@ -663,7 +663,7 @@ public abstract class CompositeView extends View { /** * Gets the right inset. * - * @return the inset >= 0 + * @return the inset >= 0 */ protected short getRightInset() { return right; @@ -672,7 +672,7 @@ public abstract class CompositeView extends View { /** * Gets the top inset. * - * @return the inset >= 0 + * @return the inset >= 0 */ protected short getTopInset() { return top; @@ -681,7 +681,7 @@ public abstract class CompositeView extends View { /** * Gets the bottom inset. * - * @return the inset >= 0 + * @return the inset >= 0 */ protected short getBottomInset() { return bottom; @@ -691,7 +691,7 @@ public abstract class CompositeView extends View { * Returns the next visual position for the cursor, in either the * north or south direction. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param b a bias value of either Position.Bias.Forward * or Position.Bias.Backward * @param a the allocated region to render into @@ -723,7 +723,7 @@ public abstract class CompositeView extends View { * Returns the next visual position for the cursor, in either the * east or west direction. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param b a bias value of either Position.Bias.Forward * or Position.Bias.Backward * @param a the allocated region to render into diff --git a/jdk/src/share/classes/javax/swing/text/DefaultEditorKit.java b/jdk/src/share/classes/javax/swing/text/DefaultEditorKit.java index 775e7393cb6..cd310104dd3 100644 --- a/jdk/src/share/classes/javax/swing/text/DefaultEditorKit.java +++ b/jdk/src/share/classes/javax/swing/text/DefaultEditorKit.java @@ -140,7 +140,7 @@ public class DefaultEditorKit extends EditorKit { * @param in The stream to read from * @param doc The destination for the insertion. * @param pos The location in the document to place the - * content >= 0. + * content >=0. * @exception IOException on any I/O error * @exception BadLocationException if pos represents an invalid * location within the document. @@ -158,8 +158,8 @@ public class DefaultEditorKit extends EditorKit { * @param out The stream to write to * @param doc The source for the write. * @param pos The location in the document to fetch the - * content >= 0. - * @param len The amount to write out >= 0. + * content >=0. + * @param len The amount to write out >=0. * @exception IOException on any I/O error * @exception BadLocationException if pos represents an invalid * location within the document. @@ -191,7 +191,7 @@ public class DefaultEditorKit extends EditorKit { * @param in The stream to read from * @param doc The destination for the insertion. * @param pos The location in the document to place the - * content >= 0. + * content >=0. * @exception IOException on any I/O error * @exception BadLocationException if pos represents an invalid * location within the document. @@ -300,8 +300,8 @@ public class DefaultEditorKit extends EditorKit { * @param out The stream to write to * @param doc The source for the write. * @param pos The location in the document to fetch the - * content from >= 0. - * @param len The amount to write out >= 0. + * content from >=0. + * @param len The amount to write out >=0. * @exception IOException on any I/O error * @exception BadLocationException if pos is not within 0 and * the length of the document. diff --git a/jdk/src/share/classes/javax/swing/text/DefaultHighlighter.java b/jdk/src/share/classes/javax/swing/text/DefaultHighlighter.java index fce9e8b4869..3614d2a60ed 100644 --- a/jdk/src/share/classes/javax/swing/text/DefaultHighlighter.java +++ b/jdk/src/share/classes/javax/swing/text/DefaultHighlighter.java @@ -105,8 +105,8 @@ public class DefaultHighlighter extends LayeredHighlighter { * Adds a highlight to the view. Returns a tag that can be used * to refer to the highlight. * - * @param p0 the start offset of the range to highlight >= 0 - * @param p1 the end offset of the range to highlight >= p0 + * @param p0 the start offset of the range to highlight >= 0 + * @param p1 the end offset of the range to highlight >= p0 * @param p the painter to use to actually render the highlight * @return an object that can be used as a tag * to refer to the highlight @@ -220,8 +220,8 @@ public class DefaultHighlighter extends LayeredHighlighter { * Changes a highlight. * * @param tag the highlight tag - * @param p0 the beginning of the range >= 0 - * @param p1 the end of the range >= p0 + * @param p0 the beginning of the range >= 0 + * @param p1 the end of the range >= p0 * @exception BadLocationException if the specified location is invalid */ public void changeHighlight(Object tag, int p0, int p1) throws BadLocationException { @@ -395,8 +395,8 @@ public class DefaultHighlighter extends LayeredHighlighter { * Paints a highlight. * * @param g the graphics context - * @param offs0 the starting model offset >= 0 - * @param offs1 the ending model offset >= offs1 + * @param offs0 the starting model offset >= 0 + * @param offs1 the ending model offset >= offs1 * @param bounds the bounding box for the highlight * @param c the editor */ @@ -441,8 +441,8 @@ public class DefaultHighlighter extends LayeredHighlighter { * Paints a portion of a highlight. * * @param g the graphics context - * @param offs0 the starting model offset >= 0 - * @param offs1 the ending model offset >= offs1 + * @param offs0 the starting model offset >= 0 + * @param offs1 the ending model offset >= offs1 * @param bounds the bounding box of the view, which is not * necessarily the region to paint. * @param c the editor diff --git a/jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java b/jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java index 0ab766bd813..4a6419e77d6 100644 --- a/jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java +++ b/jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java @@ -176,7 +176,7 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc * Concurrency * in Swing for more information. * - * @param offset the starting offset >= 0 + * @param offset the starting offset >= 0 * @param data the element data * @exception BadLocationException for an invalid starting offset */ @@ -429,7 +429,7 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc * Concurrency * in Swing for more information. * - * @param pos the offset from the start of the document >= 0 + * @param pos the offset from the start of the document >= 0 * @param s the logical style to assign to the paragraph, null if none */ public void setLogicalStyle(int pos, Style s) { @@ -458,7 +458,7 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc * represented by the given position. * * @param p the location to translate to a paragraph - * and determine the logical style assigned >= 0. This + * and determine the logical style assigned >= 0. This * is an offset from the start of the document. * @return the style, null if none */ @@ -486,8 +486,8 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc * Concurrency * in Swing for more information. * - * @param offset the offset in the document >= 0 - * @param length the length >= 0 + * @param offset the offset in the document >= 0 + * @param length the length >= 0 * @param s the attributes * @param replace true if the previous attributes should be replaced * before setting the new attributes @@ -539,8 +539,8 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc * Concurrency * in Swing for more information. * - * @param offset the offset into the paragraph >= 0 - * @param length the number of characters affected >= 0 + * @param offset the offset into the paragraph >= 0 + * @param length the number of characters affected >= 0 * @param s the attributes * @param replace whether to replace existing attributes, or merge them */ @@ -589,7 +589,7 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc * A paragraph consists of at least one child Element, which is usually * a leaf. * - * @param pos the starting offset >= 0 + * @param pos the starting offset >= 0 * @return the element */ public Element getParagraphElement(int pos) { @@ -606,7 +606,7 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc /** * Gets a character element based on a position. * - * @param pos the position in the document >= 0 + * @param pos the position in the document >= 0 * @return the element */ public Element getCharacterElement(int pos) { @@ -1233,7 +1233,7 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc * @param a the attributes for the element * @param type the type of the element (StartTagType, EndTagType, * ContentType) - * @param len the length >= 0 + * @param len the length >= 0 */ public ElementSpec(AttributeSet a, short type, int len) { this(a, type, null, 0, len); @@ -1247,8 +1247,8 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc * @param type the type of the element (StartTagType, EndTagType, * ContentType) * @param txt the text for the element - * @param offs the offset into the text >= 0 - * @param len the length of the text >= 0 + * @param offs the offset into the text >= 0 + * @param len the length of the text >= 0 */ public ElementSpec(AttributeSet a, short type, char[] txt, int offs, int len) { @@ -1321,7 +1321,7 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc /** * Gets the starting offset. * - * @return the offset >= 0 + * @return the offset >= 0 */ public int getOffset() { return offs; @@ -1330,7 +1330,7 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc /** * Gets the length. * - * @return the length >= 0 + * @return the length >= 0 */ public int getLength() { return len; @@ -1420,8 +1420,8 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc /** * Inserts new content. * - * @param offset the starting offset >= 0 - * @param length the length >= 0 + * @param offset the starting offset >= 0 + * @param length the length >= 0 * @param data the data to insert * @param de the event capturing this edit */ @@ -1500,8 +1500,8 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc /** * Removes content. * - * @param offset the starting offset >= 0 - * @param length the length >= 0 + * @param offset the starting offset >= 0 + * @param length the length >= 0 * @param de the event capturing this edit */ public void remove(int offset, int length, DefaultDocumentEvent de) { @@ -1513,8 +1513,8 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc /** * Changes content. * - * @param offset the starting offset >= 0 - * @param length the length >= 0 + * @param offset the starting offset >= 0 + * @param length the length >= 0 * @param de the event capturing this edit */ public void change(int offset, int length, DefaultDocumentEvent de) { diff --git a/jdk/src/share/classes/javax/swing/text/Document.java b/jdk/src/share/classes/javax/swing/text/Document.java index daacd05b9db..51505707db3 100644 --- a/jdk/src/share/classes/javax/swing/text/Document.java +++ b/jdk/src/share/classes/javax/swing/text/Document.java @@ -58,9 +58,9 @@ import javax.swing.event.*; *

    The following methods give access to the character data * that makes up the content. *

    *

    Structure *

    @@ -79,8 +79,8 @@ import javax.swing.event.*; * AttributeSet interface. *

    The following methods give access to the document structure. *

    * *

    Mutations @@ -93,9 +93,9 @@ import javax.swing.event.*; *

    The following methods are related to mutation of the * document content: *

    * *

    Notification @@ -161,8 +161,8 @@ import javax.swing.event.*; * and the TitleProperty, which can be used to * name the Document. The methods related to the properties are: *

    * *

    For more information on the Document class, see diff --git a/jdk/src/share/classes/javax/swing/text/DocumentFilter.java b/jdk/src/share/classes/javax/swing/text/DocumentFilter.java index 0f6ac84f02f..797cd81a605 100644 --- a/jdk/src/share/classes/javax/swing/text/DocumentFilter.java +++ b/jdk/src/share/classes/javax/swing/text/DocumentFilter.java @@ -68,8 +68,8 @@ public class DocumentFilter { * necessary. * * @param fb FilterBypass that can be used to mutate Document - * @param offset the offset from the beginning >= 0 - * @param length the number of characters to remove >= 0 + * @param offset the offset from the beginning >= 0 + * @param length the number of characters to remove >= 0 * @exception BadLocationException some portion of the removal range * was not a valid part of the document. The location in the exception * is the first bad position encountered. @@ -86,7 +86,7 @@ public class DocumentFilter { * necessary, or call directly into the FilterBypass. * * @param fb FilterBypass that can be used to mutate Document - * @param offset the offset into the document to insert the content >= 0. + * @param offset the offset into the document to insert the content >= 0. * All positions that track change at or after the given location * will move. * @param string the string to insert @@ -141,8 +141,8 @@ public class DocumentFilter { * Removes the specified region of text, bypassing the * DocumentFilter. * - * @param offset the offset from the beginning >= 0 - * @param length the number of characters to remove >= 0 + * @param offset the offset from the beginning >= 0 + * @param length the number of characters to remove >= 0 * @exception BadLocationException some portion of the removal range * was not a valid part of the document. The location in the * exception is the first bad position encountered. @@ -154,7 +154,7 @@ public class DocumentFilter { * Inserts the specified text, bypassing the * DocumentFilter. * @param offset the offset into the document to insert the - * content >= 0. All positions that track change at or after the + * content >= 0. All positions that track change at or after the * given location will move. * @param string the string to insert * @param attr the attributes to associate with the inserted diff --git a/jdk/src/share/classes/javax/swing/text/EditorKit.java b/jdk/src/share/classes/javax/swing/text/EditorKit.java index 8251ae63e7f..c3d2722b098 100644 --- a/jdk/src/share/classes/javax/swing/text/EditorKit.java +++ b/jdk/src/share/classes/javax/swing/text/EditorKit.java @@ -55,7 +55,7 @@ public abstract class EditorKit implements Cloneable, Serializable { /** * Creates a copy of the editor kit. This is implemented - * to use Object.clone. If the kit cannot be cloned, + * to use Object.clone(). If the kit cannot be cloned, * null is returned. * * @return the copy @@ -139,7 +139,7 @@ public abstract class EditorKit implements Cloneable, Serializable { * @param in The stream to read from * @param doc The destination for the insertion. * @param pos The location in the document to place the - * content >= 0. + * content >= 0. * @exception IOException on any I/O error * @exception BadLocationException if pos represents an invalid * location within the document. @@ -154,8 +154,8 @@ public abstract class EditorKit implements Cloneable, Serializable { * @param out The stream to write to * @param doc The source for the write. * @param pos The location in the document to fetch the - * content from >= 0. - * @param len The amount to write out >= 0. + * content from >= 0. + * @param len The amount to write out >= 0. * @exception IOException on any I/O error * @exception BadLocationException if pos represents an invalid * location within the document. @@ -176,7 +176,7 @@ public abstract class EditorKit implements Cloneable, Serializable { * @param in The stream to read from * @param doc The destination for the insertion. * @param pos The location in the document to place the - * content >= 0. + * content >= 0. * @exception IOException on any I/O error * @exception BadLocationException if pos represents an invalid * location within the document. @@ -196,8 +196,8 @@ public abstract class EditorKit implements Cloneable, Serializable { * @param out The stream to write to * @param doc The source for the write. * @param pos The location in the document to fetch the - * content >= 0. - * @param len The amount to write out >= 0. + * content >= 0. + * @param len The amount to write out >= 0. * @exception IOException on any I/O error * @exception BadLocationException if pos represents an invalid * location within the document. diff --git a/jdk/src/share/classes/javax/swing/text/FieldView.java b/jdk/src/share/classes/javax/swing/text/FieldView.java index 93f27f92a44..867ef44cc55 100644 --- a/jdk/src/share/classes/javax/swing/text/FieldView.java +++ b/jdk/src/share/classes/javax/swing/text/FieldView.java @@ -200,7 +200,7 @@ public class FieldView extends PlainView { * axis. * * @param axis may be either View.X_AXIS or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0. + * @return the span the view would like to be rendered into >= 0. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. @@ -241,7 +241,7 @@ public class FieldView extends PlainView { * given axis. A value of 0 or less is not resizable. * * @param axis View.X_AXIS or View.Y_AXIS - * @return the weight -> 1 for View.X_AXIS, else 0 + * @return the weight -> 1 for View.X_AXIS, else 0 */ public int getResizeWeight(int axis) { if (axis == View.X_AXIS) { @@ -254,7 +254,7 @@ public class FieldView extends PlainView { * Provides a mapping from the document model coordinate space * to the coordinate space of the view mapped to it. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param a the allocated region to render into * @return the bounding box of the given position * @exception BadLocationException if the given position does not @@ -269,8 +269,8 @@ public class FieldView extends PlainView { * Provides a mapping from the view coordinate space to the logical * coordinate space of the model. * - * @param fx the X coordinate >= 0.0f - * @param fy the Y coordinate >= 0.0f + * @param fx the X coordinate >= 0.0f + * @param fy the Y coordinate >= 0.0f * @param a the allocated region to render into * @return the location within the model that best represents the * given point in the view diff --git a/jdk/src/share/classes/javax/swing/text/FlowView.java b/jdk/src/share/classes/javax/swing/text/FlowView.java index 8cd647ce961..972d10e3b22 100644 --- a/jdk/src/share/classes/javax/swing/text/FlowView.java +++ b/jdk/src/share/classes/javax/swing/text/FlowView.java @@ -88,7 +88,7 @@ public abstract class FlowView extends BoxView { * is returned. * * @param index the index of the row being updated. - * This should be a value >= 0 and < getViewCount(). + * This should be a value >= 0 and < getViewCount(). * @see #getFlowStart */ public int getFlowSpan(int index) { @@ -103,7 +103,7 @@ public abstract class FlowView extends BoxView { * for the row constraints. * @param index the index of the row being updated. - * This should be a value >= 0 and < getViewCount(). + * This should be a value >= 0 and < getViewCount(). * @see #getFlowSpan */ public int getFlowStart(int index) { @@ -147,7 +147,7 @@ public abstract class FlowView extends BoxView { * Fetches the child view index representing the given position in * the model. * - * @param pos the position >= 0 + * @param pos the position >= 0 * @return index of the view representing the given position, or * -1 if no view represents that position */ @@ -175,9 +175,9 @@ public abstract class FlowView extends BoxView { * a preferenceChanged is called. Following all of that, * the normal box layout of the superclass is performed. * - * @param width the width to lay out against >= 0. This is + * @param width the width to lay out against >= 0. This is * the width inside of the inset area. - * @param height the height to lay out against >= 0 This + * @param height the height to lay out against >= 0 This * is the height inside of the inset area. */ protected void layout(int width, int height) { @@ -580,7 +580,7 @@ public abstract class FlowView extends BoxView { * * @param rowIndex the row to adjust to the current layout * span. - * @param desiredSpan the current layout span >= 0 + * @param desiredSpan the current layout span >= 0 * @param x the location r starts at. */ protected void adjustRow(FlowView fv, int rowIndex, int desiredSpan, int x) { @@ -832,8 +832,8 @@ public abstract class FlowView extends BoxView { * Implemented to return false, as hit detection is not * performed on the logical view. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >= 0 + * @param y the Y coordinate >= 0 * @param alloc the rectangle * @return true if the point is before the specified range */ @@ -846,8 +846,8 @@ public abstract class FlowView extends BoxView { * Implemented to return false, as hit detection is not * performed on the logical view. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >= 0 + * @param y the Y coordinate >= 0 * @param alloc the rectangle * @return true if the point is after the specified range */ @@ -860,8 +860,8 @@ public abstract class FlowView extends BoxView { * Implemented to return null, as hit detection is not * performed on the logical view. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >= 0 + * @param y the Y coordinate >= 0 * @param alloc the parent's allocation on entry, which should * be changed to the child's allocation on exit * @return the child view @@ -875,7 +875,7 @@ public abstract class FlowView extends BoxView { * Implemented to do nothing, as the logical view doesn't * perform layout on the children. * - * @param index the index of the child, >= 0 && < getViewCount() + * @param index the index of the child, >= 0 && < getViewCount() * @param a the allocation to the interior of the box on entry, * and the allocation of the child view at the index on exit. */ diff --git a/jdk/src/share/classes/javax/swing/text/GapContent.java b/jdk/src/share/classes/javax/swing/text/GapContent.java index fecf9c6dc72..160ea1bdecd 100644 --- a/jdk/src/share/classes/javax/swing/text/GapContent.java +++ b/jdk/src/share/classes/javax/swing/text/GapContent.java @@ -107,7 +107,7 @@ public class GapContent extends GapVector implements AbstractDocument.Content, S /** * Returns the length of the content. * - * @return the length >= 1 + * @return the length >= 1 * @see AbstractDocument.Content#length */ public int length() { @@ -118,7 +118,7 @@ public class GapContent extends GapVector implements AbstractDocument.Content, S /** * Inserts a string into the content. * - * @param where the starting position >= 0, < length() + * @param where the starting position >= 0, < length() * @param str the non-null string to insert * @return an UndoableEdit object for undoing * @exception BadLocationException if the specified position is invalid @@ -136,8 +136,8 @@ public class GapContent extends GapVector implements AbstractDocument.Content, S /** * Removes part of the content. * - * @param where the starting position >= 0, where + nitems < length() - * @param nitems the number of characters to remove >= 0 + * @param where the starting position >= 0, where + nitems < length() + * @param nitems the number of characters to remove >= 0 * @return an UndoableEdit object for undoing * @exception BadLocationException if the specified position is invalid * @see AbstractDocument.Content#remove @@ -156,8 +156,8 @@ public class GapContent extends GapVector implements AbstractDocument.Content, S /** * Retrieves a portion of the content. * - * @param where the starting position >= 0 - * @param len the length to retrieve >= 0 + * @param where the starting position >= 0 + * @param len the length to retrieve >= 0 * @return a string representing the content * @exception BadLocationException if the specified position is invalid * @see AbstractDocument.Content#getString @@ -174,8 +174,8 @@ public class GapContent extends GapVector implements AbstractDocument.Content, S * span the gap, the actual store is returned to avoid the copy since * it is contiguous. * - * @param where the starting position >= 0, where + len <= length() - * @param len the number of characters to retrieve >= 0 + * @param where the starting position >= 0, where + len <= length() + * @param len the number of characters to retrieve >= 0 * @param chars the Segment object to return the characters in * @exception BadLocationException if the specified position is invalid * @see AbstractDocument.Content#getChars @@ -222,7 +222,7 @@ public class GapContent extends GapVector implements AbstractDocument.Content, S * Creates a position within the content that will * track change as the content is mutated. * - * @param offset the offset to track >= 0 + * @param offset the offset to track >= 0 * @return the position * @exception BadLocationException if the specified position is invalid */ @@ -705,8 +705,8 @@ public class GapContent extends GapVector implements AbstractDocument.Content, S * there. The vector with the resulting Positions are returned. * * @param v the Vector to use, with a new one created on null - * @param offset the starting offset >= 0 - * @param length the length >= 0 + * @param offset the starting offset >= 0 + * @param length the length >= 0 * @return the set of instances */ protected Vector getPositionsInRange(Vector v, int offset, int length) { diff --git a/jdk/src/share/classes/javax/swing/text/GlyphView.java b/jdk/src/share/classes/javax/swing/text/GlyphView.java index a0ca975c2c3..0c801cfc04a 100644 --- a/jdk/src/share/classes/javax/swing/text/GlyphView.java +++ b/jdk/src/share/classes/javax/swing/text/GlyphView.java @@ -121,8 +121,8 @@ public class GlyphView extends View implements TabableView, Cloneable { * the GlyphPainter to determine what characters * it should render glyphs for. * - * @param p0 the starting document offset >= 0 - * @param p1 the ending document offset >= p0 + * @param p0 the starting document offset >= 0 + * @param p1 the ending document offset >= p0 * @return the Segment containing the text */ public Segment getText(int p0, int p1) { @@ -282,9 +282,9 @@ public class GlyphView extends View implements TabableView, Cloneable { * tab expansion implementation. * * @param x the position the view would be located - * at for the purpose of tab expansion >= 0. + * at for the purpose of tab expansion >= 0. * @param e how to expand the tabs when encountered. - * @return the desired span >= 0 + * @return the desired span >= 0 * @see TabableView#getTabbedSpan */ public float getTabbedSpan(float x, TabExpander e) { @@ -321,9 +321,9 @@ public class GlyphView extends View implements TabableView, Cloneable { * arrange for its own text buffer to make the * measurements. * - * @param p0 the starting document offset >= 0 - * @param p1 the ending document offset >= p0 - * @return the span >= 0 + * @param p0 the starting document offset >= 0 + * @param p1 the ending document offset >= p0 + * @return the span >= 0 */ public float getPartialSpan(int p0, int p1) { checkPainter(); @@ -572,7 +572,7 @@ public class GlyphView extends View implements TabableView, Cloneable { * axis. * * @param axis may be either View.X_AXIS or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0. + * @return the span the view would like to be rendered into >= 0. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. @@ -639,7 +639,7 @@ public class GlyphView extends View implements TabableView, Cloneable { * Provides a mapping from the document model coordinate space * to the coordinate space of the view mapped to it. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param a the allocated region to render into * @param b either Position.Bias.Forward * or Position.Bias.Backward @@ -657,14 +657,14 @@ public class GlyphView extends View implements TabableView, Cloneable { * Provides a mapping from the view coordinate space to the logical * coordinate space of the model. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >= 0 + * @param y the Y coordinate >= 0 * @param a the allocated region to render into * @param biasReturn either Position.Bias.Forward * or Position.Bias.Backward is returned as the * zero-th element of this array * @return the location within the model that best represents the - * given point of view >= 0 + * given point of view >= 0 * @see View#viewToModel */ public int viewToModel(float x, float y, Shape a, Position.Bias[] biasReturn) { @@ -702,10 +702,10 @@ public class GlyphView extends View implements TabableView, Cloneable { * * @param axis may be either View.X_AXIS or View.Y_AXIS * @param pos the potential location of the start of the - * broken view >= 0. This may be useful for calculating tab + * broken view >= 0. This may be useful for calculating tab * positions. * @param len specifies the relative length from pos - * where a potential break is desired >= 0. + * where a potential break is desired >= 0. * @return the weight, which should be a value between * View.ForcedBreakWeight and View.BadBreakWeight. * @see LabelView @@ -736,12 +736,12 @@ public class GlyphView extends View implements TabableView, Cloneable { * * @param axis may be either View.X_AXIS or View.Y_AXIS * @param p0 the location in the model where the - * fragment should start it's representation >= 0. + * fragment should start it's representation >= 0. * @param pos the position along the axis that the - * broken view would occupy >= 0. This may be useful for + * broken view would occupy >= 0. This may be useful for * things like tab calculations. * @param len specifies the distance along the axis - * where a potential break is desired >= 0. + * where a potential break is desired >= 0. * @return the fragment of the view that represents the * given span, if the view can be broken. If the view * doesn't support breaking behavior, the view itself is @@ -852,10 +852,10 @@ public class GlyphView extends View implements TabableView, Cloneable { * to return a nested class that shares state in this view * representing only a portion of the view. * - * @param p0 the starting offset >= 0. This should be a value + * @param p0 the starting offset >= 0. This should be a value * greater or equal to the element starting offset and * less than the element ending offset. - * @param p1 the ending offset > p0. This should be a value + * @param p1 the ending offset > p0. This should be a value * less than or equal to the elements end offset and * greater than the elements starting offset. * @return the view fragment, or itself if the view doesn't @@ -880,7 +880,7 @@ public class GlyphView extends View implements TabableView, Cloneable { * they just might not allow access to some of the locations in the * model. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param a the allocated region to render into * @param direction the direction from the current position that can * be thought of as the arrow keys typically found on a keyboard. @@ -1196,12 +1196,12 @@ public class GlyphView extends View implements TabableView, Cloneable { * * @param v the view to find the model location to break at. * @param p0 the location in the model where the - * fragment should start it's representation >= 0. + * fragment should start it's representation >= 0. * @param x the graphic location along the axis that the - * broken view would occupy >= 0. This may be useful for + * broken view would occupy >= 0. This may be useful for * things like tab calculations. * @param len specifies the distance into the view - * where a potential break is desired >= 0. + * where a potential break is desired >= 0. * @return the maximum model location possible for a break. * @see View#breakView */ @@ -1214,8 +1214,8 @@ public class GlyphView extends View implements TabableView, Cloneable { * the painter doesn't hold any significant state, it can * return itself. The default behavior is to return itself. * @param v the GlyphView to provide a painter for - * @param p0 the starting document offset >= 0 - * @param p1 the ending document offset >= p0 + * @param p0 the starting document offset >= 0 + * @param p1 the ending document offset >= p0 */ public GlyphPainter getPainter(GlyphView v, int p0, int p1) { return this; @@ -1229,7 +1229,7 @@ public class GlyphView extends View implements TabableView, Cloneable { * model. * * @param v the view to use - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param b either Position.Bias.Forward * or Position.Bias.Backward * @param a the allocated region to render into diff --git a/jdk/src/share/classes/javax/swing/text/Highlighter.java b/jdk/src/share/classes/javax/swing/text/Highlighter.java index 0f8484ecd3c..f30f66abbc8 100644 --- a/jdk/src/share/classes/javax/swing/text/Highlighter.java +++ b/jdk/src/share/classes/javax/swing/text/Highlighter.java @@ -66,8 +66,8 @@ public interface Highlighter { * Adds a highlight to the view. Returns a tag that can be used * to refer to the highlight. * - * @param p0 the beginning of the range >= 0 - * @param p1 the end of the range >= p0 + * @param p0 the beginning of the range >= 0 + * @param p1 the end of the range >= p0 * @param p the painter to use for the actual highlighting * @return an object that refers to the highlight * @exception BadLocationException for an invalid range specification @@ -93,8 +93,8 @@ public interface Highlighter { * with a mouse) by damaging only what changed. * * @param tag which highlight to change - * @param p0 the beginning of the range >= 0 - * @param p1 the end of the range >= p0 + * @param p0 the beginning of the range >= 0 + * @param p1 the end of the range >= p0 * @exception BadLocationException for an invalid range specification */ public void changeHighlight(Object tag, int p0, int p1) throws BadLocationException; @@ -115,8 +115,8 @@ public interface Highlighter { * Renders the highlight. * * @param g the graphics context - * @param p0 the starting offset in the model >= 0 - * @param p1 the ending offset in the model >= p0 + * @param p0 the starting offset in the model >= 0 + * @param p1 the ending offset in the model >= p0 * @param bounds the bounding box for the highlight * @param c the editor */ @@ -129,14 +129,14 @@ public interface Highlighter { /** * Gets the starting model offset for the highlight. * - * @return the starting offset >= 0 + * @return the starting offset >= 0 */ public int getStartOffset(); /** * Gets the ending model offset for the highlight. * - * @return the ending offset >= 0 + * @return the ending offset >= 0 */ public int getEndOffset(); diff --git a/jdk/src/share/classes/javax/swing/text/IconView.java b/jdk/src/share/classes/javax/swing/text/IconView.java index 1d4f543d740..ef1a41e4698 100644 --- a/jdk/src/share/classes/javax/swing/text/IconView.java +++ b/jdk/src/share/classes/javax/swing/text/IconView.java @@ -101,7 +101,7 @@ public class IconView extends View { * along the x axis. * * @param axis may be either View.X_AXIS or View.Y_AXIS - * @return the desired alignment >= 0.0f && <= 1.0f. This should be + * @return the desired alignment >= 0.0f && <= 1.0f. This should be * a value between 0.0 and 1.0 where 0 indicates alignment at the * origin and 1.0 indicates alignment to the full span * away from the origin. An alignment of 0.5 would be the @@ -120,7 +120,7 @@ public class IconView extends View { * Provides a mapping from the document model coordinate space * to the coordinate space of the view mapped to it. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param a the allocated region to render into * @return the bounding box of the given position * @exception BadLocationException if the given position does not @@ -145,11 +145,11 @@ public class IconView extends View { * Provides a mapping from the view coordinate space to the logical * coordinate space of the model. * - * @param x the X coordinate >= 0 - * @param y the Y coordinate >= 0 + * @param x the X coordinate >= 0 + * @param y the Y coordinate >= 0 * @param a the allocated region to render into * @return the location within the model that best represents the - * given point of view >= 0 + * given point of view >= 0 * @see View#viewToModel */ public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) { diff --git a/jdk/src/share/classes/javax/swing/text/NavigationFilter.java b/jdk/src/share/classes/javax/swing/text/NavigationFilter.java index 96206b82cab..d5ca6575d58 100644 --- a/jdk/src/share/classes/javax/swing/text/NavigationFilter.java +++ b/jdk/src/share/classes/javax/swing/text/NavigationFilter.java @@ -57,7 +57,7 @@ public class NavigationFilter { * on the FilterBypass * * @param fb FilterBypass that can be used to mutate caret position - * @param dot the position >= 0 + * @param dot the position >= 0 * @param bias Bias to place the dot at */ public void setDot(FilterBypass fb, int dot, Position.Bias bias) { @@ -72,7 +72,7 @@ public class NavigationFilter { * methods on the FilterBypass. * * @param fb FilterBypass that can be used to mutate caret position - * @param dot the position >= 0 + * @param dot the position >= 0 * @param bias Bias for new location */ public void moveDot(FilterBypass fb, int dot, Position.Bias bias) { @@ -131,7 +131,7 @@ public class NavigationFilter { /** * Sets the caret location, bypassing the NavigationFilter. * - * @param dot the position >= 0 + * @param dot the position >= 0 * @param bias Bias to place the dot at */ public abstract void setDot(int dot, Position.Bias bias); @@ -139,7 +139,7 @@ public class NavigationFilter { /** * Moves the caret location, bypassing the NavigationFilter. * - * @param dot the position >= 0 + * @param dot the position >= 0 * @param bias Bias for new location */ public abstract void moveDot(int dot, Position.Bias bias); diff --git a/jdk/src/share/classes/javax/swing/text/ParagraphView.java b/jdk/src/share/classes/javax/swing/text/ParagraphView.java index 396e153e520..85d70d5f9c9 100644 --- a/jdk/src/share/classes/javax/swing/text/ParagraphView.java +++ b/jdk/src/share/classes/javax/swing/text/ParagraphView.java @@ -409,8 +409,8 @@ public class ParagraphView extends FlowView implements TabExpander { * * @param x the X reference position * @param tabOffset the position within the text stream - * that the tab occurred at >= 0 - * @return the trailing end of the tab expansion >= 0 + * that the tab occurred at >= 0 + * @return the trailing end of the tab expansion >= 0 * @see TabSet * @see TabStop * @see LabelView @@ -489,9 +489,9 @@ public class ParagraphView extends FlowView implements TabExpander { * the TabableView interface, * the preferredSpan will be used. * - * @param startOffset the starting document offset >= 0 - * @param endOffset the ending document offset >= startOffset - * @return the size >= 0 + * @param startOffset the starting document offset >= 0 + * @param endOffset the ending document offset >= startOffset + * @return the size >= 0 */ protected float getPartialSize(int startOffset, int endOffset) { float size = 0.0f; @@ -529,7 +529,7 @@ public class ParagraphView extends FlowView implements TabExpander { * there are no characters found, -1 will be returned. * * @param string the string of characters - * @param start where to start in the model >= 0 + * @param start where to start in the model >= 0 * @return the document offset, or -1 if no characters found */ protected int findOffsetToCharactersInString(char[] string, @@ -642,7 +642,7 @@ public class ParagraphView extends FlowView implements TabExpander { * @param axis may be either View.X_AXIS * or View.Y_AXIS * @param len specifies where a potential break is desired - * along the given axis >= 0 + * along the given axis >= 0 * @param a the current allocation of the view * @return the fragment of the view that represents the * given span, if the view can be broken; if the view @@ -675,7 +675,7 @@ public class ParagraphView extends FlowView implements TabExpander { * * @param axis may be either View.X_AXIS * or View.Y_AXIS - * @param len specifies where a potential break is desired >= 0 + * @param len specifies where a potential break is desired >= 0 * @return a value indicating the attractiveness of breaking here; * either GoodBreakWeight or BadBreakWeight * @see View#getBreakWeight @@ -1141,7 +1141,7 @@ public class ParagraphView extends FlowView implements TabExpander { * Fetches the child view index representing the given position in * the model. * - * @param pos the position >= 0 + * @param pos the position >= 0 * @return index of the view representing the given position, or * -1 if no view represents that position */ diff --git a/jdk/src/share/classes/javax/swing/text/PasswordView.java b/jdk/src/share/classes/javax/swing/text/PasswordView.java index 5073218dafb..c9b9659a45b 100644 --- a/jdk/src/share/classes/javax/swing/text/PasswordView.java +++ b/jdk/src/share/classes/javax/swing/text/PasswordView.java @@ -55,11 +55,11 @@ public class PasswordView extends FieldView { * using the value returned by getEchoChar(). * * @param g the graphics context - * @param x the starting X coordinate >= 0 - * @param y the starting Y coordinate >= 0 - * @param p0 the starting offset in the model >= 0 - * @param p1 the ending offset in the model >= p0 - * @return the X location of the end of the range >= 0 + * @param x the starting X coordinate >= 0 + * @param y the starting Y coordinate >= 0 + * @param p0 the starting offset in the model >= 0 + * @param p1 the ending offset in the model >= p0 + * @return the X location of the end of the range >= 0 * @exception BadLocationException if p0 or p1 are out of range */ protected int drawUnselectedText(Graphics g, int x, int y, @@ -94,11 +94,11 @@ public class PasswordView extends FieldView { * display the characters. * * @param g the graphics context - * @param x the starting X coordinate >= 0 - * @param y the starting Y coordinate >= 0 - * @param p0 the starting offset in the model >= 0 - * @param p1 the ending offset in the model >= p0 - * @return the X location of the end of the range >= 0 + * @param x the starting X coordinate >= 0 + * @param y the starting Y coordinate >= 0 + * @param p0 the starting offset in the model >= 0 + * @param p1 the ending offset in the model >= p0 + * @return the X location of the end of the range >= 0 * @exception BadLocationException if p0 or p1 are out of range */ protected int drawSelectedText(Graphics g, int x, @@ -126,10 +126,10 @@ public class PasswordView extends FieldView { * or unselected text. * * @param g the graphics context - * @param x the starting X coordinate >= 0 - * @param y the starting Y coordinate >= 0 + * @param x the starting X coordinate >= 0 + * @param y the starting Y coordinate >= 0 * @param c the echo character - * @return the updated X position >= 0 + * @return the updated X position >= 0 */ protected int drawEchoCharacter(Graphics g, int x, int y, char c) { ONE[0] = c; @@ -142,7 +142,7 @@ public class PasswordView extends FieldView { * Provides a mapping from the document model coordinate space * to the coordinate space of the view mapped to it. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param a the allocated region to render into * @return the bounding box of the given position * @exception BadLocationException if the given position does not @@ -172,8 +172,8 @@ public class PasswordView extends FieldView { * Provides a mapping from the view coordinate space to the logical * coordinate space of the model. * - * @param fx the X coordinate >= 0.0f - * @param fy the Y coordinate >= 0.0f + * @param fx the X coordinate >= 0.0f + * @param fy the Y coordinate >= 0.0f * @param a the allocated region to render into * @return the location within the model that best represents the * given point in the view @@ -210,7 +210,7 @@ public class PasswordView extends FieldView { * axis. * * @param axis may be either View.X_AXIS or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0. + * @return the span the view would like to be rendered into >= 0. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. diff --git a/jdk/src/share/classes/javax/swing/text/PlainDocument.java b/jdk/src/share/classes/javax/swing/text/PlainDocument.java index 05fd22110fa..8424faf092c 100644 --- a/jdk/src/share/classes/javax/swing/text/PlainDocument.java +++ b/jdk/src/share/classes/javax/swing/text/PlainDocument.java @@ -103,7 +103,7 @@ public class PlainDocument extends AbstractDocument { * Concurrency * in Swing for more information. * - * @param offs the starting offset >= 0 + * @param offs the starting offset >= 0 * @param str the string to insert; does nothing with null/empty strings * @param a the attributes for the inserted content * @exception BadLocationException the given insert position is not a valid diff --git a/jdk/src/share/classes/javax/swing/text/PlainView.java b/jdk/src/share/classes/javax/swing/text/PlainView.java index 7a071777010..ec5d6b68366 100644 --- a/jdk/src/share/classes/javax/swing/text/PlainView.java +++ b/jdk/src/share/classes/javax/swing/text/PlainView.java @@ -66,10 +66,10 @@ public class PlainView extends View implements TabExpander { * drawSelectedText so that the way selected and * unselected text are rendered can be customized. * - * @param lineIndex the line to draw >= 0 + * @param lineIndex the line to draw >= 0 * @param g the Graphics context - * @param x the starting X position >= 0 - * @param y the starting Y position >= 0 + * @param x the starting X position >= 0 + * @param y the starting Y position >= 0 * @see #drawUnselectedText * @see #drawSelectedText */ @@ -138,11 +138,11 @@ public class PlainView extends View implements TabExpander { * text. Uses the foreground or disabled color to render the text. * * @param g the graphics context - * @param x the starting X coordinate >= 0 - * @param y the starting Y coordinate >= 0 - * @param p0 the beginning position in the model >= 0 - * @param p1 the ending position in the model >= 0 - * @return the X location of the end of the range >= 0 + * @param x the starting X coordinate >= 0 + * @param y the starting Y coordinate >= 0 + * @param p0 the beginning position in the model >= 0 + * @param p1 the ending position in the model >= 0 + * @return the X location of the end of the range >= 0 * @exception BadLocationException if the range is invalid */ protected int drawUnselectedText(Graphics g, int x, int y, @@ -163,10 +163,10 @@ public class PlainView extends View implements TabExpander { * the selected background. * * @param g the graphics context - * @param x the starting X coordinate >= 0 - * @param y the starting Y coordinate >= 0 - * @param p0 the beginning position in the model >= 0 - * @param p1 the ending position in the model >= 0 + * @param x the starting X coordinate >= 0 + * @param y the starting Y coordinate >= 0 + * @param p0 the beginning position in the model >= 0 + * @param p1 the ending position in the model >= 0 * @return the location of the end of the range * @exception BadLocationException if the range is invalid */ @@ -218,7 +218,7 @@ public class PlainView extends View implements TabExpander { * axis. * * @param axis may be either View.X_AXIS or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0. + * @return the span the view would like to be rendered into >= 0. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. @@ -332,7 +332,7 @@ public class PlainView extends View implements TabExpander { * Provides a mapping from the document model coordinate space * to the coordinate space of the view mapped to it. * - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param a the allocated region to render into * @return the bounding box of the given position * @exception BadLocationException if the given position does not @@ -369,11 +369,11 @@ public class PlainView extends View implements TabExpander { * Provides a mapping from the view coordinate space to the logical * coordinate space of the model. * - * @param fx the X coordinate >= 0 - * @param fy the Y coordinate >= 0 + * @param fx the X coordinate >= 0 + * @param fy the Y coordinate >= 0 * @param a the allocated region to render into * @return the location within the model that best represents the - * given point in the view >= 0 + * given point in the view >= 0 * @see View#viewToModel */ public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) { @@ -482,8 +482,8 @@ public class PlainView extends View implements TabExpander { * layout of the view along the given axis, if it * has any layout duties. * - * @param width the width >= 0 - * @param height the height >= 0 + * @param width the width >= 0 + * @param height the height >= 0 */ public void setSize(float width, float height) { super.setSize(width, height); @@ -497,10 +497,10 @@ public class PlainView extends View implements TabExpander { * This implementation does not support things like centering so it * ignores the tabOffset argument. * - * @param x the current position >= 0 + * @param x the current position >= 0 * @param tabOffset the position within the text stream - * that the tab occurred at >= 0. - * @return the tab stop, measured in points >= 0 + * that the tab occurred at >= 0. + * @return the tab stop, measured in points >= 0 */ public float nextTabStop(float x, int tabOffset) { if (tabSize == 0) { diff --git a/jdk/src/share/classes/javax/swing/text/Position.java b/jdk/src/share/classes/javax/swing/text/Position.java index 92c500f6ce6..7ad9d8bc52a 100644 --- a/jdk/src/share/classes/javax/swing/text/Position.java +++ b/jdk/src/share/classes/javax/swing/text/Position.java @@ -51,7 +51,7 @@ public interface Position { /** * Fetches the current offset within the document. * - * @return the offset >= 0 + * @return the offset >= 0 */ public int getOffset(); diff --git a/jdk/src/share/classes/javax/swing/text/StringContent.java b/jdk/src/share/classes/javax/swing/text/StringContent.java index 7fe6906a4d8..c834894845c 100644 --- a/jdk/src/share/classes/javax/swing/text/StringContent.java +++ b/jdk/src/share/classes/javax/swing/text/StringContent.java @@ -61,7 +61,7 @@ public final class StringContent implements AbstractDocument.Content, Serializab /** * Creates a new StringContent object, with the initial - * size specified. If the length is < 1, a size of 1 is used. + * size specified. If the length is < 1, a size of 1 is used. * * @param initialLength the initial size */ @@ -77,7 +77,7 @@ public final class StringContent implements AbstractDocument.Content, Serializab /** * Returns the length of the content. * - * @return the length >= 1 + * @return the length >= 1 * @see AbstractDocument.Content#length */ public int length() { @@ -87,7 +87,7 @@ public final class StringContent implements AbstractDocument.Content, Serializab /** * Inserts a string into the content. * - * @param where the starting position >= 0 && < length() + * @param where the starting position >= 0 && < length() * @param str the non-null string to insert * @return an UndoableEdit object for undoing * @exception BadLocationException if the specified position is invalid @@ -106,10 +106,10 @@ public final class StringContent implements AbstractDocument.Content, Serializab } /** - * Removes part of the content. where + nitems must be < length(). + * Removes part of the content. where + nitems must be < length(). * - * @param where the starting position >= 0 - * @param nitems the number of characters to remove >= 0 + * @param where the starting position >= 0 + * @param nitems the number of characters to remove >= 0 * @return an UndoableEdit object for undoing * @exception BadLocationException if the specified position is invalid * @see AbstractDocument.Content#remove @@ -129,10 +129,10 @@ public final class StringContent implements AbstractDocument.Content, Serializab } /** - * Retrieves a portion of the content. where + len must be <= length(). + * Retrieves a portion of the content. where + len must be <= length(). * - * @param where the starting position >= 0 - * @param len the length to retrieve >= 0 + * @param where the starting position >= 0 + * @param len the length to retrieve >= 0 * @return a string representing the content; may be empty * @exception BadLocationException if the specified position is invalid * @see AbstractDocument.Content#getString @@ -145,10 +145,10 @@ public final class StringContent implements AbstractDocument.Content, Serializab } /** - * Retrieves a portion of the content. where + len must be <= length() + * Retrieves a portion of the content. where + len must be <= length() * - * @param where the starting position >= 0 - * @param len the number of characters to retrieve >= 0 + * @param where the starting position >= 0 + * @param len the number of characters to retrieve >= 0 * @param chars the Segment object to return the characters in * @exception BadLocationException if the specified position is invalid * @see AbstractDocument.Content#getChars @@ -166,7 +166,7 @@ public final class StringContent implements AbstractDocument.Content, Serializab * Creates a position within the content that will * track change as the content is mutated. * - * @param offset the offset to create a position for >= 0 + * @param offset the offset to create a position for >= 0 * @return the position * @exception BadLocationException if the specified position is invalid */ @@ -266,8 +266,8 @@ public final class StringContent implements AbstractDocument.Content, Serializab * to subclasses. * * @param v the Vector to use, with a new one created on null - * @param offset the starting offset >= 0 - * @param length the length >= 0 + * @param offset the starting offset >= 0 + * @param length the length >= 0 * @return the set of instances */ protected Vector getPositionsInRange(Vector v, int offset, diff --git a/jdk/src/share/classes/javax/swing/text/StyleContext.java b/jdk/src/share/classes/javax/swing/text/StyleContext.java index ca0eeea66d7..ac11b1f82f4 100644 --- a/jdk/src/share/classes/javax/swing/text/StyleContext.java +++ b/jdk/src/share/classes/javax/swing/text/StyleContext.java @@ -241,7 +241,7 @@ public class StyleContext implements Serializable, AbstractDocument.AttributeCon * * @param family the font family (such as "Monospaced") * @param style the style of the font (such as Font.PLAIN) - * @param size the point size >= 1 + * @param size the point size >= 1 * @return the new font */ public Font getFont(String family, int style, int size) { @@ -1387,7 +1387,7 @@ public class StyleContext implements Serializable, AbstractDocument.AttributeCon /** * Gets the number of attributes that are defined. * - * @return the number of attributes >= 0 + * @return the number of attributes >= 0 * @see AttributeSet#getAttributeCount */ public int getAttributeCount() { diff --git a/jdk/src/share/classes/javax/swing/text/StyledDocument.java b/jdk/src/share/classes/javax/swing/text/StyledDocument.java index 9c687189ca2..ad7c1c1eb2a 100644 --- a/jdk/src/share/classes/javax/swing/text/StyledDocument.java +++ b/jdk/src/share/classes/javax/swing/text/StyledDocument.java @@ -76,8 +76,8 @@ public interface StyledDocument extends Document { * giving an Attributes argument that has no attributes defined * and setting replace to true. * - * @param offset the start of the change >= 0 - * @param length the length of the change >= 0 + * @param offset the start of the change >= 0 + * @param length the length of the change >= 0 * @param s the non-null attributes to change to. Any attributes * defined will be applied to the text for the given range. * @param replace indicates whether or not the previous @@ -91,8 +91,8 @@ public interface StyledDocument extends Document { /** * Sets paragraph attributes. * - * @param offset the start of the change >= 0 - * @param length the length of the change >= 0 + * @param offset the start of the change >= 0 + * @param length the length of the change >= 0 * @param s the non-null attributes to change to. Any attributes * defined will be applied to the text for the given range. * @param replace indicates whether or not the previous @@ -111,7 +111,7 @@ public interface StyledDocument extends Document { * in turn may resolve through some hierarchy completely * independent of the element hierarchy in the document. * - * @param pos the starting position >= 0 + * @param pos the starting position >= 0 * @param s the style to set */ public void setLogicalStyle(int pos, Style s); @@ -119,7 +119,7 @@ public interface StyledDocument extends Document { /** * Gets a logical style for a given position in a paragraph. * - * @param p the position >= 0 + * @param p the position >= 0 * @return the style */ public Style getLogicalStyle(int p); @@ -128,7 +128,7 @@ public interface StyledDocument extends Document { * Gets the element that represents the paragraph that * encloses the given offset within the document. * - * @param pos the offset >= 0 + * @param pos the offset >= 0 * @return the element */ public Element getParagraphElement(int pos); @@ -137,7 +137,7 @@ public interface StyledDocument extends Document { * Gets the element that represents the character that * is at the given offset within the document. * - * @param pos the offset >= 0 + * @param pos the offset >= 0 * @return the element */ public Element getCharacterElement(int pos); diff --git a/jdk/src/share/classes/javax/swing/text/StyledEditorKit.java b/jdk/src/share/classes/javax/swing/text/StyledEditorKit.java index d11f75fdf6e..20832c6c8b8 100644 --- a/jdk/src/share/classes/javax/swing/text/StyledEditorKit.java +++ b/jdk/src/share/classes/javax/swing/text/StyledEditorKit.java @@ -689,7 +689,7 @@ public class StyledEditorKit extends DefaultEditorKit { * Creates a new AlignmentAction. * * @param nm the action name - * @param a the alignment >= 0 + * @param a the alignment >= 0 */ public AlignmentAction(String nm, int a) { super(nm); diff --git a/jdk/src/share/classes/javax/swing/text/TabExpander.java b/jdk/src/share/classes/javax/swing/text/TabExpander.java index a6ff2cfc6d3..fa3ec69222e 100644 --- a/jdk/src/share/classes/javax/swing/text/TabExpander.java +++ b/jdk/src/share/classes/javax/swing/text/TabExpander.java @@ -37,10 +37,10 @@ public interface TabExpander { * Returns the next tab stop position given a reference * position. Values are expressed in points. * - * @param x the position in points >= 0 + * @param x the position in points >= 0 * @param tabOffset the position within the text stream - * that the tab occurred at >= 0. - * @return the next tab stop >= 0 + * that the tab occurred at >= 0. + * @return the next tab stop >= 0 */ float nextTabStop(float x, int tabOffset); diff --git a/jdk/src/share/classes/javax/swing/text/TabableView.java b/jdk/src/share/classes/javax/swing/text/TabableView.java index fb409286d60..e28107ab4aa 100644 --- a/jdk/src/share/classes/javax/swing/text/TabableView.java +++ b/jdk/src/share/classes/javax/swing/text/TabableView.java @@ -46,9 +46,9 @@ public interface TabableView { * along the axis of tab expansion. * * @param x the position the view would be located - * at for the purpose of tab expansion >= 0. + * at for the purpose of tab expansion >= 0. * @param e how to expand the tabs when encountered. - * @return the desired span >= 0 + * @return the desired span >= 0 */ float getTabbedSpan(float x, TabExpander e); @@ -62,9 +62,9 @@ public interface TabableView { * an assumption that the range given does not * contain tabs. * - * @param p0 the starting location in the text document >= 0 - * @param p1 the ending location in the text document >= p0 - * @return the span >= 0 + * @param p0 the starting location in the text document >= 0 + * @param p1 the ending location in the text document >= p0 + * @return the span >= 0 */ float getPartialSpan(int p0, int p1); } diff --git a/jdk/src/share/classes/javax/swing/text/TableView.java b/jdk/src/share/classes/javax/swing/text/TableView.java index c579873cf02..159575302e7 100644 --- a/jdk/src/share/classes/javax/swing/text/TableView.java +++ b/jdk/src/share/classes/javax/swing/text/TableView.java @@ -542,7 +542,7 @@ public abstract class TableView extends BoxView { * view the children do not necessarily have a one to one mapping * with the child elements. * - * @param pos the search position >= 0 + * @param pos the search position >= 0 * @param a the allocation to the table on entry, and the * allocation of the view containing the position on exit * @return the view representing the given position, or @@ -755,7 +755,7 @@ public abstract class TableView extends BoxView { * view the children do not necessarily have a one to one mapping * with the child elements. * - * @param pos the search position >= 0 + * @param pos the search position >= 0 * @param a the allocation to the table on entry, and the * allocation of the view containing the position on exit * @return the view representing the given position, or @@ -833,8 +833,8 @@ public abstract class TableView extends BoxView { /** * Sets the grid location. * - * @param row the row >= 0 - * @param col the column >= 0 + * @param row the row >= 0 + * @param col the column >= 0 */ public void setGridLocation(int row, int col) { this.row = row; @@ -871,8 +871,8 @@ public abstract class TableView extends BoxView { /** * Sets the grid location. * - * @param row the row >= 0 - * @param col the column >= 0 + * @param row the row >= 0 + * @param col the column >= 0 */ public void setGridLocation(int row, int col); diff --git a/jdk/src/share/classes/javax/swing/text/Utilities.java b/jdk/src/share/classes/javax/swing/text/Utilities.java index a6cbfadb0d8..87db7911b89 100644 --- a/jdk/src/share/classes/javax/swing/text/Utilities.java +++ b/jdk/src/share/classes/javax/swing/text/Utilities.java @@ -71,12 +71,12 @@ public class Utilities { * where ints are used and 72dpi is assumed. * * @param s the source of the text - * @param x the X origin >= 0 - * @param y the Y origin >= 0 + * @param x the X origin >= 0 + * @param y the Y origin >= 0 * @param g the graphics context * @param e how to expand the tabs. If this value is null, * tabs will be expanded as a space character. - * @param startOffset starting offset of the text in the document >= 0 + * @param startOffset starting offset of the text in the document >= 0 * @return the X location at the end of the rendered text */ public static final int drawTabbedText(Segment s, int x, int y, Graphics g, @@ -92,12 +92,12 @@ public class Utilities { * * @param view View requesting rendering, may be null. * @param s the source of the text - * @param x the X origin >= 0 - * @param y the Y origin >= 0 + * @param x the X origin >= 0 + * @param y the Y origin >= 0 * @param g the graphics context * @param e how to expand the tabs. If this value is null, * tabs will be expanded as a space character. - * @param startOffset starting offset of the text in the document >= 0 + * @param startOffset starting offset of the text in the document >= 0 * @return the X location at the end of the rendered text */ static final int drawTabbedText(View view, @@ -197,10 +197,10 @@ public class Utilities { * * @param s the source of the text * @param metrics the font metrics to use for the calculation - * @param x the X origin >= 0 + * @param x the X origin >= 0 * @param e how to expand the tabs. If this value is null, * tabs will be expanded as a space character. - * @param startOffset starting offset of the text in the document >= 0 + * @param startOffset starting offset of the text in the document >= 0 * @return the width of the text */ public static final int getTabbedTextWidth(Segment s, FontMetrics metrics, int x, @@ -289,13 +289,13 @@ public class Utilities { * @param s the source of the text * @param metrics the font metrics to use for the calculation * @param x0 the starting view location representing the start - * of the given text >= 0. + * of the given text >= 0. * @param x the target view location to translate to an - * offset into the text >= 0. + * offset into the text >= 0. * @param e how to expand the tabs. If this value is null, * tabs will be expanded as a space character. - * @param startOffset starting offset of the text in the document >= 0 - * @return the offset into the text >= 0 + * @param startOffset starting offset of the text in the document >= 0 + * @return the offset into the text >= 0 */ public static final int getTabbedTextOffset(Segment s, FontMetrics metrics, int x0, int x, TabExpander e, @@ -488,8 +488,8 @@ public class Utilities { * a value of -1 will be returned. * * @param c the editor - * @param offs the offset in the document >= 0 - * @return the position >= 0 if the request can be computed, otherwise + * @param offs the offset in the document >= 0 + * @return the position >= 0 if the request can be computed, otherwise * a value of -1 will be returned. * @exception BadLocationException if the offset is out of range */ @@ -518,8 +518,8 @@ public class Utilities { * a value of -1 will be returned. * * @param c the editor - * @param offs the offset in the document >= 0 - * @return the position >= 0 if the request can be computed, otherwise + * @param offs the offset in the document >= 0 + * @return the position >= 0 if the request can be computed, otherwise * a value of -1 will be returned. * @exception BadLocationException if the offset is out of range */ @@ -549,9 +549,9 @@ public class Utilities { * a value of -1 will be returned. * * @param c the editor - * @param offs the offset in the document >= 0 - * @param x the X coordinate >= 0 - * @return the position >= 0 if the request can be computed, otherwise + * @param offs the offset in the document >= 0 + * @param x the X coordinate >= 0 + * @return the position >= 0 if the request can be computed, otherwise * a value of -1 will be returned. * @exception BadLocationException if the offset is out of range */ @@ -586,9 +586,9 @@ public class Utilities { * a value of -1 will be returned. * * @param c the editor - * @param offs the offset in the document >= 0 - * @param x the X coordinate >= 0 - * @return the position >= 0 if the request can be computed, otherwise + * @param offs the offset in the document >= 0 + * @param x the X coordinate >= 0 + * @return the position >= 0 if the request can be computed, otherwise * a value of -1 will be returned. * @exception BadLocationException if the offset is out of range */ @@ -622,8 +622,8 @@ public class Utilities { * Uses BreakIterator.getWordInstance() to actually get the words. * * @param c the editor - * @param offs the offset in the document >= 0 - * @return the location in the model of the word start >= 0 + * @param offs the offset in the document >= 0 + * @return the location in the model of the word start >= 0 * @exception BadLocationException if the offset is out of range */ public static final int getWordStart(JTextComponent c, int offs) throws BadLocationException { @@ -656,8 +656,8 @@ public class Utilities { * Uses BreakIterator.getWordInstance() to actually get the words. * * @param c the editor - * @param offs the offset in the document >= 0 - * @return the location in the model of the word end >= 0 + * @param offs the offset in the document >= 0 + * @return the location in the model of the word end >= 0 * @exception BadLocationException if the offset is out of range */ public static final int getWordEnd(JTextComponent c, int offs) throws BadLocationException { @@ -689,8 +689,8 @@ public class Utilities { * Uses BreakIterator.getWordInstance() to actually get the words. * * @param c the editor - * @param offs the offset in the document >= 0 - * @return the location in the model of the word start >= 0 + * @param offs the offset in the document >= 0 + * @return the location in the model of the word start >= 0 * @exception BadLocationException if the offset is out of range */ public static final int getNextWord(JTextComponent c, int offs) throws BadLocationException { @@ -767,8 +767,8 @@ public class Utilities { * Uses BreakIterator.getWordInstance() to actually get the words. * * @param c the editor - * @param offs the offset in the document >= 0 - * @return the location in the model of the word start >= 0 + * @param offs the offset in the document >= 0 + * @return the location in the model of the word start >= 0 * @exception BadLocationException if the offset is out of range */ public static final int getPreviousWord(JTextComponent c, int offs) throws BadLocationException { @@ -841,7 +841,7 @@ public class Utilities { * Determines the element to use for a paragraph/line. * * @param c the editor - * @param offs the starting offset in the document >= 0 + * @param offs the starting offset in the document >= 0 * @return the element */ public static final Element getParagraphElement(JTextComponent c, int offs) { @@ -972,7 +972,7 @@ public class Utilities { * must then override the flipEastAndWestAtEnds method. * * @param v View to query - * @param pos the position to convert >= 0 + * @param pos the position to convert >= 0 * @param a the allocated region to render into * @param direction the direction from the current position that can * be thought of as the arrow keys typically found on a keyboard; diff --git a/jdk/src/share/classes/javax/swing/text/View.java b/jdk/src/share/classes/javax/swing/text/View.java index be3a0e4336f..7eed01ef111 100644 --- a/jdk/src/share/classes/javax/swing/text/View.java +++ b/jdk/src/share/classes/javax/swing/text/View.java @@ -72,12 +72,12 @@ A view has the following responsibilities: alt="The above text describes this graphic.">

    The minimum set of methods for layout are:

      -
    • getMinimumSpan -
    • getPreferredSpan -
    • getMaximumSpan -
    • getAlignment -
    • preferenceChanged -
    • setSize +
    • {@link #getMinimumSpan(int) getMinimumSpan} +
    • {@link #getPreferredSpan(int) getPreferredSpan} +
    • {@link #getMaximumSpan(int) getMaximumSpan} +
    • {@link #getAlignment(int) getAlignment} +
    • {@link #preferenceChanged(javax.swing.text.View, boolean, boolean) preferenceChanged} +
    • {@link #setSize(float, float) setSize}

    The setSize method should be prepared to be called a number of times @@ -142,7 +142,7 @@ A view has the following responsibilities:

    The methods for rendering are:

      -
    • paint +
    • {@link #paint(java.awt.Graphics, java.awt.Shape) paint}

    @@ -153,12 +153,12 @@ A view has the following responsibilities: to perform translation to properly locate spatial representation of the model. The methods for doing this are:

      -
    • modelToView -
    • viewToModel -
    • getDocument -
    • getElement -
    • getStartOffset -
    • getEndOffset +
    • {@link #modelToView(int, javax.swing.text.Position.Bias, int, javax.swing.text.Position.Bias, java.awt.Shape) modelToView} +
    • {@link #viewToModel(float, float, java.awt.Shape, javax.swing.text.Position.Bias[]) viewToModel} +
    • {@link #getDocument() getDocument} +
    • {@link #getElement() getElement} +
    • {@link #getStartOffset() getStartOffset} +
    • {@link #getEndOffset() getEndOffset}

    The layout must be valid prior to attempting to make the translation. The translation is not valid, and must not be attempted while changes diff --git a/jdk/src/share/classes/javax/swing/text/WrappedPlainView.java b/jdk/src/share/classes/javax/swing/text/WrappedPlainView.java index 5ee6eaf163b..1ab45943548 100644 --- a/jdk/src/share/classes/javax/swing/text/WrappedPlainView.java +++ b/jdk/src/share/classes/javax/swing/text/WrappedPlainView.java @@ -93,11 +93,11 @@ public class WrappedPlainView extends BoxView implements TabExpander { * drawSelectedText so that the way selected and * unselected text are rendered can be customized. * - * @param p0 the starting document location to use >= 0 - * @param p1 the ending document location to use >= p1 + * @param p0 the starting document location to use >= 0 + * @param p1 the ending document location to use >= p1 * @param g the graphics context - * @param x the starting X position >= 0 - * @param y the starting Y position >= 0 + * @param x the starting X position >= 0 + * @param y the starting Y position >= 0 * @see #drawUnselectedText * @see #drawSelectedText */ @@ -165,11 +165,11 @@ public class WrappedPlainView extends BoxView implements TabExpander { * text. * * @param g the graphics context - * @param x the starting X coordinate >= 0 - * @param y the starting Y coordinate >= 0 - * @param p0 the beginning position in the model >= 0 - * @param p1 the ending position in the model >= p0 - * @return the X location of the end of the range >= 0 + * @param x the starting X coordinate >= 0 + * @param y the starting Y coordinate >= 0 + * @param p0 the beginning position in the model >= 0 + * @param p1 the ending position in the model >= p0 + * @return the X location of the end of the range >= 0 * @exception BadLocationException if the range is invalid */ protected int drawUnselectedText(Graphics g, int x, int y, @@ -190,10 +190,10 @@ public class WrappedPlainView extends BoxView implements TabExpander { * the selected background. * * @param g the graphics context - * @param x the starting X coordinate >= 0 - * @param y the starting Y coordinate >= 0 - * @param p0 the beginning position in the model >= 0 - * @param p1 the ending position in the model >= p0 + * @param x the starting X coordinate >= 0 + * @param y the starting Y coordinate >= 0 + * @param p0 the beginning position in the model >= 0 + * @param p1 the ending position in the model >= p0 * @return the location of the end of the range. * @exception BadLocationException if the range is invalid */ @@ -326,10 +326,10 @@ public class WrappedPlainView extends BoxView implements TabExpander { * This implementation does not support things like centering so it * ignores the tabOffset argument. * - * @param x the current position >= 0 + * @param x the current position >= 0 * @param tabOffset the position within the text stream - * that the tab occurred at >= 0. - * @return the tab stop, measured in points >= 0 + * that the tab occurred at >= 0. + * @return the tab stop, measured in points >= 0 */ public float nextTabStop(float x, int tabOffset) { if (tabSize == 0) @@ -374,8 +374,8 @@ public class WrappedPlainView extends BoxView implements TabExpander { * layout of the view along the given axis, if it * has any layout duties. * - * @param width the width >= 0 - * @param height the height >= 0 + * @param width the width >= 0 + * @param height the height >= 0 */ public void setSize(float width, float height) { updateMetrics(); diff --git a/jdk/src/share/classes/javax/swing/text/ZoneView.java b/jdk/src/share/classes/javax/swing/text/ZoneView.java index cb567e3c258..3b79f234c9a 100644 --- a/jdk/src/share/classes/javax/swing/text/ZoneView.java +++ b/jdk/src/share/classes/javax/swing/text/ZoneView.java @@ -130,7 +130,7 @@ public class ZoneView extends BoxView { * * @param mzl the desired maximum number of zones * to be actively loaded, must be greater than 0 - * @exception IllegalArgumentException if mzl is < 1 + * @exception IllegalArgumentException if mzl is < 1 */ public void setMaxZonesLoaded(int mzl) { if (mzl < 1) { @@ -198,11 +198,11 @@ public class ZoneView extends BoxView { * implementation for a zone by changing this method. * * @param p0 the start of the desired zone. This should - * be >= getStartOffset() and < getEndOffset(). This - * value should also be < p1. + * be >= getStartOffset() and < getEndOffset(). This + * value should also be < p1. * @param p1 the end of the desired zone. This should - * be > getStartOffset() and <= getEndOffset(). This - * value should also be > p0. + * be > getStartOffset() and <= getEndOffset(). This + * value should also be > p0. */ protected View createZone(int p0, int p1) { Document doc = getDocument(); @@ -242,7 +242,7 @@ public class ZoneView extends BoxView { * Returns the child view index representing the given position in * the model. * - * @param pos the position >= 0 + * @param pos the position >= 0 * @return index of the view representing the given position, or * -1 if no view represents that position */ diff --git a/jdk/src/share/classes/javax/swing/text/html/BlockView.java b/jdk/src/share/classes/javax/swing/text/html/BlockView.java index 6ba247a3a6a..949b11c7c68 100644 --- a/jdk/src/share/classes/javax/swing/text/html/BlockView.java +++ b/jdk/src/share/classes/javax/swing/text/html/BlockView.java @@ -352,7 +352,7 @@ public class BlockView extends BoxView { * * @param axis may be either View.X_AXIS * or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0; + * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view @@ -368,7 +368,7 @@ public class BlockView extends BoxView { * * @param axis may be either View.X_AXIS * or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0; + * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view @@ -384,7 +384,7 @@ public class BlockView extends BoxView { * * @param axis may be either View.X_AXIS * or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0; + * @return the span the view would like to be rendered into >= 0; * typically the view is told to render into the span * that is returned, although there is no guarantee; * the parent may choose to resize or break the view diff --git a/jdk/src/share/classes/javax/swing/text/html/CSS.java b/jdk/src/share/classes/javax/swing/text/html/CSS.java index f0f8cb2de11..22b3ad9315b 100644 --- a/jdk/src/share/classes/javax/swing/text/html/CSS.java +++ b/jdk/src/share/classes/javax/swing/text/html/CSS.java @@ -117,7 +117,7 @@ import javax.swing.text.*; * *

    Note: for the time being we do not fully support relative units, * unless noted, so that - * p { margin-top: 10% } will be treated as if no margin-top was specified. + * p { margin-top: 10% } will be treated as if no margin-top was specified. * * @author Timothy Prinzing * @author Scott Violet diff --git a/jdk/src/share/classes/javax/swing/text/html/FormView.java b/jdk/src/share/classes/javax/swing/text/html/FormView.java index 2d25516f339..84c0a34c016 100644 --- a/jdk/src/share/classes/javax/swing/text/html/FormView.java +++ b/jdk/src/share/classes/javax/swing/text/html/FormView.java @@ -380,7 +380,7 @@ public class FormView extends ComponentView implements ActionListener { * axis of interest. * * @param axis may be either View.X_AXIS or View.Y_AXIS - * @return the span the view would like to be rendered into >= 0. + * @return the span the view would like to be rendered into >= 0. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. diff --git a/jdk/src/share/classes/javax/swing/text/html/HTMLDocument.java b/jdk/src/share/classes/javax/swing/text/html/HTMLDocument.java index a1f99e9cae8..71f26093252 100644 --- a/jdk/src/share/classes/javax/swing/text/html/HTMLDocument.java +++ b/jdk/src/share/classes/javax/swing/text/html/HTMLDocument.java @@ -107,21 +107,21 @@ import static sun.swing.SwingUtilities2.IMPLIED_CR; *

    With the following HTML content:

    * *
    - * <html>
    - *   <head>
    - *     <title>An example HTMLDocument</title>
    - *     <style type="text/css">
    + * <html>
    + *   <head>
    + *     <title>An example HTMLDocument</title>
    + *     <style type="text/css">
      *       div { background-color: silver; }
      *       ul { color: red; }
    - *     </style>
    - *   </head>
    - *   <body>
    - *     <div id="BOX">
    - *       <p>Paragraph 1</p>
    - *       <p>Paragraph 2</p>
    - *     </div>
    - *   </body>
    - * </html>
    + *     </style>
    + *   </head>
    + *   <body>
    + *     <div id="BOX">
    + *       <p>Paragraph 1</p>
    + *       <p>Paragraph 2</p>
    + *     </div>
    + *   </body>
    + * </html>
      * 
    * *

    All the methods for modifying an HTML document require an {@link @@ -149,10 +149,10 @@ import static sun.swing.SwingUtilities2.IMPLIED_CR; * of any non-leaf element by using the methods * insertAfterStart and insertBeforeEnd. * For example, if e is the DIV element, - * d.insertAfterStart(e, "<ul><li>List - * Item</li></ul>") inserts the list before the first - * paragraph, and d.insertBeforeEnd(e, "<ul><li>List - * Item</li></ul>") inserts the list after the last + * d.insertAfterStart(e, "<ul><li>List + * Item</li></ul>") inserts the list before the first + * paragraph, and d.insertBeforeEnd(e, "<ul><li>List + * Item</li></ul>") inserts the list after the last * paragraph. The DIV block becomes the parent of the * newly inserted elements.

    * @@ -160,9 +160,9 @@ import static sun.swing.SwingUtilities2.IMPLIED_CR; * using the methods insertBeforeStart and * insertAfterEnd. For example, if e is the * DIV element, d.insertBeforeStart(e, - * "<ul><li>List Item</li></ul>") inserts the list + * "<ul><li>List Item</li></ul>")
    inserts the list * before the DIV element, and d.insertAfterEnd(e, - * "<ul><li>List Item</li></ul>") inserts the list + * "<ul><li>List Item</li></ul>") inserts the list * after the DIV element. The newly inserted elements * become siblings of the DIV element.

    * @@ -171,10 +171,10 @@ import static sun.swing.SwingUtilities2.IMPLIED_CR; *

    Elements and all their descendants can be replaced by using the * methods setInnerHTML and setOuterHTML. * For example, if e is the DIV element, - * d.setInnerHTML(e, "<ul><li>List - * Item</li></ul>") replaces all children paragraphs with - * the list, and d.setOuterHTML(e, "<ul><li>List - * Item</li></ul>") replaces the DIV element + * d.setInnerHTML(e, "<ul><li>List + * Item</li></ul>") replaces all children paragraphs with + * the list, and d.setOuterHTML(e, "<ul><li>List + * Item</li></ul>") replaces the DIV element * itself. In latter case the parent of the list is the * BODY element. * @@ -184,6 +184,7 @@ import static sun.swing.SwingUtilities2.IMPLIED_CR; * of various methods described above.

    * *

    - * + * * By default, {@code DragSourceContext} sets the cursor as appropriate * for the current state of the drag and drop operation. For example, if * the user has chosen {@linkplain DnDConstants#ACTION_MOVE the move action}, diff --git a/jdk/src/share/classes/java/awt/dnd/DragSourceDragEvent.java b/jdk/src/share/classes/java/awt/dnd/DragSourceDragEvent.java index 4ca92d86c07..315fa3c680d 100644 --- a/jdk/src/share/classes/java/awt/dnd/DragSourceDragEvent.java +++ b/jdk/src/share/classes/java/awt/dnd/DragSourceDragEvent.java @@ -47,9 +47,9 @@ import java.awt.event.InputEvent; * source and the drop action selected by the user. The user can select a drop * action by pressing modifier keys during the drag operation: *

    Audio Format Property KeysAudio Format Properties
    Property keyValue type @@ -971,25 +967,6 @@ developer install location
    --with-dxsdk=path - select location of the Windows Direct X SDK install -
    - The Microsoft DirectX 9.0 SDK - header files and libraries - from the Summer 2004 edition - are required for building OpenJDK. - This SDK can be downloaded from - - Microsoft DirectX 9.0 SDK (Summer 2004). - If the link above becomes obsolete, the SDK can be found from - the Microsoft Download Site - (search with "DirectX 9.0 SDK Update Summer 2004"). - Installation usually will set the environment variable - DXSDK_DIR to it's install location. -
    --with-freetype=path diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 373f03fa2b1..84c38a67dba 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -766,8 +766,6 @@ BUILD_LD BUILD_CXX BUILD_CC MSVCR_DLL -DXSDK_INCLUDE_PATH -DXSDK_LIB_PATH VS_PATH VS_LIB VS_INCLUDE @@ -1035,9 +1033,6 @@ with_override_nashorn with_override_jdk with_import_hotspot with_msvcr_dll -with_dxsdk -with_dxsdk_lib -with_dxsdk_include with_jtreg with_extra_cflags with_extra_cxxflags @@ -1792,11 +1787,6 @@ Optional Packages: source --with-msvcr-dll copy this msvcr100.dll into the built JDK (Windows only) [probed] - --with-dxsdk the DirectX SDK (Windows only) [probed] - --with-dxsdk-lib the DirectX SDK lib directory (Windows only) - [probed] - --with-dxsdk-include the DirectX SDK include directory (Windows only) - [probed] --with-jtreg Regression Test Harness [probed] --with-extra-cflags extra flags to be used when compiling jdk c-files --with-extra-cxxflags extra flags to be used when compiling jdk c++-files @@ -3807,10 +3797,6 @@ fi -# Setup the DXSDK paths - - - @@ -3820,7 +3806,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1378975246 +DATE_WHEN_GENERATED=1378980507 ############################################################################### # @@ -17599,441 +17585,6 @@ $as_echo "$as_me: The path of MSVCR_DLL, which resolves as \"$path\", is invalid fi - - -# Check whether --with-dxsdk was given. -if test "${with_dxsdk+set}" = set; then : - withval=$with_dxsdk; -fi - - -# Check whether --with-dxsdk-lib was given. -if test "${with_dxsdk_lib+set}" = set; then : - withval=$with_dxsdk_lib; -fi - - -# Check whether --with-dxsdk-include was given. -if test "${with_dxsdk_include+set}" = set; then : - withval=$with_dxsdk_include; -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK" >&5 -$as_echo_n "checking for DirectX SDK... " >&6; } - - if test "x$with_dxsdk" != x; then - dxsdk_path="$with_dxsdk" - elif test "x$DXSDK_DIR" != x; then - dxsdk_path="$DXSDK_DIR" - elif test -d "C:/DXSDK"; then - dxsdk_path="C:/DXSDK" - else - as_fn_error $? "Could not find the DirectX SDK" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dxsdk_path" >&5 -$as_echo "$dxsdk_path" >&6; } - - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - - # Input might be given as Windows format, start by converting to - # unix format. - path="$dxsdk_path" - new_path=`$CYGPATH -u "$path"` - - # Cygwin tries to hide some aspects of the Windows file system, such that binaries are - # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered - # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then - # "foo.exe" is OK but "foo" is an error. - # - # This test is therefore slightly more accurate than "test -f" to check for file precense. - # It is also a way to make sure we got the proper file name for the real test later on. - test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` - if test "x$test_shortpath" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Cannot locate the the path of dxsdk_path" "$LINENO" 5 - fi - - # Call helper function which possibly converts this using DOS-style short mode. - # If so, the updated path is stored in $new_path. - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - shortmode_path=`$CYGPATH -s -m -a "$input_path"` - path_after_shortmode=`$CYGPATH -u "$shortmode_path"` - if test "x$path_after_shortmode" != "x$input_to_shortpath"; then - # Going to short mode and back again did indeed matter. Since short mode is - # case insensitive, let's make it lowercase to improve readability. - shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Now convert it back to Unix-stile (cygpath) - input_path=`$CYGPATH -u "$shortmode_path"` - new_path="$input_path" - fi - fi - - test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/` - if test "x$test_cygdrive_prefix" = x; then - # As a simple fix, exclude /usr/bin since it's not a real path. - if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then - # The path is in a Cygwin special directory (e.g. /home). We need this converted to - # a path prefixed by /cygdrive for fixpath to work. - new_path="$CYGWIN_ROOT_PATH$input_path" - fi - fi - - - if test "x$path" != "x$new_path"; then - dxsdk_path="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting dxsdk_path to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting dxsdk_path to \"$new_path\"" >&6;} - fi - - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - - path="$dxsdk_path" - has_colon=`$ECHO $path | $GREP ^.:` - new_path="$path" - if test "x$has_colon" = x; then - # Not in mixed or Windows style, start by that. - new_path=`cmd //c echo $path` - fi - - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - fi - - - windows_path="$new_path" - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - unix_path=`$CYGPATH -u "$windows_path"` - new_path="$unix_path" - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` - new_path="$unix_path" - fi - - if test "x$path" != "x$new_path"; then - dxsdk_path="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting dxsdk_path to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting dxsdk_path to \"$new_path\"" >&6;} - fi - - # Save the first 10 bytes of this path to the storage, so fixpath can work. - all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}") - - else - # We're on a posix platform. Hooray! :) - path="$dxsdk_path" - has_space=`$ECHO "$path" | $GREP " "` - if test "x$has_space" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5 - fi - - # Use eval to expand a potential ~ - eval path="$path" - if test ! -f "$path" && test ! -d "$path"; then - as_fn_error $? "The path of dxsdk_path, which resolves as \"$path\", is not found." "$LINENO" 5 - fi - - dxsdk_path="`cd "$path"; $THEPWDCMD -L`" - fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK lib dir" >&5 -$as_echo_n "checking for DirectX SDK lib dir... " >&6; } - if test "x$with_dxsdk_lib" != x; then - DXSDK_LIB_PATH="$with_dxsdk_lib" - elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then - DXSDK_LIB_PATH="$dxsdk_path/Lib/x64" - else - DXSDK_LIB_PATH="$dxsdk_path/Lib" - fi - # dsound.lib is linked to in jsoundds - if test ! -f "$DXSDK_LIB_PATH/dsound.lib"; then - as_fn_error $? "Invalid DirectX SDK lib dir" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DXSDK_LIB_PATH" >&5 -$as_echo "$DXSDK_LIB_PATH" >&6; } - - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - - # Input might be given as Windows format, start by converting to - # unix format. - path="$DXSDK_LIB_PATH" - new_path=`$CYGPATH -u "$path"` - - # Cygwin tries to hide some aspects of the Windows file system, such that binaries are - # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered - # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then - # "foo.exe" is OK but "foo" is an error. - # - # This test is therefore slightly more accurate than "test -f" to check for file precense. - # It is also a way to make sure we got the proper file name for the real test later on. - test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` - if test "x$test_shortpath" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Cannot locate the the path of DXSDK_LIB_PATH" "$LINENO" 5 - fi - - # Call helper function which possibly converts this using DOS-style short mode. - # If so, the updated path is stored in $new_path. - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - shortmode_path=`$CYGPATH -s -m -a "$input_path"` - path_after_shortmode=`$CYGPATH -u "$shortmode_path"` - if test "x$path_after_shortmode" != "x$input_to_shortpath"; then - # Going to short mode and back again did indeed matter. Since short mode is - # case insensitive, let's make it lowercase to improve readability. - shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Now convert it back to Unix-stile (cygpath) - input_path=`$CYGPATH -u "$shortmode_path"` - new_path="$input_path" - fi - fi - - test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/` - if test "x$test_cygdrive_prefix" = x; then - # As a simple fix, exclude /usr/bin since it's not a real path. - if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then - # The path is in a Cygwin special directory (e.g. /home). We need this converted to - # a path prefixed by /cygdrive for fixpath to work. - new_path="$CYGWIN_ROOT_PATH$input_path" - fi - fi - - - if test "x$path" != "x$new_path"; then - DXSDK_LIB_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&6;} - fi - - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - - path="$DXSDK_LIB_PATH" - has_colon=`$ECHO $path | $GREP ^.:` - new_path="$path" - if test "x$has_colon" = x; then - # Not in mixed or Windows style, start by that. - new_path=`cmd //c echo $path` - fi - - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - fi - - - windows_path="$new_path" - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - unix_path=`$CYGPATH -u "$windows_path"` - new_path="$unix_path" - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` - new_path="$unix_path" - fi - - if test "x$path" != "x$new_path"; then - DXSDK_LIB_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&6;} - fi - - # Save the first 10 bytes of this path to the storage, so fixpath can work. - all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}") - - else - # We're on a posix platform. Hooray! :) - path="$DXSDK_LIB_PATH" - has_space=`$ECHO "$path" | $GREP " "` - if test "x$has_space" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5 - fi - - # Use eval to expand a potential ~ - eval path="$path" - if test ! -f "$path" && test ! -d "$path"; then - as_fn_error $? "The path of DXSDK_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 - fi - - DXSDK_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" - fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK include dir" >&5 -$as_echo_n "checking for DirectX SDK include dir... " >&6; } - if test "x$with_dxsdk_include" != x; then - DXSDK_INCLUDE_PATH="$with_dxsdk_include" - else - DXSDK_INCLUDE_PATH="$dxsdk_path/Include" - fi - # dsound.h is included in jsoundds - if test ! -f "$DXSDK_INCLUDE_PATH/dsound.h"; then - as_fn_error $? "Invalid DirectX SDK lib dir" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DXSDK_INCLUDE_PATH" >&5 -$as_echo "$DXSDK_INCLUDE_PATH" >&6; } - - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - - # Input might be given as Windows format, start by converting to - # unix format. - path="$DXSDK_INCLUDE_PATH" - new_path=`$CYGPATH -u "$path"` - - # Cygwin tries to hide some aspects of the Windows file system, such that binaries are - # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered - # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then - # "foo.exe" is OK but "foo" is an error. - # - # This test is therefore slightly more accurate than "test -f" to check for file precense. - # It is also a way to make sure we got the proper file name for the real test later on. - test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` - if test "x$test_shortpath" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Cannot locate the the path of DXSDK_INCLUDE_PATH" "$LINENO" 5 - fi - - # Call helper function which possibly converts this using DOS-style short mode. - # If so, the updated path is stored in $new_path. - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - shortmode_path=`$CYGPATH -s -m -a "$input_path"` - path_after_shortmode=`$CYGPATH -u "$shortmode_path"` - if test "x$path_after_shortmode" != "x$input_to_shortpath"; then - # Going to short mode and back again did indeed matter. Since short mode is - # case insensitive, let's make it lowercase to improve readability. - shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Now convert it back to Unix-stile (cygpath) - input_path=`$CYGPATH -u "$shortmode_path"` - new_path="$input_path" - fi - fi - - test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/` - if test "x$test_cygdrive_prefix" = x; then - # As a simple fix, exclude /usr/bin since it's not a real path. - if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then - # The path is in a Cygwin special directory (e.g. /home). We need this converted to - # a path prefixed by /cygdrive for fixpath to work. - new_path="$CYGWIN_ROOT_PATH$input_path" - fi - fi - - - if test "x$path" != "x$new_path"; then - DXSDK_INCLUDE_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&6;} - fi - - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - - path="$DXSDK_INCLUDE_PATH" - has_colon=`$ECHO $path | $GREP ^.:` - new_path="$path" - if test "x$has_colon" = x; then - # Not in mixed or Windows style, start by that. - new_path=`cmd //c echo $path` - fi - - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - fi - - - windows_path="$new_path" - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - unix_path=`$CYGPATH -u "$windows_path"` - new_path="$unix_path" - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` - new_path="$unix_path" - fi - - if test "x$path" != "x$new_path"; then - DXSDK_INCLUDE_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&6;} - fi - - # Save the first 10 bytes of this path to the storage, so fixpath can work. - all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}") - - else - # We're on a posix platform. Hooray! :) - path="$DXSDK_INCLUDE_PATH" - has_space=`$ECHO "$path" | $GREP " "` - if test "x$has_space" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5 - fi - - # Use eval to expand a potential ~ - eval path="$path" - if test ! -f "$path" && test ! -d "$path"; then - as_fn_error $? "The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 - fi - - DXSDK_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" - fi - - - - - LDFLAGS_JDK="$LDFLAGS_JDK -libpath:$DXSDK_LIB_PATH" - fi diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index d2ffb614bcc..d44b3c8c973 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -291,10 +291,6 @@ X_CFLAGS:=@X_CFLAGS@ X_LIBS:=@X_LIBS@ OPENWIN_HOME:=@OPENWIN_HOME@ -# DirectX SDK -DXSDK_LIB_PATH=@DXSDK_LIB_PATH@ -DXSDK_INCLUDE_PATH=@DXSDK_INCLUDE_PATH@ - # The lowest required version of macosx to enforce compatiblity for MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@ diff --git a/common/autoconf/toolchain.m4 b/common/autoconf/toolchain.m4 index efaecc18960..b60f3e3c583 100644 --- a/common/autoconf/toolchain.m4 +++ b/common/autoconf/toolchain.m4 @@ -176,7 +176,6 @@ AC_DEFUN([TOOLCHAIN_SETUP_PATHS], [ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV - TOOLCHAIN_SETUP_DXSDK fi AC_SUBST(MSVCR_DLL) diff --git a/common/autoconf/toolchain_windows.m4 b/common/autoconf/toolchain_windows.m4 index e5d4fff38f9..f97713f952f 100644 --- a/common/autoconf/toolchain_windows.m4 +++ b/common/autoconf/toolchain_windows.m4 @@ -277,61 +277,3 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV], AC_MSG_RESULT([$MSVCR_DLL]) BASIC_FIXUP_PATH(MSVCR_DLL) ]) - - -# Setup the DXSDK paths -AC_DEFUN([TOOLCHAIN_SETUP_DXSDK], -[ - AC_ARG_WITH(dxsdk, [AS_HELP_STRING([--with-dxsdk], - [the DirectX SDK (Windows only) @<:@probed@:>@])]) - AC_ARG_WITH(dxsdk-lib, [AS_HELP_STRING([--with-dxsdk-lib], - [the DirectX SDK lib directory (Windows only) @<:@probed@:>@])]) - AC_ARG_WITH(dxsdk-include, [AS_HELP_STRING([--with-dxsdk-include], - [the DirectX SDK include directory (Windows only) @<:@probed@:>@])]) - - AC_MSG_CHECKING([for DirectX SDK]) - - if test "x$with_dxsdk" != x; then - dxsdk_path="$with_dxsdk" - elif test "x$DXSDK_DIR" != x; then - dxsdk_path="$DXSDK_DIR" - elif test -d "C:/DXSDK"; then - dxsdk_path="C:/DXSDK" - else - AC_MSG_ERROR([Could not find the DirectX SDK]) - fi - AC_MSG_RESULT([$dxsdk_path]) - BASIC_FIXUP_PATH(dxsdk_path) - - AC_MSG_CHECKING([for DirectX SDK lib dir]) - if test "x$with_dxsdk_lib" != x; then - DXSDK_LIB_PATH="$with_dxsdk_lib" - elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then - DXSDK_LIB_PATH="$dxsdk_path/Lib/x64" - else - DXSDK_LIB_PATH="$dxsdk_path/Lib" - fi - # dsound.lib is linked to in jsoundds - if test ! -f "$DXSDK_LIB_PATH/dsound.lib"; then - AC_MSG_ERROR([Invalid DirectX SDK lib dir]) - fi - AC_MSG_RESULT([$DXSDK_LIB_PATH]) - BASIC_FIXUP_PATH(DXSDK_LIB_PATH) - - AC_MSG_CHECKING([for DirectX SDK include dir]) - if test "x$with_dxsdk_include" != x; then - DXSDK_INCLUDE_PATH="$with_dxsdk_include" - else - DXSDK_INCLUDE_PATH="$dxsdk_path/Include" - fi - # dsound.h is included in jsoundds - if test ! -f "$DXSDK_INCLUDE_PATH/dsound.h"; then - AC_MSG_ERROR([Invalid DirectX SDK lib dir]) - fi - AC_MSG_RESULT([$DXSDK_INCLUDE_PATH]) - BASIC_FIXUP_PATH(DXSDK_INCLUDE_PATH) - - AC_SUBST(DXSDK_LIB_PATH) - AC_SUBST(DXSDK_INCLUDE_PATH) - LDFLAGS_JDK="$LDFLAGS_JDK -libpath:$DXSDK_LIB_PATH" -]) From 10fa6ae01ea94054b1f87df1d3a73746f15c3aff Mon Sep 17 00:00:00 2001 From: Vadim Pakhnushev Date: Thu, 12 Sep 2013 12:12:32 +0200 Subject: [PATCH 0310/1294] 8008022: Upgrade Direct X SDK used to build JDK Reviewed-by: erikj, prr, ihse --- jdk/make/Makefile | 12 ------ jdk/make/common/Defs-windows.gmk | 2 - jdk/make/common/Sanity.gmk | 1 - jdk/make/common/shared/Defs-versions.gmk | 4 -- jdk/make/common/shared/Defs-windows.gmk | 47 +--------------------- jdk/make/common/shared/Sanity-Settings.gmk | 4 -- jdk/make/common/shared/Sanity.gmk | 47 ---------------------- jdk/make/javax/sound/jsoundds/Makefile | 3 +- jdk/make/jdk_generic_profile.sh | 1 - jdk/make/netbeans/awt2d/README | 5 +-- jdk/make/sun/awt/Makefile | 1 - jdk/make/sun/jawt/Makefile | 1 - jdk/makefiles/CompileNativeLibraries.gmk | 7 +--- 13 files changed, 5 insertions(+), 130 deletions(-) diff --git a/jdk/make/Makefile b/jdk/make/Makefile index c2db5a816a2..e82edd7271f 100644 --- a/jdk/make/Makefile +++ b/jdk/make/Makefile @@ -99,7 +99,6 @@ COMPILER_PATH.desc = Compiler install directory CACERTS_FILE.desc = Location of certificates file DEVTOOLS_PATH.desc = Directory containing zip and unzip CUPS_HEADERS_PATH.desc = Include directory location for CUPS header files -DXSDK_PATH.desc = Root directory of DirectX SDK # Make variables to print out (description and value) VARIABLE_PRINTVAL_LIST += \ @@ -128,17 +127,6 @@ VARIABLE_CHECKDIR_LIST += \ VARIABLE_CHECKFIL_LIST += \ CACERTS_FILE -# Some are windows specific -ifeq ($(PLATFORM), windows) - -VARIABLE_PRINTVAL_LIST += \ - DXSDK_PATH - -VARIABLE_CHECKDIR_LIST += \ - DXSDK_PATH - -endif - # For pattern rules below, so all are treated the same DO_PRINTVAL_LIST=$(VARIABLE_PRINTVAL_LIST:%=%.printval) DO_CHECKDIR_LIST=$(VARIABLE_CHECKDIR_LIST:%=%.checkdir) diff --git a/jdk/make/common/Defs-windows.gmk b/jdk/make/common/Defs-windows.gmk index c5c15b3d387..ef2c4aeab6f 100644 --- a/jdk/make/common/Defs-windows.gmk +++ b/jdk/make/common/Defs-windows.gmk @@ -78,8 +78,6 @@ ifeq ($(COMPILER_VERSION), VS2010) MS_RUNTIME_LIBRARIES = $(MSVCRNN_DLL) endif -EXTRA_LFLAGS += -LIBPATH:$(DXSDK_LIB_PATH) - # Full Debug Symbols has been enabled on Windows since JDK1.4.1. # The Full Debug Symbols (FDS) default for VARIANT == OPT builds is # enabled with debug info files ZIP'ed to save space. For VARIANT != diff --git a/jdk/make/common/Sanity.gmk b/jdk/make/common/Sanity.gmk index 25f5fa7bfe8..233abeacabb 100644 --- a/jdk/make/common/Sanity.gmk +++ b/jdk/make/common/Sanity.gmk @@ -65,7 +65,6 @@ sanity-base: pre-sanity \ sane-libCrun \ sane-unixccs_path \ sane-msdevtools_path \ - sane-dxsdk \ sane-compiler \ sane-cacerts \ sane-ant_version \ diff --git a/jdk/make/common/shared/Defs-versions.gmk b/jdk/make/common/shared/Defs-versions.gmk index 8a60563c122..a3a53c5c048 100644 --- a/jdk/make/common/shared/Defs-versions.gmk +++ b/jdk/make/common/shared/Defs-versions.gmk @@ -74,9 +74,6 @@ endif # REQUIRED_CYGWIN_VER # Windows only: If CYGWIN is used, the minimum CYGWIN version. # -# REQUIRED_DXSDK_VER -# Windows only: The version of DirectX SDK expected. -# # REQUIRED_FREETYPE_VERSION # If we are using freetype, the freetype version expected. # @@ -193,7 +190,6 @@ ifeq ($(PLATFORM), windows) REQUIRED_OS_VARIANT_VERSION = $(REQUIRED_OS_VERSION) REQUIRED_CYGWIN_VER = 4.0 REQUIRED_MKS_VER = 6.1 - REQUIRED_DXSDK_VER = 0x0900 ifeq ($(CC_VERSION),msvc) REQUIRED_COMPILER_NAME = Visual Studio 10 REQUIRED_COMPILER_VERSION = VS2010 diff --git a/jdk/make/common/shared/Defs-windows.gmk b/jdk/make/common/shared/Defs-windows.gmk index 40415547d71..d46d884cc05 100644 --- a/jdk/make/common/shared/Defs-windows.gmk +++ b/jdk/make/common/shared/Defs-windows.gmk @@ -79,7 +79,7 @@ override INCREMENTAL_BUILD = false # The ALT values should never really have spaces or use \. # Suspect these environment variables to have spaces and/or \ characters: # SYSTEMROOT, SystemRoot, WINDIR, windir, PROGRAMFILES, ProgramFiles, -# DXSDK_DIR, MSTOOLS, Mstools, MSSDK, MSSdk, VCnnCOMNTOOLS, +# MSTOOLS, Mstools, MSSDK, MSSdk, VCnnCOMNTOOLS, # MSVCDIR, MSVCDir. # So use $(subst \,/,) on them first adding quotes and placing them in # their own variable assigned with :=, then use FullPath. @@ -255,18 +255,6 @@ ifneq ($(word 1,$(_program_files)),$(_program_files)) _program_files:= endif -# DirectX SDK -ifdef ALT_DXSDK_DRIVE - _dx_sdk_dir =$(ALT_DXSDK_DRIVE):/DXSDK -else - ifdef DXSDK_DIR - xDXSDK_DIR :="$(subst \,/,$(DXSDK_DIR))" - else - xDXSDK_DIR :="$(_system_drive)/DXSDK" - endif - _dx_sdk_dir :=$(call FullPath,$(xDXSDK_DIR)) -endif - # Use of the Visual Studio compilers requires certain env variables be set: # PATH should include the path to cl.exe # INCLUDE should be defined @@ -489,39 +477,6 @@ ifeq ($(_NEEDS_MSVCRNN), true) MSVCRNN_DLL_PATH:=$(call AltCheckValue,MSVCRNN_DLL_PATH) endif -# DXSDK_PATH: path to Microsoft DirectX SDK Include and Lib -ifdef ALT_DXSDK_PATH - xALT_DXSDK_PATH :="$(subst \,/,$(ALT_DXSDK_PATH))" - DXSDK_PATH :=$(call FullPath,$(xALT_DXSDK_PATH)) -else - _DXSDK_PATH1 :=$(_dx_sdk_dir) - _DXSDK_PATH2 :=$(JDK_DEVTOOLS_DIR)/windows/dxsdk - DXSDK_PATH :=$(call DirExists,$(_DXSDK_PATH1),$(_DXSDK_PATH2),$(_dx_sdk_dir)) -endif -DXSDK_PATH :=$(call AltCheckSpaces,DXSDK_PATH) -DXSDK_PATH:=$(call AltCheckValue,DXSDK_PATH) - -# DXSDK_INCLUDE_PATH: path to Microsoft DirectX SDK Include -ifdef ALT_DXSDK_INCLUDE_PATH - xALT_DXSDK_INCLUDE_PATH :="$(subst \,/,$(ALT_DXSDK_INCLUDE_PATH))" - DXSDK_INCLUDE_PATH :=$(call FullPath,$(xALT_DXSDK_INCLUDE_PATH)) -else - DXSDK_INCLUDE_PATH =$(subst //,/,$(DXSDK_PATH)/Include) -endif - -# DXSDK_LIB_PATH: path to Microsoft DirectX SDK Lib -ifdef ALT_DXSDK_LIB_PATH - xALT_DXSDK_LIB_PATH :="$(subst \,/,$(ALT_DXSDK_LIB_PATH))" - DXSDK_LIB_PATH :=$(call FullPath,$(xALT_DXSDK_LIB_PATH)) -else - ifeq ($(ARCH_DATA_MODEL), 64) - # 64bit libs are located in "Lib/x64" subdir - DXSDK_LIB_PATH =$(subst //,/,$(DXSDK_PATH)/Lib/x64) - else - DXSDK_LIB_PATH =$(subst //,/,$(DXSDK_PATH)/Lib) - endif -endif - # DEPLOY_MSSDK: Microsoft SDK for this platform (for deploy) ifdef ALT_DEPLOY_MSSDK xALT_DEPLOY_MSSDK :="$(subst \,/,$(ALT_DEPLOY_MSSDK))" diff --git a/jdk/make/common/shared/Sanity-Settings.gmk b/jdk/make/common/shared/Sanity-Settings.gmk index ea32eeadcaa..2ceef21e13e 100644 --- a/jdk/make/common/shared/Sanity-Settings.gmk +++ b/jdk/make/common/shared/Sanity-Settings.gmk @@ -234,10 +234,6 @@ endif ALL_SETTINGS+=$(call addAltSetting,HOTSPOT_SERVER_PATH) ifeq ($(PLATFORM),windows) ALL_SETTINGS+=$(call addAltSetting,HOTSPOT_LIB_PATH) - ALL_SETTINGS+=$(call addRequiredSetting,DXSDK_VER) - ALL_SETTINGS+=$(call addAltSetting,DXSDK_PATH) - ALL_SETTINGS+=$(call addAltSetting,DXSDK_INCLUDE_PATH) - ALL_SETTINGS+=$(call addAltSetting,DXSDK_LIB_PATH) ALL_SETTINGS+=$(call addAltSetting,WINDOWSSDKDIR) ALL_SETTINGS+=$(call addRequiredSetting,RC) ALL_SETTINGS+=$(call addRequiredSetting,REBASE) diff --git a/jdk/make/common/shared/Sanity.gmk b/jdk/make/common/shared/Sanity.gmk index c4a96d73c5f..a9f4692064a 100644 --- a/jdk/make/common/shared/Sanity.gmk +++ b/jdk/make/common/shared/Sanity.gmk @@ -143,8 +143,6 @@ ifeq ($(PLATFORM), windows) _CYGWIN_VER := $(SYSTEM_UNAME) CYGWIN_VER :=$(call GetVersion,$(_CYGWIN_VER)) endif - DXSDK_VER := $(shell $(EGREP) DIRECT3D_VERSION $(DXSDK_INCLUDE_PATH)/d3d9.h 2>&1 | \ - $(EGREP) "\#define" | $(NAWK) '{print $$3}') endif # Get the version numbers of what we are using @@ -1300,51 +1298,6 @@ sane-unzip_version: "" >> $(WARNING_FILE) ; \ fi -###################################################### -# Check for windows DirectX sdk directory -###################################################### -sane-dxsdk: -ifeq ($(PLATFORM), windows) - @if [ ! -r $(DXSDK_INCLUDE_PATH)/d3d9.h ]; then \ - $(ECHO) "ERROR: You do not have access to a valid DirectX SDK Include dir.\n" \ - " The value of DXSDK_INCLUDE_PATH must point a valid DX SDK dir.\n" \ - " Please check your access to \n" \ - " $(DXSDK_INCLUDE_PATH) \n" \ - " and/or check your value of ALT_DXSDK_PATH or ALT_DXSDK_INCLUDE_PATH.\n" \ - " Microsoft DirectX 9 SDK (Summer 2004 Update or newer) can be downloaded from the following location:\n" \ - " http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp\n" \ - " Or http://www.microsoft.com/directx\n" \ - "" >> $(ERROR_FILE) ; \ - else \ - if [ ! "$(DXSDK_VER)" = "$(REQUIRED_DXSDK_VER)" ]; then \ - $(ECHO) "ERROR: The DirectX SDK must be version $(REQUIRED_DXSDK_VER).\n" \ - " $(YOU_ARE_USING) DirectX SDK version: $(DXSDK_VER)\n" \ - " The DirectX SDK was obtained from the following location: \n" \ - " $(DXSDK_PATH) \n" \ - " Please change your DirectX SDK. \n" \ - " Microsoft DirectX 9 SDK (Summer 2004 Update or newer) can be downloaded from the following location:\n" \ - " http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp\n" \ - " Or http://www.microsoft.com/directx\n" \ - "" >> $(ERROR_FILE) ; \ - else \ - if [ -r $(DXSDK_INCLUDE_PATH)/basetsd.h ]; then \ - if [ `$(EGREP) -c __int3264 $(DXSDK_INCLUDE_PATH)/basetsd.h` -ne 0 ]; then \ - $(ECHO) "WARNING: The DirectX SDK Include directory contains a newer basetsd.h,\n" \ - " which may indicate that you're using an incorrect version of DirectX SDK.\n" \ - " This may result in a build failure.\n" \ - " The DirectX SDK Include dir was obtained from the following location:\n" \ - " $(DXSDK_INCLUDE_PATH) \n" \ - " Please change your DirectX SDK to version 9 (Summer 2004 Update or newer).\n" \ - " Microsoft DirectX 9 SDK can be downloaded from the following location:\n" \ - " http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp\n" \ - " Or http://www.microsoft.com/directx\n" \ - "" >> $(WARNING_FILE) ; \ - fi \ - fi \ - fi \ - fi -endif - ###################################################### # Check the linker version(s) ###################################################### diff --git a/jdk/make/javax/sound/jsoundds/Makefile b/jdk/make/javax/sound/jsoundds/Makefile index f476b39811a..a747d699a0a 100644 --- a/jdk/make/javax/sound/jsoundds/Makefile +++ b/jdk/make/javax/sound/jsoundds/Makefile @@ -55,8 +55,7 @@ FILES_export = \ LDLIBS += dsound.lib winmm.lib user32.lib ole32.lib CPPFLAGS += \ -DUSE_DAUDIO=TRUE \ - -I$(SHARE_SRC)/native/com/sun/media/sound \ - -I$(DXSDK_INCLUDE_PATH) + -I$(SHARE_SRC)/native/com/sun/media/sound # # Add to the ambient VPATH. diff --git a/jdk/make/jdk_generic_profile.sh b/jdk/make/jdk_generic_profile.sh index 28705393a33..1103a56aa52 100644 --- a/jdk/make/jdk_generic_profile.sh +++ b/jdk/make/jdk_generic_profile.sh @@ -80,7 +80,6 @@ # ALT_BOOTDIR # Windows Only: # ALT_UNIXCOMMAND_PATH -# ALT_DXSDK_PATH # ALT_MSVCRNN_DLL_PATH # ############################################################################# diff --git a/jdk/make/netbeans/awt2d/README b/jdk/make/netbeans/awt2d/README index 040c9e76919..4df566dd157 100644 --- a/jdk/make/netbeans/awt2d/README +++ b/jdk/make/netbeans/awt2d/README @@ -39,7 +39,6 @@ Here are the steps: (on Windows): #>env | grep ALT ALT_JDK_IMPORT_PATH=c:/devtools/java/jdk1.7.0 - ALT_DXSDK_PATH=c:/devtools/DirectX/DXSDK_Dec06 ALT_BOOTDIR=c:/DevTools/java/jdk1.6.0 If your build is a FASTDEBUG build, don't forget @@ -50,7 +49,6 @@ Here are the steps: accordingly: make.options=\ ALT_JDK_IMPORT_PATH=c:/devtools/java/jdk1.7.0 \ - ALT_DXSDK_PATH=c:/devtools/DirectX/DXSDK_Dec06 \ ALT_BOOTDIR=c:/DevTools/java/jdk1.6.0 \ FASTDEBUG=true make=c:/devtools/cygwin/bin/make @@ -175,7 +173,6 @@ Notes on using CND (C/C++ pack) with this project and NetBeans. ../../build/windows-i586/tmp/sun/sun.awt/splashscreen/CClassHeaders; ../../build/windows-i586/tmp/sun/sun.font/fontmanager/CClassHeaders; ../../build/windows-i586/tmp/sun/sun.font/t2k/CClassHeaders; - C:/DevTools/DirectX/DXSDK_Dec06/Include; C:/devtools/VS2003/SDK/v1.1/include; C:/devtools/VS2003/VC7/ATLMFC/INCLUDE; C:/devtools/VS2003/VC7/INCLUDE; @@ -188,7 +185,7 @@ Notes on using CND (C/C++ pack) with this project and NetBeans. Note that most paths are relative to the native project directory - this helps if you decide to relocate the workspace later. The ones that aren't relative are paths to external include directories, like those - of the Platform SDK, DirectX SDK. + of the Platform SDK. On Unix platforms these may be directories like /usr/include. The parser must know some defines to correctly parse the source files, diff --git a/jdk/make/sun/awt/Makefile b/jdk/make/sun/awt/Makefile index dc4c250cf74..8b7612e416a 100644 --- a/jdk/make/sun/awt/Makefile +++ b/jdk/make/sun/awt/Makefile @@ -564,7 +564,6 @@ OTHER_INCLUDES += -I$(CLASSHDRDIR)/../../java/jvm \ -I$(OBJDIR) \ -I$(SHARE_SRC)/native/common \ -I$(WINAWT_native) \ - -I$(DXSDK_INCLUDE_PATH) \ -I$(SHARE_SRC)/native/sun/awt/image/cvutils \ -I$(SHARE_SRC)/native/sun/awt/image \ -I$(SHARE_SRC)/native/sun/java2d/loops \ diff --git a/jdk/make/sun/jawt/Makefile b/jdk/make/sun/jawt/Makefile index 718fb33c499..0520fc17bf1 100644 --- a/jdk/make/sun/jawt/Makefile +++ b/jdk/make/sun/jawt/Makefile @@ -69,7 +69,6 @@ OTHER_CXXFLAGS += $(GX_OPTION) -DUNICODE -D_UNICODE # Other extra flags needed for compiling. # CPPFLAGS += -I$(SHARE_SRC)/native/common \ - -I$(DXSDK_INCLUDE_PATH) \ -I$(PLATFORM_SRC)/native/sun/windows \ -I$(CLASSHDRDIR)/../../awt/CClassHeaders \ -I$(SHARE_SRC)/native/sun/awt/debug \ diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 656ee3c4841..79204e0a3e0 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.gmk @@ -472,7 +472,6 @@ ifeq ($(OPENJDK_TARGET_OS),windows) $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/d3d - LIBAWT_CFLAGS+=-I$(DXSDK_INCLUDE_PATH) else LIBAWT_DIRS+=\ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/x11 @@ -1482,8 +1481,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows) -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \ - -I$(DXSDK_INCLUDE_PATH), \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows, \ LDFLAGS:=$(LDFLAGS_JDKLIB) $(KERNEL32_LIB) $(LDFLAGS_CXX_JDK) \ advapi32.lib $(WIN_AWT_LIB),\ LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX),\ @@ -2961,8 +2959,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDDS,\ OPTIMIZATION:=LOW, \ CFLAGS:=$(CFLAGS_JDKLIB) \ $(LIBJSOUND_CFLAGS) \ - -DUSE_DAUDIO=TRUE \ - -I$(DXSDK_INCLUDE_PATH), \ + -DUSE_DAUDIO=TRUE, \ LDFLAGS:=$(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ $(call SET_SHARED_LIBRARY_ORIGIN),\ LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX) dsound.lib winmm.lib user32.lib ole32.lib,\ From 9c2e380d22104332becfb94daf13ee500b87425c Mon Sep 17 00:00:00 2001 From: Oleg Pekhovskiy Date: Thu, 12 Sep 2013 14:56:20 +0400 Subject: [PATCH 0311/1294] 8003965: Toolkit.beep() documentation is ambiguous Reviewed-by: anthony --- jdk/src/share/classes/java/awt/Toolkit.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java index 92bedb7580b..84f3206d6d3 100644 --- a/jdk/src/share/classes/java/awt/Toolkit.java +++ b/jdk/src/share/classes/java/awt/Toolkit.java @@ -1239,7 +1239,8 @@ public abstract class Toolkit { } /** - * Emits an audio beep. + * Emits an audio beep depending on native system settings and hardware + * capabilities. * @since JDK1.1 */ public abstract void beep(); From fcb6d58798f5f6f814a85b71f4ca7d20283bd46e Mon Sep 17 00:00:00 2001 From: Oleg Pekhovskiy Date: Thu, 12 Sep 2013 15:50:25 +0400 Subject: [PATCH 0312/1294] 7064312: Cleanup: avoid using unsafe string function Reviewed-by: serb, pchelko --- .../windows/native/sun/windows/awt_FileDialog.cpp | 6 +++--- jdk/src/windows/native/sun/windows/awt_Font.cpp | 13 +------------ .../windows/native/sun/windows/awt_PrintControl.cpp | 8 ++++---- jdk/src/windows/native/sun/windows/awt_Toolkit.cpp | 2 +- jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp | 8 ++++---- jdk/src/windows/native/sun/windows/awt_ole.cpp | 2 +- 6 files changed, 14 insertions(+), 25 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp b/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp index 276f3647e68..3fd993cc646 100644 --- a/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp +++ b/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,7 +73,7 @@ AwtFileDialog::Initialize(JNIEnv *env, jstring filterDescription) int length = env->GetStringLength(filterDescription); DASSERT(length + 1 < MAX_FILTER_STRING); LPCTSTR tmp = JNU_GetStringPlatformChars(env, filterDescription, NULL); - _tcscpy(s_fileFilterString, tmp); + _tcscpy_s(s_fileFilterString, MAX_FILTER_STRING, tmp); JNU_ReleaseStringPlatformChars(env, filterDescription, tmp); //AdditionalString should be terminated by two NULL characters (Windows @@ -353,7 +353,7 @@ AwtFileDialog::Show(void *p) if (!result) { dlgerr = ::CommDlgExtendedError(); if (dlgerr == FNERR_INVALIDFILENAME) { - _tcscpy(fileBuffer, TEXT("")); + _tcscpy_s(fileBuffer, bufferLimit, TEXT("")); if (mode == java_awt_FileDialog_LOAD) { result = AwtFileDialog::GetOpenFileName(&ofn); } else { diff --git a/jdk/src/windows/native/sun/windows/awt_Font.cpp b/jdk/src/windows/native/sun/windows/awt_Font.cpp index d0d31ff0d07..df3fbcbbb12 100644 --- a/jdk/src/windows/native/sun/windows/awt_Font.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Font.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -366,17 +366,6 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale) return awtFont; } -int CALLBACK FindFamilyName (ENUMLOGFONTEX *lpelfe, - NEWTEXTMETRICEX *lpntme, int FontType, LPARAM lParam) -{ - if(_tcsstr((LPTSTR)lParam, lpelfe->elfLogFont.lfFaceName)) { - _tcscpy((LPTSTR)lParam, lpelfe->elfLogFont.lfFaceName); - return 0; - } else { - return 1; - } -} - static void strip_tail(wchar_t* text, wchar_t* tail) { // strips tail and any possible whitespace before it from the end of text if (wcslen(text)<=wcslen(tail)) { return; diff --git a/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp b/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp index 71a08d3df33..78272a6c521 100644 --- a/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp +++ b/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -422,17 +422,17 @@ BOOL AwtPrintControl::CreateDevModeAndDevNames(PRINTDLG *ppd, devnames->wOutputOffset = static_cast(sizeof(DEVNAMES)/sizeof(TCHAR) + lenDriverName + lenPrinterName); if (info2->pDriverName != NULL) { - _tcscpy(lpcDevnames + devnames->wDriverOffset, info2->pDriverName); + _tcscpy_s(lpcDevnames + devnames->wDriverOffset, devnameSize - devnames->wDriverOffset, info2->pDriverName); } else { *(lpcDevnames + devnames->wDriverOffset) = _T('\0'); } if (pPrinterName != NULL) { - _tcscpy(lpcDevnames + devnames->wDeviceOffset, pPrinterName); + _tcscpy_s(lpcDevnames + devnames->wDeviceOffset, devnameSize - devnames->wDeviceOffset, pPrinterName); } else { *(lpcDevnames + devnames->wDeviceOffset) = _T('\0'); } if (info2->pPortName != NULL) { - _tcscpy(lpcDevnames + devnames->wOutputOffset, info2->pPortName); + _tcscpy_s(lpcDevnames + devnames->wOutputOffset, devnameSize - devnames->wOutputOffset, info2->pPortName); } else { *(lpcDevnames + devnames->wOutputOffset) = _T('\0'); } diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp index 8a3ed22c17d..cdb5247d618 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -228,7 +228,7 @@ BOOL AwtToolkit::activateKeyboardLayout(HKL hkl) { // create input locale string, e.g., "00000409", from hkl. TCHAR inputLocale[9]; TCHAR buf[9]; - _tcscpy(inputLocale, TEXT("00000000")); + _tcscpy_s(inputLocale, 9, TEXT("00000000")); // 64-bit: ::LoadKeyboardLayout() is such a weird API - a string of // the hex value you want?! Here we're converting our HKL value to diff --git a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp index 6cd2ce49954..c26769bf5f2 100644 --- a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp +++ b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -711,7 +711,7 @@ void AwtTrayIcon::SetToolTip(LPCTSTR tooltip) _tcsncpy(m_nid.szTip, tooltip, TRAY_ICON_TOOLTIP_MAX_SIZE); m_nid.szTip[TRAY_ICON_TOOLTIP_MAX_SIZE - 1] = '\0'; } else { - _tcscpy(m_nid.szTip, tooltip); + _tcscpy_s(m_nid.szTip, TRAY_ICON_TOOLTIP_MAX_SIZE, tooltip); } SendTrayMessage(NIM_MODIFY); @@ -817,7 +817,7 @@ void AwtTrayIcon::DisplayMessage(LPCTSTR caption, LPCTSTR text, LPCTSTR msgType) m_nid.szInfoTitle[TRAY_ICON_BALLOON_TITLE_MAX_SIZE - 1] = '\0'; } else { - _tcscpy(m_nid.szInfoTitle, caption); + _tcscpy_s(m_nid.szInfoTitle, TRAY_ICON_BALLOON_TITLE_MAX_SIZE, caption); } if (text[0] == '\0') { @@ -830,7 +830,7 @@ void AwtTrayIcon::DisplayMessage(LPCTSTR caption, LPCTSTR text, LPCTSTR msgType) m_nid.szInfo[TRAY_ICON_BALLOON_INFO_MAX_SIZE - 1] = '\0'; } else { - _tcscpy(m_nid.szInfo, text); + _tcscpy_s(m_nid.szInfo, TRAY_ICON_BALLOON_INFO_MAX_SIZE, text); } SendTrayMessage(NIM_MODIFY); diff --git a/jdk/src/windows/native/sun/windows/awt_ole.cpp b/jdk/src/windows/native/sun/windows/awt_ole.cpp index 0643ad8afb9..68912e5545e 100644 --- a/jdk/src/windows/native/sun/windows/awt_ole.cpp +++ b/jdk/src/windows/native/sun/windows/awt_ole.cpp @@ -70,7 +70,7 @@ namespace SUN_DBG_NS{ bErrorReport?_T("Error:"):_T(""), szBuffer) < 0) { - _tcscpy(szBuffer1 + DTRACE_BUF_LEN - 5, _T("...")); //reserver for \n + _tcscpy_s(szBuffer1 + DTRACE_BUF_LEN - 5, 5, _T("...")); //reserver for \n } memcpy(szBuffer1, szTime, iTimeLen*sizeof(TCHAR)); _tcscat(szBuffer1, _T("\n")); From dc7c7c5e1361ab08d3c251f7fcaadf1aca4eff6c Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Thu, 12 Sep 2013 15:53:49 +0400 Subject: [PATCH 0313/1294] 8022617: Openjdk hotspot build is broken on BSD platforms using gcc Enforce of preprocessing of all assembly sources by assembler-with-cpp Reviewed-by: dholmes, erikj --- hotspot/make/bsd/makefiles/gcc.make | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make index b98485f901d..0277bb66aa3 100644 --- a/hotspot/make/bsd/makefiles/gcc.make +++ b/hotspot/make/bsd/makefiles/gcc.make @@ -80,7 +80,7 @@ ifeq ($(SPEC),) HOSTCC = $(CC) endif - AS = $(CC) -c -x assembler-with-cpp + AS = $(CC) -c endif @@ -347,6 +347,13 @@ ifeq ($(OS_VENDOR), Darwin) LDFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN) endif + +#------------------------------------------------------------------------ +# Assembler flags + +# Enforce prerpocessing of .s files +ASFLAGS += -x assembler-with-cpp + #------------------------------------------------------------------------ # Linker flags From a556e37ff2bbae5198dbbe9077c98536074f48cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Thu, 12 Sep 2013 14:02:15 +0200 Subject: [PATCH 0314/1294] 8024476: Octane regression on Richards Reviewed-by: sundar, jlaskey --- .../jdk/nashorn/internal/runtime/JSType.java | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java index 073c237c69b..6098eb27728 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java @@ -29,7 +29,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import java.lang.invoke.MethodHandles; -import java.util.Locale; import jdk.internal.dynalink.beans.StaticClass; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.parser.Lexer; @@ -40,25 +39,28 @@ import jdk.nashorn.internal.runtime.linker.Bootstrap; */ public enum JSType { /** The undefined type */ - UNDEFINED, + UNDEFINED("undefined"), /** The null type */ - NULL, + NULL("object"), /** The boolean type */ - BOOLEAN, + BOOLEAN("boolean"), /** The number type */ - NUMBER, + NUMBER("number"), /** The string type */ - STRING, + STRING("string"), /** The object type */ - OBJECT, + OBJECT("object"), /** The function type */ - FUNCTION; + FUNCTION("function"); + + /** The type name as returned by ECMAScript "typeof" operator*/ + private final String typeName; /** Max value for an uint32 in JavaScript */ public static final long MAX_UINT = 0xFFFF_FFFFL; @@ -109,14 +111,22 @@ public enum JSType { private static final double INT32_LIMIT = 4294967296.0; + /** + * Constructor + * + * @param typeName the type name + */ + private JSType(final String typeName) { + this.typeName = typeName; + } + /** * The external type name as returned by ECMAScript "typeof" operator * * @return type name for this type */ public final String typeName() { - // For NULL, "object" has to be returned! - return ((this == NULL) ? OBJECT : this).name().toLowerCase(Locale.ENGLISH); + return this.typeName; } /** @@ -127,31 +137,32 @@ public enum JSType { * @return the JSType for the object */ public static JSType of(final Object obj) { - if (obj == ScriptRuntime.UNDEFINED) { - return JSType.UNDEFINED; - } - + // Order of these statements is tuned for performance (see JDK-8024476) if (obj == null) { return JSType.NULL; } + if (obj instanceof ScriptObject) { + return (obj instanceof ScriptFunction) ? JSType.FUNCTION : JSType.OBJECT; + } + if (obj instanceof Boolean) { return JSType.BOOLEAN; } - if (obj instanceof Number) { - return JSType.NUMBER; - } - if (obj instanceof String || obj instanceof ConsString) { return JSType.STRING; } - if (Bootstrap.isCallable(obj)) { - return JSType.FUNCTION; + if (obj instanceof Number) { + return JSType.NUMBER; } - return JSType.OBJECT; + if (obj == ScriptRuntime.UNDEFINED) { + return JSType.UNDEFINED; + } + + return Bootstrap.isCallable(obj) ? JSType.FUNCTION : JSType.OBJECT; } /** From d8c5dcc1fc9b74a37e2e01f2782caae6d0e551c5 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Thu, 12 Sep 2013 18:21:06 +0400 Subject: [PATCH 0315/1294] 7124537: [macosx] Menu shortcuts for all menu items should be disabled if a menu itself is disabled Reviewed-by: anthony, leonidr --- .../macosx/classes/sun/lwawt/macosx/CMenu.java | 16 ++++++++++++++++ .../classes/sun/lwawt/macosx/CMenuItem.java | 17 +++++++++++++++-- .../classes/sun/lwawt/macosx/LWCToolkit.java | 6 +++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CMenu.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CMenu.java index 56a7061325e..cad1b36aa9c 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CMenu.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CMenu.java @@ -26,9 +26,11 @@ package sun.lwawt.macosx; import java.awt.*; +import java.awt.peer.MenuItemPeer; import java.awt.peer.MenuPeer; public class CMenu extends CMenuItem implements MenuPeer { + public CMenu(Menu target) { super(target); } @@ -40,6 +42,20 @@ public class CMenu extends CMenuItem implements MenuPeer { setEnabled(target.isEnabled()); } + @Override + public final void setEnabled(final boolean b) { + super.setEnabled(b); + final Menu target = (Menu) getTarget(); + final int count = target.getItemCount(); + for (int i = 0; i < count; ++i) { + MenuItem item = target.getItem(i); + MenuItemPeer p = (MenuItemPeer) LWCToolkit.targetToPeer(item); + if (p != null) { + p.setEnabled(b && item.isEnabled()); + } + } + } + @Override protected long createModel() { CMenuComponent parent = (CMenuComponent) diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java index ac3bea392a1..b1492bd0a43 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java @@ -28,17 +28,20 @@ package sun.lwawt.macosx; import sun.awt.SunToolkit; import sun.lwawt.LWToolkit; +import java.awt.MenuContainer; import java.awt.MenuItem; import java.awt.MenuShortcut; import java.awt.event.*; import java.awt.peer.MenuItemPeer; +import java.util.concurrent.atomic.AtomicBoolean; public class CMenuItem extends CMenuComponent implements MenuItemPeer { + private final AtomicBoolean enabled = new AtomicBoolean(true); + public CMenuItem(MenuItem target) { super(target); initialize(target); - } // This way we avoiding invocation of the setters twice @@ -124,9 +127,19 @@ public class CMenuItem extends CMenuComponent implements MenuItemPeer { setEnabled(false); } + public final boolean isEnabled() { + return enabled.get(); + } + @Override public void setEnabled(boolean b) { - nativeSetEnabled(getModel(), b); + final Object parent = LWToolkit.targetToPeer(getTarget().getParent()); + if (parent instanceof CMenuItem) { + b &= ((CMenuItem) parent).isEnabled(); + } + if (enabled.compareAndSet(!b, b)) { + nativeSetEnabled(getModel(), b); + } } private native long nativeCreate(long parentMenu, boolean isSeparator); diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index 943dbe2fe47..e028df560f6 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -207,9 +207,9 @@ public final class LWCToolkit extends LWToolkit { @Override public MenuBarPeer createMenuBar(MenuBar target) { - MenuBarPeer peer = new CMenuBar(target); - targetCreatedPeer(target, peer); - return peer; + MenuBarPeer peer = new CMenuBar(target); + targetCreatedPeer(target, peer); + return peer; } @Override From 1ef8009ccfd57220bf6eedcdc2d129a414bf9256 Mon Sep 17 00:00:00 2001 From: Dmitry Markov Date: Thu, 12 Sep 2013 18:44:14 +0400 Subject: [PATCH 0316/1294] 8024395: Improve fix for line break calculations Reviewed-by: alexp, alexsch --- .../classes/javax/swing/text/FlowView.java | 18 ++- .../share/classes/javax/swing/text/View.java | 78 ++++++---- .../swing/text/View/8014863/bug8014863.java | 140 ++++++++++-------- 3 files changed, 141 insertions(+), 95 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/text/FlowView.java b/jdk/src/share/classes/javax/swing/text/FlowView.java index e04b2fe91bf..8cd647ce961 100644 --- a/jdk/src/share/classes/javax/swing/text/FlowView.java +++ b/jdk/src/share/classes/javax/swing/text/FlowView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -796,6 +796,22 @@ public abstract class FlowView extends BoxView { v.setParent(parent); } + /** {@inheritDoc} */ + @Override + protected void forwardUpdate(DocumentEvent.ElementChange ec, + DocumentEvent e, Shape a, ViewFactory f) { + calculateUpdateIndexes(e); + // Send update event to all views followed by the changed place. + lastUpdateIndex = Math.max((getViewCount() - 1), 0); + for (int i = firstUpdateIndex; i <= lastUpdateIndex; i++) { + View v = getView(i); + if (v != null) { + Shape childAlloc = getChildAllocation(i, a); + forwardUpdateToView(v, e, childAlloc, f); + } + } + } + // The following methods don't do anything useful, they // simply keep the class from being abstract. diff --git a/jdk/src/share/classes/javax/swing/text/View.java b/jdk/src/share/classes/javax/swing/text/View.java index c2e1e023d5a..be3a0e4336f 100644 --- a/jdk/src/share/classes/javax/swing/text/View.java +++ b/jdk/src/share/classes/javax/swing/text/View.java @@ -1137,32 +1137,9 @@ public abstract class View implements SwingConstants { */ protected void forwardUpdate(DocumentEvent.ElementChange ec, DocumentEvent e, Shape a, ViewFactory f) { - Element elem = getElement(); - int pos = e.getOffset(); - int index0 = getViewIndex(pos, Position.Bias.Forward); - if (index0 == -1 && e.getType() == DocumentEvent.EventType.REMOVE && - pos >= getEndOffset()) { - // Event beyond our offsets. We may have represented this, that is - // the remove may have removed one of our child Elements that - // represented this, so, we should foward to last element. - index0 = getViewCount() - 1; - } - int index1 = index0; - View v = (index0 >= 0) ? getView(index0) : null; - if (v != null) { - if ((v.getStartOffset() == pos) && (pos > 0)) { - // If v is at a boundary, forward the event to the previous - // view too. - index0 = Math.max(index0 - 1, 0); - } - } - if (e.getType() != DocumentEvent.EventType.REMOVE) { - index1 = getViewIndex(pos + e.getLength(), Position.Bias.Forward); - if (index1 < 0) { - index1 = getViewCount() - 1; - } - } - int hole0 = index1 + 1; + calculateUpdateIndexes(e); + + int hole0 = lastUpdateIndex + 1; int hole1 = hole0; Element[] addedElems = (ec != null) ? ec.getChildrenAdded() : null; if ((addedElems != null) && (addedElems.length > 0)) { @@ -1173,11 +1150,9 @@ public abstract class View implements SwingConstants { // forward to any view not in the forwarding hole // formed by added elements (i.e. they will be updated // by initialization. - index0 = Math.max(index0, 0); - index1 = Math.max((getViewCount() - 1), 0); - for (int i = index0; i <= index1; i++) { + for (int i = firstUpdateIndex; i <= lastUpdateIndex; i++) { if (! ((i >= hole0) && (i <= hole1))) { - v = getView(i); + View v = getView(i); if (v != null) { Shape childAlloc = getChildAllocation(i, a); forwardUpdateToView(v, e, childAlloc, f); @@ -1186,6 +1161,39 @@ public abstract class View implements SwingConstants { } } + /** + * Calculates the first and the last indexes of the child views + * that need to be notified of the change to the model. + * @param e the change information from the associated document + */ + void calculateUpdateIndexes(DocumentEvent e) { + int pos = e.getOffset(); + firstUpdateIndex = getViewIndex(pos, Position.Bias.Forward); + if (firstUpdateIndex == -1 && e.getType() == DocumentEvent.EventType.REMOVE && + pos >= getEndOffset()) { + // Event beyond our offsets. We may have represented this, that is + // the remove may have removed one of our child Elements that + // represented this, so, we should forward to last element. + firstUpdateIndex = getViewCount() - 1; + } + lastUpdateIndex = firstUpdateIndex; + View v = (firstUpdateIndex >= 0) ? getView(firstUpdateIndex) : null; + if (v != null) { + if ((v.getStartOffset() == pos) && (pos > 0)) { + // If v is at a boundary, forward the event to the previous + // view too. + firstUpdateIndex = Math.max(firstUpdateIndex - 1, 0); + } + } + if (e.getType() != DocumentEvent.EventType.REMOVE) { + lastUpdateIndex = getViewIndex(pos + e.getLength(), Position.Bias.Forward); + if (lastUpdateIndex < 0) { + lastUpdateIndex = getViewCount() - 1; + } + } + firstUpdateIndex = Math.max(firstUpdateIndex, 0); + } + /** * Forwards the DocumentEvent to the give child view. This * simply messages the view with a call to insertUpdate, @@ -1345,4 +1353,14 @@ public abstract class View implements SwingConstants { private View parent; private Element elem; + /** + * The index of the first child view to be notified. + */ + int firstUpdateIndex; + + /** + * The index of the last child view to be notified. + */ + int lastUpdateIndex; + }; diff --git a/jdk/test/javax/swing/text/View/8014863/bug8014863.java b/jdk/test/javax/swing/text/View/8014863/bug8014863.java index ba78b4bbbbb..8618ec4eba7 100644 --- a/jdk/test/javax/swing/text/View/8014863/bug8014863.java +++ b/jdk/test/javax/swing/text/View/8014863/bug8014863.java @@ -24,6 +24,7 @@ /* * @test * @bug 8014863 + * @bug 8024395 * @summary Tests the calculation of the line breaks when a text is inserted * @author Dmitry Markov * @library ../../../regtesthelpers @@ -34,91 +35,107 @@ import sun.awt.SunToolkit; import javax.swing.*; +import javax.swing.text.GlyphView; +import javax.swing.text.View; import javax.swing.text.html.HTMLEditorKit; import java.awt.*; import java.awt.event.KeyEvent; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; public class bug8014863 { private static JEditorPane editorPane; + private static JFrame frame; private static Robot robot; private static SunToolkit toolkit; + private static String text1 = "

    one two qqqq this is a test sentence qqqq pp qqqq pp " + + "qqqq pp qqqq pp qqqq pp qqqq pp qqqq pp qqqq pp qqqq

    "; + private static String text2 = "

    qqqq this is a test sentence qqqq pp qqqq pp " + + "qqqq pp qqqq pp qqqq pp qqqq pp qqqq pp qqqq pp qqqq

    "; + + private static ArrayList glyphViews; + public static void main(String[] args) throws Exception { toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); robot = new Robot(); + robot.setAutoDelay(50); + glyphViews = new ArrayList(); - createAndShowGUI(); + createAndShowGUI(text1); + + toolkit.realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + retrieveGlyphViews(editorPane.getUI().getRootView(editorPane)); + } + }); + GlyphView [] arr1 = glyphViews.toArray(new GlyphView[glyphViews.size()]); + + frame.dispose(); + glyphViews.clear(); + + createAndShowGUI(text2); toolkit.realSync(); Util.hitKeys(robot, KeyEvent.VK_HOME); + toolkit.realSync(); + Util.hitKeys(robot, KeyEvent.VK_O); - - toolkit.realSync(); - - if (3 != getNumberOfTextLines()) { - throw new RuntimeException("The number of texts lines does not meet the expectation"); - } - Util.hitKeys(robot, KeyEvent.VK_N); - - toolkit.realSync(); - - if (3 != getNumberOfTextLines()) { - throw new RuntimeException("The number of texts lines does not meet the expectation"); - } - Util.hitKeys(robot, KeyEvent.VK_E); Util.hitKeys(robot, KeyEvent.VK_SPACE); Util.hitKeys(robot, KeyEvent.VK_T); Util.hitKeys(robot, KeyEvent.VK_W); + Util.hitKeys(robot, KeyEvent.VK_O); + Util.hitKeys(robot, KeyEvent.VK_SPACE); toolkit.realSync(); - if (3 != getNumberOfTextLines()) { - throw new RuntimeException("The number of texts lines does not meet the expectation"); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + retrieveGlyphViews(editorPane.getUI().getRootView(editorPane)); + } + }); + GlyphView [] arr2 = glyphViews.toArray(new GlyphView[glyphViews.size()]); + + if (arr1.length != arr2.length) { + throw new RuntimeException("Test Failed!"); + } + + for (int i=0; iqqqq pp qqqq pp " + - "qqqq pp qqqq pp qqqq pp qqqq pp" + - " qqqq pp qqqq pp qqqq pp qqqq

    "); + editorPane.setText(text); editorPane.setCaretPosition(1); - // An actual font size depends on OS and might be differnet on various OSs. - // It is necessary to calculate the width to meet the expected number of lines. - int width = SwingUtilities.computeStringWidth(editorPane.getFontMetrics(editorPane.getFont()), - "qqqq pp qqqq pp qqqq pp qqqqqqqq"); + frame.add(editorPane); - frame.setSize(width, 200); + frame.setSize(200, 200); frame.setVisible(true); } }); From 58b4892936f6655d552b84670255b7b54804ebac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Thu, 12 Sep 2013 17:13:59 +0200 Subject: [PATCH 0317/1294] 8024512: Regex /[^\[]/ doesn't match Reviewed-by: jlaskey, sundar --- .../runtime/regexp/RegExpScanner.java | 22 +++---- nashorn/test/script/basic/JDK-8024512.js | 59 +++++++++++++++++++ .../test/script/basic/JDK-8024512.js.EXPECTED | 21 +++++++ 3 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8024512.js create mode 100644 nashorn/test/script/basic/JDK-8024512.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java index 68df99f3af3..f4edecc40ca 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java @@ -263,15 +263,6 @@ final class RegExpScanner extends Scanner { } if (atom()) { - // Check for character classes that never or always match - if (sb.toString().endsWith("[]")) { - sb.setLength(sb.length() - 1); - sb.append("^\\s\\S]"); - } else if (sb.toString().endsWith("[^]")) { - sb.setLength(sb.length() - 2); - sb.append("\\s\\S]"); - } - quantifier(); return true; } @@ -767,7 +758,18 @@ final class RegExpScanner extends Scanner { if (classRanges() && ch0 == ']') { pop(']'); - return commit(1); + commit(1); + + // Substitute empty character classes [] and [^] that never or always match + if (position == startIn + 2) { + sb.setLength(sb.length() - 1); + sb.append("^\\s\\S]"); + } else if (position == startIn + 3 && inNegativeClass) { + sb.setLength(sb.length() - 2); + sb.append("\\s\\S]"); + } + + return true; } } finally { inCharClass = false; // no nested character classes in JavaScript diff --git a/nashorn/test/script/basic/JDK-8024512.js b/nashorn/test/script/basic/JDK-8024512.js new file mode 100644 index 00000000000..c03ba212c14 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024512.js @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024512: Regex /[^\[]/ doesn't match + * + * @test + * @run + */ + +print("[M]".match(/(\[[^\[]*\])/)); +print("[[]".match(/(\[[^\[]*\])/)); + +print("[M]".match(/(\[[^\[^]*\])/)); +print("[[]".match(/(\[[^\[^]*\])/)); +print("[^]".match(/(\[[^\[^]*\])/)); + +print("[M]".match(/(\[[^\[]\])/)); +print("[[]".match(/(\[[^\[]\])/)); + +print("[M]".match(/(\[[^\[^]\])/)); +print("[[]".match(/(\[[^\[^]\])/)); +print("[^]".match(/(\[[^\[^]\])/)); + +print("M".match(/[^\[]/)); +print("[".match(/[^\[]/)); +print("^".match(/[^\[]/)); + +// Repeat above without escaping inner square bracket +print("[M]".match(/(\[[^[]\])/)); +print("[[]".match(/(\[[^[]\])/)); + +print("[M]".match(/(\[[^[^]\])/)); +print("[[]".match(/(\[[^[^]\])/)); +print("[^]".match(/(\[[^[^]\])/)); + +print("M".match(/[^[]/)); +print("[".match(/[^[]/)); +print("^".match(/[^[]/)); diff --git a/nashorn/test/script/basic/JDK-8024512.js.EXPECTED b/nashorn/test/script/basic/JDK-8024512.js.EXPECTED new file mode 100644 index 00000000000..9bb84de91dc --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024512.js.EXPECTED @@ -0,0 +1,21 @@ +[M],[M] +[],[] +[M],[M] +[],[] +null +[M],[M] +null +[M],[M] +null +null +M +null +^ +[M],[M] +null +[M],[M] +null +null +M +null +^ From a122ebe169503caf38bc626bb82d5b5d455b5450 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 12 Sep 2013 22:16:40 +0530 Subject: [PATCH 0318/1294] 8024693: Various minor issues with JSONWriter used by script parser API Reviewed-by: jlaskey, hannesw --- nashorn/make/build.xml | 7 + .../nashorn/internal/ir/debug/JSONWriter.java | 135 ++++-- nashorn/test/script/basic/NASHORN-737.js | 2 +- .../test/script/basic/NASHORN-737.js.EXPECTED | 37 +- .../script/basic/parser/assignmentExpr.js | 44 ++ .../basic/parser/assignmentExpr.js.EXPECTED | 240 ++++++++++ .../test/script/basic/parser/binaryExpr.js | 54 +++ .../basic/parser/binaryExpr.js.EXPECTED | 440 ++++++++++++++++++ nashorn/test/script/basic/parser/breakStat.js | 35 ++ .../script/basic/parser/breakStat.js.EXPECTED | 92 ++++ nashorn/test/script/basic/parser/condExpr.js | 33 ++ .../script/basic/parser/condExpr.js.EXPECTED | 23 + .../test/script/basic/parser/continueStat.js | 35 ++ .../basic/parser/continueStat.js.EXPECTED | 92 ++++ .../test/script/basic/parser/debuggerStat.js | 33 ++ .../basic/parser/debuggerStat.js.EXPECTED | 8 + nashorn/test/script/basic/parser/functions.js | 39 ++ .../script/basic/parser/functions.js.EXPECTED | 279 +++++++++++ nashorn/test/script/basic/parser/ifStat.js | 34 ++ .../script/basic/parser/ifStat.js.EXPECTED | 73 +++ .../test/script/basic/parser/labelledStat.js | 34 ++ .../basic/parser/labelledStat.js.EXPECTED | 71 +++ nashorn/test/script/basic/parser/lhsExpr.js | 47 ++ .../script/basic/parser/lhsExpr.js.EXPECTED | 344 ++++++++++++++ nashorn/test/script/basic/parser/loopStat.js | 37 ++ .../script/basic/parser/loopStat.js.EXPECTED | 212 +++++++++ .../test/script/basic/parser/objectLitExpr.js | 36 ++ .../basic/parser/objectLitExpr.js.EXPECTED | 189 ++++++++ nashorn/test/script/basic/parser/parenExpr.js | 34 ++ .../script/basic/parser/parenExpr.js.EXPECTED | 56 +++ .../test/script/basic/parser/primaryExpr.js | 45 ++ .../basic/parser/primaryExpr.js.EXPECTED | 199 ++++++++ .../test/script/basic/parser/returnStat.js | 35 ++ .../basic/parser/returnStat.js.EXPECTED | 88 ++++ .../test/script/basic/parser/switchStat.js | 35 ++ .../basic/parser/switchStat.js.EXPECTED | 123 +++++ nashorn/test/script/basic/parser/throwStat.js | 37 ++ .../script/basic/parser/throwStat.js.EXPECTED | 85 ++++ .../test/script/basic/parser/tryCatchStat.js | 38 ++ .../basic/parser/tryCatchStat.js.EXPECTED | 305 ++++++++++++ nashorn/test/script/basic/parser/unaryExpr.js | 43 ++ .../script/basic/parser/unaryExpr.js.EXPECTED | 187 ++++++++ nashorn/test/script/basic/parser/useStrict.js | 34 ++ .../script/basic/parser/useStrict.js.EXPECTED | 41 ++ nashorn/test/script/basic/parser/util.js | 33 ++ nashorn/test/script/basic/parser/varDecl.js | 39 ++ .../script/basic/parser/varDecl.js.EXPECTED | 123 +++++ nashorn/test/script/basic/parser/withStat.js | 33 ++ .../script/basic/parser/withStat.js.EXPECTED | 32 ++ 49 files changed, 4311 insertions(+), 39 deletions(-) create mode 100644 nashorn/test/script/basic/parser/assignmentExpr.js create mode 100644 nashorn/test/script/basic/parser/assignmentExpr.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/binaryExpr.js create mode 100644 nashorn/test/script/basic/parser/binaryExpr.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/breakStat.js create mode 100644 nashorn/test/script/basic/parser/breakStat.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/condExpr.js create mode 100644 nashorn/test/script/basic/parser/condExpr.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/continueStat.js create mode 100644 nashorn/test/script/basic/parser/continueStat.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/debuggerStat.js create mode 100644 nashorn/test/script/basic/parser/debuggerStat.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/functions.js create mode 100644 nashorn/test/script/basic/parser/functions.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/ifStat.js create mode 100644 nashorn/test/script/basic/parser/ifStat.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/labelledStat.js create mode 100644 nashorn/test/script/basic/parser/labelledStat.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/lhsExpr.js create mode 100644 nashorn/test/script/basic/parser/lhsExpr.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/loopStat.js create mode 100644 nashorn/test/script/basic/parser/loopStat.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/objectLitExpr.js create mode 100644 nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/parenExpr.js create mode 100644 nashorn/test/script/basic/parser/parenExpr.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/primaryExpr.js create mode 100644 nashorn/test/script/basic/parser/primaryExpr.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/returnStat.js create mode 100644 nashorn/test/script/basic/parser/returnStat.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/switchStat.js create mode 100644 nashorn/test/script/basic/parser/switchStat.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/throwStat.js create mode 100644 nashorn/test/script/basic/parser/throwStat.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/tryCatchStat.js create mode 100644 nashorn/test/script/basic/parser/tryCatchStat.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/unaryExpr.js create mode 100644 nashorn/test/script/basic/parser/unaryExpr.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/useStrict.js create mode 100644 nashorn/test/script/basic/parser/useStrict.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/util.js create mode 100644 nashorn/test/script/basic/parser/varDecl.js create mode 100644 nashorn/test/script/basic/parser/varDecl.js.EXPECTED create mode 100644 nashorn/test/script/basic/parser/withStat.js create mode 100644 nashorn/test/script/basic/parser/withStat.js.EXPECTED diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml index 9a31be88592..df655d59e51 100644 --- a/nashorn/make/build.xml +++ b/nashorn/make/build.xml @@ -264,6 +264,13 @@ grant codeBase "file:/${basedir}/test/script/basic/*" { permission java.util.PropertyPermission "nashorn.test.*", "read"; }; +grant codeBase "file:/${basedir}/test/script/basic/parser/*" { + permission java.io.FilePermission "${basedir}/test/script/-", "read"; + permission java.io.FilePermission "$${user.dir}", "read"; + permission java.util.PropertyPermission "user.dir", "read"; + permission java.util.PropertyPermission "nashorn.test.*", "read"; +}; + grant codeBase "file:/${basedir}/test/script/basic/JDK-8010946-privileged.js" { permission java.util.PropertyPermission "java.security.policy", "read"; }; diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java index be4d49b444a..dabc7e36bf1 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java +++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java @@ -27,6 +27,7 @@ package jdk.nashorn.internal.ir.debug; import java.util.Arrays; import java.util.List; +import java.util.ArrayList; import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.ir.AccessNode; import jdk.nashorn.internal.ir.BinaryNode; @@ -197,10 +198,10 @@ public final class JSONWriter extends NodeVisitor { comma(); final IdentNode label = breakNode.getLabel(); + property("label"); if (label != null) { - property("label", label.getName()); + label.accept(this); } else { - property("label"); nullValue(); } @@ -256,13 +257,11 @@ public final class JSONWriter extends NodeVisitor { comma(); final Node guard = catchNode.getExceptionCondition(); - property("guard"); if (guard != null) { + property("guard"); guard.accept(this); - } else { - nullValue(); + comma(); } - comma(); property("body"); catchNode.getBody().accept(this); @@ -278,10 +277,10 @@ public final class JSONWriter extends NodeVisitor { comma(); final IdentNode label = continueNode.getLabel(); + property("label"); if (label != null) { - property("label", label.getName()); + label.accept(this); } else { - property("label"); nullValue(); } @@ -299,13 +298,20 @@ public final class JSONWriter extends NodeVisitor { @Override public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) { + // handle debugger statement + final Node expression = expressionStatement.getExpression(); + if (expression instanceof RuntimeNode) { + expression.accept(this); + return false; + } + enterDefault(expressionStatement); type("ExpressionStatement"); comma(); property("expression"); - expressionStatement.getExpression().accept(this); + expression.accept(this); return leave(); } @@ -388,13 +394,14 @@ public final class JSONWriter extends NodeVisitor { @Override public boolean enterFunctionNode(final FunctionNode functionNode) { - enterDefault(functionNode); - final boolean program = functionNode.isProgram(); - final String name; if (program) { - name = "Program"; - } else if (functionNode.isDeclared()) { + return emitProgram(functionNode); + } + + enterDefault(functionNode); + final String name; + if (functionNode.isDeclared()) { name = "FunctionDeclaration"; } else { name = "FunctionExpression"; @@ -402,24 +409,41 @@ public final class JSONWriter extends NodeVisitor { type(name); comma(); - if (! program) { - property("id"); - if (functionNode.isAnonymous()) { - nullValue(); - } else { - functionNode.getIdent().accept(this); - } - comma(); + property("id"); + if (functionNode.isAnonymous()) { + nullValue(); + } else { + functionNode.getIdent().accept(this); } + comma(); + + array("params", functionNode.getParameters()); + comma(); + + arrayStart("defaults"); + arrayEnd(); + comma(); property("rest"); nullValue(); comma(); - if (!program) { - array("params", functionNode.getParameters()); - comma(); - } + property("body"); + functionNode.getBody().accept(this); + comma(); + + property("generator", false); + comma(); + + property("expression", false); + + return leave(); + } + + private boolean emitProgram(final FunctionNode functionNode) { + enterDefault(functionNode); + type("Program"); + comma(); // body consists of nested functions and statements final List stats = functionNode.getBody().getStatements(); @@ -730,7 +754,31 @@ public final class JSONWriter extends NodeVisitor { tryNode.getBody().accept(this); comma(); - array("handlers", tryNode.getCatches()); + + final List catches = tryNode.getCatches(); + final List guarded = new ArrayList<>(); + CatchNode unguarded = null; + if (catches != null) { + for (Node n : catches) { + CatchNode cn = (CatchNode)n; + if (cn.getExceptionCondition() != null) { + guarded.add(cn); + } else { + assert unguarded == null: "too many unguarded?"; + unguarded = cn; + } + } + } + + array("guardedHandlers", guarded); + comma(); + + property("handler"); + if (unguarded != null) { + unguarded.accept(this); + } else { + nullValue(); + } comma(); property("finalizer"); @@ -760,8 +808,8 @@ public final class JSONWriter extends NodeVisitor { array("arguments", callNode.getArgs()); } else { - final boolean prefix; final String operator; + final boolean prefix; switch (tokenType) { case INCPOSTFIX: prefix = false; @@ -780,8 +828,9 @@ public final class JSONWriter extends NodeVisitor { prefix = true; break; default: - prefix = false; + prefix = true; operator = tokenType.getName(); + break; } type(unaryNode.isAssignment()? "UpdateExpression" : "UnaryExpression"); @@ -802,6 +851,14 @@ public final class JSONWriter extends NodeVisitor { @Override public boolean enterVarNode(final VarNode varNode) { + final Node init = varNode.getInit(); + if (init instanceof FunctionNode && ((FunctionNode)init).isDeclared()) { + // function declaration - don't emit VariableDeclaration instead + // just emit FunctionDeclaration using 'init' Node. + init.accept(this); + return false; + } + enterDefault(varNode); type("VariableDeclaration"); @@ -816,11 +873,11 @@ public final class JSONWriter extends NodeVisitor { type("VariableDeclarator"); comma(); - property("id", varNode.getName().toString()); + property("id"); + varNode.getName().accept(this); comma(); property("init"); - final Node init = varNode.getInit(); if (init != null) { init.accept(this); } else { @@ -855,7 +912,7 @@ public final class JSONWriter extends NodeVisitor { whileNode.getTest().accept(this); comma(); - property("block"); + property("body"); whileNode.getBody().accept(this); } @@ -894,23 +951,27 @@ public final class JSONWriter extends NodeVisitor { return buf.toString(); } - private void property(final String key, final String value) { + private void property(final String key, final String value, final boolean escape) { buf.append('"'); buf.append(key); buf.append("\":"); if (value != null) { - buf.append('"'); + if (escape) buf.append('"'); buf.append(value); - buf.append('"'); + if (escape) buf.append('"'); } } + private void property(final String key, final String value) { + property(key, value, true); + } + private void property(final String key, final boolean value) { - property(key, Boolean.toString(value)); + property(key, Boolean.toString(value), false); } private void property(final String key, final int value) { - property(key, Integer.toString(value)); + property(key, Integer.toString(value), false); } private void property(final String key) { diff --git a/nashorn/test/script/basic/NASHORN-737.js b/nashorn/test/script/basic/NASHORN-737.js index 44169d0435f..3db48918df1 100644 --- a/nashorn/test/script/basic/NASHORN-737.js +++ b/nashorn/test/script/basic/NASHORN-737.js @@ -30,4 +30,4 @@ load("nashorn:parser.js"); var ast = parse("label: while(true) break label;"); -print(JSON.stringify(ast)); +print(JSON.stringify(ast, null, " ")); diff --git a/nashorn/test/script/basic/NASHORN-737.js.EXPECTED b/nashorn/test/script/basic/NASHORN-737.js.EXPECTED index 8f828342948..77c796579f4 100644 --- a/nashorn/test/script/basic/NASHORN-737.js.EXPECTED +++ b/nashorn/test/script/basic/NASHORN-737.js.EXPECTED @@ -1 +1,36 @@ -{"type":"Program","rest":null,"body":[{"type":"LabeledStatement","label":{"type":"Identifier","name":"label"},"body":{"type":"BlockStatement","body":[{"type":"WhileStatement","test":{"type":"Literal","value":true},"block":{"type":"BlockStatement","body":[{"type":"BreakStatement","label":"label"}]}}]}}]} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "label" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "label" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/assignmentExpr.js b/nashorn/test/script/basic/parser/assignmentExpr.js new file mode 100644 index 00000000000..231e19fd9b1 --- /dev/null +++ b/nashorn/test/script/basic/parser/assignmentExpr.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check assignment e xyzpressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("xyz = 314"); +printParse("xyz += 314"); +printParse("xyz -= 314"); +printParse("xyz *= 314"); +printParse("xyz /= 314"); +printParse("xyz %= 314"); +printParse("xyz <<= 314"); +printParse("xyz >>= 314"); +printParse("xyz >>>= 314"); +printParse("xyz &= 314"); +printParse("xyz ^= 314"); +printParse("xyz |= 314"); diff --git a/nashorn/test/script/basic/parser/assignmentExpr.js.EXPECTED b/nashorn/test/script/basic/parser/assignmentExpr.js.EXPECTED new file mode 100644 index 00000000000..da6793afa55 --- /dev/null +++ b/nashorn/test/script/basic/parser/assignmentExpr.js.EXPECTED @@ -0,0 +1,240 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "+=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "-=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "*=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "/=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "%=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "<<=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": ">>=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": ">>>=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "&=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "^=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "|=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/binaryExpr.js b/nashorn/test/script/basic/parser/binaryExpr.js new file mode 100644 index 00000000000..a2b761da2f1 --- /dev/null +++ b/nashorn/test/script/basic/parser/binaryExpr.js @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check binary operators. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("a * b") +printParse("a / b"); +printParse("a % b"); +printParse("a + b"); +printParse("a - b"); +printParse("a << b"); +printParse("a >> b"); +printParse("a >>> b"); +printParse("a < b"); +printParse("a > b"); +printParse("a <= b"); +printParse("a >= b"); +printParse("a instanceof b"); +printParse("a == b"); +printParse("a != b"); +printParse("a === b"); +printParse("a !== b"); +printParse("a & b"); +printParse("a ^ b"); +printParse("a | b"); +printParse("a && b"); +printParse("a || b"); diff --git a/nashorn/test/script/basic/parser/binaryExpr.js.EXPECTED b/nashorn/test/script/basic/parser/binaryExpr.js.EXPECTED new file mode 100644 index 00000000000..dd75f4b6096 --- /dev/null +++ b/nashorn/test/script/basic/parser/binaryExpr.js.EXPECTED @@ -0,0 +1,440 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "*", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "/", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "%", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "-", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<<", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">>", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">>>", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<=", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">=", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "instanceof", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "==", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "!=", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "===", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "!==", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "&", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "^", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "|", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "LogicalExpression", + "operator": "&&", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "LogicalExpression", + "operator": "||", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/breakStat.js b/nashorn/test/script/basic/parser/breakStat.js new file mode 100644 index 00000000000..1b16cc2ce75 --- /dev/null +++ b/nashorn/test/script/basic/parser/breakStat.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check 'break' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("while (true) { break; }"); +printParse("loop: { while (true) { break loop } }"); +printParse("loop: { for (;;) { break loop } }"); diff --git a/nashorn/test/script/basic/parser/breakStat.js.EXPECTED b/nashorn/test/script/basic/parser/breakStat.js.EXPECTED new file mode 100644 index 00000000000..1d9fd079810 --- /dev/null +++ b/nashorn/test/script/basic/parser/breakStat.js.EXPECTED @@ -0,0 +1,92 @@ +{ + "type": "Program", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "loop" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "loop" + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "loop" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ForStatement", + "init": null, + "test": null, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "loop" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/condExpr.js b/nashorn/test/script/basic/parser/condExpr.js new file mode 100644 index 00000000000..3644ff35e84 --- /dev/null +++ b/nashorn/test/script/basic/parser/condExpr.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check ternary operator. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("a? b : c"); diff --git a/nashorn/test/script/basic/parser/condExpr.js.EXPECTED b/nashorn/test/script/basic/parser/condExpr.js.EXPECTED new file mode 100644 index 00000000000..75c486fa85f --- /dev/null +++ b/nashorn/test/script/basic/parser/condExpr.js.EXPECTED @@ -0,0 +1,23 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ConditionalExpression", + "test": { + "type": "Identifier", + "name": "a" + }, + "consequent": { + "type": "Identifier", + "name": "b" + }, + "alternate": { + "type": "Identifier", + "name": "c" + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/continueStat.js b/nashorn/test/script/basic/parser/continueStat.js new file mode 100644 index 00000000000..22ddadd44e6 --- /dev/null +++ b/nashorn/test/script/basic/parser/continueStat.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check 'continue' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("while (true) { continue; }"); +printParse("begin: { while (true) { continue begin; } }"); +printParse("start: { for(;;) { continue start; } }"); diff --git a/nashorn/test/script/basic/parser/continueStat.js.EXPECTED b/nashorn/test/script/basic/parser/continueStat.js.EXPECTED new file mode 100644 index 00000000000..cfd3114db3c --- /dev/null +++ b/nashorn/test/script/basic/parser/continueStat.js.EXPECTED @@ -0,0 +1,92 @@ +{ + "type": "Program", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ContinueStatement", + "label": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "begin" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ContinueStatement", + "label": { + "type": "Identifier", + "name": "begin" + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "start" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ForStatement", + "init": null, + "test": null, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ContinueStatement", + "label": { + "type": "Identifier", + "name": "start" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/debuggerStat.js b/nashorn/test/script/basic/parser/debuggerStat.js new file mode 100644 index 00000000000..60eab78fff0 --- /dev/null +++ b/nashorn/test/script/basic/parser/debuggerStat.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check debugger statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("debugger"); diff --git a/nashorn/test/script/basic/parser/debuggerStat.js.EXPECTED b/nashorn/test/script/basic/parser/debuggerStat.js.EXPECTED new file mode 100644 index 00000000000..7b954fc30ee --- /dev/null +++ b/nashorn/test/script/basic/parser/debuggerStat.js.EXPECTED @@ -0,0 +1,8 @@ +{ + "type": "Program", + "body": [ + { + "type": "DebuggerStatement" + } + ] +} diff --git a/nashorn/test/script/basic/parser/functions.js b/nashorn/test/script/basic/parser/functions.js new file mode 100644 index 00000000000..7b624b554be --- /dev/null +++ b/nashorn/test/script/basic/parser/functions.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check 'function' statements and expressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("function hello() { print('hello') }") +printParse("function hello(a) { print(a) }") +printParse("function hello(a, b) { print(a, b) }") +printParse("var hello = function() { print('hello') };") +printParse("var hello = function hello() { print('hello') };") +printParse("(function(){})") +printParse("function test() { 'use strict' }"); diff --git a/nashorn/test/script/basic/parser/functions.js.EXPECTED b/nashorn/test/script/basic/parser/functions.js.EXPECTED new file mode 100644 index 00000000000..59451d57942 --- /dev/null +++ b/nashorn/test/script/basic/parser/functions.js.EXPECTED @@ -0,0 +1,279 @@ +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [ + { + "type": "Identifier", + "name": "a" + } + ], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "hello" + }, + "init": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "hello" + }, + "init": { + "type": "FunctionExpression", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [] + }, + "generator": false, + "expression": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "test" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": "use strict" + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} diff --git a/nashorn/test/script/basic/parser/ifStat.js b/nashorn/test/script/basic/parser/ifStat.js new file mode 100644 index 00000000000..5d1566686c2 --- /dev/null +++ b/nashorn/test/script/basic/parser/ifStat.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check 'if' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("if (js) { nashorn() }"); +printParse("if (js) { nashorn() } else { java() }"); diff --git a/nashorn/test/script/basic/parser/ifStat.js.EXPECTED b/nashorn/test/script/basic/parser/ifStat.js.EXPECTED new file mode 100644 index 00000000000..3897dc14fca --- /dev/null +++ b/nashorn/test/script/basic/parser/ifStat.js.EXPECTED @@ -0,0 +1,73 @@ +{ + "type": "Program", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "js" + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "nashorn" + }, + "arguments": [] + } + } + ] + }, + "alternate": null + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "js" + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "nashorn" + }, + "arguments": [] + } + } + ] + }, + "alternate": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "java" + }, + "arguments": [] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/labelledStat.js b/nashorn/test/script/basic/parser/labelledStat.js new file mode 100644 index 00000000000..25829a4a755 --- /dev/null +++ b/nashorn/test/script/basic/parser/labelledStat.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010, 2013, 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 for labelled statements. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("begin: { for (;;) break begin }"); +printParse("begin: { while (true) break begin }"); diff --git a/nashorn/test/script/basic/parser/labelledStat.js.EXPECTED b/nashorn/test/script/basic/parser/labelledStat.js.EXPECTED new file mode 100644 index 00000000000..fc5f37e8a3b --- /dev/null +++ b/nashorn/test/script/basic/parser/labelledStat.js.EXPECTED @@ -0,0 +1,71 @@ +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "begin" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ForStatement", + "init": null, + "test": null, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "begin" + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "begin" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "begin" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/lhsExpr.js b/nashorn/test/script/basic/parser/lhsExpr.js new file mode 100644 index 00000000000..68f4d6c3c46 --- /dev/null +++ b/nashorn/test/script/basic/parser/lhsExpr.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check left-hand-side expressions + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("a[3]"); +printParse("a[b]"); +printParse("a['foo']"); +printParse("obj.foo"); +printParse("obj.foo.bar"); +printParse("new Type"); +printParse("new Type()"); +printParse("new Type(a, 'hello')"); +printParse("new obj.Type"); +printParse("new obj.Type()"); +printParse("new obj.Type(a, 'hello')"); +printParse("foo()") +printParse("obj.foo()"); +printParse("foo(a,b)"); +printParse("obj.foo(a, b)"); diff --git a/nashorn/test/script/basic/parser/lhsExpr.js.EXPECTED b/nashorn/test/script/basic/parser/lhsExpr.js.EXPECTED new file mode 100644 index 00000000000..e61c6c8fc6a --- /dev/null +++ b/nashorn/test/script/basic/parser/lhsExpr.js.EXPECTED @@ -0,0 +1,344 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a" + }, + "property": { + "type": "Literal", + "value": 3 + }, + "computed": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a" + }, + "property": { + "type": "Identifier", + "name": "b" + }, + "computed": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a" + }, + "property": { + "type": "Literal", + "value": "foo" + }, + "computed": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + }, + "property": { + "type": "Identifier", + "name": "bar" + }, + "computed": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "Type" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "Type" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "Type" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "Type" + }, + "computed": false + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "Type" + }, + "computed": false + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "Type" + }, + "computed": false + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/loopStat.js b/nashorn/test/script/basic/parser/loopStat.js new file mode 100644 index 00000000000..ba705568e8e --- /dev/null +++ b/nashorn/test/script/basic/parser/loopStat.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests for loop statements. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("while(true) { print('hello') }") +printParse("do { print('hello') } while(true)") +printParse("for (i in obj) { print(obj[i]) }") +printParse("for each (i in obj) { print(i) }") +printParse("for (i = 0; i < 10; i++) { print(i) }") diff --git a/nashorn/test/script/basic/parser/loopStat.js.EXPECTED b/nashorn/test/script/basic/parser/loopStat.js.EXPECTED new file mode 100644 index 00000000000..fd8ef838afc --- /dev/null +++ b/nashorn/test/script/basic/parser/loopStat.js.EXPECTED @@ -0,0 +1,212 @@ +{ + "type": "Program", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "DoWhileStatement", + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "test": { + "type": "Literal", + "value": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ForInStatement", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Identifier", + "name": "obj" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "i" + }, + "computed": true + } + ] + } + } + ] + }, + "each": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ForInStatement", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Identifier", + "name": "obj" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "i" + } + ] + } + } + ] + }, + "each": true + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ForStatement", + "init": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Literal", + "value": 0 + } + }, + "test": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Literal", + "value": 10 + } + }, + "update": { + "type": "UpdateExpression", + "operator": "++", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "i" + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "i" + } + ] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/objectLitExpr.js b/nashorn/test/script/basic/parser/objectLitExpr.js new file mode 100644 index 00000000000..bdecc7fa691 --- /dev/null +++ b/nashorn/test/script/basic/parser/objectLitExpr.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check assignment e xyzpressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("obj = {}"); +printParse("p = { x: 10, y: 2 }"); +printParse("p = { 'x': 10, 'y': 2 }"); +printParse("p = { get x() { return xValue }, get y() { return yValue } }"); diff --git a/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED b/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED new file mode 100644 index 00000000000..067c506ab95 --- /dev/null +++ b/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED @@ -0,0 +1,189 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "obj" + }, + "right": { + "type": "ObjectExpression", + "properties": [] + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "p" + }, + "right": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "x" + }, + "value": { + "type": "Literal", + "value": 10 + }, + "kind": "init" + }, + { + "key": { + "type": "Identifier", + "name": "y" + }, + "value": { + "type": "Literal", + "value": 2 + }, + "kind": "init" + } + ] + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "p" + }, + "right": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Literal", + "value": "x" + }, + "value": { + "type": "Literal", + "value": 10 + }, + "kind": "init" + }, + { + "key": { + "type": "Literal", + "value": "y" + }, + "value": { + "type": "Literal", + "value": 2 + }, + "kind": "init" + } + ] + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "p" + }, + "right": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "x" + }, + "value": { + "type": "FunctionExpression", + "id": { + "type": "Identifier", + "name": "get x" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "xValue" + } + } + ] + }, + "generator": false, + "expression": false + }, + "kind": "get" + }, + { + "key": { + "type": "Identifier", + "name": "y" + }, + "value": { + "type": "FunctionExpression", + "id": { + "type": "Identifier", + "name": "get y" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "yValue" + } + } + ] + }, + "generator": false, + "expression": false + }, + "kind": "get" + } + ] + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/parenExpr.js b/nashorn/test/script/basic/parser/parenExpr.js new file mode 100644 index 00000000000..2d52a023034 --- /dev/null +++ b/nashorn/test/script/basic/parser/parenExpr.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests for parenthesis expressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("(2) + (1) + 4"); +printParse("3 + (7) << (5)"); diff --git a/nashorn/test/script/basic/parser/parenExpr.js.EXPECTED b/nashorn/test/script/basic/parser/parenExpr.js.EXPECTED new file mode 100644 index 00000000000..1e4a2306c71 --- /dev/null +++ b/nashorn/test/script/basic/parser/parenExpr.js.EXPECTED @@ -0,0 +1,56 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Literal", + "value": 2 + }, + "right": { + "type": "Literal", + "value": 1 + } + }, + "right": { + "type": "Literal", + "value": 4 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<<", + "left": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Literal", + "value": 3 + }, + "right": { + "type": "Literal", + "value": 7 + } + }, + "right": { + "type": "Literal", + "value": 5 + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/primaryExpr.js b/nashorn/test/script/basic/parser/primaryExpr.js new file mode 100644 index 00000000000..950c47f3ea8 --- /dev/null +++ b/nashorn/test/script/basic/parser/primaryExpr.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check primary expressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("this"); +printParse("foo"); +printParse("null"); +printParse("true"); +printParse("false"); +printParse("33"); +printParse("3.14"); +printParse("(10 + 3)*2"); +printParse("({})"); +printParse("({ x: 3 })"); +printParse("[]"); +printParse("[,,]"); +printParse("[4, 5, 5]"); diff --git a/nashorn/test/script/basic/parser/primaryExpr.js.EXPECTED b/nashorn/test/script/basic/parser/primaryExpr.js.EXPECTED new file mode 100644 index 00000000000..fcb31d54cd5 --- /dev/null +++ b/nashorn/test/script/basic/parser/primaryExpr.js.EXPECTED @@ -0,0 +1,199 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ThisExpression" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Identifier", + "name": "foo" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": null + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": 33 + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": 3.14 + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "*", + "left": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Literal", + "value": 10 + }, + "right": { + "type": "Literal", + "value": 3 + } + }, + "right": { + "type": "Literal", + "value": 2 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ObjectExpression", + "properties": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "x" + }, + "value": { + "type": "Literal", + "value": 3 + }, + "kind": "init" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ArrayExpression", + "elements": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ArrayExpression", + "elements": [ + null, + null + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ArrayExpression", + "elements": [ + { + "type": "Literal", + "value": 4 + }, + { + "type": "Literal", + "value": 5 + }, + { + "type": "Literal", + "value": 5 + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/returnStat.js b/nashorn/test/script/basic/parser/returnStat.js new file mode 100644 index 00000000000..741a23403c4 --- /dev/null +++ b/nashorn/test/script/basic/parser/returnStat.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check 'return' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("(function() { return })"); +printParse("(function() { return res })"); +printParse("(function() { return foo() })"); diff --git a/nashorn/test/script/basic/parser/returnStat.js.EXPECTED b/nashorn/test/script/basic/parser/returnStat.js.EXPECTED new file mode 100644 index 00000000000..149673c1d0f --- /dev/null +++ b/nashorn/test/script/basic/parser/returnStat.js.EXPECTED @@ -0,0 +1,88 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": null + } + ] + }, + "generator": false, + "expression": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "res" + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo" + }, + "arguments": [] + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/switchStat.js b/nashorn/test/script/basic/parser/switchStat.js new file mode 100644 index 00000000000..6f0dd75e741 --- /dev/null +++ b/nashorn/test/script/basic/parser/switchStat.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests for switch statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("switch (key) {}"); +printParse("switch (key) { case 2: hello(); break; }"); +printParse("switch (key) { case 4: hello(); break; case 2: world(); break; default: break }"); diff --git a/nashorn/test/script/basic/parser/switchStat.js.EXPECTED b/nashorn/test/script/basic/parser/switchStat.js.EXPECTED new file mode 100644 index 00000000000..6de4ba484b3 --- /dev/null +++ b/nashorn/test/script/basic/parser/switchStat.js.EXPECTED @@ -0,0 +1,123 @@ +{ + "type": "Program", + "body": [ + { + "type": "SwitchStatement", + "discriminant": { + "type": "Identifier", + "name": "key" + }, + "cases": [] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "SwitchStatement", + "discriminant": { + "type": "Identifier", + "name": "key" + }, + "cases": [ + { + "type": "SwitchCase", + "test": { + "type": "Literal", + "value": 2 + }, + "consequent": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "hello" + }, + "arguments": [] + } + }, + { + "type": "BreakStatement", + "label": null + } + ] + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "SwitchStatement", + "discriminant": { + "type": "Identifier", + "name": "key" + }, + "cases": [ + { + "type": "SwitchCase", + "test": { + "type": "Literal", + "value": 4 + }, + "consequent": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "hello" + }, + "arguments": [] + } + }, + { + "type": "BreakStatement", + "label": null + } + ] + }, + { + "type": "SwitchCase", + "test": { + "type": "Literal", + "value": 2 + }, + "consequent": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "world" + }, + "arguments": [] + } + }, + { + "type": "BreakStatement", + "label": null + } + ] + }, + { + "type": "SwitchCase", + "test": null, + "consequent": [ + { + "type": "BreakStatement", + "label": null + } + ] + } + ] + } + ] +} diff --git a/nashorn/test/script/basic/parser/throwStat.js b/nashorn/test/script/basic/parser/throwStat.js new file mode 100644 index 00000000000..345e3b8c7dc --- /dev/null +++ b/nashorn/test/script/basic/parser/throwStat.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests for throw statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("throw err"); +printParse("throw 'wrong'"); +printParse("throw new TypeError"); +printParse("throw new TypeError('not an array')"); +printParse("throw { msg: 'wrong!' }"); diff --git a/nashorn/test/script/basic/parser/throwStat.js.EXPECTED b/nashorn/test/script/basic/parser/throwStat.js.EXPECTED new file mode 100644 index 00000000000..d869cbda8df --- /dev/null +++ b/nashorn/test/script/basic/parser/throwStat.js.EXPECTED @@ -0,0 +1,85 @@ +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "Identifier", + "name": "err" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "Literal", + "value": "wrong" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "TypeError" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "TypeError" + }, + "arguments": [ + { + "type": "Literal", + "value": "not an array" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "msg" + }, + "value": { + "type": "Literal", + "value": "wrong!" + }, + "kind": "init" + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/tryCatchStat.js b/nashorn/test/script/basic/parser/tryCatchStat.js new file mode 100644 index 00000000000..de1531338b0 --- /dev/null +++ b/nashorn/test/script/basic/parser/tryCatchStat.js @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check try..catch statements. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("try { } catch (e) { }"); +printParse("try { } catch (e) { } finally {}"); +printParse("try { } finally {}"); +printParse("try { } catch (e) { handle() }"); +printParse("try { that() } catch (e) { handle() } finally { clean() }"); +printParse("try { that() } catch (e if e instanceof TypeError) { handle() } catch (e) { rest() }"); diff --git a/nashorn/test/script/basic/parser/tryCatchStat.js.EXPECTED b/nashorn/test/script/basic/parser/tryCatchStat.js.EXPECTED new file mode 100644 index 00000000000..16075e15420 --- /dev/null +++ b/nashorn/test/script/basic/parser/tryCatchStat.js.EXPECTED @@ -0,0 +1,305 @@ +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [] + } + }, + "finalizer": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [] + } + }, + "finalizer": { + "type": "BlockStatement", + "body": [] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": null, + "finalizer": { + "type": "BlockStatement", + "body": [] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "handle" + }, + "arguments": [] + } + } + ] + } + }, + "finalizer": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "that" + }, + "arguments": [] + } + } + ] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "handle" + }, + "arguments": [] + } + } + ] + } + }, + "finalizer": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "clean" + }, + "arguments": [] + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "that" + }, + "arguments": [] + } + } + ] + }, + "guardedHandlers": [ + { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "guard": { + "type": "BinaryExpression", + "operator": "instanceof", + "left": { + "type": "Identifier", + "name": "e" + }, + "right": { + "type": "Identifier", + "name": "TypeError" + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "handle" + }, + "arguments": [] + } + } + ] + } + } + ], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "rest" + }, + "arguments": [] + } + } + ] + } + }, + "finalizer": null + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/unaryExpr.js b/nashorn/test/script/basic/parser/unaryExpr.js new file mode 100644 index 00000000000..e21b55f32fa --- /dev/null +++ b/nashorn/test/script/basic/parser/unaryExpr.js @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check unary operators. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("x++"); +printParse("x--"); +printParse("delete x"); +printParse("void x"); +printParse("typeof x"); +printParse("++x"); +printParse("--x"); +printParse("+x"); +printParse("-x"); +printParse("~x"); +printParse("!x"); diff --git a/nashorn/test/script/basic/parser/unaryExpr.js.EXPECTED b/nashorn/test/script/basic/parser/unaryExpr.js.EXPECTED new file mode 100644 index 00000000000..d7a9532b677 --- /dev/null +++ b/nashorn/test/script/basic/parser/unaryExpr.js.EXPECTED @@ -0,0 +1,187 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "++", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "--", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "delete", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "void", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "typeof", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "++", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "--", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "+", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "-", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "~", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/useStrict.js b/nashorn/test/script/basic/parser/useStrict.js new file mode 100644 index 00000000000..4d1c7a94d09 --- /dev/null +++ b/nashorn/test/script/basic/parser/useStrict.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check if statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("'use strict'"); +printParse("function f() { 'use strict' }"); diff --git a/nashorn/test/script/basic/parser/useStrict.js.EXPECTED b/nashorn/test/script/basic/parser/useStrict.js.EXPECTED new file mode 100644 index 00000000000..870fbc24e04 --- /dev/null +++ b/nashorn/test/script/basic/parser/useStrict.js.EXPECTED @@ -0,0 +1,41 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": "use strict" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "f" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": "use strict" + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} diff --git a/nashorn/test/script/basic/parser/util.js b/nashorn/test/script/basic/parser/util.js new file mode 100644 index 00000000000..6170018b378 --- /dev/null +++ b/nashorn/test/script/basic/parser/util.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * @subtest + */ + +// utilitity for parser tests + +load("nashorn:parser.js"); +function printParse(code) { + print(JSON.stringify(parse(code), null, ' ')); +} diff --git a/nashorn/test/script/basic/parser/varDecl.js b/nashorn/test/script/basic/parser/varDecl.js new file mode 100644 index 00000000000..e505761be8e --- /dev/null +++ b/nashorn/test/script/basic/parser/varDecl.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests to check variable declarations. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +// no initialization +printParse("var a"); +printParse("var a, b"); + +// init single, multiple +printParse("var a = 'hello'"); +printParse("var a = 1, b = 2, c = 3"); diff --git a/nashorn/test/script/basic/parser/varDecl.js.EXPECTED b/nashorn/test/script/basic/parser/varDecl.js.EXPECTED new file mode 100644 index 00000000000..96e71cf6f13 --- /dev/null +++ b/nashorn/test/script/basic/parser/varDecl.js.EXPECTED @@ -0,0 +1,123 @@ +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": null + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": null + } + ] + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b" + }, + "init": null + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": { + "type": "Literal", + "value": "hello" + } + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": { + "type": "Literal", + "value": 1 + } + } + ] + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b" + }, + "init": { + "type": "Literal", + "value": 2 + } + } + ] + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "c" + }, + "init": { + "type": "Literal", + "value": 3 + } + } + ] + } + ] +} diff --git a/nashorn/test/script/basic/parser/withStat.js b/nashorn/test/script/basic/parser/withStat.js new file mode 100644 index 00000000000..3f94c7f596f --- /dev/null +++ b/nashorn/test/script/basic/parser/withStat.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * Tests for 'with' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("with (scope) { x = y }"); diff --git a/nashorn/test/script/basic/parser/withStat.js.EXPECTED b/nashorn/test/script/basic/parser/withStat.js.EXPECTED new file mode 100644 index 00000000000..46bea479a26 --- /dev/null +++ b/nashorn/test/script/basic/parser/withStat.js.EXPECTED @@ -0,0 +1,32 @@ +{ + "type": "Program", + "body": [ + { + "type": "WithStatement", + "object": { + "type": "Identifier", + "name": "scope" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x" + }, + "right": { + "type": "Identifier", + "name": "y" + } + } + } + ] + } + } + ] +} From f0058a6c7e72240f10bc9dd2efe9ec678721966f Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 12 Sep 2013 11:08:54 -0700 Subject: [PATCH 0319/1294] Added tag jdk8-b107 for changeset 2c525ed65d4c --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index ca1497b3968..d83fa5ca611 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -228,3 +228,4 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103 96c1b9b7524b52c3fcefc90ffad4c767396727c8 jdk8-b104 5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105 8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106 +0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107 From a6085bc97e1eb5bad42140a1c7f9ab14ea1d8657 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 12 Sep 2013 11:08:55 -0700 Subject: [PATCH 0320/1294] Added tag jdk8-b107 for changeset 03623ef0f781 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index f96b90eb232..e24845b3555 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -228,3 +228,4 @@ a013024b07475782f1fa8e196e950b34b4077663 jdk8-b101 d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104 4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105 2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106 +23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107 From 32856d517b4dba9f78a9b4b6a2901e336bb7c34f Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 12 Sep 2013 11:08:59 -0700 Subject: [PATCH 0321/1294] Added tag jdk8-b107 for changeset c86a71fcceaf --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index bc3aba45318..8d3f958c431 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -375,3 +375,4 @@ acac3bde66b2c22791c257a8d99611d6d08c6713 jdk8-b105 18b4798adbc42c6fa16f5ecb7d5cd3ca130754bf hs25-b48 aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106 50794d8ac11c9579b41dec4de23b808fef9f34a1 hs25-b49 +5b7f90aab3ad25a25b75b7b2bb18d5ae23d8231c jdk8-b107 From f6cfa523c73a3670e521d0eeafebce9e8cff7539 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 12 Sep 2013 11:09:06 -0700 Subject: [PATCH 0322/1294] Added tag jdk8-b107 for changeset 82c75a285e35 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index e21e3e57573..e136f4f7d31 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -228,3 +228,4 @@ b1ceab582fc6d795b20aaa8a3fde2eba34af9399 jdk8-b103 a22fe9bd01e6c7e7ddc7995dfc9471711692b8d1 jdk8-b104 09a46ec11f880154886c70be03aff5ab2ddf0ab7 jdk8-b105 d3be8e3b429df917e72c1c23e7920c651219b587 jdk8-b106 +d6a32e3831aab20a9a3bc78cdc0a60aaad725c6c jdk8-b107 From b406ae898bafd8f0e43dcdbb375e334ea9e296a0 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 12 Sep 2013 11:09:08 -0700 Subject: [PATCH 0323/1294] Added tag jdk8-b107 for changeset 8a84d7cf2ea6 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index d213728514a..164a718d39c 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -228,3 +228,4 @@ b1fb4612a2caea52b5661b87509e560fa044b194 jdk8-b98 42211ab0ab1cca51a050d184634cf1db7ef81fbf jdk8-b104 88390df7ed2cf128298a02c5e6d978f0a603cd58 jdk8-b105 6908370afe834ff01739e8ec992d4246c74b7e6e jdk8-b106 +e3c9328f75638289a342ce15fbe532f05078946e jdk8-b107 From ccef21daceb606ea375e16e970047a8991e8818a Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 12 Sep 2013 11:09:11 -0700 Subject: [PATCH 0324/1294] Added tag jdk8-b107 for changeset 55dd1a0fe510 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index c20c5cde8f0..3e3a625970b 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -228,3 +228,4 @@ e0f6039c0290b7381042a6fec3100a69a5a67e37 jdk8-b103 f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104 1fe211ae3d2b8cc2dfc4f58d9a6eb96418679672 jdk8-b105 c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106 +eea685b9ccaa1980e0a7e07d6a3a84bcc7e9ab82 jdk8-b107 From 2de4350911f9ac388424d5e40d7fe0105708848e Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 12 Sep 2013 11:09:20 -0700 Subject: [PATCH 0325/1294] Added tag jdk8-b107 for changeset bd69808a67e1 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index d15910c1e57..f3ac2a1e9ab 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -228,3 +228,4 @@ ce5a90df517bdceb2739d7dd3e6764b070def802 jdk8-b98 dd4a00c220c6e14d9b2ce93a2bd436a1d04f0d03 jdk8-b104 375834b5cf086dd7ce9e49f602d81bb51d3e0fa9 jdk8-b105 fcd768844b9926c5f994292ec6350c20cc7c0f76 jdk8-b106 +3f274927ec1863544b8214262ab02b7de2970da6 jdk8-b107 From 9ce24938888f1c969b45282ac396b2ab58f5ab75 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 12 Sep 2013 11:09:22 -0700 Subject: [PATCH 0326/1294] Added tag jdk8-b107 for changeset e94578d4e6a5 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 0cc3a707a66..05fbb43822b 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -216,3 +216,4 @@ e966ff0a3ffef8a687eaf5a14167bb595b623d02 jdk8-b102 afc100513451d22f0b8135999d6eb52f36df3d36 jdk8-b104 f484bfb624dd06683cb33b524700a5dd4927a82b jdk8-b105 bf70cbd2c8369fd97ffdfcbe1a80dbc2797408ee jdk8-b106 +f35e1255024b66f7cf82517798f45f6e194e5567 jdk8-b107 From 914b1751c4fe4c7ad42e777c066439c3e133e1ad Mon Sep 17 00:00:00 2001 From: Eric McCorkle Date: Thu, 12 Sep 2013 14:52:28 -0400 Subject: [PATCH 0327/1294] 8013846: javac fails to reject semantically equivalent generic method declarations Cause javac to consider intersection types with the same elements to be equal regardless of order. Reviewed-by: jjg, vromero --- .../com/sun/tools/javac/comp/Check.java | 4 +++- .../generics/neg/OrderedIntersections.java | 21 +++++++++++++++++++ .../generics/neg/OrderedIntersections.out | 2 ++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/generics/neg/OrderedIntersections.java create mode 100644 langtools/test/tools/javac/generics/neg/OrderedIntersections.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 59d6c7b4468..2612741ac03 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -3340,7 +3340,9 @@ public class Check { (e.sym.flags() & CLASH) == 0 && sym.kind == e.sym.kind && sym.name != names.error && - (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) { + (sym.kind != MTH || + types.hasSameArgs(sym.type, e.sym.type) || + types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) { if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) { varargsDuplicateError(pos, sym, e.sym); return true; diff --git a/langtools/test/tools/javac/generics/neg/OrderedIntersections.java b/langtools/test/tools/javac/generics/neg/OrderedIntersections.java new file mode 100644 index 00000000000..2213ac5a78a --- /dev/null +++ b/langtools/test/tools/javac/generics/neg/OrderedIntersections.java @@ -0,0 +1,21 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6962494 + * @summary The order of elements of intersection types shouldn't matter + * @compile/fail/ref=OrderedIntersections.out -XDrawDiagnostics OrderedIntersections.java + */ + +interface i1 {} +interface i2 {} + +public class OrderedIntersections { + static Object smf(t1 x) { + System.out.println( " smf1 " ); + return null; + } + + static Object smf(t2 x) { + System.out.println( " smf2 " ); + return null; + } +} diff --git a/langtools/test/tools/javac/generics/neg/OrderedIntersections.out b/langtools/test/tools/javac/generics/neg/OrderedIntersections.out new file mode 100644 index 00000000000..69deb46b26d --- /dev/null +++ b/langtools/test/tools/javac/generics/neg/OrderedIntersections.out @@ -0,0 +1,2 @@ +OrderedIntersections.java:17:40: compiler.err.already.defined: kindname.method, smf(t1), kindname.class, OrderedIntersections +1 error From 350906807bf274a05000522a64e683da309dff94 Mon Sep 17 00:00:00 2001 From: Niclas Adlertz Date: Thu, 12 Sep 2013 23:13:45 +0200 Subject: [PATCH 0328/1294] 8024646: Remove LRG_List container, replace it with GrowableArray We already have GrowableArray, use it instead of LRG_List Reviewed-by: kvn --- hotspot/src/share/vm/opto/chaitin.cpp | 42 ++++++++------------------ hotspot/src/share/vm/opto/chaitin.hpp | 34 ++++++++++----------- hotspot/src/share/vm/opto/coalesce.hpp | 1 - hotspot/src/share/vm/opto/live.cpp | 10 +++--- hotspot/src/share/vm/opto/live.hpp | 22 +------------- 5 files changed, 36 insertions(+), 73 deletions(-) diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp index a1a0e1c1fb7..492bf384f2f 100644 --- a/hotspot/src/share/vm/opto/chaitin.cpp +++ b/hotspot/src/share/vm/opto/chaitin.cpp @@ -122,40 +122,23 @@ double LRG::score() const { return score; } -LRG_List::LRG_List( uint max ) : _cnt(max), _max(max), _lidxs(NEW_RESOURCE_ARRAY(uint,max)) { - memset( _lidxs, 0, sizeof(uint)*max ); -} - -void LRG_List::extend( uint nidx, uint lidx ) { - _nesting.check(); - if( nidx >= _max ) { - uint size = 16; - while( size <= nidx ) size <<=1; - _lidxs = REALLOC_RESOURCE_ARRAY( uint, _lidxs, _max, size ); - _max = size; - } - while( _cnt <= nidx ) - _lidxs[_cnt++] = 0; - _lidxs[nidx] = lidx; -} - #define NUMBUCKS 3 // Straight out of Tarjan's union-find algorithm uint LiveRangeMap::find_compress(uint lrg) { uint cur = lrg; - uint next = _uf_map[cur]; + uint next = _uf_map.at(cur); while (next != cur) { // Scan chain of equivalences assert( next < cur, "always union smaller"); cur = next; // until find a fixed-point - next = _uf_map[cur]; + next = _uf_map.at(cur); } // Core of union-find algorithm: update chain of // equivalences to be equal to the root. while (lrg != next) { - uint tmp = _uf_map[lrg]; - _uf_map.map(lrg, next); + uint tmp = _uf_map.at(lrg); + _uf_map.at_put(lrg, next); lrg = tmp; } return lrg; @@ -165,10 +148,10 @@ uint LiveRangeMap::find_compress(uint lrg) { void LiveRangeMap::reset_uf_map(uint max_lrg_id) { _max_lrg_id= max_lrg_id; // Force the Union-Find mapping to be at least this large - _uf_map.extend(_max_lrg_id, 0); + _uf_map.at_put_grow(_max_lrg_id, 0); // Initialize it to be the ID mapping. for (uint i = 0; i < _max_lrg_id; ++i) { - _uf_map.map(i, i); + _uf_map.at_put(i, i); } } @@ -176,12 +159,12 @@ void LiveRangeMap::reset_uf_map(uint max_lrg_id) { // the Union-Find mapping after this call. void LiveRangeMap::compress_uf_map_for_nodes() { // For all Nodes, compress mapping - uint unique = _names.Size(); + uint unique = _names.length(); for (uint i = 0; i < unique; ++i) { - uint lrg = _names[i]; + uint lrg = _names.at(i); uint compressed_lrg = find(lrg); if (lrg != compressed_lrg) { - _names.map(i, compressed_lrg); + _names.at_put(i, compressed_lrg); } } } @@ -198,11 +181,11 @@ uint LiveRangeMap::find_const(uint lrg) const { return lrg; } - uint next = _uf_map[lrg]; + uint next = _uf_map.at(lrg); while (next != lrg) { // Scan chain of equivalences assert(next < lrg, "always union smaller"); lrg = next; // until find a fixed-point - next = _uf_map[lrg]; + next = _uf_map.at(lrg); } return next; } @@ -215,7 +198,7 @@ PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher) NULL #endif ) - , _lrg_map(unique) + , _lrg_map(Thread::current()->resource_area(), unique) , _live(0) , _spilled_once(Thread::current()->resource_area()) , _spilled_twice(Thread::current()->resource_area()) @@ -692,6 +675,7 @@ void PhaseChaitin::de_ssa() { _lrg_map.map(n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0); } } + // Reset the Union-Find mapping to be identity _lrg_map.reset_uf_map(lr_counter); } diff --git a/hotspot/src/share/vm/opto/chaitin.hpp b/hotspot/src/share/vm/opto/chaitin.hpp index c951024ee75..41276efa5ca 100644 --- a/hotspot/src/share/vm/opto/chaitin.hpp +++ b/hotspot/src/share/vm/opto/chaitin.hpp @@ -283,8 +283,8 @@ private: // Straight out of Tarjan's union-find algorithm uint find_compress(const Node *node) { - uint lrg_id = find_compress(_names[node->_idx]); - _names.map(node->_idx, lrg_id); + uint lrg_id = find_compress(_names.at(node->_idx)); + _names.at_put(node->_idx, lrg_id); return lrg_id; } @@ -305,40 +305,40 @@ public: } uint size() const { - return _names.Size(); + return _names.length(); } uint live_range_id(uint idx) const { - return _names[idx]; + return _names.at(idx); } uint live_range_id(const Node *node) const { - return _names[node->_idx]; + return _names.at(node->_idx); } uint uf_live_range_id(uint lrg_id) const { - return _uf_map[lrg_id]; + return _uf_map.at(lrg_id); } void map(uint idx, uint lrg_id) { - _names.map(idx, lrg_id); + _names.at_put(idx, lrg_id); } void uf_map(uint dst_lrg_id, uint src_lrg_id) { - _uf_map.map(dst_lrg_id, src_lrg_id); + _uf_map.at_put(dst_lrg_id, src_lrg_id); } void extend(uint idx, uint lrg_id) { - _names.extend(idx, lrg_id); + _names.at_put_grow(idx, lrg_id); } void uf_extend(uint dst_lrg_id, uint src_lrg_id) { - _uf_map.extend(dst_lrg_id, src_lrg_id); + _uf_map.at_put_grow(dst_lrg_id, src_lrg_id); } - LiveRangeMap(uint unique) - : _names(unique) - , _uf_map(unique) + LiveRangeMap(Arena* arena, uint unique) + : _names(arena, unique, unique, 0) + , _uf_map(arena, unique, unique, 0) , _max_lrg_id(0) {} uint find_id( const Node *n ) { @@ -355,14 +355,14 @@ public: void compress_uf_map_for_nodes(); uint find(uint lidx) { - uint uf_lidx = _uf_map[lidx]; + uint uf_lidx = _uf_map.at(lidx); return (uf_lidx == lidx) ? uf_lidx : find_compress(lidx); } // Convert a Node into a Live Range Index - a lidx uint find(const Node *node) { uint lidx = live_range_id(node); - uint uf_lidx = _uf_map[lidx]; + uint uf_lidx = _uf_map.at(lidx); return (uf_lidx == lidx) ? uf_lidx : find_compress(node); } @@ -371,10 +371,10 @@ public: // Like Find above, but no path compress, so bad asymptotic behavior uint find_const(const Node *node) const { - if(node->_idx >= _names.Size()) { + if(node->_idx >= (uint)_names.length()) { return 0; // not mapped, usual for debug dump } - return find_const(_names[node->_idx]); + return find_const(_names.at(node->_idx)); } }; diff --git a/hotspot/src/share/vm/opto/coalesce.hpp b/hotspot/src/share/vm/opto/coalesce.hpp index a6359af101c..3a361b25f11 100644 --- a/hotspot/src/share/vm/opto/coalesce.hpp +++ b/hotspot/src/share/vm/opto/coalesce.hpp @@ -29,7 +29,6 @@ class LoopTree; class LRG; -class LRG_List; class Matcher; class PhaseIFG; class PhaseCFG; diff --git a/hotspot/src/share/vm/opto/live.cpp b/hotspot/src/share/vm/opto/live.cpp index 280d22204c2..adbbc24f8fd 100644 --- a/hotspot/src/share/vm/opto/live.cpp +++ b/hotspot/src/share/vm/opto/live.cpp @@ -91,7 +91,7 @@ void PhaseLive::compute(uint maxlrg) { break; } - uint r = _names[n->_idx]; + uint r = _names.at(n->_idx); assert(!def_outside->member(r), "Use of external LRG overlaps the same LRG defined in this block"); def->insert( r ); use->remove( r ); @@ -100,7 +100,7 @@ void PhaseLive::compute(uint maxlrg) { Node *nk = n->in(k); uint nkidx = nk->_idx; if (_cfg.get_block_for_node(nk) != block) { - uint u = _names[nkidx]; + uint u = _names.at(nkidx); use->insert(u); DEBUG_ONLY(def_outside->insert(u);) } @@ -112,7 +112,7 @@ void PhaseLive::compute(uint maxlrg) { #endif // Remove anything defined by Phis and the block start instruction for (uint k = i; k > 0; k--) { - uint r = _names[block->get_node(k - 1)->_idx]; + uint r = _names.at(block->get_node(k - 1)->_idx); def->insert(r); use->remove(r); } @@ -124,7 +124,7 @@ void PhaseLive::compute(uint maxlrg) { // PhiNode uses go in the live-out set of prior blocks. for (uint k = i; k > 0; k--) { - add_liveout(p, _names[block->get_node(k-1)->in(l)->_idx], first_pass); + add_liveout(p, _names.at(block->get_node(k-1)->in(l)->_idx), first_pass); } } freeset(block); @@ -256,7 +256,7 @@ void PhaseLive::dump( const Block *b ) const { tty->print("LiveOut: "); _live[b->_pre_order-1].dump(); uint cnt = b->number_of_nodes(); for( uint i=0; iprint("L%d/", _names[b->get_node(i)->_idx] ); + tty->print("L%d/", _names.at(b->get_node(i)->_idx)); b->get_node(i)->dump(); } tty->print("\n"); diff --git a/hotspot/src/share/vm/opto/live.hpp b/hotspot/src/share/vm/opto/live.hpp index c2ebe758cf8..e449bb3f3a6 100644 --- a/hotspot/src/share/vm/opto/live.hpp +++ b/hotspot/src/share/vm/opto/live.hpp @@ -40,27 +40,7 @@ class IndexSet; //------------------------------LRG_List--------------------------------------- // Map Node indices to Live RanGe indices. // Array lookup in the optimized case. -class LRG_List : public ResourceObj { - friend class VMStructs; - uint _cnt, _max; - uint* _lidxs; - ReallocMark _nesting; // assertion check for reallocations -public: - LRG_List( uint max ); - - uint lookup( uint nidx ) const { - return _lidxs[nidx]; - } - uint operator[] (uint nidx) const { return lookup(nidx); } - - void map( uint nidx, uint lidx ) { - assert( nidx < _cnt, "oob" ); - _lidxs[nidx] = lidx; - } - void extend( uint nidx, uint lidx ); - - uint Size() const { return _cnt; } -}; +typedef GrowableArray LRG_List; //------------------------------PhaseLive-------------------------------------- // Compute live-in/live-out From f6e4c46294b1a9df3f613bd4f14d6a6fc6b7c30f Mon Sep 17 00:00:00 2001 From: Shanliang Jiang Date: Fri, 13 Sep 2013 10:48:12 +0200 Subject: [PATCH 0329/1294] 8023669: MBean*Info.hashCode : NPE Reviewed-by: dholmes, dfuchs, jbachorik --- .../javax/management/MBeanAttributeInfo.java | 3 +- .../management/MBeanConstructorInfo.java | 7 +- .../classes/javax/management/MBeanInfo.java | 20 +- .../javax/management/MBeanOperationInfo.java | 3 +- .../javax/management/MBeanParameterInfo.java | 3 +- .../MBeanInfo/MBeanInfoHashCodeNPETest.java | 176 ++++++++++++++++++ 6 files changed, 190 insertions(+), 22 deletions(-) create mode 100644 jdk/test/javax/management/MBeanInfo/MBeanInfoHashCodeNPETest.java diff --git a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java index d99b9f7b8ad..a70fb3a3571 100644 --- a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java @@ -30,6 +30,7 @@ import java.security.AccessController; import com.sun.jmx.mbeanserver.GetPropertyAction; import com.sun.jmx.mbeanserver.Introspector; +import java.util.Objects; /** @@ -301,7 +302,7 @@ public class MBeanAttributeInfo extends MBeanFeatureInfo implements Cloneable { right and we needlessly hashed in the description and parameter array. */ public int hashCode() { - return getName().hashCode() ^ getType().hashCode(); + return Objects.hash(getName(), getType()); } private static boolean isIs(Method getter) { diff --git a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java index c2bbe5ef886..ad2176367d2 100644 --- a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java @@ -29,6 +29,7 @@ import com.sun.jmx.mbeanserver.Introspector; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.util.Arrays; +import java.util.Objects; /** * Describes a constructor exposed by an MBean. Instances of this @@ -203,11 +204,7 @@ public class MBeanConstructorInfo extends MBeanFeatureInfo implements Cloneable quite long and yet the same between constructors. Likewise for the descriptor. */ public int hashCode() { - int hash = getName().hashCode(); - MBeanParameterInfo[] sig = fastGetSignature(); - for (int i = 0; i < sig.length; i++) - hash ^= sig[i].hashCode(); - return hash; + return Objects.hash(getName()) ^ Arrays.hashCode(fastGetSignature()); } private static MBeanParameterInfo[] constructorSignature(Constructor cn) { diff --git a/jdk/src/share/classes/javax/management/MBeanInfo.java b/jdk/src/share/classes/javax/management/MBeanInfo.java index ed04c347b70..f4a9581c520 100644 --- a/jdk/src/share/classes/javax/management/MBeanInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanInfo.java @@ -36,6 +36,7 @@ import java.util.Map; import java.util.WeakHashMap; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Objects; import static javax.management.ImmutableDescriptor.nonNullDescriptor; @@ -515,24 +516,15 @@ public class MBeanInfo implements Cloneable, Serializable, DescriptorRead { if (hashCode != 0) return hashCode; - hashCode = - getClassName().hashCode() ^ - getDescriptor().hashCode() ^ - arrayHashCode(fastGetAttributes()) ^ - arrayHashCode(fastGetOperations()) ^ - arrayHashCode(fastGetConstructors()) ^ - arrayHashCode(fastGetNotifications()); + hashCode = Objects.hash(getClassName(), getDescriptor()) + ^ Arrays.hashCode(fastGetAttributes()) + ^ Arrays.hashCode(fastGetOperations()) + ^ Arrays.hashCode(fastGetConstructors()) + ^ Arrays.hashCode(fastGetNotifications()); return hashCode; } - private static int arrayHashCode(Object[] array) { - int hash = 0; - for (int i = 0; i < array.length; i++) - hash ^= array[i].hashCode(); - return hash; - } - /** * Cached results of previous calls to arrayGettersSafe. This is * a WeakHashMap so that we don't prevent a class from being diff --git a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java index 66b13a94ef0..8effa04f8d8 100644 --- a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java @@ -29,6 +29,7 @@ import com.sun.jmx.mbeanserver.Introspector; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.Objects; /** * Describes a management operation exposed by an MBean. Instances of @@ -309,7 +310,7 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable { parameter array. */ @Override public int hashCode() { - return getName().hashCode() ^ getReturnType().hashCode(); + return Objects.hash(getName(), getReturnType()); } private static MBeanParameterInfo[] methodSignature(Method method) { diff --git a/jdk/src/share/classes/javax/management/MBeanParameterInfo.java b/jdk/src/share/classes/javax/management/MBeanParameterInfo.java index ec5a31fc93e..df3d59087df 100644 --- a/jdk/src/share/classes/javax/management/MBeanParameterInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanParameterInfo.java @@ -25,6 +25,7 @@ package javax.management; +import java.util.Objects; /** * Describes an argument of an operation exposed by an MBean. @@ -143,6 +144,6 @@ public class MBeanParameterInfo extends MBeanFeatureInfo implements Cloneable { } public int hashCode() { - return getName().hashCode() ^ getType().hashCode(); + return Objects.hash(getName(), getType()); } } diff --git a/jdk/test/javax/management/MBeanInfo/MBeanInfoHashCodeNPETest.java b/jdk/test/javax/management/MBeanInfo/MBeanInfoHashCodeNPETest.java new file mode 100644 index 00000000000..bb35da38ba6 --- /dev/null +++ b/jdk/test/javax/management/MBeanInfo/MBeanInfoHashCodeNPETest.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; +import javax.management.modelmbean.DescriptorSupport; +import javax.management.openmbean.SimpleType; + +/* + * @test + * @bug 8023669 + * @summary Test that hashCode()throws NullPointerException + * @author Shanliang JIANG + * @run clean MBeanInfoHashCodeNPETest + * @run build MBeanInfoHashCodeNPETest + * @run main MBeanInfoHashCodeNPETest + */ +public class MBeanInfoHashCodeNPETest { + private static int failed = 0; + + public static void main(String[] args) throws Exception { + System.out.println("---MBeanInfoHashCodeNPETest-main ..."); + + // ---- + System.out.println("\n---Testing on MBeanAttributeInfo..."); + MBeanAttributeInfo mbeanAttributeInfo = new MBeanAttributeInfo( + null, SimpleType.INTEGER.getClassName(), "description", true, true, false); + test(mbeanAttributeInfo, "class name"); + + mbeanAttributeInfo = new MBeanAttributeInfo( + "name", null, "description", true, true, false); + test(mbeanAttributeInfo, "type"); + + mbeanAttributeInfo = new MBeanAttributeInfo( + "name", SimpleType.INTEGER.getClassName(), null, true, true, false); + test(mbeanAttributeInfo, "description"); + + // ---- + System.out.println("\n---Testing on MBeanConstructorInfo..."); + MBeanConstructorInfo mbeanConstructorInfo = new MBeanConstructorInfo( + null, "", new MBeanParameterInfo[]{}, new DescriptorSupport()); + test(mbeanConstructorInfo, "name"); + + mbeanConstructorInfo = new MBeanConstructorInfo( + "", null, new MBeanParameterInfo[]{}, new DescriptorSupport()); + test(mbeanConstructorInfo, "description"); + + mbeanConstructorInfo = new MBeanConstructorInfo( + "", "", null, new DescriptorSupport()); + test(mbeanConstructorInfo, "MBeanParameterInfo"); + + mbeanConstructorInfo = new MBeanConstructorInfo( + "", "", new MBeanParameterInfo[]{}, null); + test(mbeanConstructorInfo, "descriptor"); + + // ---- + System.out.println("\n---Testing on MBeanOperationInfo..."); + MBeanOperationInfo mbeanOperationInfo = new MBeanOperationInfo( + null, "description", new MBeanParameterInfo[]{}, "type", 1, new DescriptorSupport()); + test(mbeanOperationInfo, "name"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", null, new MBeanParameterInfo[]{}, "type", 1, new DescriptorSupport()); + test(mbeanOperationInfo, "description"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", "description", null, "type", 1, new DescriptorSupport()); + test(mbeanOperationInfo, "MBeanParameterInfo"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", "description", new MBeanParameterInfo[]{}, null, 1, new DescriptorSupport()); + test(mbeanOperationInfo, "type"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", "description", new MBeanParameterInfo[]{}, "type", -1, new DescriptorSupport()); + test(mbeanOperationInfo, "native impact"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", "description", new MBeanParameterInfo[]{}, "type", 1, null); + test(mbeanOperationInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on MBeanParameterInfo..."); + MBeanParameterInfo mbeanParameterInfo = new MBeanParameterInfo( + null, "type", "description", new DescriptorSupport()); + test(mbeanParameterInfo, "name"); + + mbeanParameterInfo = new MBeanParameterInfo( + "name", null, "description", new DescriptorSupport()); + test(mbeanParameterInfo, "description"); + + mbeanParameterInfo = new MBeanParameterInfo( + "name", "type", null, new DescriptorSupport()); + test(mbeanParameterInfo, "description"); + + mbeanParameterInfo = new MBeanParameterInfo( + "name", "type", "description", null); + test(mbeanParameterInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on MBeanInfo..."); + String className = "toto"; + String description = "titi"; + MBeanAttributeInfo[] attrInfos = new MBeanAttributeInfo[]{}; + MBeanConstructorInfo[] constrInfos = new MBeanConstructorInfo[]{}; + MBeanOperationInfo[] operaInfos = new MBeanOperationInfo[]{}; + MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{}; + + MBeanInfo minfo = new MBeanInfo(null, description, attrInfos, constrInfos, operaInfos, notifInfos); + test(minfo, "class name"); + + minfo = new MBeanInfo(className, description, attrInfos, constrInfos, operaInfos, notifInfos); + test(minfo, "name"); + + minfo = new MBeanInfo(className, null, attrInfos, constrInfos, operaInfos, notifInfos); + test(minfo, "description"); + + minfo = new MBeanInfo(className, description, null, constrInfos, operaInfos, notifInfos); + test(minfo, "attrInfos"); + + minfo = new MBeanInfo(className, description, attrInfos, constrInfos, null, notifInfos); + test(minfo, "operaInfos"); + + minfo = new MBeanInfo(className, description, attrInfos, constrInfos, operaInfos, null); + test(minfo, "notifInfos"); + + Thread.sleep(100); + if (failed > 0) { + throw new RuntimeException("Test failed: "+failed); + } else { + System.out.println("---Test: PASSED"); + } + } + + private static void test(Object obj, String param) { + try { + obj.hashCode(); + System.out.println("OK: "+obj.getClass().getSimpleName()+".hashCode worked with a null "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO!!! "+obj.getClass().getSimpleName()+".hashCode got NPE with a null "+param); + failed++; + } + + try { + obj.toString(); + System.out.println("OK: "+obj.getClass().getSimpleName()+".toString worked with a null "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO!!! "+obj.getClass().getSimpleName()+".toString got NPE."); + failed++; + } + } +} From 276b809ff474d3655f6b3d9786dd20fc4a47664f Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Thu, 12 Sep 2013 14:22:53 -0700 Subject: [PATCH 0330/1294] 8024009: Remove jdk.map.useRandomSeed system property Removed usage of hashSeed in Hashtable & WeakHashMap, and removed tests Reviewed-by: alanb, mduigou --- .../share/classes/java/util/Hashtable.java | 104 +++--------------- .../share/classes/java/util/WeakHashMap.java | 39 +------ .../java/util/Map/CheckRandomHashSeed.java | 91 --------------- jdk/test/java/util/Map/Collisions.java | 2 - 4 files changed, 19 insertions(+), 217 deletions(-) delete mode 100644 jdk/test/java/util/Map/CheckRandomHashSeed.java diff --git a/jdk/src/share/classes/java/util/Hashtable.java b/jdk/src/share/classes/java/util/Hashtable.java index 518bd17f5b7..dc50e9393ee 100644 --- a/jdk/src/share/classes/java/util/Hashtable.java +++ b/jdk/src/share/classes/java/util/Hashtable.java @@ -168,68 +168,6 @@ public class Hashtable /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = 1421746759512286392L; - private static class Holder { - // Unsafe mechanics - /** - * - */ - static final sun.misc.Unsafe UNSAFE; - - /** - * Offset of "final" hashSeed field we must set in - * readObject() method. - */ - static final long HASHSEED_OFFSET; - - static final boolean USE_HASHSEED; - - static { - String hashSeedProp = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "jdk.map.useRandomSeed")); - boolean localBool = (null != hashSeedProp) - ? Boolean.parseBoolean(hashSeedProp) : false; - USE_HASHSEED = localBool; - - if (USE_HASHSEED) { - try { - UNSAFE = sun.misc.Unsafe.getUnsafe(); - HASHSEED_OFFSET = UNSAFE.objectFieldOffset( - Hashtable.class.getDeclaredField("hashSeed")); - } catch (NoSuchFieldException | SecurityException e) { - throw new InternalError("Failed to record hashSeed offset", e); - } - } else { - UNSAFE = null; - HASHSEED_OFFSET = 0; - } - } - } - - /** - * A randomizing value associated with this instance that is applied to - * hash code of keys to make hash collisions harder to find. - * - * Non-final so it can be set lazily, but be sure not to set more than once. - */ - transient final int hashSeed; - - /** - * Return an initial value for the hashSeed, or 0 if the random seed is not - * enabled. - */ - final int initHashSeed() { - if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) { - int seed = ThreadLocalRandom.current().nextInt(); - return (seed != 0) ? seed : 1; - } - return 0; - } - - private int hash(Object k) { - return hashSeed ^ k.hashCode(); - } - /** * Constructs a new, empty hashtable with the specified initial * capacity and the specified load factor. @@ -251,7 +189,6 @@ public class Hashtable this.loadFactor = loadFactor; table = new Entry[initialCapacity]; threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1); - hashSeed = initHashSeed(); } /** @@ -395,7 +332,7 @@ public class Hashtable */ public synchronized boolean containsKey(Object key) { Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { @@ -423,7 +360,7 @@ public class Hashtable @SuppressWarnings("unchecked") public synchronized V get(Object key) { Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { @@ -488,7 +425,7 @@ public class Hashtable rehash(); tab = table; - hash = hash(key); + hash = key.hashCode(); index = (hash & 0x7FFFFFFF) % tab.length; } @@ -524,7 +461,7 @@ public class Hashtable // Makes sure the key is not already in the hashtable. Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry entry = (Entry)tab[index]; @@ -551,7 +488,7 @@ public class Hashtable */ public synchronized V remove(Object key) { Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry e = (Entry)tab[index]; @@ -760,7 +697,7 @@ public class Hashtable Map.Entry entry = (Map.Entry)o; Object key = entry.getKey(); Entry[] tab = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry e = tab[index]; e != null; e = e.next) @@ -775,7 +712,7 @@ public class Hashtable Map.Entry entry = (Map.Entry) o; Object key = entry.getKey(); Entry[] tab = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") @@ -975,7 +912,7 @@ public class Hashtable // Makes sure the key is not already in the hashtable. Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry entry = (Entry)tab[index]; @@ -998,7 +935,7 @@ public class Hashtable Objects.requireNonNull(value); Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry e = (Entry)tab[index]; @@ -1021,7 +958,7 @@ public class Hashtable @Override public synchronized boolean replace(K key, V oldValue, V newValue) { Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry e = (Entry)tab[index]; @@ -1041,7 +978,7 @@ public class Hashtable @Override public synchronized V replace(K key, V value) { Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry e = (Entry)tab[index]; @@ -1060,7 +997,7 @@ public class Hashtable Objects.requireNonNull(mappingFunction); Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry e = (Entry)tab[index]; @@ -1084,7 +1021,7 @@ public class Hashtable Objects.requireNonNull(remappingFunction); Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry e = (Entry)tab[index]; @@ -1113,7 +1050,7 @@ public class Hashtable Objects.requireNonNull(remappingFunction); Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry e = (Entry)tab[index]; @@ -1148,7 +1085,7 @@ public class Hashtable Objects.requireNonNull(remappingFunction); Entry tab[] = table; - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry e = (Entry)tab[index]; @@ -1228,13 +1165,6 @@ public class Hashtable // Read in the length, threshold, and loadfactor s.defaultReadObject(); - // set hashMask - if (Holder.USE_HASHSEED) { - int seed = ThreadLocalRandom.current().nextInt(); - Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET, - (seed != 0) ? seed : 1); - } - // Read the original length of the array and number of elements int origlength = s.readInt(); int elements = s.readInt(); @@ -1282,7 +1212,7 @@ public class Hashtable } // Makes sure the key is not already in the hashtable. // This should not happen in deserialized version. - int hash = hash(key); + int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { @@ -1347,7 +1277,7 @@ public class Hashtable } public int hashCode() { - return (Objects.hashCode(key) ^ Objects.hashCode(value)); + return hash ^ Objects.hashCode(value); } public String toString() { diff --git a/jdk/src/share/classes/java/util/WeakHashMap.java b/jdk/src/share/classes/java/util/WeakHashMap.java index 0299d296638..81f74be8e9e 100644 --- a/jdk/src/share/classes/java/util/WeakHashMap.java +++ b/jdk/src/share/classes/java/util/WeakHashMap.java @@ -190,39 +190,6 @@ public class WeakHashMap */ int modCount; - private static class Holder { - static final boolean USE_HASHSEED; - - static { - String hashSeedProp = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "jdk.map.useRandomSeed")); - boolean localBool = (null != hashSeedProp) - ? Boolean.parseBoolean(hashSeedProp) : false; - USE_HASHSEED = localBool; - } - } - - /** - * A randomizing value associated with this instance that is applied to - * hash code of keys to make hash collisions harder to find. - * - * Non-final so it can be set lazily, but be sure not to set more than once. - */ - transient int hashSeed; - - /** - * Initialize the hashing mask value. - */ - final void initHashSeed() { - if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) { - // Do not set hashSeed more than once! - // assert hashSeed == 0; - int seed = ThreadLocalRandom.current().nextInt(); - hashSeed = (seed != 0) ? seed : 1; - } - } - @SuppressWarnings("unchecked") private Entry[] newTable(int n) { return (Entry[]) new Entry[n]; @@ -253,7 +220,6 @@ public class WeakHashMap table = newTable(capacity); this.loadFactor = loadFactor; threshold = (int)(capacity * loadFactor); - initHashSeed(); } /** @@ -329,7 +295,7 @@ public class WeakHashMap * in lower bits. */ final int hash(Object k) { - int h = hashSeed ^ k.hashCode(); + int h = k.hashCode(); // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded @@ -783,8 +749,7 @@ public class WeakHashMap public int hashCode() { K k = getKey(); V v = getValue(); - return ((k==null ? 0 : k.hashCode()) ^ - (v==null ? 0 : v.hashCode())); + return Objects.hashCode(k) ^ Objects.hashCode(v); } public String toString() { diff --git a/jdk/test/java/util/Map/CheckRandomHashSeed.java b/jdk/test/java/util/Map/CheckRandomHashSeed.java deleted file mode 100644 index 2acf1bc8c9c..00000000000 --- a/jdk/test/java/util/Map/CheckRandomHashSeed.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2013, 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 8005698 - * @summary Check operation of jdk.map.useRandomSeed property - * @run main CheckRandomHashSeed - * @run main/othervm -Djdk.map.useRandomSeed=false CheckRandomHashSeed - * @run main/othervm -Djdk.map.useRandomSeed=bogus CheckRandomHashSeed - * @run main/othervm -Djdk.map.useRandomSeed=true CheckRandomHashSeed true - * @author Brent Christian - */ -import java.lang.reflect.Field; -import java.util.Map; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Hashtable; -import java.util.WeakHashMap; - -public class CheckRandomHashSeed { - private final static String PROP_NAME = "jdk.map.useRandomSeed"; - static boolean expectRandom = false; - - public static void main(String[] args) { - if (args.length > 0 && args[0].equals("true")) { - expectRandom = true; - } - String hashSeedProp = System.getProperty(PROP_NAME); - boolean propSet = (null != hashSeedProp) - ? Boolean.parseBoolean(hashSeedProp) : false; - if (expectRandom != propSet) { - throw new Error("Error in test setup: " + (expectRandom ? "" : "not " ) + "expecting random hashSeed, but " + PROP_NAME + " is " + (propSet ? "" : "not ") + "enabled"); - } - - testMap(new WeakHashMap()); - testMap(new Hashtable()); - } - - private static void testMap(Map map) { - int hashSeed = getHashSeed(map); - boolean hashSeedIsZero = (hashSeed == 0); - - if (expectRandom != hashSeedIsZero) { - System.out.println("Test passed for " + map.getClass().getSimpleName() + " - expectRandom: " + expectRandom + ", hashSeed: " + hashSeed); - } else { - throw new Error ("Test FAILED for " + map.getClass().getSimpleName() + " - expectRandom: " + expectRandom + ", hashSeed: " + hashSeed); - } - } - - private static int getHashSeed(Map map) { - try { - if (map instanceof HashMap || map instanceof LinkedHashMap) { - map.put("Key", "Value"); - Field hashSeedField = HashMap.class.getDeclaredField("hashSeed"); - hashSeedField.setAccessible(true); - int hashSeed = hashSeedField.getInt(map); - return hashSeed; - } else { - map.put("Key", "Value"); - Field hashSeedField = map.getClass().getDeclaredField("hashSeed"); - hashSeedField.setAccessible(true); - int hashSeed = hashSeedField.getInt(map); - return hashSeed; - } - } catch(Exception e) { - e.printStackTrace(); - throw new Error(e); - } - } -} diff --git a/jdk/test/java/util/Map/Collisions.java b/jdk/test/java/util/Map/Collisions.java index b7170791777..05e9e1f95e0 100644 --- a/jdk/test/java/util/Map/Collisions.java +++ b/jdk/test/java/util/Map/Collisions.java @@ -25,8 +25,6 @@ * @test * @bug 7126277 * @run main Collisions -shortrun - * @run main/othervm -Djdk.map.althashing.threshold=0 Collisions -shortrun - * @run main/othervm -Djdk.map.useRandomSeed=true Collisions -shortrun * @summary Ensure Maps behave well with lots of hashCode() collisions. * @author Mike Duigou */ From 204f4422ba5afba76c7604ba956421a290d695e2 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Thu, 12 Sep 2013 22:40:29 +0100 Subject: [PATCH 0331/1294] 8023558: Javac creates invalid bootstrap methods for complex lambda/methodref case Co-authored-by: Maurizio Cimadamore Reviewed-by: jjg --- .../com/sun/tools/javac/comp/TransTypes.java | 2 +- .../tools/javac/lambda/8023558/T8023558a.java | 38 ++++++++++++ .../tools/javac/lambda/8023558/T8023558b.java | 58 +++++++++++++++++++ .../tools/javac/lambda/8023558/T8023558c.java | 39 +++++++++++++ 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/lambda/8023558/T8023558a.java create mode 100644 langtools/test/tools/javac/lambda/8023558/T8023558b.java create mode 100644 langtools/test/tools/javac/lambda/8023558/T8023558c.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java index 47cc589e967..ff7f0da574d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -833,7 +833,7 @@ public class TransTypes extends TreeTranslator { } public void visitReference(JCMemberReference tree) { - tree.expr = translate(tree.expr, null); + tree.expr = translate(tree.expr, erasure(tree.expr.type)); tree.type = erasure(tree.type); result = tree; } diff --git a/langtools/test/tools/javac/lambda/8023558/T8023558a.java b/langtools/test/tools/javac/lambda/8023558/T8023558a.java new file mode 100644 index 00000000000..205ff9eefdc --- /dev/null +++ b/langtools/test/tools/javac/lambda/8023558/T8023558a.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013, 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 8023558 + * @summary Javac creates invalid bootstrap methods for complex lambda/methodref case + */ +public class T8023558a { + interface SAM { + T get(); + } + + public static void main(String[] args) { + SAM sam = new SAM() { public SAM get() { return null; } }; + SAM temp = sam.get()::get; + } +} diff --git a/langtools/test/tools/javac/lambda/8023558/T8023558b.java b/langtools/test/tools/javac/lambda/8023558/T8023558b.java new file mode 100644 index 00000000000..c4fe72894e3 --- /dev/null +++ b/langtools/test/tools/javac/lambda/8023558/T8023558b.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013, 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 8023558 + * @summary Javac creates invalid bootstrap methods for complex lambda/methodref case + */ +public class T8023558b { + + interface Supplier { + X get(); + } + + static class A { + public A(Supplier supplier) { } + } + + static class B { } + + static class C { + public B getB() { + return new B(); + } + } + + public static void main(String[] args) { + new T8023558b().test(T8023558b::getC); + } + + private static C getC() { + return new C(); + } + + public void test(Supplier supplier) { + new A(supplier.get()::getB); + } +} diff --git a/langtools/test/tools/javac/lambda/8023558/T8023558c.java b/langtools/test/tools/javac/lambda/8023558/T8023558c.java new file mode 100644 index 00000000000..32234178e3b --- /dev/null +++ b/langtools/test/tools/javac/lambda/8023558/T8023558c.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013, 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 8023558 + * @summary Javac creates invalid bootstrap methods for complex lambda/methodref case + */ + +interface SAM { + T get(); +} + +public class T8023558c { + public static void main(String[] args) { + SAM sam = () -> Object::new; + SAM temp = sam.get()::get; + } +} From bfe7c0bfc24b61d31ec87d3ebecb1aeec17c45f2 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Thu, 12 Sep 2013 14:53:44 -0700 Subject: [PATCH 0332/1294] 8024275: During CTW: assert(sig_bt[member_arg_pos] == T_OBJECT) failed: dispatch argument must be an object Reviewed-by: kvn, vlivanov --- .../src/share/vm/classfile/classLoader.cpp | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp index 35055b4cb41..0ab350d90f8 100644 --- a/hotspot/src/share/vm/classfile/classLoader.cpp +++ b/hotspot/src/share/vm/classfile/classLoader.cpp @@ -1319,6 +1319,25 @@ static void clear_pending_exception_if_not_oom(TRAPS) { // The CHECK at the caller will propagate the exception out } +/** + * Returns if the given method should be compiled when doing compile-the-world. + * + * TODO: This should be a private method in a CompileTheWorld class. + */ +static bool can_be_compiled(methodHandle m, int comp_level) { + assert(CompileTheWorld, "must be"); + + // It's not valid to compile a native wrapper for MethodHandle methods + // that take a MemberName appendix since the bytecode signature is not + // correct. + vmIntrinsics::ID iid = m->intrinsic_id(); + if (MethodHandles::is_signature_polymorphic(iid) && MethodHandles::has_member_arg(iid)) { + return false; + } + + return CompilationPolicy::can_be_compiled(m, comp_level); +} + void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { int len = (int)strlen(name); if (len > 6 && strcmp(".class", name + len - 6) == 0) { @@ -1362,8 +1381,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { int comp_level = CompilationPolicy::policy()->initial_compile_level(); for (int n = 0; n < k->methods()->length(); n++) { methodHandle m (THREAD, k->methods()->at(n)); - if (CompilationPolicy::can_be_compiled(m, comp_level)) { - + if (can_be_compiled(m, comp_level)) { if (++_codecache_sweep_counter == CompileTheWorldSafepointInterval) { // Give sweeper a chance to keep up with CTW VM_ForceSafepoint op; @@ -1375,7 +1393,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { methodHandle(), 0, "CTW", THREAD); if (HAS_PENDING_EXCEPTION) { clear_pending_exception_if_not_oom(CHECK); - tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string()); + tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string()); } else { _compile_the_world_method_counter++; } @@ -1391,11 +1409,13 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { methodHandle(), 0, "CTW", THREAD); if (HAS_PENDING_EXCEPTION) { clear_pending_exception_if_not_oom(CHECK); - tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string()); + tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string()); } else { _compile_the_world_method_counter++; } } + } else { + tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string()); } nmethod* nm = m->code(); From d2d4036f85983c026b380005526361567c5f4455 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 13 Sep 2013 22:21:06 +0200 Subject: [PATCH 0333/1294] 8024651: Remove the incorrect usage of Metablock::overhead() Reviewed-by: brutisso, mgerdin, coleenp, jmasa --- hotspot/src/share/vm/memory/metablock.cpp | 7 ------- hotspot/src/share/vm/memory/metablock.hpp | 2 -- hotspot/src/share/vm/memory/metaspace.cpp | 4 +--- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/hotspot/src/share/vm/memory/metablock.cpp b/hotspot/src/share/vm/memory/metablock.cpp index 450d2c3193d..b6c6947e1ac 100644 --- a/hotspot/src/share/vm/memory/metablock.cpp +++ b/hotspot/src/share/vm/memory/metablock.cpp @@ -50,13 +50,6 @@ // Chunks, change Chunks so that they can be allocated out of a VirtualSpace. size_t Metablock::_min_block_byte_size = sizeof(Metablock); -#ifdef ASSERT -size_t Metablock::_overhead = - Chunk::aligned_overhead_size(sizeof(Metablock)) / BytesPerWord; -#else -size_t Metablock::_overhead = 0; -#endif - // New blocks returned by the Metaspace are zero initialized. // We should fix the constructors to not assume this instead. Metablock* Metablock::initialize(MetaWord* p, size_t word_size) { diff --git a/hotspot/src/share/vm/memory/metablock.hpp b/hotspot/src/share/vm/memory/metablock.hpp index 220d3614818..fa4c6c0b445 100644 --- a/hotspot/src/share/vm/memory/metablock.hpp +++ b/hotspot/src/share/vm/memory/metablock.hpp @@ -48,7 +48,6 @@ class Metablock VALUE_OBJ_CLASS_SPEC { } _header; } _block; static size_t _min_block_byte_size; - static size_t _overhead; typedef union block_t Block; typedef struct header_t Header; @@ -73,7 +72,6 @@ class Metablock VALUE_OBJ_CLASS_SPEC { void set_prev(Metablock* v) { _block._header._prev = v; } static size_t min_block_byte_size() { return _min_block_byte_size; } - static size_t overhead() { return _overhead; } bool is_free() { return header()->_word_size != 0; } void clear_next() { set_next(NULL); } diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 1dd97842eb4..9d7834a56fb 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -737,9 +737,7 @@ class SpaceManager : public CHeapObj { // MinChunkSize is a placeholder for the real minimum size JJJ size_t byte_size = word_size * BytesPerWord; - size_t byte_size_with_overhead = byte_size + Metablock::overhead(); - - size_t raw_bytes_size = MAX2(byte_size_with_overhead, + size_t raw_bytes_size = MAX2(byte_size, Metablock::min_block_byte_size()); raw_bytes_size = ARENA_ALIGN(raw_bytes_size); size_t raw_word_size = raw_bytes_size / BytesPerWord; From 860b5dcec78c71f5ad307b0732b2e23c38be82c7 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 13 Sep 2013 22:22:14 +0200 Subject: [PATCH 0334/1294] 8024650: Don't adjust MaxMetaspaceSize up to MetaspaceSize Reviewed-by: jwilhelm, brutisso, tschatzl --- .../parallelScavenge/generationSizer.hpp | 5 +- .../src/share/vm/memory/collectorPolicy.cpp | 31 +++-- .../gc/metaspace/TestMetaspaceSizeFlags.java | 108 ++++++++++++++++++ .../test/testlibrary/OutputAnalyzerTest.java | 17 +++ .../java/testlibrary/OutputAnalyzer.java | 35 +++++- 5 files changed, 180 insertions(+), 16 deletions(-) create mode 100644 hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp index b4b8c1ae9bb..e5637687e84 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,9 +68,6 @@ class GenerationSizer : public TwoGenerationCollectorPolicy { size_t min_old_gen_size() { return _min_gen1_size; } size_t old_gen_size() { return _initial_gen1_size; } size_t max_old_gen_size() { return _max_gen1_size; } - - size_t metaspace_size() { return MetaspaceSize; } - size_t max_metaspace_size() { return MaxMetaspaceSize; } }; #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GENERATIONSIZER_HPP diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index a5b4aa61894..0728997b769 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -47,6 +47,11 @@ // CollectorPolicy methods. +// Align down. If the aligning result in 0, return 'alignment'. +static size_t restricted_align_down(size_t size, size_t alignment) { + return MAX2(alignment, align_size_down_(size, alignment)); +} + void CollectorPolicy::initialize_flags() { assert(max_alignment() >= min_alignment(), err_msg("max_alignment: " SIZE_FORMAT " less than min_alignment: " SIZE_FORMAT, @@ -59,18 +64,24 @@ void CollectorPolicy::initialize_flags() { vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified"); } - if (MetaspaceSize > MaxMetaspaceSize) { - MaxMetaspaceSize = MetaspaceSize; - } - MetaspaceSize = MAX2(min_alignment(), align_size_down_(MetaspaceSize, min_alignment())); - // Don't increase Metaspace size limit above specified. - MaxMetaspaceSize = align_size_down(MaxMetaspaceSize, max_alignment()); - if (MetaspaceSize > MaxMetaspaceSize) { - MetaspaceSize = MaxMetaspaceSize; + if (!is_size_aligned(MaxMetaspaceSize, max_alignment())) { + FLAG_SET_ERGO(uintx, MaxMetaspaceSize, + restricted_align_down(MaxMetaspaceSize, max_alignment())); } - MinMetaspaceExpansion = MAX2(min_alignment(), align_size_down_(MinMetaspaceExpansion, min_alignment())); - MaxMetaspaceExpansion = MAX2(min_alignment(), align_size_down_(MaxMetaspaceExpansion, min_alignment())); + if (MetaspaceSize > MaxMetaspaceSize) { + FLAG_SET_ERGO(uintx, MetaspaceSize, MaxMetaspaceSize); + } + + if (!is_size_aligned(MetaspaceSize, min_alignment())) { + FLAG_SET_ERGO(uintx, MetaspaceSize, + restricted_align_down(MetaspaceSize, min_alignment())); + } + + assert(MetaspaceSize <= MaxMetaspaceSize, "Must be"); + + MinMetaspaceExpansion = restricted_align_down(MinMetaspaceExpansion, min_alignment()); + MaxMetaspaceExpansion = restricted_align_down(MaxMetaspaceExpansion, min_alignment()); MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, min_alignment()); diff --git a/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java b/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java new file mode 100644 index 00000000000..c67b8dc5ce9 --- /dev/null +++ b/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +/* + * @test TestMetaspaceSizeFlags + * @key gc + * @bug 8024650 + * @summary Test that metaspace size flags can be set correctly + * @library /testlibrary + */ +public class TestMetaspaceSizeFlags { + public static final long K = 1024L; + public static final long M = 1024L * K; + + // HotSpot uses a number of different values to align memory size flags. + // This is currently the largest alignment (unless huge large pages are used). + public static final long MAX_ALIGNMENT = 32 * M; + + public static void main(String [] args) throws Exception { + testMaxMetaspaceSizeEQMetaspaceSize(MAX_ALIGNMENT, MAX_ALIGNMENT); + // 8024650: MaxMetaspaceSize was adjusted instead of MetaspaceSize. + testMaxMetaspaceSizeLTMetaspaceSize(MAX_ALIGNMENT, MAX_ALIGNMENT * 2); + testMaxMetaspaceSizeGTMetaspaceSize(MAX_ALIGNMENT * 2, MAX_ALIGNMENT); + testTooSmallInitialMetaspace(0, 0); + testTooSmallInitialMetaspace(0, MAX_ALIGNMENT); + testTooSmallInitialMetaspace(MAX_ALIGNMENT, 0); + } + + private static void testMaxMetaspaceSizeEQMetaspaceSize(long maxMetaspaceSize, long metaspaceSize) throws Exception { + MetaspaceFlags mf = runAndGetValue(maxMetaspaceSize, metaspaceSize); + Asserts.assertEQ(maxMetaspaceSize, metaspaceSize); + Asserts.assertEQ(mf.maxMetaspaceSize, maxMetaspaceSize); + Asserts.assertEQ(mf.metaspaceSize, metaspaceSize); + } + + private static void testMaxMetaspaceSizeLTMetaspaceSize(long maxMetaspaceSize, long metaspaceSize) throws Exception { + MetaspaceFlags mf = runAndGetValue(maxMetaspaceSize, metaspaceSize); + Asserts.assertEQ(mf.maxMetaspaceSize, maxMetaspaceSize); + Asserts.assertEQ(mf.metaspaceSize, maxMetaspaceSize); + } + + private static void testMaxMetaspaceSizeGTMetaspaceSize(long maxMetaspaceSize, long metaspaceSize) throws Exception { + MetaspaceFlags mf = runAndGetValue(maxMetaspaceSize, metaspaceSize); + Asserts.assertGT(maxMetaspaceSize, metaspaceSize); + Asserts.assertGT(mf.maxMetaspaceSize, mf.metaspaceSize); + Asserts.assertEQ(mf.maxMetaspaceSize, maxMetaspaceSize); + Asserts.assertEQ(mf.metaspaceSize, metaspaceSize); + } + + private static void testTooSmallInitialMetaspace(long maxMetaspaceSize, long metaspaceSize) throws Exception { + OutputAnalyzer output = run(maxMetaspaceSize, metaspaceSize); + output.shouldContain("Too small initial Metaspace size"); + } + + private static MetaspaceFlags runAndGetValue(long maxMetaspaceSize, long metaspaceSize) throws Exception { + OutputAnalyzer output = run(maxMetaspaceSize, metaspaceSize); + output.shouldNotMatch("Error occurred during initialization of VM\n.*"); + + String stringMaxMetaspaceSize = output.firstMatch(".* MaxMetaspaceSize .* := (\\d+).*", 1); + String stringMetaspaceSize = output.firstMatch(".* MetaspaceSize .* := (\\d+).*", 1); + + return new MetaspaceFlags(Long.parseLong(stringMaxMetaspaceSize), + Long.parseLong(stringMetaspaceSize)); + } + + private static OutputAnalyzer run(long maxMetaspaceSize, long metaspaceSize) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:MaxMetaspaceSize=" + maxMetaspaceSize, + "-XX:MetaspaceSize=" + metaspaceSize, + "-XX:-UseLargePages", // Prevent us from using 2GB large pages on solaris + sparc. + "-XX:+PrintFlagsFinal", + "-version"); + return new OutputAnalyzer(pb.start()); + } + + private static class MetaspaceFlags { + public long maxMetaspaceSize; + public long metaspaceSize; + public MetaspaceFlags(long maxMetaspaceSize, long metaspaceSize) { + this.maxMetaspaceSize = maxMetaspaceSize; + this.metaspaceSize = metaspaceSize; + } + } +} diff --git a/hotspot/test/testlibrary/OutputAnalyzerTest.java b/hotspot/test/testlibrary/OutputAnalyzerTest.java index 6117e9000bd..2fd677783a8 100644 --- a/hotspot/test/testlibrary/OutputAnalyzerTest.java +++ b/hotspot/test/testlibrary/OutputAnalyzerTest.java @@ -172,5 +172,22 @@ public class OutputAnalyzerTest { } catch (RuntimeException e) { // expected } + + { + String aaaa = "aaaa"; + String result = output.firstMatch(aaaa); + if (!aaaa.equals(result)) { + throw new Exception("firstMatch(String) faild to match. Expected: " + aaaa + " got: " + result); + } + } + + { + String aa = "aa"; + String aa_grouped_aa = aa + "(" + aa + ")"; + String result = output.firstMatch(aa_grouped_aa, 1); + if (!aa.equals(result)) { + throw new Exception("firstMatch(String, int) failed to match. Expected: " + aa + " got: " + result); + } + } } } diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java index b9e37128d23..73b65165e91 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java @@ -211,13 +211,13 @@ public final class OutputAnalyzer { if (matcher.find()) { reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' found in stdout \n"); + + "' found in stdout: '" + matcher.group() + "' \n"); } matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); if (matcher.find()) { reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' found in stderr \n"); + + "' found in stderr: '" + matcher.group() + "' \n"); } } @@ -253,6 +253,37 @@ public final class OutputAnalyzer { } } + /** + * Get the captured group of the first string matching the pattern. + * stderr is searched before stdout. + * + * @param pattern The multi-line pattern to match + * @param group The group to capture + * @return The matched string or null if no match was found + */ + public String firstMatch(String pattern, int group) { + Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); + Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); + if (stderrMatcher.find()) { + return stderrMatcher.group(group); + } + if (stdoutMatcher.find()) { + return stdoutMatcher.group(group); + } + return null; + } + + /** + * Get the first string matching the pattern. + * stderr is searched before stdout. + * + * @param pattern The multi-line pattern to match + * @return The matched string or null if no match was found + */ + public String firstMatch(String pattern) { + return firstMatch(pattern, 0); + } + /** * Verify the exit value of the process * From 9784317e8a91e5642c9128c05d78dcd4e1e80f5d Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 13 Sep 2013 22:23:48 +0200 Subject: [PATCH 0335/1294] 8024751: Fix bugs in TraceMetadata Reviewed-by: jmasa, brutisso --- hotspot/src/share/vm/memory/metaspace.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 9d7834a56fb..9b73b6303aa 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -2366,10 +2366,10 @@ Metachunk* SpaceManager::get_new_chunk(size_t word_size, grow_chunks_by_words, medium_chunk_bunch()); - if (TraceMetadataHumongousAllocation && + if (TraceMetadataHumongousAllocation && next != NULL && SpaceManager::is_humongous(next->word_size())) { - gclog_or_tty->print_cr(" new humongous chunk word size " PTR_FORMAT, - next->word_size()); + gclog_or_tty->print_cr(" new humongous chunk word size " + PTR_FORMAT, next->word_size()); } return next; @@ -2487,9 +2487,6 @@ void SpaceManager::dump(outputStream* const out) const { curr = curr->next()) { out->print("%d) ", i++); curr->print_on(out); - if (TraceMetadataChunkAllocation && Verbose) { - block_freelists()->print_on(out); - } curr_total += curr->word_size(); used += curr->used_word_size(); capacity += curr->capacity_word_size(); @@ -2497,6 +2494,10 @@ void SpaceManager::dump(outputStream* const out) const { } } + if (TraceMetadataChunkAllocation && Verbose) { + block_freelists()->print_on(out); + } + size_t free = current_chunk() == NULL ? 0 : current_chunk()->free_word_size(); // Free space isn't wasted. waste -= free; From 4d3c6221b785cb307770a5113160babe21e6e999 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 13 Sep 2013 22:25:27 +0200 Subject: [PATCH 0336/1294] 8024752: Log TraceMetadata* output to gclog_or_tty instead of tty Reviewed-by: brutisso, mgerdin, coleenp --- hotspot/src/share/vm/memory/metaspace.cpp | 38 +++++++++---------- hotspot/src/share/vm/runtime/virtualspace.cpp | 19 ++++++---- hotspot/src/share/vm/runtime/virtualspace.hpp | 3 +- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 9b73b6303aa..c12c0b8637b 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -881,9 +881,9 @@ Metachunk* VirtualSpaceNode::take_from_committed(size_t chunk_word_size) { if (!is_available(chunk_word_size)) { if (TraceMetadataChunkAllocation) { - tty->print("VirtualSpaceNode::take_from_committed() not available %d words ", chunk_word_size); + gclog_or_tty->print("VirtualSpaceNode::take_from_committed() not available %d words ", chunk_word_size); // Dump some information about the virtual space that is nearly full - print_on(tty); + print_on(gclog_or_tty); } return NULL; } @@ -904,7 +904,7 @@ bool VirtualSpaceNode::expand_by(size_t words, bool pre_touch) { if (TraceMetavirtualspaceAllocation && !result) { gclog_or_tty->print_cr("VirtualSpaceNode::expand_by() failed " "for byte size " SIZE_FORMAT, bytes); - virtual_space()->print(); + virtual_space()->print_on(gclog_or_tty); } return result; } @@ -1173,7 +1173,7 @@ void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry) { #endif if (TraceMetavirtualspaceAllocation && Verbose) { VirtualSpaceNode* vsl = current_virtual_space(); - vsl->print_on(tty); + vsl->print_on(gclog_or_tty); } } @@ -1733,9 +1733,9 @@ void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) { assert_lock_strong(SpaceManager::expand_lock()); slow_locked_verify(); if (TraceMetadataChunkAllocation) { - tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk " - PTR_FORMAT " size " SIZE_FORMAT, - chunk, chunk->word_size()); + gclog_or_tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk " + PTR_FORMAT " size " SIZE_FORMAT, + chunk, chunk->word_size()); } free_chunks_put(chunk); } @@ -1764,9 +1764,9 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { dec_free_chunks_total(chunk->capacity_word_size()); if (TraceMetadataChunkAllocation && Verbose) { - tty->print_cr("ChunkManager::free_chunks_get: free_list " - PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT, - free_list, chunk, chunk->word_size()); + gclog_or_tty->print_cr("ChunkManager::free_chunks_get: free_list " + PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT, + free_list, chunk, chunk->word_size()); } } else { chunk = humongous_dictionary()->get_chunk( @@ -1776,10 +1776,10 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { if (chunk != NULL) { if (TraceMetadataHumongousAllocation) { size_t waste = chunk->word_size() - word_size; - tty->print_cr("Free list allocate humongous chunk size " SIZE_FORMAT - " for requested size " SIZE_FORMAT - " waste " SIZE_FORMAT, - chunk->word_size(), word_size, waste); + gclog_or_tty->print_cr("Free list allocate humongous chunk size " + SIZE_FORMAT " for requested size " SIZE_FORMAT + " waste " SIZE_FORMAT, + chunk->word_size(), word_size, waste); } // Chunk is being removed from the chunks free list. dec_free_chunks_total(chunk->capacity_word_size()); @@ -1821,10 +1821,10 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { } else { list_count = humongous_dictionary()->total_count(); } - tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk " - PTR_FORMAT " size " SIZE_FORMAT " count " SIZE_FORMAT " ", - this, chunk, chunk->word_size(), list_count); - locked_print_free_chunks(tty); + gclog_or_tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk " + PTR_FORMAT " size " SIZE_FORMAT " count " SIZE_FORMAT " ", + this, chunk, chunk->word_size(), list_count); + locked_print_free_chunks(gclog_or_tty); } return chunk; @@ -2344,7 +2344,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { sum_count_in_chunks_in_use()); new_chunk->print_on(gclog_or_tty); if (vs_list() != NULL) { - vs_list()->chunk_manager()->locked_print_free_chunks(tty); + vs_list()->chunk_manager()->locked_print_free_chunks(gclog_or_tty); } } } diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp index b7724a6a082..98ee7635002 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.cpp +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp @@ -754,16 +754,19 @@ void VirtualSpace::check_for_contiguity() { assert(high() <= upper_high(), "upper high"); } -void VirtualSpace::print() { - tty->print ("Virtual space:"); - if (special()) tty->print(" (pinned in memory)"); - tty->cr(); - tty->print_cr(" - committed: " SIZE_FORMAT, committed_size()); - tty->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); - tty->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high()); - tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); +void VirtualSpace::print_on(outputStream* out) { + out->print ("Virtual space:"); + if (special()) out->print(" (pinned in memory)"); + out->cr(); + out->print_cr(" - committed: " SIZE_FORMAT, committed_size()); + out->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); + out->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high()); + out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); } +void VirtualSpace::print() { + print_on(tty); +} /////////////// Unit tests /////////////// diff --git a/hotspot/src/share/vm/runtime/virtualspace.hpp b/hotspot/src/share/vm/runtime/virtualspace.hpp index 938a71a4a43..02b14734a00 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.hpp +++ b/hotspot/src/share/vm/runtime/virtualspace.hpp @@ -203,7 +203,8 @@ class VirtualSpace VALUE_OBJ_CLASS_SPEC { void check_for_contiguity() PRODUCT_RETURN; // Debugging - void print() PRODUCT_RETURN; + void print_on(outputStream* out) PRODUCT_RETURN; + void print(); }; #endif // SHARE_VM_RUNTIME_VIRTUALSPACE_HPP From 403a37663ac616a849f35d855519d84c134ff46a Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Fri, 13 Sep 2013 07:57:13 +0200 Subject: [PATCH 0337/1294] 8024671: G1 generates assert error messages in product builds Reviewed-by: brutisso, tschatzl --- .../share/vm/gc_implementation/g1/g1CardCounts.cpp | 4 ++-- .../share/vm/gc_implementation/g1/g1CardCounts.hpp | 14 +++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp index f75e518facc..31972bf3c4e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp @@ -33,8 +33,8 @@ void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) { if (has_count_table()) { - check_card_num(from_card_num, - err_msg("from card num out of range: "SIZE_FORMAT, from_card_num)); + assert(from_card_num >= 0 && from_card_num < _committed_max_card_num, + err_msg("from card num out of range: "SIZE_FORMAT, from_card_num)); assert(from_card_num < to_card_num, err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT, from_card_num, to_card_num)); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp index fd516c0b90e..129b3b0d232 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp @@ -72,25 +72,21 @@ class G1CardCounts: public CHeapObj { return has_reserved_count_table() && _committed_max_card_num > 0; } - void check_card_num(size_t card_num, const char* msg) { - assert(card_num >= 0 && card_num < _committed_max_card_num, msg); - } - size_t ptr_2_card_num(const jbyte* card_ptr) { assert(card_ptr >= _ct_bot, - err_msg("Inavalied card pointer: " + err_msg("Invalid card pointer: " "card_ptr: " PTR_FORMAT ", " "_ct_bot: " PTR_FORMAT, card_ptr, _ct_bot)); size_t card_num = pointer_delta(card_ptr, _ct_bot, sizeof(jbyte)); - check_card_num(card_num, - err_msg("card pointer out of range: " PTR_FORMAT, card_ptr)); + assert(card_num >= 0 && card_num < _committed_max_card_num, + err_msg("card pointer out of range: " PTR_FORMAT, card_ptr)); return card_num; } jbyte* card_num_2_ptr(size_t card_num) { - check_card_num(card_num, - err_msg("card num out of range: "SIZE_FORMAT, card_num)); + assert(card_num >= 0 && card_num < _committed_max_card_num, + err_msg("card num out of range: "SIZE_FORMAT, card_num)); return (jbyte*) (_ct_bot + card_num); } From f8f4e382cf66fbf5b75a9870a1d54fd49231d0b8 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 13 Sep 2013 00:25:19 -0700 Subject: [PATCH 0338/1294] Added tag hs25-b50 for changeset 8292c62817e4 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 8d3f958c431..370ade6688d 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -376,3 +376,4 @@ acac3bde66b2c22791c257a8d99611d6d08c6713 jdk8-b105 aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106 50794d8ac11c9579b41dec4de23b808fef9f34a1 hs25-b49 5b7f90aab3ad25a25b75b7b2bb18d5ae23d8231c jdk8-b107 +a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50 From 4bc9598f85d15b28077287f8d33fda0e84830cb1 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 13 Sep 2013 00:43:01 -0700 Subject: [PATCH 0339/1294] 8024764: new hotspot build - hs25-b51 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index e1572121149..fa4d6554e16 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=50 +HS_BUILD_NUMBER=51 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From 295225d57e61ce41afa4e2e9b1b7f6670b948cbb Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Fri, 13 Sep 2013 11:58:39 +0400 Subject: [PATCH 0340/1294] 8024170: [SwingNode] Implement cursor change Reviewed-by: anthony, ant --- .../sun/lwawt/LWLightweightFramePeer.java | 12 ++++---- .../classes/sun/swing/JLightweightFrame.java | 30 ++++++++++++++++++- .../classes/sun/swing/LightweightContent.java | 8 +++++ .../classes/sun/swing/SwingAccessor.java | 29 ++++++++++++++++++ .../sun/awt/X11/XLightweightFramePeer.java | 7 +++++ .../sun/awt/windows/WComponentPeer.java | 2 +- .../awt/windows/WLightweightFramePeer.java | 7 +++++ 7 files changed, 88 insertions(+), 7 deletions(-) diff --git a/jdk/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java b/jdk/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java index 90e2e88c441..624be6bfc10 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java @@ -34,6 +34,8 @@ import java.awt.dnd.DropTarget; import sun.awt.CausedFocusEvent; import sun.awt.LightweightFrame; +import sun.swing.JLightweightFrame; +import sun.swing.SwingAccessor; public class LWLightweightFramePeer extends LWWindowPeer { @@ -90,11 +92,6 @@ public class LWLightweightFramePeer extends LWWindowPeer { setBounds(x, y, w, h, op, true, false); } - @Override - public void updateCursorImmediately() { - // TODO: tries to switch to the awt/fx toolkit thread and causes a deadlock on macosx - } - @Override public void addDropTarget(DropTarget dt) { } @@ -112,4 +109,9 @@ public class LWLightweightFramePeer extends LWWindowPeer { public void ungrab() { getLwTarget().ungrabFocus(); } + + @Override + public void updateCursorImmediately() { + SwingAccessor.getJLightweightFrameAccessor().updateCursor((JLightweightFrame)getLwTarget()); + } } diff --git a/jdk/src/share/classes/sun/swing/JLightweightFrame.java b/jdk/src/share/classes/sun/swing/JLightweightFrame.java index 36bb1c351b7..e9a655309e2 100644 --- a/jdk/src/share/classes/sun/swing/JLightweightFrame.java +++ b/jdk/src/share/classes/sun/swing/JLightweightFrame.java @@ -33,8 +33,9 @@ import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.MouseInfo; +import java.awt.Point; import java.awt.Rectangle; -import java.awt.event.ComponentListener; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; import java.awt.image.BufferedImage; @@ -48,6 +49,7 @@ import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.LayoutFocusTraversalPolicy; import javax.swing.RootPaneContainer; +import javax.swing.SwingUtilities; import sun.awt.LightweightFrame; import sun.security.action.GetPropertyAction; @@ -88,6 +90,15 @@ public final class JLightweightFrame extends LightweightFrame implements RootPan private PropertyChangeListener layoutSizeListener; + static { + SwingAccessor.setJLightweightFrameAccessor(new SwingAccessor.JLightweightFrameAccessor() { + @Override + public void updateCursor(JLightweightFrame frame) { + frame.updateClientCursor(); + } + }); + } + /** * Constructs a new, initially invisible {@code JLightweightFrame} * instance. @@ -358,4 +369,21 @@ public final class JLightweightFrame extends LightweightFrame implements RootPan public Component getGlassPane() { return getRootPane().getGlassPane(); } + + + /* + * Notifies client toolkit that it should change a cursor. + * + * Called from the peer via SwingAccessor, because the + * Component.updateCursorImmediately method is final + * and could not be overridden. + */ + private void updateClientCursor() { + Point p = MouseInfo.getPointerInfo().getLocation(); + SwingUtilities.convertPointFromScreen(p, this); + Component target = SwingUtilities.getDeepestComponentAt(this, p.x, p.y); + if (target != null) { + content.setCursor(target.getCursor()); + } + } } diff --git a/jdk/src/share/classes/sun/swing/LightweightContent.java b/jdk/src/share/classes/sun/swing/LightweightContent.java index 256262dded1..dd3373aea1a 100644 --- a/jdk/src/share/classes/sun/swing/LightweightContent.java +++ b/jdk/src/share/classes/sun/swing/LightweightContent.java @@ -26,6 +26,7 @@ package sun.swing; import javax.swing.JComponent; +import java.awt.Cursor; /** * The interface by means of which the {@link JLightweightFrame} class @@ -179,4 +180,11 @@ public interface LightweightContent { * application that the content minimum size has changed. */ public void minimumSizeChanged(int width, int height); + + /** + * {@code JLightweightFrame} calls this method to notify the client + * application that in needs to set a cursor + * @param cursor a cursor to set + */ + default public void setCursor(Cursor cursor) { } } diff --git a/jdk/src/share/classes/sun/swing/SwingAccessor.java b/jdk/src/share/classes/sun/swing/SwingAccessor.java index 7e5100df6b7..72d15f41bd0 100644 --- a/jdk/src/share/classes/sun/swing/SwingAccessor.java +++ b/jdk/src/share/classes/sun/swing/SwingAccessor.java @@ -71,6 +71,16 @@ public final class SwingAccessor { Object state, boolean forDrop); } + /** + * An accessor for the JLightweightFrame class. + */ + public interface JLightweightFrameAccessor { + /** + * Notifies the JLightweight frame that it needs to update a cursor + */ + void updateCursor(JLightweightFrame frame); + } + /** * The javax.swing.text.JTextComponent class accessor object. */ @@ -93,4 +103,23 @@ public final class SwingAccessor { return jtextComponentAccessor; } + + /** + * The JLightweightFrame class accessor object + */ + private static JLightweightFrameAccessor jLightweightFrameAccessor; + + /** + * Set an accessor object for the JLightweightFrame class. + */ + public static void setJLightweightFrameAccessor(JLightweightFrameAccessor accessor) { + jLightweightFrameAccessor = accessor; + } + + /** + * Retrieve the accessor object for the JLightweightFrame class + */ + public static JLightweightFrameAccessor getJLightweightFrameAccessor() { + return jLightweightFrameAccessor; + } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java b/jdk/src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java index 6292482acdf..49d48c806ae 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java @@ -28,6 +28,8 @@ package sun.awt.X11; import java.awt.Graphics; import sun.awt.LightweightFrame; +import sun.swing.JLightweightFrame; +import sun.swing.SwingAccessor; public class XLightweightFramePeer extends XFramePeer { @@ -62,4 +64,9 @@ public class XLightweightFramePeer extends XFramePeer { getLwTarget().ungrabFocus(); } } + + @Override + public void updateCursorImmediately() { + SwingAccessor.getJLightweightFrameAccessor().updateCursor((JLightweightFrame)getLwTarget()); + } } diff --git a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java index db62ab477ed..da4135ec033 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java @@ -656,7 +656,7 @@ public abstract class WComponentPeer extends WObjectPeer _setFont(f); } public synchronized native void _setFont(Font f); - public final void updateCursorImmediately() { + public void updateCursorImmediately() { WGlobalCursorManager.getCursorManager().updateCursorImmediately(); } diff --git a/jdk/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java b/jdk/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java index c2c1604bef4..ae5afdc56e7 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java @@ -31,6 +31,8 @@ import java.awt.event.ComponentEvent; import java.awt.event.MouseEvent; import sun.awt.LightweightFrame; +import sun.swing.JLightweightFrame; +import sun.swing.SwingAccessor; public class WLightweightFramePeer extends WFramePeer { @@ -83,4 +85,9 @@ public class WLightweightFramePeer extends WFramePeer { public void ungrab() { getLwTarget().ungrabFocus(); } + + @Override + public void updateCursorImmediately() { + SwingAccessor.getJLightweightFrameAccessor().updateCursor((JLightweightFrame)getLwTarget()); + } } From d477f2800d171cbf34b92d0a8c82630017122a10 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Fri, 13 Sep 2013 13:07:02 +0200 Subject: [PATCH 0341/1294] 8024620: config.log does not end up in corresponding configuration Reviewed-by: erikj --- common/autoconf/configure | 5 ----- common/autoconf/configure.ac | 6 ++++++ common/autoconf/generated-configure.sh | 8 +++++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/common/autoconf/configure b/common/autoconf/configure index 8e4560df114..7378efe379d 100644 --- a/common/autoconf/configure +++ b/common/autoconf/configure @@ -219,9 +219,4 @@ else echo configure exiting with result code $conf_result_code fi -# Move the log file to the output root, if this was successfully created -if test -d "$OUTPUT_ROOT"; then - mv -f config.log "$OUTPUT_ROOT" 2> /dev/null -fi - exit $conf_result_code diff --git a/common/autoconf/configure.ac b/common/autoconf/configure.ac index 274f278fb3d..ad8bd97cea3 100644 --- a/common/autoconf/configure.ac +++ b/common/autoconf/configure.ac @@ -232,9 +232,15 @@ CUSTOM_LATE_HOOK # We're messing a bit with internal autoconf variables to put the config.status # in the output directory instead of the current directory. CONFIG_STATUS="$OUTPUT_ROOT/config.status" + # Create the actual output files. Now the main work of configure is done. AC_OUTPUT +# Try to move the config.log file to the output directory. +if test -e ./config.log; then + $MV -f ./config.log "$OUTPUT_ROOT/config.log" 2> /dev/null +fi + # Make the compare script executable $CHMOD +x $OUTPUT_ROOT/compare.sh diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 84c38a67dba..f273159ba26 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -3806,7 +3806,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1378980507 +DATE_WHEN_GENERATED=1379070243 ############################################################################### # @@ -33186,6 +33186,7 @@ fi # We're messing a bit with internal autoconf variables to put the config.status # in the output directory instead of the current directory. CONFIG_STATUS="$OUTPUT_ROOT/config.status" + # Create the actual output files. Now the main work of configure is done. cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -34467,6 +34468,11 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi +# Try to move the config.log file to the output directory. +if test -e ./config.log; then + $MV -f ./config.log "$OUTPUT_ROOT/config.log" 2> /dev/null +fi + # Make the compare script executable $CHMOD +x $OUTPUT_ROOT/compare.sh From 8c226a62109922de0117159a19a16b7dbb855f07 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 13 Sep 2013 16:45:11 +0530 Subject: [PATCH 0342/1294] 8024619: JDBC java.sql.DriverManager is not usable from JS script Reviewed-by: jlaskey, lagergren, attila --- nashorn/make/build.xml | 5 ++ .../jdk/nashorn/internal/runtime/Context.java | 17 ++-- .../internal/runtime/NashornLoader.java | 30 +------ .../internal/runtime/ScriptLoader.java | 31 +++++++- .../internal/runtime/StructureLoader.java | 27 ++----- nashorn/test/script/basic/JDK-8024619.js | 46 +++++++++++ .../src/META-INF/services/java.sql.Driver | 1 + .../src/jdk/nashorn/api/NashornSQLDriver.java | 79 +++++++++++++++++++ 8 files changed, 177 insertions(+), 59 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8024619.js create mode 100644 nashorn/test/src/META-INF/services/java.sql.Driver create mode 100644 nashorn/test/src/jdk/nashorn/api/NashornSQLDriver.java diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml index df655d59e51..73644a6b523 100644 --- a/nashorn/make/build.xml +++ b/nashorn/make/build.xml @@ -230,6 +230,10 @@ + + + + @@ -238,6 +242,7 @@ + diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 4651b508721..7c69eb52035 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -236,6 +236,10 @@ public final class Context { private static final ClassLoader myLoader = Context.class.getClassLoader(); private static final StructureLoader sharedLoader; + /*package-private*/ ClassLoader getSharedLoader() { + return sharedLoader; + } + private static AccessControlContext createNoPermAccCtxt() { return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) }); } @@ -254,7 +258,7 @@ public final class Context { sharedLoader = AccessController.doPrivileged(new PrivilegedAction() { @Override public StructureLoader run() { - return new StructureLoader(myLoader, null); + return new StructureLoader(myLoader); } }, CREATE_LOADER_ACC_CTXT); } @@ -599,7 +603,7 @@ public final class Context { * @throws ClassNotFoundException if structure class cannot be resolved */ public static Class forStructureClass(final String fullName) throws ClassNotFoundException { - if (System.getSecurityManager() != null && !NashornLoader.isStructureClass(fullName)) { + if (System.getSecurityManager() != null && !StructureLoader.isStructureClass(fullName)) { throw new ClassNotFoundException(fullName); } return Class.forName(fullName, true, sharedLoader); @@ -792,12 +796,11 @@ public final class Context { static Context fromClass(final Class clazz) { final ClassLoader loader = clazz.getClassLoader(); - Context context = null; - if (loader instanceof NashornLoader) { - context = ((NashornLoader)loader).getContext(); + if (loader instanceof ScriptLoader) { + return ((ScriptLoader)loader).getContext(); } - return (context != null) ? context : Context.getContextTrusted(); + return Context.getContextTrusted(); } private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) { @@ -899,7 +902,7 @@ public final class Context { new PrivilegedAction() { @Override public ScriptLoader run() { - return new ScriptLoader(sharedLoader, Context.this); + return new ScriptLoader(appLoader, Context.this); } }, CREATE_LOADER_ACC_CTXT); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java index 4e349730451..e7837013f53 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java @@ -38,10 +38,7 @@ import java.security.SecureClassLoader; import jdk.nashorn.tools.Shell; /** - * Superclass for Nashorn class loader classes. This stores Context - * instance as an instance field. The current context can be - * efficiently accessed from a given Class via it's ClassLoader. - * + * Superclass for Nashorn class loader classes. */ abstract class NashornLoader extends SecureClassLoader { private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects"; @@ -69,27 +66,8 @@ abstract class NashornLoader extends SecureClassLoader { }; } - private final Context context; - - final Context getContext() { - return context; - } - - NashornLoader(final ClassLoader parent, final Context context) { + NashornLoader(final ClassLoader parent) { super(parent); - this.context = context; - } - - - /** - * Called by subclass after package access check is done - * @param name name of the class to be loaded - * @param resolve whether the class should be resolved or not - * @return Class object - * @throws ClassNotFoundException if class cannot be loaded - */ - protected final Class loadClassTrusted(final String name, final boolean resolve) throws ClassNotFoundException { - return super.loadClass(name, resolve); } protected static void checkPackageAccess(final String name) { @@ -122,10 +100,6 @@ abstract class NashornLoader extends SecureClassLoader { return permCollection; } - static boolean isStructureClass(final String fullName) { - return fullName.startsWith(SCRIPTS_PKG); - } - /** * Create a secure URL class loader for the given classpath * @param classPath classpath for the loader to search from diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java index 370faf312d0..736932ea318 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java @@ -33,17 +33,42 @@ import java.security.ProtectionDomain; * */ final class ScriptLoader extends NashornLoader { + private static final String NASHORN_PKG_PREFIX = "jdk.nashorn.internal."; + + private final Context context; + + /*package-private*/ Context getContext() { + return context; + } + /** * Constructor. */ - ScriptLoader(final StructureLoader parent, final Context context) { - super(parent, context); + ScriptLoader(final ClassLoader parent, final Context context) { + super(parent); + this.context = context; } @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { checkPackageAccess(name); - return super.loadClassTrusted(name, resolve); + try { + return super.loadClass(name, resolve); + } catch (final ClassNotFoundException | SecurityException e) { + // We'll get ClassNotFoundException for Nashorn 'struct' classes. + // Also, we'll get SecurityException for jdk.nashorn.internal.* + // classes. So, load these using to context's 'shared' loader. + // All these classes start with "jdk.nashorn.internal." prefix. + try { + if (name.startsWith(NASHORN_PKG_PREFIX)) { + return context.getSharedLoader().loadClass(name); + } + } catch (final ClassNotFoundException ignored) { + } + + // throw the original exception from here + throw e; + } } // package-private and private stuff below this point diff --git a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java index bdc40eddcc9..41201cde847 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java @@ -34,7 +34,6 @@ import jdk.nashorn.internal.codegen.ObjectClassGenerator; /** * Responsible for on the fly construction of structure classes. - * */ final class StructureLoader extends NashornLoader { private static final String JS_OBJECT_PREFIX_EXTERNAL = binaryName(SCRIPTS_PACKAGE) + '.' + JS_OBJECT_PREFIX.symbolName(); @@ -42,27 +41,17 @@ final class StructureLoader extends NashornLoader { /** * Constructor. */ - StructureLoader(final ClassLoader parent, final Context context) { - super(parent, context); + StructureLoader(final ClassLoader parent) { + super(parent); } - @Override - protected synchronized Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException { - // check the cache first - final Class loadedClass = findLoadedClass(name); - if (loadedClass != null) { - if (resolve) { - resolveClass(loadedClass); - } - return loadedClass; - } - - return super.loadClassTrusted(name, resolve); + static boolean isStructureClass(final String name) { + return name.startsWith(JS_OBJECT_PREFIX_EXTERNAL); } @Override protected Class findClass(final String name) throws ClassNotFoundException { - if (name.startsWith(JS_OBJECT_PREFIX_EXTERNAL)) { + if (isStructureClass(name)) { return generateClass(name, name.substring(JS_OBJECT_PREFIX_EXTERNAL.length())); } return super.findClass(name); @@ -75,11 +64,7 @@ final class StructureLoader extends NashornLoader { * @return Generated class. */ private Class generateClass(final String name, final String descriptor) { - Context context = getContext(); - - if (context == null) { - context = Context.getContextTrusted(); - } + final Context context = Context.getContextTrusted(); final byte[] code = new ObjectClassGenerator(context).generate(descriptor); return defineClass(name, code, 0, code.length, new ProtectionDomain(null, getPermissions(null))); diff --git a/nashorn/test/script/basic/JDK-8024619.js b/nashorn/test/script/basic/JDK-8024619.js new file mode 100644 index 00000000000..064e0d7b676 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024619.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024619: JDBC java.sql.DriverManager is not usable from JS script + * + * @test + * @run + */ + +var DriverManager = Java.type("java.sql.DriverManager"); +var e = DriverManager.getDrivers(); + +var driverFound = false; +// check for Nashorn SQL driver +while (e.hasMoreElements()) { + var driver = e.nextElement(); + if (driver.acceptsURL("jdbc:nashorn:")) { + driverFound = true; + break; + } +} + +if (! driverFound) { + fail("Nashorn JDBC Driver not found!"); +} diff --git a/nashorn/test/src/META-INF/services/java.sql.Driver b/nashorn/test/src/META-INF/services/java.sql.Driver new file mode 100644 index 00000000000..295fe48075f --- /dev/null +++ b/nashorn/test/src/META-INF/services/java.sql.Driver @@ -0,0 +1 @@ +jdk.nashorn.api.NashornSQLDriver diff --git a/nashorn/test/src/jdk/nashorn/api/NashornSQLDriver.java b/nashorn/test/src/jdk/nashorn/api/NashornSQLDriver.java new file mode 100644 index 00000000000..2987b948548 --- /dev/null +++ b/nashorn/test/src/jdk/nashorn/api/NashornSQLDriver.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api; + +import java.sql.*; +import java.util.Properties; +import java.util.logging.Logger; + +/** + * A dummy SQL driver for testing purpose. + */ +public final class NashornSQLDriver implements Driver { + static { + try { + DriverManager.registerDriver(new NashornSQLDriver(), null); + } catch (SQLException se) { + throw new RuntimeException(se); + } + } + + @Override + public boolean acceptsURL(String url) { + return url.startsWith("jdbc:nashorn:"); + } + + @Override + public Connection connect(String url, Properties info) { + throw new UnsupportedOperationException("I am a dummy!!"); + } + + @Override + public int getMajorVersion() { + return -1; + } + + @Override + public int getMinorVersion() { + return -1; + } + + @Override + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) { + return new DriverPropertyInfo[0]; + } + + @Override + public boolean jdbcCompliant() { + // no way! + return false; + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + throw new SQLFeatureNotSupportedException(); + } +} From 13d322d70fa5dba35976acaa7236fd23371352e0 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Fri, 13 Sep 2013 04:16:54 -0700 Subject: [PATCH 0343/1294] 8023134: Rename VM LogFile to hotspot_pid{pid}.log (was hotspot.log) Reviewed-by: twisti, kvn, sla --- hotspot/src/share/tools/LogCompilation/README | 6 ++-- hotspot/src/share/vm/runtime/arguments.cpp | 35 ++++++++++++++++++- .../src/share/vm/runtime/deoptimization.cpp | 4 +-- hotspot/src/share/vm/runtime/globals.hpp | 11 +++--- hotspot/src/share/vm/utilities/ostream.cpp | 7 ++-- 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/hotspot/src/share/tools/LogCompilation/README b/hotspot/src/share/tools/LogCompilation/README index 90dc3b893bb..aa18fe891f6 100644 --- a/hotspot/src/share/tools/LogCompilation/README +++ b/hotspot/src/share/tools/LogCompilation/README @@ -4,14 +4,14 @@ It's main purpose is to recreate output similar to requires a 1.5 JDK to build and simply typing make should build it. It produces a jar file, logc.jar, that can be run on the -hotspot.log from LogCompilation output like this: +HotSpot log (by default, hotspot_pid{pid}.log) from LogCompilation output like this: - java -jar logc.jar hotspot.log + java -jar logc.jar hotspot_pid1234.log This will produce something like the normal PrintCompilation output. Adding the -i option with also report inlining like PrintInlining. -More information about the LogCompilation output can be found at +More information about the LogCompilation output can be found at https://wikis.oracle.com/display/HotSpotInternals/LogCompilation+overview https://wikis.oracle.com/display/HotSpotInternals/PrintCompilation diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 1287e811496..b2627fea1d1 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -3337,6 +3337,33 @@ static char* get_shared_archive_path() { return shared_archive_path; } +#ifndef PRODUCT +// Determine whether LogVMOutput should be implicitly turned on. +static bool use_vm_log() { + if (LogCompilation || !FLAG_IS_DEFAULT(LogFile) || + PrintCompilation || PrintInlining || PrintDependencies || PrintNativeNMethods || + PrintDebugInfo || PrintRelocations || PrintNMethods || PrintExceptionHandlers || + PrintAssembly || TraceDeoptimization || TraceDependencies || + (VerifyDependencies && FLAG_IS_CMDLINE(VerifyDependencies))) { + return true; + } + +#ifdef COMPILER1 + if (PrintC1Statistics) { + return true; + } +#endif // COMPILER1 + +#ifdef COMPILER2 + if (PrintOptoAssembly || PrintOptoStatistics) { + return true; + } +#endif // COMPILER2 + + return false; +} +#endif // PRODUCT + // Parse entry point called from JNI_CreateJavaVM jint Arguments::parse(const JavaVMInitArgs* args) { @@ -3630,7 +3657,13 @@ jint Arguments::parse(const JavaVMInitArgs* args) { NmethodSweepFraction = 1; } } -#endif + + if (!LogVMOutput && FLAG_IS_DEFAULT(LogVMOutput)) { + if (use_vm_log()) { + LogVMOutput = true; + } + } +#endif // PRODUCT if (PrintCommandLineFlags) { CommandLineFlags::printSetFlags(tty); diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp index 7f71c2d8b76..007bfe7aa13 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.cpp +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp @@ -1751,7 +1751,7 @@ int Deoptimization::trap_state_set_recompiled(int trap_state, bool z) { else return trap_state & ~DS_RECOMPILE_BIT; } //---------------------------format_trap_state--------------------------------- -// This is used for debugging and diagnostics, including hotspot.log output. +// This is used for debugging and diagnostics, including LogFile output. const char* Deoptimization::format_trap_state(char* buf, size_t buflen, int trap_state) { DeoptReason reason = trap_state_reason(trap_state); @@ -1828,7 +1828,7 @@ const char* Deoptimization::trap_action_name(int action) { return buf; } -// This is used for debugging and diagnostics, including hotspot.log output. +// This is used for debugging and diagnostics, including LogFile output. const char* Deoptimization::format_trap_request(char* buf, size_t buflen, int trap_request) { jint unloaded_class_index = trap_request_index(trap_request); diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 7fdf668bac5..ed3e1e8ff5d 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -880,7 +880,7 @@ class CommandLineFlags { "stay alive at the expense of JVM performance") \ \ diagnostic(bool, LogCompilation, false, \ - "Log compilation activity in detail to hotspot.log or LogFile") \ + "Log compilation activity in detail to LogFile") \ \ product(bool, PrintCompilation, false, \ "Print compilations") \ @@ -2498,16 +2498,17 @@ class CommandLineFlags { "Print all VM flags with default values and descriptions and exit")\ \ diagnostic(bool, SerializeVMOutput, true, \ - "Use a mutex to serialize output to tty and hotspot.log") \ + "Use a mutex to serialize output to tty and LogFile") \ \ diagnostic(bool, DisplayVMOutput, true, \ "Display all VM output on the tty, independently of LogVMOutput") \ \ - diagnostic(bool, LogVMOutput, trueInDebug, \ - "Save VM output to hotspot.log, or to LogFile") \ + diagnostic(bool, LogVMOutput, false, \ + "Save VM output to LogFile") \ \ diagnostic(ccstr, LogFile, NULL, \ - "If LogVMOutput is on, save VM output to this file [hotspot.log]") \ + "If LogVMOutput or LogCompilation is on, save VM output to " \ + "this file [default: ./hotspot_pid%p.log] (%p replaced with pid)") \ \ product(ccstr, ErrorFile, NULL, \ "If an error occurs, save the error data to this file " \ diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp index 2f04fa0e437..90532078652 100644 --- a/hotspot/src/share/vm/utilities/ostream.cpp +++ b/hotspot/src/share/vm/utilities/ostream.cpp @@ -592,7 +592,7 @@ static const char* make_log_name(const char* log_name, const char* force_directo void defaultStream::init_log() { // %%% Need a MutexLocker? - const char* log_name = LogFile != NULL ? LogFile : "hotspot.log"; + const char* log_name = LogFile != NULL ? LogFile : "hotspot_pid%p.log"; const char* try_name = make_log_name(log_name, NULL); fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); if (!file->is_open()) { @@ -603,14 +603,15 @@ void defaultStream::init_log() { // Note: This feature is for maintainer use only. No need for L10N. jio_print(warnbuf); FREE_C_HEAP_ARRAY(char, try_name, mtInternal); - try_name = make_log_name("hs_pid%p.log", os::get_temp_directory()); + try_name = make_log_name(log_name, os::get_temp_directory()); jio_snprintf(warnbuf, sizeof(warnbuf), "Warning: Forcing option -XX:LogFile=%s\n", try_name); jio_print(warnbuf); delete file; file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); - FREE_C_HEAP_ARRAY(char, try_name, mtInternal); } + FREE_C_HEAP_ARRAY(char, try_name, mtInternal); + if (file->is_open()) { _log_file = file; xmlStream* xs = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file); From 767ab8c9ae5c20f2be376b3b49768d000d37d8ae Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Fri, 13 Sep 2013 12:20:53 +0100 Subject: [PATCH 0344/1294] 8024675: java/net/NetworkInterface/UniqueMacAddressesTest.java fails on Windows Amended test to add active, i.e. isUp(), NetworkInterfaces to test list Reviewed-by: alanb, chegar --- .../NetworkInterface/UniqueMacAddressesTest.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/jdk/test/java/net/NetworkInterface/UniqueMacAddressesTest.java b/jdk/test/java/net/NetworkInterface/UniqueMacAddressesTest.java index c2f5c495c73..4017c0702ed 100644 --- a/jdk/test/java/net/NetworkInterface/UniqueMacAddressesTest.java +++ b/jdk/test/java/net/NetworkInterface/UniqueMacAddressesTest.java @@ -118,11 +118,14 @@ public class UniqueMacAddressesTest { NetworkInterface netIf = null; while (nis.hasMoreElements()) { netIf = (NetworkInterface) nis.nextElement(); - macAddr = netIf.getHardwareAddress(); - if (macAddr != null) { - System.out - .println("Adding NetworkInterface " + netIf.getName()); - networkInterfaceList.add(netIf); + if (netIf.isUp()) { + macAddr = netIf.getHardwareAddress(); + if (macAddr != null) { + System.out.println("Adding NetworkInterface " + + netIf.getName() + " with mac address " + + createMacAddressString(netIf)); + networkInterfaceList.add(netIf); + } } } } From 3c2808598812d24e00b4a4eb7dc1ca13a9e43702 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Fri, 13 Sep 2013 14:59:23 +0200 Subject: [PATCH 0345/1294] 8024665: Move open changes for JDK-8020411 to closed source Reviewed-by: erikj --- common/autoconf/generated-configure.sh | 49 ++++++++++++++------------ common/autoconf/platform.m4 | 23 ++++++------ common/autoconf/spec.gmk.in | 1 - 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index f273159ba26..bc9d07da3f3 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -709,7 +709,6 @@ STATIC_LIBRARY SHARED_LIBRARY OBJ_SUFFIX COMPILER_NAME -TARGET_BITS_FLAG JT_HOME JTREGEXE LIPO @@ -3806,7 +3805,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1379070243 +DATE_WHEN_GENERATED=1379077060 ############################################################################### # @@ -28398,35 +28397,41 @@ done if test "x$OPENJDK_TARGET_OS" = xsolaris; then # Always specify -m flags on Solaris - # keep track of c/cxx flags that we added outselves... - # to prevent emitting warning... - TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" + # When we add flags to the "official" CFLAGS etc, we need to + # keep track of these additions in ADDED_CFLAGS etc. These + # will later be checked to make sure only controlled additions + # have been made to CFLAGS etc. + ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + CFLAGS="${CFLAGS}${ADDED_CFLAGS}" + CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}" + LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}" - CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}" - CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" - LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" - - CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}" - CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}" - LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}" + CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}" + CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}" + LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}" elif test "x$COMPILE_TYPE" = xreduced; then if test "x$OPENJDK_TARGET_OS" != xwindows; then # Specify -m if running reduced on other Posix platforms - # keep track of c/cxx flags that we added outselves... - # to prevent emitting warning... - TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" + # When we add flags to the "official" CFLAGS etc, we need to + # keep track of these additions in ADDED_CFLAGS etc. These + # will later be checked to make sure only controlled additions + # have been made to CFLAGS etc. + ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + CFLAGS="${CFLAGS}${ADDED_CFLAGS}" + CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}" + LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}" - CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}" - CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" - LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" - - CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}" - CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}" - LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}" + CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}" + CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}" + LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}" fi fi diff --git a/common/autoconf/platform.m4 b/common/autoconf/platform.m4 index 71ae2ceab7b..96c710d8a18 100644 --- a/common/autoconf/platform.m4 +++ b/common/autoconf/platform.m4 @@ -422,18 +422,21 @@ AC_SUBST(OS_VERSION_MICRO) # Add -mX to various FLAGS variables. AC_DEFUN([PLATFORM_SET_COMPILER_TARGET_BITS_FLAGS], [ - # keep track of c/cxx flags that we added outselves... - # to prevent emitting warning... - TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" - AC_SUBST(TARGET_BITS_FLAG) + # When we add flags to the "official" CFLAGS etc, we need to + # keep track of these additions in ADDED_CFLAGS etc. These + # will later be checked to make sure only controlled additions + # have been made to CFLAGS etc. + ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" - CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}" - CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" - LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" + CFLAGS="${CFLAGS}${ADDED_CFLAGS}" + CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}" + LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}" - CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}" - CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}" - LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}" + CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}" + CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}" + LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}" ]) AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_TARGET_BITS], diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index d44b3c8c973..7e186693700 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -300,7 +300,6 @@ MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@ COMPILER_TYPE:=@COMPILER_TYPE@ COMPILER_NAME:=@COMPILER_NAME@ -TARGET_BITS_FLAG=@TARGET_BITS_FLAG@ COMPILER_SUPPORTS_TARGET_BITS_FLAG=@COMPILER_SUPPORTS_TARGET_BITS_FLAG@ CC_OUT_OPTION:=@CC_OUT_OPTION@ From 0960c5ec562343dcf6929cb1cae83cb6e5fb2c13 Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Fri, 13 Sep 2013 17:25:31 +0400 Subject: [PATCH 0346/1294] 8015453: java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java failed on windows with jdk8 since b86 Reviewed-by: art, serb --- .../classes/sun/awt/datatransfer/DataTransferer.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java index 83a73dbd51c..493d80a4c82 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -1765,7 +1765,14 @@ search: Reader reader = new InputStreamReader(is, unicode); theObject = constructFlavoredObject(reader, flavor, Reader.class); - + // Target data is a byte array + } else if (byteArrayClass.equals(flavor.getRepresentationClass())) { + if(isFlavorCharsetTextType(flavor) && isTextFormat(format)) { + theObject = translateBytesToString(inputStreamToByteArray(str), format, localeTransferable) + .getBytes(DataTransferer.getTextCharset(flavor)); + } else { + theObject = inputStreamToByteArray(str); + } // Target data is an RMI object } else if (flavor.isRepresentationClassRemote()) { From d6a839a6381e15b44376ab025871199046231f35 Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Fri, 13 Sep 2013 17:38:28 +0400 Subject: [PATCH 0347/1294] 8015371: The HTML text without tags does not appear inside the WordPad application, and we try to click the button, but the case exits Reviewed-by: anthony, serb --- jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java index 0ac812dd0a9..e499feb1885 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java @@ -211,9 +211,9 @@ public class WDataTransferer extends DataTransferer { DataFlavor.allHtmlFlavor, format); } else { - // handel other html flavor types, including custom and + // handle other html flavor types, including custom and // fragment ones - bytes = HTMLCodec.convertToHTMLFormat(bytes); + bytes = HTMLCodec.convertToHTMLFormat(super.translateTransferable(contents, flavor, format)); } } else { // we handle non-html types basing on their From 2527551f1d1461a242cd1c1ffa47181d41409acc Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Fri, 13 Sep 2013 17:41:47 +0400 Subject: [PATCH 0348/1294] 8015455: java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java hangs on windows Reviewed-by: serb, anthony --- .../share/classes/java/awt/dnd/DropTarget.java | 17 +++++++++++++++++ .../classes/javax/swing/TransferHandler.java | 8 ++++++++ 2 files changed, 25 insertions(+) diff --git a/jdk/src/share/classes/java/awt/dnd/DropTarget.java b/jdk/src/share/classes/java/awt/dnd/DropTarget.java index b167b8e63d8..a1fd5b56db9 100644 --- a/jdk/src/share/classes/java/awt/dnd/DropTarget.java +++ b/jdk/src/share/classes/java/awt/dnd/DropTarget.java @@ -351,6 +351,8 @@ public class DropTarget implements DropTargetListener, Serializable { * @see #isActive */ public synchronized void dragEnter(DropTargetDragEvent dtde) { + isDraggingInside = true; + if (!active) return; if (dtListener != null) { @@ -421,6 +423,8 @@ public class DropTarget implements DropTargetListener, Serializable { * @see #isActive */ public synchronized void dragExit(DropTargetEvent dte) { + isDraggingInside = false; + if (!active) return; if (dtListener != null && active) dtListener.dragExit(dte); @@ -444,6 +448,8 @@ public class DropTarget implements DropTargetListener, Serializable { * @see #isActive */ public synchronized void drop(DropTargetDropEvent dtde) { + isDraggingInside = false; + clearAutoscroll(); if (dtListener != null && active) @@ -533,6 +539,12 @@ public class DropTarget implements DropTargetListener, Serializable { ((DropTargetPeer)nativePeer).removeDropTarget(this); componentPeer = nativePeer = null; + + synchronized (this) { + if (isDraggingInside) { + dragExit(new DropTargetEvent(getDropTargetContext())); + } + } } /** @@ -855,4 +867,9 @@ public class DropTarget implements DropTargetListener, Serializable { */ private transient FlavorMap flavorMap; + + /* + * If the dragging is currently inside this drop target + */ + private transient boolean isDraggingInside; } diff --git a/jdk/src/share/classes/javax/swing/TransferHandler.java b/jdk/src/share/classes/javax/swing/TransferHandler.java index ed8a8d1ea30..f5d85408e70 100644 --- a/jdk/src/share/classes/javax/swing/TransferHandler.java +++ b/jdk/src/share/classes/javax/swing/TransferHandler.java @@ -1268,6 +1268,14 @@ public class TransferHandler implements Serializable { } } } + if (!isActive()) { + // If the Drop target is inactive the dragExit will not be dispatched to the dtListener, + // so make sure that we clean up the dtListener anyway. + DropTargetListener dtListener = getDropTargetListener(); + if (dtListener != null && dtListener instanceof DropHandler) { + ((DropHandler)dtListener).cleanup(false); + } + } } public void drop(DropTargetDropEvent e) { From d52e73dc35503f66759f011de8b7fd66000c81bd Mon Sep 17 00:00:00 2001 From: Mikhail Cherkasov Date: Fri, 13 Sep 2013 17:48:37 +0400 Subject: [PATCH 0349/1294] 8015601: [macosx] Test javax/swing/JInternalFrame/InternalFrameIsNotCollectedTest.java fails on MacOS X Reviewed-by: alexp, alexsch --- .../InternalFrameIsNotCollectedTest.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/jdk/test/javax/swing/JInternalFrame/InternalFrameIsNotCollectedTest.java b/jdk/test/javax/swing/JInternalFrame/InternalFrameIsNotCollectedTest.java index 182e57eef55..fff9c8e1d94 100644 --- a/jdk/test/javax/swing/JInternalFrame/InternalFrameIsNotCollectedTest.java +++ b/jdk/test/javax/swing/JInternalFrame/InternalFrameIsNotCollectedTest.java @@ -27,19 +27,19 @@ @author mcherkas @run main InternalFrameIsNotCollectedTest */ - import sun.awt.SunToolkit; import javax.swing.*; import java.awt.*; -import java.awt.event.KeyEvent; import java.beans.PropertyVetoException; import java.util.Date; public class InternalFrameIsNotCollectedTest { - public static final int waitTime = 10000; + public static final int maxWaitTime = 100000; + public static final int waitTime = 5000; private static Robot robot; + private static CustomInternalFrame iFrame; public static void sync() { @@ -62,12 +62,13 @@ public class InternalFrameIsNotCollectedTest { }); sync(); invokeGC(); + System.runFinalization(); Thread.sleep(1000); // it's better to wait 1 sec now then 10 sec later Date startWaiting = new Date(); synchronized (CustomInternalFrame.waiter) { // Sync with finalization thread. Date now = new Date(); - while (now.getTime() - startWaiting.getTime() < waitTime && !CustomInternalFrame.finalized) { + while (now.getTime() - startWaiting.getTime() < maxWaitTime && !CustomInternalFrame.finalized) { CustomInternalFrame.waiter.wait(waitTime); now = new Date(); } @@ -83,10 +84,8 @@ public class InternalFrameIsNotCollectedTest { } private static void closeInternalFrame() throws PropertyVetoException { - robot.keyPress(KeyEvent.VK_CONTROL); - robot.keyPress(KeyEvent.VK_F4); - robot.keyRelease(KeyEvent.VK_F4); - robot.keyRelease(KeyEvent.VK_CONTROL); + iFrame.setClosed(true); + iFrame = null; } private static void initUI() { @@ -96,7 +95,7 @@ public class InternalFrameIsNotCollectedTest { desktopPane.setDesktopManager(new DefaultDesktopManager()); frame.getContentPane().add(desktopPane, BorderLayout.CENTER); - CustomInternalFrame iFrame = new CustomInternalFrame("Dummy Frame"); + iFrame = new CustomInternalFrame("Dummy Frame"); iFrame.setSize(200, 200); iFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); From fee5a04c7bfb5dfbf57e8488f03b90b676da0f5d Mon Sep 17 00:00:00 2001 From: Konstantin Shefov Date: Fri, 13 Sep 2013 17:54:45 +0400 Subject: [PATCH 0350/1294] 8006087: [TEST_BUG] The BACKSPACE key doesn't work and after pressing 'cancel' and 'DONE' button, the case pass automatically Reviewed-by: alexsch, serb --- .../JFileChooser/4150029/bug4150029.html | 32 +++++++++++++++++++ .../JFileChooser/4150029/bug4150029.java | 19 +++++++---- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/jdk/test/javax/swing/JFileChooser/4150029/bug4150029.html b/jdk/test/javax/swing/JFileChooser/4150029/bug4150029.html index 15620bf05a3..902dda5b6c9 100644 --- a/jdk/test/javax/swing/JFileChooser/4150029/bug4150029.html +++ b/jdk/test/javax/swing/JFileChooser/4150029/bug4150029.html @@ -1,6 +1,38 @@ + + + + +Follow the instructions below. 1.Go into 'subDir' folder. 2.Press BACKSPACE key. 3.Push OPEN button. diff --git a/jdk/test/javax/swing/JFileChooser/4150029/bug4150029.java b/jdk/test/javax/swing/JFileChooser/4150029/bug4150029.java index d71bbf46828..bc4b1a8ef43 100644 --- a/jdk/test/javax/swing/JFileChooser/4150029/bug4150029.java +++ b/jdk/test/javax/swing/JFileChooser/4150029/bug4150029.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -21,11 +21,10 @@ * questions. */ -/* @test - @bug 4150029 - @summary BackSpace keyboard button does not lead to parent directory - @author Oleg Mokhovikov - @run applet/manual=done bug4150029.html +/* + bug 4150029 8006087 + summary BackSpace keyboard button does not lead to parent directory + author Oleg Mokhovikov */ import javax.swing.*; @@ -36,6 +35,14 @@ public class bug4150029 extends JApplet { private boolean res; public void init() { + if (sun.awt.OSInfo.getOSType() == sun.awt.OSInfo.OSType.MACOSX) { + try { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + String tmpDir = System.getProperty("java.io.tmpdir"); if (tmpDir.length() == 0) {//'java.io.tmpdir' isn't guaranteed to be defined From 6578d6acada94b72a51a222b4b81c0c674d3142c Mon Sep 17 00:00:00 2001 From: Konstantin Shefov Date: Fri, 13 Sep 2013 17:58:05 +0400 Subject: [PATCH 0351/1294] 8015597: [TEST_BUG] [macosx] Test closed/javax/swing/JMenuBar/4750590/bug4750590.java fails since JDK 8 b75 on MacOSX Reviewed-by: alexsch, serb --- .../swing/JMenuBar/4750590/bug4750590.java | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 jdk/test/javax/swing/JMenuBar/4750590/bug4750590.java diff --git a/jdk/test/javax/swing/JMenuBar/4750590/bug4750590.java b/jdk/test/javax/swing/JMenuBar/4750590/bug4750590.java new file mode 100644 index 00000000000..2ba8a51ebae --- /dev/null +++ b/jdk/test/javax/swing/JMenuBar/4750590/bug4750590.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013, 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 + @library ../../regtesthelpers + @build Util + @bug 4750590 8015597 + @summary SwingSet: Cannot change Themes using menu accelerators + @author Alexander Zuev + @run main bug4750590 + */ + +import javax.swing.*; +import java.awt.event.*; +import java.awt.*; + +public class bug4750590 { + + public static PassedListener pass = new PassedListener(); + public static volatile boolean passed = false; + + public static void main(String args[]) throws Throwable { + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + createAndShowGUI(); + } + }); + + sun.awt.SunToolkit toolkit = (sun.awt.SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(); + + Robot robo = new Robot(); + robo.setAutoDelay(500); + Util.hitMnemonics(robo, KeyEvent.VK_F); + robo.keyPress(KeyEvent.VK_M); + robo.keyRelease(KeyEvent.VK_M); + + toolkit.realSync(); + + if (passed) { + System.out.println("Test passed!"); + } else { + throw new RuntimeException("Test FAILED!"); + } + } + + private static void createAndShowGUI() { + JFrame mainFrame = new JFrame("Bug 4750590"); + JMenuBar mbar = new JMenuBar(); + JMenu menu = new JMenu("File"); + menu.setMnemonic('F'); + JMenu submenu = new JMenu("Submenu"); + submenu.add(new JMenuItem("SubMenu Item 1")).setMnemonic('S'); + submenu.add(new JMenuItem("SubMenu Item 2")); + menu.add(submenu); + + menu.add(new JMenuItem("Menu Item 1")); + JMenuItem menuItem = menu.add(new JMenuItem("Menu Item 2")); + menuItem.setMnemonic('M'); + menuItem.addActionListener(pass); + mbar.add(menu); + mainFrame.setJMenuBar(mbar); + + mainFrame.setSize(200, 200); + mainFrame.setLocation(200, 200); + mainFrame.setVisible(true); + mainFrame.toFront(); + } + + public static class PassedListener implements ActionListener { + public void actionPerformed(ActionEvent ev) { + passed = true; + } + } + +} From a7d4eaed9ad897dd8868e7a56308b9d2ae01f6c2 Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Fri, 13 Sep 2013 18:02:18 +0400 Subject: [PATCH 0352/1294] 8012026: [macosx] Component.getMousePosition() does not work in an applet on MacOS Reviewed-by: anthony, serb --- jdk/make/sun/lwawt/FILES_export_macosx.gmk | 1 - .../sun/lwawt/macosx/CMouseInfoPeer.java | 45 ------- .../classes/sun/lwawt/macosx/LWCToolkit.java | 5 - jdk/src/macosx/native/sun/awt/AWTView.m | 2 +- .../GetMousePositionWithOverlay.java | 108 +++++++++++++++++ .../GetMousePositionWithPopup.java | 111 ++++++++++++++++++ 6 files changed, 220 insertions(+), 52 deletions(-) delete mode 100644 jdk/src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java create mode 100644 jdk/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithOverlay.java create mode 100644 jdk/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java diff --git a/jdk/make/sun/lwawt/FILES_export_macosx.gmk b/jdk/make/sun/lwawt/FILES_export_macosx.gmk index 5799b32c954..0750201e9ec 100644 --- a/jdk/make/sun/lwawt/FILES_export_macosx.gmk +++ b/jdk/make/sun/lwawt/FILES_export_macosx.gmk @@ -141,7 +141,6 @@ FILES_export = \ sun/lwawt/macosx/CMenuBar.java \ sun/lwawt/macosx/CMenuComponent.java \ sun/lwawt/macosx/CMenuItem.java \ - sun/lwawt/macosx/CMouseInfoPeer.java \ sun/lwawt/macosx/CPlatformView.java \ sun/lwawt/macosx/CPlatformWindow.java \ sun/lwawt/macosx/CWarningWindow.java \ diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java deleted file mode 100644 index 8ee580108dc..00000000000 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.lwawt.macosx; - -import java.awt.Window; -import sun.lwawt.LWMouseInfoPeer; -import sun.lwawt.LWWindowPeer; - -public class CMouseInfoPeer extends LWMouseInfoPeer -{ - //If a new window is to appear under the cursor, - //we get wrong window. - //This is a workaround for macosx. - @Override - public boolean isWindowUnderMouse(Window w) { - if (w == null) { - return false; - } - - return ((LWWindowPeer)w.getPeer()).getPlatformWindow().isUnderMouse(); - } -} diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index e028df560f6..cf395f3ab86 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -302,11 +302,6 @@ public final class LWCToolkit extends LWToolkit { return new OSXPlatformFont(name, style); } - @Override - protected MouseInfoPeer createMouseInfoPeerImpl() { - return new CMouseInfoPeer(); - } - @Override protected int getScreenHeight() { return GraphicsEnvironment.getLocalGraphicsEnvironment() diff --git a/jdk/src/macosx/native/sun/awt/AWTView.m b/jdk/src/macosx/native/sun/awt/AWTView.m index 7e1f248c7ed..6ee074f12ab 100644 --- a/jdk/src/macosx/native/sun/awt/AWTView.m +++ b/jdk/src/macosx/native/sun/awt/AWTView.m @@ -387,7 +387,7 @@ AWT_ASSERT_APPKIT_THREAD; [rolloverTrackingArea release]; } - int options = (NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited | + int options = (NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag); rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] diff --git a/jdk/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithOverlay.java b/jdk/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithOverlay.java new file mode 100644 index 00000000000..3cb1b735837 --- /dev/null +++ b/jdk/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithOverlay.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import test.java.awt.regtesthelpers.Util; + +import javax.swing.*; +import java.awt.*; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @test + * @bug 8012026 + * @summary Component.getMousePosition() does not work in an applet on MacOS + * @author Petr Pchelko + * @library ../../regtesthelpers + * @build Util + * @compile GetMousePositionWithOverlay.java + * @run main/othervm GetMousePositionWithOverlay + */ + +public class GetMousePositionWithOverlay { + + static Frame backFrame; + static Frame frontFrame; + + public static void main(String[] args) throws Throwable { + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + constructTestUI(); + } + }); + Util.waitForIdle(null); + + Robot r = new Robot(); + Util.pointOnComp(frontFrame, r); + Util.waitForIdle(null); + + Point pos = getMousePosition(backFrame); + if (pos != null) { + throw new RuntimeException("Test failed. Mouse position should be null but was" + pos); + } + + pos = getMousePosition(frontFrame); + if (pos == null) { + throw new RuntimeException("Test failed. Mouse position should not be null"); + } + + r.mouseMove(189, 189); + Util.waitForIdle(null); + + pos = getMousePosition(backFrame); + if (pos == null) { + throw new RuntimeException("Test failed. Mouse position should not be null"); + } + } finally { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + backFrame.dispose(); + frontFrame.dispose(); + } + }); + } + } + + private static Point getMousePosition(final Component component) throws Exception { + final AtomicReference pos = new AtomicReference(); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + pos.set(component.getMousePosition()); + } + }); + return pos.get(); + } + + private static void constructTestUI() { + backFrame = new Frame(); + backFrame.setBounds(100, 100, 100, 100); + backFrame.setVisible(true); + + frontFrame = new Frame(); + frontFrame.setBounds(120, 120, 60, 60); + frontFrame.setVisible(true); + } +} diff --git a/jdk/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java b/jdk/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java new file mode 100644 index 00000000000..d04b50087ad --- /dev/null +++ b/jdk/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import test.java.awt.regtesthelpers.Util; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; + +/** + * @test + * @bug 8012026 + * @summary Component.getMousePosition() does not work in an applet on MacOS + * @author Petr Pchelko + * @library ../../regtesthelpers + * @build Util + * @compile GetMousePositionWithPopup.java + * @run main/othervm GetMousePositionWithPopup + */ + +public class GetMousePositionWithPopup { + + private static Frame frame1; + private static Frame frame2; + + public static void main(String[] args) throws Exception { + try { + Robot r = Util.createRobot(); + r.mouseMove(0, 0); + Util.waitForIdle(null); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + constructTestUI(); + } + }); + + Util.waitForIdle(null); + r.mouseMove(149, 149); + Util.waitForIdle(null); + r.mouseMove(150, 150); + Util.waitForIdle(null); + + } finally { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + frame1.dispose(); + frame2.dispose(); + } + }); + } + } + + private static void constructTestUI() { + frame1 = new Frame(); + frame1.setBounds(100, 100, 100, 100); + frame1.addMouseMotionListener(new MouseMotionAdapter() { + + private boolean shown = false; + + @Override + public void mouseMoved(MouseEvent e) { + if (shown) { + return; + } + + shown = true; + + frame2 = new Frame(); + frame2.setBounds(120, 120, 120, 120); + frame2.setVisible(true); + + Point positionInFrame2 = frame2.getMousePosition(); + if (positionInFrame2.x != 30 || positionInFrame2.y != 30) { + throw new RuntimeException("Wrong position reported. Should be [30, 30] but was [" + + positionInFrame2.x + ", " + positionInFrame2.y + "]"); + } + + Point positionInFrame1 = frame1.getMousePosition(); + if (positionInFrame1 != null) { + throw new RuntimeException("Wrong position reported. Should be null"); + } + + } + }); + frame1.setVisible(true); + } +} From dc42cb136dae4a66dc582ed312480c84c81c65d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Fri, 13 Sep 2013 17:47:00 +0200 Subject: [PATCH 0353/1294] 8021353: Event based tracing is missing thread exit Reviewed-by: allwin, acorn, dcubed, dholmes, egahlin --- hotspot/src/share/vm/runtime/thread.cpp | 2 ++ hotspot/src/share/vm/trace/traceMacros.hpp | 1 + 2 files changed, 3 insertions(+) diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index 18b46c988e3..eab949297b3 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -333,6 +333,8 @@ Thread::~Thread() { // Reclaim the objectmonitors from the omFreeList of the moribund thread. ObjectSynchronizer::omFlush (this) ; + EVENT_THREAD_DESTRUCT(this); + // stack_base can be NULL if the thread is never started or exited before // record_stack_base_and_size called. Although, we would like to ensure // that all started threads do call record_stack_base_and_size(), there is diff --git a/hotspot/src/share/vm/trace/traceMacros.hpp b/hotspot/src/share/vm/trace/traceMacros.hpp index 1a6dd644935..4776e13507e 100644 --- a/hotspot/src/share/vm/trace/traceMacros.hpp +++ b/hotspot/src/share/vm/trace/traceMacros.hpp @@ -26,6 +26,7 @@ #define SHARE_VM_TRACE_TRACE_MACRO_HPP #define EVENT_THREAD_EXIT(thread) +#define EVENT_THREAD_DESTRUCT(thread) #define TRACE_INIT_ID(k) #define TRACE_DATA TraceThreadData From e3016af23b88aa40523ced16d5af94a0c5c8627b Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Fri, 13 Sep 2013 20:28:17 +0400 Subject: [PATCH 0354/1294] 8024697: Fix for 8020983 causes Xcheck:jni warnings Reviewed-by: prr, jchen --- .../native/sun/awt/image/jpeg/imageioJPEG.c | 18 +++++++++++------- .../plugins/jpeg/JpegWriterLeakTest.java | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c index e0716b1835b..fce061d0fb8 100644 --- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c +++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c @@ -930,9 +930,10 @@ imageio_fill_input_buffer(j_decompress_ptr cinfo) * Now fill a complete buffer, or as much of one as the stream * will give us if we are near the end. */ + RELEASE_ARRAYS(env, data, src->next_input_byte); + GET_IO_REF(input); - RELEASE_ARRAYS(env, data, src->next_input_byte); ret = (*env)->CallIntMethod(env, input, JPEGImageReader_readInputDataID, @@ -1017,9 +1018,11 @@ imageio_fill_suspended_buffer(j_decompress_ptr cinfo) memcpy(sb->buf, src->next_input_byte, offset); } - GET_IO_REF(input); RELEASE_ARRAYS(env, data, src->next_input_byte); + + GET_IO_REF(input); + buflen = sb->bufferLength - offset; if (buflen <= 0) { if (!GET_ARRAYS(env, data, &(src->next_input_byte))) { @@ -1121,9 +1124,10 @@ imageio_skip_input_data(j_decompress_ptr cinfo, long num_bytes) return; } + RELEASE_ARRAYS(env, data, src->next_input_byte); + GET_IO_REF(input); - RELEASE_ARRAYS(env, data, src->next_input_byte); ret = (*env)->CallLongMethod(env, input, JPEGImageReader_skipInputBytesID, @@ -2306,10 +2310,10 @@ imageio_empty_output_buffer (j_compress_ptr cinfo) JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); jobject output = NULL; - GET_IO_REF(output); - RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte)); + GET_IO_REF(output); + (*env)->CallVoidMethod(env, output, JPEGImageWriter_writeOutputDataID, @@ -2348,10 +2352,10 @@ imageio_term_destination (j_compress_ptr cinfo) if (datacount != 0) { jobject output = NULL; - GET_IO_REF(output); - RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte)); + GET_IO_REF(output); + (*env)->CallVoidMethod(env, output, JPEGImageWriter_writeOutputDataID, diff --git a/jdk/test/javax/imageio/plugins/jpeg/JpegWriterLeakTest.java b/jdk/test/javax/imageio/plugins/jpeg/JpegWriterLeakTest.java index ffb2b63b0b0..bb5fc06e99b 100644 --- a/jdk/test/javax/imageio/plugins/jpeg/JpegWriterLeakTest.java +++ b/jdk/test/javax/imageio/plugins/jpeg/JpegWriterLeakTest.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8020983 + * @bug 8020983 8024697 * @summary Test verifies that jpeg writer instances are collected * even if destroy() or reset() methods is not invoked. * From 4831191842e6f1b54b5fa9ff73c2c6e8459f6aad Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Fri, 13 Sep 2013 12:06:53 -0700 Subject: [PATCH 0355/1294] 8024201: Update bugdatabase url Reviewed-by: wetmore --- make/scripts/webrev.ksh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/make/scripts/webrev.ksh b/make/scripts/webrev.ksh index 9fef47fa69e..3839b7490f5 100644 --- a/make/scripts/webrev.ksh +++ b/make/scripts/webrev.ksh @@ -27,7 +27,7 @@ # Documentation is available via 'webrev -h'. # -WEBREV_UPDATED=24.0-hg+jbs +WEBREV_UPDATED=24.1-hg+openjdk.java.net HTML=' +# ' # JDK-1234567 my bugid' > .html # # framed_sdiff() is then called which creates $2.frames.html @@ -1476,7 +1476,7 @@ function treestatus # The first and last are simple addition while the middle one # is a move/rename or a copy. We can't distinguish from a rename vs a copy # without also getting the status of removed files. The middle case above - # is a rename if File4 is also shown a being removed. If File4 is not a + # is a rename if File4 is also shown a being removed. If File4 is not a # removed file, then the middle case is a copy from File4 to subdir/File4 # FIXME - we're not distinguishing copy from rename $HGCMD -aC | $FILTER | while read LINE; do @@ -1644,7 +1644,7 @@ function flist_from_mercurial # The first and last are simple addition while the middle one # is a move/rename or a copy. We can't distinguish from a rename vs a copy # without also getting the status of removed files. The middle case above - # is a rename if File4 is also shown a being removed. If File4 is not a + # is a rename if File4 is also shown a being removed. If File4 is not a # removed file, then the middle case is a copy from File4 to subdir/File4 # FIXME - we're not distinguishing copy from rename @@ -2529,7 +2529,7 @@ print " Output to: $WDIR" # Bug IDs will be replaced by a URL. Order of precedence # is: default location, $WEBREV_BUGURL, the -O flag. # -BUGURL='https://jbs.oracle.com/bugs/browse/' +BUGURL='https://bugs.openjdk.java.net/browse/' [[ -n $WEBREV_BUGURL ]] && BUGURL="$WEBREV_BUGURL" if [[ -n "$Oflag" ]]; then CRID=`echo $CRID | sed -e 's/JDK-//'` @@ -3056,7 +3056,7 @@ if [[ -n $CRID ]]; then for id in $CRID do if [[ -z "$Oflag" ]]; then - #add "JDK-" to raw bug id for jbs links. + #add "JDK-" to raw bug id for openjdk.java.net links. id=`echo ${id} | sed 's/^\([0-9]\{5,\}\)$/JDK-\1/'` fi print "
    Bug id:" From 5c11ecebfba784fda6007fda8447fc60d02224a8 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Fri, 13 Sep 2013 12:46:40 -0700 Subject: [PATCH 0356/1294] 8017230: Internal Error (jvmtiRedefineClasses.cpp:1662): guarantee(false) failed: insert_space_at() failed Handle pending exceptions instead of firing a guarantee() Reviewed-by: coleenp, dholmes --- .../share/vm/prims/jvmtiRedefineClasses.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 803cf9a7545..5330ab791b2 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1590,11 +1590,23 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_methods( for (int i = methods->length() - 1; i >= 0; i--) { methodHandle method(THREAD, methods->at(i)); methodHandle new_method; - rewrite_cp_refs_in_method(method, &new_method, CHECK_false); + rewrite_cp_refs_in_method(method, &new_method, THREAD); if (!new_method.is_null()) { // the method has been replaced so save the new method version + // even in the case of an exception. original method is on the + // deallocation list. methods->at_put(i, new_method()); } + if (HAS_PENDING_EXCEPTION) { + Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); + // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark + RC_TRACE_WITH_THREAD(0x00000002, THREAD, + ("rewrite_cp_refs_in_method exception: '%s'", ex_name->as_C_string())); + // Need to clear pending exception here as the super caller sets + // the JVMTI_ERROR_INTERNAL if the returned value is false. + CLEAR_PENDING_EXCEPTION; + return false; + } } return true; @@ -1674,10 +1686,7 @@ void VM_RedefineClasses::rewrite_cp_refs_in_method(methodHandle method, Pause_No_Safepoint_Verifier pnsv(&nsv); // ldc is 2 bytes and ldc_w is 3 bytes - m = rc.insert_space_at(bci, 3, inst_buffer, THREAD); - if (m.is_null() || HAS_PENDING_EXCEPTION) { - guarantee(false, "insert_space_at() failed"); - } + m = rc.insert_space_at(bci, 3, inst_buffer, CHECK); } // return the new method so that the caller can update From 47e8234251c09ec74d0de11f602b6c9a2c51d432 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Fri, 13 Sep 2013 12:47:44 -0700 Subject: [PATCH 0357/1294] 8024345: 'assert(_value != NULL) failed: resolving NULL _value' from VM_RedefineClasses::set_new_constant_pool The OOME's in the JVMTI merge_cp_and_rewrite and set_new_constant_pool must be handled correctly Reviewed-by: coleenp, dholmes --- .../share/vm/prims/jvmtiRedefineClasses.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 5330ab791b2..69e1c9f949c 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1395,8 +1395,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite( ClassLoaderData* loader_data = the_class->class_loader_data(); ConstantPool* merge_cp_oop = ConstantPool::allocate(loader_data, - merge_cp_length, - THREAD); + merge_cp_length, + CHECK_(JVMTI_ERROR_OUT_OF_MEMORY)); MergeCPCleaner cp_cleaner(loader_data, merge_cp_oop); HandleMark hm(THREAD); // make sure handles are cleared before @@ -1472,7 +1472,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite( // Replace the new constant pool with a shrunken copy of the // merged constant pool - set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD); + set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, + CHECK_(JVMTI_ERROR_OUT_OF_MEMORY)); // The new constant pool replaces scratch_cp so have cleaner clean it up. // It can't be cleaned up while there are handles to it. cp_cleaner.add_scratch_cp(scratch_cp()); @@ -1502,7 +1503,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite( // merged constant pool so now the rewritten bytecodes have // valid references; the previous new constant pool will get // GCed. - set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD); + set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, + CHECK_(JVMTI_ERROR_OUT_OF_MEMORY)); // The new constant pool replaces scratch_cp so have cleaner clean it up. // It can't be cleaned up while there are handles to it. cp_cleaner.add_scratch_cp(scratch_cp()); @@ -2496,8 +2498,8 @@ void VM_RedefineClasses::set_new_constant_pool( // scratch_cp is a merged constant pool and has enough space for a // worst case merge situation. We want to associate the minimum // sized constant pool with the klass to save space. - constantPoolHandle smaller_cp(THREAD, - ConstantPool::allocate(loader_data, scratch_cp_length, THREAD)); + ConstantPool* cp = ConstantPool::allocate(loader_data, scratch_cp_length, CHECK); + constantPoolHandle smaller_cp(THREAD, cp); // preserve version() value in the smaller copy int version = scratch_cp->version(); @@ -2509,6 +2511,11 @@ void VM_RedefineClasses::set_new_constant_pool( smaller_cp->set_pool_holder(scratch_class()); scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD); + if (HAS_PENDING_EXCEPTION) { + // Exception is handled in the caller + loader_data->add_to_deallocate_list(smaller_cp()); + return; + } scratch_cp = smaller_cp; // attach new constant pool to klass From 2823ae69434df3acb2a94227539fd6f7038db557 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Fri, 13 Sep 2013 12:48:50 -0700 Subject: [PATCH 0358/1294] 8024346: ~CautiouslyPreserveExceptionMark - assert(!_thread->has_pending_exception()) failed: unexpected exception generated Pending exceptions must be handled properly after a call to the JVMTI merge_cp_and_rewrite Reviewed-by: coleenp, dholmes --- .../src/share/vm/prims/jvmtiRedefineClasses.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 69e1c9f949c..6894ec3f1f4 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1072,8 +1072,17 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) { } res = merge_cp_and_rewrite(the_class, scratch_class, THREAD); - if (res != JVMTI_ERROR_NONE) { - return res; + if (HAS_PENDING_EXCEPTION) { + Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); + // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark + RC_TRACE_WITH_THREAD(0x00000002, THREAD, + ("merge_cp_and_rewrite exception: '%s'", ex_name->as_C_string())); + CLEAR_PENDING_EXCEPTION; + if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { + return JVMTI_ERROR_OUT_OF_MEMORY; + } else { + return JVMTI_ERROR_INTERNAL; + } } if (VerifyMergedCPBytecodes) { @@ -1105,6 +1114,9 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) { } if (HAS_PENDING_EXCEPTION) { Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); + // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark + RC_TRACE_WITH_THREAD(0x00000002, THREAD, + ("Rewriter::rewrite or link_methods exception: '%s'", ex_name->as_C_string())); CLEAR_PENDING_EXCEPTION; if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { return JVMTI_ERROR_OUT_OF_MEMORY; From 4fa99b3fc5fa1a52b1e7edd24076ab6d83e70e7d Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Fri, 13 Sep 2013 16:55:44 -0700 Subject: [PATCH 0359/1294] 8024760: add more types, fields and constants to VMStructs Reviewed-by: kvn, coleenp --- .../sun/jvm/hotspot/CommandProcessor.java | 2 + .../vm/gc_implementation/g1/ptrQueue.hpp | 1 + .../vm/gc_implementation/g1/vmStructs_g1.hpp | 3 +- hotspot/src/share/vm/memory/universe.cpp | 8 +- hotspot/src/share/vm/memory/universe.hpp | 2 + hotspot/src/share/vm/oops/klassVtable.hpp | 2 + hotspot/src/share/vm/oops/methodData.hpp | 2 + hotspot/src/share/vm/runtime/os.hpp | 2 + hotspot/src/share/vm/runtime/vmStructs.cpp | 119 ++++++++++++++++-- 9 files changed, 123 insertions(+), 18 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java index 1840caf9313..354f0b906b3 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java @@ -1213,6 +1213,7 @@ public class CommandProcessor { } HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase(); if (t.countTokens() == 1) { + String name = t.nextToken(); out.println("intConstant " + name + " " + db.lookupIntConstant(name)); } else if (t.countTokens() == 0) { Iterator i = db.getIntConstants(); @@ -1235,6 +1236,7 @@ public class CommandProcessor { } HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase(); if (t.countTokens() == 1) { + String name = t.nextToken(); out.println("longConstant " + name + " " + db.lookupLongConstant(name)); } else if (t.countTokens() == 0) { Iterator i = db.getLongConstants(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp index 1f6d9b21388..958317166ea 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp @@ -38,6 +38,7 @@ class PtrQueueSet; class PtrQueue VALUE_OBJ_CLASS_SPEC { + friend class VMStructs; protected: // The ptr queue set to which this queue belongs. diff --git a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp index 5507dee5f80..736c2d75096 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp @@ -31,7 +31,8 @@ #define VM_STRUCTS_G1(nonstatic_field, static_field) \ \ - static_field(HeapRegion, GrainBytes, size_t) \ + static_field(HeapRegion, GrainBytes, size_t) \ + static_field(HeapRegion, LogOfHRGrainBytes, int) \ \ nonstatic_field(HeapRegionSeq, _regions, HeapRegion**) \ nonstatic_field(HeapRegionSeq, _length, uint) \ diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 143c0c00c45..f00a10f74a4 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -602,7 +602,7 @@ oop Universe::gen_out_of_memory_error(oop default_err) { } } -static intptr_t non_oop_bits = 0; +intptr_t Universe::_non_oop_bits = 0; void* Universe::non_oop_word() { // Neither the high bits nor the low bits of this value is allowed @@ -616,11 +616,11 @@ void* Universe::non_oop_word() { // Using the OS-supplied non-memory-address word (usually 0 or -1) // will take care of the high bits, however many there are. - if (non_oop_bits == 0) { - non_oop_bits = (intptr_t)os::non_memory_address_word() | 1; + if (_non_oop_bits == 0) { + _non_oop_bits = (intptr_t)os::non_memory_address_word() | 1; } - return (void*)non_oop_bits; + return (void*)_non_oop_bits; } jint universe_init() { diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp index a8b541d03a1..09b52c099f2 100644 --- a/hotspot/src/share/vm/memory/universe.hpp +++ b/hotspot/src/share/vm/memory/universe.hpp @@ -179,6 +179,8 @@ class Universe: AllStatic { // The particular choice of collected heap. static CollectedHeap* _collectedHeap; + static intptr_t _non_oop_bits; + // For UseCompressedOops. static struct NarrowPtrStruct _narrow_oop; // For UseCompressedKlassPointers. diff --git a/hotspot/src/share/vm/oops/klassVtable.hpp b/hotspot/src/share/vm/oops/klassVtable.hpp index 01495e35d90..8d8d6cf27c5 100644 --- a/hotspot/src/share/vm/oops/klassVtable.hpp +++ b/hotspot/src/share/vm/oops/klassVtable.hpp @@ -150,6 +150,8 @@ class klassVtable : public ResourceObj { // from_compiled_code_entry_point -> nmethod entry point // from_interpreter_entry_point -> i2cadapter class vtableEntry VALUE_OBJ_CLASS_SPEC { + friend class VMStructs; + public: // size in words static int size() { diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp index 765b91c142c..7ff9b2bbb6d 100644 --- a/hotspot/src/share/vm/oops/methodData.hpp +++ b/hotspot/src/share/vm/oops/methodData.hpp @@ -72,6 +72,8 @@ class ProfileData; // // Overlay for generic profiling data. class DataLayout VALUE_OBJ_CLASS_SPEC { + friend class VMStructs; + private: // Every data layout begins with a header. This header // contains a tag, which is used to indicate the size/layout diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index e43d68981cb..b224a3d7427 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -91,6 +91,8 @@ const bool ExecMem = true; typedef void (*java_call_t)(JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread); class os: AllStatic { + friend class VMStructs; + public: enum { page_sizes_max = 9 }; // Size of _page_sizes array (8 plus a sentinel) diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 7e0df23a3e1..448a8919f0e 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -330,11 +330,13 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(Klass, _java_mirror, oop) \ nonstatic_field(Klass, _modifier_flags, jint) \ nonstatic_field(Klass, _super, Klass*) \ + nonstatic_field(Klass, _subklass, Klass*) \ nonstatic_field(Klass, _layout_helper, jint) \ nonstatic_field(Klass, _name, Symbol*) \ nonstatic_field(Klass, _access_flags, AccessFlags) \ - nonstatic_field(Klass, _subklass, Klass*) \ + nonstatic_field(Klass, _prototype_header, markOop) \ nonstatic_field(Klass, _next_sibling, Klass*) \ + nonstatic_field(vtableEntry, _method, Method*) \ nonstatic_field(MethodData, _size, int) \ nonstatic_field(MethodData, _method, Method*) \ nonstatic_field(MethodData, _data_size, int) \ @@ -342,10 +344,15 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(MethodData, _nof_decompiles, uint) \ nonstatic_field(MethodData, _nof_overflow_recompiles, uint) \ nonstatic_field(MethodData, _nof_overflow_traps, uint) \ + nonstatic_field(MethodData, _trap_hist._array[0], u1) \ nonstatic_field(MethodData, _eflags, intx) \ nonstatic_field(MethodData, _arg_local, intx) \ nonstatic_field(MethodData, _arg_stack, intx) \ nonstatic_field(MethodData, _arg_returned, intx) \ + nonstatic_field(DataLayout, _header._struct._tag, u1) \ + nonstatic_field(DataLayout, _header._struct._flags, u1) \ + nonstatic_field(DataLayout, _header._struct._bci, u2) \ + nonstatic_field(DataLayout, _cells[0], intptr_t) \ nonstatic_field(MethodCounters, _interpreter_invocation_count, int) \ nonstatic_field(MethodCounters, _interpreter_throwout_count, u2) \ nonstatic_field(MethodCounters, _number_of_breakpoints, u2) \ @@ -357,6 +364,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(Method, _access_flags, AccessFlags) \ nonstatic_field(Method, _vtable_index, int) \ nonstatic_field(Method, _method_size, u2) \ + nonstatic_field(Method, _intrinsic_id, u1) \ nonproduct_nonstatic_field(Method, _compiled_invocation_count, int) \ volatile_nonstatic_field(Method, _code, nmethod*) \ nonstatic_field(Method, _i2i_entry, address) \ @@ -443,12 +451,19 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; static_field(Universe, _bootstrapping, bool) \ static_field(Universe, _fully_initialized, bool) \ static_field(Universe, _verify_count, int) \ + static_field(Universe, _non_oop_bits, intptr_t) \ static_field(Universe, _narrow_oop._base, address) \ static_field(Universe, _narrow_oop._shift, int) \ static_field(Universe, _narrow_oop._use_implicit_null_checks, bool) \ static_field(Universe, _narrow_klass._base, address) \ static_field(Universe, _narrow_klass._shift, int) \ \ + /******/ \ + /* os */ \ + /******/ \ + \ + static_field(os, _polling_page, address) \ + \ /**********************************************************************************/ \ /* Generation and Space hierarchies */ \ /**********************************************************************************/ \ @@ -456,6 +471,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; unchecked_nonstatic_field(ageTable, sizes, sizeof(ageTable::sizes)) \ \ nonstatic_field(BarrierSet, _max_covered_regions, int) \ + nonstatic_field(BarrierSet, _kind, BarrierSet::Name) \ nonstatic_field(BlockOffsetTable, _bottom, HeapWord*) \ nonstatic_field(BlockOffsetTable, _end, HeapWord*) \ \ @@ -495,6 +511,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(CollectedHeap, _barrier_set, BarrierSet*) \ nonstatic_field(CollectedHeap, _defer_initial_card_mark, bool) \ nonstatic_field(CollectedHeap, _is_gc_active, bool) \ + nonstatic_field(CollectedHeap, _total_collections, unsigned int) \ nonstatic_field(CompactibleSpace, _compaction_top, HeapWord*) \ nonstatic_field(CompactibleSpace, _first_dead, HeapWord*) \ nonstatic_field(CompactibleSpace, _end_of_live, HeapWord*) \ @@ -505,7 +522,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(ContiguousSpace, _saved_mark_word, HeapWord*) \ \ nonstatic_field(DefNewGeneration, _next_gen, Generation*) \ - nonstatic_field(DefNewGeneration, _tenuring_threshold, uint) \ + nonstatic_field(DefNewGeneration, _tenuring_threshold, uint) \ nonstatic_field(DefNewGeneration, _age_table, ageTable) \ nonstatic_field(DefNewGeneration, _eden_space, EdenSpace*) \ nonstatic_field(DefNewGeneration, _from_space, ContiguousSpace*) \ @@ -552,6 +569,11 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(ThreadLocalAllocBuffer, _desired_size, size_t) \ nonstatic_field(ThreadLocalAllocBuffer, _refill_waste_limit, size_t) \ static_field(ThreadLocalAllocBuffer, _target_refills, unsigned) \ + nonstatic_field(ThreadLocalAllocBuffer, _number_of_refills, unsigned) \ + nonstatic_field(ThreadLocalAllocBuffer, _fast_refill_waste, unsigned) \ + nonstatic_field(ThreadLocalAllocBuffer, _slow_refill_waste, unsigned) \ + nonstatic_field(ThreadLocalAllocBuffer, _gc_waste, unsigned) \ + nonstatic_field(ThreadLocalAllocBuffer, _slow_allocations, unsigned) \ nonstatic_field(VirtualSpace, _low_boundary, char*) \ nonstatic_field(VirtualSpace, _high_boundary, char*) \ nonstatic_field(VirtualSpace, _low, char*) \ @@ -713,6 +735,13 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; \ static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \ \ + /**********/ \ + /* Arrays */ \ + /**********/ \ + \ + nonstatic_field(Array, _length, int) \ + nonstatic_field(Array, _data[0], Klass*) \ + \ /*******************/ \ /* GrowableArrays */ \ /*******************/ \ @@ -720,7 +749,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(GenericGrowableArray, _len, int) \ nonstatic_field(GenericGrowableArray, _max, int) \ nonstatic_field(GenericGrowableArray, _arena, Arena*) \ - nonstatic_field(GrowableArray, _data, int*) \ + nonstatic_field(GrowableArray, _data, int*) \ \ /********************************/ \ /* CodeCache (NOTE: incomplete) */ \ @@ -763,7 +792,20 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* StubRoutines (NOTE: incomplete) */ \ /***********************************/ \ \ + static_field(StubRoutines, _verify_oop_count, jint) \ static_field(StubRoutines, _call_stub_return_address, address) \ + static_field(StubRoutines, _aescrypt_encryptBlock, address) \ + static_field(StubRoutines, _aescrypt_decryptBlock, address) \ + static_field(StubRoutines, _cipherBlockChaining_encryptAESCrypt, address) \ + static_field(StubRoutines, _cipherBlockChaining_decryptAESCrypt, address) \ + static_field(StubRoutines, _updateBytesCRC32, address) \ + static_field(StubRoutines, _crc_table_adr, address) \ + \ + /*****************/ \ + /* SharedRuntime */ \ + /*****************/ \ + \ + static_field(SharedRuntime, _ic_miss_blob, RuntimeStub*) \ \ /***************************************/ \ /* PcDesc and other compiled code info */ \ @@ -853,6 +895,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; volatile_nonstatic_field(Thread, _suspend_flags, uint32_t) \ nonstatic_field(Thread, _active_handles, JNIHandleBlock*) \ nonstatic_field(Thread, _tlab, ThreadLocalAllocBuffer) \ + nonstatic_field(Thread, _allocated_bytes, jlong) \ nonstatic_field(Thread, _current_pending_monitor, ObjectMonitor*) \ nonstatic_field(Thread, _current_pending_monitor_is_from_java, bool) \ nonstatic_field(Thread, _current_waiting_monitor, ObjectMonitor*) \ @@ -866,6 +909,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(JavaThread, _pending_async_exception, oop) \ volatile_nonstatic_field(JavaThread, _exception_oop, oop) \ volatile_nonstatic_field(JavaThread, _exception_pc, address) \ + volatile_nonstatic_field(JavaThread, _is_method_handle_return, int) \ nonstatic_field(JavaThread, _is_compiling, bool) \ nonstatic_field(JavaThread, _special_runtime_exit_condition, JavaThread::AsyncRequests) \ nonstatic_field(JavaThread, _saved_exception_pc, address) \ @@ -875,6 +919,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(JavaThread, _stack_size, size_t) \ nonstatic_field(JavaThread, _vframe_array_head, vframeArray*) \ nonstatic_field(JavaThread, _vframe_array_last, vframeArray*) \ + nonstatic_field(JavaThread, _satb_mark_queue, ObjPtrQueue) \ + nonstatic_field(JavaThread, _dirty_card_queue, DirtyCardQueue) \ nonstatic_field(Thread, _resource_area, ResourceArea*) \ nonstatic_field(CompilerThread, _env, ciEnv*) \ \ @@ -1187,7 +1233,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; unchecked_nonstatic_field(Array, _data, sizeof(int)) \ unchecked_nonstatic_field(Array, _data, sizeof(u1)) \ unchecked_nonstatic_field(Array, _data, sizeof(u2)) \ - unchecked_nonstatic_field(Array, _data, sizeof(Method*)) \ + unchecked_nonstatic_field(Array, _data, sizeof(Method*)) \ unchecked_nonstatic_field(Array, _data, sizeof(Klass*)) \ \ /*********************************/ \ @@ -1203,7 +1249,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* Miscellaneous fields */ \ /************************/ \ \ - nonstatic_field(CompileTask, _method, Method*) \ + nonstatic_field(CompileTask, _method, Method*) \ nonstatic_field(CompileTask, _osr_bci, int) \ nonstatic_field(CompileTask, _comp_level, int) \ nonstatic_field(CompileTask, _compile_id, uint) \ @@ -1217,7 +1263,11 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; \ nonstatic_field(vframeArrayElement, _frame, frame) \ nonstatic_field(vframeArrayElement, _bci, int) \ - nonstatic_field(vframeArrayElement, _method, Method*) \ + nonstatic_field(vframeArrayElement, _method, Method*) \ + \ + nonstatic_field(PtrQueue, _active, bool) \ + nonstatic_field(PtrQueue, _buf, void**) \ + nonstatic_field(PtrQueue, _index, size_t) \ \ nonstatic_field(AccessFlags, _flags, jint) \ nonstatic_field(elapsedTimer, _counter, jlong) \ @@ -1363,7 +1413,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* MetadataOopDesc hierarchy (NOTE: some missing) */ \ /**************************************************/ \ \ - declare_toplevel_type(CompiledICHolder) \ + declare_toplevel_type(CompiledICHolder) \ declare_toplevel_type(MetaspaceObj) \ declare_type(Metadata, MetaspaceObj) \ declare_type(Klass, Metadata) \ @@ -1374,17 +1424,20 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_type(InstanceClassLoaderKlass, InstanceKlass) \ declare_type(InstanceMirrorKlass, InstanceKlass) \ declare_type(InstanceRefKlass, InstanceKlass) \ - declare_type(ConstantPool, Metadata) \ - declare_type(ConstantPoolCache, MetaspaceObj) \ - declare_type(MethodData, Metadata) \ - declare_type(Method, Metadata) \ - declare_type(MethodCounters, MetaspaceObj) \ - declare_type(ConstMethod, MetaspaceObj) \ + declare_type(ConstantPool, Metadata) \ + declare_type(ConstantPoolCache, MetaspaceObj) \ + declare_type(MethodData, Metadata) \ + declare_type(Method, Metadata) \ + declare_type(MethodCounters, MetaspaceObj) \ + declare_type(ConstMethod, MetaspaceObj) \ + \ + declare_toplevel_type(vtableEntry) \ \ declare_toplevel_type(Symbol) \ declare_toplevel_type(Symbol*) \ declare_toplevel_type(volatile Metadata*) \ \ + declare_toplevel_type(DataLayout) \ declare_toplevel_type(nmethodBucket) \ \ /********/ \ @@ -1432,6 +1485,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_type(ModRefBarrierSet, BarrierSet) \ declare_type(CardTableModRefBS, ModRefBarrierSet) \ declare_type(CardTableModRefBSForCTRS, CardTableModRefBS) \ + declare_toplevel_type(BarrierSet::Name) \ declare_toplevel_type(GenRemSet) \ declare_type(CardTableRS, GenRemSet) \ declare_toplevel_type(BlockOffsetSharedArray) \ @@ -1450,6 +1504,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_toplevel_type(ThreadLocalAllocBuffer) \ declare_toplevel_type(VirtualSpace) \ declare_toplevel_type(WaterMark) \ + declare_toplevel_type(ObjPtrQueue) \ + declare_toplevel_type(DirtyCardQueue) \ \ /* Pointers to Garbage Collection types */ \ \ @@ -2068,6 +2124,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_toplevel_type(StubQueue*) \ declare_toplevel_type(Thread*) \ declare_toplevel_type(Universe) \ + declare_toplevel_type(os) \ declare_toplevel_type(vframeArray) \ declare_toplevel_type(vframeArrayElement) \ declare_toplevel_type(Annotations*) \ @@ -2076,6 +2133,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* Miscellaneous types */ \ /***************/ \ \ + declare_toplevel_type(PtrQueue) \ + \ /* freelist */ \ declare_toplevel_type(FreeChunk*) \ declare_toplevel_type(Metablock*) \ @@ -2106,6 +2165,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* Useful globals */ \ /******************/ \ \ + declare_preprocessor_constant("ASSERT", DEBUG_ONLY(1) NOT_DEBUG(0)) \ \ /**************/ \ /* Stack bias */ \ @@ -2122,6 +2182,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(BytesPerWord) \ declare_constant(BytesPerLong) \ \ + declare_constant(LogKlassAlignmentInBytes) \ + \ /********************************************/ \ /* Generation and Space Hierarchy Constants */ \ /********************************************/ \ @@ -2130,6 +2192,9 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; \ declare_constant(BarrierSet::ModRef) \ declare_constant(BarrierSet::CardTableModRef) \ + declare_constant(BarrierSet::CardTableExtension) \ + declare_constant(BarrierSet::G1SATBCT) \ + declare_constant(BarrierSet::G1SATBCTLogging) \ declare_constant(BarrierSet::Other) \ \ declare_constant(BlockOffsetSharedArray::LogN) \ @@ -2248,8 +2313,11 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(Klass::_primary_super_limit) \ declare_constant(Klass::_lh_instance_slow_path_bit) \ declare_constant(Klass::_lh_log2_element_size_shift) \ + declare_constant(Klass::_lh_log2_element_size_mask) \ declare_constant(Klass::_lh_element_type_shift) \ + declare_constant(Klass::_lh_element_type_mask) \ declare_constant(Klass::_lh_header_size_shift) \ + declare_constant(Klass::_lh_header_size_mask) \ declare_constant(Klass::_lh_array_tag_shift) \ declare_constant(Klass::_lh_array_tag_type_value) \ declare_constant(Klass::_lh_array_tag_obj_value) \ @@ -2268,6 +2336,12 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(ConstMethod::_has_default_annotations) \ declare_constant(ConstMethod::_has_type_annotations) \ \ + /**************/ \ + /* DataLayout */ \ + /**************/ \ + \ + declare_constant(DataLayout::cell_size) \ + \ /*************************************/ \ /* InstanceKlass enum */ \ /*************************************/ \ @@ -2402,6 +2476,13 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(Deoptimization::Reason_LIMIT) \ declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \ \ + declare_constant(Deoptimization::Action_none) \ + declare_constant(Deoptimization::Action_maybe_recompile) \ + declare_constant(Deoptimization::Action_reinterpret) \ + declare_constant(Deoptimization::Action_make_not_entrant) \ + declare_constant(Deoptimization::Action_make_not_compilable) \ + declare_constant(Deoptimization::Action_LIMIT) \ + \ /*********************/ \ /* Matcher (C2 only) */ \ /*********************/ \ @@ -2468,6 +2549,16 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(vmSymbols::FIRST_SID) \ declare_constant(vmSymbols::SID_LIMIT) \ \ + /****************/ \ + /* vmIntrinsics */ \ + /****************/ \ + \ + declare_constant(vmIntrinsics::_invokeBasic) \ + declare_constant(vmIntrinsics::_linkToVirtual) \ + declare_constant(vmIntrinsics::_linkToStatic) \ + declare_constant(vmIntrinsics::_linkToSpecial) \ + declare_constant(vmIntrinsics::_linkToInterface) \ + \ /********************************/ \ /* Calling convention constants */ \ /********************************/ \ @@ -2515,6 +2606,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(markOopDesc::biased_lock_bit_in_place) \ declare_constant(markOopDesc::age_mask) \ declare_constant(markOopDesc::age_mask_in_place) \ + declare_constant(markOopDesc::epoch_mask) \ + declare_constant(markOopDesc::epoch_mask_in_place) \ declare_constant(markOopDesc::hash_mask) \ declare_constant(markOopDesc::hash_mask_in_place) \ declare_constant(markOopDesc::biased_lock_alignment) \ From 7b2ffab30e57a21afe0ee70a801d4faa68d03b07 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Fri, 13 Sep 2013 21:36:27 -0400 Subject: [PATCH 0360/1294] 8024505: [TESTBUG] update test groups for additional tests that can't run on the minimal VM Reviewed-by: coleenp, hseigel --- hotspot/test/TEST.groups | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index bf5e3f088fb..d2ad0c7ea18 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -84,6 +84,7 @@ needs_jdk = \ runtime/NMT/ThreadedVirtualAllocTestType.java \ runtime/NMT/VirtualAllocTestType.java \ runtime/RedefineObject/TestRedefineObject.java \ + runtime/XCheckJniJsig/XCheckJSig.java \ serviceability/attach/AttachWithStalePidFile.java # JRE adds further tests to compact3 @@ -159,7 +160,18 @@ needs_full_vm_compact1 = \ gc/g1/TestRegionAlignment.java \ gc/g1/TestShrinkToOneRegion.java \ gc/metaspace/G1AddMetaspaceDependency.java \ - runtime/6929067/Test6929067.sh + gc/startup_warnings/TestCMS.java \ + gc/startup_warnings/TestCMSIncrementalMode.java \ + gc/startup_warnings/TestCMSNoIncrementalMode.java \ + gc/startup_warnings/TestDefaultMaxRAMFraction.java \ + gc/startup_warnings/TestDefNewCMS.java \ + gc/startup_warnings/TestIncGC.java \ + gc/startup_warnings/TestParallelGC.java \ + gc/startup_warnings/TestParallelScavengeSerialOld.java \ + gc/startup_warnings/TestParNewCMS.java \ + gc/startup_warnings/TestParNewSerialOld.java \ + runtime/6929067/Test6929067.sh \ + runtime/SharedArchiveFile/SharedArchiveFile.java # Minimal VM on Compact 2 adds in some compact2 tests # From 222c7354581b068ba6ff99d041084b481b08960f Mon Sep 17 00:00:00 2001 From: David Chase Date: Fri, 13 Sep 2013 22:38:02 -0400 Subject: [PATCH 0361/1294] 8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation Enhance method resolution and resulting data structures, plus some refactoring. Reviewed-by: twisti, acorn, jrose --- hotspot/src/share/vm/c1/c1_Runtime1.cpp | 12 +- hotspot/src/share/vm/ci/ciField.cpp | 18 +- hotspot/src/share/vm/ci/ciField.hpp | 5 +- hotspot/src/share/vm/ci/ciInstanceKlass.cpp | 5 +- hotspot/src/share/vm/ci/ciMethod.cpp | 9 +- hotspot/src/share/vm/ci/ciSymbol.hpp | 3 +- .../share/vm/classfile/classFileParser.cpp | 5 +- hotspot/src/share/vm/code/compiledIC.cpp | 27 +- hotspot/src/share/vm/code/vtableStubs.cpp | 2 +- hotspot/src/share/vm/code/vtableStubs.hpp | 4 +- .../vm/interpreter/interpreterRuntime.cpp | 52 +++- .../src/share/vm/interpreter/linkResolver.cpp | 213 ++++++++++------ .../src/share/vm/interpreter/linkResolver.hpp | 111 ++++---- hotspot/src/share/vm/oops/constantPool.cpp | 26 -- hotspot/src/share/vm/oops/constantPool.hpp | 2 - hotspot/src/share/vm/oops/cpCache.cpp | 28 +- hotspot/src/share/vm/oops/cpCache.hpp | 22 +- hotspot/src/share/vm/oops/fieldStreams.hpp | 13 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 119 ++------- hotspot/src/share/vm/oops/instanceKlass.hpp | 10 - hotspot/src/share/vm/oops/klass.cpp | 16 +- hotspot/src/share/vm/oops/klass.hpp | 3 +- hotspot/src/share/vm/oops/klassVtable.cpp | 239 +++++++++++------- hotspot/src/share/vm/oops/klassVtable.hpp | 6 +- hotspot/src/share/vm/oops/method.cpp | 34 ++- hotspot/src/share/vm/oops/method.hpp | 19 +- hotspot/src/share/vm/oops/symbol.hpp | 2 +- hotspot/src/share/vm/opto/library_call.cpp | 4 + hotspot/src/share/vm/prims/jni.cpp | 8 +- hotspot/src/share/vm/prims/jvm.cpp | 2 +- .../share/vm/prims/jvmtiRedefineClasses.cpp | 2 +- hotspot/src/share/vm/prims/methodHandles.cpp | 235 +++++++---------- hotspot/src/share/vm/prims/methodHandles.hpp | 13 +- .../src/share/vm/runtime/fieldDescriptor.cpp | 18 +- .../src/share/vm/runtime/fieldDescriptor.hpp | 12 +- hotspot/src/share/vm/runtime/mutexLocker.cpp | 2 - hotspot/src/share/vm/runtime/mutexLocker.hpp | 3 +- hotspot/src/share/vm/runtime/reflection.cpp | 3 +- .../src/share/vm/runtime/reflectionUtils.hpp | 8 + hotspot/src/share/vm/runtime/vmStructs.cpp | 1 - 40 files changed, 715 insertions(+), 601 deletions(-) diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 037bc31f658..080eaf67088 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -709,10 +709,10 @@ static Klass* resolve_field_return_klass(methodHandle caller, int bci, TRAPS) { Bytecodes::Code code = field_access.code(); // We must load class, initialize class and resolvethe field - FieldAccessInfo result; // initialize class if needed + fieldDescriptor result; // initialize class if needed constantPoolHandle constants(THREAD, caller->constants()); - LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK_NULL); - return result.klass()(); + LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK_NULL); + return result.field_holder(); } @@ -826,11 +826,11 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i if (stub_id == Runtime1::access_field_patching_id) { Bytecode_field field_access(caller_method, bci); - FieldAccessInfo result; // initialize class if needed + fieldDescriptor result; // initialize class if needed Bytecodes::Code code = field_access.code(); constantPoolHandle constants(THREAD, caller_method->constants()); - LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK); - patch_field_offset = result.field_offset(); + LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK); + patch_field_offset = result.offset(); // If we're patching a field which is volatile then at compile it // must not have been know to be volatile, so the generated code diff --git a/hotspot/src/share/vm/ci/ciField.cpp b/hotspot/src/share/vm/ci/ciField.cpp index 1a711ae522a..b08ec3616fa 100644 --- a/hotspot/src/share/vm/ci/ciField.cpp +++ b/hotspot/src/share/vm/ci/ciField.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,6 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constan-pool"); - _cp_index = index; constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants()); // Get the field's name, signature, and type. @@ -116,7 +115,7 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL // The declared holder of this field may not have been loaded. // Bail out with partial field information. if (!holder_is_accessible) { - // _cp_index and _type have already been set. + // _type has already been set. // The default values for _flags and _constant_value will suffice. // We need values for _holder, _offset, and _is_constant, _holder = declared_holder; @@ -146,8 +145,6 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL ciField::ciField(fieldDescriptor *fd): _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) { ASSERT_IN_VM; - _cp_index = -1; - // Get the field's name, signature, and type. ciEnv* env = CURRENT_ENV; _name = env->get_symbol(fd->name()); @@ -351,12 +348,11 @@ bool ciField::will_link(ciInstanceKlass* accessing_klass, } } - FieldAccessInfo result; - constantPoolHandle c_pool(THREAD, - accessing_klass->get_instanceKlass()->constants()); - LinkResolver::resolve_field(result, c_pool, _cp_index, - Bytecodes::java_code(bc), - true, false, KILL_COMPILE_ON_FATAL_(false)); + fieldDescriptor result; + LinkResolver::resolve_field(result, _holder->get_instanceKlass(), + _name->get_symbol(), _signature->get_symbol(), + accessing_klass->get_Klass(), bc, true, false, + KILL_COMPILE_ON_FATAL_(false)); // update the hit-cache, unless there is a problem with memory scoping: if (accessing_klass->is_shared() || !is_shared()) { diff --git a/hotspot/src/share/vm/ci/ciField.hpp b/hotspot/src/share/vm/ci/ciField.hpp index 81af9ca79a9..75263e3f217 100644 --- a/hotspot/src/share/vm/ci/ciField.hpp +++ b/hotspot/src/share/vm/ci/ciField.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -53,9 +53,6 @@ private: ciInstanceKlass* _known_to_link_with_get; ciConstant _constant_value; - // Used for will_link - int _cp_index; - ciType* compute_type(); ciType* compute_type_impl(); diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp index d74e484c66e..c689efa46d6 100644 --- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -522,8 +522,7 @@ ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray* for (JavaFieldStream fs(k); !fs.done(); fs.next()) { if (fs.access_flags().is_static()) continue; - fieldDescriptor fd; - fd.initialize(k, fs.index()); + fieldDescriptor& fd = fs.field_descriptor(); ciField* field = new (arena) ciField(&fd); fields->append(field); } diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp index d0363250ee6..486d8c499b6 100644 --- a/hotspot/src/share/vm/ci/ciMethod.cpp +++ b/hotspot/src/share/vm/ci/ciMethod.cpp @@ -286,7 +286,10 @@ int ciMethod::itable_index() { check_is_loaded(); assert(holder()->is_linked(), "must be linked"); VM_ENTRY_MARK; - return klassItable::compute_itable_index(get_Method()); + Method* m = get_Method(); + if (!m->has_itable_index()) + return Method::nonvirtual_vtable_index; + return m->itable_index(); } #endif // SHARK @@ -1137,6 +1140,10 @@ bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const { // ------------------------------------------------------------------ // ciMethod::check_call bool ciMethod::check_call(int refinfo_index, bool is_static) const { + // This method is used only in C2 from InlineTree::ok_to_inline, + // and is only used under -Xcomp or -XX:CompileTheWorld. + // It appears to fail when applied to an invokeinterface call site. + // FIXME: Remove this method and resolve_method_statically; refactor to use the other LinkResolver entry points. VM_ENTRY_MARK; { EXCEPTION_MARK; diff --git a/hotspot/src/share/vm/ci/ciSymbol.hpp b/hotspot/src/share/vm/ci/ciSymbol.hpp index d54b54009be..3c974cf272e 100644 --- a/hotspot/src/share/vm/ci/ciSymbol.hpp +++ b/hotspot/src/share/vm/ci/ciSymbol.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,7 @@ class ciSymbol : public ciBaseObject { friend class ciInstanceKlass; friend class ciSignature; friend class ciMethod; + friend class ciField; friend class ciObjArrayKlass; private: diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 8972bceb434..dc00790869c 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -3954,9 +3954,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, this_klass->set_has_final_method(); } this_klass->copy_method_ordering(method_ordering, CHECK_NULL); - // The InstanceKlass::_methods_jmethod_ids cache and the - // InstanceKlass::_methods_cached_itable_indices cache are - // both managed on the assumption that the initial cache + // The InstanceKlass::_methods_jmethod_ids cache + // is managed on the assumption that the initial cache // size is equal to the number of methods in the class. If // that changes, then InstanceKlass::idnum_can_increment() // has to be changed accordingly. diff --git a/hotspot/src/share/vm/code/compiledIC.cpp b/hotspot/src/share/vm/code/compiledIC.cpp index e9a63b86623..b9db323e5b2 100644 --- a/hotspot/src/share/vm/code/compiledIC.cpp +++ b/hotspot/src/share/vm/code/compiledIC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -161,31 +161,36 @@ address CompiledIC::stub_address() const { void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { - methodHandle method = call_info->selected_method(); - bool is_invoke_interface = (bytecode == Bytecodes::_invokeinterface && !call_info->has_vtable_index()); assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic"); assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?"); address entry; - if (is_invoke_interface) { - int index = klassItable::compute_itable_index(call_info->resolved_method()()); - entry = VtableStubs::create_stub(false, index, method()); + if (call_info->call_kind() == CallInfo::itable_call) { + assert(bytecode == Bytecodes::_invokeinterface, ""); + int itable_index = call_info->itable_index(); + entry = VtableStubs::find_itable_stub(itable_index); +#ifdef ASSERT assert(entry != NULL, "entry not computed"); + int index = call_info->resolved_method()->itable_index(); + assert(index == itable_index, "CallInfo pre-computes this"); +#endif //ASSERT InstanceKlass* k = call_info->resolved_method()->method_holder(); - assert(k->is_interface(), "sanity check"); + assert(k->verify_itable_index(itable_index), "sanity check"); InlineCacheBuffer::create_transition_stub(this, k, entry); } else { - // Can be different than method->vtable_index(), due to package-private etc. + assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable"); + // Can be different than selected_method->vtable_index(), due to package-private etc. int vtable_index = call_info->vtable_index(); - entry = VtableStubs::create_stub(true, vtable_index, method()); - InlineCacheBuffer::create_transition_stub(this, method(), entry); + assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check"); + entry = VtableStubs::find_vtable_stub(vtable_index); + InlineCacheBuffer::create_transition_stub(this, NULL, entry); } if (TraceICs) { ResourceMark rm; tty->print_cr ("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT, - instruction_address(), method->print_value_string(), entry); + instruction_address(), call_info->selected_method()->print_value_string(), entry); } // We can't check this anymore. With lazy deopt we could have already diff --git a/hotspot/src/share/vm/code/vtableStubs.cpp b/hotspot/src/share/vm/code/vtableStubs.cpp index 0d7b39a0241..7d9d7efaf67 100644 --- a/hotspot/src/share/vm/code/vtableStubs.cpp +++ b/hotspot/src/share/vm/code/vtableStubs.cpp @@ -111,7 +111,7 @@ void VtableStubs::initialize() { } -address VtableStubs::create_stub(bool is_vtable_stub, int vtable_index, Method* method) { +address VtableStubs::find_stub(bool is_vtable_stub, int vtable_index) { assert(vtable_index >= 0, "must be positive"); VtableStub* s = ShareVtableStubs ? lookup(is_vtable_stub, vtable_index) : NULL; diff --git a/hotspot/src/share/vm/code/vtableStubs.hpp b/hotspot/src/share/vm/code/vtableStubs.hpp index aa95fee763c..06f2a67a857 100644 --- a/hotspot/src/share/vm/code/vtableStubs.hpp +++ b/hotspot/src/share/vm/code/vtableStubs.hpp @@ -121,9 +121,11 @@ class VtableStubs : AllStatic { static VtableStub* lookup (bool is_vtable_stub, int vtable_index); static void enter (bool is_vtable_stub, int vtable_index, VtableStub* s); static inline uint hash (bool is_vtable_stub, int vtable_index); + static address find_stub (bool is_vtable_stub, int vtable_index); public: - static address create_stub(bool is_vtable_stub, int vtable_index, Method* method); // return the entry point of a stub for this call + static address find_vtable_stub(int vtable_index) { return find_stub(true, vtable_index); } + static address find_itable_stub(int itable_index) { return find_stub(false, itable_index); } static bool is_entry_point(address pc); // is pc a vtable stub entry point? static bool contains(address pc); // is pc within any stub? static VtableStub* stub_containing(address pc); // stub containing pc or NULL diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp index 4a3019f867f..4c082597b22 100644 --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp @@ -496,15 +496,15 @@ IRT_END IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode)) // resolve field - FieldAccessInfo info; + fieldDescriptor info; constantPoolHandle pool(thread, method(thread)->constants()); bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_putstatic); bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic); { JvmtiHideSingleStepping jhss(thread); - LinkResolver::resolve_field(info, pool, get_index_u2_cpcache(thread, bytecode), - bytecode, false, CHECK); + LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode), + bytecode, CHECK); } // end JvmtiHideSingleStepping // check if link resolution caused cpCache to be updated @@ -524,7 +524,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode // class is intitialized. This is required so that access to the static // field will call the initialization function every time until the class // is completely initialized ala. in 2.17.5 in JVM Specification. - InstanceKlass *klass = InstanceKlass::cast(info.klass()()); + InstanceKlass* klass = InstanceKlass::cast(info.field_holder()); bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) && !klass->is_initialized()); Bytecodes::Code get_code = (Bytecodes::Code)0; @@ -539,9 +539,9 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode cache_entry(thread)->set_field( get_code, put_code, - info.klass(), - info.field_index(), - info.field_offset(), + info.field_holder(), + info.index(), + info.offset(), state, info.access_flags().is_final(), info.access_flags().is_volatile(), @@ -686,29 +686,55 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes if (already_resolved(thread)) return; if (bytecode == Bytecodes::_invokeinterface) { - if (TraceItables && Verbose) { ResourceMark rm(thread); tty->print_cr("Resolving: klass: %s to method: %s", info.resolved_klass()->name()->as_C_string(), info.resolved_method()->name()->as_C_string()); } + } +#ifdef ASSERT + if (bytecode == Bytecodes::_invokeinterface) { if (info.resolved_method()->method_holder() == SystemDictionary::Object_klass()) { // NOTE: THIS IS A FIX FOR A CORNER CASE in the JVM spec - // (see also cpCacheOop.cpp for details) + // (see also CallInfo::set_interface for details) + assert(info.call_kind() == CallInfo::vtable_call || + info.call_kind() == CallInfo::direct_call, ""); methodHandle rm = info.resolved_method(); assert(rm->is_final() || info.has_vtable_index(), "should have been set already"); - cache_entry(thread)->set_method(bytecode, rm, info.vtable_index()); + } else if (!info.resolved_method()->has_itable_index()) { + // Resolved something like CharSequence.toString. Use vtable not itable. + assert(info.call_kind() != CallInfo::itable_call, ""); } else { // Setup itable entry - int index = klassItable::compute_itable_index(info.resolved_method()()); - cache_entry(thread)->set_interface_call(info.resolved_method(), index); + assert(info.call_kind() == CallInfo::itable_call, ""); + int index = info.resolved_method()->itable_index(); + assert(info.itable_index() == index, ""); } } else { - cache_entry(thread)->set_method( + assert(info.call_kind() == CallInfo::direct_call || + info.call_kind() == CallInfo::vtable_call, ""); + } +#endif + switch (info.call_kind()) { + case CallInfo::direct_call: + cache_entry(thread)->set_direct_call( + bytecode, + info.resolved_method()); + break; + case CallInfo::vtable_call: + cache_entry(thread)->set_vtable_call( bytecode, info.resolved_method(), info.vtable_index()); + break; + case CallInfo::itable_call: + cache_entry(thread)->set_itable_call( + bytecode, + info.resolved_method(), + info.itable_index()); + break; + default: ShouldNotReachHere(); } } IRT_END diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index b0bd678b597..44ac9e0862d 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -46,19 +46,6 @@ #include "runtime/thread.inline.hpp" #include "runtime/vmThread.hpp" -//------------------------------------------------------------------------------------------------------------------------ -// Implementation of FieldAccessInfo - -void FieldAccessInfo::set(KlassHandle klass, Symbol* name, int field_index, int field_offset, -BasicType field_type, AccessFlags access_flags) { - _klass = klass; - _name = name; - _field_index = field_index; - _field_offset = field_offset; - _field_type = field_type; - _access_flags = access_flags; -} - //------------------------------------------------------------------------------------------------------------------------ // Implementation of CallInfo @@ -66,26 +53,25 @@ BasicType field_type, AccessFlags access_flags) { void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) { int vtable_index = Method::nonvirtual_vtable_index; - set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK); + set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK); } -void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, TRAPS) { +void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index, TRAPS) { // This is only called for interface methods. If the resolved_method // comes from java/lang/Object, it can be the subject of a virtual call, so // we should pick the vtable index from the resolved method. - // Other than that case, there is no valid vtable index to specify. - int vtable_index = Method::invalid_vtable_index; - if (resolved_method->method_holder() == SystemDictionary::Object_klass()) { - assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check"); - vtable_index = resolved_method->vtable_index(); - } - set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); + // In that case, the caller must call set_virtual instead of set_interface. + assert(resolved_method->method_holder()->is_interface(), ""); + assert(itable_index == resolved_method()->itable_index(), ""); + set_common(resolved_klass, selected_klass, resolved_method, selected_method, CallInfo::itable_call, itable_index, CHECK); } void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, "valid index"); - set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); + assert(vtable_index < 0 || !resolved_method->has_vtable_index() || vtable_index == resolved_method->vtable_index(), ""); + CallKind kind = (vtable_index >= 0 && !resolved_method->can_be_statically_bound() ? CallInfo::vtable_call : CallInfo::direct_call); + set_common(resolved_klass, selected_klass, resolved_method, selected_method, kind, vtable_index, CHECK); assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call"); } @@ -98,20 +84,29 @@ void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix resolved_method->is_compiled_lambda_form(), "linkMethod must return one of these"); int vtable_index = Method::nonvirtual_vtable_index; - assert(resolved_method->vtable_index() == vtable_index, ""); - set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK); + assert(!resolved_method->has_vtable_index(), ""); + set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK); _resolved_appendix = resolved_appendix; _resolved_method_type = resolved_method_type; } -void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { +void CallInfo::set_common(KlassHandle resolved_klass, + KlassHandle selected_klass, + methodHandle resolved_method, + methodHandle selected_method, + CallKind kind, + int index, + TRAPS) { assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond"); _resolved_klass = resolved_klass; _selected_klass = selected_klass; _resolved_method = resolved_method; _selected_method = selected_method; - _vtable_index = vtable_index; + _call_kind = kind; + _call_index = index; _resolved_appendix = Handle(); + DEBUG_ONLY(verify()); // verify before making side effects + if (CompilationPolicy::must_be_compiled(selected_method)) { // This path is unusual, mostly used by the '-Xcomp' stress test mode. @@ -138,6 +133,65 @@ void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass } } +// utility query for unreflecting a method +CallInfo::CallInfo(Method* resolved_method, Klass* resolved_klass) { + Klass* resolved_method_holder = resolved_method->method_holder(); + if (resolved_klass == NULL) { // 2nd argument defaults to holder of 1st + resolved_klass = resolved_method_holder; + } + _resolved_klass = resolved_klass; + _selected_klass = resolved_klass; + _resolved_method = resolved_method; + _selected_method = resolved_method; + // classify: + CallKind kind = CallInfo::unknown_kind; + int index = resolved_method->vtable_index(); + if (resolved_method->can_be_statically_bound()) { + kind = CallInfo::direct_call; + } else if (!resolved_method_holder->is_interface()) { + // Could be an Object method inherited into an interface, but still a vtable call. + kind = CallInfo::vtable_call; + } else if (!resolved_klass->is_interface()) { + // A miranda method. Compute the vtable index. + ResourceMark rm; + klassVtable* vt = InstanceKlass::cast(resolved_klass)->vtable(); + index = vt->index_of_miranda(resolved_method->name(), + resolved_method->signature()); + kind = CallInfo::vtable_call; + } else { + // A regular interface call. + kind = CallInfo::itable_call; + index = resolved_method->itable_index(); + } + assert(index == Method::nonvirtual_vtable_index || index >= 0, err_msg("bad index %d", index)); + _call_kind = kind; + _call_index = index; + _resolved_appendix = Handle(); + DEBUG_ONLY(verify()); +} + +#ifdef ASSERT +void CallInfo::verify() { + switch (call_kind()) { // the meaning and allowed value of index depends on kind + case CallInfo::direct_call: + if (_call_index == Method::nonvirtual_vtable_index) break; + // else fall through to check vtable index: + case CallInfo::vtable_call: + assert(resolved_klass()->verify_vtable_index(_call_index), ""); + break; + case CallInfo::itable_call: + assert(resolved_method()->method_holder()->verify_itable_index(_call_index), ""); + break; + case CallInfo::unknown_kind: + assert(call_kind() != CallInfo::unknown_kind, "CallInfo must be set"); + break; + default: + fatal(err_msg_res("Unexpected call kind %d", call_kind())); + } +} +#endif //ASSERT + + //------------------------------------------------------------------------------------------------------------------------ // Klass resolution @@ -163,13 +217,6 @@ void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, i result = KlassHandle(THREAD, result_oop); } -void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) { - Klass* result_oop = - ConstantPool::klass_ref_at_if_loaded_check(pool, index, CHECK); - result = KlassHandle(THREAD, result_oop); -} - - //------------------------------------------------------------------------------------------------------------------------ // Method resolution // @@ -360,7 +407,12 @@ void LinkResolver::check_method_accessability(KlassHandle ref_klass, void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass, Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) { - + // This method is used only + // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call), + // and + // (2) in Bytecode_invoke::static_target + // It appears to fail when applied to an invokeinterface call site. + // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points. // resolve klass if (code == Bytecodes::_invokedynamic) { resolved_klass = SystemDictionary::MethodHandle_klass(); @@ -580,45 +632,49 @@ void LinkResolver::check_field_accessability(KlassHandle ref_klass, } } -void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS) { - resolve_field(result, pool, index, byte, check_only, true, CHECK); +void LinkResolver::resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) { + // Load these early in case the resolve of the containing klass fails + Symbol* field = pool->name_ref_at(index); + Symbol* sig = pool->signature_ref_at(index); + + // resolve specified klass + KlassHandle resolved_klass; + resolve_klass(resolved_klass, pool, index, CHECK); + + KlassHandle current_klass(THREAD, pool->pool_holder()); + resolve_field(result, resolved_klass, field, sig, current_klass, byte, true, true, CHECK); } -void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS) { +void LinkResolver::resolve_field(fieldDescriptor& fd, KlassHandle resolved_klass, Symbol* field, Symbol* sig, + KlassHandle current_klass, Bytecodes::Code byte, bool check_access, bool initialize_class, + TRAPS) { assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic || - byte == Bytecodes::_getfield || byte == Bytecodes::_putfield, "bad bytecode"); + byte == Bytecodes::_getfield || byte == Bytecodes::_putfield || + (byte == Bytecodes::_nop && !check_access), "bad field access bytecode"); bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic); bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic); - // resolve specified klass - KlassHandle resolved_klass; - if (update_pool) { - resolve_klass(resolved_klass, pool, index, CHECK); - } else { - resolve_klass_no_update(resolved_klass, pool, index, CHECK); - } - // Load these early in case the resolve of the containing klass fails - Symbol* field = pool->name_ref_at(index); - Symbol* sig = pool->signature_ref_at(index); // Check if there's a resolved klass containing the field - if( resolved_klass.is_null() ) { + if (resolved_klass.is_null()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); } // Resolve instance field - fieldDescriptor fd; // find_field initializes fd if found KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd)); // check if field exists; i.e., if a klass containing the field def has been selected - if (sel_klass.is_null()){ + if (sel_klass.is_null()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); } + if (!check_access) + // Access checking may be turned off when calling from within the VM. + return; + // check access - KlassHandle ref_klass(THREAD, pool->pool_holder()); - check_field_accessability(ref_klass, resolved_klass, sel_klass, fd, CHECK); + check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK); // check for errors if (is_static != fd.is_static()) { @@ -629,7 +685,7 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo } // Final fields can only be accessed from its own class. - if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) { + if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) { THROW(vmSymbols::java_lang_IllegalAccessError()); } @@ -639,19 +695,18 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo // // note 2: we don't want to force initialization if we are just checking // if the field access is legal; e.g., during compilation - if (is_static && !check_only) { + if (is_static && initialize_class) { sel_klass->initialize(CHECK); } - { + if (sel_klass() != current_klass()) { HandleMark hm(THREAD); - Handle ref_loader (THREAD, InstanceKlass::cast(ref_klass())->class_loader()); + Handle ref_loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); Handle sel_loader (THREAD, InstanceKlass::cast(sel_klass())->class_loader()); - Symbol* signature_ref = pool->signature_ref_at(index); { ResourceMark rm(THREAD); Symbol* failed_type_symbol = - SystemDictionary::check_signature_loaders(signature_ref, + SystemDictionary::check_signature_loaders(sig, ref_loader, sel_loader, false, CHECK); @@ -677,9 +732,6 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo // return information. note that the klass is set to the actual klass containing the // field, otherwise access of static fields in superclasses will not work. - KlassHandle holder (THREAD, fd.field_holder()); - Symbol* name = fd.name(); - result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags()); } @@ -906,10 +958,6 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, THROW(vmSymbols::java_lang_NullPointerException()); } - // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s - // has not been rewritten, and the vtable initialized. - assert(resolved_method->method_holder()->is_linked(), "must be linked"); - // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since // a missing receiver might result in a bogus lookup. @@ -920,6 +968,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, vtable_index = vtable_index_of_miranda_method(resolved_klass, resolved_method->name(), resolved_method->signature(), CHECK); + assert(vtable_index >= 0 , "we should have valid vtable index at this point"); InstanceKlass* inst = InstanceKlass::cast(recv_klass()); @@ -927,6 +976,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, } else { // at this point we are sure that resolved_method is virtual and not // a miranda method; therefore, it must have a valid vtable index. + assert(!resolved_method->has_itable_index(), ""); vtable_index = resolved_method->vtable_index(); // We could get a negative vtable_index for final methods, // because as an optimization they are they are never put in the vtable, @@ -1006,6 +1056,12 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand lookup_instance_method_in_klasses(sel_method, recv_klass, resolved_method->name(), resolved_method->signature(), CHECK); + if (sel_method.is_null() && !check_null_and_abstract) { + // In theory this is a harmless placeholder value, but + // in practice leaving in null affects the nsk default method tests. + // This needs further study. + sel_method = resolved_method; + } // check if method exists if (sel_method.is_null()) { ResourceMark rm(THREAD); @@ -1046,7 +1102,14 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand sel_method->signature())); } // setup result - result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK); + if (!resolved_method->has_itable_index()) { + int vtable_index = resolved_method->vtable_index(); + assert(vtable_index == sel_method->vtable_index(), "sanity check"); + result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK); + return; + } + int itable_index = resolved_method()->itable_index(); + result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK); } @@ -1293,7 +1356,8 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle po } if (TraceMethodHandles) { - tty->print_cr("resolve_invokedynamic #%d %s %s", + ResourceMark rm(THREAD); + tty->print_cr("resolve_invokedynamic #%d %s %s", ConstantPool::decode_invokedynamic_index(index), method_name->as_C_string(), method_signature->as_C_string()); tty->print(" BSM info: "); bootstrap_specifier->print(); @@ -1342,9 +1406,16 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result, //------------------------------------------------------------------------------------------------------------------------ #ifndef PRODUCT -void FieldAccessInfo::print() { +void CallInfo::print() { ResourceMark rm; - tty->print_cr("Field %s@%d", name()->as_C_string(), field_offset()); + const char* kindstr = "unknown"; + switch (_call_kind) { + case direct_call: kindstr = "direct"; break; + case vtable_call: kindstr = "vtable"; break; + case itable_call: kindstr = "itable"; break; + } + tty->print_cr("Call %s@%d %s", kindstr, _call_index, + _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string()); } #endif diff --git a/hotspot/src/share/vm/interpreter/linkResolver.hpp b/hotspot/src/share/vm/interpreter/linkResolver.hpp index 4054eeb35ef..0fb551a23a8 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.hpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,63 +30,54 @@ // All the necessary definitions for run-time link resolution. -// LinkInfo & its subclasses provide all the information gathered -// for a particular link after resolving it. A link is any reference +// CallInfo provides all the information gathered for a particular +// linked call site after resolving it. A link is any reference // made from within the bytecodes of a method to an object outside of // that method. If the info is invalid, the link has not been resolved // successfully. -class LinkInfo VALUE_OBJ_CLASS_SPEC { -}; - - -// Link information for getfield/putfield & getstatic/putstatic bytecodes. - -class FieldAccessInfo: public LinkInfo { - protected: - KlassHandle _klass; - Symbol* _name; - AccessFlags _access_flags; - int _field_index; // original index in the klass - int _field_offset; - BasicType _field_type; - +class CallInfo VALUE_OBJ_CLASS_SPEC { public: - void set(KlassHandle klass, Symbol* name, int field_index, int field_offset, - BasicType field_type, AccessFlags access_flags); - KlassHandle klass() const { return _klass; } - Symbol* name() const { return _name; } - int field_index() const { return _field_index; } - int field_offset() const { return _field_offset; } - BasicType field_type() const { return _field_type; } - AccessFlags access_flags() const { return _access_flags; } - - // debugging - void print() PRODUCT_RETURN; -}; - - -// Link information for all calls. - -class CallInfo: public LinkInfo { + // Ways that a method call might be selected (or not) based on receiver type. + // Note that an invokevirtual instruction might be linked with no_dispatch, + // and an invokeinterface instruction might be linked with any of the three options + enum CallKind { + direct_call, // jump into resolved_method (must be concrete) + vtable_call, // select recv.klass.method_at_vtable(index) + itable_call, // select recv.klass.method_at_itable(resolved_method.holder, index) + unknown_kind = -1 + }; private: - KlassHandle _resolved_klass; // static receiver klass + KlassHandle _resolved_klass; // static receiver klass, resolved from a symbolic reference KlassHandle _selected_klass; // dynamic receiver class (same as static, or subklass) methodHandle _resolved_method; // static target method methodHandle _selected_method; // dynamic (actual) target method - int _vtable_index; // vtable index of selected method + CallKind _call_kind; // kind of call (static(=bytecode static/special + + // others inferred), vtable, itable) + int _call_index; // vtable or itable index of selected class method (if any) Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix) Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites) void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS); - void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method , TRAPS); + void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index , TRAPS); void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS); void set_handle( methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS); - void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS); + void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, CallKind kind, int index, TRAPS); friend class LinkResolver; public: + CallInfo() { +#ifndef PRODUCT + _call_kind = CallInfo::unknown_kind; + _call_index = Method::garbage_vtable_index; +#endif //PRODUCT + } + + // utility to extract an effective CallInfo from a method and an optional receiver limit + // does not queue the method for compilation + CallInfo(Method* resolved_method, Klass* resolved_klass = NULL); + KlassHandle resolved_klass() const { return _resolved_klass; } KlassHandle selected_klass() const { return _selected_klass; } methodHandle resolved_method() const { return _resolved_method; } @@ -95,21 +86,43 @@ class CallInfo: public LinkInfo { Handle resolved_method_type() const { return _resolved_method_type; } BasicType result_type() const { return selected_method()->result_type(); } - bool has_vtable_index() const { return _vtable_index >= 0; } - bool is_statically_bound() const { return _vtable_index == Method::nonvirtual_vtable_index; } + CallKind call_kind() const { return _call_kind; } + int call_index() const { return _call_index; } int vtable_index() const { // Even for interface calls the vtable index could be non-negative. // See CallInfo::set_interface. assert(has_vtable_index() || is_statically_bound(), ""); - return _vtable_index; + assert(call_kind() == vtable_call || call_kind() == direct_call, ""); + // The returned value is < 0 if the call is statically bound. + // But, the returned value may be >= 0 even if the kind is direct_call. + // It is up to the caller to decide which way to go. + return _call_index; } + int itable_index() const { + assert(call_kind() == itable_call, ""); + // The returned value is always >= 0, a valid itable index. + return _call_index; + } + + // debugging +#ifdef ASSERT + bool has_vtable_index() const { return _call_index >= 0 && _call_kind != CallInfo::itable_call; } + bool is_statically_bound() const { return _call_index == Method::nonvirtual_vtable_index; } +#endif //ASSERT + void verify() PRODUCT_RETURN; + void print() PRODUCT_RETURN; }; +// Link information for getfield/putfield & getstatic/putstatic bytecodes +// is represented using a fieldDescriptor. // The LinkResolver is used to resolve constant-pool references at run-time. // It does all necessary link-time checks & throws exceptions if necessary. class LinkResolver: AllStatic { + friend class klassVtable; + friend class klassItable; + private: static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); @@ -120,7 +133,6 @@ class LinkResolver: AllStatic { static int vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); - static void resolve_klass_no_update (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); // no update of constantPool entry static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); @@ -148,9 +160,16 @@ class LinkResolver: AllStatic { Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS); // runtime/static resolving for fields - static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS); - // takes an extra bool argument "update_pool" to decide whether to update the constantPool during klass resolution. - static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS); + static void resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS); + static void resolve_field(fieldDescriptor& result, KlassHandle resolved_klass, Symbol* field_name, Symbol* field_signature, + KlassHandle current_klass, Bytecodes::Code access_kind, bool check_access, bool initialize_class, TRAPS); + + // source of access_kind codes: + static Bytecodes::Code field_access_kind(bool is_static, bool is_put) { + return (is_static + ? (is_put ? Bytecodes::_putstatic : Bytecodes::_getstatic) + : (is_put ? Bytecodes::_putfield : Bytecodes::_getfield )); + } // runtime resolving: // resolved_klass = specified class (i.e., static receiver class) diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index 8033d7e3850..673da4dd622 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -396,32 +396,6 @@ Klass* ConstantPool::klass_ref_at_if_loaded(constantPoolHandle this_oop, int whi } -// This is an interface for the compiler that allows accessing non-resolved entries -// in the constant pool - but still performs the validations tests. Must be used -// in a pre-parse of the compiler - to determine what it can do and not do. -// Note: We cannot update the ConstantPool from the vm_thread. -Klass* ConstantPool::klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int index, TRAPS) { - int which = this_oop->klass_ref_index_at(index); - CPSlot entry = this_oop->slot_at(which); - if (entry.is_resolved()) { - assert(entry.get_klass()->is_klass(), "must be"); - return entry.get_klass(); - } else { - assert(entry.is_unresolved(), "must be either symbol or klass"); - Symbol* name = entry.get_symbol(); - oop loader = this_oop->pool_holder()->class_loader(); - oop protection_domain = this_oop->pool_holder()->protection_domain(); - Handle h_loader(THREAD, loader); - Handle h_prot (THREAD, protection_domain); - KlassHandle k(THREAD, SystemDictionary::find(name, h_loader, h_prot, THREAD)); - - // Do access check for klasses - if( k.not_null() ) verify_constant_pool_resolve(this_oop, k, CHECK_NULL); - return k(); - } -} - - Method* ConstantPool::method_at_if_loaded(constantPoolHandle cpool, int which) { if (cpool->cache() == NULL) return NULL; // nothing to load yet diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp index eca2dcd9c56..b7d607d763a 100644 --- a/hotspot/src/share/vm/oops/constantPool.hpp +++ b/hotspot/src/share/vm/oops/constantPool.hpp @@ -730,8 +730,6 @@ class ConstantPool : public Metadata { static oop method_type_at_if_loaded (constantPoolHandle this_oop, int which); static Klass* klass_at_if_loaded (constantPoolHandle this_oop, int which); static Klass* klass_ref_at_if_loaded (constantPoolHandle this_oop, int which); - // Same as above - but does LinkResolving. - static Klass* klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int which, TRAPS); // Routines currently used for annotations (only called by jvm.cpp) but which might be used in the // future by other Java code. These take constant pool indices rather than diff --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp index 9e2b83c2caf..9d358955025 100644 --- a/hotspot/src/share/vm/oops/cpCache.cpp +++ b/hotspot/src/share/vm/oops/cpCache.cpp @@ -140,9 +140,10 @@ void ConstantPoolCacheEntry::set_parameter_size(int value) { err_msg("size must not change: parameter_size=%d, value=%d", parameter_size(), value)); } -void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, - methodHandle method, - int vtable_index) { +void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code, + methodHandle method, + int vtable_index) { + bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean assert(method->interpreter_entry() != NULL, "should have been set at this point"); assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); @@ -160,7 +161,8 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, // ...and fall through as if we were handling invokevirtual: case Bytecodes::_invokevirtual: { - if (method->can_be_statically_bound()) { + if (!is_vtable_call) { + assert(method->can_be_statically_bound(), ""); // set_f2_as_vfinal_method checks if is_vfinal flag is true. set_method_flags(as_TosState(method->result_type()), ( 1 << is_vfinal_shift) | @@ -169,6 +171,7 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, method()->size_of_parameters()); set_f2_as_vfinal_method(method()); } else { + assert(!method->can_be_statically_bound(), ""); assert(vtable_index >= 0, "valid index"); assert(!method->is_final_method(), "sanity"); set_method_flags(as_TosState(method->result_type()), @@ -182,6 +185,7 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: + assert(!is_vtable_call, ""); // Note: Read and preserve the value of the is_vfinal flag on any // invokevirtual bytecode shared with this constant pool cache entry. // It is cheap and safe to consult is_vfinal() at all times. @@ -232,8 +236,22 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, NOT_PRODUCT(verify(tty)); } +void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, methodHandle method) { + int index = Method::nonvirtual_vtable_index; + // index < 0; FIXME: inline and customize set_direct_or_vtable_call + set_direct_or_vtable_call(invoke_code, method, index); +} -void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) { +void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, methodHandle method, int index) { + // either the method is a miranda or its holder should accept the given index + assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), ""); + // index >= 0; FIXME: inline and customize set_direct_or_vtable_call + set_direct_or_vtable_call(invoke_code, method, index); +} + +void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) { + assert(method->method_holder()->verify_itable_index(index), ""); + assert(invoke_code == Bytecodes::_invokeinterface, ""); InstanceKlass* interf = method->method_holder(); assert(interf->is_interface(), "must be an interface"); assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here"); diff --git a/hotspot/src/share/vm/oops/cpCache.hpp b/hotspot/src/share/vm/oops/cpCache.hpp index c15b4a54bd6..77c0deb9d8f 100644 --- a/hotspot/src/share/vm/oops/cpCache.hpp +++ b/hotspot/src/share/vm/oops/cpCache.hpp @@ -219,15 +219,29 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC { Klass* root_klass // needed by the GC to dirty the klass ); - void set_method( // sets entry to resolved method entry + private: + void set_direct_or_vtable_call( Bytecodes::Code invoke_code, // the bytecode used for invoking the method methodHandle method, // the method/prototype if any (NULL, otherwise) int vtable_index // the vtable index if any, else negative ); - void set_interface_call( - methodHandle method, // Resolved method - int index // Method index into interface + public: + void set_direct_call( // sets entry to exact concrete method entry + Bytecodes::Code invoke_code, // the bytecode used for invoking the method + methodHandle method // the method to call + ); + + void set_vtable_call( // sets entry to vtable index + Bytecodes::Code invoke_code, // the bytecode used for invoking the method + methodHandle method, // resolved method which declares the vtable index + int vtable_index // the vtable index + ); + + void set_itable_call( + Bytecodes::Code invoke_code, // the bytecode used; must be invokeinterface + methodHandle method, // the resolved interface method + int itable_index // index into itable for the method ); void set_method_handle( diff --git a/hotspot/src/share/vm/oops/fieldStreams.hpp b/hotspot/src/share/vm/oops/fieldStreams.hpp index acc590c970c..17f1b0a8585 100644 --- a/hotspot/src/share/vm/oops/fieldStreams.hpp +++ b/hotspot/src/share/vm/oops/fieldStreams.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ #include "oops/instanceKlass.hpp" #include "oops/fieldInfo.hpp" +#include "runtime/fieldDescriptor.hpp" // The is the base class for iteration over the fields array // describing the declared fields in the class. Several subclasses @@ -43,8 +44,10 @@ class FieldStreamBase : public StackObj { int _index; int _limit; int _generic_signature_slot; + fieldDescriptor _fd_buf; FieldInfo* field() const { return FieldInfo::from_field_array(_fields, _index); } + InstanceKlass* field_holder() const { return _constants->pool_holder(); } int init_generic_signature_start_slot() { int length = _fields->length(); @@ -102,6 +105,7 @@ class FieldStreamBase : public StackObj { _index = 0; _limit = klass->java_fields_count(); init_generic_signature_start_slot(); + assert(klass == field_holder(), ""); } FieldStreamBase(instanceKlassHandle klass) { _fields = klass->fields(); @@ -109,6 +113,7 @@ class FieldStreamBase : public StackObj { _index = 0; _limit = klass->java_fields_count(); init_generic_signature_start_slot(); + assert(klass == field_holder(), ""); } // accessors @@ -180,6 +185,12 @@ class FieldStreamBase : public StackObj { return field()->contended_group(); } + // bridge to a heavier API: + fieldDescriptor& field_descriptor() const { + fieldDescriptor& field = const_cast(_fd_buf); + field.reinitialize(field_holder(), _index); + return field; + } }; // Iterate over only the internal fields diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 29c77a07ccb..cf77300dcf0 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -286,7 +286,6 @@ InstanceKlass::InstanceKlass(int vtable_len, init_previous_versions(); set_generic_signature_index(0); release_set_methods_jmethod_ids(NULL); - release_set_methods_cached_itable_indices(NULL); set_annotations(NULL); set_jvmti_cached_class_field_map(NULL); set_initial_method_idnum(0); @@ -1149,7 +1148,7 @@ bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* Symbol* f_name = fs.name(); Symbol* f_sig = fs.signature(); if (f_name == name && f_sig == sig) { - fd->initialize(const_cast(this), fs.index()); + fd->reinitialize(const_cast(this), fs.index()); return true; } } @@ -1218,7 +1217,7 @@ Klass* InstanceKlass::find_field(Symbol* name, Symbol* sig, bool is_static, fiel bool InstanceKlass::find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const { for (JavaFieldStream fs(this); !fs.done(); fs.next()) { if (fs.offset() == offset) { - fd->initialize(const_cast(this), fs.index()); + fd->reinitialize(const_cast(this), fs.index()); if (fd->is_static() == is_static) return true; } } @@ -1251,8 +1250,7 @@ void InstanceKlass::methods_do(void f(Method* method)) { void InstanceKlass::do_local_static_fields(FieldClosure* cl) { for (JavaFieldStream fs(this); !fs.done(); fs.next()) { if (fs.access_flags().is_static()) { - fieldDescriptor fd; - fd.initialize(this, fs.index()); + fieldDescriptor& fd = fs.field_descriptor(); cl->do_field(&fd); } } @@ -1268,8 +1266,7 @@ void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAP void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_oop, void f(fieldDescriptor* fd, TRAPS), TRAPS) { for (JavaFieldStream fs(this_oop()); !fs.done(); fs.next()) { if (fs.access_flags().is_static()) { - fieldDescriptor fd; - fd.initialize(this_oop(), fs.index()); + fieldDescriptor& fd = fs.field_descriptor(); f(&fd, CHECK); } } @@ -1291,7 +1288,7 @@ void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) { int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1), mtClass); int j = 0; for (int i = 0; i < length; i += 1) { - fd.initialize(this, i); + fd.reinitialize(this, i); if (!fd.is_static()) { fields_sorted[j + 0] = fd.offset(); fields_sorted[j + 1] = i; @@ -1303,7 +1300,7 @@ void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) { // _sort_Fn is defined in growableArray.hpp. qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset); for (int i = 0; i < length; i += 2) { - fd.initialize(this, fields_sorted[i + 1]); + fd.reinitialize(this, fields_sorted[i + 1]); assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields"); cl->do_field(&fd); } @@ -1686,87 +1683,6 @@ jmethodID InstanceKlass::jmethod_id_or_null(Method* method) { } -// Cache an itable index -void InstanceKlass::set_cached_itable_index(size_t idnum, int index) { - int* indices = methods_cached_itable_indices_acquire(); - int* to_dealloc_indices = NULL; - - // We use a double-check locking idiom here because this cache is - // performance sensitive. In the normal system, this cache only - // transitions from NULL to non-NULL which is safe because we use - // release_set_methods_cached_itable_indices() to advertise the - // new cache. A partially constructed cache should never be seen - // by a racing thread. Cache reads and writes proceed without a - // lock, but creation of the cache itself requires no leaks so a - // lock is generally acquired in that case. - // - // If the RedefineClasses() API has been used, then this cache can - // grow and we'll have transitions from non-NULL to bigger non-NULL. - // Cache creation requires no leaks and we require safety between all - // cache accesses and freeing of the old cache so a lock is generally - // acquired when the RedefineClasses() API has been used. - - if (indices == NULL || idnum_can_increment()) { - // we need a cache or the cache can grow - MutexLocker ml(JNICachedItableIndex_lock); - // reacquire the cache to see if another thread already did the work - indices = methods_cached_itable_indices_acquire(); - size_t length = 0; - // cache size is stored in element[0], other elements offset by one - if (indices == NULL || (length = (size_t)indices[0]) <= idnum) { - size_t size = MAX2(idnum+1, (size_t)idnum_allocated_count()); - int* new_indices = NEW_C_HEAP_ARRAY(int, size+1, mtClass); - new_indices[0] = (int)size; - // copy any existing entries - size_t i; - for (i = 0; i < length; i++) { - new_indices[i+1] = indices[i+1]; - } - // Set all the rest to -1 - for (i = length; i < size; i++) { - new_indices[i+1] = -1; - } - if (indices != NULL) { - // We have an old cache to delete so save it for after we - // drop the lock. - to_dealloc_indices = indices; - } - release_set_methods_cached_itable_indices(indices = new_indices); - } - - if (idnum_can_increment()) { - // this cache can grow so we have to write to it safely - indices[idnum+1] = index; - } - } else { - CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); - } - - if (!idnum_can_increment()) { - // The cache cannot grow and this JNI itable index value does not - // have to be unique like a jmethodID. If there is a race to set it, - // it doesn't matter. - indices[idnum+1] = index; - } - - if (to_dealloc_indices != NULL) { - // we allocated a new cache so free the old one - FreeHeap(to_dealloc_indices); - } -} - - -// Retrieve a cached itable index -int InstanceKlass::cached_itable_index(size_t idnum) { - int* indices = methods_cached_itable_indices_acquire(); - if (indices != NULL && ((size_t)indices[0]) > idnum) { - // indices exist and are long enough, retrieve possible cached - return indices[idnum+1]; - } - return -1; -} - - // // Walk the list of dependent nmethods searching for nmethods which // are dependent on the changes that were passed in and mark them for @@ -2326,12 +2242,6 @@ void InstanceKlass::release_C_heap_structures() { } } - int* indices = methods_cached_itable_indices_acquire(); - if (indices != (int*)NULL) { - release_set_methods_cached_itable_indices(NULL); - FreeHeap(indices); - } - // release dependencies nmethodBucket* b = _dependencies; _dependencies = NULL; @@ -2782,6 +2692,18 @@ static const char* state_names[] = { "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error" }; +static void print_vtable(intptr_t* start, int len, outputStream* st) { + for (int i = 0; i < len; i++) { + intptr_t e = start[i]; + st->print("%d : " INTPTR_FORMAT, i, e); + if (e != 0 && ((Metadata*)e)->is_metaspace_object()) { + st->print(" "); + ((Metadata*)e)->print_value_on(st); + } + st->cr(); + } +} + void InstanceKlass::print_on(outputStream* st) const { assert(is_klass(), "must be klass"); Klass::print_on(st); @@ -2816,7 +2738,7 @@ void InstanceKlass::print_on(outputStream* st) const { st->print(BULLET"arrays: "); array_klasses()->print_value_on_maybe_null(st); st->cr(); st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr(); - if (Verbose) { + if (Verbose || WizardMode) { Array* method_array = methods(); for(int i = 0; i < method_array->length(); i++) { st->print("%d : ", i); method_array->at(i)->print_value(); st->cr(); @@ -2874,7 +2796,9 @@ void InstanceKlass::print_on(outputStream* st) const { st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr(); st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr(); st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), start_of_vtable()); st->cr(); + if (vtable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_vtable(), vtable_length(), st); st->print(BULLET"itable length %d (start addr: " INTPTR_FORMAT ")", itable_length(), start_of_itable()); st->cr(); + if (itable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_itable(), itable_length(), st); st->print_cr(BULLET"---- static fields (%d words):", static_field_size()); FieldPrinter print_static_field(st); ((InstanceKlass*)this)->do_local_static_fields(&print_static_field); @@ -2896,6 +2820,7 @@ void InstanceKlass::print_on(outputStream* st) const { void InstanceKlass::print_value_on(outputStream* st) const { assert(is_klass(), "must be klass"); + if (Verbose || WizardMode) access_flags().print_on(st); name()->print_value_on(st); } diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 123f6b17911..3bd4e9de40c 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -245,7 +245,6 @@ class InstanceKlass: public Klass { MemberNameTable* _member_names; // Member names JNIid* _jni_ids; // First JNI identifier for static fields in this class jmethodID* _methods_jmethod_ids; // jmethodIDs corresponding to method_idnum, or NULL if none - int* _methods_cached_itable_indices; // itable_index cache for JNI invoke corresponding to methods idnum, or NULL nmethodBucket* _dependencies; // list of dependent nmethods nmethod* _osr_nmethods_head; // Head of list of on-stack replacement nmethods for this class BreakpointInfo* _breakpoints; // bpt lists, managed by Method* @@ -690,10 +689,6 @@ class InstanceKlass: public Klass { size_t *length_p, jmethodID* id_p); jmethodID jmethod_id_or_null(Method* method); - // cached itable index support - void set_cached_itable_index(size_t idnum, int index); - int cached_itable_index(size_t idnum); - // annotations support Annotations* annotations() const { return _annotations; } void set_annotations(Annotations* anno) { _annotations = anno; } @@ -994,11 +989,6 @@ private: void release_set_methods_jmethod_ids(jmethodID* jmeths) { OrderAccess::release_store_ptr(&_methods_jmethod_ids, jmeths); } - int* methods_cached_itable_indices_acquire() const - { return (int*)OrderAccess::load_ptr_acquire(&_methods_cached_itable_indices); } - void release_set_methods_cached_itable_indices(int* indices) - { OrderAccess::release_store_ptr(&_methods_cached_itable_indices, indices); } - // Lock during initialization public: // Lock for (1) initialization; (2) access to the ConstantPool of this class. diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index cf24783fbf8..22b570bbff3 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -674,13 +674,23 @@ void Klass::oop_verify_on(oop obj, outputStream* st) { #ifndef PRODUCT -void Klass::verify_vtable_index(int i) { +bool Klass::verify_vtable_index(int i) { if (oop_is_instance()) { - assert(i>=0 && i<((InstanceKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds"); + int limit = ((InstanceKlass*)this)->vtable_length()/vtableEntry::size(); + assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit)); } else { assert(oop_is_array(), "Must be"); - assert(i>=0 && i<((ArrayKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds"); + int limit = ((ArrayKlass*)this)->vtable_length()/vtableEntry::size(); + assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit)); } + return true; +} + +bool Klass::verify_itable_index(int i) { + assert(oop_is_instance(), ""); + int method_count = klassItable::method_count_for_interface(this); + assert(i >= 0 && i < method_count, "index out of bounds"); + return true; } #endif diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp index 83bf44561b2..9855fdd3233 100644 --- a/hotspot/src/share/vm/oops/klass.hpp +++ b/hotspot/src/share/vm/oops/klass.hpp @@ -699,7 +699,8 @@ class Klass : public Metadata { void verify(bool check_dictionary = true) { verify_on(tty, check_dictionary); } #ifndef PRODUCT - void verify_vtable_index(int index); + bool verify_vtable_index(int index); + bool verify_itable_index(int index); #endif virtual void oop_verify_on(oop obj, outputStream* st); diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp index ebc6e0aea88..7105368840f 100644 --- a/hotspot/src/share/vm/oops/klassVtable.cpp +++ b/hotspot/src/share/vm/oops/klassVtable.cpp @@ -47,11 +47,12 @@ inline InstanceKlass* klassVtable::ik() const { // this function computes the vtable size (including the size needed for miranda -// methods) and the number of miranda methods in this class +// methods) and the number of miranda methods in this class. // Note on Miranda methods: Let's say there is a class C that implements -// interface I. Let's say there is a method m in I that neither C nor any -// of its super classes implement (i.e there is no method of any access, with -// the same name and signature as m), then m is a Miranda method which is +// interface I, and none of C's superclasses implements I. +// Let's say there is an abstract method m in I that neither C +// nor any of its super classes implement (i.e there is no method of any access, +// with the same name and signature as m), then m is a Miranda method which is // entered as a public abstract method in C's vtable. From then on it should // treated as any other public method in C for method over-ride purposes. void klassVtable::compute_vtable_size_and_num_mirandas( @@ -111,10 +112,13 @@ void klassVtable::compute_vtable_size_and_num_mirandas( } int klassVtable::index_of(Method* m, int len) const { - assert(m->vtable_index() >= 0, "do not ask this of non-vtable methods"); + assert(m->has_vtable_index(), "do not ask this of non-vtable methods"); return m->vtable_index(); } +// Copy super class's vtable to the first part (prefix) of this class's vtable, +// and return the number of entries copied. Expects that 'super' is the Java +// super class (arrays can have "array" super classes that must be skipped). int klassVtable::initialize_from_super(KlassHandle super) { if (super.is_null()) { return 0; @@ -139,14 +143,14 @@ int klassVtable::initialize_from_super(KlassHandle super) { } } -// Revised lookup semantics introduced 1.3 (Kestral beta) +// +// Revised lookup semantics introduced 1.3 (Kestrel beta) void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { // Note: Arrays can have intermediate array supers. Use java_super to skip them. KlassHandle super (THREAD, klass()->java_super()); int nofNewEntries = 0; - if (PrintVtables && !klass()->oop_is_array()) { ResourceMark rm(THREAD); tty->print_cr("Initializing: %s", _klass->name()->as_C_string()); @@ -174,8 +178,10 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { int len = methods->length(); int initialized = super_vtable_len; - // update_inherited_vtable can stop for gc - ensure using handles + // Check each of this class's methods against super; + // if override, replace in copy of super vtable, otherwise append to end for (int i = 0; i < len; i++) { + // update_inherited_vtable can stop for gc - ensure using handles HandleMark hm(THREAD); assert(methods->at(i)->is_method(), "must be a Method*"); methodHandle mh(THREAD, methods->at(i)); @@ -189,11 +195,11 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { } } - // add miranda methods; it will also update the value of initialized - fill_in_mirandas(&initialized); + // add miranda methods to end of vtable. + initialized = fill_in_mirandas(initialized); // In class hierarchies where the accessibility is not increasing (i.e., going from private -> - // package_private -> publicprotected), the vtable might actually be smaller than our initial + // package_private -> public/protected), the vtable might actually be smaller than our initial // calculation. assert(initialized <= _length, "vtable initialization failed"); for(;initialized < _length; initialized++) { @@ -248,14 +254,8 @@ InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper return superk; } -// Methods that are "effectively" final don't need vtable entries. -bool method_is_effectively_final( - AccessFlags klass_flags, methodHandle target) { - return target->is_final() || klass_flags.is_final() && !target->is_overpass(); -} - // Update child's copy of super vtable for overrides -// OR return true if a new vtable entry is required +// OR return true if a new vtable entry is required. // Only called for InstanceKlass's, i.e. not for arrays // If that changed, could not use _klass as handle for klass bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle target_method, int super_vtable_len, @@ -263,6 +263,7 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar ResourceMark rm; bool allocate_new = true; assert(klass->oop_is_instance(), "must be InstanceKlass"); + assert(klass == target_method()->method_holder(), "caller resp."); // Initialize the method's vtable index to "nonvirtual". // If we allocate a vtable entry, we will update it to a non-negative number. @@ -273,11 +274,17 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar return false; } - if (method_is_effectively_final(klass->access_flags(), target_method)) { + if (target_method->is_final_method(klass->access_flags())) { // a final method never needs a new entry; final methods can be statically // resolved and they have to be present in the vtable only if they override // a super's method, in which case they re-use its entry allocate_new = false; + } else if (klass->is_interface()) { + allocate_new = false; // see note below in needs_new_vtable_entry + // An interface never allocates new vtable slots, only inherits old ones. + // This method will either be assigned its own itable index later, + // or be assigned an inherited vtable index in the loop below. + target_method()->set_vtable_index(Method::pending_itable_index); } // we need a new entry if there is no superclass @@ -411,8 +418,14 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, Symbol* classname, AccessFlags class_flags, TRAPS) { + if (class_flags.is_interface()) { + // Interfaces do not use vtables, so there is no point to assigning + // a vtable index to any of their methods. If we refrain from doing this, + // we can use Method::_vtable_index to hold the itable index + return false; + } - if (method_is_effectively_final(class_flags, target_method) || + if (target_method->is_final_method(class_flags) || // a final method never needs a new entry; final methods can be statically // resolved and they have to be present in the vtable only if they override // a super's method, in which case they re-use its entry @@ -500,7 +513,8 @@ int klassVtable::index_of_miranda(Symbol* name, Symbol* signature) { return Method::invalid_vtable_index; } -// check if an entry is miranda +// check if an entry at an index is miranda +// requires that method m at entry be declared ("held") by an interface. bool klassVtable::is_miranda_entry_at(int i) { Method* m = method_at(i); Klass* method_holder = m->method_holder(); @@ -516,7 +530,9 @@ bool klassVtable::is_miranda_entry_at(int i) { return false; } -// check if a method is a miranda method, given a class's methods table and it's super +// check if a method is a miranda method, given a class's methods table and its super +// "miranda" means not static, not defined by this class, and not defined +// in super unless it is private and therefore inaccessible to this class. // the caller must make sure that the method belongs to an interface implemented by the class bool klassVtable::is_miranda(Method* m, Array* class_methods, Klass* super) { if (m->is_static()) { @@ -541,6 +557,14 @@ bool klassVtable::is_miranda(Method* m, Array* class_methods, Klass* su return false; } +// Scans current_interface_methods for miranda methods that do not +// already appear in new_mirandas and are also not defined-and-non-private +// in super (superclass). These mirandas are added to all_mirandas if it is +// not null; in addition, those that are not duplicates of miranda methods +// inherited by super from its interfaces are added to new_mirandas. +// Thus, new_mirandas will be the set of mirandas that this class introduces, +// all_mirandas will be the set of all mirandas applicable to this class +// including all defined in superclasses. void klassVtable::add_new_mirandas_to_lists( GrowableArray* new_mirandas, GrowableArray* all_mirandas, Array* current_interface_methods, Array* class_methods, @@ -599,17 +623,22 @@ void klassVtable::get_mirandas(GrowableArray* new_mirandas, } } -// fill in mirandas -void klassVtable::fill_in_mirandas(int* initialized) { +// Discover miranda methods ("miranda" = "interface abstract, no binding"), +// and append them into the vtable starting at index initialized, +// return the new value of initialized. +int klassVtable::fill_in_mirandas(int initialized) { GrowableArray mirandas(20); get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), ik()->local_interfaces()); for (int i = 0; i < mirandas.length(); i++) { - put_method_at(mirandas.at(i), *initialized); - ++(*initialized); + put_method_at(mirandas.at(i), initialized); + ++initialized; } + return initialized; } +// Copy this class's vtable to the vtable beginning at start. +// Used to copy superclass vtable to prefix of subclass's vtable. void klassVtable::copy_vtable_to(vtableEntry* start) { Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size()); } @@ -723,6 +752,12 @@ static int initialize_count = 0; // Initialization void klassItable::initialize_itable(bool checkconstraints, TRAPS) { + if (_klass->is_interface()) { + // This needs to go after vtable indexes are assigned but + // before implementors need to know the number of itable indexes. + assign_itable_indexes_for_interface(_klass()); + } + // Cannot be setup doing bootstrapping, interfaces don't have // itables, and klass with only ones entry have empty itables if (Universe::is_bootstrapping() || @@ -754,45 +789,89 @@ void klassItable::initialize_itable(bool checkconstraints, TRAPS) { } +inline bool interface_method_needs_itable_index(Method* m) { + if (m->is_static()) return false; // e.g., Stream.empty + if (m->is_initializer()) return false; // or + // If an interface redeclares a method from java.lang.Object, + // it should already have a vtable index, don't touch it. + // e.g., CharSequence.toString (from initialize_vtable) + // if (m->has_vtable_index()) return false; // NO! + return true; +} + +int klassItable::assign_itable_indexes_for_interface(Klass* klass) { + // an interface does not have an itable, but its methods need to be numbered + if (TraceItables) tty->print_cr("%3d: Initializing itable for interface %s", ++initialize_count, + klass->name()->as_C_string()); + Array* methods = InstanceKlass::cast(klass)->methods(); + int nof_methods = methods->length(); + int ime_num = 0; + for (int i = 0; i < nof_methods; i++) { + Method* m = methods->at(i); + if (interface_method_needs_itable_index(m)) { + assert(!m->is_final_method(), "no final interface methods"); + // If m is already assigned a vtable index, do not disturb it. + if (!m->has_vtable_index()) { + assert(m->vtable_index() == Method::pending_itable_index, "set by initialize_vtable"); + m->set_itable_index(ime_num); + // Progress to next itable entry + ime_num++; + } + } + } + assert(ime_num == method_count_for_interface(klass), "proper sizing"); + return ime_num; +} + +int klassItable::method_count_for_interface(Klass* interf) { + assert(interf->oop_is_instance(), "must be"); + assert(interf->is_interface(), "must be"); + Array* methods = InstanceKlass::cast(interf)->methods(); + int nof_methods = methods->length(); + while (nof_methods > 0) { + Method* m = methods->at(nof_methods-1); + if (m->has_itable_index()) { + int length = m->itable_index() + 1; +#ifdef ASSERT + while (nof_methods = 0) { + m = methods->at(--nof_methods); + assert(!m->has_itable_index() || m->itable_index() < length, ""); + } +#endif //ASSERT + return length; // return the rightmost itable index, plus one + } + nof_methods -= 1; + } + // no methods have itable indexes + return 0; +} + + void klassItable::initialize_itable_for_interface(int method_table_offset, KlassHandle interf_h, bool checkconstraints, TRAPS) { Array* methods = InstanceKlass::cast(interf_h())->methods(); int nof_methods = methods->length(); HandleMark hm; - KlassHandle klass = _klass; assert(nof_methods > 0, "at least one method must exist for interface to be in vtable"); Handle interface_loader (THREAD, InstanceKlass::cast(interf_h())->class_loader()); - int ime_num = 0; - // Skip first Method* if it is a class initializer - int i = methods->at(0)->is_static_initializer() ? 1 : 0; - - // m, method_name, method_signature, klass reset each loop so they - // don't need preserving across check_signature_loaders call - // methods needs a handle in case of gc from check_signature_loaders - for(; i < nof_methods; i++) { + int ime_count = method_count_for_interface(interf_h()); + for (int i = 0; i < nof_methods; i++) { Method* m = methods->at(i); - Symbol* method_name = m->name(); - Symbol* method_signature = m->signature(); - - // This is same code as in Linkresolver::lookup_instance_method_in_klasses - Method* target = klass->uncached_lookup_method(method_name, method_signature); - while (target != NULL && target->is_static()) { - // continue with recursive lookup through the superclass - Klass* super = target->method_holder()->super(); - target = (super == NULL) ? (Method*)NULL : super->uncached_lookup_method(method_name, method_signature); + methodHandle target; + if (m->has_itable_index()) { + LinkResolver::lookup_instance_method_in_klasses(target, _klass, m->name(), m->signature(), CHECK); } if (target == NULL || !target->is_public() || target->is_abstract()) { // Entry do not resolve. Leave it empty } else { // Entry did resolve, check loader constraints before initializing // if checkconstraints requested - methodHandle target_h (THREAD, target); // preserve across gc if (checkconstraints) { Handle method_holder_loader (THREAD, target->method_holder()->class_loader()); if (method_holder_loader() != interface_loader()) { ResourceMark rm(THREAD); Symbol* failed_type_symbol = - SystemDictionary::check_signature_loaders(method_signature, + SystemDictionary::check_signature_loaders(m->signature(), method_holder_loader, interface_loader, true, CHECK); @@ -803,9 +882,9 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass "and the class loader (instance of %s) for interface " "%s have different Class objects for the type %s " "used in the signature"; - char* sig = target_h()->name_and_sig_as_C_string(); + char* sig = target()->name_and_sig_as_C_string(); const char* loader1 = SystemDictionary::loader_name(method_holder_loader()); - char* current = klass->name()->as_C_string(); + char* current = _klass->name()->as_C_string(); const char* loader2 = SystemDictionary::loader_name(interface_loader()); char* iface = InstanceKlass::cast(interf_h())->name()->as_C_string(); char* failed_type_name = failed_type_symbol->as_C_string(); @@ -821,10 +900,10 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass } // ime may have moved during GC so recalculate address - itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target_h()); + int ime_num = m->itable_index(); + assert(ime_num < ime_count, "oob"); + itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target()); } - // Progress to next entry - ime_num++; } } @@ -913,20 +992,22 @@ class InterfaceVisiterClosure : public StackObj { virtual void doit(Klass* intf, int method_count) = 0; }; -// Visit all interfaces with at-least one method (excluding ) +// Visit all interfaces with at least one itable method void visit_all_interfaces(Array* transitive_intf, InterfaceVisiterClosure *blk) { // Handle array argument for(int i = 0; i < transitive_intf->length(); i++) { Klass* intf = transitive_intf->at(i); assert(intf->is_interface(), "sanity check"); - // Find no. of methods excluding a - int method_count = InstanceKlass::cast(intf)->methods()->length(); - if (method_count > 0) { - Method* m = InstanceKlass::cast(intf)->methods()->at(0); - assert(m != NULL && m->is_method(), "sanity check"); - if (m->name() == vmSymbols::object_initializer_name()) { - method_count--; + // Find no. of itable methods + int method_count = 0; + // method_count = klassItable::method_count_for_interface(intf); + Array* methods = InstanceKlass::cast(intf)->methods(); + if (methods->length() > 0) { + for (int i = methods->length(); --i >= 0; ) { + if (interface_method_needs_itable_index(methods->at(i))) { + method_count++; + } } } @@ -1024,40 +1105,26 @@ void klassItable::setup_itable_offset_table(instanceKlassHandle klass) { } -// m must be a method in an interface -int klassItable::compute_itable_index(Method* m) { - InstanceKlass* intf = m->method_holder(); - assert(intf->is_interface(), "sanity check"); - Array* methods = intf->methods(); - int index = 0; - while(methods->at(index) != m) { - index++; - assert(index < methods->length(), "should find index for resolve_invoke"); - } - // Adjust for , which is left out of table if first method - if (methods->length() > 0 && methods->at(0)->is_static_initializer()) { - index--; - } - return index; -} - - -// inverse to compute_itable_index +// inverse to itable_index Method* klassItable::method_for_itable_index(Klass* intf, int itable_index) { assert(InstanceKlass::cast(intf)->is_interface(), "sanity check"); + assert(intf->verify_itable_index(itable_index), ""); Array* methods = InstanceKlass::cast(intf)->methods(); - int index = itable_index; - // Adjust for , which is left out of table if first method - if (methods->length() > 0 && methods->at(0)->is_static_initializer()) { - index++; - } - - if (itable_index < 0 || index >= methods->length()) + if (itable_index < 0 || itable_index >= method_count_for_interface(intf)) return NULL; // help caller defend against bad indexes + int index = itable_index; Method* m = methods->at(index); - assert(compute_itable_index(m) == itable_index, "correct inverse"); + int index2 = -1; + while (!m->has_itable_index() || + (index2 = m->itable_index()) != itable_index) { + assert(index2 < itable_index, "monotonic"); + if (++index == methods->length()) + return NULL; + m = methods->at(index); + } + assert(m->itable_index() == itable_index, "correct inverse"); return m; } diff --git a/hotspot/src/share/vm/oops/klassVtable.hpp b/hotspot/src/share/vm/oops/klassVtable.hpp index 8d8d6cf27c5..06d55af2566 100644 --- a/hotspot/src/share/vm/oops/klassVtable.hpp +++ b/hotspot/src/share/vm/oops/klassVtable.hpp @@ -124,7 +124,7 @@ class klassVtable : public ResourceObj { // support for miranda methods bool is_miranda_entry_at(int i); - void fill_in_mirandas(int* initialized); + int fill_in_mirandas(int initialized); static bool is_miranda(Method* m, Array* class_methods, Klass* super); static void add_new_mirandas_to_lists( GrowableArray* new_mirandas, @@ -290,12 +290,12 @@ class klassItable : public ResourceObj { #endif // INCLUDE_JVMTI // Setup of itable + static int assign_itable_indexes_for_interface(Klass* klass); + static int method_count_for_interface(Klass* klass); static int compute_itable_size(Array* transitive_interfaces); static void setup_itable_offset_table(instanceKlassHandle klass); // Resolving of method to index - static int compute_itable_index(Method* m); - // ...and back again: static Method* method_for_itable_index(Klass* klass, int itable_index); // Debugging/Statistics diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index b8e60a774f3..30631fa3b61 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -509,24 +509,31 @@ bool Method::compute_has_loops_flag() { return _access_flags.has_loops(); } +bool Method::is_final_method(AccessFlags class_access_flags) const { + // or "does_not_require_vtable_entry" + // overpass can occur, is not final (reuses vtable entry) + // private methods get vtable entries for backward class compatibility. + if (is_overpass()) return false; + return is_final() || class_access_flags.is_final(); +} bool Method::is_final_method() const { - // %%% Should return true for private methods also, - // since there is no way to override them. - return is_final() || method_holder()->is_final(); + return is_final_method(method_holder()->access_flags()); } - -bool Method::is_strict_method() const { - return is_strict(); -} - - -bool Method::can_be_statically_bound() const { - if (is_final_method()) return true; +bool Method::can_be_statically_bound(AccessFlags class_access_flags) const { + if (is_final_method(class_access_flags)) return true; +#ifdef ASSERT + bool is_nonv = (vtable_index() == nonvirtual_vtable_index); + if (class_access_flags.is_interface()) assert(is_nonv == is_static(), err_msg("is_nonv=%s", is_nonv)); +#endif + assert(valid_vtable_index() || valid_itable_index(), "method must be linked before we ask this question"); return vtable_index() == nonvirtual_vtable_index; } +bool Method::can_be_statically_bound() const { + return can_be_statically_bound(method_holder()->access_flags()); +} bool Method::is_accessor() const { if (code_size() != 5) return false; @@ -967,7 +974,7 @@ bool Method::is_overridden_in(Klass* k) const { assert(ik->is_subclass_of(method_holder()), "should be subklass"); assert(ik->vtable() != NULL, "vtable should exist"); - if (vtable_index() == nonvirtual_vtable_index) { + if (!has_vtable_index()) { return false; } else { Method* vt_m = ik->method_at_vtable(vtable_index()); @@ -1959,7 +1966,7 @@ void Method::print_on(outputStream* st) const { void Method::print_value_on(outputStream* st) const { assert(is_method(), "must be method"); - st->print_cr(internal_name()); + st->print(internal_name()); print_address_on(st); st->print(" "); name()->print_value_on(st); @@ -1967,6 +1974,7 @@ void Method::print_value_on(outputStream* st) const { signature()->print_value_on(st); st->print(" in "); method_holder()->print_value_on(st); + if (WizardMode) st->print("#%d", _vtable_index); if (WizardMode) st->print("[%d,%d]", size_of_parameters(), max_locals()); if (WizardMode && code() != NULL) st->print(" ((nmethod*)%p)", code()); } diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index faaf5105994..02d2253b80a 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -448,16 +448,22 @@ class Method : public Metadata { enum VtableIndexFlag { // Valid vtable indexes are non-negative (>= 0). // These few negative values are used as sentinels. - highest_unused_vtable_index_value = -5, + itable_index_max = -10, // first itable index, growing downward + pending_itable_index = -9, // itable index will be assigned invalid_vtable_index = -4, // distinct from any valid vtable index garbage_vtable_index = -3, // not yet linked; no vtable layout yet nonvirtual_vtable_index = -2 // there is no need for vtable dispatch // 6330203 Note: Do not use -1, which was overloaded with many meanings. }; DEBUG_ONLY(bool valid_vtable_index() const { return _vtable_index >= nonvirtual_vtable_index; }) - int vtable_index() const { assert(valid_vtable_index(), ""); - return _vtable_index; } + bool has_vtable_index() const { return _vtable_index >= 0; } + int vtable_index() const { return _vtable_index; } void set_vtable_index(int index) { _vtable_index = index; } + DEBUG_ONLY(bool valid_itable_index() const { return _vtable_index <= pending_itable_index; }) + bool has_itable_index() const { return _vtable_index <= itable_index_max; } + int itable_index() const { assert(valid_itable_index(), ""); + return itable_index_max - _vtable_index; } + void set_itable_index(int index) { _vtable_index = itable_index_max - index; assert(valid_itable_index(), ""); } // interpreter entry address interpreter_entry() const { return _i2i_entry; } @@ -560,10 +566,11 @@ class Method : public Metadata { // checks method and its method holder bool is_final_method() const; - bool is_strict_method() const; + bool is_final_method(AccessFlags class_access_flags) const; // true if method needs no dynamic dispatch (final and/or no vtable entry) bool can_be_statically_bound() const; + bool can_be_statically_bound(AccessFlags class_access_flags) const; // returns true if the method has any backward branches. bool has_loops() { @@ -740,10 +747,6 @@ class Method : public Metadata { // so handles are not used to avoid deadlock. jmethodID find_jmethod_id_or_null() { return method_holder()->jmethod_id_or_null(this); } - // JNI static invoke cached itable index accessors - int cached_itable_index() { return method_holder()->cached_itable_index(method_idnum()); } - void set_cached_itable_index(int index) { method_holder()->set_cached_itable_index(method_idnum(), index); } - // Support for inlining of intrinsic methods vmIntrinsics::ID intrinsic_id() const { return (vmIntrinsics::ID) _intrinsic_id; } void set_intrinsic_id(vmIntrinsics::ID id) { _intrinsic_id = (u1) id; } diff --git a/hotspot/src/share/vm/oops/symbol.hpp b/hotspot/src/share/vm/oops/symbol.hpp index f9db8d39974..e747c464607 100644 --- a/hotspot/src/share/vm/oops/symbol.hpp +++ b/hotspot/src/share/vm/oops/symbol.hpp @@ -45,7 +45,7 @@ // in the SymbolTable bucket (the _literal field in HashtableEntry) // that points to the Symbol. All other stores of a Symbol* // to a field of a persistent variable (e.g., the _name filed in -// FieldAccessInfo or _ptr in a CPSlot) is reference counted. +// fieldDescriptor or _ptr in a CPSlot) is reference counted. // // 1) The lookup of a "name" in the SymbolTable either creates a Symbol F for // "name" and returns a pointer to F or finds a pre-existing Symbol F for diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index f7e09c3f89f..e0d68d9fc58 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -3734,6 +3734,8 @@ Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass, RegionNode* slow_region) { ciMethod* method = callee(); int vtable_index = method->vtable_index(); + assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, + err_msg_res("bad index %d", vtable_index)); // Get the Method* out of the appropriate vtable entry. int entry_offset = (InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size()) * wordSize + @@ -3784,6 +3786,8 @@ LibraryCallKit::generate_method_call(vmIntrinsics::ID method_id, bool is_virtual // so the vtable index is fixed. // No need to use the linkResolver to get it. vtable_index = method->vtable_index(); + assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, + err_msg_res("bad index %d", vtable_index)); } slow_call = new(C) CallDynamicJavaNode(tf, SharedRuntime::get_resolve_virtual_call_stub(), diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index ea44e2c6679..8367f5133b6 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -1336,6 +1336,7 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive if (call_type == JNI_VIRTUAL) { // jni_GetMethodID makes sure class is linked and initialized // so m should have a valid vtable index. + assert(!m->has_itable_index(), ""); int vtbl_index = m->vtable_index(); if (vtbl_index != Method::nonvirtual_vtable_index) { Klass* k = h_recv->klass(); @@ -1355,12 +1356,7 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive // interface call KlassHandle h_holder(THREAD, holder); - int itbl_index = m->cached_itable_index(); - if (itbl_index == -1) { - itbl_index = klassItable::compute_itable_index(m); - m->set_cached_itable_index(itbl_index); - // the above may have grabbed a lock, 'm' and anything non-handlized can't be used again - } + int itbl_index = m->itable_index(); Klass* k = h_recv->klass(); selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK); } diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index caed2d13612..d7a961edfbb 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1824,7 +1824,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, } if (!publicOnly || fs.access_flags().is_public()) { - fd.initialize(k(), fs.index()); + fd.reinitialize(k(), fs.index()); oop field = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); result->obj_at_put(out_idx, field); ++out_idx; diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 803cf9a7545..db009a43361 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -2930,7 +2930,7 @@ void VM_RedefineClasses::check_methods_and_mark_as_obsolete( for (int i = 0; i < _deleted_methods_length; ++i) { Method* old_method = _deleted_methods[i]; - assert(old_method->vtable_index() < 0, + assert(!old_method->has_vtable_index(), "cannot delete methods with vtable entries");; // Mark all deleted methods as old and obsolete diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp index ac1c796eb31..88b82b358e6 100644 --- a/hotspot/src/share/vm/prims/methodHandles.cpp +++ b/hotspot/src/share/vm/prims/methodHandles.cpp @@ -127,25 +127,37 @@ Handle MethodHandles::new_MemberName(TRAPS) { } oop MethodHandles::init_MemberName(Handle mname, Handle target) { + // This method is used from java.lang.invoke.MemberName constructors. + // It fills in the new MemberName from a java.lang.reflect.Member. Thread* thread = Thread::current(); oop target_oop = target(); Klass* target_klass = target_oop->klass(); if (target_klass == SystemDictionary::reflect_Field_klass()) { oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder() int slot = java_lang_reflect_Field::slot(target_oop); // fd.index() - int mods = java_lang_reflect_Field::modifiers(target_oop); - oop type = java_lang_reflect_Field::type(target_oop); - oop name = java_lang_reflect_Field::name(target_oop); KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); - intptr_t offset = InstanceKlass::cast(k())->field_offset(slot); - return init_field_MemberName(mname, k, accessFlags_from(mods), type, name, offset); + if (!k.is_null() && k->oop_is_instance()) { + fieldDescriptor fd(InstanceKlass::cast(k()), slot); + oop mname2 = init_field_MemberName(mname, fd); + if (mname2 != NULL) { + // Since we have the reified name and type handy, add them to the result. + if (java_lang_invoke_MemberName::name(mname2) == NULL) + java_lang_invoke_MemberName::set_name(mname2, java_lang_reflect_Field::name(target_oop)); + if (java_lang_invoke_MemberName::type(mname2) == NULL) + java_lang_invoke_MemberName::set_type(mname2, java_lang_reflect_Field::type(target_oop)); + } + return mname2; + } } else if (target_klass == SystemDictionary::reflect_Method_klass()) { oop clazz = java_lang_reflect_Method::clazz(target_oop); int slot = java_lang_reflect_Method::slot(target_oop); KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); if (!k.is_null() && k->oop_is_instance()) { Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); - return init_method_MemberName(mname, m, true, k); + if (m == NULL || is_signature_polymorphic(m->intrinsic_id())) + return NULL; // do not resolve unless there is a concrete signature + CallInfo info(m, k()); + return init_method_MemberName(mname, info); } } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) { oop clazz = java_lang_reflect_Constructor::clazz(target_oop); @@ -153,65 +165,50 @@ oop MethodHandles::init_MemberName(Handle mname, Handle target) { KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); if (!k.is_null() && k->oop_is_instance()) { Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); - return init_method_MemberName(mname, m, false, k); - } - } else if (target_klass == SystemDictionary::MemberName_klass()) { - // Note: This only works if the MemberName has already been resolved. - oop clazz = java_lang_invoke_MemberName::clazz(target_oop); - int flags = java_lang_invoke_MemberName::flags(target_oop); - Metadata* vmtarget=java_lang_invoke_MemberName::vmtarget(target_oop); - intptr_t vmindex = java_lang_invoke_MemberName::vmindex(target_oop); - KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); - int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; - if (vmtarget == NULL) return NULL; // not resolved - if ((flags & IS_FIELD) != 0) { - assert(vmtarget->is_klass(), "field vmtarget is Klass*"); - int basic_mods = (ref_kind_is_static(ref_kind) ? JVM_ACC_STATIC : 0); - // FIXME: how does k (receiver_limit) contribute? - KlassHandle k_vmtarget(thread, (Klass*)vmtarget); - return init_field_MemberName(mname, k_vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex); - } else if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) { - assert(vmtarget->is_method(), "method or constructor vmtarget is Method*"); - return init_method_MemberName(mname, (Method*)vmtarget, ref_kind_does_dispatch(ref_kind), k); - } else { - return NULL; + if (m == NULL) return NULL; + CallInfo info(m, k()); + return init_method_MemberName(mname, info); } } return NULL; } -oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispatch, - KlassHandle receiver_limit_h) { - Klass* receiver_limit = receiver_limit_h(); - AccessFlags mods = m->access_flags(); - int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); - int vmindex = Method::nonvirtual_vtable_index; // implies never any dispatch - Klass* mklass = m->method_holder(); - if (receiver_limit == NULL) - receiver_limit = mklass; - if (m->is_initializer()) { - flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); - } else if (mods.is_static()) { - flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); - } else if (receiver_limit != mklass && - !receiver_limit->is_subtype_of(mklass)) { - return NULL; // bad receiver limit - } else if (do_dispatch && receiver_limit->is_interface() && - mklass->is_interface()) { +oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { + assert(info.resolved_appendix().is_null(), "only normal methods here"); + KlassHandle receiver_limit = info.resolved_klass(); + methodHandle m = info.resolved_method(); + int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); + int vmindex = Method::invalid_vtable_index; + + switch (info.call_kind()) { + case CallInfo::itable_call: + vmindex = info.itable_index(); + // More importantly, the itable index only works with the method holder. + receiver_limit = m->method_holder(); + assert(receiver_limit->verify_itable_index(vmindex), ""); flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT); - receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible - vmindex = klassItable::compute_itable_index(m); - } else if (do_dispatch && mklass != receiver_limit && mklass->is_interface()) { + break; + + case CallInfo::vtable_call: + vmindex = info.vtable_index(); flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); - // it is a miranda method, so m->vtable_index is not what we want - ResourceMark rm; - klassVtable* vt = InstanceKlass::cast(receiver_limit)->vtable(); - vmindex = vt->index_of_miranda(m->name(), m->signature()); - } else if (!do_dispatch || m->can_be_statically_bound()) { - flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); - } else { - flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); - vmindex = m->vtable_index(); + assert(receiver_limit->is_subtype_of(m->method_holder()), "virtual call must be type-safe"); + break; + + case CallInfo::direct_call: + vmindex = Method::nonvirtual_vtable_index; + if (m->is_static()) { + flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); + } else if (m->is_initializer()) { + flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); + assert(receiver_limit == m->method_holder(), "constructor call must be exactly typed"); + } else { + flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); + assert(receiver_limit->is_subtype_of(m->method_holder()), "special call must be type-safe"); + } + break; + + default: assert(false, "bad CallInfo"); return NULL; } // @CallerSensitive annotation detected @@ -221,7 +218,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispa oop mname_oop = mname(); java_lang_invoke_MemberName::set_flags( mname_oop, flags); - java_lang_invoke_MemberName::set_vmtarget(mname_oop, m); + java_lang_invoke_MemberName::set_vmtarget(mname_oop, m()); java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index java_lang_invoke_MemberName::set_clazz( mname_oop, receiver_limit->java_mirror()); // Note: name and type can be lazily computed by resolve_MemberName, @@ -237,59 +234,19 @@ oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispa return mname(); } -Handle MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, TRAPS) { - Handle empty; - if (info.resolved_appendix().not_null()) { - // The resolved MemberName must not be accompanied by an appendix argument, - // since there is no way to bind this value into the MemberName. - // Caller is responsible to prevent this from happening. - THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty); - } - methodHandle m = info.resolved_method(); - KlassHandle defc = info.resolved_klass(); - int vmindex = Method::invalid_vtable_index; - if (defc->is_interface() && m->method_holder()->is_interface()) { - // static interface methods do not reference vtable or itable - if (m->is_static()) { - vmindex = Method::nonvirtual_vtable_index; - } - // interface methods invoked via invokespecial also - // do not reference vtable or itable. - int ref_kind = ((java_lang_invoke_MemberName::flags(mname()) >> - REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK); - if (ref_kind == JVM_REF_invokeSpecial) { - vmindex = Method::nonvirtual_vtable_index; - } - // If neither m is static nor ref_kind is invokespecial, - // set it to itable index. - if (vmindex == Method::invalid_vtable_index) { - // LinkResolver does not report itable indexes! (fix this?) - vmindex = klassItable::compute_itable_index(m()); - } - } else if (m->can_be_statically_bound()) { - // LinkResolver reports vtable index even for final methods! - vmindex = Method::nonvirtual_vtable_index; - } else { - vmindex = info.vtable_index(); - } - oop res = init_method_MemberName(mname, m(), (vmindex >= 0), defc()); - assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), ""); - return Handle(THREAD, res); -} - -oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder, - AccessFlags mods, oop type, oop name, - intptr_t offset, bool is_setter) { - int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); - flags |= IS_FIELD | ((mods.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); +oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { + int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); + flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); - Metadata* vmtarget = field_holder(); - int vmindex = offset; // determines the field uniquely when combined with static bit + Metadata* vmtarget = fd.field_holder(); + int vmindex = fd.offset(); // determines the field uniquely when combined with static bit oop mname_oop = mname(); java_lang_invoke_MemberName::set_flags(mname_oop, flags); java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); - java_lang_invoke_MemberName::set_clazz(mname_oop, field_holder->java_mirror()); + java_lang_invoke_MemberName::set_clazz(mname_oop, fd.field_holder()->java_mirror()); + oop type = field_signature_type_or_null(fd.signature()); + oop name = field_name_or_null(fd.name()); if (name != NULL) java_lang_invoke_MemberName::set_name(mname_oop, name); if (type != NULL) @@ -305,19 +262,6 @@ oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder, return mname(); } -Handle MethodHandles::init_field_MemberName(Handle mname, FieldAccessInfo& info, TRAPS) { - return Handle(); -#if 0 // FIXME - KlassHandle field_holder = info.klass(); - intptr_t field_offset = info.field_offset(); - return init_field_MemberName(mname_oop, field_holder(), - info.access_flags(), - type, name, - field_offset, false /*is_setter*/); -#endif -} - - // JVM 2.9 Special Methods: // A method is signature polymorphic if and only if all of the following conditions hold : // * It is declared in the java.lang.invoke.MethodHandle class. @@ -573,12 +517,12 @@ static oop object_java_mirror() { return SystemDictionary::Object_klass()->java_mirror(); } -static oop field_name_or_null(Symbol* s) { +oop MethodHandles::field_name_or_null(Symbol* s) { if (s == NULL) return NULL; return StringTable::lookup(s); } -static oop field_signature_type_or_null(Symbol* s) { +oop MethodHandles::field_signature_type_or_null(Symbol* s) { if (s == NULL) return NULL; BasicType bt = FieldType::basic_type(s); if (is_java_primitive(bt)) { @@ -701,7 +645,14 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) { return empty; } } - return init_method_MemberName(mname, result, THREAD); + if (result.resolved_appendix().not_null()) { + // The resolved MemberName must not be accompanied by an appendix argument, + // since there is no way to bind this value into the MemberName. + // Caller is responsible to prevent this from happening. + THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty); + } + oop mname2 = init_method_MemberName(mname, result); + return Handle(THREAD, mname2); } case IS_CONSTRUCTOR: { @@ -719,22 +670,21 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) { } } assert(result.is_statically_bound(), ""); - return init_method_MemberName(mname, result, THREAD); + oop mname2 = init_method_MemberName(mname, result); + return Handle(THREAD, mname2); } case IS_FIELD: { - // This is taken from LinkResolver::resolve_field, sans access checks. - fieldDescriptor fd; // find_field initializes fd if found - KlassHandle sel_klass(THREAD, InstanceKlass::cast(defc())->find_field(name, type, &fd)); - // check if field exists; i.e., if a klass containing the field def has been selected - if (sel_klass.is_null()) return empty; // should not happen - oop type = field_signature_type_or_null(fd.signature()); - oop name = field_name_or_null(fd.name()); - bool is_setter = (ref_kind_is_valid(ref_kind) && ref_kind_is_setter(ref_kind)); - mname = Handle(THREAD, - init_field_MemberName(mname, sel_klass, - fd.access_flags(), type, name, fd.offset(), is_setter)); - return mname; + fieldDescriptor result; // find_field initializes fd if found + { + assert(!HAS_PENDING_EXCEPTION, ""); + LinkResolver::resolve_field(result, defc, name, type, KlassHandle(), Bytecodes::_nop, false, false, THREAD); + if (HAS_PENDING_EXCEPTION) { + return empty; + } + } + oop mname2 = init_field_MemberName(mname, result, ref_kind_is_setter(ref_kind)); + return Handle(THREAD, mname2); } default: THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty); @@ -793,7 +743,6 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) { } case IS_FIELD: { - // This is taken from LinkResolver::resolve_field, sans access checks. assert(vmtarget->is_klass(), "field vmtarget is Klass*"); if (!((Klass*) vmtarget)->oop_is_instance()) break; instanceKlassHandle defc(THREAD, (Klass*) vmtarget); @@ -872,11 +821,7 @@ int MethodHandles::find_MemberNames(KlassHandle k, Handle result(thread, results->obj_at(rfill++)); if (!java_lang_invoke_MemberName::is_instance(result())) return -99; // caller bug! - oop type = field_signature_type_or_null(st.signature()); - oop name = field_name_or_null(st.name()); - oop saved = MethodHandles::init_field_MemberName(result, st.klass(), - st.access_flags(), type, name, - st.offset()); + oop saved = MethodHandles::init_field_MemberName(result, st.field_descriptor()); if (saved != result()) results->obj_at_put(rfill-1, saved); // show saved instance to user } else if (++overflow >= overflow_limit) { @@ -926,7 +871,8 @@ int MethodHandles::find_MemberNames(KlassHandle k, Handle result(thread, results->obj_at(rfill++)); if (!java_lang_invoke_MemberName::is_instance(result())) return -99; // caller bug! - oop saved = MethodHandles::init_method_MemberName(result, m, true, NULL); + CallInfo info(m); + oop saved = MethodHandles::init_method_MemberName(result, info); if (saved != result()) results->obj_at_put(rfill-1, saved); // show saved instance to user } else if (++overflow >= overflow_limit) { @@ -1227,7 +1173,8 @@ JVM_ENTRY(jobject, MHN_getMemberVMInfo(JNIEnv *env, jobject igcls, jobject mname x = ((Klass*) vmtarget)->java_mirror(); } else if (vmtarget->is_method()) { Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL); - x = MethodHandles::init_method_MemberName(mname2, (Method*)vmtarget, false, NULL); + CallInfo info((Method*)vmtarget); + x = MethodHandles::init_method_MemberName(mname2, info); } result->obj_at_put(1, x); return JNIHandles::make_local(env, result()); diff --git a/hotspot/src/share/vm/prims/methodHandles.hpp b/hotspot/src/share/vm/prims/methodHandles.hpp index 50ce7af86ea..7ae7bd36fb5 100644 --- a/hotspot/src/share/vm/prims/methodHandles.hpp +++ b/hotspot/src/share/vm/prims/methodHandles.hpp @@ -49,19 +49,18 @@ class MethodHandles: AllStatic { // Adapters. static MethodHandlesAdapterBlob* _adapter_code; + // utility functions for reifying names and types + static oop field_name_or_null(Symbol* s); + static oop field_signature_type_or_null(Symbol* s); + public: // working with member names static Handle resolve_MemberName(Handle mname, TRAPS); // compute vmtarget/vmindex from name/type static void expand_MemberName(Handle mname, int suppress, TRAPS); // expand defc/name/type if missing static Handle new_MemberName(TRAPS); // must be followed by init_MemberName static oop init_MemberName(Handle mname_h, Handle target_h); // compute vmtarget/vmindex from target - static oop init_method_MemberName(Handle mname_h, Method* m, bool do_dispatch, - KlassHandle receiver_limit_h); - static oop init_field_MemberName(Handle mname_h, KlassHandle field_holder_h, - AccessFlags mods, oop type, oop name, - intptr_t offset, bool is_setter = false); - static Handle init_method_MemberName(Handle mname_h, CallInfo& info, TRAPS); - static Handle init_field_MemberName(Handle mname_h, FieldAccessInfo& info, TRAPS); + static oop init_field_MemberName(Handle mname_h, fieldDescriptor& fd, bool is_setter = false); + static oop init_method_MemberName(Handle mname_h, CallInfo& info); static int method_ref_kind(Method* m, bool do_dispatch_if_possible = true); static int find_MemberNames(KlassHandle k, Symbol* name, Symbol* sig, int mflags, KlassHandle caller, diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp index 23d679494ac..79e3ddcd85d 100644 --- a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp +++ b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp @@ -97,18 +97,32 @@ oop fieldDescriptor::string_initial_value(TRAPS) const { return constants()->uncached_string_at(initial_value_index(), CHECK_0); } -void fieldDescriptor::initialize(InstanceKlass* ik, int index) { - _cp = ik->constants(); +void fieldDescriptor::reinitialize(InstanceKlass* ik, int index) { + if (_cp.is_null() || field_holder() != ik) { + _cp = constantPoolHandle(Thread::current(), ik->constants()); + // _cp should now reference ik's constant pool; i.e., ik is now field_holder. + assert(field_holder() == ik, "must be already initialized to this class"); + } FieldInfo* f = ik->field(index); assert(!f->is_internal(), "regular Java fields only"); _access_flags = accessFlags_from(f->access_flags()); guarantee(f->name_index() != 0 && f->signature_index() != 0, "bad constant pool index for fieldDescriptor"); _index = index; + verify(); } #ifndef PRODUCT +void fieldDescriptor::verify() const { + if (_cp.is_null()) { + assert(_index == badInt, "constructor must be called"); // see constructor + } else { + assert(_index >= 0, "good index"); + assert(_index < field_holder()->java_fields_count(), "oob"); + } +} + void fieldDescriptor::print_on(outputStream* st) const { access_flags().print_on(st); name()->print_value_on(st); diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp index 12b75cab144..9c3101b38ba 100644 --- a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp +++ b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -53,6 +53,13 @@ class fieldDescriptor VALUE_OBJ_CLASS_SPEC { } public: + fieldDescriptor() { + DEBUG_ONLY(_index = badInt); + } + fieldDescriptor(InstanceKlass* ik, int index) { + DEBUG_ONLY(_index = badInt); + reinitialize(ik, index); + } Symbol* name() const { return field()->name(_cp); } @@ -112,12 +119,13 @@ class fieldDescriptor VALUE_OBJ_CLASS_SPEC { } // Initialization - void initialize(InstanceKlass* ik, int index); + void reinitialize(InstanceKlass* ik, int index); // Print void print() { print_on(tty); } void print_on(outputStream* st) const PRODUCT_RETURN; void print_on_for(outputStream* st, oop obj) PRODUCT_RETURN; + void verify() const PRODUCT_RETURN; }; #endif // SHARE_VM_RUNTIME_FIELDDESCRIPTOR_HPP diff --git a/hotspot/src/share/vm/runtime/mutexLocker.cpp b/hotspot/src/share/vm/runtime/mutexLocker.cpp index f513b7b376c..19f98cc2e4f 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp @@ -45,7 +45,6 @@ Mutex* InlineCacheBuffer_lock = NULL; Mutex* VMStatistic_lock = NULL; Mutex* JNIGlobalHandle_lock = NULL; Mutex* JNIHandleBlockFreeList_lock = NULL; -Mutex* JNICachedItableIndex_lock = NULL; Mutex* MemberNameTable_lock = NULL; Mutex* JmethodIdCreation_lock = NULL; Mutex* JfieldIdCreation_lock = NULL; @@ -253,7 +252,6 @@ void mutex_init() { } def(Heap_lock , Monitor, nonleaf+1, false); def(JfieldIdCreation_lock , Mutex , nonleaf+1, true ); // jfieldID, Used in VM_Operation - def(JNICachedItableIndex_lock , Mutex , nonleaf+1, false); // Used to cache an itable index during JNI invoke def(MemberNameTable_lock , Mutex , nonleaf+1, false); // Used to protect MemberNameTable def(CompiledIC_lock , Mutex , nonleaf+2, false); // locks VtableStubs_lock, InlineCacheBuffer_lock diff --git a/hotspot/src/share/vm/runtime/mutexLocker.hpp b/hotspot/src/share/vm/runtime/mutexLocker.hpp index d98b8d890fd..361febdcdb8 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.hpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -50,7 +50,6 @@ extern Mutex* InlineCacheBuffer_lock; // a lock used to guard the Inl extern Mutex* VMStatistic_lock; // a lock used to guard statistics count increment extern Mutex* JNIGlobalHandle_lock; // a lock on creating JNI global handles extern Mutex* JNIHandleBlockFreeList_lock; // a lock on the JNI handle block free list -extern Mutex* JNICachedItableIndex_lock; // a lock on caching an itable index during JNI invoke extern Mutex* MemberNameTable_lock; // a lock on the MemberNameTable updates extern Mutex* JmethodIdCreation_lock; // a lock on creating JNI method identifiers extern Mutex* JfieldIdCreation_lock; // a lock on creating JNI static field identifiers diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp index f06a7f922aa..be29fdecfcf 100644 --- a/hotspot/src/share/vm/runtime/reflection.cpp +++ b/hotspot/src/share/vm/runtime/reflection.cpp @@ -952,7 +952,8 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, } } else { // if the method can be overridden, we resolve using the vtable index. - int index = reflected_method->vtable_index(); + assert(!reflected_method->has_itable_index(), ""); + int index = reflected_method->vtable_index(); method = reflected_method; if (index != Method::nonvirtual_vtable_index) { // target_klass might be an arrayKlassOop but all vtables start at diff --git a/hotspot/src/share/vm/runtime/reflectionUtils.hpp b/hotspot/src/share/vm/runtime/reflectionUtils.hpp index d51b2ab7874..71a500976a7 100644 --- a/hotspot/src/share/vm/runtime/reflectionUtils.hpp +++ b/hotspot/src/share/vm/runtime/reflectionUtils.hpp @@ -109,6 +109,8 @@ class FieldStream : public KlassStream { private: int length() const { return _klass->java_fields_count(); } + fieldDescriptor _fd_buf; + public: FieldStream(instanceKlassHandle klass, bool local_only, bool classes_only) : KlassStream(klass, local_only, classes_only) { @@ -134,6 +136,12 @@ class FieldStream : public KlassStream { int offset() const { return _klass->field_offset( index() ); } + // bridge to a heavier API: + fieldDescriptor& field_descriptor() const { + fieldDescriptor& field = const_cast(_fd_buf); + field.reinitialize(_klass(), _index); + return field; + } }; class FilteredField : public CHeapObj { diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 448a8919f0e..55405b27fd4 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -315,7 +315,6 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(InstanceKlass, _breakpoints, BreakpointInfo*) \ nonstatic_field(InstanceKlass, _generic_signature_index, u2) \ nonstatic_field(InstanceKlass, _methods_jmethod_ids, jmethodID*) \ - nonstatic_field(InstanceKlass, _methods_cached_itable_indices, int*) \ volatile_nonstatic_field(InstanceKlass, _idnum_allocated_count, u2) \ nonstatic_field(InstanceKlass, _annotations, Annotations*) \ nonstatic_field(InstanceKlass, _dependencies, nmethodBucket*) \ From 0a312ba2ce98432392b3fe7b9054c74f93e66631 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Sat, 14 Sep 2013 15:23:21 +0100 Subject: [PATCH 0362/1294] 8024207: javac crash in Flow.AssignAnalyzer.visitIdent Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Resolve.java | 2 +- .../tools/javac/T8024207/FlowCrashTest.java | 23 +++++++++++++++++++ .../tools/javac/T8024207/FlowCrashTest.out | 2 ++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/T8024207/FlowCrashTest.java create mode 100644 langtools/test/tools/javac/T8024207/FlowCrashTest.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index f89bfed0161..e3c427413ec 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -2546,7 +2546,7 @@ public class Resolve { @Override Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) { if (sym.kind >= AMBIGUOUS) { - if (sym.kind == HIDDEN) { + if (sym.kind != WRONG_MTH && sym.kind != WRONG_MTHS) { sym = super.access(env, pos, location, sym); } else { final JCDiagnostic details = sym.kind == WRONG_MTH ? diff --git a/langtools/test/tools/javac/T8024207/FlowCrashTest.java b/langtools/test/tools/javac/T8024207/FlowCrashTest.java new file mode 100644 index 00000000000..5040c0ad448 --- /dev/null +++ b/langtools/test/tools/javac/T8024207/FlowCrashTest.java @@ -0,0 +1,23 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8024207 + * @summary javac crash in Flow$AssignAnalyzer.visitIdent + * @compile/fail/ref=FlowCrashTest.out -XDrawDiagnostics FlowCrashTest.java + */ + +import java.util.*; +import java.util.stream.*; + +public class FlowCrashTest { + static class ViewId { } + + public void crash() { + + Map viewToProfile = null; + new TreeMap<>(viewToProfile.entrySet().stream() + .collect(Collectors.toMap((vid, prn) -> prn, + (vid, prn) -> Arrays.asList(vid), + (a, b) -> { a.addAll(b); return a; }))); + + } +} diff --git a/langtools/test/tools/javac/T8024207/FlowCrashTest.out b/langtools/test/tools/javac/T8024207/FlowCrashTest.out new file mode 100644 index 00000000000..7eab7ccbb39 --- /dev/null +++ b/langtools/test/tools/javac/T8024207/FlowCrashTest.out @@ -0,0 +1,2 @@ +FlowCrashTest.java:18:42: compiler.err.cant.apply.symbols: kindname.method, toMap, @475,@542,@624,{(compiler.misc.inapplicable.method: kindname.method, java.util.stream.Collectors, toMap(java.util.function.Function,java.util.function.Function), (compiler.misc.infer.arg.length.mismatch: T,K,U)),(compiler.misc.inapplicable.method: kindname.method, java.util.stream.Collectors, toMap(java.util.function.Function,java.util.function.Function,java.util.function.BinaryOperator), (compiler.misc.infer.no.conforming.assignment.exists: T,K,U, (compiler.misc.incompatible.arg.types.in.lambda))),(compiler.misc.inapplicable.method: kindname.method, java.util.stream.Collectors, toMap(java.util.function.Function,java.util.function.Function,java.util.function.BinaryOperator,java.util.function.Supplier), (compiler.misc.infer.arg.length.mismatch: T,K,U,M))} +1 error From 86baa378e40350b45d474582e38bd5d87ab2b351 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Sat, 14 Sep 2013 19:04:47 +0100 Subject: [PATCH 0363/1294] 7047734: javac, the LVT is not generated correctly in several scenarios Reviewed-by: jjg, mcimadamore --- .../com/sun/tools/javac/code/Lint.java | 5 - .../com/sun/tools/javac/comp/Flow.java | 563 ++++++++++++------ .../sun/tools/javac/comp/LambdaToMethod.java | 5 + .../com/sun/tools/javac/comp/Lower.java | 37 +- .../com/sun/tools/javac/comp/MemberEnter.java | 4 +- .../com/sun/tools/javac/comp/TransTypes.java | 2 +- .../com/sun/tools/javac/jvm/ClassWriter.java | 51 +- .../classes/com/sun/tools/javac/jvm/Code.java | 215 ++++++- .../classes/com/sun/tools/javac/jvm/Gen.java | 457 +++++++++++++- .../com/sun/tools/javac/jvm/Items.java | 8 +- .../com/sun/tools/javac/jvm/LVTRanges.java | 129 ++++ .../com/sun/tools/javac/tree/TreeMaker.java | 2 +- .../com/sun/tools/javac/util/Bits.java | 128 ++-- .../test/tools/javac/flow/AliveRanges.java | 34 ++ .../test/tools/javac/flow/LVTHarness.java | 280 +++++++++ .../javac/flow/tests/TestCaseConditional.java | 16 + .../javac/flow/tests/TestCaseDoLoop.java | 15 + .../tools/javac/flow/tests/TestCaseFor.java | 27 + .../javac/flow/tests/TestCaseForEach.java | 15 + .../tools/javac/flow/tests/TestCaseIf.java | 61 ++ .../javac/flow/tests/TestCaseIfElse.java | 48 ++ .../javac/flow/tests/TestCaseSwitch.java | 73 +++ .../tools/javac/flow/tests/TestCaseTry.java | 76 +++ .../tools/javac/flow/tests/TestCaseWhile.java | 15 + 24 files changed, 1888 insertions(+), 378 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/javac/jvm/LVTRanges.java create mode 100644 langtools/test/tools/javac/flow/AliveRanges.java create mode 100644 langtools/test/tools/javac/flow/LVTHarness.java create mode 100644 langtools/test/tools/javac/flow/tests/TestCaseConditional.java create mode 100644 langtools/test/tools/javac/flow/tests/TestCaseDoLoop.java create mode 100644 langtools/test/tools/javac/flow/tests/TestCaseFor.java create mode 100644 langtools/test/tools/javac/flow/tests/TestCaseForEach.java create mode 100644 langtools/test/tools/javac/flow/tests/TestCaseIf.java create mode 100644 langtools/test/tools/javac/flow/tests/TestCaseIfElse.java create mode 100644 langtools/test/tools/javac/flow/tests/TestCaseSwitch.java create mode 100644 langtools/test/tools/javac/flow/tests/TestCaseTry.java create mode 100644 langtools/test/tools/javac/flow/tests/TestCaseWhile.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java index fb0ea30429f..9e1c4424fa8 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java @@ -33,9 +33,6 @@ import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Options; import com.sun.tools.javac.util.Pair; -import static com.sun.tools.javac.code.Flags.*; - - /** * A class for handling -Xlint suboptions and @SuppresssWarnings. * @@ -81,7 +78,6 @@ public class Lint return l; } - private final AugmentVisitor augmentor; private final EnumSet values; @@ -90,7 +86,6 @@ public class Lint private static final Map map = new java.util.concurrent.ConcurrentHashMap(20); - protected Lint(Context context) { // initialize values according to the lint options Options options = Options.instance(context); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index 466436b6b9e..252124370e5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -207,7 +207,7 @@ public class Flow { public void analyzeTree(Env env, TreeMaker make) { new AliveAnalyzer().analyzeTree(env, make); - new AssignAnalyzer().analyzeTree(env, make); + new AssignAnalyzer(log, syms, lint, names).analyzeTree(env); new FlowAnalyzer().analyzeTree(env, make); new CaptureAnalyzer().analyzeTree(env, make); } @@ -239,7 +239,7 @@ public class Flow { //related errors, which will allow for more errors to be detected Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); try { - new AssignAnalyzer().analyzeTree(env, that, make); + new AssignAnalyzer(log, syms, lint, names).analyzeTree(env); LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer(); flowAnalyzer.analyzeTree(env, that, make); return flowAnalyzer.inferredThrownTypes; @@ -291,15 +291,6 @@ public class Flow { allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses(); } - /** - * Utility method to reset several Bits instances. - */ - private void resetBits(Bits... bits) { - for (Bits b : bits) { - b.reset(); - } - } - /** * Base visitor class for all visitors implementing dataflow analysis logic. * This class define the shared logic for handling jumps (break/continue statements). @@ -347,17 +338,17 @@ public class Flow { this.tree = tree; } - void resolveJump() { + void resolveJump(JCTree tree) { //do nothing } } - abstract void markDead(); + abstract void markDead(JCTree tree); /** Record an outward transfer of control. */ void recordExit(JCTree tree, P pe) { pendingExits.append(pe); - markDead(); + markDead(tree); } /** Resolve all jumps of this statement. */ @@ -371,7 +362,7 @@ public class Flow { P exit = exits.head; if (exit.tree.hasTag(jk.treeTag) && jk.getTarget(exit.tree) == tree) { - exit.resolveJump(); + exit.resolveJump(tree); resolved = true; } else { pendingExits.append(exit); @@ -380,12 +371,12 @@ public class Flow { return resolved; } - /** Resolve all breaks of this statement. */ + /** Resolve all continues of this statement. */ boolean resolveContinues(JCTree tree) { return resolveJump(tree, new ListBuffer

    (), JumpKind.CONTINUE); } - /** Resolve all continues of this statement. */ + /** Resolve all breaks of this statement. */ boolean resolveBreaks(JCTree tree, ListBuffer

    oldPendingExits) { return resolveJump(tree, oldPendingExits, JumpKind.BREAK); } @@ -414,7 +405,7 @@ public class Flow { private boolean alive; @Override - void markDead() { + void markDead(JCTree tree) { alive = false; } @@ -696,7 +687,7 @@ public class Flow { public void visitThrow(JCThrow tree) { scan(tree.expr); - markDead(); + markDead(tree); } public void visitApply(JCMethodInvocation tree) { @@ -797,7 +788,7 @@ public class Flow { } @Override - void markDead() { + void markDead(JCTree tree) { //do nothing } @@ -1222,7 +1213,7 @@ public class Flow { else { markThrown(tree, tree.expr.type); } - markDead(); + markDead(tree); } public void visitApply(JCMethodInvocation tree) { @@ -1372,11 +1363,13 @@ public class Flow { * depends on the results of the liveliness analyzer. This pass is also used to mark * effectively-final local variables/parameters. */ - class AssignAnalyzer extends BaseAnalyzer { + + public abstract static class AbstractAssignAnalyzer

    + extends BaseAnalyzer

    { /** The set of definitely assigned variables. */ - final Bits inits; + protected final Bits inits; /** The set of definitely unassigned variables. */ @@ -1402,7 +1395,7 @@ public class Flow { /** A mapping from addresses to variable symbols. */ - JCVariableDecl[] vardecls; + protected JCVariableDecl[] vardecls; /** The current class being defined. */ @@ -1414,11 +1407,11 @@ public class Flow { /** The next available variable sequence number. */ - int nextadr; + protected int nextadr; /** The first variable sequence number in a block that can return. */ - int returnadr; + protected int returnadr; /** The list of unreferenced automatic resources. */ @@ -1430,35 +1423,46 @@ public class Flow { /** The starting position of the analysed tree */ int startPos; - AssignAnalyzer() { - inits = new Bits(); + final Symtab syms; + + protected Names names; + + public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit { + + final Bits inits; + final Bits uninits; + final Bits exit_inits = new Bits(true); + final Bits exit_uninits = new Bits(true); + + public AbstractAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { + super(tree); + this.inits = inits; + this.uninits = uninits; + this.exit_inits.assign(inits); + this.exit_uninits.assign(uninits); + } + + @Override + public void resolveJump(JCTree tree) { + inits.andSet(exit_inits); + uninits.andSet(exit_uninits); + } + } + + public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names) { + this.inits = inits; uninits = new Bits(); uninitsTry = new Bits(); initsWhenTrue = new Bits(true); initsWhenFalse = new Bits(true); uninitsWhenTrue = new Bits(true); uninitsWhenFalse = new Bits(true); - } - - class AssignPendingExit extends BaseAnalyzer.PendingExit { - - final Bits exit_inits = new Bits(true); - final Bits exit_uninits = new Bits(true); - - AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { - super(tree); - this.exit_inits.assign(inits); - this.exit_uninits.assign(uninits); - } - - void resolveJump() { - inits.andSet(exit_inits); - uninits.andSet(exit_uninits); - } + this.syms = syms; + this.names = names; } @Override - void markDead() { + protected void markDead(JCTree tree) { inits.inclRange(returnadr, nextadr); uninits.inclRange(returnadr, nextadr); } @@ -1468,7 +1472,7 @@ public class Flow { /** Do we need to track init/uninit state of this symbol? * I.e. is symbol either a local or a blank final variable? */ - boolean trackable(VarSymbol sym) { + protected boolean trackable(VarSymbol sym) { return sym.pos >= startPos && ((sym.owner.kind == MTH || @@ -1488,44 +1492,35 @@ public class Flow { } sym.adr = nextadr; vardecls[nextadr] = varDecl; - inits.excl(nextadr); + exclVarFromInits(varDecl, nextadr); uninits.incl(nextadr); nextadr++; } + protected void exclVarFromInits(JCTree tree, int adr) { + inits.excl(adr); + } + + protected void assignToInits(JCTree tree, Bits bits) { + inits.assign(bits); + } + + protected void andSetInits(JCTree tree, Bits bits) { + inits.andSet(bits); + } + + protected void orSetInits(JCTree tree, Bits bits) { + inits.orSet(bits); + } + /** Record an initialization of a trackable variable. */ void letInit(DiagnosticPosition pos, VarSymbol sym) { if (sym.adr >= firstadr && trackable(sym)) { - if ((sym.flags() & EFFECTIVELY_FINAL) != 0) { - if (!uninits.isMember(sym.adr)) { - //assignment targeting an effectively final variable - //makes the variable lose its status of effectively final - //if the variable is _not_ definitively unassigned - sym.flags_field &= ~EFFECTIVELY_FINAL; - } else { - uninit(sym); - } - } - else if ((sym.flags() & FINAL) != 0) { - if ((sym.flags() & PARAMETER) != 0) { - if ((sym.flags() & UNION) != 0) { //multi-catch parameter - log.error(pos, "multicatch.parameter.may.not.be.assigned", - sym); - } - else { - log.error(pos, "final.parameter.may.not.be.assigned", - sym); - } - } else if (!uninits.isMember(sym.adr)) { - log.error(pos, flowKind.errKey, sym); - } else { - uninit(sym); - } + if (uninits.isMember(sym.adr)) { + uninit(sym); } inits.incl(sym.adr); - } else if ((sym.flags() & FINAL) != 0) { - log.error(pos, "var.might.already.be.assigned", sym); } } //where @@ -1559,12 +1554,14 @@ public class Flow { void checkInit(DiagnosticPosition pos, VarSymbol sym) { checkInit(pos, sym, "var.might.not.have.been.initialized"); } - void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) { - if ((sym.adr >= firstadr || sym.owner.kind != TYP) && - trackable(sym) && - !inits.isMember(sym.adr)) { - log.error(pos, errkey, sym); - inits.incl(sym.adr); + + void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {} + + /** Utility method to reset several Bits instances. + */ + private void resetBits(Bits... bits) { + for (Bits b : bits) { + b.reset(); } } @@ -1582,7 +1579,7 @@ public class Flow { /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets. */ - void merge() { + protected void merge(JCTree tree) { inits.assign(initsWhenFalse.andSet(initsWhenTrue)); uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue)); } @@ -1597,7 +1594,9 @@ public class Flow { void scanExpr(JCTree tree) { if (tree != null) { scan(tree); - if (inits.isReset()) merge(); + if (inits.isReset()) { + merge(tree); + } } } @@ -1614,7 +1613,7 @@ public class Flow { */ void scanCond(JCTree tree) { if (tree.type.isFalse()) { - if (inits.isReset()) merge(); + if (inits.isReset()) merge(tree); initsWhenTrue.assign(inits); initsWhenTrue.inclRange(firstadr, nextadr); uninitsWhenTrue.assign(uninits); @@ -1622,7 +1621,7 @@ public class Flow { initsWhenFalse.assign(inits); uninitsWhenFalse.assign(uninits); } else if (tree.type.isTrue()) { - if (inits.isReset()) merge(); + if (inits.isReset()) merge(tree); initsWhenFalse.assign(inits); initsWhenFalse.inclRange(firstadr, nextadr); uninitsWhenFalse.assign(uninits); @@ -1641,22 +1640,22 @@ public class Flow { /* ------------ Visitor methods for various sorts of trees -------------*/ + @Override public void visitClassDef(JCClassDecl tree) { - if (tree.sym == null) return; + if (tree.sym == null) { + return; + } JCClassDecl classDefPrev = classDef; int firstadrPrev = firstadr; int nextadrPrev = nextadr; - ListBuffer pendingExitsPrev = pendingExits; - Lint lintPrev = lint; + ListBuffer

    pendingExitsPrev = pendingExits; - pendingExits = new ListBuffer(); + pendingExits = new ListBuffer

    (); if (tree.name != names.empty) { firstadr = nextadr; } classDef = tree; - lint = lint.augment(tree.sym); - try { // define all the static fields for (List l = tree.defs; l.nonEmpty(); l = l.tail) { @@ -1664,8 +1663,9 @@ public class Flow { JCVariableDecl def = (JCVariableDecl)l.head; if ((def.mods.flags & STATIC) != 0) { VarSymbol sym = def.sym; - if (trackable(sym)) + if (trackable(sym)) { newVar(def); + } } } } @@ -1684,8 +1684,9 @@ public class Flow { JCVariableDecl def = (JCVariableDecl)l.head; if ((def.mods.flags & STATIC) == 0) { VarSymbol sym = def.sym; - if (trackable(sym)) + if (trackable(sym)) { newVar(def); + } } } } @@ -1709,21 +1710,25 @@ public class Flow { nextadr = nextadrPrev; firstadr = firstadrPrev; classDef = classDefPrev; - lint = lintPrev; } } + @Override public void visitMethodDef(JCMethodDecl tree) { - if (tree.body == null) return; + if (tree.body == null) { + return; + } + /* MemberEnter can generate synthetic methods, ignore them + */ + if ((tree.sym.flags() & SYNTHETIC) != 0) { + return; + } final Bits initsPrev = new Bits(inits); final Bits uninitsPrev = new Bits(uninits); int nextadrPrev = nextadr; int firstadrPrev = firstadr; int returnadrPrev = returnadr; - Lint lintPrev = lint; - - lint = lint.augment(tree.sym); Assert.check(pendingExits.isEmpty()); @@ -1731,13 +1736,17 @@ public class Flow { boolean isInitialConstructor = TreeInfo.isInitialConstructor(tree); - if (!isInitialConstructor) + if (!isInitialConstructor) { firstadr = nextadr; + } for (List l = tree.params; l.nonEmpty(); l = l.tail) { JCVariableDecl def = l.head; scan(def); - inits.incl(def.sym.adr); - uninits.excl(def.sym.adr); + Assert.check((def.sym.flags() & PARAMETER) != 0, "Method parameter without PARAMETER flag"); + /* If we are executing the code from Gen, then there can be + * synthetic or mandated variables, ignore them. + */ + initParam(def); } // else we are in an instance initializer block; // leave caught unchanged. @@ -1761,39 +1770,42 @@ public class Flow { } } } - List exits = pendingExits.toList(); - pendingExits = new ListBuffer(); + List

    exits = pendingExits.toList(); + pendingExits = new ListBuffer<>(); while (exits.nonEmpty()) { - AssignPendingExit exit = exits.head; + P exit = exits.head; exits = exits.tail; Assert.check(exit.tree.hasTag(RETURN), exit.tree); if (isInitialConstructor) { - inits.assign(exit.exit_inits); - for (int i = firstadr; i < nextadr; i++) + assignToInits(exit.tree, exit.exit_inits); + for (int i = firstadr; i < nextadr; i++) { checkInit(exit.tree.pos(), vardecls[i].sym); + } } } } finally { - inits.assign(initsPrev); + assignToInits(tree, initsPrev); uninits.assign(uninitsPrev); nextadr = nextadrPrev; firstadr = firstadrPrev; returnadr = returnadrPrev; - lint = lintPrev; } } + protected void initParam(JCVariableDecl def) { + inits.incl(def.sym.adr); + uninits.excl(def.sym.adr); + } + public void visitVarDef(JCVariableDecl tree) { boolean track = trackable(tree.sym); - if (track && tree.sym.owner.kind == MTH) newVar(tree); + if (track && tree.sym.owner.kind == MTH) { + newVar(tree); + } if (tree.init != null) { - Lint lintPrev = lint; - lint = lint.augment(tree.sym); - try{ - scanExpr(tree.init); - if (track) letInit(tree.pos(), tree.sym); - } finally { - lint = lintPrev; + scanExpr(tree.init); + if (track) { + letInit(tree.pos(), tree.sym); } } } @@ -1804,14 +1816,18 @@ public class Flow { nextadr = nextadrPrev; } + int getLogNumberOfErrors() { + return 0; + } + public void visitDoLoop(JCDoWhileLoop tree) { - ListBuffer prevPendingExits = pendingExits; + ListBuffer

    prevPendingExits = pendingExits; FlowKind prevFlowKind = flowKind; flowKind = FlowKind.NORMAL; final Bits initsSkip = new Bits(true); final Bits uninitsSkip = new Bits(true); - pendingExits = new ListBuffer(); - int prevErrors = log.nerrors; + pendingExits = new ListBuffer

    (); + int prevErrors = getLogNumberOfErrors(); do { final Bits uninitsEntry = new Bits(uninits); uninitsEntry.excludeFrom(nextadr); @@ -1822,28 +1838,28 @@ public class Flow { initsSkip.assign(initsWhenFalse); uninitsSkip.assign(uninitsWhenFalse); } - if (log.nerrors != prevErrors || + if (getLogNumberOfErrors() != prevErrors || flowKind.isFinal() || new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1) break; - inits.assign(initsWhenTrue); + assignToInits(tree.cond, initsWhenTrue); uninits.assign(uninitsEntry.andSet(uninitsWhenTrue)); flowKind = FlowKind.SPECULATIVE_LOOP; } while (true); flowKind = prevFlowKind; - inits.assign(initsSkip); + assignToInits(tree, initsSkip); uninits.assign(uninitsSkip); resolveBreaks(tree, prevPendingExits); } public void visitWhileLoop(JCWhileLoop tree) { - ListBuffer prevPendingExits = pendingExits; + ListBuffer

    prevPendingExits = pendingExits; FlowKind prevFlowKind = flowKind; flowKind = FlowKind.NORMAL; final Bits initsSkip = new Bits(true); final Bits uninitsSkip = new Bits(true); - pendingExits = new ListBuffer(); - int prevErrors = log.nerrors; + pendingExits = new ListBuffer<>(); + int prevErrors = getLogNumberOfErrors(); final Bits uninitsEntry = new Bits(uninits); uninitsEntry.excludeFrom(nextadr); do { @@ -1852,35 +1868,36 @@ public class Flow { initsSkip.assign(initsWhenFalse) ; uninitsSkip.assign(uninitsWhenFalse); } - inits.assign(initsWhenTrue); + assignToInits(tree, initsWhenTrue); uninits.assign(uninitsWhenTrue); scan(tree.body); resolveContinues(tree); - if (log.nerrors != prevErrors || + if (getLogNumberOfErrors() != prevErrors || flowKind.isFinal() || - new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) + new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) { break; + } uninits.assign(uninitsEntry.andSet(uninits)); flowKind = FlowKind.SPECULATIVE_LOOP; } while (true); flowKind = prevFlowKind; //a variable is DA/DU after the while statement, if it's DA/DU assuming the //branch is not taken AND if it's DA/DU before any break statement - inits.assign(initsSkip); + assignToInits(tree.body, initsSkip); uninits.assign(uninitsSkip); resolveBreaks(tree, prevPendingExits); } public void visitForLoop(JCForLoop tree) { - ListBuffer prevPendingExits = pendingExits; + ListBuffer

    prevPendingExits = pendingExits; FlowKind prevFlowKind = flowKind; flowKind = FlowKind.NORMAL; int nextadrPrev = nextadr; scan(tree.init); final Bits initsSkip = new Bits(true); final Bits uninitsSkip = new Bits(true); - pendingExits = new ListBuffer(); - int prevErrors = log.nerrors; + pendingExits = new ListBuffer

    (); + int prevErrors = getLogNumberOfErrors(); do { final Bits uninitsEntry = new Bits(uninits); uninitsEntry.excludeFrom(nextadr); @@ -1890,7 +1907,7 @@ public class Flow { initsSkip.assign(initsWhenFalse); uninitsSkip.assign(uninitsWhenFalse); } - inits.assign(initsWhenTrue); + assignToInits(tree.body, initsWhenTrue); uninits.assign(uninitsWhenTrue); } else if (!flowKind.isFinal()) { initsSkip.assign(inits); @@ -1901,7 +1918,7 @@ public class Flow { scan(tree.body); resolveContinues(tree); scan(tree.step); - if (log.nerrors != prevErrors || + if (getLogNumberOfErrors() != prevErrors || flowKind.isFinal() || new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) break; @@ -1911,7 +1928,7 @@ public class Flow { flowKind = prevFlowKind; //a variable is DA/DU after a for loop, if it's DA/DU assuming the //branch is not taken AND if it's DA/DU before any break statement - inits.assign(initsSkip); + assignToInits(tree.body, initsSkip); uninits.assign(uninitsSkip); resolveBreaks(tree, prevPendingExits); nextadr = nextadrPrev; @@ -1920,7 +1937,7 @@ public class Flow { public void visitForeachLoop(JCEnhancedForLoop tree) { visitVarDef(tree.var); - ListBuffer prevPendingExits = pendingExits; + ListBuffer

    prevPendingExits = pendingExits; FlowKind prevFlowKind = flowKind; flowKind = FlowKind.NORMAL; int nextadrPrev = nextadr; @@ -1929,14 +1946,14 @@ public class Flow { final Bits uninitsStart = new Bits(uninits); letInit(tree.pos(), tree.var.sym); - pendingExits = new ListBuffer(); - int prevErrors = log.nerrors; + pendingExits = new ListBuffer

    (); + int prevErrors = getLogNumberOfErrors(); do { final Bits uninitsEntry = new Bits(uninits); uninitsEntry.excludeFrom(nextadr); scan(tree.body); resolveContinues(tree); - if (log.nerrors != prevErrors || + if (getLogNumberOfErrors() != prevErrors || flowKind.isFinal() || new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) break; @@ -1944,41 +1961,50 @@ public class Flow { flowKind = FlowKind.SPECULATIVE_LOOP; } while (true); flowKind = prevFlowKind; - inits.assign(initsStart); + assignToInits(tree.body, initsStart); uninits.assign(uninitsStart.andSet(uninits)); resolveBreaks(tree, prevPendingExits); nextadr = nextadrPrev; } public void visitLabelled(JCLabeledStatement tree) { - ListBuffer prevPendingExits = pendingExits; - pendingExits = new ListBuffer(); + ListBuffer

    prevPendingExits = pendingExits; + pendingExits = new ListBuffer

    (); scan(tree.body); resolveBreaks(tree, prevPendingExits); } public void visitSwitch(JCSwitch tree) { - ListBuffer prevPendingExits = pendingExits; - pendingExits = new ListBuffer(); + ListBuffer

    prevPendingExits = pendingExits; + pendingExits = new ListBuffer<>(); int nextadrPrev = nextadr; scanExpr(tree.selector); final Bits initsSwitch = new Bits(inits); final Bits uninitsSwitch = new Bits(uninits); boolean hasDefault = false; for (List l = tree.cases; l.nonEmpty(); l = l.tail) { - inits.assign(initsSwitch); + assignToInits(l.head, initsSwitch); uninits.assign(uninits.andSet(uninitsSwitch)); JCCase c = l.head; - if (c.pat == null) + if (c.pat == null) { hasDefault = true; - else + } else { scanExpr(c.pat); + } + if (hasDefault) { + assignToInits(null, initsSwitch); + uninits.assign(uninits.andSet(uninitsSwitch)); + } scan(c.stats); addVars(c.stats, initsSwitch, uninitsSwitch); + if (!hasDefault) { + assignToInits(l.head.stats.last(), initsSwitch); + uninits.assign(uninits.andSet(uninitsSwitch)); + } // Warn about fall-through if lint switch fallthrough enabled. } if (!hasDefault) { - inits.andSet(initsSwitch); + andSetInits(null, initsSwitch); } resolveBreaks(tree, prevPendingExits); nextadr = nextadrPrev; @@ -1997,11 +2023,17 @@ public class Flow { } } + boolean isEnabled(Lint.LintCategory lc) { + return false; + } + + void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {} + public void visitTry(JCTry tree) { ListBuffer resourceVarDecls = ListBuffer.lb(); final Bits uninitsTryPrev = new Bits(uninitsTry); - ListBuffer prevPendingExits = pendingExits; - pendingExits = new ListBuffer(); + ListBuffer

    prevPendingExits = pendingExits; + pendingExits = new ListBuffer<>(); final Bits initsTry = new Bits(inits); uninitsTry.assign(uninits); for (JCTree resource : tree.resources) { @@ -2023,10 +2055,10 @@ public class Flow { int nextadrCatch = nextadr; if (!resourceVarDecls.isEmpty() && - lint.isEnabled(Lint.LintCategory.TRY)) { + isEnabled(Lint.LintCategory.TRY)) { for (JCVariableDecl resVar : resourceVarDecls) { if (unrefdResources.includes(resVar.sym)) { - log.warning(Lint.LintCategory.TRY, resVar.pos(), + reportWarning(Lint.LintCategory.TRY, resVar.pos(), "try.resource.not.referenced", resVar.sym); unrefdResources.remove(resVar.sym); } @@ -2042,20 +2074,22 @@ public class Flow { for (List l = tree.catchers; l.nonEmpty(); l = l.tail) { JCVariableDecl param = l.head.param; - inits.assign(initsCatchPrev); + assignToInits(tree.body, initsCatchPrev); uninits.assign(uninitsCatchPrev); scan(param); - inits.incl(param.sym.adr); - uninits.excl(param.sym.adr); + /* If this is a TWR and we are executing the code from Gen, + * then there can be synthetic variables, ignore them. + */ + initParam(param); scan(l.head.body); initsEnd.andSet(inits); uninitsEnd.andSet(uninits); nextadr = nextadrCatch; } if (tree.finalizer != null) { - inits.assign(initsTry); + assignToInits(tree.finalizer, initsTry); uninits.assign(uninitsTry); - ListBuffer exits = pendingExits; + ListBuffer

    exits = pendingExits; pendingExits = prevPendingExits; scan(tree.finalizer); if (!tree.finallyCanCompleteNormally) { @@ -2065,19 +2099,19 @@ public class Flow { // FIX: this doesn't preserve source order of exits in catch // versus finally! while (exits.nonEmpty()) { - AssignPendingExit exit = exits.next(); + P exit = exits.next(); if (exit.exit_inits != null) { exit.exit_inits.orSet(inits); exit.exit_uninits.andSet(uninits); } pendingExits.append(exit); } - inits.orSet(initsEnd); + orSetInits(tree, initsEnd); } } else { - inits.assign(initsEnd); + assignToInits(tree, initsEnd); uninits.assign(uninitsEnd); - ListBuffer exits = pendingExits; + ListBuffer

    exits = pendingExits; pendingExits = prevPendingExits; while (exits.nonEmpty()) pendingExits.append(exits.next()); } @@ -2088,7 +2122,7 @@ public class Flow { scanCond(tree.cond); final Bits initsBeforeElse = new Bits(initsWhenFalse); final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse); - inits.assign(initsWhenTrue); + assignToInits(tree.cond, initsWhenTrue); uninits.assign(uninitsWhenTrue); if (tree.truepart.type.hasTag(BOOLEAN) && tree.falsepart.type.hasTag(BOOLEAN)) { @@ -2101,7 +2135,7 @@ public class Flow { final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse); final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue); final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse); - inits.assign(initsBeforeElse); + assignToInits(tree.truepart, initsBeforeElse); uninits.assign(uninitsBeforeElse); scanCond(tree.falsepart); initsWhenTrue.andSet(initsAfterThenWhenTrue); @@ -2112,10 +2146,10 @@ public class Flow { scanExpr(tree.truepart); final Bits initsAfterThen = new Bits(inits); final Bits uninitsAfterThen = new Bits(uninits); - inits.assign(initsBeforeElse); + assignToInits(tree.truepart, initsBeforeElse); uninits.assign(uninitsBeforeElse); scanExpr(tree.falsepart); - inits.andSet(initsAfterThen); + andSetInits(tree.falsepart, initsAfterThen); uninits.andSet(uninitsAfterThen); } } @@ -2124,39 +2158,46 @@ public class Flow { scanCond(tree.cond); final Bits initsBeforeElse = new Bits(initsWhenFalse); final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse); - inits.assign(initsWhenTrue); + assignToInits(tree.cond, initsWhenTrue); uninits.assign(uninitsWhenTrue); scan(tree.thenpart); if (tree.elsepart != null) { final Bits initsAfterThen = new Bits(inits); final Bits uninitsAfterThen = new Bits(uninits); - inits.assign(initsBeforeElse); + assignToInits(tree.thenpart, initsBeforeElse); uninits.assign(uninitsBeforeElse); scan(tree.elsepart); - inits.andSet(initsAfterThen); + andSetInits(tree.elsepart, initsAfterThen); uninits.andSet(uninitsAfterThen); } else { - inits.andSet(initsBeforeElse); + andSetInits(tree.thenpart, initsBeforeElse); uninits.andSet(uninitsBeforeElse); } } + protected P createNewPendingExit(JCTree tree, Bits inits, Bits uninits) { + return null; + } + + @Override public void visitBreak(JCBreak tree) { - recordExit(tree, new AssignPendingExit(tree, inits, uninits)); + recordExit(tree, createNewPendingExit(tree, inits, uninits)); } + @Override public void visitContinue(JCContinue tree) { - recordExit(tree, new AssignPendingExit(tree, inits, uninits)); + recordExit(tree, createNewPendingExit(tree, inits, uninits)); } + @Override public void visitReturn(JCReturn tree) { scanExpr(tree.expr); - recordExit(tree, new AssignPendingExit(tree, inits, uninits)); + recordExit(tree, createNewPendingExit(tree, inits, uninits)); } public void visitThrow(JCThrow tree) { scanExpr(tree.expr); - markDead(); + markDead(tree.expr); } public void visitApply(JCMethodInvocation tree) { @@ -2175,10 +2216,10 @@ public class Flow { final Bits prevUninits = new Bits(uninits); final Bits prevInits = new Bits(inits); int returnadrPrev = returnadr; - ListBuffer prevPending = pendingExits; + ListBuffer

    prevPending = pendingExits; try { returnadr = nextadr; - pendingExits = new ListBuffer(); + pendingExits = new ListBuffer

    (); for (List l = tree.params; l.nonEmpty(); l = l.tail) { JCVariableDecl def = l.head; scan(def); @@ -2194,7 +2235,7 @@ public class Flow { finally { returnadr = returnadrPrev; uninits.assign(prevUninits); - inits.assign(prevInits); + assignToInits(tree, prevInits); pendingExits = prevPending; } } @@ -2210,11 +2251,11 @@ public class Flow { scanCond(tree.cond); uninitsExit.andSet(uninitsWhenTrue); if (tree.detail != null) { - inits.assign(initsWhenFalse); + assignToInits(tree, initsWhenFalse); uninits.assign(uninitsWhenFalse); scanExpr(tree.detail); } - inits.assign(initsExit); + assignToInits(tree, initsExit); uninits.assign(uninitsExit); } @@ -2260,7 +2301,7 @@ public class Flow { scanCond(tree.lhs); final Bits initsWhenFalseLeft = new Bits(initsWhenFalse); final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse); - inits.assign(initsWhenTrue); + assignToInits(tree.lhs, initsWhenTrue); uninits.assign(uninitsWhenTrue); scanCond(tree.rhs); initsWhenFalse.andSet(initsWhenFalseLeft); @@ -2270,7 +2311,7 @@ public class Flow { scanCond(tree.lhs); final Bits initsWhenTrueLeft = new Bits(initsWhenTrue); final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue); - inits.assign(initsWhenFalse); + assignToInits(tree.lhs, initsWhenFalse); uninits.assign(uninitsWhenFalse); scanCond(tree.rhs); initsWhenTrue.andSet(initsWhenTrueLeft); @@ -2308,14 +2349,12 @@ public class Flow { /** Perform definite assignment/unassignment analysis on a tree. */ - public void analyzeTree(Env env, TreeMaker make) { - analyzeTree(env, env.tree, make); - } + public void analyzeTree(Env env) { + analyzeTree(env, env.tree); + } - public void analyzeTree(Env env, JCTree tree, TreeMaker make) { + public void analyzeTree(Env env, JCTree tree) { try { - attrEnv = env; - Flow.this.make = make; startPos = tree.pos().getStartPosition(); if (vardecls == null) @@ -2325,7 +2364,7 @@ public class Flow { vardecls[i] = null; firstadr = 0; nextadr = 0; - pendingExits = new ListBuffer(); + pendingExits = new ListBuffer<>(); this.classDef = null; unrefdResources = new Scope(env.enclClass.sym); scan(tree); @@ -2334,18 +2373,160 @@ public class Flow { startPos = -1; resetBits(inits, uninits, uninitsTry, initsWhenTrue, initsWhenFalse, uninitsWhenTrue, uninitsWhenFalse); - if (vardecls != null) for (int i=0; i { + + Log log; + Lint lint; + + public static class AssignPendingExit + extends AbstractAssignAnalyzer.AbstractAssignPendingExit { + + public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { + super(tree, inits, uninits); + } + } + + public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names) { + super(new Bits(), syms, names); + this.log = log; + this.lint = lint; + } + + @Override + protected AssignPendingExit createNewPendingExit(JCTree tree, + Bits inits, Bits uninits) { + return new AssignPendingExit(tree, inits, uninits); + } + + /** Record an initialization of a trackable variable. + */ + @Override + void letInit(DiagnosticPosition pos, VarSymbol sym) { + if (sym.adr >= firstadr && trackable(sym)) { + if ((sym.flags() & EFFECTIVELY_FINAL) != 0) { + if (!uninits.isMember(sym.adr)) { + //assignment targeting an effectively final variable + //makes the variable lose its status of effectively final + //if the variable is _not_ definitively unassigned + sym.flags_field &= ~EFFECTIVELY_FINAL; + } else { + uninit(sym); + } + } + else if ((sym.flags() & FINAL) != 0) { + if ((sym.flags() & PARAMETER) != 0) { + if ((sym.flags() & UNION) != 0) { //multi-catch parameter + log.error(pos, "multicatch.parameter.may.not.be.assigned", sym); + } + else { + log.error(pos, "final.parameter.may.not.be.assigned", + sym); + } + } else if (!uninits.isMember(sym.adr)) { + log.error(pos, flowKind.errKey, sym); + } else { + uninit(sym); + } + } + inits.incl(sym.adr); + } else if ((sym.flags() & FINAL) != 0) { + log.error(pos, "var.might.already.be.assigned", sym); + } + } + + @Override + void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) { + if ((sym.adr >= firstadr || sym.owner.kind != TYP) && + trackable(sym) && + !inits.isMember(sym.adr)) { + log.error(pos, errkey, sym); + inits.incl(sym.adr); + } + } + + @Override + void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos, + String key, Object ... args) { + log.warning(lc, pos, key, args); + } + + @Override + int getLogNumberOfErrors() { + return log.nerrors; + } + + @Override + boolean isEnabled(Lint.LintCategory lc) { + return lint.isEnabled(lc); + } + + @Override + public void visitClassDef(JCClassDecl tree) { + if (tree.sym == null) { + return; + } + + Lint lintPrev = lint; + lint = lint.augment(tree.sym); + try { + super.visitClassDef(tree); + } finally { + lint = lintPrev; + } + } + + @Override + public void visitMethodDef(JCMethodDecl tree) { + if (tree.body == null) { + return; + } + + /* MemberEnter can generate synthetic methods ignore them + */ + if ((tree.sym.flags() & SYNTHETIC) != 0) { + return; + } + + Lint lintPrev = lint; + lint = lint.augment(tree.sym); + try { + super.visitMethodDef(tree); + } finally { + lint = lintPrev; + } + } + + @Override + public void visitVarDef(JCVariableDecl tree) { + if (tree.init == null) { + super.visitVarDef(tree); + } else { + Lint lintPrev = lint; + lint = lint.augment(tree.sym); + try{ + super.visitVarDef(tree); + } finally { + lint = lintPrev; + } + } + } + + } + /** * This pass implements the last step of the dataflow analysis, namely * the effectively-final analysis check. This checks that every local variable @@ -2358,7 +2539,7 @@ public class Flow { JCTree currentTree; //local class or lambda @Override - void markDead() { + void markDead(JCTree tree) { //do nothing } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index 7633f96d1df..b2a501d27d6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -1745,6 +1745,11 @@ public class LambdaToMethod extends TreeTranslator { // Just erase the type var ret = new VarSymbol(sym.flags(), name, types.erasure(sym.type), sym.owner); + + /* this information should also be kept for LVT generation at Gen + * a Symbol with pos < startPos won't be tracked. + */ + ((VarSymbol)ret).pos = ((VarSymbol)sym).pos; break; case CAPTURED_VAR: ret = new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 5926a1b68c1..cb054fe80f2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -1479,7 +1479,12 @@ public class Lower extends TreeTranslator { * @param owner The class in which the definitions go. */ List freevarDefs(int pos, List freevars, Symbol owner) { - long flags = FINAL | SYNTHETIC; + return freevarDefs(pos, freevars, owner, 0); + } + + List freevarDefs(int pos, List freevars, Symbol owner, + long additionalFlags) { + long flags = FINAL | SYNTHETIC | additionalFlags; if (owner.kind == TYP && target.usePrivateSyntheticFields()) flags |= PRIVATE; @@ -1542,7 +1547,7 @@ public class Lower extends TreeTranslator { (owner.isConstructor() && c.isInner() && !c.isPrivate() && !c.isStatic()); long flags = - FINAL | (isMandated ? MANDATED : SYNTHETIC); + FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER; VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags); owner.extraParams = owner.extraParams.prepend(outerThis); return makeOuterThisVarDecl(pos, outerThis); @@ -1626,7 +1631,8 @@ public class Lower extends TreeTranslator { JCTree makeTwrTry(JCTry tree) { make_at(tree.pos()); twrVars = twrVars.dup(); - JCBlock twrBlock = makeTwrBlock(tree.resources, tree.body, 0); + JCBlock twrBlock = makeTwrBlock(tree.resources, tree.body, + tree.finallyCanCompleteNormally, 0); if (tree.catchers.isEmpty() && tree.finalizer == null) result = translate(twrBlock); else @@ -1635,7 +1641,8 @@ public class Lower extends TreeTranslator { return result; } - private JCBlock makeTwrBlock(List resources, JCBlock block, int depth) { + private JCBlock makeTwrBlock(List resources, JCBlock block, + boolean finallyCanCompleteNormally, int depth) { if (resources.isEmpty()) return block; @@ -1691,17 +1698,20 @@ public class Lower extends TreeTranslator { make.at(TreeInfo.endPos(block)); JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr); make.at(oldPos); - JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1), + JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, + finallyCanCompleteNormally, depth + 1), List.of(catchClause), finallyClause); + outerTry.finallyCanCompleteNormally = finallyCanCompleteNormally; stats.add(outerTry); - return make.Block(0L, stats.toList()); + JCBlock newBlock = make.Block(0L, stats.toList()); + return newBlock; } private JCBlock makeTwrFinallyClause(Symbol primaryException, JCExpression resource) { // primaryException.addSuppressed(catchException); VarSymbol catchException = - new VarSymbol(0, make.paramName(2), + new VarSymbol(SYNTHETIC, make.paramName(2), syms.throwableType, currentMethodSym); JCStatement addSuppressionStatement = @@ -1716,6 +1726,7 @@ public class Lower extends TreeTranslator { JCBlock catchBlock = make.Block(0L, List.of(addSuppressionStatement)); List catchClauses = List.of(make.Catch(catchExceptionDecl, catchBlock)); JCTry tryTree = make.Try(tryBlock, catchClauses, null); + tryTree.finallyCanCompleteNormally = true; // if (primaryException != null) {try...} else resourceClose; JCIf closeIfStatement = make.If(makeNonNullCheck(make.Ident(primaryException)), @@ -2016,7 +2027,7 @@ public class Lower extends TreeTranslator { // catchParam := ClassNotFoundException e1 VarSymbol catchParam = - new VarSymbol(0, make.paramName(1), + new VarSymbol(SYNTHETIC, make.paramName(1), syms.classNotFoundExceptionType, classDollarSym); @@ -2704,7 +2715,7 @@ public class Lower extends TreeTranslator { JCVariableDecl otdef = null; if (currentClass.hasOuterInstance()) otdef = outerThisDef(tree.pos, m); - List fvdefs = freevarDefs(tree.pos, fvs, m); + List fvdefs = freevarDefs(tree.pos, fvs, m, PARAMETER); // Recursively translate result type, parameters and thrown list. tree.restype = translate(tree.restype); @@ -3363,18 +3374,18 @@ public class Lower extends TreeTranslator { */ private void visitArrayForeachLoop(JCEnhancedForLoop tree) { make_at(tree.expr.pos()); - VarSymbol arraycache = new VarSymbol(0, + VarSymbol arraycache = new VarSymbol(SYNTHETIC, names.fromString("arr" + target.syntheticNameChar()), tree.expr.type, currentMethodSym); JCStatement arraycachedef = make.VarDef(arraycache, tree.expr); - VarSymbol lencache = new VarSymbol(0, + VarSymbol lencache = new VarSymbol(SYNTHETIC, names.fromString("len" + target.syntheticNameChar()), syms.intType, currentMethodSym); JCStatement lencachedef = make. VarDef(lencache, make.Select(make.Ident(arraycache), syms.lengthVar)); - VarSymbol index = new VarSymbol(0, + VarSymbol index = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()), syms.intType, currentMethodSym); @@ -3456,7 +3467,7 @@ public class Lower extends TreeTranslator { names.iterator, eType, List.nil()); - VarSymbol itvar = new VarSymbol(0, names.fromString("i" + target.syntheticNameChar()), + VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()), types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym)), currentMethodSym); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 9f9dd4fb874..a2d021fbc36 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -1532,7 +1532,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { * parameters from baseInit. */ initParams = List.nil(); - VarSymbol param = new VarSymbol(0, make.paramName(0), argtypes.head, init); + VarSymbol param = new VarSymbol(PARAMETER, make.paramName(0), argtypes.head, init); initParams = initParams.append(param); argTypesList = argTypesList.tail; } @@ -1541,7 +1541,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { initParams = (initParams == null) ? List.nil() : initParams; List baseInitParams = baseInit.params; while (baseInitParams.nonEmpty() && argTypesList.nonEmpty()) { - VarSymbol param = new VarSymbol(baseInitParams.head.flags(), + VarSymbol param = new VarSymbol(baseInitParams.head.flags() | PARAMETER, baseInitParams.head.name, argTypesList.head, init); initParams = initParams.append(param); baseInitParams = baseInitParams.tail; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java index ff7f0da574d..d747a2b5156 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -310,7 +310,7 @@ public class TransTypes extends TreeTranslator { Type.MethodType mType = (Type.MethodType)bridgeType; List argTypes = mType.argtypes; while (implParams.nonEmpty() && argTypes.nonEmpty()) { - VarSymbol param = new VarSymbol(implParams.head.flags() | SYNTHETIC, + VarSymbol param = new VarSymbol(implParams.head.flags() | SYNTHETIC | PARAMETER, implParams.head.name, argTypes.head, bridge); param.setAttributes(implParams.head); bridgeParams = bridgeParams.append(param); diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index 73eb2d34acf..6698c7fde27 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -37,7 +37,6 @@ import javax.tools.JavaFileObject; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Attribute.RetentionPolicy; -import com.sun.tools.javac.code.Attribute.TypeCompound; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Types.UniqueType; @@ -55,7 +54,6 @@ import static com.sun.tools.javac.jvm.UninitializedType.*; import static com.sun.tools.javac.main.Option.*; import static javax.tools.StandardLocation.CLASS_OUTPUT; - /** This class provides operations to map an internal symbol table graph * rooted in a ClassSymbol into a classfile. * @@ -1180,25 +1178,26 @@ public class ClassWriter extends ClassFile { if (code.varBufferSize > 0) { int alenIdx = writeAttr(names.LocalVariableTable); - databuf.appendChar(code.varBufferSize); - + databuf.appendChar(code.getLVTSize()); for (int i=0; i= 0 - && var.start_pc <= code.cp); - databuf.appendChar(var.start_pc); - Assert.check(var.length >= 0 - && (var.start_pc + var.length) <= code.cp); - databuf.appendChar(var.length); - VarSymbol sym = var.sym; - databuf.appendChar(pool.put(sym.name)); - Type vartype = sym.erasure(types); - if (needsLocalVariableTypeEntry(sym.type)) - nGenericVars++; - databuf.appendChar(pool.put(typeSig(vartype))); - databuf.appendChar(var.reg); + for (Code.LocalVar.Range r: var.aliveRanges) { + // write variable info + Assert.check(r.start_pc >= 0 + && r.start_pc <= code.cp); + databuf.appendChar(r.start_pc); + Assert.check(r.length >= 0 + && (r.start_pc + r.length) <= code.cp); + databuf.appendChar(r.length); + VarSymbol sym = var.sym; + databuf.appendChar(pool.put(sym.name)); + Type vartype = sym.erasure(types); + databuf.appendChar(pool.put(typeSig(vartype))); + databuf.appendChar(var.reg); + if (needsLocalVariableTypeEntry(var.sym.type)) + nGenericVars++; + } } endAttr(alenIdx); acount++; @@ -1214,13 +1213,15 @@ public class ClassWriter extends ClassFile { VarSymbol sym = var.sym; if (!needsLocalVariableTypeEntry(sym.type)) continue; - count++; - // write variable info - databuf.appendChar(var.start_pc); - databuf.appendChar(var.length); - databuf.appendChar(pool.put(sym.name)); - databuf.appendChar(pool.put(typeSig(sym.type))); - databuf.appendChar(var.reg); + for (Code.LocalVar.Range r : var.aliveRanges) { + // write variable info + databuf.appendChar(r.start_pc); + databuf.appendChar(r.length); + databuf.appendChar(pool.put(sym.name)); + databuf.appendChar(pool.put(typeSig(sym.type))); + databuf.appendChar(var.reg); + count++; + } } Assert.check(count == nGenericVars); endAttr(alenIdx); diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java index d151dd46172..d0ed7ec559c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java @@ -28,6 +28,7 @@ package com.sun.tools.javac.jvm; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Types.UniqueType; +import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -181,6 +182,8 @@ public class Code { final MethodSymbol meth; + final LVTRanges lvtRanges; + /** Construct a code object, given the settings of the fatcode, * debugging info switches and the CharacterRangeTable. */ @@ -193,7 +196,8 @@ public class Code { CRTable crt, Symtab syms, Types types, - Pool pool) { + Pool pool, + LVTRanges lvtRanges) { this.meth = meth; this.fatcode = fatcode; this.lineMap = lineMap; @@ -215,6 +219,7 @@ public class Code { state = new State(); lvar = new LocalVar[20]; this.pool = pool; + this.lvtRanges = lvtRanges; } @@ -305,9 +310,19 @@ public class Code { /** The current output code pointer. */ - public int curPc() { - if (pendingJumps != null) resolvePending(); - if (pendingStatPos != Position.NOPOS) markStatBegin(); + public int curCP() { + /* + * This method has side-effects because calling it can indirectly provoke + * extra code generation, like goto instructions, depending on the context + * where it's called. + * Use with care or even better avoid using it. + */ + if (pendingJumps != null) { + resolvePending(); + } + if (pendingStatPos != Position.NOPOS) { + markStatBegin(); + } fixedPc = true; return cp; } @@ -1175,7 +1190,7 @@ public class Code { /** Declare an entry point; return current code pointer */ public int entryPoint() { - int pc = curPc(); + int pc = curCP(); alive = true; pendingStackMap = needStackMap; return pc; @@ -1185,7 +1200,7 @@ public class Code { * return current code pointer */ public int entryPoint(State state) { - int pc = curPc(); + int pc = curCP(); alive = true; this.state = state.dup(); Assert.check(state.stacksize <= max_stack); @@ -1198,7 +1213,7 @@ public class Code { * return current code pointer */ public int entryPoint(State state, Type pushed) { - int pc = curPc(); + int pc = curCP(); alive = true; this.state = state.dup(); Assert.check(state.stacksize <= max_stack); @@ -1238,7 +1253,7 @@ public class Code { /** Emit a stack map entry. */ public void emitStackMap() { - int pc = curPc(); + int pc = curCP(); if (!needStackMap) return; @@ -1482,6 +1497,9 @@ public class Code { chain.pc + 3 == target && target == cp && !fixedPc) { // If goto the next instruction, the jump is not needed: // compact the code. + if (varDebugInfo) { + adjustAliveRanges(cp, -3); + } cp = cp - 3; target = target - 3; if (chain.next == null) { @@ -1781,8 +1799,7 @@ public class Code { sym = sym.clone(sym.owner); sym.type = newtype; LocalVar newlv = lvar[i] = new LocalVar(sym); - // should the following be initialized to cp? - newlv.start_pc = lv.start_pc; + newlv.aliveRanges = lv.aliveRanges; } } } @@ -1870,8 +1887,36 @@ public class Code { static class LocalVar { final VarSymbol sym; final char reg; - char start_pc = Character.MAX_VALUE; - char length = Character.MAX_VALUE; + + class Range { + char start_pc = Character.MAX_VALUE; + char length = Character.MAX_VALUE; + + Range() {} + + Range(char start) { + this.start_pc = start; + } + + Range(char start, char length) { + this.start_pc = start; + this.length = length; + } + + boolean closed() { + return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE; + } + + @Override + public String toString() { + int currentStartPC = start_pc; + int currentLength = length; + return "startpc = " + currentStartPC + " length " + currentLength; + } + } + + java.util.List aliveRanges = new java.util.ArrayList<>(); + LocalVar(VarSymbol v) { this.sym = v; this.reg = (char)v.adr; @@ -1879,9 +1924,78 @@ public class Code { public LocalVar dup() { return new LocalVar(sym); } - public String toString() { - return "" + sym + " in register " + ((int)reg) + " starts at pc=" + ((int)start_pc) + " length=" + ((int)length); + + Range firstRange() { + return aliveRanges.isEmpty() ? null : aliveRanges.get(0); } + + Range lastRange() { + return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1); + } + + @Override + public String toString() { + if (aliveRanges == null) { + return "empty local var"; + } + StringBuilder sb = new StringBuilder().append(sym) + .append(" in register ").append((int)reg).append(" \n"); + for (Range r : aliveRanges) { + sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc))) + .append(" length=").append(Integer.toString(((int)r.length))) + .append("\n"); + } + return sb.toString(); + } + + public void openRange(char start) { + if (!hasOpenRange()) { + aliveRanges.add(new Range(start)); + } + } + + public void closeRange(char end) { + if (isLastRangeInitialized()) { + Range range = lastRange(); + if (range != null) { + if (range.length == Character.MAX_VALUE) { + range.length = end; + } + } + } else { + if (!aliveRanges.isEmpty()) { + aliveRanges.remove(aliveRanges.size() - 1); + } + } + } + + public boolean hasOpenRange() { + if (aliveRanges.isEmpty()) { + return false; + } + Range range = lastRange(); + return range.length == Character.MAX_VALUE; + } + + public boolean isLastRangeInitialized() { + if (aliveRanges.isEmpty()) { + return false; + } + Range range = lastRange(); + return range.start_pc != Character.MAX_VALUE; + } + + public Range getWidestRange() { + if (aliveRanges.isEmpty()) { + return new Range(); + } else { + Range firstRange = firstRange(); + Range lastRange = lastRange(); + char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc)); + return new Range(firstRange.start_pc, length); + } + } + }; /** Local variables, indexed by register. */ @@ -1892,11 +2006,60 @@ public class Code { int adr = v.adr; lvar = ArrayUtils.ensureCapacity(lvar, adr+1); Assert.checkNull(lvar[adr]); - if (pendingJumps != null) resolvePending(); + if (pendingJumps != null) { + resolvePending(); + } lvar[adr] = new LocalVar(v); state.defined.excl(adr); } + + public void closeAliveRanges(JCTree tree) { + closeAliveRanges(tree, cp); + } + + public void closeAliveRanges(JCTree tree, int closingCP) { + List locals = lvtRanges.getVars(meth, tree); + for (LocalVar localVar: lvar) { + for (VarSymbol aliveLocal : locals) { + if (localVar == null) { + return; + } + if (localVar.sym == aliveLocal && localVar.lastRange() != null) { + char length = (char)(closingCP - localVar.lastRange().start_pc); + if (length > 0 && length < Character.MAX_VALUE) { + localVar.closeRange(length); + } + } + } + } + } + + void adjustAliveRanges(int oldCP, int delta) { + for (LocalVar localVar: lvar) { + if (localVar == null) { + return; + } + for (LocalVar.Range range: localVar.aliveRanges) { + if (range.closed() && range.start_pc + range.length >= oldCP) { + range.length += delta; + } + } + } + } + + /** + * Calculates the size of the LocalVariableTable. + */ + public int getLVTSize() { + int result = varBufferSize; + for (int i = 0; i < varBufferSize; i++) { + LocalVar var = varBuffer[i]; + result += var.aliveRanges.size() - 1; + } + return result; + } + /** Set the current variable defined state. */ public void setDefined(Bits newDefined) { if (alive && newDefined != state.defined) { @@ -1922,8 +2085,7 @@ public class Code { } else { state.defined.incl(adr); if (cp < Character.MAX_VALUE) { - if (v.start_pc == Character.MAX_VALUE) - v.start_pc = (char)cp; + v.openRange((char)cp); } } } @@ -1933,15 +2095,15 @@ public class Code { state.defined.excl(adr); if (adr < lvar.length && lvar[adr] != null && - lvar[adr].start_pc != Character.MAX_VALUE) { + lvar[adr].isLastRangeInitialized()) { LocalVar v = lvar[adr]; - char length = (char)(curPc() - v.start_pc); + char length = (char)(curCP() - v.lastRange().start_pc); if (length > 0 && length < Character.MAX_VALUE) { lvar[adr] = v.dup(); - v.length = length; + v.closeRange(length); putVar(v); } else { - v.start_pc = Character.MAX_VALUE; + v.lastRange().start_pc = Character.MAX_VALUE; } } } @@ -1951,10 +2113,10 @@ public class Code { LocalVar v = lvar[adr]; if (v != null) { lvar[adr] = null; - if (v.start_pc != Character.MAX_VALUE) { - char length = (char)(curPc() - v.start_pc); + if (v.isLastRangeInitialized()) { + char length = (char)(curCP() - v.lastRange().start_pc); if (length < Character.MAX_VALUE) { - v.length = length; + v.closeRange(length); putVar(v); fillLocalVarPosition(v); } @@ -1968,8 +2130,9 @@ public class Code { return; for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) { TypeAnnotationPosition p = ta.position; - p.lvarOffset = new int[] { (int)lv.start_pc }; - p.lvarLength = new int[] { (int)lv.length }; + LocalVar.Range widestRange = lv.getWidestRange(); + p.lvarOffset = new int[] { (int)widestRange.start_pc }; + p.lvarLength = new int[] { (int)widestRange.length }; p.lvarIndex = new int[] { (int)lv.reg }; p.isValidOffset = true; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index 3f0fc861da3..7e727f23955 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -24,6 +24,7 @@ */ package com.sun.tools.javac.jvm; + import java.util.*; import com.sun.tools.javac.util.*; @@ -95,10 +96,14 @@ public class Gen extends JCTree.Visitor { return instance; } - /* Constant pool, reset by genClass. + /** Constant pool, reset by genClass. */ private Pool pool; + /** LVTRanges info. + */ + private LVTRanges lvtRanges; + protected Gen(Context context) { context.put(genKey, this); @@ -128,6 +133,9 @@ public class Gen extends JCTree.Visitor { options.isUnset(G_CUSTOM) ? options.isSet(G) : options.isSet(G_CUSTOM, "vars"); + if (varDebugInfo) { + lvtRanges = LVTRanges.instance(context); + } genCrt = options.isSet(XJCOV); debugCode = options.isSet("debugcode"); allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic"); @@ -423,7 +431,7 @@ public class Gen extends JCTree.Visitor { */ void endFinalizerGap(Env env) { if (env.info.gaps != null && env.info.gaps.length() % 2 == 1) - env.info.gaps.append(code.curPc()); + env.info.gaps.append(code.curCP()); } /** Mark end of all gaps in catch-all ranges for finalizers of environments @@ -743,10 +751,10 @@ public class Gen extends JCTree.Visitor { genStat(tree, env); return; } - int startpc = code.curPc(); + int startpc = code.curCP(); genStat(tree, env); if (tree.hasTag(Tag.BLOCK)) crtFlags |= CRT_BLOCK; - code.crt.put(tree, crtFlags, startpc, code.curPc()); + code.crt.put(tree, crtFlags, startpc, code.curCP()); } /** Derived visitor method: generate code for a statement. @@ -781,9 +789,9 @@ public class Gen extends JCTree.Visitor { if (trees.length() == 1) { // mark one statement with the flags genStat(trees.head, env, crtFlags | CRT_STATEMENT); } else { - int startpc = code.curPc(); + int startpc = code.curCP(); genStats(trees, env); - code.crt.put(trees, crtFlags, startpc, code.curPc()); + code.crt.put(trees, crtFlags, startpc, code.curCP()); } } @@ -806,9 +814,9 @@ public class Gen extends JCTree.Visitor { */ public CondItem genCond(JCTree tree, int crtFlags) { if (!genCrt) return genCond(tree, false); - int startpc = code.curPc(); + int startpc = code.curCP(); CondItem item = genCond(tree, (crtFlags & CRT_FLOW_CONTROLLER) != 0); - code.crt.put(tree, crtFlags, startpc, code.curPc()); + code.crt.put(tree, crtFlags, startpc, code.curCP()); return item; } @@ -971,7 +979,6 @@ public class Gen extends JCTree.Visitor { // definition. Env localEnv = env.dup(tree); localEnv.enclMethod = tree; - // The expected type of every return statement in this method // is the method's return type. this.pt = tree.sym.erasure(types).getReturnType(); @@ -1045,7 +1052,7 @@ public class Gen extends JCTree.Visitor { code.crt.put(tree.body, CRT_BLOCK, startpcCrt, - code.curPc()); + code.curCP()); code.endScopes(0); @@ -1087,10 +1094,12 @@ public class Gen extends JCTree.Visitor { : null, syms, types, - pool); + pool, + varDebugInfo ? lvtRanges : null); items = new Items(pool, code, syms, types); - if (code.debugCode) + if (code.debugCode) { System.err.println(meth + " for body " + tree); + } // If method is not static, create a new local variable address // for `this'. @@ -1111,7 +1120,7 @@ public class Gen extends JCTree.Visitor { } // Get ready to generate code for method body. - int startpcCrt = genCrt ? code.curPc() : 0; + int startpcCrt = genCrt ? code.curCP() : 0; code.entryPoint(); // Suppress initial stackmap @@ -1189,14 +1198,30 @@ public class Gen extends JCTree.Visitor { Chain loopDone = c.jumpFalse(); code.resolve(c.trueJumps); genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET); + if (varDebugInfo) { + checkLoopLocalVarRangeEnding(loop, body, + LoopLocalVarRangeEndingPoint.BEFORE_STEPS); + } code.resolve(loopEnv.info.cont); genStats(step, loopEnv); + if (varDebugInfo) { + checkLoopLocalVarRangeEnding(loop, body, + LoopLocalVarRangeEndingPoint.AFTER_STEPS); + } code.resolve(code.branch(goto_), startpc); code.resolve(loopDone); } else { genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET); + if (varDebugInfo) { + checkLoopLocalVarRangeEnding(loop, body, + LoopLocalVarRangeEndingPoint.BEFORE_STEPS); + } code.resolve(loopEnv.info.cont); genStats(step, loopEnv); + if (varDebugInfo) { + checkLoopLocalVarRangeEnding(loop, body, + LoopLocalVarRangeEndingPoint.AFTER_STEPS); + } CondItem c; if (cond != null) { code.statBegin(cond.pos); @@ -1210,6 +1235,44 @@ public class Gen extends JCTree.Visitor { code.resolve(loopEnv.info.exit); } + private enum LoopLocalVarRangeEndingPoint { + BEFORE_STEPS, + AFTER_STEPS, + } + + /** + * Checks whether we have reached an alive range ending point for local + * variables after a loop. + * + * Local variables alive range ending point for loops varies depending + * on the loop type. The range can be closed before or after the code + * for the steps sentences has been generated. + * + * - While loops has no steps so in that case the range is closed just + * after the body of the loop. + * + * - For-like loops may have steps so as long as the steps sentences + * can possibly contain non-synthetic local variables, the alive range + * for local variables must be closed after the steps in this case. + */ + private void checkLoopLocalVarRangeEnding(JCTree loop, JCTree body, + LoopLocalVarRangeEndingPoint endingPoint) { + if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) { + switch (endingPoint) { + case BEFORE_STEPS: + if (!loop.hasTag(FORLOOP)) { + code.closeAliveRanges(body); + } + break; + case AFTER_STEPS: + if (loop.hasTag(FORLOOP)) { + code.closeAliveRanges(body); + } + break; + } + } + } + public void visitForeachLoop(JCEnhancedForLoop tree) { throw new AssertionError(); // should have been removed by Lower. } @@ -1223,7 +1286,7 @@ public class Gen extends JCTree.Visitor { public void visitSwitch(JCSwitch tree) { int limit = code.nextreg; Assert.check(!tree.selector.type.hasTag(CLASS)); - int startpcCrt = genCrt ? code.curPc() : 0; + int startpcCrt = genCrt ? code.curCP() : 0; Item sel = genExpr(tree.selector, syms.intType); List cases = tree.cases; if (cases.isEmpty()) { @@ -1231,13 +1294,13 @@ public class Gen extends JCTree.Visitor { sel.load().drop(); if (genCrt) code.crt.put(TreeInfo.skipParens(tree.selector), - CRT_FLOW_CONTROLLER, startpcCrt, code.curPc()); + CRT_FLOW_CONTROLLER, startpcCrt, code.curCP()); } else { // We are seeing a nonempty switch. sel.load(); if (genCrt) code.crt.put(TreeInfo.skipParens(tree.selector), - CRT_FLOW_CONTROLLER, startpcCrt, code.curPc()); + CRT_FLOW_CONTROLLER, startpcCrt, code.curCP()); Env switchEnv = env.dup(tree, new GenContext()); switchEnv.info.isSwitch = true; @@ -1278,10 +1341,10 @@ public class Gen extends JCTree.Visitor { ? tableswitch : lookupswitch; - int startpc = code.curPc(); // the position of the selector operation + int startpc = code.curCP(); // the position of the selector operation code.emitop0(opcode); code.align(4); - int tableBase = code.curPc(); // the start of the jump table + int tableBase = code.curCP(); // the start of the jump table int[] offsets = null; // a table of offsets for a lookupswitch code.emit4(-1); // leave space for default offset if (opcode == tableswitch) { @@ -1323,6 +1386,9 @@ public class Gen extends JCTree.Visitor { // Generate code for the statements in this case. genStats(c.stats, switchEnv, CRT_FLOW_TARGET); + if (varDebugInfo && lvtRanges.containsKey(code.meth, c.stats.last())) { + code.closeAliveRanges(c.stats.last()); + } } // Resolve all breaks. @@ -1402,7 +1468,7 @@ public class Gen extends JCTree.Visitor { void gen() { genLast(); Assert.check(syncEnv.info.gaps.length() % 2 == 0); - syncEnv.info.gaps.append(code.curPc()); + syncEnv.info.gaps.append(code.curCP()); } void genLast() { if (code.isAlive()) { @@ -1441,10 +1507,10 @@ public class Gen extends JCTree.Visitor { jsrState); } Assert.check(tryEnv.info.gaps.length() % 2 == 0); - tryEnv.info.gaps.append(code.curPc()); + tryEnv.info.gaps.append(code.curCP()); } else { Assert.check(tryEnv.info.gaps.length() % 2 == 0); - tryEnv.info.gaps.append(code.curPc()); + tryEnv.info.gaps.append(code.curCP()); genLast(); } } @@ -1467,10 +1533,10 @@ public class Gen extends JCTree.Visitor { */ void genTry(JCTree body, List catchers, Env env) { int limit = code.nextreg; - int startpc = code.curPc(); + int startpc = code.curCP(); Code.State stateTry = code.state.dup(); genStat(body, env, CRT_BLOCK); - int endpc = code.curPc(); + int endpc = code.curCP(); boolean hasFinalizer = env.info.finalize != null && env.info.finalize.hasFinalizer(); @@ -1479,6 +1545,9 @@ public class Gen extends JCTree.Visitor { genFinalizer(env); code.statBegin(TreeInfo.endPos(env.tree)); Chain exitChain = code.branch(goto_); + if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) { + code.closeAliveRanges(body); + } endFinalizerGap(env); if (startpc != endpc) for (List l = catchers; l.nonEmpty(); l = l.tail) { // start off with exception on stack @@ -1573,7 +1642,7 @@ public class Gen extends JCTree.Visitor { int catchType = makeRef(tree.pos(), subCatch.type); int end = gaps.head.intValue(); registerCatch(tree.pos(), - startpc, end, code.curPc(), + startpc, end, code.curCP(), catchType); if (subCatch.type.isAnnotated()) { // All compounds share the same position, simply update the @@ -1589,7 +1658,7 @@ public class Gen extends JCTree.Visitor { for (JCExpression subCatch : subClauses) { int catchType = makeRef(tree.pos(), subCatch.type); registerCatch(tree.pos(), - startpc, endpc, code.curPc(), + startpc, endpc, code.curCP(), catchType); if (subCatch.type.isAnnotated()) { // All compounds share the same position, simply update the @@ -1732,11 +1801,19 @@ public class Gen extends JCTree.Visitor { code.resolve(c.trueJumps); genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET); thenExit = code.branch(goto_); + if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) { + code.closeAliveRanges(tree.thenpart, + thenExit != null && tree.elsepart == null ? thenExit.pc : code.cp); + } } if (elseChain != null) { code.resolve(elseChain); - if (tree.elsepart != null) + if (tree.elsepart != null) { genStat(tree.elsepart, env,CRT_STATEMENT | CRT_FLOW_TARGET); + if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.elsepart)) { + code.closeAliveRanges(tree.elsepart); + } + } } code.resolve(thenExit); code.endScopes(limit); @@ -1830,20 +1907,20 @@ public class Gen extends JCTree.Visitor { Chain elseChain = c.jumpFalse(); if (!c.isFalse()) { code.resolve(c.trueJumps); - int startpc = genCrt ? code.curPc() : 0; + int startpc = genCrt ? code.curCP() : 0; genExpr(tree.truepart, pt).load(); code.state.forceStackTop(tree.type); if (genCrt) code.crt.put(tree.truepart, CRT_FLOW_TARGET, - startpc, code.curPc()); + startpc, code.curCP()); thenExit = code.branch(goto_); } if (elseChain != null) { code.resolve(elseChain); - int startpc = genCrt ? code.curPc() : 0; + int startpc = genCrt ? code.curCP() : 0; genExpr(tree.falsepart, pt).load(); code.state.forceStackTop(tree.type); if (genCrt) code.crt.put(tree.falsepart, CRT_FLOW_TARGET, - startpc, code.curPc()); + startpc, code.curCP()); } code.resolve(thenExit); result = items.makeStackItem(pt); @@ -2423,6 +2500,19 @@ public class Gen extends JCTree.Visitor { new Env(cdef, new GenContext()); localEnv.toplevel = env.toplevel; localEnv.enclClass = cdef; + + /* We must not analyze synthetic methods + */ + if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) { + try { + LVTAssignAnalyzer lvtAssignAnalyzer = LVTAssignAnalyzer.make( + lvtRanges, syms, names); + lvtAssignAnalyzer.analyzeTree(localEnv); + } catch (Throwable e) { + throw e; + } + } + for (List l = cdef.defs; l.nonEmpty(); l = l.tail) { genDef(l.head, localEnv); } @@ -2507,4 +2597,311 @@ public class Gen extends JCTree.Visitor { cont = Code.mergeChains(c, cont); } } + + static class LVTAssignAnalyzer + extends Flow.AbstractAssignAnalyzer { + + final LVTBits lvtInits; + final LVTRanges lvtRanges; + + /* This class is anchored to a context dependent tree. The tree can + * vary inside the same instruction for example in the switch instruction + * the same FlowBits instance can be anchored to the whole tree, or + * to a given case. The aim is to always anchor the bits to the tree + * capable of closing a DA range. + */ + static class LVTBits extends Bits { + + enum BitsOpKind { + INIT, + CLEAR, + INCL_BIT, + EXCL_BIT, + ASSIGN, + AND_SET, + OR_SET, + DIFF_SET, + XOR_SET, + INCL_RANGE, + EXCL_RANGE, + } + + JCTree currentTree; + LVTAssignAnalyzer analyzer; + private int[] oldBits = null; + BitsState stateBeforeOp; + + LVTBits() { + super(false); + } + + LVTBits(int[] bits, BitsState initState) { + super(bits, initState); + } + + @Override + public void clear() { + generalOp(null, -1, BitsOpKind.CLEAR); + } + + @Override + protected void internalReset() { + super.internalReset(); + oldBits = null; + } + + @Override + public Bits assign(Bits someBits) { + // bits can be null + oldBits = bits; + stateBeforeOp = currentState; + super.assign(someBits); + changed(); + return this; + } + + @Override + public void excludeFrom(int start) { + generalOp(null, start, BitsOpKind.EXCL_RANGE); + } + + @Override + public void excl(int x) { + Assert.check(x >= 0); + generalOp(null, x, BitsOpKind.EXCL_BIT); + } + + @Override + public Bits andSet(Bits xs) { + return generalOp(xs, -1, BitsOpKind.AND_SET); + } + + @Override + public Bits orSet(Bits xs) { + return generalOp(xs, -1, BitsOpKind.OR_SET); + } + + @Override + public Bits diffSet(Bits xs) { + return generalOp(xs, -1, BitsOpKind.DIFF_SET); + } + + @Override + public Bits xorSet(Bits xs) { + return generalOp(xs, -1, BitsOpKind.XOR_SET); + } + + private Bits generalOp(Bits xs, int i, BitsOpKind opKind) { + Assert.check(currentState != BitsState.UNKNOWN); + oldBits = dupBits(); + stateBeforeOp = currentState; + switch (opKind) { + case AND_SET: + super.andSet(xs); + break; + case OR_SET: + super.orSet(xs); + break; + case XOR_SET: + super.xorSet(xs); + break; + case DIFF_SET: + super.diffSet(xs); + break; + case CLEAR: + super.clear(); + break; + case EXCL_BIT: + super.excl(i); + break; + case EXCL_RANGE: + super.excludeFrom(i); + break; + } + changed(); + return this; + } + + /* The tree we need to anchor the bits instance to. + */ + LVTBits at(JCTree tree) { + this.currentTree = tree; + return this; + } + + /* If the instance should be changed but the tree is not a closing + * tree then a reset is needed or the former tree can mistakingly be + * used. + */ + LVTBits resetTree() { + this.currentTree = null; + return this; + } + + /** This method will be called after any operation that causes a change to + * the bits. Subclasses can thus override it in order to extract information + * from the changes produced to the bits by the given operation. + */ + public void changed() { + if (currentTree != null && + stateBeforeOp != BitsState.UNKNOWN && + trackTree(currentTree)) { + List locals = + analyzer.lvtRanges + .getVars(analyzer.currentMethod, currentTree); + locals = locals != null ? + locals : List.nil(); + for (JCVariableDecl vardecl : analyzer.vardecls) { + //once the first is null, the rest will be so. + if (vardecl == null) { + break; + } + if (trackVar(vardecl.sym) && bitChanged(vardecl.sym.adr)) { + locals = locals.prepend(vardecl.sym); + } + } + if (!locals.isEmpty()) { + analyzer.lvtRanges.setEntry(analyzer.currentMethod, + currentTree, locals); + } + } + } + + boolean bitChanged(int x) { + boolean isMemberOfBits = isMember(x); + int[] tmp = bits; + bits = oldBits; + boolean isMemberOfOldBits = isMember(x); + bits = tmp; + return (!isMemberOfBits && isMemberOfOldBits); + } + + boolean trackVar(VarSymbol var) { + return (var.owner.kind == MTH && + (var.flags() & (PARAMETER | HASINIT)) == 0 && + analyzer.trackable(var)); + } + + boolean trackTree(JCTree tree) { + switch (tree.getTag()) { + // of course a method closes the alive range of a local variable. + case METHODDEF: + // for while loops we want only the body + case WHILELOOP: + return false; + } + return true; + } + + } + + public class LVTAssignPendingExit extends Flow.AssignAnalyzer.AssignPendingExit { + + LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { + super(tree, inits, uninits); + } + + @Override + public void resolveJump(JCTree tree) { + lvtInits.at(tree); + super.resolveJump(tree); + } + } + + private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) { + super(new LVTBits(), syms, names); + lvtInits = (LVTBits)inits; + this.lvtRanges = lvtRanges; + } + + public static LVTAssignAnalyzer make(LVTRanges lvtRanges, Symtab syms, Names names) { + LVTAssignAnalyzer result = new LVTAssignAnalyzer(lvtRanges, syms, names); + result.lvtInits.analyzer = result; + return result; + } + + @Override + protected void markDead(JCTree tree) { + lvtInits.at(tree).inclRange(returnadr, nextadr); + super.markDead(tree); + } + + @Override + protected void merge(JCTree tree) { + lvtInits.at(tree); + super.merge(tree); + } + + boolean isSyntheticOrMandated(Symbol sym) { + return (sym.flags() & (SYNTHETIC | MANDATED)) != 0; + } + + @Override + protected boolean trackable(VarSymbol sym) { + if (isSyntheticOrMandated(sym)) { + //fast check to avoid tracking synthetic or mandated variables + return false; + } + return super.trackable(sym); + } + + @Override + protected void initParam(JCVariableDecl def) { + if (!isSyntheticOrMandated(def.sym)) { + super.initParam(def); + } + } + + @Override + protected void assignToInits(JCTree tree, Bits bits) { + lvtInits.at(tree); + lvtInits.assign(bits); + } + + @Override + protected void andSetInits(JCTree tree, Bits bits) { + lvtInits.at(tree); + lvtInits.andSet(bits); + } + + @Override + protected void orSetInits(JCTree tree, Bits bits) { + lvtInits.at(tree); + lvtInits.orSet(bits); + } + + @Override + protected void exclVarFromInits(JCTree tree, int adr) { + lvtInits.at(tree); + lvtInits.excl(adr); + } + + @Override + protected LVTAssignPendingExit createNewPendingExit(JCTree tree, Bits inits, Bits uninits) { + return new LVTAssignPendingExit(tree, inits, uninits); + } + + MethodSymbol currentMethod; + + @Override + public void visitMethodDef(JCMethodDecl tree) { + if ((tree.sym.flags() & (SYNTHETIC | GENERATEDCONSTR)) != 0) { + return; + } + if (tree.name.equals(names.clinit)) { + return; + } + boolean enumClass = (tree.sym.owner.flags() & ENUM) != 0; + if (enumClass && + (tree.name.equals(names.valueOf) || + tree.name.equals(names.values) || + tree.name.equals(names.init))) { + return; + } + currentMethod = tree.sym; + super.visitMethodDef(tree); + } + + } + } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java index 054facddaa6..3e1d7c68eb6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java @@ -789,18 +789,18 @@ public class Items { Chain jumpTrue() { if (tree == null) return Code.mergeChains(trueJumps, code.branch(opcode)); // we should proceed further in -Xjcov mode only - int startpc = code.curPc(); + int startpc = code.curCP(); Chain c = Code.mergeChains(trueJumps, code.branch(opcode)); - code.crt.put(tree, CRTable.CRT_BRANCH_TRUE, startpc, code.curPc()); + code.crt.put(tree, CRTable.CRT_BRANCH_TRUE, startpc, code.curCP()); return c; } Chain jumpFalse() { if (tree == null) return Code.mergeChains(falseJumps, code.branch(Code.negate(opcode))); // we should proceed further in -Xjcov mode only - int startpc = code.curPc(); + int startpc = code.curCP(); Chain c = Code.mergeChains(falseJumps, code.branch(Code.negate(opcode))); - code.crt.put(tree, CRTable.CRT_BRANCH_FALSE, startpc, code.curPc()); + code.crt.put(tree, CRTable.CRT_BRANCH_FALSE, startpc, code.curCP()); return c; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/LVTRanges.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/LVTRanges.java new file mode 100644 index 00000000000..71139ee78b6 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/LVTRanges.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javac.jvm; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.WeakHashMap; + +import com.sun.tools.javac.code.Symbol.MethodSymbol; +import com.sun.tools.javac.code.Symbol.VarSymbol; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.List; + +/** This class contains a one to many relation between a tree and a set of variables. + * The relation implies that the given tree closes the DA (definite assignment) + * range for the set of variables. + * + *

    This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class LVTRanges { + /** The context key for the LVT ranges. */ + protected static final Context.Key lvtRangesKey = new Context.Key<>(); + + /** Get the LVTRanges instance for this context. */ + public static LVTRanges instance(Context context) { + LVTRanges instance = context.get(lvtRangesKey); + if (instance == null) { + instance = new LVTRanges(context); + } + return instance; + } + + private static final long serialVersionUID = 1812267524140424433L; + + protected Context context; + + protected Map>> + aliveRangeClosingTrees = new WeakHashMap<>(); + + public LVTRanges(Context context) { + this.context = context; + context.put(lvtRangesKey, this); + } + + public List getVars(MethodSymbol method, JCTree tree) { + Map> varMap = aliveRangeClosingTrees.get(method); + return (varMap != null) ? varMap.get(tree) : null; + } + + public boolean containsKey(MethodSymbol method, JCTree tree) { + Map> varMap = aliveRangeClosingTrees.get(method); + if (varMap == null) { + return false; + } + return varMap.containsKey(tree); + } + + public void setEntry(MethodSymbol method, JCTree tree, List vars) { + Map> varMap = aliveRangeClosingTrees.get(method); + if (varMap != null) { + varMap.put(tree, vars); + } else { + varMap = new WeakHashMap<>(); + varMap.put(tree, vars); + aliveRangeClosingTrees.put(method, varMap); + } + } + + public List removeEntry(MethodSymbol method, JCTree tree) { + Map> varMap = aliveRangeClosingTrees.get(method); + if (varMap != null) { + List result = varMap.remove(tree); + if (varMap.isEmpty()) { + aliveRangeClosingTrees.remove(method); + } + return result; + } + return null; + } + + /* This method should be used for debugging LVT related issues. + */ + @Override + public String toString() { + String result = ""; + for (Entry>> mainEntry: aliveRangeClosingTrees.entrySet()) { + result += "Method: \n" + mainEntry.getKey().flatName() + "\n"; + int i = 1; + for (Entry> treeEntry: mainEntry.getValue().entrySet()) { + result += " Tree " + i + ": \n" + treeEntry.getKey().toString() + "\n"; + result += " Variables closed:\n"; + for (VarSymbol var: treeEntry.getValue()) { + result += " " + var.toString(); + } + result += "\n"; + i++; + } + } + return result; + } + +} diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java index b94dd5f8a4f..4e6ef7ba6ff 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -890,7 +890,7 @@ public class TreeMaker implements JCTree.Factory { /** Create a value parameter tree from its name, type, and owner. */ public JCVariableDecl Param(Name name, Type argtype, Symbol owner) { - return VarDef(new VarSymbol(0, name, argtype, owner), null); + return VarDef(new VarSymbol(PARAMETER, name, argtype, owner), null); } /** Create a a list of value parameter trees x0, ..., xn from a list of diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Bits.java b/langtools/src/share/classes/com/sun/tools/javac/util/Bits.java index 272bf0fd49c..f8db31a4665 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Bits.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Bits.java @@ -27,8 +27,6 @@ package com.sun.tools.javac.util; import java.util.Arrays; -import static com.sun.tools.javac.util.Bits.BitsOpKind.*; - /** A class for extensible, mutable bit sets. * *

    This is NOT part of any supported API. @@ -38,20 +36,6 @@ import static com.sun.tools.javac.util.Bits.BitsOpKind.*; */ public class Bits { - public enum BitsOpKind { - INIT, - CLEAR, - INCL_BIT, - EXCL_BIT, - ASSIGN, - AND_SET, - OR_SET, - DIFF_SET, - XOR_SET, - INCL_RANGE, - EXCL_RANGE, - } - // ____________ reset _________ // / UNKNOWN \ <-------- / UNINIT \ // \____________/ | \_________/ @@ -64,11 +48,14 @@ public class Bits { // | | // ----------- // any - private enum BitsState { + protected enum BitsState { /* A Bits instance is in UNKNOWN state if it has been explicitly reset. * It is possible to get to this state from any other by calling the * reset method. An instance in the UNKNOWN state can pass to the * NORMAL state after being assigned another Bits instance. + * + * Bits instances are final fields in Flow so the UNKNOWN state models + * the null assignment. */ UNKNOWN, /* A Bits instance is in UNINIT when it is created with the default @@ -103,13 +90,9 @@ public class Bits { public int[] bits = null; // This field will store last version of bits after every change. - public int[] oldBits = null; - - public BitsOpKind lastOperation = null; - private static final int[] unassignedBits = new int[0]; - private BitsState currentState; + protected BitsState currentState; /** Construct an initially empty set. */ @@ -127,27 +110,20 @@ public class Bits { /** Construct a set consisting initially of given bit vector. */ - private Bits(int[] bits, BitsState initState) { + protected Bits(int[] bits, BitsState initState) { this.bits = bits; this.currentState = initState; switch (initState) { case UNKNOWN: - reset(); //this will also set current state; + this.bits = null; break; case NORMAL: Assert.check(bits != unassignedBits); - lastOperation = INIT; break; } } - /** This method will be called after any operation that causes a change to - * the bits. Subclasses can thus override it in order to extract information - * from the changes produced to the bits by the given operation. - */ - public void changed() {} - - private void sizeTo(int len) { + protected void sizeTo(int len) { if (bits.length < len) { bits = Arrays.copyOf(bits, len); } @@ -157,16 +133,18 @@ public class Bits { */ public void clear() { Assert.check(currentState != BitsState.UNKNOWN); - oldBits = bits; - lastOperation = CLEAR; - for (int i = 0; i < bits.length; i++) bits[i] = 0; - changed(); + for (int i = 0; i < bits.length; i++) { + bits[i] = 0; + } currentState = BitsState.NORMAL; } public void reset() { + internalReset(); + } + + protected void internalReset() { bits = null; - oldBits = null; currentState = BitsState.UNKNOWN; } @@ -175,40 +153,40 @@ public class Bits { } public Bits assign(Bits someBits) { - lastOperation = ASSIGN; - oldBits = bits; bits = someBits.dup().bits; - changed(); currentState = BitsState.NORMAL; return this; } /** Return a copy of this set. */ - private Bits dup() { + public Bits dup() { Assert.check(currentState != BitsState.UNKNOWN); Bits tmp = new Bits(); - if (currentState != BitsState.NORMAL) { - tmp.bits = bits; - } else { - tmp.bits = new int[bits.length]; - System.arraycopy(bits, 0, tmp.bits, 0, bits.length); - } + tmp.bits = dupBits(); currentState = BitsState.NORMAL; return tmp; } + protected int[] dupBits() { + int [] result; + if (currentState != BitsState.NORMAL) { + result = bits; + } else { + result = new int[bits.length]; + System.arraycopy(bits, 0, result, 0, bits.length); + } + return result; + } + /** Include x in this set. */ public void incl(int x) { Assert.check(currentState != BitsState.UNKNOWN); - Assert.check(x >= 0); - oldBits = bits; - lastOperation = INCL_BIT; + Assert.check(x >= 0, "Value of x " + x); sizeTo((x >>> wordshift) + 1); bits[x >>> wordshift] = bits[x >>> wordshift] | (1 << (x & wordmask)); - changed(); currentState = BitsState.NORMAL; } @@ -217,14 +195,11 @@ public class Bits { */ public void inclRange(int start, int limit) { Assert.check(currentState != BitsState.UNKNOWN); - oldBits = bits; - lastOperation = INCL_RANGE; sizeTo((limit >>> wordshift) + 1); for (int x = start; x < limit; x++) { bits[x >>> wordshift] = bits[x >>> wordshift] | (1 << (x & wordmask)); } - changed(); currentState = BitsState.NORMAL; } @@ -232,13 +207,10 @@ public class Bits { */ public void excludeFrom(int start) { Assert.check(currentState != BitsState.UNKNOWN); - oldBits = bits; - lastOperation = EXCL_RANGE; Bits temp = new Bits(); temp.sizeTo(bits.length); temp.inclRange(0, start); internalAndSet(temp); - changed(); currentState = BitsState.NORMAL; } @@ -247,12 +219,9 @@ public class Bits { public void excl(int x) { Assert.check(currentState != BitsState.UNKNOWN); Assert.check(x >= 0); - oldBits = bits; - lastOperation = EXCL_BIT; sizeTo((x >>> wordshift) + 1); bits[x >>> wordshift] = bits[x >>> wordshift] & ~(1 << (x & wordmask)); - changed(); currentState = BitsState.NORMAL; } @@ -269,15 +238,12 @@ public class Bits { */ public Bits andSet(Bits xs) { Assert.check(currentState != BitsState.UNKNOWN); - oldBits = bits; - lastOperation = AND_SET; internalAndSet(xs); - changed(); currentState = BitsState.NORMAL; return this; } - private void internalAndSet(Bits xs) { + protected void internalAndSet(Bits xs) { Assert.check(currentState != BitsState.UNKNOWN); sizeTo(xs.bits.length); for (int i = 0; i < xs.bits.length; i++) { @@ -289,13 +255,10 @@ public class Bits { */ public Bits orSet(Bits xs) { Assert.check(currentState != BitsState.UNKNOWN); - oldBits = bits; - lastOperation = OR_SET; sizeTo(xs.bits.length); for (int i = 0; i < xs.bits.length; i++) { bits[i] = bits[i] | xs.bits[i]; } - changed(); currentState = BitsState.NORMAL; return this; } @@ -304,14 +267,11 @@ public class Bits { */ public Bits diffSet(Bits xs) { Assert.check(currentState != BitsState.UNKNOWN); - oldBits = bits; - lastOperation = DIFF_SET; for (int i = 0; i < bits.length; i++) { if (i < xs.bits.length) { bits[i] = bits[i] & ~xs.bits[i]; } } - changed(); currentState = BitsState.NORMAL; return this; } @@ -320,13 +280,10 @@ public class Bits { */ public Bits xorSet(Bits xs) { Assert.check(currentState != BitsState.UNKNOWN); - oldBits = bits; - lastOperation = XOR_SET; sizeTo(xs.bits.length); for (int i = 0; i < xs.bits.length; i++) { bits[i] = bits[i] ^ xs.bits[i]; } - changed(); currentState = BitsState.NORMAL; return this; } @@ -336,7 +293,9 @@ public class Bits { */ private static int trailingZeroBits(int x) { Assert.check(wordlen == 32); - if (x == 0) return 32; + if (x == 0) { + return 32; + } int n = 1; if ((x & 0xffff) == 0) { n += 16; x >>>= 16; } if ((x & 0x00ff) == 0) { n += 8; x >>>= 8; } @@ -355,24 +314,31 @@ public class Bits { public int nextBit(int x) { Assert.check(currentState != BitsState.UNKNOWN); int windex = x >>> wordshift; - if (windex >= bits.length) return -1; + if (windex >= bits.length) { + return -1; + } int word = bits[windex] & ~((1 << (x & wordmask))-1); while (true) { - if (word != 0) + if (word != 0) { return (windex << wordshift) + trailingZeroBits(word); + } windex++; - if (windex >= bits.length) return -1; + if (windex >= bits.length) { + return -1; + } word = bits[windex]; } } /** a string representation of this set. */ + @Override public String toString() { - if (bits.length > 0) { + if (bits != null && bits.length > 0) { char[] digits = new char[bits.length * wordlen]; - for (int i = 0; i < bits.length * wordlen; i++) + for (int i = 0; i < bits.length * wordlen; i++) { digits[i] = isMember(i) ? '1' : '0'; + } return new String(digits); } else { return "[]"; @@ -396,6 +362,8 @@ public class Bits { System.out.println("found " + i); count ++; } - if (count != 125) throw new Error(); + if (count != 125) { + throw new Error(); + } } } diff --git a/langtools/test/tools/javac/flow/AliveRanges.java b/langtools/test/tools/javac/flow/AliveRanges.java new file mode 100644 index 00000000000..2494f77aca8 --- /dev/null +++ b/langtools/test/tools/javac/flow/AliveRanges.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.lang.annotation.*; + +@Repeatable(AliveRanges.class) +@Target({ElementType.METHOD}) +@interface AliveRange { + String varName(); + int bytecodeStart(); + int bytecodeLength(); +} + +@Target({ElementType.METHOD}) +@interface AliveRanges {AliveRange[] value();} diff --git a/langtools/test/tools/javac/flow/LVTHarness.java b/langtools/test/tools/javac/flow/LVTHarness.java new file mode 100644 index 00000000000..7794ded19dd --- /dev/null +++ b/langtools/test/tools/javac/flow/LVTHarness.java @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2013, 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 7047734 + * @summary The LVT is not generated correctly during some try/catch scenarios + * @library /tools/javac/lib + * @build JavacTestingAbstractProcessor LVTHarness + * @run main LVTHarness + */ + +import java.io.File; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.util.Set; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +import com.sun.source.util.JavacTask; +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPool; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.ConstantPool.InvalidIndex; +import com.sun.tools.classfile.ConstantPool.UnexpectedEntry; +import com.sun.tools.classfile.Descriptor.InvalidDescriptor; +import com.sun.tools.classfile.LocalVariableTable_attribute; +import com.sun.tools.classfile.Method; + +import static javax.tools.StandardLocation.*; +import static com.sun.tools.classfile.LocalVariableTable_attribute.Entry; + +public class LVTHarness { + + static int nerrors = 0; + + static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); + static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + + public static void main(String[] args) throws Exception { + fm.setLocation(SOURCE_PATH, + Arrays.asList(new File(System.getProperty("test.src"), "tests"))); + for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", + Collections.singleton(JavaFileObject.Kind.SOURCE), true)) { + new LVTHarness(jfo).check(); + } + if (nerrors > 0) { + throw new AssertionError("Errors were found"); + } + } + + + JavaFileObject jfo; + Map aliveRangeMap = + new HashMap(); + Set declaredKeys = new HashSet<>(); + List seenAliveRanges = new ArrayList<>(); + + protected LVTHarness(JavaFileObject jfo) { + this.jfo = jfo; + } + + protected void check() throws Exception { + JavacTask ct = (JavacTask)comp.getTask(null, fm, null, Arrays.asList("-g"), + null, Arrays.asList(jfo)); + System.err.println("compiling code " + jfo.toString()); + ct.setProcessors(Collections.singleton(new AliveRangeFinder())); + if (!ct.call()) { + throw new AssertionError("Error during compilation"); + } + + checkClassFile(new File(jfo.getName().replace(".java", ".class"))); + + //check all candidates have been used up + for (Map.Entry entry : aliveRangeMap.entrySet()) { + if (!seenAliveRanges.contains(entry.getKey())) { + error("Redundant @AliveRanges annotation on method " + + entry.getKey().elem); + } + } + } + + void checkClassFile(File file) + throws IOException, ConstantPoolException, InvalidDescriptor { + ClassFile classFile = ClassFile.read(file); + ConstantPool constantPool = classFile.constant_pool; + + //lets get all the methods in the class file. + for (Method method : classFile.methods) { + for (ElementKey elementKey: aliveRangeMap.keySet()) { + String methodDesc = method.getName(constantPool) + + method.descriptor.getParameterTypes(constantPool); + if (methodDesc.equals(elementKey.elem.toString())) { + checkMethod(constantPool, method, aliveRangeMap.get(elementKey)); + seenAliveRanges.add(elementKey); + } + } + } + } + + void checkMethod(ConstantPool constantPool, Method method, AliveRanges ranges) + throws InvalidIndex, UnexpectedEntry { + Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code); + LocalVariableTable_attribute lvt = + (LocalVariableTable_attribute) (code.attributes.get(Attribute.LocalVariableTable)); + List infoFromRanges = convertToStringList(ranges); + List infoFromLVT = convertToStringList(constantPool, lvt); + + // infoFromRanges most be contained in infoFromLVT + int i = 0; + int j = 0; + while (i < infoFromRanges.size() && j < infoFromLVT.size()) { + int comparison = infoFromRanges.get(i).compareTo(infoFromLVT.get(j)); + if (comparison == 0) { + i++; j++; + } else if (comparison > 0) { + j++; + } else { + break; + } + } + + if (i < infoFromRanges.size()) { + error(infoFromLVT, infoFromRanges); + } + } + + List convertToStringList(AliveRanges ranges) { + List result = new ArrayList<>(); + for (Annotation anno : ranges.value()) { + AliveRange range = (AliveRange)anno; + String str = formatLocalVariableData(range.varName(), + range.bytecodeStart(), range.bytecodeLength()); + result.add(str); + } + Collections.sort(result); + return result; + } + + List convertToStringList(ConstantPool constantPool, + LocalVariableTable_attribute lvt) throws InvalidIndex, UnexpectedEntry { + List result = new ArrayList<>(); + for (Entry entry : lvt.local_variable_table) { + String str = formatLocalVariableData(constantPool.getUTF8Value(entry.name_index), + entry.start_pc, entry.length); + result.add(str); + } + Collections.sort(result); + return result; + } + + String formatLocalVariableData(String varName, int start, int length) { + StringBuilder sb = new StringBuilder() + .append("var name: ").append(varName) + .append(" start: ").append(start) + .append(" length: ").append(length); + return sb.toString(); + } + + protected void error(List infoFromLVT, List infoFromRanges) { + nerrors++; + System.err.printf("Error occurred while checking file: %s\n", jfo.getName()); + System.err.println("The range info from the annotations is"); + printStringListToErrOutput(infoFromRanges); + System.err.println(); + System.err.println("And the range info from the class file is"); + printStringListToErrOutput(infoFromLVT); + System.err.println(); + } + + void printStringListToErrOutput(List list) { + for (String s : list) { + System.err.println("\t" + s); + } + } + + protected void error(String msg) { + nerrors++; + System.err.printf("Error occurred while checking file: %s\nreason: %s\n", + jfo.getName(), msg); + } + + class AliveRangeFinder extends JavacTestingAbstractProcessor { + + @Override + public boolean process(Set annotations, + RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) + return true; + + TypeElement aliveRangeAnno = elements.getTypeElement("AliveRanges"); + + if (!annotations.contains(aliveRangeAnno)) { + error("no @AliveRanges annotation found in test class"); + } + + for (Element elem: roundEnv.getElementsAnnotatedWith(aliveRangeAnno)) { + Annotation annotation = elem.getAnnotation(AliveRanges.class); + aliveRangeMap.put(new ElementKey(elem), (AliveRanges)annotation); + } + return true; + } + } + + class ElementKey { + + String key; + Element elem; + + public ElementKey(Element elem) { + this.elem = elem; + this.key = computeKey(elem); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ElementKey) { + ElementKey other = (ElementKey)obj; + return other.key.equals(key); + } + return false; + } + + @Override + public int hashCode() { + return key.hashCode(); + } + + String computeKey(Element e) { + StringBuilder buf = new StringBuilder(); + while (e != null) { + buf.append(e.toString()); + e = e.getEnclosingElement(); + } + buf.append(jfo.getName()); + return buf.toString(); + } + + @Override + public String toString() { + return "Key{" + key + "}"; + } + } + +} diff --git a/langtools/test/tools/javac/flow/tests/TestCaseConditional.java b/langtools/test/tools/javac/flow/tests/TestCaseConditional.java new file mode 100644 index 00000000000..0e5915985d0 --- /dev/null +++ b/langtools/test/tools/javac/flow/tests/TestCaseConditional.java @@ -0,0 +1,16 @@ +/* /nodynamiccopyright/ */ + +public class TestCaseConditional { + + @AliveRange(varName="o", bytecodeStart=5, bytecodeLength=33) + @AliveRange(varName="oo", bytecodeStart=23, bytecodeLength=15) + void m(String[] args) { + Boolean o; + Boolean oo = ((o = Boolean.TRUE).booleanValue()) ? + o = Boolean.TRUE : + Boolean.FALSE; + oo.hashCode(); + o = Boolean.FALSE; + o.hashCode(); + } +} diff --git a/langtools/test/tools/javac/flow/tests/TestCaseDoLoop.java b/langtools/test/tools/javac/flow/tests/TestCaseDoLoop.java new file mode 100644 index 00000000000..68e3d20e6a4 --- /dev/null +++ b/langtools/test/tools/javac/flow/tests/TestCaseDoLoop.java @@ -0,0 +1,15 @@ +/* /nodynamiccopyright/ */ + +public class TestCaseDoLoop { + + @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=15) + @AliveRange(varName="args", bytecodeStart=0, bytecodeLength=18) + void m(String[] args) { + Object o; + do { + o = ""; + o.hashCode(); + } while (args[0] != null); + o = ""; + } +} diff --git a/langtools/test/tools/javac/flow/tests/TestCaseFor.java b/langtools/test/tools/javac/flow/tests/TestCaseFor.java new file mode 100644 index 00000000000..10056b88086 --- /dev/null +++ b/langtools/test/tools/javac/flow/tests/TestCaseFor.java @@ -0,0 +1,27 @@ +/* /nodynamiccopyright/ */ + +public class TestCaseFor { + + @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8) + @AliveRange(varName="o", bytecodeStart=24, bytecodeLength=1) + void m1(String[] args) { + Object o; + for (int i = 0; i < 5; i++) { + o = ""; + o.hashCode(); + } + o = ""; + } + + @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8) + @AliveRange(varName="o", bytecodeStart=24, bytecodeLength=1) + void m2(String[] args) { + Object o; + for (int i = 0; i < 5; i++) { + o = ""; + o.hashCode(); + continue; + } + o = ""; + } +} diff --git a/langtools/test/tools/javac/flow/tests/TestCaseForEach.java b/langtools/test/tools/javac/flow/tests/TestCaseForEach.java new file mode 100644 index 00000000000..219f1180772 --- /dev/null +++ b/langtools/test/tools/javac/flow/tests/TestCaseForEach.java @@ -0,0 +1,15 @@ +/* /nodynamiccopyright/ */ + +public class TestCaseForEach { + + @AliveRange(varName="o", bytecodeStart=25, bytecodeLength=8) + @AliveRange(varName="o", bytecodeStart=39, bytecodeLength=1) + void m(String[] args) { + Object o; + for (String s : args) { + o = ""; + o.hashCode(); + } + o = ""; + } +} diff --git a/langtools/test/tools/javac/flow/tests/TestCaseIf.java b/langtools/test/tools/javac/flow/tests/TestCaseIf.java new file mode 100644 index 00000000000..9869443f773 --- /dev/null +++ b/langtools/test/tools/javac/flow/tests/TestCaseIf.java @@ -0,0 +1,61 @@ +/* /nodynamiccopyright/ */ + +public class TestCaseIf { + + @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=5) + @AliveRange(varName="o", bytecodeStart=17, bytecodeLength=1) + void m0(String[] args) { + Object o; + if (args[0] != null) { + o = ""; + o.hashCode(); + } + o = ""; + } + + @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=5) + @AliveRange(varName="o", bytecodeStart=18, bytecodeLength=1) + void m1() { + Object o; + int i = 5; + if (i == 5) { + o = ""; + o.hashCode(); + } + o = ""; + } + + @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=5) + @AliveRange(varName="o", bytecodeStart=18, bytecodeLength=1) + void m2() { + Object o; + int i = 5; + if (!(i == 5)) { + o = ""; + o.hashCode(); + } + o = ""; + } + + @AliveRange(varName="o", bytecodeStart=15, bytecodeLength=5) + @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=1) + void m3(String[] args) { + Object o; + if (args[0] != null && args[1] != null) { + o = ""; + o.hashCode(); + } + o = ""; + } + + @AliveRange(varName="o", bytecodeStart=15, bytecodeLength=5) + @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=1) + void m4(String[] args) { + Object o; + if (args[0] != null || args[1] != null) { + o = ""; + o.hashCode(); + } + o = ""; + } +} diff --git a/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java b/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java new file mode 100644 index 00000000000..3e6cc893794 --- /dev/null +++ b/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java @@ -0,0 +1,48 @@ +/* /nodynamiccopyright/ */ + +public class TestCaseIfElse { + + @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=8) + @AliveRange(varName="o", bytecodeStart=20, bytecodeLength=9) + void m0(String[] args) { + Object o; + if (args[0] != null) { + o = "then"; + o.hashCode(); + } else { + o = "else"; + o.hashCode(); + } + o = "finish"; + } + + @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8) + @AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9) + void m1() { + Object o; + int i = 5; + if (i == 5) { + o = "then"; + o.hashCode(); + } else { + o = "else"; + o.hashCode(); + } + o = "finish"; + } + + @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8) + @AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9) + void m2(String[] args) { + Object o; + int i = 5; + if (i != 5) { + o = "then"; + o.hashCode(); + } else { + o = "else"; + o.hashCode(); + } + o = "finish"; + } +} diff --git a/langtools/test/tools/javac/flow/tests/TestCaseSwitch.java b/langtools/test/tools/javac/flow/tests/TestCaseSwitch.java new file mode 100644 index 00000000000..d96850ffd21 --- /dev/null +++ b/langtools/test/tools/javac/flow/tests/TestCaseSwitch.java @@ -0,0 +1,73 @@ +/* /nodynamiccopyright/ */ + +public class TestCaseSwitch { + + @AliveRange(varName="o", bytecodeStart=31, bytecodeLength=16) + @AliveRange(varName="o", bytecodeStart=50, bytecodeLength=15) + @AliveRange(varName="o", bytecodeStart=68, bytecodeLength=1) + @AliveRange(varName="oo", bytecodeStart=39, bytecodeLength=26) + @AliveRange(varName="uu", bytecodeStart=59, bytecodeLength=6) + void m1(String[] args) { + Object o; + switch (args.length) { + case 0: + o = "0"; + o.hashCode(); + Object oo = "oo"; + oo.hashCode(); + break; + case 1: + o = "1"; + o.hashCode(); + Object uu = "uu"; + uu.hashCode(); + break; + } + o = "return"; + } + + @AliveRange(varName="o", bytecodeStart=95, bytecodeLength=18) + @AliveRange(varName="o", bytecodeStart=116, bytecodeLength=15) + @AliveRange(varName="o", bytecodeStart=134, bytecodeLength=1) + @AliveRange(varName="oo", bytecodeStart=104, bytecodeLength=27) + @AliveRange(varName="uu", bytecodeStart=125, bytecodeLength=6) + void m2(String[] args) { + Object o; + switch (args[0]) { + case "string0": + o = "0"; + o.hashCode(); + Object oo = "oo"; + oo.hashCode(); + break; + case "string1": + o = "1"; + o.hashCode(); + Object uu = "uu"; + uu.hashCode(); + break; + } + o = "return"; + } + + @AliveRange(varName="o", bytecodeStart=31, bytecodeLength=8) + @AliveRange(varName="o", bytecodeStart=42, bytecodeLength=8) + @AliveRange(varName="o", bytecodeStart=53, bytecodeLength=9) + void m3(String[] args) { + Object o; + switch (args.length) { + case 0: + o = "0"; + o.hashCode(); + break; + case 1: + o = "1"; + o.hashCode(); + break; + default: + o = "default"; + o.hashCode(); + } + o = "finish"; + } +} diff --git a/langtools/test/tools/javac/flow/tests/TestCaseTry.java b/langtools/test/tools/javac/flow/tests/TestCaseTry.java new file mode 100644 index 00000000000..e987534ddfc --- /dev/null +++ b/langtools/test/tools/javac/flow/tests/TestCaseTry.java @@ -0,0 +1,76 @@ +/* /nodynamiccopyright/ */ + +import java.io.BufferedReader; +import java.io.FileReader; + +public class TestCaseTry { + + @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=8) + @AliveRange(varName="o", bytecodeStart=15, bytecodeLength=1) + void m0(String[] args) { + Object o; + try { + o = ""; + o.hashCode(); + } catch (RuntimeException e) {} + o = ""; + } + + @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=16) + @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=23) + void m1() { + Object o; + try { + o = ""; + o.hashCode(); + } catch (RuntimeException e) { + } + finally { + o = "finally"; + o.hashCode(); + } + o = ""; + } + + @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=16) + @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=31) + void m2() { + Object o; + try { + o = ""; + o.hashCode(); + } catch (RuntimeException e) { + o = "catch"; + o.hashCode(); + } + finally { + o = "finally"; + o.hashCode(); + } + o = ""; + } + + @AliveRange(varName="o", bytecodeStart=22, bytecodeLength=38) + @AliveRange(varName="o", bytecodeStart=103, bytecodeLength=8) + void m3() { + Object o; + try (BufferedReader br = + new BufferedReader(new FileReader("aFile"))) { + o = "inside try"; + o.hashCode(); + } catch (Exception e) {} + o = ""; + } + + @AliveRange(varName="o", bytecodeStart=12, bytecodeLength=96) + @AliveRange(varName="o", bytecodeStart=112, bytecodeLength=1) + void m4() { + String o; + try (BufferedReader br = + new BufferedReader(new FileReader(o = "aFile"))) { + o = "inside try"; + o.hashCode(); + } catch (Exception e) {} + o = ""; + } +} diff --git a/langtools/test/tools/javac/flow/tests/TestCaseWhile.java b/langtools/test/tools/javac/flow/tests/TestCaseWhile.java new file mode 100644 index 00000000000..bbe1f844422 --- /dev/null +++ b/langtools/test/tools/javac/flow/tests/TestCaseWhile.java @@ -0,0 +1,15 @@ +/* /nodynamiccopyright/ */ + +public class TestCaseWhile { + + @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=5) + @AliveRange(varName="o", bytecodeStart=20, bytecodeLength=1) + void m(String[] args) { + Object o; + while (args[0] != null) { + o = ""; + o.hashCode(); + } + o = ""; + } +} From c492e4ef1fa7888cf1a5f69249c0fd87b2dcc4ed Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Sat, 14 Sep 2013 22:46:49 +0100 Subject: [PATCH 0364/1294] 8024835: Change until() to accept any compatible temporal Method until(Temporal,TemporalUnit) now uses from() to convert; Enhance from() methods where necessary Reviewed-by: sherman --- jdk/src/share/classes/java/time/Duration.java | 8 +- jdk/src/share/classes/java/time/Instant.java | 26 ++++--- .../share/classes/java/time/LocalDate.java | 28 ++++--- .../classes/java/time/LocalDateTime.java | 26 +++---- .../share/classes/java/time/LocalTime.java | 23 +++--- jdk/src/share/classes/java/time/MonthDay.java | 3 +- .../classes/java/time/OffsetDateTime.java | 22 +++--- .../share/classes/java/time/OffsetTime.java | 22 +++--- jdk/src/share/classes/java/time/Year.java | 23 +++--- .../share/classes/java/time/YearMonth.java | 23 +++--- .../share/classes/java/time/ZoneOffset.java | 1 + .../classes/java/time/ZonedDateTime.java | 26 +++---- .../java/time/chrono/ChronoLocalDate.java | 17 +++-- .../java/time/chrono/ChronoLocalDateImpl.java | 21 ++---- .../java/time/chrono/ChronoLocalDateTime.java | 1 + .../time/chrono/ChronoLocalDateTimeImpl.java | 15 ++-- .../java/time/chrono/ChronoZonedDateTime.java | 1 + .../time/chrono/ChronoZonedDateTimeImpl.java | 19 ++--- .../java/time/temporal/ChronoUnit.java | 4 +- .../classes/java/time/temporal/IsoFields.java | 11 ++- .../classes/java/time/temporal/Temporal.java | 22 ++++-- .../java/time/temporal/TemporalUnit.java | 23 ++++-- .../java/time/tck/java/time/TCKDuration.java | 10 ++- .../java/time/tck/java/time/TCKInstant.java | 32 ++++++-- .../java/time/tck/java/time/TCKLocalDate.java | 29 +++++-- .../time/tck/java/time/TCKLocalDateTime.java | 27 ++++++- .../java/time/tck/java/time/TCKLocalTime.java | 29 +++++-- .../time/tck/java/time/TCKOffsetDateTime.java | 75 +++++++++++++++++++ .../time/tck/java/time/TCKOffsetTime.java | 62 ++++++++------- jdk/test/java/time/tck/java/time/TCKYear.java | 47 ++++++++---- .../java/time/tck/java/time/TCKYearMonth.java | 44 +++++++---- .../time/tck/java/time/TCKZonedDateTime.java | 22 +++--- .../time/tck/java/time/chrono/CopticDate.java | 12 +-- .../tck/java/time/temporal/TCKIsoFields.java | 11 ++- 34 files changed, 487 insertions(+), 278 deletions(-) diff --git a/jdk/src/share/classes/java/time/Duration.java b/jdk/src/share/classes/java/time/Duration.java index ce2ba7781b0..896a2990eaa 100644 --- a/jdk/src/share/classes/java/time/Duration.java +++ b/jdk/src/share/classes/java/time/Duration.java @@ -441,9 +441,13 @@ public final class Duration //----------------------------------------------------------------------- /** - * Obtains a {@code Duration} representing the duration between two instants. + * Obtains a {@code Duration} representing the duration between two temporal objects. + *

    + * This calculates the duration between two temporal objects. If the objects + * are of different types, then the duration is calculated based on the type + * of the first object. For example, if the first argument is a {@code LocalTime} + * then the second argument is converted to a {@code LocalTime}. *

    - * This calculates the duration between two temporal objects of the same type. * The specified temporal objects must support the {@link ChronoUnit#SECONDS SECONDS} unit. * For full accuracy, either the {@link ChronoUnit#NANOS NANOS} unit or the * {@link ChronoField#NANO_OF_SECOND NANO_OF_SECOND} field should be supported. diff --git a/jdk/src/share/classes/java/time/Instant.java b/jdk/src/share/classes/java/time/Instant.java index 9d74e29f91a..a7bd6f92004 100644 --- a/jdk/src/share/classes/java/time/Instant.java +++ b/jdk/src/share/classes/java/time/Instant.java @@ -362,6 +362,10 @@ public final class Instant * @throws DateTimeException if unable to convert to an {@code Instant} */ public static Instant from(TemporalAccessor temporal) { + if (temporal instanceof Instant) { + return (Instant) temporal; + } + Objects.requireNonNull(temporal, "temporal"); long instantSecs = temporal.getLong(INSTANT_SECONDS); int nanoOfSecond = temporal.get(NANO_OF_SECOND); return Instant.ofEpochSecond(instantSecs, nanoOfSecond); @@ -1091,7 +1095,8 @@ public final class Instant * The result will be negative if the end is before the start. * The calculation returns a whole number, representing the number of * complete units between the two instants. - * The {@code Temporal} passed to this method must be an {@code Instant}. + * The {@code Temporal} passed to this method is converted to a + * {@code Instant} using {@link #from(TemporalAccessor)}. * For example, the amount in days between two dates can be calculated * using {@code startInstant.until(endInstant, SECONDS)}. *

    @@ -1112,25 +1117,22 @@ public final class Instant *

    * If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

    * This instance is immutable and unaffected by this method call. * - * @param endInstant the end date, which must be an {@code Instant}, not null + * @param endExclusive the end date, exclusive, which is converted to an {@code Instant}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this instant and the end instant - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to an {@code Instant} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endInstant, TemporalUnit unit) { - if (endInstant instanceof Instant == false) { - Objects.requireNonNull(endInstant, "endInstant"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - Instant end = (Instant) endInstant; + public long until(Temporal endExclusive, TemporalUnit unit) { + Instant end = Instant.from(endExclusive); if (unit instanceof ChronoUnit) { ChronoUnit f = (ChronoUnit) unit; switch (f) { @@ -1145,7 +1147,7 @@ public final class Instant } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endInstant); + return unit.between(this, end); } private long nanosUntil(Instant end) { diff --git a/jdk/src/share/classes/java/time/LocalDate.java b/jdk/src/share/classes/java/time/LocalDate.java index 110a80fc9c0..f388959aa63 100644 --- a/jdk/src/share/classes/java/time/LocalDate.java +++ b/jdk/src/share/classes/java/time/LocalDate.java @@ -353,6 +353,7 @@ public final class LocalDate * @throws DateTimeException if unable to convert to a {@code LocalDate} */ public static LocalDate from(TemporalAccessor temporal) { + Objects.requireNonNull(temporal, "temporal"); LocalDate date = temporal.query(TemporalQuery.localDate()); if (date == null) { throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " + temporal.getClass()); @@ -1125,11 +1126,11 @@ public final class LocalDate */ @Override public LocalDate plus(TemporalAmount amountToAdd) { - Objects.requireNonNull(amountToAdd, "amountToAdd"); if (amountToAdd instanceof Period) { Period periodToAdd = (Period) amountToAdd; return plusMonths(periodToAdd.toTotalMonths()).plusDays(periodToAdd.getDays()); } + Objects.requireNonNull(amountToAdd, "amountToAdd"); return (LocalDate) amountToAdd.addTo(this); } @@ -1358,11 +1359,11 @@ public final class LocalDate */ @Override public LocalDate minus(TemporalAmount amountToSubtract) { - Objects.requireNonNull(amountToSubtract, "amountToSubtract"); if (amountToSubtract instanceof Period) { Period periodToSubtract = (Period) amountToSubtract; return minusMonths(periodToSubtract.toTotalMonths()).minusDays(periodToSubtract.getDays()); } + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); return (LocalDate) amountToSubtract.subtractFrom(this); } @@ -1541,7 +1542,8 @@ public final class LocalDate * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified date. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a {@code LocalDate}. + * The {@code Temporal} passed to this method is converted to a + * {@code LocalDate} using {@link #from(TemporalAccessor)}. * For example, the amount in days between two dates can be calculated * using {@code startDate.until(endDate, DAYS)}. *

    @@ -1567,26 +1569,22 @@ public final class LocalDate *

    * If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

    * This instance is immutable and unaffected by this method call. * - * @param endDate the end date, which must be a {@code LocalDate}, not null + * @param endExclusive the end date, exclusive, which is converted to a {@code LocalDate}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this date and the end date - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code LocalDate} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endDate, TemporalUnit unit) { - Objects.requireNonNull(unit, "unit"); - if (endDate instanceof LocalDate == false) { - Objects.requireNonNull(endDate, "endDate"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - LocalDate end = (LocalDate) endDate; + public long until(Temporal endExclusive, TemporalUnit unit) { + LocalDate end = LocalDate.from(endExclusive); if (unit instanceof ChronoUnit) { switch ((ChronoUnit) unit) { case DAYS: return daysUntil(end); @@ -1600,7 +1598,7 @@ public final class LocalDate } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endDate); + return unit.between(this, end); } long daysUntil(LocalDate end) { diff --git a/jdk/src/share/classes/java/time/LocalDateTime.java b/jdk/src/share/classes/java/time/LocalDateTime.java index d0b72b90f82..aed44dd4bfe 100644 --- a/jdk/src/share/classes/java/time/LocalDateTime.java +++ b/jdk/src/share/classes/java/time/LocalDateTime.java @@ -1129,11 +1129,11 @@ public final class LocalDateTime */ @Override public LocalDateTime plus(TemporalAmount amountToAdd) { - Objects.requireNonNull(amountToAdd, "amountToAdd"); if (amountToAdd instanceof Period) { Period periodToAdd = (Period) amountToAdd; return with(date.plus(periodToAdd), time); } + Objects.requireNonNull(amountToAdd, "amountToAdd"); return (LocalDateTime) amountToAdd.addTo(this); } @@ -1348,11 +1348,11 @@ public final class LocalDateTime */ @Override public LocalDateTime minus(TemporalAmount amountToSubtract) { - Objects.requireNonNull(amountToSubtract, "amountToSubtract"); if (amountToSubtract instanceof Period) { Period periodToSubtract = (Period) amountToSubtract; return with(date.minus(periodToSubtract), time); } + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); return (LocalDateTime) amountToSubtract.subtractFrom(this); } @@ -1621,7 +1621,8 @@ public final class LocalDateTime * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified date-time. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a {@code LocalDateTime}. + * The {@code Temporal} passed to this method is converted to a + * {@code LocalDateTime} using {@link #from(TemporalAccessor)}. * For example, the amount in days between two date-times can be calculated * using {@code startDateTime.until(endDateTime, DAYS)}. *

    @@ -1649,25 +1650,22 @@ public final class LocalDateTime *

    * If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

    * This instance is immutable and unaffected by this method call. * - * @param endDateTime the end date-time, which must be a {@code LocalDateTime}, not null + * @param endExclusive the end date, exclusive, which is converted to a {@code LocalDateTime}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this date-time and the end date-time - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code LocalDateTime} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof LocalDateTime == false) { - Objects.requireNonNull(endDateTime, "endDateTime"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - LocalDateTime end = (LocalDateTime) endDateTime; + public long until(Temporal endExclusive, TemporalUnit unit) { + LocalDateTime end = LocalDateTime.from(endExclusive); if (unit instanceof ChronoUnit) { if (unit.isTimeBased()) { long amount = date.daysUntil(end.date); @@ -1721,7 +1719,7 @@ public final class LocalDateTime } return date.until(endDate, unit); } - return unit.between(this, endDateTime); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/LocalTime.java b/jdk/src/share/classes/java/time/LocalTime.java index a6270db19cf..77ab2c7f286 100644 --- a/jdk/src/share/classes/java/time/LocalTime.java +++ b/jdk/src/share/classes/java/time/LocalTime.java @@ -394,6 +394,7 @@ public final class LocalTime * @throws DateTimeException if unable to convert to a {@code LocalTime} */ public static LocalTime from(TemporalAccessor temporal) { + Objects.requireNonNull(temporal, "temporal"); LocalTime time = temporal.query(TemporalQuery.localTime()); if (time == null) { throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + temporal.getClass()); @@ -1330,7 +1331,8 @@ public final class LocalTime * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified time. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a {@code LocalTime}. + * The {@code Temporal} passed to this method is converted to a + * {@code LocalTime} using {@link #from(TemporalAccessor)}. * For example, the amount in hours between two times can be calculated * using {@code startTime.until(endTime, HOURS)}. *

    @@ -1356,25 +1358,22 @@ public final class LocalTime *

    * If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

    * This instance is immutable and unaffected by this method call. * - * @param endTime the end time, which must be a {@code LocalTime}, not null + * @param endExclusive the end time, exclusive, which is converted to a {@code LocalTime}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this time and the end time - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code LocalTime} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endTime, TemporalUnit unit) { - if (endTime instanceof LocalTime == false) { - Objects.requireNonNull(endTime, "endTime"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - LocalTime end = (LocalTime) endTime; + public long until(Temporal endExclusive, TemporalUnit unit) { + LocalTime end = LocalTime.from(endExclusive); if (unit instanceof ChronoUnit) { long nanosUntil = end.toNanoOfDay() - toNanoOfDay(); // no overflow switch ((ChronoUnit) unit) { @@ -1388,7 +1387,7 @@ public final class LocalTime } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endTime); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/MonthDay.java b/jdk/src/share/classes/java/time/MonthDay.java index 22807822f2b..67f5d4fa87f 100644 --- a/jdk/src/share/classes/java/time/MonthDay.java +++ b/jdk/src/share/classes/java/time/MonthDay.java @@ -246,7 +246,8 @@ public final class MonthDay *

    * The conversion extracts the {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} and * {@link ChronoField#DAY_OF_MONTH DAY_OF_MONTH} fields. - * The extraction is only permitted if the date-time has an ISO chronology. + * The extraction is only permitted if the temporal object has an ISO + * chronology, or can be converted to a {@code LocalDate}. *

    * This method matches the signature of the functional interface {@link TemporalQuery} * allowing it to be used in queries via method reference, {@code MonthDay::from}. diff --git a/jdk/src/share/classes/java/time/OffsetDateTime.java b/jdk/src/share/classes/java/time/OffsetDateTime.java index f894e53e46f..410c7f3a747 100644 --- a/jdk/src/share/classes/java/time/OffsetDateTime.java +++ b/jdk/src/share/classes/java/time/OffsetDateTime.java @@ -1592,7 +1592,8 @@ public final class OffsetDateTime * For example, the period in days between two date-times can be calculated * using {@code startDateTime.until(endDateTime, DAYS)}. *

    - * The {@code Temporal} passed to this method must be an {@code OffsetDateTime}. + * The {@code Temporal} passed to this method is converted to a + * {@code OffsetDateTime} using {@link #from(TemporalAccessor)}. * If the offset differs between the two date-times, the specified * end date-time is normalized to have the same offset as this date-time. *

    @@ -1620,30 +1621,27 @@ public final class OffsetDateTime *

    * If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

    * This instance is immutable and unaffected by this method call. * - * @param endDateTime the end date-time, which must be an {@code OffsetDateTime}, not null + * @param endExclusive the end date, exclusive, which is converted to an {@code OffsetDateTime}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this date-time and the end date-time - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to an {@code OffsetDateTime} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof OffsetDateTime == false) { - Objects.requireNonNull(endDateTime, "endDateTime"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + OffsetDateTime end = OffsetDateTime.from(endExclusive); if (unit instanceof ChronoUnit) { - OffsetDateTime end = (OffsetDateTime) endDateTime; end = end.withOffsetSameInstant(offset); return dateTime.until(end.dateTime, unit); } - return unit.between(this, endDateTime); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/OffsetTime.java b/jdk/src/share/classes/java/time/OffsetTime.java index 6c67ef82bb1..a8dbf8a7a56 100644 --- a/jdk/src/share/classes/java/time/OffsetTime.java +++ b/jdk/src/share/classes/java/time/OffsetTime.java @@ -1124,7 +1124,8 @@ public final class OffsetTime * For example, the period in hours between two times can be calculated * using {@code startTime.until(endTime, HOURS)}. *

    - * The {@code Temporal} passed to this method must be an {@code OffsetTime}. + * The {@code Temporal} passed to this method is converted to a + * {@code OffsetTime} using {@link #from(TemporalAccessor)}. * If the offset differs between the two times, then the specified * end time is normalized to have the same offset as this time. *

    @@ -1150,26 +1151,23 @@ public final class OffsetTime *

    * If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

    * This instance is immutable and unaffected by this method call. * - * @param endTime the end time, which must be an {@code OffsetTime}, not null + * @param endExclusive the end date, exclusive, which is converted to an {@code OffsetTime}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this time and the end time - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to an {@code OffsetTime} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endTime, TemporalUnit unit) { - if (endTime instanceof OffsetTime == false) { - Objects.requireNonNull(endTime, "endTime"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + OffsetTime end = OffsetTime.from(endExclusive); if (unit instanceof ChronoUnit) { - OffsetTime end = (OffsetTime) endTime; long nanosUntil = end.toEpochNano() - toEpochNano(); // no overflow switch ((ChronoUnit) unit) { case NANOS: return nanosUntil; @@ -1182,7 +1180,7 @@ public final class OffsetTime } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endTime); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/Year.java b/jdk/src/share/classes/java/time/Year.java index f51bda69664..377dfd5185a 100644 --- a/jdk/src/share/classes/java/time/Year.java +++ b/jdk/src/share/classes/java/time/Year.java @@ -242,6 +242,7 @@ public final class Year if (temporal instanceof Year) { return (Year) temporal; } + Objects.requireNonNull(temporal, "temporal"); try { if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) { temporal = LocalDate.from(temporal); @@ -859,7 +860,8 @@ public final class Year * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified year. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a {@code Year}. + * The {@code Temporal} passed to this method is converted to a + * {@code Year} using {@link #from(TemporalAccessor)}. * For example, the period in decades between two year can be calculated * using {@code startYear.until(endYear, DECADES)}. *

    @@ -885,25 +887,22 @@ public final class Year *

    * If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

    * This instance is immutable and unaffected by this method call. * - * @param endYear the end year, which must be a {@code Year}, not null + * @param endExclusive the end date, exclusive, which is converted to a {@code Year}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this year and the end year - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code Year} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endYear, TemporalUnit unit) { - if (endYear instanceof Year == false) { - Objects.requireNonNull(endYear, "endYear"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - Year end = (Year) endYear; + public long until(Temporal endExclusive, TemporalUnit unit) { + Year end = Year.from(endExclusive); if (unit instanceof ChronoUnit) { long yearsUntil = ((long) end.year) - year; // no overflow switch ((ChronoUnit) unit) { @@ -915,7 +914,7 @@ public final class Year } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endYear); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/YearMonth.java b/jdk/src/share/classes/java/time/YearMonth.java index 541676117eb..223c90ab0f0 100644 --- a/jdk/src/share/classes/java/time/YearMonth.java +++ b/jdk/src/share/classes/java/time/YearMonth.java @@ -245,6 +245,7 @@ public final class YearMonth if (temporal instanceof YearMonth) { return (YearMonth) temporal; } + Objects.requireNonNull(temporal, "temporal"); try { if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) { temporal = LocalDate.from(temporal); @@ -992,7 +993,8 @@ public final class YearMonth * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified year-month. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a {@code YearMonth}. + * The {@code Temporal} passed to this method is converted to a + * {@code YearMonth} using {@link #from(TemporalAccessor)}. * For example, the period in years between two year-months can be calculated * using {@code startYearMonth.until(endYearMonth, YEARS)}. *

    @@ -1018,25 +1020,22 @@ public final class YearMonth *

    * If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

    * This instance is immutable and unaffected by this method call. * - * @param endYearMonth the end year-month, which must be a {@code YearMonth}, not null + * @param endExclusive the end date, exclusive, which is converted to a {@code YearMonth}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this year-month and the end year-month - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code YearMonth} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endYearMonth, TemporalUnit unit) { - if (endYearMonth instanceof YearMonth == false) { - Objects.requireNonNull(endYearMonth, "endYearMonth"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - YearMonth end = (YearMonth) endYearMonth; + public long until(Temporal endExclusive, TemporalUnit unit) { + YearMonth end = YearMonth.from(endExclusive); if (unit instanceof ChronoUnit) { long monthsUntil = end.getProlepticMonth() - getProlepticMonth(); // no overflow switch ((ChronoUnit) unit) { @@ -1049,7 +1048,7 @@ public final class YearMonth } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endYearMonth); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/ZoneOffset.java b/jdk/src/share/classes/java/time/ZoneOffset.java index 2d63a978d8c..3475e5f4db3 100644 --- a/jdk/src/share/classes/java/time/ZoneOffset.java +++ b/jdk/src/share/classes/java/time/ZoneOffset.java @@ -333,6 +333,7 @@ public final class ZoneOffset * @throws DateTimeException if unable to convert to an {@code ZoneOffset} */ public static ZoneOffset from(TemporalAccessor temporal) { + Objects.requireNonNull(temporal, "temporal"); ZoneOffset offset = temporal.query(TemporalQuery.offset()); if (offset == null) { throw new DateTimeException("Unable to obtain ZoneOffset from TemporalAccessor: " + temporal.getClass()); diff --git a/jdk/src/share/classes/java/time/ZonedDateTime.java b/jdk/src/share/classes/java/time/ZonedDateTime.java index 971ba6daf5b..1114ab4edd3 100644 --- a/jdk/src/share/classes/java/time/ZonedDateTime.java +++ b/jdk/src/share/classes/java/time/ZonedDateTime.java @@ -1540,11 +1540,11 @@ public final class ZonedDateTime */ @Override public ZonedDateTime plus(TemporalAmount amountToAdd) { - Objects.requireNonNull(amountToAdd, "amountToAdd"); if (amountToAdd instanceof Period) { Period periodToAdd = (Period) amountToAdd; return resolveLocal(dateTime.plus(periodToAdd)); } + Objects.requireNonNull(amountToAdd, "amountToAdd"); return (ZonedDateTime) amountToAdd.addTo(this); } @@ -1792,11 +1792,11 @@ public final class ZonedDateTime */ @Override public ZonedDateTime minus(TemporalAmount amountToSubtract) { - Objects.requireNonNull(amountToSubtract, "amountToSubtract"); if (amountToSubtract instanceof Period) { Period periodToSubtract = (Period) amountToSubtract; return resolveLocal(dateTime.minus(periodToSubtract)); } + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); return (ZonedDateTime) amountToSubtract.subtractFrom(this); } @@ -2044,7 +2044,8 @@ public final class ZonedDateTime * For example, the period in days between two date-times can be calculated * using {@code startDateTime.until(endDateTime, DAYS)}. *

    - * The {@code Temporal} passed to this method must be a {@code ZonedDateTime}. + * The {@code Temporal} passed to this method is converted to a + * {@code ZonedDateTime} using {@link #from(TemporalAccessor)}. * If the time-zone differs between the two zoned date-times, the specified * end date-time is normalized to have the same zone as this date-time. *

    @@ -2086,26 +2087,23 @@ public final class ZonedDateTime *

    * If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

    * This instance is immutable and unaffected by this method call. * - * @param endDateTime the end date-time, which must be a {@code ZonedDateTime}, not null + * @param endExclusive the end date, exclusive, which is converted to a {@code ZonedDateTime}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this date-time and the end date-time - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code ZonedDateTime} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof ZonedDateTime == false) { - Objects.requireNonNull(endDateTime, "endDateTime"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + ZonedDateTime end = ZonedDateTime.from(endExclusive); if (unit instanceof ChronoUnit) { - ZonedDateTime end = (ZonedDateTime) endDateTime; end = end.withZoneSameInstant(zone); if (unit.isDateBased()) { return dateTime.until(end.dateTime, unit); @@ -2113,7 +2111,7 @@ public final class ZonedDateTime return toOffsetDateTime().until(end.toOffsetDateTime(), unit); } } - return unit.between(this, endDateTime); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java index 58ae3b8c1c5..58e4f5d5250 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java @@ -291,6 +291,7 @@ public interface ChronoLocalDate if (temporal instanceof ChronoLocalDate) { return (ChronoLocalDate) temporal; } + Objects.requireNonNull(temporal, "temporal"); Chronology chrono = temporal.query(TemporalQuery.chronology()); if (chrono == null) { throw new DateTimeException("Unable to obtain ChronoLocalDate from TemporalAccessor: " + temporal.getClass()); @@ -560,8 +561,8 @@ public interface ChronoLocalDate * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified date. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a - * {@code ChronoLocalDate} in the same chronology. + * The {@code Temporal} passed to this method is converted to a + * {@code ChronoLocalDate} using {@link Chronology#date(TemporalAccessor)}. * The calculation returns a whole number, representing the number of * complete units between the two dates. * For example, the amount in days between two dates can be calculated @@ -585,20 +586,22 @@ public interface ChronoLocalDate *

    * If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as + * passing {@code this} as the first argument and the converted input temporal as * the second argument. *

    * This instance is immutable and unaffected by this method call. * - * @param endDate the end date, which must be a {@code ChronoLocalDate} - * in the same chronology, not null + * @param endExclusive the end date, exclusive, which is converted to a + * {@code ChronoLocalDate} in the same chronology, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this date and the end date - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code ChronoLocalDate} + * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override // override for Javadoc - long until(Temporal endDate, TemporalUnit unit); + long until(Temporal endExclusive, TemporalUnit unit); /** * Calculates the period between this date and another date as a {@code ChronoPeriod}. diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java index fd8c8f88662..6cb115d393e 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java @@ -372,22 +372,10 @@ abstract class ChronoLocalDateImpl } //----------------------------------------------------------------------- - /** - * {@inheritDoc} - * @throws DateTimeException {@inheritDoc} - * @throws ArithmeticException {@inheritDoc} - */ @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - Objects.requireNonNull(endDateTime, "endDateTime"); - Objects.requireNonNull(unit, "unit"); - if (endDateTime instanceof ChronoLocalDate == false) { - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - ChronoLocalDate end = (ChronoLocalDate) endDateTime; - if (getChronology().equals(end.getChronology()) == false) { - throw new DateTimeException("Unable to calculate amount as objects have different chronologies"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + Objects.requireNonNull(endExclusive, "endExclusive"); + ChronoLocalDate end = getChronology().date(endExclusive); if (unit instanceof ChronoUnit) { switch ((ChronoUnit) unit) { case DAYS: return daysUntil(end); @@ -401,7 +389,8 @@ abstract class ChronoLocalDateImpl } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endDateTime); + Objects.requireNonNull(unit, "unit"); + return unit.between(this, end); } private long daysUntil(ChronoLocalDate end) { diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java index be93f0e036a..cde8a982fbc 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java @@ -165,6 +165,7 @@ public interface ChronoLocalDateTime if (temporal instanceof ChronoLocalDateTime) { return (ChronoLocalDateTime) temporal; } + Objects.requireNonNull(temporal, "temporal"); Chronology chrono = temporal.query(TemporalQuery.chronology()); if (chrono == null) { throw new DateTimeException("Unable to obtain ChronoLocalDateTime from TemporalAccessor: " + temporal.getClass()); diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java index 13b3a0e8817..817ae85411a 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java @@ -69,7 +69,6 @@ import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectStreamException; import java.io.Serializable; -import java.time.DateTimeException; import java.time.LocalTime; import java.time.ZoneId; import java.time.temporal.ChronoField; @@ -369,15 +368,10 @@ final class ChronoLocalDateTimeImpl //----------------------------------------------------------------------- @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof ChronoLocalDateTime == false) { - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + Objects.requireNonNull(endExclusive, "endExclusive"); @SuppressWarnings("unchecked") - ChronoLocalDateTime end = (ChronoLocalDateTime) endDateTime; - if (toLocalDate().getChronology().equals(end.toLocalDate().getChronology()) == false) { - throw new DateTimeException("Unable to calculate amount as objects have different chronologies"); - } + ChronoLocalDateTime end = (ChronoLocalDateTime) toLocalDate().getChronology().localDateTime(endExclusive); if (unit instanceof ChronoUnit) { if (unit.isTimeBased()) { long amount = end.getLong(EPOCH_DAY) - date.getLong(EPOCH_DAY); @@ -398,7 +392,8 @@ final class ChronoLocalDateTimeImpl } return date.until(endDate, unit); } - return unit.between(this, endDateTime); + Objects.requireNonNull(unit, "unit"); + return unit.between(this, end); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java index dd911fcd789..abe84799716 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java @@ -166,6 +166,7 @@ public interface ChronoZonedDateTime if (temporal instanceof ChronoZonedDateTime) { return (ChronoZonedDateTime) temporal; } + Objects.requireNonNull(temporal, "temporal"); Chronology chrono = temporal.query(TemporalQuery.chronology()); if (chrono == null) { throw new DateTimeException("Unable to obtain ChronoZonedDateTime from TemporalAccessor: " + temporal.getClass()); diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java index 1cc7b5b5786..1fe8ccf0192 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java @@ -69,7 +69,6 @@ import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectStreamException; import java.io.Serializable; -import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -234,7 +233,7 @@ final class ChronoZonedDateTimeImpl if (trans != null && trans.isOverlap()) { ZoneOffset earlierOffset = trans.getOffsetBefore(); if (earlierOffset.equals(offset) == false) { - return new ChronoZonedDateTimeImpl(dateTime, earlierOffset, zone); + return new ChronoZonedDateTimeImpl<>(dateTime, earlierOffset, zone); } } return this; @@ -246,7 +245,7 @@ final class ChronoZonedDateTimeImpl if (trans != null) { ZoneOffset offset = trans.getOffsetAfter(); if (offset.equals(getOffset()) == false) { - return new ChronoZonedDateTimeImpl(dateTime, offset, zone); + return new ChronoZonedDateTimeImpl<>(dateTime, offset, zone); } } return this; @@ -308,20 +307,16 @@ final class ChronoZonedDateTimeImpl //----------------------------------------------------------------------- @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof ChronoZonedDateTime == false) { - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + Objects.requireNonNull(endExclusive, "endExclusive"); @SuppressWarnings("unchecked") - ChronoZonedDateTime end = (ChronoZonedDateTime) endDateTime; - if (toLocalDate().getChronology().equals(end.toLocalDate().getChronology()) == false) { - throw new DateTimeException("Unable to calculate amount as objects have different chronologies"); - } + ChronoZonedDateTime end = (ChronoZonedDateTime) toLocalDate().getChronology().zonedDateTime(endExclusive); if (unit instanceof ChronoUnit) { end = end.withZoneSameInstant(offset); return dateTime.until(end.toLocalDateTime(), unit); } - return unit.between(this, endDateTime); + Objects.requireNonNull(unit, "unit"); + return unit.between(this, end); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/temporal/ChronoUnit.java b/jdk/src/share/classes/java/time/temporal/ChronoUnit.java index 19a37e46f4c..c7043272398 100644 --- a/jdk/src/share/classes/java/time/temporal/ChronoUnit.java +++ b/jdk/src/share/classes/java/time/temporal/ChronoUnit.java @@ -268,8 +268,8 @@ public enum ChronoUnit implements TemporalUnit { //----------------------------------------------------------------------- @Override - public long between(Temporal temporal1, Temporal temporal2) { - return temporal1.until(temporal2, this); + public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive) { + return temporal1Inclusive.until(temporal2Exclusive, this); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/temporal/IsoFields.java b/jdk/src/share/classes/java/time/temporal/IsoFields.java index eae057afb2a..bb19c299875 100644 --- a/jdk/src/share/classes/java/time/temporal/IsoFields.java +++ b/jdk/src/share/classes/java/time/temporal/IsoFields.java @@ -684,13 +684,16 @@ public final class IsoFields { } @Override - public long between(Temporal temporal1, Temporal temporal2) { + public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive) { + if (temporal1Inclusive.getClass() != temporal2Exclusive.getClass()) { + return temporal1Inclusive.until(temporal2Exclusive, this); + } switch(this) { case WEEK_BASED_YEARS: - return Math.subtractExact(temporal2.getLong(WEEK_BASED_YEAR), - temporal1.getLong(WEEK_BASED_YEAR)); + return Math.subtractExact(temporal2Exclusive.getLong(WEEK_BASED_YEAR), + temporal1Inclusive.getLong(WEEK_BASED_YEAR)); case QUARTER_YEARS: - return temporal1.until(temporal2, MONTHS) / 3; + return temporal1Inclusive.until(temporal2Exclusive, MONTHS) / 3; default: throw new IllegalStateException("Unreachable"); } diff --git a/jdk/src/share/classes/java/time/temporal/Temporal.java b/jdk/src/share/classes/java/time/temporal/Temporal.java index 54110bed771..9931c46f4f1 100644 --- a/jdk/src/share/classes/java/time/temporal/Temporal.java +++ b/jdk/src/share/classes/java/time/temporal/Temporal.java @@ -374,8 +374,9 @@ public interface Temporal extends TemporalAccessor { * Calculates the amount of time until another temporal in terms of the specified unit. *

    * This calculates the amount of time between two temporal objects - * of the same type in terms of a single {@code TemporalUnit}. + * in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified temporal. + * The end point is converted to be of the same type as the start point if different. * The result will be negative if the end is before the start. * For example, the period in hours between two temporal objects can be * calculated using {@code startTime.until(endTime, HOURS)}. @@ -412,31 +413,36 @@ public interface Temporal extends TemporalAccessor { *

    * If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as + * passing {@code this} as the first argument and the converted input temporal as * the second argument. *

    - * In summary, implementations must behave in a manner equivalent to this code: + * In summary, implementations must behave in a manner equivalent to this pseudo-code: *

    -     *  // check input temporal is the same type as this class
    +     *  // convert the end temporal to the same type as this class
          *  if (unit instanceof ChronoUnit) {
          *    // if unit is supported, then calculate and return result
          *    // else throw UnsupportedTemporalTypeException for unsupported units
          *  }
    -     *  return unit.between(this, endTemporal);
    +     *  return unit.between(this, convertedEndTemporal);
          * 
    *

    + * Note that the unit's {@code between} method must only be invoked if the + * two temporal objects have exactly the same type evaluated by {@code getClass()}. + *

    * Implementations must ensure that no observable state is altered when this * read-only method is invoked. * - * @param endTemporal the end temporal, of the same type as this object, not null + * @param endExclusive the end temporal, exclusive, converted to be of the + * same type as this object, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this temporal object and the specified one * in terms of the unit; positive if the specified object is later than this one, * negative if it is earlier than this one - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to the same type as this temporal * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ - long until(Temporal endTemporal, TemporalUnit unit); + long until(Temporal endExclusive, TemporalUnit unit); } diff --git a/jdk/src/share/classes/java/time/temporal/TemporalUnit.java b/jdk/src/share/classes/java/time/temporal/TemporalUnit.java index 05577d713f8..1c41afa0593 100644 --- a/jdk/src/share/classes/java/time/temporal/TemporalUnit.java +++ b/jdk/src/share/classes/java/time/temporal/TemporalUnit.java @@ -231,7 +231,9 @@ public interface TemporalUnit { * Calculates the amount of time between two temporal objects. *

    * This calculates the amount in terms of this unit. The start and end - * points are supplied as temporal objects and must be of the same type. + * points are supplied as temporal objects and must be of compatible types. + * The implementation will convert the second type to be an instance of the + * first type before the calculating the amount. * The result will be negative if the end is before the start. * For example, the amount in hours between two temporal objects can be * calculated using {@code HOURS.between(startTime, endTime)}. @@ -264,15 +266,22 @@ public interface TemporalUnit { * If the unit is not supported an {@code UnsupportedTemporalTypeException} must be thrown. * Implementations must not alter the specified temporal objects. * - * @param temporal1 the base temporal object, not null - * @param temporal2 the other temporal object, not null - * @return the amount of time between temporal1 and temporal2 in terms of this unit; - * positive if temporal2 is later than temporal1, negative if earlier - * @throws DateTimeException if the amount cannot be calculated + * @implSpec + * Implementations must begin by checking to if the two temporals have the + * same type using {@code getClass()}. If they do not, then the result must be + * obtained by calling {@code temporal1Inclusive.until(temporal2Exclusive, this)}. + * + * @param temporal1Inclusive the base temporal object, not null + * @param temporal2Exclusive the other temporal object, exclusive, not null + * @return the amount of time between temporal1Inclusive and temporal2Exclusive + * in terms of this unit; positive if temporal2Exclusive is later than + * temporal1Inclusive, negative if earlier + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to the same type as the start temporal * @throws UnsupportedTemporalTypeException if the unit is not supported by the temporal * @throws ArithmeticException if numeric overflow occurs */ - long between(Temporal temporal1, Temporal temporal2); + long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive); //----------------------------------------------------------------------- /** diff --git a/jdk/test/java/time/tck/java/time/TCKDuration.java b/jdk/test/java/time/tck/java/time/TCKDuration.java index c3bb0c9c906..c12e914b91f 100644 --- a/jdk/test/java/time/tck/java/time/TCKDuration.java +++ b/jdk/test/java/time/tck/java/time/TCKDuration.java @@ -77,6 +77,7 @@ import java.io.DataOutputStream; import java.time.DateTimeException; import java.time.Duration; import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Period; @@ -843,10 +844,17 @@ public class TCKDuration extends AbstractTCKTest { assertEquals(Duration.between(end, start), Duration.between(start, end).negated()); } - @Test(expectedExceptions=DateTimeException.class) + @Test public void factory_between_TemporalTemporal_mixedTypes() { Instant start = Instant.ofEpochSecond(1); ZonedDateTime end = Instant.ofEpochSecond(4).atZone(ZoneOffset.UTC); + assertEquals(Duration.between(start, end), Duration.ofSeconds(3)); + } + + @Test(expectedExceptions=DateTimeException.class) + public void factory_between_TemporalTemporal_invalidMixedTypes() { + Instant start = Instant.ofEpochSecond(1); + LocalDate end = LocalDate.of(2010, 6, 20); Duration.between(start, end); } diff --git a/jdk/test/java/time/tck/java/time/TCKInstant.java b/jdk/test/java/time/tck/java/time/TCKInstant.java index bb3a765de42..bf6ac9e7026 100644 --- a/jdk/test/java/time/tck/java/time/TCKInstant.java +++ b/jdk/test/java/time/tck/java/time/TCKInstant.java @@ -84,6 +84,7 @@ import java.time.DateTimeException; import java.time.Duration; import java.time.Instant; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.ZoneOffset; @@ -1800,7 +1801,7 @@ public class TCKInstant extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { Instant i1 = Instant.ofEpochSecond(seconds1, nanos1); Instant i2 = Instant.ofEpochSecond(seconds2, nanos2); long amount = i1.until(i2, unit); @@ -1808,25 +1809,46 @@ public class TCKInstant extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { Instant i1 = Instant.ofEpochSecond(seconds1, nanos1); Instant i2 = Instant.ofEpochSecond(seconds2, nanos2); long amount = i2.until(i1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { + Instant i1 = Instant.ofEpochSecond(seconds1, nanos1); + Instant i2 = Instant.ofEpochSecond(seconds2, nanos2); + long amount = unit.between(i1, i2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + Instant start = Instant.ofEpochSecond(12, 3000); + OffsetDateTime end = start.plusSeconds(2).atOffset(ZoneOffset.ofHours(2)); + assertEquals(start.until(end, SECONDS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + Instant start = Instant.ofEpochSecond(12, 3000); + start.until(LocalTime.of(11, 30), SECONDS); + } + @Test(expectedExceptions = UnsupportedTemporalTypeException.class) - public void test_periodUntil_TemporalUnit_unsupportedUnit() { + public void test_until_TemporalUnit_unsupportedUnit() { TEST_12345_123456789.until(TEST_12345_123456789, MONTHS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_12345_123456789.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_12345_123456789.until(TEST_12345_123456789, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDate.java b/jdk/test/java/time/tck/java/time/TCKLocalDate.java index 3d4cbbbc884..cb41a707945 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java @@ -1723,29 +1723,48 @@ public class TCKLocalDate extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { long amount = date1.until(date2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { long amount = date2.until(date1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { + long amount = unit.between(date1, date2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + LocalDate start = LocalDate.of(2010, 6, 30); + OffsetDateTime end = start.plusDays(2).atStartOfDay().atOffset(OFFSET_PONE); + assertEquals(start.until(end, DAYS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + LocalDate start = LocalDate.of(2010, 6, 30); + start.until(LocalTime.of(11, 30), DAYS); + } + @Test(expectedExceptions = UnsupportedTemporalTypeException.class) - public void test_periodUntil_TemporalUnit_unsupportedUnit() { + public void test_until_TemporalUnit_unsupportedUnit() { TEST_2007_07_15.until(TEST_2007_07_15, HOURS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_2007_07_15.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_2007_07_15.until(TEST_2007_07_15, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java index 040704cd9bc..62b53b3b8a3 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java @@ -2895,24 +2895,43 @@ public class TCKLocalDateTime extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { long amount = dt1.until(dt2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { long amount = dt2.until(dt1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { + long amount = unit.between(dt1, dt2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + LocalDateTime start = LocalDateTime.of(2010, 6, 30, 2, 30); + OffsetDateTime end = start.plusDays(2).atOffset(OFFSET_PONE); + assertEquals(start.until(end, DAYS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + LocalDateTime start = LocalDateTime.of(2010, 6, 30, 2, 30); + start.until(LocalTime.of(11, 30), DAYS); + } + @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_2007_07_15_12_30_40_987654321.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_2007_07_15_12_30_40_987654321.until(TEST_2007_07_15_12_30_40_987654321, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/TCKLocalTime.java index 2291b5ca16b..bac3f8587d1 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java @@ -1971,29 +1971,48 @@ public class TCKLocalTime extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { long amount = time1.until(time2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { long amount = time2.until(time1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { + long amount = unit.between(time1, time2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + LocalTime start = LocalTime.of(11, 30); + LocalDateTime end = start.plusSeconds(2).atDate(LocalDate.of(2010, 6, 30)); + assertEquals(start.until(end, SECONDS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + LocalTime start = LocalTime.of(11, 30); + start.until(LocalDate.of(2010, 6, 30), SECONDS); + } + @Test(expectedExceptions = UnsupportedTemporalTypeException.class) - public void test_periodUntil_TemporalUnit_unsupportedUnit() { + public void test_until_TemporalUnit_unsupportedUnit() { TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, DAYS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_12_30_40_987654321.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java index 0cf024fdde1..0ced814d06b 100644 --- a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java @@ -91,6 +91,13 @@ import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.FOREVER; +import static java.time.temporal.ChronoUnit.HALF_DAYS; +import static java.time.temporal.ChronoUnit.HOURS; +import static java.time.temporal.ChronoUnit.MICROS; +import static java.time.temporal.ChronoUnit.MILLIS; +import static java.time.temporal.ChronoUnit.MINUTES; +import static java.time.temporal.ChronoUnit.MONTHS; import static java.time.temporal.ChronoUnit.NANOS; import static java.time.temporal.ChronoUnit.SECONDS; import static org.testng.Assert.assertEquals; @@ -1128,6 +1135,74 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { assertEquals(test, OffsetDateTime.of(2008, 6, 30, 11, 30, 58, 999999999, OFFSET_PONE)); } + //----------------------------------------------------------------------- + // until(Temporal, TemporalUnit) + //----------------------------------------------------------------------- + @DataProvider(name="periodUntilUnit") + Object[][] data_untilUnit() { + return new Object[][] { + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 13, 1, 1, 0, OFFSET_PONE), HALF_DAYS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), HOURS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), MINUTES, 60}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), SECONDS, 3600}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), MILLIS, 3600*1000}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), MICROS, 3600*1000*1000L}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), NANOS, 3600*1000*1000L*1000}, + + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 14, 1, 1, 0, OFFSET_PTWO), HALF_DAYS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), HOURS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), MINUTES, 60}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), SECONDS, 3600}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), MILLIS, 3600*1000}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), MICROS, 3600*1000*1000L}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), NANOS, 3600*1000*1000L*1000}, + + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 7, 1, 1, 1, 0, 999999999, OFFSET_PONE), DAYS, 0}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 7, 1, 1, 1, 1, 0, OFFSET_PONE), DAYS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 8, 29, 1, 1, 1, 0, OFFSET_PONE), MONTHS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 8, 30, 1, 1, 1, 0, OFFSET_PONE), MONTHS, 2}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 8, 31, 1, 1, 1, 0, OFFSET_PONE), MONTHS, 2}, + }; + } + + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit(OffsetDateTime odt1, OffsetDateTime odt2, TemporalUnit unit, long expected) { + long amount = odt1.until(odt2, unit); + assertEquals(amount, expected); + } + + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_negated(OffsetDateTime odt1, OffsetDateTime odt2, TemporalUnit unit, long expected) { + long amount = odt2.until(odt1, unit); + assertEquals(amount, -expected); + } + + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(OffsetDateTime odt1, OffsetDateTime odt2, TemporalUnit unit, long expected) { + long amount = unit.between(odt1, odt2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + OffsetDateTime odt = OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE); + ZonedDateTime zdt = odt.plusSeconds(3).toZonedDateTime(); + assertEquals(odt.until(zdt, SECONDS), 3); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + OffsetDateTime odt = OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE); + odt.until(Instant.ofEpochSecond(12), SECONDS); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidTemporalUnit() { + OffsetDateTime odt1 = OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE); + OffsetDateTime odt2 = OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE); + odt1.until(odt2, FOREVER); + } + //----------------------------------------------------------------------- // format(DateTimeFormatter) //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java index ee5b2d3f69f..5bc2312ea0f 100644 --- a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java +++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java @@ -1069,49 +1069,61 @@ public class TCKOffsetTime extends AbstractDateTimeTest { // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") - Object[][] data_periodUntilUnit() { + Object[][] data_untilUnit() { return new Object[][] { - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(13, 1, 1), ZoneOffset.ofHours(1)), HALF_DAYS, 1}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), HOURS, 1}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MINUTES, 60}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), SECONDS, 3600}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MILLIS, 3600*1000}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MICROS, 3600*1000*1000L}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), NANOS, 3600*1000*1000L*1000}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(13, 1, 1, 0, OFFSET_PONE), HALF_DAYS, 1}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), HOURS, 1}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), MINUTES, 60}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), SECONDS, 3600}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), MILLIS, 3600*1000}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), MICROS, 3600*1000*1000L}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), NANOS, 3600*1000*1000L*1000}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(14, 1, 1), ZoneOffset.ofHours(2)), HALF_DAYS, 1}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), HOURS, 1}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MINUTES, 60}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), SECONDS, 3600}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MILLIS, 3600*1000}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MICROS, 3600*1000*1000L}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), NANOS, 3600*1000*1000L*1000}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(14, 1, 1, 0, OFFSET_PTWO), HALF_DAYS, 1}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), HOURS, 1}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), MINUTES, 60}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), SECONDS, 3600}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), MILLIS, 3600*1000}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), MICROS, 3600*1000*1000L}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), NANOS, 3600*1000*1000L*1000}, }; } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { long amount = offsetTime1.until(offsetTime2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { long amount = offsetTime2.until(offsetTime1, unit); assertEquals(amount, -expected); } - @Test(expectedExceptions=DateTimeException.class) - public void test_periodUntil_InvalidType() { - OffsetTime offsetTime = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)); - OffsetDateTime offsetDateTime = offsetTime.atDate(LocalDate.of(1980, 2, 10)); - offsetTime.until(offsetDateTime, SECONDS); + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { + long amount = unit.between(offsetTime1, offsetTime2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + OffsetTime offsetTime = OffsetTime.of(1, 1, 1, 0, OFFSET_PONE); + OffsetDateTime offsetDateTime = offsetTime.plusSeconds(3).atDate(LocalDate.of(1980, 2, 10)); + assertEquals(offsetTime.until(offsetDateTime, SECONDS), 3); } @Test(expectedExceptions=DateTimeException.class) - public void test_periodUntil_InvalidTemporalUnit() { - OffsetTime offsetTime1 = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)); - OffsetTime offsetTime2 = OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)); + public void test_until_invalidType() { + OffsetTime offsetTime = OffsetTime.of(1, 1, 1, 0, OFFSET_PONE); + offsetTime.until(LocalDate.of(1980, 2, 10), SECONDS); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidTemporalUnit() { + OffsetTime offsetTime1 = OffsetTime.of(1, 1, 1, 0, OFFSET_PONE); + OffsetTime offsetTime2 = OffsetTime.of(2, 1, 1, 0, OFFSET_PONE); offsetTime1.until(offsetTime2, MONTHS); } diff --git a/jdk/test/java/time/tck/java/time/TCKYear.java b/jdk/test/java/time/tck/java/time/TCKYear.java index c0a35967a7b..59d464a5373 100644 --- a/jdk/test/java/time/tck/java/time/TCKYear.java +++ b/jdk/test/java/time/tck/java/time/TCKYear.java @@ -65,10 +65,8 @@ import static java.time.temporal.ChronoField.YEAR_OF_ERA; import static java.time.temporal.ChronoUnit.CENTURIES; import static java.time.temporal.ChronoUnit.DAYS; import static java.time.temporal.ChronoUnit.DECADES; -import static java.time.temporal.ChronoUnit.HOURS; import static java.time.temporal.ChronoUnit.MILLENNIA; import static java.time.temporal.ChronoUnit.MONTHS; -import static java.time.temporal.ChronoUnit.WEEKS; import static java.time.temporal.ChronoUnit.YEARS; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -90,8 +88,8 @@ import java.time.Year; import java.time.YearMonth; import java.time.ZoneId; import java.time.ZoneOffset; -import java.time.chrono.IsoEra; import java.time.chrono.IsoChronology; +import java.time.chrono.IsoEra; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoField; @@ -229,17 +227,17 @@ public class TCKYear extends AbstractDateTimeTest { //----------------------------------------------------------------------- @Test - public void test_factory_CalendricalObject() { + public void test_from_TemporalAccessor() { assertEquals(Year.from(LocalDate.of(2007, 7, 15)), Year.of(2007)); } @Test(expectedExceptions=DateTimeException.class) - public void test_factory_CalendricalObject_invalid_noDerive() { + public void test_from_TemporalAccessor_invalid_noDerive() { Year.from(LocalTime.of(12, 30)); } @Test(expectedExceptions=NullPointerException.class) - public void test_factory_CalendricalObject_null() { + public void test_from_TemporalAccessor_null() { Year.from((TemporalAccessor) null); } @@ -597,13 +595,13 @@ public class TCKYear extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="plus_long_TemporalUnit") + @Test(dataProvider="plus_long_TemporalUnit") public void test_plus_long_TemporalUnit(Year base, long amount, TemporalUnit unit, Year expectedYear, Class expectedEx) { if (expectedEx == null) { assertEquals(base.plus(amount, unit), expectedYear); } else { try { - Year result = base.plus(amount, unit); + base.plus(amount, unit); fail(); } catch (Exception ex) { assertTrue(expectedEx.isInstance(ex)); @@ -729,7 +727,7 @@ public class TCKYear extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="minus_long_TemporalUnit") + @Test(dataProvider="minus_long_TemporalUnit") public void test_minus_long_TemporalUnit(Year base, long amount, TemporalUnit unit, Year expectedYear, Class expectedEx) { if (expectedEx == null) { assertEquals(base.minus(amount, unit), expectedYear); @@ -788,7 +786,7 @@ public class TCKYear extends AbstractDateTimeTest { //----------------------------------------------------------------------- // with(TemporalField, long) //----------------------------------------------------------------------- - @Test(groups={"tck"}) + @Test public void test_with() { Year base = Year.of(5); Year result = base.with(ChronoField.ERA, 0); @@ -923,29 +921,48 @@ public class TCKYear extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(Year year1, Year year2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(Year year1, Year year2, TemporalUnit unit, long expected) { long amount = year1.until(year2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(Year year1, Year year2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(Year year1, Year year2, TemporalUnit unit, long expected) { long amount = year2.until(year1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(Year year1, Year year2, TemporalUnit unit, long expected) { + long amount = unit.between(year1, year2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + Year start = Year.of(2010); + YearMonth end = start.plusYears(2).atMonth(Month.APRIL); + assertEquals(start.until(end, YEARS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + Year start = Year.of(2010); + start.until(LocalTime.of(11, 30), YEARS); + } + @Test(expectedExceptions = UnsupportedTemporalTypeException.class) - public void test_periodUntil_TemporalUnit_unsupportedUnit() { + public void test_until_TemporalUnit_unsupportedUnit() { TEST_2008.until(TEST_2008, MONTHS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_2008.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_2008.until(TEST_2008, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKYearMonth.java b/jdk/test/java/time/tck/java/time/TCKYearMonth.java index e1f1a466574..bb16839bda1 100644 --- a/jdk/test/java/time/tck/java/time/TCKYearMonth.java +++ b/jdk/test/java/time/tck/java/time/TCKYearMonth.java @@ -70,7 +70,6 @@ import static java.time.temporal.ChronoUnit.DECADES; import static java.time.temporal.ChronoUnit.HOURS; import static java.time.temporal.ChronoUnit.MILLENNIA; import static java.time.temporal.ChronoUnit.MONTHS; -import static java.time.temporal.ChronoUnit.WEEKS; import static java.time.temporal.ChronoUnit.YEARS; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -270,17 +269,17 @@ public class TCKYearMonth extends AbstractDateTimeTest { //----------------------------------------------------------------------- @Test - public void test_factory_CalendricalObject() { + public void test_from_TemporalAccessor() { assertEquals(YearMonth.from(LocalDate.of(2007, 7, 15)), YearMonth.of(2007, 7)); } @Test(expectedExceptions=DateTimeException.class) - public void test_factory_CalendricalObject_invalid_noDerive() { + public void test_from_TemporalAccessor_invalid_noDerive() { YearMonth.from(LocalTime.of(12, 30)); } @Test(expectedExceptions=NullPointerException.class) - public void test_factory_CalendricalObject_null() { + public void test_from_TemporalAccessor_null() { YearMonth.from((TemporalAccessor) null); } @@ -768,7 +767,7 @@ public class TCKYearMonth extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="plus_long_TemporalUnit") + @Test(dataProvider="plus_long_TemporalUnit") public void test_plus_long_TemporalUnit(YearMonth base, long amount, TemporalUnit unit, YearMonth expectedYearMonth, Class expectedEx) { if (expectedEx == null) { assertEquals(base.plus(amount, unit), expectedYearMonth); @@ -820,7 +819,7 @@ public class TCKYearMonth extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="plus_TemporalAmount") + @Test(dataProvider="plus_TemporalAmount") public void test_plus_TemporalAmount(YearMonth base, TemporalAmount temporalAmount, YearMonth expectedYearMonth, Class expectedEx) { if (expectedEx == null) { assertEquals(base.plus(temporalAmount), expectedYearMonth); @@ -983,7 +982,7 @@ public class TCKYearMonth extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="minus_long_TemporalUnit") + @Test(dataProvider="minus_long_TemporalUnit") public void test_minus_long_TemporalUnit(YearMonth base, long amount, TemporalUnit unit, YearMonth expectedYearMonth, Class expectedEx) { if (expectedEx == null) { assertEquals(base.minus(amount, unit), expectedYearMonth); @@ -1035,7 +1034,7 @@ public class TCKYearMonth extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="minus_TemporalAmount") + @Test(dataProvider="minus_TemporalAmount") public void test_minus_TemporalAmount(YearMonth base, TemporalAmount temporalAmount, YearMonth expectedYearMonth, Class expectedEx) { if (expectedEx == null) { assertEquals(base.minus(temporalAmount), expectedYearMonth); @@ -1243,29 +1242,48 @@ public class TCKYearMonth extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { long amount = ym1.until(ym2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { long amount = ym2.until(ym1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { + long amount = unit.between(ym1, ym2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + YearMonth start = YearMonth.of(2010, 6); + LocalDate end = start.plusMonths(2).atDay(12); + assertEquals(start.until(end, MONTHS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + YearMonth start = YearMonth.of(2010, 6); + start.until(LocalTime.of(11, 30), MONTHS); + } + @Test(expectedExceptions = UnsupportedTemporalTypeException.class) - public void test_periodUntil_TemporalUnit_unsupportedUnit() { + public void test_until_TemporalUnit_unsupportedUnit() { TEST_2008_06.until(TEST_2008_06, HOURS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_2008_06.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_2008_06.until(TEST_2008_06, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java index 1f5bee32283..4c5319d483a 100644 --- a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java @@ -2001,7 +2001,7 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { // compare results to OffsetDateTime.until, especially wrt dates @Test(dataProvider="plusDays") - public void test_periodUntil_days(ZonedDateTime base, long expected, ZonedDateTime end) { + public void test_until_days(ZonedDateTime base, long expected, ZonedDateTime end) { if (base.toLocalTime().equals(end.toLocalTime()) == false) { return; // avoid DST gap input values } @@ -2009,27 +2009,27 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { } @Test(dataProvider="plusTime") - public void test_periodUntil_hours(ZonedDateTime base, long expected, ZonedDateTime end) { + public void test_until_hours(ZonedDateTime base, long expected, ZonedDateTime end) { assertEquals(base.until(end, HOURS), expected); } @Test(dataProvider="plusTime") - public void test_periodUntil_minutes(ZonedDateTime base, long expected, ZonedDateTime end) { + public void test_until_minutes(ZonedDateTime base, long expected, ZonedDateTime end) { assertEquals(base.until(end, MINUTES), expected * 60); } @Test(dataProvider="plusTime") - public void test_periodUntil_seconds(ZonedDateTime base, long expected, ZonedDateTime end) { + public void test_until_seconds(ZonedDateTime base, long expected, ZonedDateTime end) { assertEquals(base.until(end, SECONDS), expected * 3600); } @Test(dataProvider="plusTime") - public void test_periodUntil_nanos(ZonedDateTime base, long expected, ZonedDateTime end) { + public void test_until_nanos(ZonedDateTime base, long expected, ZonedDateTime end) { assertEquals(base.until(end, NANOS), expected * 3600_000_000_000L); } @Test - public void test_periodUntil_parisLondon() { + public void test_until_parisLondon() { ZonedDateTime midnightLondon = LocalDate.of(2012, 6, 28).atStartOfDay(ZONE_LONDON); ZonedDateTime midnightParis1 = LocalDate.of(2012, 6, 29).atStartOfDay(ZONE_PARIS); ZonedDateTime oneAm1 = LocalDateTime.of(2012, 6, 29, 1, 0).atZone(ZONE_PARIS); @@ -2045,7 +2045,7 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { } @Test - public void test_periodUntil_gap() { + public void test_until_gap() { ZonedDateTime before = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS); ZonedDateTime after = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS); @@ -2054,7 +2054,7 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { } @Test - public void test_periodUntil_overlap() { + public void test_until_overlap() { ZonedDateTime before = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS); ZonedDateTime after = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS); @@ -2063,17 +2063,17 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { } @Test(expectedExceptions=DateTimeException.class) - public void test_periodUntil_differentType() { + public void test_until_differentType() { TEST_DATE_TIME_PARIS.until(TEST_LOCAL_2008_06_30_11_30_59_500, DAYS); } @Test(expectedExceptions=NullPointerException.class) - public void test_periodUntil_nullTemporal() { + public void test_until_nullTemporal() { TEST_DATE_TIME_PARIS.until(null, DAYS); } @Test(expectedExceptions=NullPointerException.class) - public void test_periodUntil_nullUnit() { + public void test_until_nullUnit() { TEST_DATE_TIME_PARIS.until(TEST_DATE_TIME_PARIS, null); } diff --git a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java index 6377c1fc421..c0da6975623 100644 --- a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java +++ b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java @@ -297,18 +297,12 @@ public final class CopticDate } @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof ChronoLocalDate == false) { - throw new DateTimeException("Unable to calculate period between objects of two different types"); - } - ChronoLocalDate end = (ChronoLocalDate) endDateTime; - if (getChronology().equals(end.getChronology()) == false) { - throw new DateTimeException("Unable to calculate period between two different chronologies"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + CopticDate end = getChronology().date(endExclusive); if (unit instanceof ChronoUnit) { return LocalDate.from(this).until(end, unit); // TODO: this is wrong } - return unit.between(this, endDateTime); + return unit.between(this, end); } @Override diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java index 7159b312866..d607571aba1 100644 --- a/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java +++ b/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java @@ -70,11 +70,13 @@ import static org.testng.Assert.fail; import java.time.DayOfWeek; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; import java.time.format.ResolverStyle; import java.time.temporal.IsoFields; +import java.time.temporal.Temporal; import java.time.temporal.ValueRange; import org.testng.annotations.DataProvider; @@ -276,14 +278,21 @@ public class TCKIsoFields { {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 12, 31), -4}, {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 10, 2), -4}, {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 10, 1), -5}, + + {LocalDate.of(2000, 1, 1), LocalDateTime.of(2001, 4, 5, 0, 0), 5}, }; } @Test(dataProvider="quartersBetween") - public void test_quarters_between(LocalDate start, LocalDate end, long expected) { + public void test_quarters_between(LocalDate start, Temporal end, long expected) { assertEquals(IsoFields.QUARTER_YEARS.between(start, end), expected); } + @Test(dataProvider="quartersBetween") + public void test_quarters_between_until(LocalDate start, Temporal end, long expected) { + assertEquals(start.until(end, IsoFields.QUARTER_YEARS), expected); + } + //----------------------------------------------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- From d18aae693d00009b2e91a3a852210c7fd4ff09b8 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Fri, 4 Oct 2013 12:01:29 -0400 Subject: [PATCH 0365/1294] 8024999: Instant.Parse typo in example Javadoc only fix to correct example to use "." and "Z" Reviewed-by: sherman --- jdk/src/share/classes/java/time/Instant.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/time/Instant.java b/jdk/src/share/classes/java/time/Instant.java index a7bd6f92004..0e22c7bf972 100644 --- a/jdk/src/share/classes/java/time/Instant.java +++ b/jdk/src/share/classes/java/time/Instant.java @@ -374,7 +374,7 @@ public final class Instant //----------------------------------------------------------------------- /** * Obtains an instance of {@code Instant} from a text string such as - * {@code 2007-12-03T10:15:30:00}. + * {@code 2007-12-03T10:15:30.00Z}. *

    * The string must represent a valid instant in UTC and is parsed using * {@link DateTimeFormatter#ISO_INSTANT}. From 2040c66b16231be86df4e288dcd1b79ae8790df2 Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Sat, 14 Sep 2013 22:50:40 +0100 Subject: [PATCH 0366/1294] 8024807: Add getChronlogy() to CLDT/CZDT Alternative to method is clunky and hard to find Reviewed-by: sherman --- .../java/time/chrono/ChronoLocalDateTime.java | 24 ++++++++++++++----- .../time/chrono/ChronoLocalDateTimeImpl.java | 6 ++--- .../java/time/chrono/ChronoZonedDateTime.java | 24 ++++++++++++++----- .../time/chrono/ChronoZonedDateTimeImpl.java | 12 +++++----- .../time/chrono/TCKChronoLocalDateTime.java | 7 ++++++ .../time/chrono/TCKChronoZonedDateTime.java | 7 ++++++ 6 files changed, 59 insertions(+), 21 deletions(-) diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java index cde8a982fbc..4c2ddfd31a7 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java @@ -174,6 +174,18 @@ public interface ChronoLocalDateTime } //----------------------------------------------------------------------- + /** + * Gets the chronology of this date-time. + *

    + * The {@code Chronology} represents the calendar system in use. + * The era and other fields in {@link ChronoField} are defined by the chronology. + * + * @return the chronology, not null + */ + default Chronology getChronology() { + return toLocalDate().getChronology(); + } + /** * Gets the local date part of this date-time. *

    @@ -251,7 +263,7 @@ public interface ChronoLocalDateTime */ @Override default ChronoLocalDateTime with(TemporalAdjuster adjuster) { - return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.with(adjuster)); + return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); } /** @@ -269,7 +281,7 @@ public interface ChronoLocalDateTime */ @Override default ChronoLocalDateTime plus(TemporalAmount amount) { - return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.plus(amount)); + return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); } /** @@ -287,7 +299,7 @@ public interface ChronoLocalDateTime */ @Override default ChronoLocalDateTime minus(TemporalAmount amount) { - return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amount)); + return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); } /** @@ -297,7 +309,7 @@ public interface ChronoLocalDateTime */ @Override default ChronoLocalDateTime minus(long amountToSubtract, TemporalUnit unit) { - return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amountToSubtract, unit)); + return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- @@ -327,7 +339,7 @@ public interface ChronoLocalDateTime } else if (query == TemporalQuery.localTime()) { return (R) toLocalTime(); } else if (query == TemporalQuery.chronology()) { - return (R) toLocalDate().getChronology(); + return (R) getChronology(); } else if (query == TemporalQuery.precision()) { return (R) NANOS; } @@ -489,7 +501,7 @@ public interface ChronoLocalDateTime if (cmp == 0) { cmp = toLocalTime().compareTo(other.toLocalTime()); if (cmp == 0) { - cmp = toLocalDate().getChronology().compareTo(other.toLocalDate().getChronology()); + cmp = getChronology().compareTo(other.getChronology()); } } return cmp; diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java index 817ae85411a..e33e82ebab2 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java @@ -186,9 +186,9 @@ final class ChronoLocalDateTimeImpl static ChronoLocalDateTimeImpl ensureValid(Chronology chrono, Temporal temporal) { @SuppressWarnings("unchecked") ChronoLocalDateTimeImpl other = (ChronoLocalDateTimeImpl) temporal; - if (chrono.equals(other.toLocalDate().getChronology()) == false) { + if (chrono.equals(other.getChronology()) == false) { throw new ClassCastException("Chronology mismatch, required: " + chrono.getId() - + ", actual: " + other.toLocalDate().getChronology().getId()); + + ", actual: " + other.getChronology().getId()); } return other; } @@ -371,7 +371,7 @@ final class ChronoLocalDateTimeImpl public long until(Temporal endExclusive, TemporalUnit unit) { Objects.requireNonNull(endExclusive, "endExclusive"); @SuppressWarnings("unchecked") - ChronoLocalDateTime end = (ChronoLocalDateTime) toLocalDate().getChronology().localDateTime(endExclusive); + ChronoLocalDateTime end = (ChronoLocalDateTime) getChronology().localDateTime(endExclusive); if (unit instanceof ChronoUnit) { if (unit.isTimeBased()) { long amount = end.getLong(EPOCH_DAY) - date.getLong(EPOCH_DAY); diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java index abe84799716..033ab997fdd 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java @@ -246,6 +246,18 @@ public interface ChronoZonedDateTime */ ChronoLocalDateTime toLocalDateTime(); + /** + * Gets the chronology of this date-time. + *

    + * The {@code Chronology} represents the calendar system in use. + * The era and other fields in {@link ChronoField} are defined by the chronology. + * + * @return the chronology, not null + */ + default Chronology getChronology() { + return toLocalDate().getChronology(); + } + /** * Gets the zone offset, such as '+01:00'. *

    @@ -398,7 +410,7 @@ public interface ChronoZonedDateTime */ @Override default ChronoZonedDateTime with(TemporalAdjuster adjuster) { - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.with(adjuster)); + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); } /** @@ -416,7 +428,7 @@ public interface ChronoZonedDateTime */ @Override default ChronoZonedDateTime plus(TemporalAmount amount) { - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.plus(amount)); + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); } /** @@ -434,7 +446,7 @@ public interface ChronoZonedDateTime */ @Override default ChronoZonedDateTime minus(TemporalAmount amount) { - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amount)); + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); } /** @@ -444,7 +456,7 @@ public interface ChronoZonedDateTime */ @Override default ChronoZonedDateTime minus(long amountToSubtract, TemporalUnit unit) { - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amountToSubtract, unit)); + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- @@ -476,7 +488,7 @@ public interface ChronoZonedDateTime } else if (query == TemporalQuery.localTime()) { return (R) toLocalTime(); } else if (query == TemporalQuery.chronology()) { - return (R) toLocalDate().getChronology(); + return (R) getChronology(); } else if (query == TemporalQuery.precision()) { return (R) NANOS; } @@ -563,7 +575,7 @@ public interface ChronoZonedDateTime if (cmp == 0) { cmp = getZone().getId().compareTo(other.getZone().getId()); if (cmp == 0) { - cmp = toLocalDate().getChronology().compareTo(other.toLocalDate().getChronology()); + cmp = getChronology().compareTo(other.getChronology()); } } } diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java index 1fe8ccf0192..5222db367f2 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java @@ -185,7 +185,7 @@ final class ChronoZonedDateTimeImpl */ @SuppressWarnings("unchecked") private ChronoZonedDateTimeImpl create(Instant instant, ZoneId zone) { - return (ChronoZonedDateTimeImpl)ofInstant(toLocalDate().getChronology(), instant, zone); + return (ChronoZonedDateTimeImpl)ofInstant(getChronology(), instant, zone); } /** @@ -200,9 +200,9 @@ final class ChronoZonedDateTimeImpl static ChronoZonedDateTimeImpl ensureValid(Chronology chrono, Temporal temporal) { @SuppressWarnings("unchecked") ChronoZonedDateTimeImpl other = (ChronoZonedDateTimeImpl) temporal; - if (chrono.equals(other.toLocalDate().getChronology()) == false) { + if (chrono.equals(other.getChronology()) == false) { throw new ClassCastException("Chronology mismatch, required: " + chrono.getId() - + ", actual: " + other.toLocalDate().getChronology().getId()); + + ", actual: " + other.getChronology().getId()); } return other; } @@ -293,7 +293,7 @@ final class ChronoZonedDateTimeImpl } return ofBest(dateTime.with(field, newValue), zone, offset); } - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), field.adjustInto(this, newValue)); + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), field.adjustInto(this, newValue)); } //----------------------------------------------------------------------- @@ -302,7 +302,7 @@ final class ChronoZonedDateTimeImpl if (unit instanceof ChronoUnit) { return with(dateTime.plus(amountToAdd, unit)); } - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), unit.addTo(this, amountToAdd)); /// TODO: Generics replacement Risk! + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd)); /// TODO: Generics replacement Risk! } //----------------------------------------------------------------------- @@ -310,7 +310,7 @@ final class ChronoZonedDateTimeImpl public long until(Temporal endExclusive, TemporalUnit unit) { Objects.requireNonNull(endExclusive, "endExclusive"); @SuppressWarnings("unchecked") - ChronoZonedDateTime end = (ChronoZonedDateTime) toLocalDate().getChronology().zonedDateTime(endExclusive); + ChronoZonedDateTime end = (ChronoZonedDateTime) getChronology().zonedDateTime(endExclusive); if (unit instanceof ChronoUnit) { end = end.withZoneSameInstant(offset); return dateTime.until(end.toLocalDateTime(), unit); diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java index 7ca03e2e3fb..51b68bb7c1f 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java @@ -343,6 +343,13 @@ public class TCKChronoLocalDateTime { ChronoLocalDateTime.from(null); } + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_getChronology(Chronology chrono) { + ChronoLocalDateTime test = chrono.localDateTime(LocalDateTime.of(2010, 6, 30, 11, 30)); + assertEquals(test.getChronology(), chrono); + } + //----------------------------------------------------------------------- /** * FixedAdjusted returns a fixed Temporal in all adjustments. diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java index b2b7fc2cc6c..0cabccab036 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java @@ -344,6 +344,13 @@ public class TCKChronoZonedDateTime { ChronoZonedDateTime.from(null); } + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_getChronology(Chronology chrono) { + ChronoZonedDateTime test = chrono.zonedDateTime(ZonedDateTime.of(2010, 6, 30, 11, 30, 0, 0, ZoneOffset.UTC)); + assertEquals(test.getChronology(), chrono); + } + //----------------------------------------------------------------------- /** * FixedAdjusted returns a fixed Temporal in all adjustments. From ea9e3930af2c8ff70178064b53b9455424ffe55b Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Sat, 14 Sep 2013 22:54:38 +0100 Subject: [PATCH 0367/1294] 8024834: Better return type for TemporalField resolve Allow resolve method to return more than just ChronoLocalDate Reviewed-by: sherman --- .../classes/java/time/format/Parsed.java | 40 +++- .../java/time/temporal/TemporalField.java | 11 +- .../time/format/TCKDateTimeParseResolver.java | 219 ++++++++++++++++++ 3 files changed, 260 insertions(+), 10 deletions(-) diff --git a/jdk/src/share/classes/java/time/format/Parsed.java b/jdk/src/share/classes/java/time/format/Parsed.java index 42223d6c1d9..7413467826d 100644 --- a/jdk/src/share/classes/java/time/format/Parsed.java +++ b/jdk/src/share/classes/java/time/format/Parsed.java @@ -83,6 +83,8 @@ import java.time.LocalTime; import java.time.Period; import java.time.ZoneId; import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoZonedDateTime; import java.time.chrono.Chronology; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; @@ -260,11 +262,34 @@ final class Parsed implements TemporalAccessor { while (changedCount < 50) { for (Map.Entry entry : fieldValues.entrySet()) { TemporalField targetField = entry.getKey(); - ChronoLocalDate resolvedDate = targetField.resolve(fieldValues, chrono, zone, resolverStyle); - if (resolvedDate != null) { - updateCheckConflict(resolvedDate); - changedCount++; - continue outer; // have to restart to avoid concurrent modification + TemporalAccessor resolvedObject = targetField.resolve(fieldValues, chrono, zone, resolverStyle); + if (resolvedObject != null) { + if (resolvedObject instanceof ChronoZonedDateTime) { + ChronoZonedDateTime czdt = (ChronoZonedDateTime) resolvedObject; + if (zone.equals(czdt.getZone()) == false) { + throw new DateTimeException("ChronoZonedDateTime must use the effective parsed zone: " + zone); + } + resolvedObject = czdt.toLocalDateTime(); + } + if (resolvedObject instanceof ChronoLocalDateTime) { + ChronoLocalDateTime cldt = (ChronoLocalDateTime) resolvedObject; + updateCheckConflict(cldt.toLocalTime(), Period.ZERO); + updateCheckConflict(cldt.toLocalDate()); + changedCount++; + continue outer; // have to restart to avoid concurrent modification + } + if (resolvedObject instanceof ChronoLocalDate) { + updateCheckConflict((ChronoLocalDate) resolvedObject); + changedCount++; + continue outer; // have to restart to avoid concurrent modification + } + if (resolvedObject instanceof LocalTime) { + updateCheckConflict((LocalTime) resolvedObject, Period.ZERO); + changedCount++; + continue outer; // have to restart to avoid concurrent modification + } + throw new DateTimeException("Method resolveFields() can only return ChronoZonedDateTime," + + "ChronoLocalDateTime, ChronoLocalDate or LocalTime"); } else if (fieldValues.containsKey(targetField) == false) { changedCount++; continue outer; // have to restart to avoid concurrent modification @@ -302,7 +327,10 @@ final class Parsed implements TemporalAccessor { if (cld != null && date.equals(cld) == false) { throw new DateTimeException("Conflict found: Fields resolved to two different dates: " + date + " " + cld); } - } else { + } else if (cld != null) { + if (chrono.equals(cld.getChronology()) == false) { + throw new DateTimeException("ChronoLocalDate must use the effective parsed chronology: " + chrono); + } date = cld; } } diff --git a/jdk/src/share/classes/java/time/temporal/TemporalField.java b/jdk/src/share/classes/java/time/temporal/TemporalField.java index e4d6b407783..e757734510c 100644 --- a/jdk/src/share/classes/java/time/temporal/TemporalField.java +++ b/jdk/src/share/classes/java/time/temporal/TemporalField.java @@ -63,7 +63,6 @@ package java.time.temporal; import java.time.DateTimeException; import java.time.ZoneId; -import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; import java.time.format.ResolverStyle; import java.util.Locale; @@ -350,6 +349,10 @@ public interface TemporalField { * be acceptable for the date fields to be resolved into other {@code ChronoField} * instances that can produce a date, such as {@code EPOCH_DAY}. *

    + * Not all {@code TemporalAccessor} implementations are accepted as return values. + * Implementations must accept {@code ChronoLocalDate}, {@code ChronoLocalDateTime}, + * {@code ChronoZonedDateTime} and {@code LocalTime}. + *

    * The zone is not normally required for resolution, but is provided for completeness. *

    * The default implementation must return null. @@ -358,13 +361,13 @@ public interface TemporalField { * @param chronology the effective chronology, not null * @param zone the effective zone, not null * @param resolverStyle the requested type of resolve, not null - * @return the resolved date; null if resolving only changed the map, - * or no resolve occurred + * @return the resolved temporal object; null if resolving only + * changed the map, or no resolve occurred * @throws ArithmeticException if numeric overflow occurs * @throws DateTimeException if resolving results in an error. This must not be thrown * by querying a field on the temporal without first checking if it is supported */ - default ChronoLocalDate resolve( + default TemporalAccessor resolve( Map fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { return null; diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java index 9b249f19224..4ef01317b2e 100644 --- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java +++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java @@ -90,20 +90,33 @@ import static java.time.temporal.ChronoField.SECOND_OF_DAY; import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.FOREVER; +import static java.time.temporal.ChronoUnit.NANOS; import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Period; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.chrono.Chronology; +import java.time.chrono.ThaiBuddhistChronology; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; import java.time.format.ResolverStyle; +import java.time.temporal.ChronoUnit; import java.time.temporal.IsoFields; +import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.TemporalUnit; +import java.time.temporal.ValueRange; +import java.util.Map; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -872,4 +885,210 @@ public class TCKDateTimeParseResolver { } } + //----------------------------------------------------------------------- + @Test + public void test_fieldResolvesToLocalTime() { + TemporalField field = new TemporalField() { + @Override + public TemporalUnit getBaseUnit() { + throw new UnsupportedOperationException(); + } + @Override + public TemporalUnit getRangeUnit() { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange range() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isDateBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isTimeBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isSupportedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange rangeRefinedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public long getFrom(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public R adjustInto(R temporal, long newValue) { + throw new UnsupportedOperationException(); + } + @Override + public TemporalAccessor resolve( + Map fieldValues, Chronology chronology, + ZoneId zone, ResolverStyle resolverStyle) { + return LocalTime.MIDNIGHT.plusNanos(fieldValues.remove(this)); + } + }; + DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter(); + TemporalAccessor accessor = f.parse("1234567890"); + assertEquals(accessor.query(TemporalQuery.localDate()), null); + assertEquals(accessor.query(TemporalQuery.localTime()), LocalTime.of(0, 0, 1, 234_567_890)); + } + + @Test + public void test_fieldResolvesToChronoLocalDateTime() { + TemporalField field = new TemporalField() { + @Override + public TemporalUnit getBaseUnit() { + throw new UnsupportedOperationException(); + } + @Override + public TemporalUnit getRangeUnit() { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange range() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isDateBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isTimeBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isSupportedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange rangeRefinedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public long getFrom(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public R adjustInto(R temporal, long newValue) { + throw new UnsupportedOperationException(); + } + @Override + public TemporalAccessor resolve( + Map fieldValues, Chronology chronology, + ZoneId zone, ResolverStyle resolverStyle) { + fieldValues.remove(this); + return LocalDateTime.of(2010, 6, 30, 12, 30); + } + }; + DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter(); + TemporalAccessor accessor = f.parse("1234567890"); + assertEquals(accessor.query(TemporalQuery.localDate()), LocalDate.of(2010, 6, 30)); + assertEquals(accessor.query(TemporalQuery.localTime()), LocalTime.of(12, 30)); + } + + @Test(expectedExceptions = DateTimeParseException.class) + public void test_fieldResolvesWrongChrono() { + TemporalField field = new TemporalField() { + @Override + public TemporalUnit getBaseUnit() { + throw new UnsupportedOperationException(); + } + @Override + public TemporalUnit getRangeUnit() { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange range() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isDateBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isTimeBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isSupportedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange rangeRefinedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public long getFrom(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public R adjustInto(R temporal, long newValue) { + throw new UnsupportedOperationException(); + } + @Override + public TemporalAccessor resolve( + Map fieldValues, Chronology chronology, + ZoneId zone, ResolverStyle resolverStyle) { + return ThaiBuddhistChronology.INSTANCE.dateNow(); + } + }; + DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter(); + f.parse("1234567890"); + } + + @Test(expectedExceptions = DateTimeParseException.class) + public void test_fieldResolvesWrongZone() { + TemporalField field = new TemporalField() { + @Override + public TemporalUnit getBaseUnit() { + throw new UnsupportedOperationException(); + } + @Override + public TemporalUnit getRangeUnit() { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange range() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isDateBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isTimeBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isSupportedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange rangeRefinedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public long getFrom(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public R adjustInto(R temporal, long newValue) { + throw new UnsupportedOperationException(); + } + @Override + public TemporalAccessor resolve( + Map fieldValues, Chronology chronology, + ZoneId zone, ResolverStyle resolverStyle) { + return ZonedDateTime.of(2010, 6, 30, 12, 30, 0, 0, ZoneId.of("Europe/Paris")); + } + }; + DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter().withZone(ZoneId.of("Europe/London")); + f.parse("1234567890"); + } + } From 4df3876c56f6b810120159af2959e59f90bab69b Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Sun, 15 Sep 2013 16:13:41 +0200 Subject: [PATCH 0368/1294] 8024837: Rename java/util/concurrent/ConcurrentHashMap/toArray.java to ToArray.java Reviewed-by: alanb --- .../concurrent/ConcurrentHashMap/{toArray.java => ToArray.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename jdk/test/java/util/concurrent/ConcurrentHashMap/{toArray.java => ToArray.java} (98%) diff --git a/jdk/test/java/util/concurrent/ConcurrentHashMap/toArray.java b/jdk/test/java/util/concurrent/ConcurrentHashMap/ToArray.java similarity index 98% rename from jdk/test/java/util/concurrent/ConcurrentHashMap/toArray.java rename to jdk/test/java/util/concurrent/ConcurrentHashMap/ToArray.java index 81108ac9c55..dca07084162 100644 --- a/jdk/test/java/util/concurrent/ConcurrentHashMap/toArray.java +++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/ToArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, 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 From 344c38fc804de7d28b95d044c4f45ad007933ba6 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Sun, 15 Sep 2013 11:16:58 -0700 Subject: [PATCH 0369/1294] 7186311: (props) "Unicode" is misspelled as "Uniocde" in JavaDoc and error message To correct the typo Reviewed-by: alanb, chegar --- .../tools/src/build/tools/generatecharacter/CharacterName.java | 2 +- jdk/src/share/classes/java/util/Properties.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java b/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java index 0872100b7db..833a835c0ce 100644 --- a/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java +++ b/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java @@ -11,7 +11,7 @@ public class CharacterName { FileReader reader = null; try { if (args.length != 2) { - System.err.println("Usage: java CharacterName UniocdeData.txt uniName.dat"); + System.err.println("Usage: java CharacterName UnicodeData.txt uniName.dat"); System.exit(1); } diff --git a/jdk/src/share/classes/java/util/Properties.java b/jdk/src/share/classes/java/util/Properties.java index ed0bf857d66..073c7771630 100644 --- a/jdk/src/share/classes/java/util/Properties.java +++ b/jdk/src/share/classes/java/util/Properties.java @@ -304,7 +304,7 @@ class Properties extends Hashtable { * preceded by a backslash still yield single and double quote * characters, respectively. * - *

  • Only a single 'u' character is allowed in a Uniocde escape + *
  • Only a single 'u' character is allowed in a Unicode escape * sequence. * * From 763eb8d2e341667f9f8470df39a6bb0ff84b20ce Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Sun, 15 Sep 2013 13:58:47 -0700 Subject: [PATCH 0370/1294] 8020687: Deflater.setLevel does not work as expected To clarify the api to match the existing implementation behavior Reviewed-by: alanb --- jdk/src/share/classes/java/util/zip/Deflater.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/util/zip/Deflater.java b/jdk/src/share/classes/java/util/zip/Deflater.java index 085287996be..c4521bec667 100644 --- a/jdk/src/share/classes/java/util/zip/Deflater.java +++ b/jdk/src/share/classes/java/util/zip/Deflater.java @@ -261,6 +261,12 @@ class Deflater { /** * Sets the compression strategy to the specified value. + * + *

    If the compression strategy is changed, the next invocation + * of {@code deflate} will compress the input available so far with + * the old strategy (and may be flushed); the new strategy will take + * effect only after that invocation. + * * @param strategy the new compression strategy * @exception IllegalArgumentException if the compression strategy is * invalid @@ -283,7 +289,13 @@ class Deflater { } /** - * Sets the current compression level to the specified value. + * Sets the compression level to the specified value. + * + *

    If the compression level is changed, the next invocation + * of {@code deflate} will compress the input available so far + * with the old level (and may be flushed); the new level will + * take effect only after that invocation. + * * @param level the new compression level (0-9) * @exception IllegalArgumentException if the compression level is invalid */ From 3184042cd14fb6a080bb75cb31f683200855393c Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Mon, 16 Sep 2013 10:20:45 +0200 Subject: [PATCH 0371/1294] 8024396: VM crashing with assert(!UseLargePages || UseParallelOldGC || use_large_pages) failed: Wrong alignment to use large pages Loosen wrong assert for UseParallelOldGC to UseParallelGC Reviewed-by: stefank, brutisso --- hotspot/src/share/vm/memory/universe.cpp | 2 +- .../TestAlignmentToUseLargePages.java | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 54d6851d16d..a9be3486396 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -881,7 +881,7 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { bool use_large_pages = UseLargePages && is_size_aligned(alignment, os::large_page_size()); assert(!UseLargePages - || UseParallelOldGC + || UseParallelGC || use_large_pages, "Wrong alignment to use large pages"); char* addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::UnscaledNarrowOop); diff --git a/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java b/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java new file mode 100644 index 00000000000..125c1aabd51 --- /dev/null +++ b/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, 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 TestAlignmentToUseLargePages + * @summary All parallel GC variants may use large pages without the requirement that the + * heap alignment is large page aligned. Other collectors also need to start up with odd sized heaps. + * @bug 8024396 + * @key gc + * @key regression + * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseSerialGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseSerialGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseConcMarkSweepGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseConcMarkSweepGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseG1GC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseG1GC -XX:-UseLargePages TestAlignmentToUseLargePages + */ + +public class TestAlignmentToUseLargePages { + public static void main(String args[]) throws Exception { + // nothing to do + } +} From aea57c9e6ff5ec06df41e6d1e19356510aa26383 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Mon, 16 Sep 2013 15:08:36 +0530 Subject: [PATCH 0372/1294] 8024847: Java.to should accept mirror and external JSObjects as array-like objects as well Reviewed-by: hannesw, attila, lagergren --- .../nashorn/internal/objects/NativeJava.java | 10 +- .../nashorn/internal/runtime/ECMAErrors.java | 1 - .../internal/runtime/JSObjectListAdapter.java | 56 ++++++++++ .../jdk/nashorn/internal/runtime/JSType.java | 60 ++++++++++ .../nashorn/internal/runtime/ListAdapter.java | 105 ++++++++++-------- .../runtime/ScriptObjectListAdapter.java | 54 +++++++++ .../internal/runtime/arrays/ArrayData.java | 18 +-- nashorn/test/script/basic/JDK-8024847.js | 102 +++++++++++++++++ .../test/script/basic/JDK-8024847.js.EXPECTED | 12 ++ 9 files changed, 352 insertions(+), 66 deletions(-) create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java create mode 100644 nashorn/test/script/basic/JDK-8024847.js create mode 100644 nashorn/test/script/basic/JDK-8024847.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java index 011fd8bf84b..5e9ac83d5e1 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java @@ -34,6 +34,7 @@ import java.util.Deque; import java.util.List; import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.support.TypeUtilities; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.ScriptClass; @@ -43,6 +44,7 @@ import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ListAdapter; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory; @@ -288,7 +290,9 @@ public final class NativeJava { return null; } - Global.checkObject(obj); + if (!(obj instanceof ScriptObject) && !(obj instanceof JSObject)) { + throw typeError("not.an.object", ScriptRuntime.safeToString(obj)); + } final Class targetClass; if(objType == UNDEFINED) { @@ -304,11 +308,11 @@ public final class NativeJava { } if(targetClass.isArray()) { - return ((ScriptObject)obj).getArray().asArrayOfType(targetClass.getComponentType()); + return JSType.toJavaArray(obj, targetClass.getComponentType()); } if(targetClass == List.class || targetClass == Deque.class) { - return new ListAdapter((ScriptObject)obj); + return ListAdapter.create(obj); } throw typeError("unsupported.java.to.type", targetClass.getName()); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java b/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java index 5b608f4b37b..0ff843a4271 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java @@ -28,7 +28,6 @@ package jdk.nashorn.internal.runtime; import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; - import jdk.nashorn.api.scripting.NashornException; import jdk.nashorn.internal.scripts.JS; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java b/nashorn/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java new file mode 100644 index 00000000000..3c430b29e03 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime; + +import jdk.nashorn.api.scripting.JSObject; + +/** + * A ListAdapter that can wraps a JSObject. + */ +public final class JSObjectListAdapter extends ListAdapter { + /** + * Creates a new list wrapper for the specified JSObject. + * @param obj JSOcript the object to wrap + */ + public JSObjectListAdapter(final JSObject obj) { + super(obj); + } + + @Override + public int size() { + return JSType.toInt32(((JSObject)obj).getMember("length")); + } + + @Override + protected Object getAt(int index) { + return ((JSObject)obj).getSlot(index); + } + + @Override + protected void setAt(int index, Object element) { + ((JSObject)obj).setSlot(index, element); + } +} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java index 6098eb27728..93f0835b465 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java @@ -28,10 +28,14 @@ package jdk.nashorn.internal.runtime; import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.lang.reflect.Array; import jdk.internal.dynalink.beans.StaticClass; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.parser.Lexer; +import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator; import jdk.nashorn.internal.runtime.linker.Bootstrap; /** @@ -859,6 +863,53 @@ public enum JSType { return ((GlobalObject)global).wrapAsObject(obj); } + /** + * Script object to Java array conversion. + * + * @param obj script object to be converted to Java array + * @param componentType component type of the destination array required + * @return converted Java array + */ + public static Object toJavaArray(final Object obj, final Class componentType) { + if (obj instanceof ScriptObject) { + return convertArray(((ScriptObject)obj).getArray().asObjectArray(), componentType); + } else if (obj instanceof JSObject) { + final ArrayLikeIterator itr = ArrayLikeIterator.arrayLikeIterator(obj); + final int len = (int) itr.getLength(); + final Object[] res = new Object[len]; + int idx = 0; + while (itr.hasNext()) { + res[idx++] = itr.next(); + } + return convertArray(res, componentType); + } else { + throw new IllegalArgumentException("not a script object"); + } + } + + /** + * Java array to java array conversion - but using type conversions implemented by linker. + * + * @param src source array + * @param componentType component type of the destination array required + * @return converted Java array + */ + public static Object convertArray(final Object[] src, final Class componentType) { + final int l = src.length; + final Object dst = Array.newInstance(componentType, l); + final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType); + try { + for (int i = 0; i < src.length; i++) { + Array.set(dst, i, invoke(converter, src[i])); + } + } catch (final RuntimeException | Error e) { + throw e; + } catch (final Throwable t) { + throw new RuntimeException(t); + } + return dst; + } + /** * Check if an object is null or undefined * @@ -964,4 +1015,13 @@ public enum JSType { return Double.NaN; } + private static Object invoke(final MethodHandle mh, final Object arg) { + try { + return mh.invoke(arg); + } catch (final RuntimeException | Error e) { + throw e; + } catch (final Throwable t) { + throw new RuntimeException(t); + } + } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java b/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java index ae6d74461a1..41d34600de4 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java @@ -32,6 +32,7 @@ import java.util.ListIterator; import java.util.NoSuchElementException; import java.util.RandomAccess; import java.util.concurrent.Callable; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.InvokeByName; @@ -48,7 +49,7 @@ import jdk.nashorn.internal.runtime.linker.InvokeByName; * operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and * {@code pop}. */ -public final class ListAdapter extends AbstractList implements RandomAccess, Deque { +public abstract class ListAdapter extends AbstractList implements RandomAccess, Deque { // These add to the back and front of the list private static final Object PUSH = new Object(); private static InvokeByName getPUSH() { @@ -56,7 +57,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("push", ScriptObject.class, void.class, Object.class); + return new InvokeByName("push", Object.class, void.class, Object.class); } }); } @@ -67,7 +68,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("unshift", ScriptObject.class, void.class, Object.class); + return new InvokeByName("unshift", Object.class, void.class, Object.class); } }); } @@ -79,7 +80,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("pop", ScriptObject.class, Object.class); + return new InvokeByName("pop", Object.class, Object.class); } }); } @@ -90,7 +91,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("shift", ScriptObject.class, Object.class); + return new InvokeByName("shift", Object.class, Object.class); } }); } @@ -102,7 +103,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class, Object.class); + return new InvokeByName("splice", Object.class, void.class, int.class, int.class, Object.class); } }); } @@ -113,40 +114,52 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class); + return new InvokeByName("splice", Object.class, void.class, int.class, int.class); } }); } - private final ScriptObject obj; + protected final Object obj; - /** - * Creates a new list wrapper for the specified script object. - * @param obj script the object to wrap - */ - public ListAdapter(ScriptObject obj) { + // allow subclasses only in this package + ListAdapter(Object obj) { this.obj = obj; } - @Override - public int size() { - return JSType.toInt32(obj.getLength()); + /** + * Factory to create a ListAdapter for a given script object. + * + * @param obj script object to wrap as a ListAdapter + * @return A ListAdapter wrapper object + */ + public static ListAdapter create(final Object obj) { + if (obj instanceof ScriptObject) { + return new ScriptObjectListAdapter((ScriptObject)obj); + } else if (obj instanceof JSObject) { + return new JSObjectListAdapter((JSObject)obj); + } else { + throw new IllegalArgumentException("ScriptObject or JSObject expected"); + } } @Override - public Object get(int index) { + public final Object get(int index) { checkRange(index); - return obj.get(index); + return getAt(index); } + protected abstract Object getAt(final int index); + @Override public Object set(int index, Object element) { checkRange(index); - final Object prevValue = get(index); - obj.set(index, element, false); + final Object prevValue = getAt(index); + setAt(index, element); return prevValue; } + protected abstract void setAt(int index, Object element); + private void checkRange(int index) { if(index < 0 || index >= size()) { throw invalidIndex(index); @@ -154,18 +167,18 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public void push(Object e) { + public final void push(Object e) { addFirst(e); } @Override - public boolean add(Object e) { + public final boolean add(Object e) { addLast(e); return true; } @Override - public void addFirst(Object e) { + public final void addFirst(Object e) { try { final InvokeByName unshiftInvoker = getUNSHIFT(); final Object fn = unshiftInvoker.getGetter().invokeExact(obj); @@ -179,7 +192,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public void addLast(Object e) { + public final void addLast(Object e) { try { final InvokeByName pushInvoker = getPUSH(); final Object fn = pushInvoker.getGetter().invokeExact(obj); @@ -193,7 +206,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public void add(int index, Object e) { + public final void add(int index, Object e) { try { if(index < 0) { throw invalidIndex(index); @@ -229,40 +242,40 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public boolean offer(Object e) { + public final boolean offer(Object e) { return offerLast(e); } @Override - public boolean offerFirst(Object e) { + public final boolean offerFirst(Object e) { addFirst(e); return true; } @Override - public boolean offerLast(Object e) { + public final boolean offerLast(Object e) { addLast(e); return true; } @Override - public Object pop() { + public final Object pop() { return removeFirst(); } @Override - public Object remove() { + public final Object remove() { return removeFirst(); } @Override - public Object removeFirst() { + public final Object removeFirst() { checkNonEmpty(); return invokeShift(); } @Override - public Object removeLast() { + public final Object removeLast() { checkNonEmpty(); return invokePop(); } @@ -274,7 +287,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public Object remove(int index) { + public final Object remove(int index) { if(index < 0) { throw invalidIndex(index); } else if (index == 0) { @@ -320,7 +333,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - protected void removeRange(int fromIndex, int toIndex) { + protected final void removeRange(int fromIndex, int toIndex) { invokeSpliceRemove(fromIndex, toIndex - fromIndex); } @@ -338,54 +351,54 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public Object poll() { + public final Object poll() { return pollFirst(); } @Override - public Object pollFirst() { + public final Object pollFirst() { return isEmpty() ? null : invokeShift(); } @Override - public Object pollLast() { + public final Object pollLast() { return isEmpty() ? null : invokePop(); } @Override - public Object peek() { + public final Object peek() { return peekFirst(); } @Override - public Object peekFirst() { + public final Object peekFirst() { return isEmpty() ? null : get(0); } @Override - public Object peekLast() { + public final Object peekLast() { return isEmpty() ? null : get(size() - 1); } @Override - public Object element() { + public final Object element() { return getFirst(); } @Override - public Object getFirst() { + public final Object getFirst() { checkNonEmpty(); return get(0); } @Override - public Object getLast() { + public final Object getLast() { checkNonEmpty(); return get(size() - 1); } @Override - public Iterator descendingIterator() { + public final Iterator descendingIterator() { final ListIterator it = listIterator(size()); return new Iterator() { @Override @@ -406,12 +419,12 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public boolean removeFirstOccurrence(Object o) { + public final boolean removeFirstOccurrence(Object o) { return removeOccurrence(o, iterator()); } @Override - public boolean removeLastOccurrence(Object o) { + public final boolean removeLastOccurrence(Object o) { return removeOccurrence(o, descendingIterator()); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java new file mode 100644 index 00000000000..4fe2dc408f0 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime; + +/** + * A ListAdapter that can wrap a ScriptObject. + */ +public final class ScriptObjectListAdapter extends ListAdapter { + /** + * Creates a new list wrapper for the specified ScriptObject. + * @param obj script the object to wrap + */ + public ScriptObjectListAdapter(final ScriptObject obj) { + super(obj); + } + + @Override + public int size() { + return JSType.toInt32(((ScriptObject)obj).getLength()); + } + + @Override + protected Object getAt(int index) { + return ((ScriptObject)obj).get(index); + } + + @Override + protected void setAt(int index, Object element) { + ((ScriptObject)obj).set(index, element, false); + } +} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java index 1278d49ff95..ca4adb62e97 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java @@ -26,10 +26,9 @@ package jdk.nashorn.internal.runtime.arrays; import java.lang.invoke.MethodHandle; -import java.lang.reflect.Array; import jdk.nashorn.internal.runtime.GlobalObject; +import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.PropertyDescriptor; -import jdk.nashorn.internal.runtime.linker.Bootstrap; /** * ArrayData - abstraction for wrapping array elements @@ -204,20 +203,7 @@ public abstract class ArrayData { * @return and array of the given type */ public Object asArrayOfType(final Class componentType) { - final Object[] src = asObjectArray(); - final int l = src.length; - final Object dst = Array.newInstance(componentType, l); - final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType); - try { - for (int i = 0; i < src.length; i++) { - Array.set(dst, i, invoke(converter, src[i])); - } - } catch (final RuntimeException | Error e) { - throw e; - } catch (final Throwable t) { - throw new RuntimeException(t); - } - return dst; + return JSType.convertArray(asObjectArray(), componentType); } /** diff --git a/nashorn/test/script/basic/JDK-8024847.js b/nashorn/test/script/basic/JDK-8024847.js new file mode 100644 index 00000000000..4a671ecd9f0 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024847.js @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024847: Java.to should accept mirror and external JSObjects as array-like objects as well + * + * @test + * @run + */ + +var global = loadWithNewGlobal({ name: "test", script:"this" }); +var arr = new global.Array(2, 4, 6, 8); +var jarr = Java.to(arr, "int[]"); +for (var i in jarr) { + print(jarr[i]); +} + +arr = null; +jarr = null; + +// external JSObjects +var JSObject = Java.type("jdk.nashorn.api.scripting.JSObject"); +var arr = new JSObject() { + getMember: function(name) { + return name == "length"? 4 : undefined; + }, + + hasMember: function(name) { + return name == "length"; + }, + + getSlot: function(idx) { + return idx*idx; + }, + + hasSlot: function(idx) { + return true; + } +}; + +var jarr = Java.to(arr, "int[]"); +for (var i in jarr) { + print(jarr[i]); +} + +arr = null; +jarr = null; + +// List conversion +var arr = global.Array("hello", "world"); +var jlist = Java.to(arr, java.util.List); +print(jlist instanceof java.util.List); +print(jlist); + +arr = null; +jlist = null; + +// external JSObject +var __array__ = [ "nashorn", "js" ]; + +var obj = new JSObject() { + + hasMember: function(name) { + return name in __array__; + }, + + hasSlot: function(idx) { + return idx in __array__; + }, + + getMember: function(name) { + return __array__[name]; + }, + + getSlot: function(idx) { + return __array__[idx]; + } +} + +var jlist = Java.to(obj, java.util.List); +print(jlist instanceof java.util.List); +print(jlist); diff --git a/nashorn/test/script/basic/JDK-8024847.js.EXPECTED b/nashorn/test/script/basic/JDK-8024847.js.EXPECTED new file mode 100644 index 00000000000..015183a02a9 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024847.js.EXPECTED @@ -0,0 +1,12 @@ +2 +4 +6 +8 +0 +1 +4 +9 +true +[hello, world] +true +[nashorn, js] From 139c3e6621b2105f1d69c5032e5a10b48967dc8a Mon Sep 17 00:00:00 2001 From: David Holmes Date: Mon, 16 Sep 2013 07:38:13 -0400 Subject: [PATCH 0373/1294] 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock Associate CLOCK_MONOTONIC with the pthread_cond_t objects used for relative timed waits Reviewed-by: dcubed, shade --- hotspot/src/os/linux/vm/os_linux.cpp | 148 +++++++++++++++++++-------- hotspot/src/os/linux/vm/os_linux.hpp | 25 ++++- 2 files changed, 128 insertions(+), 45 deletions(-) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 70837a850d8..de5a7686989 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -131,6 +131,7 @@ bool os::Linux::_is_NPTL = false; bool os::Linux::_supports_fast_thread_cpu_time = false; const char * os::Linux::_glibc_version = NULL; const char * os::Linux::_libpthread_version = NULL; +pthread_condattr_t os::Linux::_condattr[1]; static jlong initial_time_count=0; @@ -1399,12 +1400,15 @@ void os::Linux::clock_init() { clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) { // yes, monotonic clock is supported _clock_gettime = clock_gettime_func; + return; } else { // close librt if there is no monotonic clock dlclose(handle); } } } + warning("No monotonic clock was available - timed services may " \ + "be adversely affected if the time-of-day clock changes"); } #ifndef SYS_clock_getres @@ -4709,6 +4713,26 @@ void os::init(void) { Linux::clock_init(); initial_time_count = os::elapsed_counter(); + + // pthread_condattr initialization for monotonic clock + int status; + pthread_condattr_t* _condattr = os::Linux::condAttr(); + if ((status = pthread_condattr_init(_condattr)) != 0) { + fatal(err_msg("pthread_condattr_init: %s", strerror(status))); + } + // Only set the clock if CLOCK_MONOTONIC is available + if (Linux::supports_monotonic_clock()) { + if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) { + if (status == EINVAL) { + warning("Unable to use monotonic clock with relative timed-waits" \ + " - changes to the time-of-day clock may have adverse affects"); + } else { + fatal(err_msg("pthread_condattr_setclock: %s", strerror(status))); + } + } + } + // else it defaults to CLOCK_REALTIME + pthread_mutex_init(&dl_mutex, NULL); // If the pagesize of the VM is greater than 8K determine the appropriate @@ -5519,21 +5543,36 @@ void os::pause() { static struct timespec* compute_abstime(timespec* abstime, jlong millis) { if (millis < 0) millis = 0; - struct timeval now; - int status = gettimeofday(&now, NULL); - assert(status == 0, "gettimeofday"); + jlong seconds = millis / 1000; millis %= 1000; if (seconds > 50000000) { // see man cond_timedwait(3T) seconds = 50000000; } - abstime->tv_sec = now.tv_sec + seconds; - long usec = now.tv_usec + millis * 1000; - if (usec >= 1000000) { - abstime->tv_sec += 1; - usec -= 1000000; + + if (os::Linux::supports_monotonic_clock()) { + struct timespec now; + int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now); + assert_status(status == 0, status, "clock_gettime"); + abstime->tv_sec = now.tv_sec + seconds; + long nanos = now.tv_nsec + millis * NANOSECS_PER_MILLISEC; + if (nanos >= NANOSECS_PER_SEC) { + abstime->tv_sec += 1; + nanos -= NANOSECS_PER_SEC; + } + abstime->tv_nsec = nanos; + } else { + struct timeval now; + int status = gettimeofday(&now, NULL); + assert(status == 0, "gettimeofday"); + abstime->tv_sec = now.tv_sec + seconds; + long usec = now.tv_usec + millis * 1000; + if (usec >= 1000000) { + abstime->tv_sec += 1; + usec -= 1000000; + } + abstime->tv_nsec = usec * 1000; } - abstime->tv_nsec = usec * 1000; return abstime; } @@ -5625,7 +5664,7 @@ int os::PlatformEvent::park(jlong millis) { status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst); if (status != 0 && WorkAroundNPTLTimedWaitHang) { pthread_cond_destroy (_cond); - pthread_cond_init (_cond, NULL) ; + pthread_cond_init (_cond, os::Linux::condAttr()) ; } assert_status(status == 0 || status == EINTR || status == ETIME || status == ETIMEDOUT, @@ -5726,32 +5765,50 @@ void os::PlatformEvent::unpark() { static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) { assert (time > 0, "convertTime"); + time_t max_secs = 0; - struct timeval now; - int status = gettimeofday(&now, NULL); - assert(status == 0, "gettimeofday"); + if (!os::Linux::supports_monotonic_clock() || isAbsolute) { + struct timeval now; + int status = gettimeofday(&now, NULL); + assert(status == 0, "gettimeofday"); - time_t max_secs = now.tv_sec + MAX_SECS; + max_secs = now.tv_sec + MAX_SECS; - if (isAbsolute) { - jlong secs = time / 1000; - if (secs > max_secs) { - absTime->tv_sec = max_secs; + if (isAbsolute) { + jlong secs = time / 1000; + if (secs > max_secs) { + absTime->tv_sec = max_secs; + } else { + absTime->tv_sec = secs; + } + absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; + } else { + jlong secs = time / NANOSECS_PER_SEC; + if (secs >= MAX_SECS) { + absTime->tv_sec = max_secs; + absTime->tv_nsec = 0; + } else { + absTime->tv_sec = now.tv_sec + secs; + absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; + if (absTime->tv_nsec >= NANOSECS_PER_SEC) { + absTime->tv_nsec -= NANOSECS_PER_SEC; + ++absTime->tv_sec; // note: this must be <= max_secs + } + } } - else { - absTime->tv_sec = secs; - } - absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; - } - else { + } else { + // must be relative using monotonic clock + struct timespec now; + int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now); + assert_status(status == 0, status, "clock_gettime"); + max_secs = now.tv_sec + MAX_SECS; jlong secs = time / NANOSECS_PER_SEC; if (secs >= MAX_SECS) { absTime->tv_sec = max_secs; absTime->tv_nsec = 0; - } - else { + } else { absTime->tv_sec = now.tv_sec + secs; - absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; + absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_nsec; if (absTime->tv_nsec >= NANOSECS_PER_SEC) { absTime->tv_nsec -= NANOSECS_PER_SEC; ++absTime->tv_sec; // note: this must be <= max_secs @@ -5831,15 +5888,19 @@ void Parker::park(bool isAbsolute, jlong time) { jt->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() + assert(_cur_index == -1, "invariant"); if (time == 0) { - status = pthread_cond_wait (_cond, _mutex) ; + _cur_index = REL_INDEX; // arbitrary choice when not timed + status = pthread_cond_wait (&_cond[_cur_index], _mutex) ; } else { - status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ; + _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX; + status = os::Linux::safe_cond_timedwait (&_cond[_cur_index], _mutex, &absTime) ; if (status != 0 && WorkAroundNPTLTimedWaitHang) { - pthread_cond_destroy (_cond) ; - pthread_cond_init (_cond, NULL); + pthread_cond_destroy (&_cond[_cur_index]) ; + pthread_cond_init (&_cond[_cur_index], isAbsolute ? NULL : os::Linux::condAttr()); } } + _cur_index = -1; assert_status(status == 0 || status == EINTR || status == ETIME || status == ETIMEDOUT, status, "cond_timedwait"); @@ -5868,17 +5929,24 @@ void Parker::unpark() { s = _counter; _counter = 1; if (s < 1) { - if (WorkAroundNPTLTimedWaitHang) { - status = pthread_cond_signal (_cond) ; - assert (status == 0, "invariant") ; + // thread might be parked + if (_cur_index != -1) { + // thread is definitely parked + if (WorkAroundNPTLTimedWaitHang) { + status = pthread_cond_signal (&_cond[_cur_index]); + assert (status == 0, "invariant"); status = pthread_mutex_unlock(_mutex); - assert (status == 0, "invariant") ; - } else { + assert (status == 0, "invariant"); + } else { status = pthread_mutex_unlock(_mutex); - assert (status == 0, "invariant") ; - status = pthread_cond_signal (_cond) ; - assert (status == 0, "invariant") ; - } + assert (status == 0, "invariant"); + status = pthread_cond_signal (&_cond[_cur_index]); + assert (status == 0, "invariant"); + } + } else { + pthread_mutex_unlock(_mutex); + assert (status == 0, "invariant") ; + } } else { pthread_mutex_unlock(_mutex); assert (status == 0, "invariant") ; diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp index c824e8ad3fe..5eed54f8c1e 100644 --- a/hotspot/src/os/linux/vm/os_linux.hpp +++ b/hotspot/src/os/linux/vm/os_linux.hpp @@ -221,6 +221,13 @@ class Linux { static jlong fast_thread_cpu_time(clockid_t clockid); + // pthread_cond clock suppport + private: + static pthread_condattr_t _condattr[1]; + + public: + static pthread_condattr_t* condAttr() { return _condattr; } + // Stack repair handling // none present @@ -295,7 +302,7 @@ class PlatformEvent : public CHeapObj { public: PlatformEvent() { int status; - status = pthread_cond_init (_cond, NULL); + status = pthread_cond_init (_cond, os::Linux::condAttr()); assert_status(status == 0, status, "cond_init"); status = pthread_mutex_init (_mutex, NULL); assert_status(status == 0, status, "mutex_init"); @@ -310,14 +317,19 @@ class PlatformEvent : public CHeapObj { void park () ; void unpark () ; int TryPark () ; - int park (jlong millis) ; + int park (jlong millis) ; // relative timed-wait only void SetAssociation (Thread * a) { _Assoc = a ; } } ; class PlatformParker : public CHeapObj { protected: + enum { + REL_INDEX = 0, + ABS_INDEX = 1 + }; + int _cur_index; // which cond is in use: -1, 0, 1 pthread_mutex_t _mutex [1] ; - pthread_cond_t _cond [1] ; + pthread_cond_t _cond [2] ; // one for relative times and one for abs. public: // TODO-FIXME: make dtor private ~PlatformParker() { guarantee (0, "invariant") ; } @@ -325,10 +337,13 @@ class PlatformParker : public CHeapObj { public: PlatformParker() { int status; - status = pthread_cond_init (_cond, NULL); - assert_status(status == 0, status, "cond_init"); + status = pthread_cond_init (&_cond[REL_INDEX], os::Linux::condAttr()); + assert_status(status == 0, status, "cond_init rel"); + status = pthread_cond_init (&_cond[ABS_INDEX], NULL); + assert_status(status == 0, status, "cond_init abs"); status = pthread_mutex_init (_mutex, NULL); assert_status(status == 0, status, "mutex_init"); + _cur_index = -1; // mark as unused } }; From 315696de0025ff317cd5cb0e28d4f26cc13b16e7 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Mon, 16 Sep 2013 14:13:44 +0200 Subject: [PATCH 0374/1294] 8021112: Spurious unchecked warning reported by javac 6480588: No way to suppress deprecation warnings when implementing deprecated interface Fixing DeferredLintHandler configuration, so lint warnings are reported with correct @SuppressWarnings settings Reviewed-by: jjg, vromero --- .../tools/javac/code/DeferredLintHandler.java | 73 +++++- .../com/sun/tools/javac/code/Symbol.java | 5 +- .../com/sun/tools/javac/comp/Attr.java | 40 ++-- .../com/sun/tools/javac/comp/Check.java | 31 +-- .../com/sun/tools/javac/comp/MemberEnter.java | 98 +++++--- .../depDocComment/SuppressDeprecation.out | 2 +- .../javac/warnings/6594914/T6594914a.out | 2 +- .../javac/warnings/6594914/T6594914b.out | 2 +- .../javac/warnings/suppress/ImplicitTest.java | 31 +++ .../javac/warnings/suppress/ImplicitTest.out | 2 + .../javac/warnings/suppress/PackageInfo.java | 30 +++ .../javac/warnings/suppress/PackageInfo.out | 3 + .../javac/warnings/suppress/T6480588.java | 36 +++ .../javac/warnings/suppress/T6480588.out | 18 ++ .../javac/warnings/suppress/T8021112a.java | 45 ++++ .../javac/warnings/suppress/T8021112b.java | 22 ++ .../javac/warnings/suppress/T8021112b.out | 3 + .../warnings/suppress/TypeAnnotations.java | 51 +++++ .../warnings/suppress/TypeAnnotations.out | 41 ++++ .../suppress/VerifySuppressWarnings.java | 212 ++++++++++++++++++ .../suppress/pack/DeprecatedClass.java | 5 + .../warnings/suppress/pack/ImplicitMain.java | 14 ++ .../warnings/suppress/pack/ImplicitUse.java | 7 + .../warnings/suppress/pack/package-info.java | 5 + 24 files changed, 687 insertions(+), 91 deletions(-) create mode 100644 langtools/test/tools/javac/warnings/suppress/ImplicitTest.java create mode 100644 langtools/test/tools/javac/warnings/suppress/ImplicitTest.out create mode 100644 langtools/test/tools/javac/warnings/suppress/PackageInfo.java create mode 100644 langtools/test/tools/javac/warnings/suppress/PackageInfo.out create mode 100644 langtools/test/tools/javac/warnings/suppress/T6480588.java create mode 100644 langtools/test/tools/javac/warnings/suppress/T6480588.out create mode 100644 langtools/test/tools/javac/warnings/suppress/T8021112a.java create mode 100644 langtools/test/tools/javac/warnings/suppress/T8021112b.java create mode 100644 langtools/test/tools/javac/warnings/suppress/T8021112b.out create mode 100644 langtools/test/tools/javac/warnings/suppress/TypeAnnotations.java create mode 100644 langtools/test/tools/javac/warnings/suppress/TypeAnnotations.out create mode 100644 langtools/test/tools/javac/warnings/suppress/VerifySuppressWarnings.java create mode 100644 langtools/test/tools/javac/warnings/suppress/pack/DeprecatedClass.java create mode 100644 langtools/test/tools/javac/warnings/suppress/pack/ImplicitMain.java create mode 100644 langtools/test/tools/javac/warnings/suppress/pack/ImplicitUse.java create mode 100644 langtools/test/tools/javac/warnings/suppress/pack/package-info.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java b/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java index 022681bd8f6..9392046bb2d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ package com.sun.tools.javac.code; import java.util.HashMap; import java.util.Map; +import com.sun.tools.javac.tree.EndPosTable; +import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -53,10 +55,13 @@ public class DeferredLintHandler { protected DeferredLintHandler(Context context) { context.put(deferredLintHandlerKey, this); + this.currentPos = IMMEDIATE_POSITION; } - private DeferredLintHandler() {} - + /**An interface for deferred lint reporting - loggers passed to + * {@link #report(LintLogger) } will be called when + * {@link #flush(DiagnosticPosition) } is invoked. + */ public interface LintLogger { void report(); } @@ -64,12 +69,26 @@ public class DeferredLintHandler { private DiagnosticPosition currentPos; private Map> loggersQueue = new HashMap>(); + /**Associate the given logger with the current position as set by {@link #setPos(DiagnosticPosition) }. + * Will be invoked when {@link #flush(DiagnosticPosition) } will be invoked with the same position. + *
    + * Will invoke the logger synchronously if {@link #immediate() } was called + * instead of {@link #setPos(DiagnosticPosition) }. + */ public void report(LintLogger logger) { - ListBuffer loggers = loggersQueue.get(currentPos); - Assert.checkNonNull(loggers); - loggers.append(logger); + if (currentPos == IMMEDIATE_POSITION) { + logger.report(); + } else { + ListBuffer loggers = loggersQueue.get(currentPos); + if (loggers == null) { + loggersQueue.put(currentPos, loggers = ListBuffer.lb()); + } + loggers.append(logger); + } } + /**Invoke all {@link LintLogger}s that were associated with the provided {@code pos}. + */ public void flush(DiagnosticPosition pos) { ListBuffer loggers = loggersQueue.get(pos); if (loggers != null) { @@ -80,16 +99,46 @@ public class DeferredLintHandler { } } - public DeferredLintHandler setPos(DiagnosticPosition currentPos) { + /**Sets the current position to the provided {@code currentPos}. {@link LintLogger}s + * passed to subsequent invocations of {@link #report(LintLogger) } will be associated + * with the given position. + */ + public DiagnosticPosition setPos(DiagnosticPosition currentPos) { + DiagnosticPosition prevPosition = this.currentPos; this.currentPos = currentPos; - loggersQueue.put(currentPos, ListBuffer.lb()); - return this; + return prevPosition; } - public static final DeferredLintHandler immediateHandler = new DeferredLintHandler() { + /**{@link LintLogger}s passed to subsequent invocations of + * {@link #report(LintLogger) } will be invoked immediately. + */ + public DiagnosticPosition immediate() { + return setPos(IMMEDIATE_POSITION); + } + + private static final DiagnosticPosition IMMEDIATE_POSITION = new DiagnosticPosition() { @Override - public void report(LintLogger logger) { - logger.report(); + public JCTree getTree() { + Assert.error(); + return null; + } + + @Override + public int getStartPosition() { + Assert.error(); + return -1; + } + + @Override + public int getPreferredPosition() { + Assert.error(); + return -1; + } + + @Override + public int getEndPosition(EndPosTable endPosTable) { + Assert.error(); + return -1; } }; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index d7552ee2a9e..65459ec3daf 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -46,6 +46,7 @@ import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.FORALL; import static com.sun.tools.javac.code.TypeTag.TYPEVAR; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; /** Root class for Java symbols. It contains subclasses * for specific sorts of symbols, such as variables, methods and operators, @@ -1167,11 +1168,11 @@ public abstract class Symbol implements Element { public void setLazyConstValue(final Env env, final Attr attr, - final JCTree.JCExpression initializer) + final JCVariableDecl variable) { setData(new Callable() { public Object call() { - return attr.attribLazyConstantValue(env, initializer, type); + return attr.attribLazyConstantValue(env, variable, type); } }); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index c09ab8907a2..cb2337f936c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -748,19 +748,11 @@ public class Attr extends JCTree.Visitor { * @see VarSymbol#setLazyConstValue */ public Object attribLazyConstantValue(Env env, - JCTree.JCExpression initializer, + JCVariableDecl variable, Type type) { - /* When this env was created, it didn't have the correct lint nor had - * annotations has been processed. - * But now at this phase we have already processed annotations and the - * correct lint must have been set in chk, so we should use that one to - * attribute the initializer. - */ - Lint prevLint = env.info.lint; - env.info.lint = chk.getLint(); - - JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile); + DiagnosticPosition prevLintPos + = deferredLintHandler.setPos(variable.pos()); try { // Use null as symbol to not attach the type annotation to any symbol. @@ -768,17 +760,16 @@ public class Attr extends JCTree.Visitor { // to the symbol. // This prevents having multiple type annotations, just because of // lazy constant value evaluation. - memberEnter.typeAnnotate(initializer, env, null); + memberEnter.typeAnnotate(variable.init, env, null, variable.pos()); annotate.flush(); - Type itype = attribExpr(initializer, env, type); + Type itype = attribExpr(variable.init, env, type); if (itype.constValue() != null) { return coerce(itype, type).constValue(); } else { return null; } } finally { - env.info.lint = prevLint; - log.useSource(prevSource); + deferredLintHandler.setPos(prevLintPos); } } @@ -1012,7 +1003,7 @@ public class Attr extends JCTree.Visitor { } // Attribute all type annotations in the body - memberEnter.typeAnnotate(tree.body, localEnv, m); + memberEnter.typeAnnotate(tree.body, localEnv, m, null); annotate.flush(); // Attribute method body. @@ -1042,7 +1033,7 @@ public class Attr extends JCTree.Visitor { } else { if (tree.init != null) { // Field initializer expression need to be entered. - memberEnter.typeAnnotate(tree.init, env, tree.sym); + memberEnter.typeAnnotate(tree.init, env, tree.sym, tree.pos()); annotate.flush(); } } @@ -1056,18 +1047,16 @@ public class Attr extends JCTree.Visitor { ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT && (tree.sym.flags() & PARAMETER) != 0; chk.validate(tree.vartype, env, !isImplicitLambdaParameter); - deferredLintHandler.flush(tree.pos()); try { + v.getConstValue(); // ensure compile-time constant initializer is evaluated + deferredLintHandler.flush(tree.pos()); chk.checkDeprecatedAnnotation(tree.pos(), v); if (tree.init != null) { - if ((v.flags_field & FINAL) != 0 && - memberEnter.needsLazyConstValue(tree.init)) { - // In this case, `v' is final. Ensure that it's initializer is - // evaluated. - v.getConstValue(); // ensure initializer is evaluated - } else { + if ((v.flags_field & FINAL) == 0 || + !memberEnter.needsLazyConstValue(tree.init)) { + // Not a compile-time constant // Attribute initializer in a new environment // with the declared variable as owner. // Check that initializer conforms to variable's declared type. @@ -1106,7 +1095,7 @@ public class Attr extends JCTree.Visitor { if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; // Attribute all type annotations in the block - memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner); + memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner, null); annotate.flush(); { @@ -4209,6 +4198,7 @@ public class Attr extends JCTree.Visitor { ResultInfo prevReturnRes = env.info.returnResult; try { + deferredLintHandler.flush(env.tree); env.info.returnResult = null; // java.lang.Enum may not be subclassed by a non-enum if (st.tsym == syms.enumSym && diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 2612741ac03..5f6d1886bd8 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -148,7 +148,7 @@ public class Check { sunApiHandler = new MandatoryWarningHandler(log, verboseSunApi, enforceMandatoryWarnings, "sunapi", null); - deferredLintHandler = DeferredLintHandler.immediateHandler; + deferredLintHandler = DeferredLintHandler.instance(context); } /** Switch: generics enabled? @@ -218,20 +218,6 @@ public class Check { return prev; } - /* This idiom should be used only in cases when it is needed to set the lint - * of an environment that has been created in a phase previous to annotations - * processing. - */ - Lint getLint() { - return lint; - } - - DeferredLintHandler setDeferredLintHandler(DeferredLintHandler newDeferredLintHandler) { - DeferredLintHandler prev = deferredLintHandler; - deferredLintHandler = newDeferredLintHandler; - return prev; - } - MethodSymbol setMethod(MethodSymbol newMethod) { MethodSymbol prev = method; method = newMethod; @@ -582,14 +568,19 @@ public class Check { /** Check for redundant casts (i.e. where source type is a subtype of target type) * The problem should only be reported for non-292 cast */ - public void checkRedundantCast(Env env, JCTypeCast tree) { - if (!tree.type.isErroneous() && - (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST)) + public void checkRedundantCast(Env env, final JCTypeCast tree) { + if (!tree.type.isErroneous() && types.isSameType(tree.expr.type, tree.clazz.type) && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz)) && !is292targetTypeCast(tree)) { - log.warning(Lint.LintCategory.CAST, - tree.pos(), "redundant.cast", tree.expr.type); + deferredLintHandler.report(new DeferredLintHandler.LintLogger() { + @Override + public void report() { + if (lint.isEnabled(Lint.LintCategory.CAST)) + log.warning(Lint.LintCategory.CAST, + tree.pos(), "redundant.cast", tree.expr.type); + } + }); } } //where diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index a2d021fbc36..634e875d5aa 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -84,6 +84,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { private final Source source; private final Target target; private final DeferredLintHandler deferredLintHandler; + private final Lint lint; public static MemberEnter instance(Context context) { MemberEnter instance = context.get(memberEnterKey); @@ -109,6 +110,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { source = Source.instance(context); target = Target.instance(context); deferredLintHandler = DeferredLintHandler.instance(context); + lint = Lint.instance(context); allowTypeAnnos = source.allowTypeAnnotations(); } @@ -506,9 +508,10 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } // process package annotations - annotateLater(tree.packageAnnotations, env, tree.packge); + annotateLater(tree.packageAnnotations, env, tree.packge, null); - DeferredLintHandler prevLintHandler = chk.setDeferredLintHandler(DeferredLintHandler.immediateHandler); + DiagnosticPosition prevLintPos = deferredLintHandler.immediate(); + Lint prevLint = chk.setLint(lint); try { // Import-on-demand java.lang. @@ -517,7 +520,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer { // Process all import clauses. memberEnter(tree.defs, env); } finally { - chk.setDeferredLintHandler(prevLintHandler); + chk.setLint(prevLint); + deferredLintHandler.setPos(prevLintPos); } } @@ -564,8 +568,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { Env localEnv = methodEnv(tree, env); - DeferredLintHandler prevLintHandler = - chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos())); + DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos()); try { // Compute the method type m.type = signature(m, tree.typarams, tree.params, @@ -573,7 +576,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { tree.thrown, localEnv); } finally { - chk.setDeferredLintHandler(prevLintHandler); + deferredLintHandler.setPos(prevLintPos); } if (types.isSignaturePolymorphic(m)) { @@ -597,10 +600,10 @@ public class MemberEnter extends JCTree.Visitor implements Completer { if (chk.checkUnique(tree.pos(), m, enclScope)) { enclScope.enter(m); } - annotateLater(tree.mods.annotations, localEnv, m); + annotateLater(tree.mods.annotations, localEnv, m, tree.pos()); // Visit the signature of the method. Note that // TypeAnnotate doesn't descend into the body. - typeAnnotate(tree, localEnv, m); + typeAnnotate(tree, localEnv, m, tree.pos()); if (tree.defaultValue != null) annotateDefaultValueLater(tree.defaultValue, localEnv, m); @@ -630,15 +633,14 @@ public class MemberEnter extends JCTree.Visitor implements Completer { localEnv = env.dup(tree, env.info.dup()); localEnv.info.staticLevel++; } - DeferredLintHandler prevLintHandler = - chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos())); + DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos()); try { if (TreeInfo.isEnumInit(tree)) { attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype); } else { // Make sure type annotations are processed. // But we don't have a symbol to attach them to yet - use null. - typeAnnotate(tree.vartype, env, null); + typeAnnotate(tree.vartype, env, null, tree.pos()); attr.attribType(tree.vartype, localEnv); if (tree.nameexpr != null) { attr.attribExpr(tree.nameexpr, localEnv); @@ -658,7 +660,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } } } finally { - chk.setDeferredLintHandler(prevLintHandler); + deferredLintHandler.setPos(prevLintPos); } if ((tree.mods.flags & VARARGS) != 0) { @@ -680,15 +682,15 @@ public class MemberEnter extends JCTree.Visitor implements Completer { needsLazyConstValue(tree.init)) { Env initEnv = getInitEnv(tree, env); initEnv.info.enclVar = v; - v.setLazyConstValue(initEnv(tree, initEnv), attr, tree.init); + v.setLazyConstValue(initEnv(tree, initEnv), attr, tree); } } if (chk.checkUnique(tree.pos(), v, enclScope)) { chk.checkTransparentVar(tree.pos(), v, enclScope); enclScope.enter(v); } - annotateLater(tree.mods.annotations, localEnv, v); - typeAnnotate(tree.vartype, env, v); + annotateLater(tree.mods.annotations, localEnv, v, tree.pos()); + typeAnnotate(tree.vartype, env, v, tree.pos()); annotate.flush(); v.pos = tree.pos; } @@ -719,6 +721,11 @@ public class MemberEnter extends JCTree.Visitor implements Completer { result = false; } + @Override + public void visitNewArray(JCNewArray that) { + result = false; + } + @Override public void visitLambda(JCLambda that) { result = false; @@ -729,6 +736,11 @@ public class MemberEnter extends JCTree.Visitor implements Completer { result = false; } + @Override + public void visitApply(JCMethodInvocation that) { + result = false; + } + @Override public void visitSelect(JCFieldAccess tree) { tree.selected.accept(this); @@ -820,7 +832,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer { /** Queue annotations for later processing. */ void annotateLater(final List annotations, final Env localEnv, - final Symbol s) { + final Symbol s, + final DiagnosticPosition deferPos) { if (annotations.isEmpty()) { return; } @@ -837,6 +850,11 @@ public class MemberEnter extends JCTree.Visitor implements Completer { public void enterAnnotation() { Assert.check(s.kind == PCK || s.annotationsPendingCompletion()); JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); + DiagnosticPosition prevLintPos = + deferPos != null + ? deferredLintHandler.setPos(deferPos) + : deferredLintHandler.immediate(); + Lint prevLint = deferPos != null ? null : chk.setLint(lint); try { if (s.hasAnnotations() && annotations.nonEmpty()) @@ -845,6 +863,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer { kindName(s), s); actualEnterAnnotations(annotations, localEnv, s); } finally { + if (prevLint != null) + chk.setLint(prevLint); + deferredLintHandler.setPos(prevLintPos); log.useSource(prev); } } @@ -964,6 +985,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { isFirst = false; JavaFileObject prev = log.useSource(env.toplevel.sourcefile); + DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos()); try { // Save class environment for later member enter (2) processing. halfcompleted.append(env); @@ -985,9 +1007,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer { Env baseEnv = baseEnv(tree, env); if (tree.extending != null) - typeAnnotate(tree.extending, baseEnv, sym); + typeAnnotate(tree.extending, baseEnv, sym, tree.pos()); for (JCExpression impl : tree.implementing) - typeAnnotate(impl, baseEnv, sym); + typeAnnotate(impl, baseEnv, sym, tree.pos()); annotate.flush(); // Determine supertype. @@ -1048,7 +1070,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { attr.attribAnnotationTypes(tree.mods.annotations, baseEnv); if (hasDeprecatedAnnotation(tree.mods.annotations)) c.flags_field |= DEPRECATED; - annotateLater(tree.mods.annotations, baseEnv, c); + annotateLater(tree.mods.annotations, baseEnv, c, tree.pos()); // class type parameters use baseEnv but everything uses env chk.checkNonCyclicDecl(tree); @@ -1056,7 +1078,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { attr.attribTypeVariables(tree.typarams, baseEnv); // Do this here, where we have the symbol. for (JCTypeParameter tp : tree.typarams) - typeAnnotate(tp, baseEnv, sym); + typeAnnotate(tp, baseEnv, sym, tree.pos()); annotate.flush(); // Add default constructor if needed. @@ -1126,6 +1148,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } catch (CompletionFailure ex) { chk.completionError(tree.pos(), ex); } finally { + deferredLintHandler.setPos(prevLintPos); log.useSource(prev); } @@ -1186,9 +1209,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } } - public void typeAnnotate(final JCTree tree, final Env env, final Symbol sym) { + public void typeAnnotate(final JCTree tree, final Env env, final Symbol sym, DiagnosticPosition deferPos) { if (allowTypeAnnos) { - tree.accept(new TypeAnnotate(env, sym)); + tree.accept(new TypeAnnotate(env, sym, deferPos)); } } @@ -1199,10 +1222,12 @@ public class MemberEnter extends JCTree.Visitor implements Completer { private class TypeAnnotate extends TreeScanner { private Env env; private Symbol sym; + private DiagnosticPosition deferPos; - public TypeAnnotate(final Env env, final Symbol sym) { + public TypeAnnotate(final Env env, final Symbol sym, DiagnosticPosition deferPos) { this.env = env; this.sym = sym; + this.deferPos = deferPos; } void annotateTypeLater(final List annotations) { @@ -1210,6 +1235,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer { return; } + final DiagnosticPosition deferPos = this.deferPos; + annotate.normal(new Annotate.Annotator() { @Override public String toString() { @@ -1218,9 +1245,16 @@ public class MemberEnter extends JCTree.Visitor implements Completer { @Override public void enterAnnotation() { JavaFileObject prev = log.useSource(env.toplevel.sourcefile); + DiagnosticPosition prevLintPos = null; + + if (deferPos != null) { + prevLintPos = deferredLintHandler.setPos(deferPos); + } try { actualEnterTypeAnnotations(annotations, env, sym); } finally { + if (prevLintPos != null) + deferredLintHandler.setPos(prevLintPos); log.useSource(prev); } } @@ -1262,13 +1296,19 @@ public class MemberEnter extends JCTree.Visitor implements Completer { @Override public void visitVarDef(final JCVariableDecl tree) { - if (sym != null && sym.kind == Kinds.VAR) { - // Don't visit a parameter once when the sym is the method - // and once when the sym is the parameter. - scan(tree.mods); - scan(tree.vartype); + DiagnosticPosition prevPos = deferPos; + deferPos = tree.pos(); + try { + if (sym != null && sym.kind == Kinds.VAR) { + // Don't visit a parameter once when the sym is the method + // and once when the sym is the parameter. + scan(tree.mods); + scan(tree.vartype); + } + scan(tree.init); + } finally { + deferPos = prevPos; } - scan(tree.init); } @Override diff --git a/langtools/test/tools/javac/depDocComment/SuppressDeprecation.out b/langtools/test/tools/javac/depDocComment/SuppressDeprecation.out index eb0c0ff686b..4a8b15f33fd 100644 --- a/langtools/test/tools/javac/depDocComment/SuppressDeprecation.out +++ b/langtools/test/tools/javac/depDocComment/SuppressDeprecation.out @@ -1,8 +1,8 @@ -SuppressDeprecation.java:130:17: compiler.warn.has.been.deprecated: X, compiler.misc.unnamed.package SuppressDeprecation.java:82:10: compiler.warn.has.been.deprecated: g(), T SuppressDeprecation.java:83:14: compiler.warn.has.been.deprecated: g(), T SuppressDeprecation.java:84:9: compiler.warn.has.been.deprecated: var, T SuppressDeprecation.java:87:9: compiler.warn.has.been.deprecated: T(), T SuppressDeprecation.java:90:9: compiler.warn.has.been.deprecated: T(int), T SuppressDeprecation.java:98:1: compiler.warn.has.been.deprecated: T(), T +SuppressDeprecation.java:130:17: compiler.warn.has.been.deprecated: X, compiler.misc.unnamed.package 7 warnings diff --git a/langtools/test/tools/javac/warnings/6594914/T6594914a.out b/langtools/test/tools/javac/warnings/6594914/T6594914a.out index d3d759ca044..62f99072a7a 100644 --- a/langtools/test/tools/javac/warnings/6594914/T6594914a.out +++ b/langtools/test/tools/javac/warnings/6594914/T6594914a.out @@ -1,7 +1,7 @@ T6594914a.java:11:5: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package T6594914a.java:16:16: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package -T6594914a.java:16:52: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package T6594914a.java:16:33: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package T6594914a.java:17:20: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6594914a.java:16:52: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package T6594914a.java:24:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package 6 warnings diff --git a/langtools/test/tools/javac/warnings/6594914/T6594914b.out b/langtools/test/tools/javac/warnings/6594914/T6594914b.out index 652ad120d78..56e0794f1d8 100644 --- a/langtools/test/tools/javac/warnings/6594914/T6594914b.out +++ b/langtools/test/tools/javac/warnings/6594914/T6594914b.out @@ -1,7 +1,7 @@ T6594914b.java:11:13: compiler.warn.sun.proprietary: sun.misc.Lock T6594914b.java:16:24: compiler.warn.sun.proprietary: sun.misc.Lock -T6594914b.java:16:56: compiler.warn.sun.proprietary: sun.misc.Lock T6594914b.java:16:39: compiler.warn.sun.proprietary: sun.misc.Lock T6594914b.java:17:28: compiler.warn.sun.proprietary: sun.misc.CEFormatException +T6594914b.java:16:56: compiler.warn.sun.proprietary: sun.misc.Lock T6594914b.java:24:17: compiler.warn.sun.proprietary: sun.misc.Lock 6 warnings diff --git a/langtools/test/tools/javac/warnings/suppress/ImplicitTest.java b/langtools/test/tools/javac/warnings/suppress/ImplicitTest.java new file mode 100644 index 00000000000..1c4208ca902 --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/ImplicitTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013, 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 8021112 + * @summary Verify that deprecated warning is printed correctly for import + * statement when processing a file on demand while attributing another file. + * @clean pack.ImplicitUse pack.ImplicitMain pack.Dep + * @compile/ref=ImplicitTest.out -XDrawDiagnostics -Xlint:deprecation pack/ImplicitMain.java + */ diff --git a/langtools/test/tools/javac/warnings/suppress/ImplicitTest.out b/langtools/test/tools/javac/warnings/suppress/ImplicitTest.out new file mode 100644 index 00000000000..be39624289b --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/ImplicitTest.out @@ -0,0 +1,2 @@ +ImplicitUse.java:4:12: compiler.warn.has.been.deprecated: pack.Dep, pack +1 warning \ No newline at end of file diff --git a/langtools/test/tools/javac/warnings/suppress/PackageInfo.java b/langtools/test/tools/javac/warnings/suppress/PackageInfo.java new file mode 100644 index 00000000000..98a93102a7c --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/PackageInfo.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013, 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 8021112 + * @summary Verify that deprecated warnings are printed correctly for package-info.java + * @clean pack.package-info pack.DeprecatedClass + * @compile/ref=PackageInfo.out -XDrawDiagnostics -Xlint:deprecation pack/package-info.java pack/DeprecatedClass.java + */ diff --git a/langtools/test/tools/javac/warnings/suppress/PackageInfo.out b/langtools/test/tools/javac/warnings/suppress/PackageInfo.out new file mode 100644 index 00000000000..d1379ce82ab --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/PackageInfo.out @@ -0,0 +1,3 @@ +package-info.java:5:12: compiler.warn.has.been.deprecated: pack.DeprecatedClass, pack +package-info.java:2:2: compiler.warn.has.been.deprecated: pack.DeprecatedClass, pack +2 warnings diff --git a/langtools/test/tools/javac/warnings/suppress/T6480588.java b/langtools/test/tools/javac/warnings/suppress/T6480588.java new file mode 100644 index 00000000000..88af4cca73d --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/T6480588.java @@ -0,0 +1,36 @@ +/** + * @test /nodynamiccopyright/ + * @bug 6470588 + * @summary Verify that \\@SuppressWarnings("deprecation") works OK for all parts + * of class/method/field "header", including (declaration) annotations + * @build VerifySuppressWarnings + * @compile/ref=T6480588.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast T6480588.java + * @run main VerifySuppressWarnings T6480588.java + */ + +@DeprecatedAnnotation +class T6480588 extends DeprecatedClass implements DeprecatedInterface { + @DeprecatedAnnotation + public DeprecatedClass method(DeprecatedClass param) throws DeprecatedClass { + DeprecatedClass lv = new DeprecatedClass(); + @Deprecated + DeprecatedClass lvd = new DeprecatedClass(); + return null; + } + + @Deprecated + public void methodD() { + } + + @DeprecatedAnnotation + DeprecatedClass field = new DeprecatedClass(); + + @DeprecatedAnnotation + class Inner extends DeprecatedClass implements DeprecatedInterface { + } + +} + +@Deprecated class DeprecatedClass extends Throwable { } +@Deprecated interface DeprecatedInterface { } +@Deprecated @interface DeprecatedAnnotation { } diff --git a/langtools/test/tools/javac/warnings/suppress/T6480588.out b/langtools/test/tools/javac/warnings/suppress/T6480588.out new file mode 100644 index 00000000000..6e6f36739f3 --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/T6480588.out @@ -0,0 +1,18 @@ +T6480588.java:12:24: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6480588.java:12:51: compiler.warn.has.been.deprecated: DeprecatedInterface, compiler.misc.unnamed.package +T6480588.java:11:2: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package +T6480588.java:14:12: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6480588.java:14:65: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6480588.java:13:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package +T6480588.java:14:35: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6480588.java:15:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6480588.java:15:34: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6480588.java:17:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6480588.java:17:35: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6480588.java:26:5: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6480588.java:25:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package +T6480588.java:26:33: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6480588.java:29:25: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package +T6480588.java:29:52: compiler.warn.has.been.deprecated: DeprecatedInterface, compiler.misc.unnamed.package +T6480588.java:28:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package +17 warnings \ No newline at end of file diff --git a/langtools/test/tools/javac/warnings/suppress/T8021112a.java b/langtools/test/tools/javac/warnings/suppress/T8021112a.java new file mode 100644 index 00000000000..4e8b69895fa --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/T8021112a.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, 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. + */ +package test; + +/** + * @test + * @bug 8021112 + * @summary Verify that \\@SuppressWarnings work even if the value is defined + * inside the suppressed class itself, and verify that "unnecessary cast" + * lint can be properly suppressed. + * @compile -Xlint:cast -Werror T8021112a.java + */ + +import static test.T8021112a.D; + +@SuppressWarnings(D) +public class T8021112a { + public static final String D = (String) "cast"; +} + +class Other { + public static final String D = "cast"; + @SuppressWarnings(D) + public static final String D2 = (String) "cast"; +} diff --git a/langtools/test/tools/javac/warnings/suppress/T8021112b.java b/langtools/test/tools/javac/warnings/suppress/T8021112b.java new file mode 100644 index 00000000000..eb391bb1753 --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/T8021112b.java @@ -0,0 +1,22 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8021112 + * @summary Verify that \\@SuppressWarnings("unchecked") works correctly for lazy attrib values + * @build VerifySuppressWarnings + * @compile/ref=T8021112b.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast T8021112b.java + * @run main VerifySuppressWarnings T8021112b.java + */ + +public class T8021112b { + public static final String D1 = Dep.D; + public static final String D2 = ""; + public static final Object[] o = { + new Object() { + Dep d; + } + }; +} + +@Deprecated class Dep { + public static final String D = T8021112b.D2; +} diff --git a/langtools/test/tools/javac/warnings/suppress/T8021112b.out b/langtools/test/tools/javac/warnings/suppress/T8021112b.out new file mode 100644 index 00000000000..bc45f324cde --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/T8021112b.out @@ -0,0 +1,3 @@ +T8021112b.java:11:37: compiler.warn.has.been.deprecated: Dep, compiler.misc.unnamed.package +T8021112b.java:15:13: compiler.warn.has.been.deprecated: Dep, compiler.misc.unnamed.package +2 warnings \ No newline at end of file diff --git a/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.java b/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.java new file mode 100644 index 00000000000..58d63bc9bd0 --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.java @@ -0,0 +1,51 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8021112 + * @summary Verify that \\@SuppressWarnings("unchecked") works for type annotations + * @build VerifySuppressWarnings + * @compile/ref=TypeAnnotations.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast TypeAnnotations.java + * @run main VerifySuppressWarnings TypeAnnotations.java + */ + +import java.lang.annotation.*; + +public class TypeAnnotations extends @TA Object implements @TA Runnable { + + public @TA String @TA [] m(@TA String @TA [] p) throws @TA Throwable { + Runnable r = () -> { + @TA Object tested = null; + @TA boolean isAnnotated = tested instanceof @TA String; + }; + + @TA Object tested = null; + @TA boolean isAnnotated = tested instanceof @TA String; + + return (@TA String @TA []) null; + } + + { + Runnable r = () -> { + @TA Object tested = null; + @TA boolean isAnnotated = tested instanceof @TA String; + }; + + @TA Object tested = null; + @TA boolean isAnnotated = tested instanceof @TA String; + + @TA String @TA [] ret = (@TA String @TA []) null; + } + + @TA String @TA [] f = new @TA String @TA[0]; + + @Override public void run() { } + + public static class Inner extends @TA Object implements @TA Runnable { + @Override public void run() { } + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE}) +@Deprecated +@interface TA { + +} diff --git a/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.out b/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.out new file mode 100644 index 00000000000..52a5484ea5e --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.out @@ -0,0 +1,41 @@ +TypeAnnotations.java:12:39: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:12:61: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:14:24: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:14:61: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:14:13: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:14:44: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:14:33: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:23:29: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:23:18: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:16:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:17:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:17:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:17:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:20:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:21:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:21:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:21:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:23:18: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:23:29: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:28:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:29:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:29:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:29:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:32:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:33:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:33:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:33:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:35:46: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:35:35: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:35:21: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:35:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:35:35: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:35:46: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:38:17: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:38:6: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:38:43: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:38:32: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:38:32: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:42:40: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +TypeAnnotations.java:42:62: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package +40 warnings \ No newline at end of file diff --git a/langtools/test/tools/javac/warnings/suppress/VerifySuppressWarnings.java b/langtools/test/tools/javac/warnings/suppress/VerifySuppressWarnings.java new file mode 100644 index 00000000000..037f2a1764a --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/VerifySuppressWarnings.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.source.tree.ClassTree; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.MethodTree; +import com.sun.source.tree.NewClassTree; +import com.sun.source.tree.Tree; +import com.sun.source.tree.VariableTree; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import com.sun.source.util.Trees; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticListener; +import javax.tools.FileObject; +import javax.tools.ForwardingJavaFileManager; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; + +/**Takes a source file, parses it once to get the warnings inside the file and + * then for each and every declaration in the file, it tries to place + * the @SuppressWarnings annotation on the declaration and verifies than no + * warnings are produced inside the declaration, but all are produced outside it. + * + * Currently only works with unchecked,deprecation,cast warnings. + */ +public class VerifySuppressWarnings { + + private static final List STANDARD_PARAMS = Arrays.asList("-Xlint:unchecked,deprecation,cast", "-Xjcov"); + + public static void main(String... args) throws IOException, URISyntaxException { + if (args.length != 1) throw new IllegalStateException("Must provide class name!"); + String testContent = null; + List sourcePath = new ArrayList<>(); + for (String sourcePaths : System.getProperty("test.src.path").split(":")) { + sourcePath.add(new File(sourcePaths)); + } + JavacFileManager fm = JavacTool.create().getStandardFileManager(null, null, null); + for (File sp : sourcePath) { + File inp = new File(sp, args[0]); + + if (inp.canRead()) { + testContent = fm.getRegularFile(inp).getCharContent(true).toString(); + } + } + if (testContent == null) throw new IllegalStateException(); + final List> diagnostics = new ArrayList<>(); + DiagnosticListener collectDiagnostics = new DiagnosticListener() { + @Override public void report(Diagnostic diagnostic) { + diagnostics.add(diagnostic); + } + }; + JavaFileObject testFile = new TestFO(new URI("mem://" + args[0]), testContent); + JavacTask task = JavacTool.create().getTask(null, + new TestFM(fm), + collectDiagnostics, + STANDARD_PARAMS, + null, + Arrays.asList(testFile)); + final Trees trees = Trees.instance(task); + final CompilationUnitTree cut = task.parse().iterator().next(); + task.analyze(); + + final List declarationSpans = new ArrayList<>(); + + new TreeScanner() { + @Override public Void visitClass(ClassTree node, Void p) { + handleDeclaration(node); + return super.visitClass(node, p); + } + @Override public Void visitMethod(MethodTree node, Void p) { + handleDeclaration(node); + return super.visitMethod(node, p); + } + @Override public Void visitVariable(VariableTree node, Void p) { + handleDeclaration(node); + return super.visitVariable(node, p); + } + + @Override + public Void visitNewClass(NewClassTree node, Void p) { + if (node.getClassBody() != null) { + scan(node.getClassBody().getMembers(), null); + } + return null; + } + + private void handleDeclaration(Tree node) { + int endPos = (int) trees.getSourcePositions().getEndPosition(cut, node); + + if (endPos == (-1)) { + if (node.getKind() == Tree.Kind.METHOD && (((JCMethodDecl) node).getModifiers().flags & Flags.GENERATEDCONSTR) != 0) { + return ; + } + throw new IllegalStateException(); + } + + declarationSpans.add(new int[] {(int) trees.getSourcePositions().getStartPosition(cut, node), endPos}); + } + }.scan(cut, null); + + for (final int[] declarationSpan : declarationSpans) { + final String suppressWarnings = "@SuppressWarnings({\"deprecation\", \"unchecked\", \"serial\"})"; + final String updatedContent = testContent.substring(0, declarationSpan[0]) + suppressWarnings + testContent.substring(declarationSpan[0]); + final List> foundErrors = new ArrayList<>(diagnostics); + DiagnosticListener verifyDiagnostics = new DiagnosticListener() { + @Override public void report(Diagnostic diagnostic) { + long adjustedPos = diagnostic.getPosition(); + + if (adjustedPos >= declarationSpan[0]) adjustedPos -= suppressWarnings.length(); + + if (declarationSpan[0] <= adjustedPos && adjustedPos <= declarationSpan[1]) { + throw new IllegalStateException("unsuppressed: " + diagnostic.getMessage(null)); + } + + boolean found = false; + + for (Iterator> it = foundErrors.iterator(); it.hasNext();) { + Diagnostic d = it.next(); + if (d.getPosition() == adjustedPos && d.getCode().equals(diagnostic.getCode())) { + it.remove(); + found = true; + break; + } + } + + if (!found) { + throw new IllegalStateException("diagnostic not originally reported: " + diagnostic.getMessage(null)); + } + } + }; + + JavaFileObject updatedFile = new TestFO(new URI("mem://" + args[0]), updatedContent); + JavacTask testTask = JavacTool.create().getTask(null, + new TestFM(fm), + verifyDiagnostics, + STANDARD_PARAMS, + null, + Arrays.asList(updatedFile)); + + testTask.analyze(); + + for (Diagnostic d : foundErrors) { + if (d.getPosition() < declarationSpan[0] || declarationSpan[1] < d.getPosition()) { + throw new IllegalStateException("missing: " + d.getMessage(null)); + } + } + } + } + + private static final class TestFO extends SimpleJavaFileObject { + private final String content; + public TestFO(URI uri, String content) { + super(uri, Kind.SOURCE); + this.content = content; + } + + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return content; + } + + @Override public boolean isNameCompatible(String simpleName, Kind kind) { + return true; + } + } + + private static final class TestFM extends ForwardingJavaFileManager { + + public TestFM(JavaFileManager fileManager) { + super(fileManager); + } + + @Override + public boolean isSameFile(FileObject a, FileObject b) { + return a.equals(b); + } + + } +} diff --git a/langtools/test/tools/javac/warnings/suppress/pack/DeprecatedClass.java b/langtools/test/tools/javac/warnings/suppress/pack/DeprecatedClass.java new file mode 100644 index 00000000000..8b7a482298e --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/pack/DeprecatedClass.java @@ -0,0 +1,5 @@ +/* /nodynamiccopyright/ */ +package pack; +@Deprecated +@interface DeprecatedClass { +} diff --git a/langtools/test/tools/javac/warnings/suppress/pack/ImplicitMain.java b/langtools/test/tools/javac/warnings/suppress/pack/ImplicitMain.java new file mode 100644 index 00000000000..22ed4e7def8 --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/pack/ImplicitMain.java @@ -0,0 +1,14 @@ +/* /nodynamiccopyright/ */ +package pack; + +@SuppressWarnings("deprecation") +public class ImplicitMain { + private Object test() { + return new ImplicitUse(); + } +} + +@Deprecated +class Dep { + +} diff --git a/langtools/test/tools/javac/warnings/suppress/pack/ImplicitUse.java b/langtools/test/tools/javac/warnings/suppress/pack/ImplicitUse.java new file mode 100644 index 00000000000..9e9e6cd5916 --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/pack/ImplicitUse.java @@ -0,0 +1,7 @@ +/* /nodynamiccopyright/ */ +package pack; + +import pack.Dep; + +public class ImplicitUse { +} diff --git a/langtools/test/tools/javac/warnings/suppress/pack/package-info.java b/langtools/test/tools/javac/warnings/suppress/pack/package-info.java new file mode 100644 index 00000000000..679de2b4f60 --- /dev/null +++ b/langtools/test/tools/javac/warnings/suppress/pack/package-info.java @@ -0,0 +1,5 @@ +/* /nodynamiccopyright/ */ +@DeprecatedClass +package pack; + +import pack.DeprecatedClass; From 5ddc447fc5785e7993b6d6ad9a7e0bc892526f43 Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Mon, 16 Sep 2013 14:44:20 +0200 Subject: [PATCH 0375/1294] 8024846: keep separate internal arguments variable Reviewed-by: lagergren, sundar --- .../jdk/nashorn/internal/codegen/Attr.java | 89 ++++++++++++------- .../internal/codegen/CompilerConstants.java | 8 +- .../jdk/nashorn/internal/parser/Parser.java | 21 +++-- nashorn/test/script/basic/JDK-8024846.js | 37 ++++++++ 4 files changed, 115 insertions(+), 40 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8024846.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index 88e904dcf58..813d3fc9083 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -26,6 +26,7 @@ package jdk.nashorn.internal.codegen; import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; +import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR; import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE; import static jdk.nashorn.internal.codegen.CompilerConstants.EXCEPTION_PREFIX; import static jdk.nashorn.internal.codegen.CompilerConstants.ITERATOR_PREFIX; @@ -172,7 +173,9 @@ final class Attr extends NodeOperatorVisitor { initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL); if (functionNode.needsArguments()) { initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED); - addLocalDef(ARGUMENTS.symbolName()); + final String argumentsName = ARGUMENTS_VAR.symbolName(); + newType(defineSymbol(body, argumentsName, IS_VAR | IS_ALWAYS_DEFINED), Type.typeFor(ARGUMENTS_VAR.type())); + addLocalDef(argumentsName); } } @@ -491,30 +494,29 @@ final class Attr extends NodeOperatorVisitor { objectifySymbols(body); } + List syntheticInitializers = null; + if (body.getFlag(Block.NEEDS_SELF_SYMBOL)) { - final IdentNode callee = compilerConstant(CALLEE); - VarNode selfInit = - new VarNode( - newFunctionNode.getLineNumber(), - newFunctionNode.getToken(), - newFunctionNode.getFinish(), - newFunctionNode.getIdent(), - callee); + syntheticInitializers = new ArrayList<>(2); + LOG.info("Accepting self symbol init for ", newFunctionNode.getName()); + // "var fn = :callee" + syntheticInitializers.add(createSyntheticInitializer(newFunctionNode.getIdent(), CALLEE, newFunctionNode)); + } - LOG.info("Accepting self symbol init ", selfInit, " for ", newFunctionNode.getName()); + if(newFunctionNode.needsArguments()) { + if(syntheticInitializers == null) { + syntheticInitializers = new ArrayList<>(1); + } + // "var arguments = :arguments" + syntheticInitializers.add(createSyntheticInitializer(createImplicitIdentifier(ARGUMENTS_VAR.symbolName()), + ARGUMENTS, newFunctionNode)); + } - final List newStatements = new ArrayList<>(); - assert callee.getSymbol() != null && callee.getSymbol().hasSlot(); - - final IdentNode name = selfInit.getName(); - final Symbol nameSymbol = body.getExistingSymbol(name.getName()); - - assert nameSymbol != null; - - selfInit = selfInit.setName((IdentNode)name.setSymbol(lc, nameSymbol)); - - newStatements.add(selfInit); - newStatements.addAll(body.getStatements()); + if(syntheticInitializers != null) { + final List stmts = body.getStatements(); + final List newStatements = new ArrayList<>(stmts.size() + syntheticInitializers.size()); + newStatements.addAll(syntheticInitializers); + newStatements.addAll(stmts); newFunctionNode = newFunctionNode.setBody(lc, body.setStatements(lc, newStatements)); } @@ -533,6 +535,28 @@ final class Attr extends NodeOperatorVisitor { return newFunctionNode; } + /** + * Creates a synthetic initializer for a variable (a var statement that doesn't occur in the source code). Typically + * used to create assignmnent of {@code :callee} to the function name symbol in self-referential function + * expressions as well as for assignment of {@code :arguments} to {@code arguments}. + * + * @param name the ident node identifying the variable to initialize + * @param initConstant the compiler constant it is initialized to + * @param fn the function node the assignment is for + * @return a var node with the appropriate assignment + */ + private VarNode createSyntheticInitializer(final IdentNode name, final CompilerConstants initConstant, final FunctionNode fn) { + final IdentNode init = compilerConstant(initConstant); + assert init.getSymbol() != null && init.getSymbol().hasSlot(); + + VarNode synthVar = new VarNode(fn.getLineNumber(), fn.getToken(), fn.getFinish(), name, init); + + final Symbol nameSymbol = fn.getBody().getExistingSymbol(name.getName()); + assert nameSymbol != null; + + return synthVar.setName((IdentNode)name.setSymbol(lc, nameSymbol)); + } + @Override public Node leaveCONVERT(final UnaryNode unaryNode) { assert false : "There should be no convert operators in IR during Attribution"; @@ -974,15 +998,18 @@ final class Attr extends NodeOperatorVisitor { } private IdentNode compilerConstant(CompilerConstants cc) { - final FunctionNode functionNode = lc.getCurrentFunction(); - return (IdentNode) - new IdentNode( - functionNode.getToken(), - functionNode.getFinish(), - cc.symbolName()). - setSymbol( - lc, - functionNode.compilerConstant(cc)); + return (IdentNode)createImplicitIdentifier(cc.symbolName()).setSymbol(lc, lc.getCurrentFunction().compilerConstant(cc)); + } + + /** + * Creates an ident node for an implicit identifier within the function (one not declared in the script source + * code). These identifiers are defined with function's token and finish. + * @param name the name of the identifier + * @return an ident node representing the implicit identifier. + */ + private IdentNode createImplicitIdentifier(final String name) { + final FunctionNode fn = lc.getCurrentFunction(); + return new IdentNode(fn.getToken(), fn.getFinish(), name); } @Override diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java index 5207fbce636..fb347c75afb 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java @@ -102,8 +102,12 @@ public enum CompilerConstants { /** the varargs variable when necessary */ VARARGS(":varargs", Object[].class), - /** the arguments vector when necessary and the slot */ - ARGUMENTS("arguments", ScriptObject.class, 2), + /** the arguments variable (visible to function body). Initially set to ARGUMENTS, but can be reassigned by code in + * the function body.*/ + ARGUMENTS_VAR("arguments", Object.class), + + /** the internal arguments object, when necessary (not visible to scripts, can't be reassigned). */ + ARGUMENTS(":arguments", ScriptObject.class), /** prefix for iterators for for (x in ...) */ ITERATOR_PREFIX(":i", Iterator.class), diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index ea01f5984ed..d051917149e 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -25,7 +25,6 @@ package jdk.nashorn.internal.parser; -import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL; import static jdk.nashorn.internal.codegen.CompilerConstants.FUNCTION_PREFIX; import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT; @@ -115,6 +114,8 @@ import jdk.nashorn.internal.runtime.Timing; * Builds the IR. */ public class Parser extends AbstractParser { + private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName(); + /** Current script environment. */ private final ScriptEnvironment env; @@ -511,13 +512,19 @@ loop: * @param ident Referenced property. */ private void detectSpecialProperty(final IdentNode ident) { - final String name = ident.getName(); - - if (ARGUMENTS.symbolName().equals(name)) { + if (isArguments(ident)) { lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_ARGUMENTS); } } + private static boolean isArguments(final String name) { + return ARGUMENTS_NAME.equals(name); + } + + private static boolean isArguments(final IdentNode ident) { + return isArguments(ident.getName()); + } + /** * Tells whether a IdentNode can be used as L-value of an assignment * @@ -2449,7 +2456,7 @@ loop: } else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.WARNING) { warning(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here.warn"), functionToken); } - if (ARGUMENTS.symbolName().equals(name.getName())) { + if (isArguments(name)) { lc.setFlag(lc.getCurrentFunction(), FunctionNode.DEFINES_ARGUMENTS); } } @@ -2468,7 +2475,7 @@ loop: final IdentNode parameter = parameters.get(i); String parameterName = parameter.getName(); - if (ARGUMENTS.symbolName().equals(parameterName)) { + if (isArguments(parameterName)) { functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS); } @@ -2486,7 +2493,7 @@ loop: parametersSet.add(parameterName); } } else if (arity == 1) { - if (ARGUMENTS.symbolName().equals(parameters.get(0).getName())) { + if (isArguments(parameters.get(0))) { functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS); } } diff --git a/nashorn/test/script/basic/JDK-8024846.js b/nashorn/test/script/basic/JDK-8024846.js new file mode 100644 index 00000000000..ccdf8fcc9b6 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024846.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8024846: keep separate internal arguments variable + * + * @test + */ + +function f() { print(arguments); } + +function func(obj) { + var arguments = obj; + for (var i in arguments) { + } + return obj; +} From 5b376db4f09b35f7c561d3a360c96d716cc7b143 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Mon, 16 Sep 2013 17:45:07 +0400 Subject: [PATCH 0376/1294] 8008728: [macosx] Swing. JDialog. Modal dialog goes to background Reviewed-by: serb --- .../sun/lwawt/macosx/CPlatformWindow.java | 5 +- jdk/src/macosx/native/sun/awt/AWTWindow.m | 16 +++ .../ModalDialogOrderingTest.java | 114 ++++++++++++++++++ 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 jdk/test/java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index d38946d4376..b85942002fb 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -820,6 +820,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo } nativeSetEnabled(getNSWindowPtr(), !blocked); + checkBlockingAndOrder(); } public final void invalidateShadow(){ @@ -984,7 +985,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo setStyleBits(SHOULD_BECOME_KEY | SHOULD_BECOME_MAIN, isFocusable); // set both bits at once } - private boolean checkBlocking() { + private boolean checkBlockingAndOrder() { LWWindowPeer blocker = (peer == null)? null : peer.getBlocker(); if (blocker == null) { return false; @@ -1040,7 +1041,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo private void windowDidBecomeMain() { assert CThreading.assertAppKit(); - if (checkBlocking()) return; + if (checkBlockingAndOrder()) return; // If it's not blocked, make sure it's above its siblings orderAboveSiblings(); } diff --git a/jdk/src/macosx/native/sun/awt/AWTWindow.m b/jdk/src/macosx/native/sun/awt/AWTWindow.m index 5608b4ad98c..89b0f04640b 100644 --- a/jdk/src/macosx/native/sun/awt/AWTWindow.m +++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m @@ -366,6 +366,22 @@ AWT_ASSERT_APPKIT_THREAD; - (BOOL) canBecomeMainWindow { AWT_ASSERT_APPKIT_THREAD; + if(!self.isEnabled){ + // Native system can bring up the NSWindow to + // the top even if the window is not main. + // We should bring up the modal dialog manually + [AWTToolkit eventCountPlusPlus]; + + JNIEnv *env = [ThreadUtilities getJNIEnv]; + jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env]; + if (platformWindow != NULL) { + static JNF_MEMBER_CACHE(jm_checkBlockingAndOrder, jc_CPlatformWindow, + "checkBlockingAndOrder", "()Z"); + JNFCallVoidMethod(env, platformWindow, jm_checkBlockingAndOrder); + (*env)->DeleteLocalRef(env, platformWindow); + } + } + return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_MAIN); } diff --git a/jdk/test/java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java b/jdk/test/java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java new file mode 100644 index 00000000000..e78145e4e12 --- /dev/null +++ b/jdk/test/java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.InputEvent; +import sun.awt.SunToolkit; +/* + * @test + * @bug 8008728 + * @summary [macosx] Swing. JDialog. Modal dialog goes to background + * @author Alexandr Scherbatiy + * @run main ModalDialogOrderingTest + */ + +public class ModalDialogOrderingTest { + + private static final Color DIALOG_COLOR = Color.GREEN; + private static final Color FRAME_COLOR = Color.BLUE; + + public static void main(String[] args) { + + final Frame frame = new Frame("Test"); + frame.setSize(100, 100); + frame.setBackground(FRAME_COLOR); + frame.setVisible(true); + + final Dialog modalDialog = new Dialog((Frame) null, true); + modalDialog.setTitle("Modal Dialog"); + modalDialog.setSize(50, 50); + modalDialog.setBackground(DIALOG_COLOR); + modalDialog.setModal(true); + + new Thread(new Runnable() { + + @Override + public void run() { + runTest(modalDialog, frame); + } + }).start(); + + modalDialog.setVisible(true); + } + + private static void runTest(Dialog dialog, Frame frame) { + try { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(15); + robot.mouseMove(300, 300); + + while (!dialog.isVisible()) { + toolkit.realSync(); + } + + Rectangle dialogBounds = dialog.getBounds(); + Rectangle frameBounds = frame.getBounds(); + + double x0 = dialogBounds.getX(); + double y0 = dialogBounds.getY(); + double x1 = dialogBounds.getX() + dialogBounds.getWidth(); + double y1 = dialogBounds.getY() + dialogBounds.getHeight(); + double x2 = frameBounds.getX() + frameBounds.getWidth(); + double y2 = frameBounds.getY() + frameBounds.getHeight(); + + int clickX = (int) ((x2 + x1) / 2); + int clickY = (int) ((y2 + y1) / 2); + + robot.mouseMove(clickX, clickY); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + int colorX = (int) ((x0 + x1) / 2); + int colorY = (int) ((y0 + y1) / 2); + + Color color = robot.getPixelColor(colorX, colorY); + + dialog.setVisible(false); + frame.setVisible(false); + + if (!DIALOG_COLOR.equals(color)) { + throw new RuntimeException("The frame is on top" + + " of the modal dialog!"); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} From 4d540aa581e7f9ecb8b74cf519238d182b42e28d Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Mon, 16 Sep 2013 14:51:48 +0100 Subject: [PATCH 0377/1294] 6458027: Disabling IPv6 on a specific network interface causes problems Added a check to test if an interface is configured for IPv6 to native code TwoStacklainDatagramSocketImpl: getMulticastInterface, setMulticastInterface Reviewed-by: chegar, michaelm --- .../native/java/net/NetworkInterface.c | 2 +- .../net/TwoStacksPlainDatagramSocketImpl.c | 160 ++++++++++++------ .../SetGetNetworkInterfaceTest.java | 125 ++++++++++++++ 3 files changed, 230 insertions(+), 57 deletions(-) create mode 100644 jdk/test/java/net/MulticastSocket/SetGetNetworkInterfaceTest.java diff --git a/jdk/src/windows/native/java/net/NetworkInterface.c b/jdk/src/windows/native/java/net/NetworkInterface.c index c548930a913..98606fab667 100644 --- a/jdk/src/windows/native/java/net/NetworkInterface.c +++ b/jdk/src/windows/native/java/net/NetworkInterface.c @@ -900,7 +900,7 @@ JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0 MIB_IFROW *ifRowP; ifRowP = getIF(index); if (ifRowP != NULL) { - ret = ifRowP->dwAdminStatus == 1 && + ret = ifRowP->dwAdminStatus == MIB_IF_ADMIN_STATUS_UP && (ifRowP->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL || ifRowP->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED); free(ifRowP); diff --git a/jdk/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c b/jdk/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c index 5adadd28e0f..77496d195cf 100644 --- a/jdk/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c +++ b/jdk/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c @@ -43,6 +43,7 @@ #include "java_net_SocketOptions.h" #include "java_net_NetworkInterface.h" +#include "NetworkInterface.h" #include "jvm.h" #include "jni_util.h" #include "net_util.h" @@ -1644,6 +1645,33 @@ static int getIndexFromIf (JNIEnv *env, jobject nif) { return (*env)->GetIntField(env, nif, ni_indexID); } +static int isAdapterIpv6Enabled(JNIEnv *env, int index) { + netif *ifList, *curr; + int ipv6Enabled = 0; + if (getAllInterfacesAndAddresses (env, &ifList) < 0) { + return ipv6Enabled; + } + + /* search by index */ + curr = ifList; + while (curr != NULL) { + if (index == curr->index) { + break; + } + curr = curr->next; + } + + /* if found ipv6Index != 0 then interface is configured with IPV6 */ + if ((curr != NULL) && (curr->ipv6Index !=0)) { + ipv6Enabled = 1; + } + + /* release the interface list */ + free_netif(ifList); + + return ipv6Enabled; +} + /* * Sets the multicast interface. * @@ -1703,7 +1731,6 @@ static void setMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, struct in_addr in; in.s_addr = htonl(getInetAddress_addr(env, value)); - if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&in, sizeof(in)) < 0) { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", @@ -1734,19 +1761,20 @@ static void setMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, } index = (*env)->GetIntField(env, value, ni_indexID); - if (setsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF, + if ( isAdapterIpv6Enabled(env, index) != 0 ) { + if (setsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF, (const char*)&index, sizeof(index)) < 0) { - if (errno == EINVAL && index > 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", - "IPV6_MULTICAST_IF failed (interface has IPv4 " - "address only?)"); - } else { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + if (errno == EINVAL && index > 0) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + "IPV6_MULTICAST_IF failed (interface has IPv4 " + "address only?)"); + } else { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Error setting socket option"); + } + return; } - return; } - /* If there are any IPv4 addresses on this interface then * repeat the operation on the IPv4 fd */ @@ -1797,7 +1825,6 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketNativeSetOption(JNIEnv *env char c; } optval; int ipv6_supported = ipv6_available(); - fd = getFD(env, this); if (ipv6_supported) { @@ -1898,42 +1925,21 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketNativeSetOption(JNIEnv *env } /* - * Return the multicast interface: * - * SocketOptions.IP_MULTICAST_IF - * IPv4: Query IPPROTO_IP/IP_MULTICAST_IF - * Create InetAddress - * IP_MULTICAST_IF returns struct ip_mreqn on 2.2 - * kernel but struct in_addr on 2.4 kernel - * IPv6: Query IPPROTO_IPV6 / IPV6_MULTICAST_IF or - * obtain from impl is Linux 2.2 kernel - * If index == 0 return InetAddress representing - * anyLocalAddress. - * If index > 0 query NetworkInterface by index - * and returns addrs[0] + * called by getMulticastInterface to retrieve a NetworkInterface + * configured for IPv4. + * The ipv4Mode parameter, is a closet boolean, which allows for a NULL return, + * or forces the creation of a NetworkInterface object with null data. + * It relates to its calling context in getMulticastInterface. + * ipv4Mode == 1, the context is IPV4 processing only. + * ipv4Mode == 0, the context is IPV6 processing * - * SocketOptions.IP_MULTICAST_IF2 - * IPv4: Query IPPROTO_IP/IP_MULTICAST_IF - * Query NetworkInterface by IP address and - * return the NetworkInterface that the address - * is bound too. - * IPv6: Query IPPROTO_IPV6 / IPV6_MULTICAST_IF - * (except Linux .2 kernel) - * Query NetworkInterface by index and - * return NetworkInterface. */ -jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint opt) { - jboolean isIPV4 = !ipv6_available() || fd1 == -1; - - /* - * IPv4 implementation - */ - if (isIPV4) { +static jobject getIPv4NetworkInterface (JNIEnv *env, jobject this, int fd, jint opt, int ipv4Mode) { static jclass inet4_class; static jmethodID inet4_ctrID; - static jclass ni_class; - static jmethodID ni_ctrID; + static jclass ni_class; static jmethodID ni_ctrID; static jfieldID ni_indexID; static jfieldID ni_addrsID; @@ -1944,7 +1950,6 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o struct in_addr in; struct in_addr *inP = ∈ int len = sizeof(struct in_addr); - if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char *)inP, &len) < 0) { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", @@ -1996,23 +2001,57 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o if (ni) { return ni; } + if (ipv4Mode) { + ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0); + CHECK_NULL_RETURN(ni, NULL); - /* - * The address doesn't appear to be bound at any known - * NetworkInterface. Therefore we construct a NetworkInterface - * with this address. - */ - ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0); - CHECK_NULL_RETURN(ni, NULL); - - (*env)->SetIntField(env, ni, ni_indexID, -1); - addrArray = (*env)->NewObjectArray(env, 1, inet4_class, NULL); - CHECK_NULL_RETURN(addrArray, NULL); - (*env)->SetObjectArrayElement(env, addrArray, 0, addr); - (*env)->SetObjectField(env, ni, ni_addrsID, addrArray); + (*env)->SetIntField(env, ni, ni_indexID, -1); + addrArray = (*env)->NewObjectArray(env, 1, inet4_class, NULL); + CHECK_NULL_RETURN(addrArray, NULL); + (*env)->SetObjectArrayElement(env, addrArray, 0, addr); + (*env)->SetObjectField(env, ni, ni_addrsID, addrArray); + } else { + ni = NULL; + } return ni; - } +} +/* + * Return the multicast interface: + * + * SocketOptions.IP_MULTICAST_IF + * IPv4: Query IPPROTO_IP/IP_MULTICAST_IF + * Create InetAddress + * IP_MULTICAST_IF returns struct ip_mreqn on 2.2 + * kernel but struct in_addr on 2.4 kernel + * IPv6: Query IPPROTO_IPV6 / IPV6_MULTICAST_IF or + * obtain from impl is Linux 2.2 kernel + * If index == 0 return InetAddress representing + * anyLocalAddress. + * If index > 0 query NetworkInterface by index + * and returns addrs[0] + * + * SocketOptions.IP_MULTICAST_IF2 + * IPv4: Query IPPROTO_IP/IP_MULTICAST_IF + * Query NetworkInterface by IP address and + * return the NetworkInterface that the address + * is bound too. + * IPv6: Query IPPROTO_IPV6 / IPV6_MULTICAST_IF + * (except Linux .2 kernel) + * Query NetworkInterface by index and + * return NetworkInterface. + */ +jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint opt) { + jboolean isIPV4 = !ipv6_available() || fd1 == -1; + + /* + * IPv4 implementation + */ + if (isIPV4) { + jobject netObject = NULL; // return is either an addr or a netif + netObject = getIPv4NetworkInterface(env, this, fd, opt, 1); + return netObject; + } /* * IPv6 implementation @@ -2103,6 +2142,13 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o addr = (*env)->GetObjectArrayElement(env, addrArray, 0); return addr; + } else if (index == 0) { // index == 0 typically means IPv6 not configured on the interfaces + // falling back to treat interface as configured for IPv4 + jobject netObject = NULL; + netObject = getIPv4NetworkInterface(env, this, fd, opt, 0); + if (netObject != NULL) { + return netObject; + } } /* @@ -2127,6 +2173,8 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o } return NULL; } + + /* * Returns relevant info as a jint. * diff --git a/jdk/test/java/net/MulticastSocket/SetGetNetworkInterfaceTest.java b/jdk/test/java/net/MulticastSocket/SetGetNetworkInterfaceTest.java new file mode 100644 index 00000000000..b46bdbedbce --- /dev/null +++ b/jdk/test/java/net/MulticastSocket/SetGetNetworkInterfaceTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013, 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 6458027 + * @summary Disabling IPv6 on a specific network interface causes problems. + * + */ + +import java.io.IOException; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Arrays; +import java.util.Enumeration; + + +public class SetGetNetworkInterfaceTest { + + public static void main(String[] args) throws Exception { + + boolean passed = true; + try { + MulticastSocket ms = new MulticastSocket(); + Enumeration networkInterfaces = NetworkInterface + .getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + NetworkInterface netIf = networkInterfaces.nextElement(); + if (isNetworkInterfaceTestable(netIf)) { + printNetIfDetails(netIf); + ms.setNetworkInterface(netIf); + NetworkInterface msNetIf = ms.getNetworkInterface(); + if (netIf.equals(msNetIf)) { + System.out.println(" OK"); + } else { + System.out.println("FAILED!!!"); + printNetIfDetails(msNetIf); + passed = false; + } + System.out.println("------------------"); + } + } + } catch (IOException e) { + e.printStackTrace(); + passed = false; + } + if (!passed) { + throw new RuntimeException("Test Fail"); + } + System.out.println("Test passed "); + } + + private static boolean isNetworkInterfaceTestable(NetworkInterface netIf) throws Exception { + System.out.println("checking netif == " + netIf.getName()); + return (netIf.isUp() && netIf.supportsMulticast() && isIpAddrAvailable(netIf)); + } + + private static boolean isIpAddrAvailable (NetworkInterface netIf) { + boolean ipAddrAvailable = false; + byte[] nullIpAddr = {'0', '0', '0', '0'}; + byte[] testIpAddr = null; + + Enumeration ipAddresses = netIf.getInetAddresses(); + while (ipAddresses.hasMoreElements()) { + InetAddress testAddr = ipAddresses.nextElement(); + testIpAddr = testAddr.getAddress(); + if ((testIpAddr != null) && (!Arrays.equals(testIpAddr, nullIpAddr))) { + ipAddrAvailable = true; + break; + } else { + System.out.println("ignore netif " + netIf.getName()); + } + } + return ipAddrAvailable; + } + + private static void printNetIfDetails(NetworkInterface ni) + throws SocketException { + System.out.println("Name " + ni.getName() + " index " + ni.getIndex()); + Enumeration en = ni.getInetAddresses(); + while (en.hasMoreElements()) { + System.out.println(" InetAdress: " + en.nextElement()); + } + System.out.println("HardwareAddress: " + createMacAddrString(ni)); + System.out.println("loopback: " + ni.isLoopback() + "; pointToPoint: " + + ni.isPointToPoint() + "; virtual: " + ni.isVirtual() + + "; MTU: " + ni.getMTU()); + } + + private static String createMacAddrString(NetworkInterface netIf) + throws SocketException { + byte[] macAddr = netIf.getHardwareAddress(); + StringBuilder sb = new StringBuilder(); + if (macAddr != null) { + for (int i = 0; i < macAddr.length; i++) { + sb.append(String.format("%02X%s", macAddr[i], + (i < macAddr.length - 1) ? "-" : "")); + } + } + return sb.toString(); + } +} From 70ab336e389848707f5ffe18dd8dca515683bec4 Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Mon, 16 Sep 2013 18:00:06 +0400 Subject: [PATCH 0378/1294] 8022512: JLightweightFrame: the content pane should be transparent Reviewed-by: anthony --- jdk/src/share/classes/sun/swing/JLightweightFrame.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/sun/swing/JLightweightFrame.java b/jdk/src/share/classes/sun/swing/JLightweightFrame.java index e9a655309e2..dfba20fae2c 100644 --- a/jdk/src/share/classes/sun/swing/JLightweightFrame.java +++ b/jdk/src/share/classes/sun/swing/JLightweightFrame.java @@ -106,7 +106,7 @@ public final class JLightweightFrame extends LightweightFrame implements RootPan public JLightweightFrame() { super(); copyBufferEnabled = "true".equals(AccessController. - doPrivileged(new GetPropertyAction("jlf.copyBufferEnabled", "true"))); + doPrivileged(new GetPropertyAction("swing.jlf.copyBufferEnabled", "true"))); add(rootPane, BorderLayout.CENTER); setFocusTraversalPolicy(new LayoutFocusTraversalPolicy()); @@ -250,6 +250,11 @@ public final class JLightweightFrame extends LightweightFrame implements RootPan }; contentPane.setLayout(new BorderLayout()); contentPane.add(component); + if ("true".equals(AccessController. + doPrivileged(new GetPropertyAction("swing.jlf.contentPaneTransparent", "false")))) + { + contentPane.setOpaque(false); + } setContentPane(contentPane); contentPane.addContainerListener(new ContainerListener() { From 52cf3b81e76671914f7e360bb7da285b577ed394 Mon Sep 17 00:00:00 2001 From: Konstantin Shefov Date: Mon, 16 Sep 2013 19:15:53 +0400 Subject: [PATCH 0379/1294] 7020060: [TEST_BUG] java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java failed Reviewed-by: anthony, serb --- .../java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/test/java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java b/jdk/test/java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java index 3c2a636a094..0d5ada5b74b 100644 --- a/jdk/test/java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java +++ b/jdk/test/java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java @@ -42,6 +42,7 @@ public class TranslucentWindow { GraphicsDevice gd = ge.getDefaultScreenDevice(); Frame f = new Frame("Test frame"); + f.setUndecorated(true); f.setBounds(100, 100, 320, 240); // First, check it can be made fullscreen window without any effects applied From 441fa0cc1d8cfef87b6f38a40f6363a3fe153d0e Mon Sep 17 00:00:00 2001 From: Konstantin Shefov Date: Mon, 16 Sep 2013 19:21:50 +0400 Subject: [PATCH 0380/1294] 8015588: [TEST_BUG] [macosx] Test java/awt/MenuBar/MenuBarSetFont/MenuBarSetFont.java fails on MacOSX Reviewed-by: anthony, serb --- .../java/awt/MenuBar/MenuBarSetFont/MenuBarSetFont.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jdk/test/java/awt/MenuBar/MenuBarSetFont/MenuBarSetFont.java b/jdk/test/java/awt/MenuBar/MenuBarSetFont/MenuBarSetFont.java index 559d7de4d97..9505c12a374 100644 --- a/jdk/test/java/awt/MenuBar/MenuBarSetFont/MenuBarSetFont.java +++ b/jdk/test/java/awt/MenuBar/MenuBarSetFont/MenuBarSetFont.java @@ -65,6 +65,12 @@ public final class MenuBarSetFont { } public static void main(final String[] args) throws Exception { + + if (sun.awt.OSInfo.getOSType() == sun.awt.OSInfo.OSType.MACOSX) { + System.err.println("This test is not for OS X. Menu.setFont() is not supported on OS X."); + return; + } + //Components initialization. frame.setMenuBar(mb); mb.setFont(new Font("Helvetica", Font.ITALIC, 5)); From 9d4a780ccd2057c8ae36373e4a49d2755147eddb Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Mon, 16 Sep 2013 19:38:32 +0400 Subject: [PATCH 0381/1294] 8024779: [macosx] SwingNode crashes on exit Reviewed-by: anthony, ant --- jdk/src/macosx/native/sun/awt/AWTView.m | 2 +- jdk/src/macosx/native/sun/awt/AWTWindow.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/macosx/native/sun/awt/AWTView.m b/jdk/src/macosx/native/sun/awt/AWTView.m index 6ee074f12ab..28bdb4b9077 100644 --- a/jdk/src/macosx/native/sun/awt/AWTView.m +++ b/jdk/src/macosx/native/sun/awt/AWTView.m @@ -126,7 +126,7 @@ AWT_ASSERT_APPKIT_THREAD; self.cglLayer = nil; - JNIEnv *env = [ThreadUtilities getJNIEnv]; + JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; (*env)->DeleteGlobalRef(env, m_cPlatformView); m_cPlatformView = NULL; diff --git a/jdk/src/macosx/native/sun/awt/AWTWindow.m b/jdk/src/macosx/native/sun/awt/AWTWindow.m index 89b0f04640b..c933379f141 100644 --- a/jdk/src/macosx/native/sun/awt/AWTWindow.m +++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m @@ -350,7 +350,7 @@ AWT_ASSERT_APPKIT_THREAD; - (void) dealloc { AWT_ASSERT_APPKIT_THREAD; - JNIEnv *env = [ThreadUtilities getJNIEnv]; + JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; [self.javaPlatformWindow setJObject:nil withEnv:env]; self.nsWindow = nil; From cc5b6c903d58cb2eab9414bc8c295144091fc78b Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Mon, 16 Sep 2013 19:44:47 +0400 Subject: [PATCH 0382/1294] 8024485: For 5-1 step: if input something into the 'File:' and 'Dir:', the dir output isn't empty in the output window after showing and canceling the file dialog Reviewed-by: serb, anthony --- jdk/src/windows/classes/sun/awt/windows/WFileDialogPeer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/src/windows/classes/sun/awt/windows/WFileDialogPeer.java b/jdk/src/windows/classes/sun/awt/windows/WFileDialogPeer.java index 92ec5f337ee..bac55be02d3 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WFileDialogPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WFileDialogPeer.java @@ -182,6 +182,7 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { AWTAccessor.getFileDialogAccessor().setFile(fileDialog, null); AWTAccessor.getFileDialogAccessor().setFiles(fileDialog, null); + AWTAccessor.getFileDialogAccessor().setDirectory(fileDialog, null); WToolkit.executeOnEventHandlerThread(fileDialog, new Runnable() { public void run() { From 43e0cb63278d4ab1a1b4443e1bee83daefbf751c Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Mon, 16 Sep 2013 10:28:20 -0700 Subject: [PATCH 0383/1294] 8024874: Copy-paste typo in the spec for j.u.Comparator.thenComparing(Function, Comparator) Reviewed-by: mduigou --- jdk/src/share/classes/java/util/Comparator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/util/Comparator.java b/jdk/src/share/classes/java/util/Comparator.java index b19481df198..6f9d1663e69 100644 --- a/jdk/src/share/classes/java/util/Comparator.java +++ b/jdk/src/share/classes/java/util/Comparator.java @@ -230,7 +230,7 @@ public interface Comparator { * @param keyComparator the {@code Comparator} used to compare the sort key * @return a lexicographic-order comparator composed of this comparator * and then comparing on the key extracted by the keyExtractor function - * @throws NullPointerException if the argument is null. + * @throws NullPointerException if either argument is null. * @see #comparing(Function, Comparator) * @see #thenComparing(Comparator) * @since 1.8 From 38fb96b8d131732bb2c9e6142308a0d34a709c40 Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Mon, 16 Sep 2013 15:43:06 -0400 Subject: [PATCH 0384/1294] 8024863: X11: Support GNOME Shell as mutter Reviewed-by: anthony --- jdk/src/solaris/classes/sun/awt/X11/XWM.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWM.java b/jdk/src/solaris/classes/sun/awt/X11/XWM.java index 54eaa656232..c76892ed0b7 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWM.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWM.java @@ -592,7 +592,7 @@ final class XWM } static boolean isMutter() { - return isNetWMName("Mutter"); + return isNetWMName("Mutter") || isNetWMName("GNOME Shell"); } static boolean isNonReparentingWM() { From dffefd9ecfd231283a25f48e3a45c92fdeac11ba Mon Sep 17 00:00:00 2001 From: Gerald Thornbrugh Date: Mon, 16 Sep 2013 12:43:34 -0700 Subject: [PATCH 0385/1294] 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian" Cleanup and document how various Linux release info files are used by print_distro_info(). Reviewed-by: dcubed, dsamersoff, coleenp, iklam, omajid --- hotspot/src/os/linux/vm/os_linux.cpp | 58 ++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index de5a7686989..ec6adc5d3ea 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -2169,23 +2169,49 @@ void os::print_os_info(outputStream* st) { } // Try to identify popular distros. -// Most Linux distributions have /etc/XXX-release file, which contains -// the OS version string. Some have more than one /etc/XXX-release file -// (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.), -// so the order is important. +// Most Linux distributions have a /etc/XXX-release file, which contains +// the OS version string. Newer Linux distributions have a /etc/lsb-release +// file that also contains the OS version string. Some have more than one +// /etc/XXX-release file (e.g. Mandrake has both /etc/mandrake-release and +// /etc/redhat-release.), so the order is important. +// Any Linux that is based on Redhat (i.e. Oracle, Mandrake, Sun JDS...) have +// their own specific XXX-release file as well as a redhat-release file. +// Because of this the XXX-release file needs to be searched for before the +// redhat-release file. +// Since Red Hat has a lsb-release file that is not very descriptive the +// search for redhat-release needs to be before lsb-release. +// Since the lsb-release file is the new standard it needs to be searched +// before the older style release files. +// Searching system-release (Red Hat) and os-release (other Linuxes) are a +// next to last resort. The os-release file is a new standard that contains +// distribution information and the system-release file seems to be an old +// standard that has been replaced by the lsb-release and os-release files. +// Searching for the debian_version file is the last resort. It contains +// an informative string like "6.0.6" or "wheezy/sid". Because of this +// "Debian " is printed before the contents of the debian_version file. void os::Linux::print_distro_info(outputStream* st) { - if (!_print_ascii_file("/etc/mandrake-release", st) && - !_print_ascii_file("/etc/sun-release", st) && - !_print_ascii_file("/etc/redhat-release", st) && - !_print_ascii_file("/etc/SuSE-release", st) && - !_print_ascii_file("/etc/turbolinux-release", st) && - !_print_ascii_file("/etc/gentoo-release", st) && - !_print_ascii_file("/etc/debian_version", st) && - !_print_ascii_file("/etc/ltib-release", st) && - !_print_ascii_file("/etc/angstrom-version", st)) { - st->print("Linux"); - } - st->cr(); + if (!_print_ascii_file("/etc/oracle-release", st) && + !_print_ascii_file("/etc/mandriva-release", st) && + !_print_ascii_file("/etc/mandrake-release", st) && + !_print_ascii_file("/etc/sun-release", st) && + !_print_ascii_file("/etc/redhat-release", st) && + !_print_ascii_file("/etc/lsb-release", st) && + !_print_ascii_file("/etc/SuSE-release", st) && + !_print_ascii_file("/etc/turbolinux-release", st) && + !_print_ascii_file("/etc/gentoo-release", st) && + !_print_ascii_file("/etc/ltib-release", st) && + !_print_ascii_file("/etc/angstrom-version", st) && + !_print_ascii_file("/etc/system-release", st) && + !_print_ascii_file("/etc/os-release", st)) { + + if (file_exists("/etc/debian_version")) { + st->print("Debian "); + _print_ascii_file("/etc/debian_version", st); + } else { + st->print("Linux"); + } + } + st->cr(); } void os::Linux::print_libversion_info(outputStream* st) { From 9505ddf1e2ac35d74071f4425bdeba180c11a46a Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Mon, 16 Sep 2013 17:57:56 -0400 Subject: [PATCH 0386/1294] 8024647: Default method resolution with private superclass method Reviewed-by: kamg, minqi --- .../src/share/vm/classfile/defaultMethods.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index b59fe66e062..99a45b55b6d 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -450,6 +450,10 @@ class MethodFamily : public ResourceObj { streamIndentor si(str, indent * 2); str->indent().print("Selected method: "); print_method(str, _selected_target); + Klass* method_holder = _selected_target->method_holder(); + if (!method_holder->is_interface()) { + tty->print(" : in superclass"); + } str->print_cr(""); } @@ -1141,19 +1145,23 @@ static void create_overpasses( #endif // ndef PRODUCT if (method->has_target()) { Method* selected = method->get_selected_target(); - max_stack = assemble_redirect( + if (selected->method_holder()->is_interface()) { + max_stack = assemble_redirect( &bpool, &buffer, slot->signature(), selected, CHECK); + } } else if (method->throws_exception()) { max_stack = assemble_abstract_method_error( &bpool, &buffer, method->get_exception_message(), CHECK); } - AccessFlags flags = accessFlags_from( + if (max_stack != 0) { + AccessFlags flags = accessFlags_from( JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE); - Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), + Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), flags, max_stack, slot->size_of_parameters(), ConstMethod::OVERPASS, CHECK); - if (m != NULL) { - overpasses.push(m); + if (m != NULL) { + overpasses.push(m); + } } } } From 0cd7bc2cde5d0042634e25b269501235707fea7c Mon Sep 17 00:00:00 2001 From: Yumin Qi Date: Mon, 16 Sep 2013 15:35:04 -0700 Subject: [PATCH 0387/1294] 7164841: Improvements to the GC log file rotation Made changes to easily identify current log file in rotation. Parameterize the input with %t for time replacement in file name. Reviewed-by: ccheung, tschatzl, tamao, zgu --- hotspot/src/share/vm/prims/jni.cpp | 2 + hotspot/src/share/vm/runtime/arguments.cpp | 54 ++- hotspot/src/share/vm/utilities/ostream.cpp | 385 ++++++++++++++++----- hotspot/src/share/vm/utilities/ostream.hpp | 18 +- 4 files changed, 357 insertions(+), 102 deletions(-) diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index ea44e2c6679..4fba6577d82 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -5037,6 +5037,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) { #include "gc_implementation/g1/heapRegionRemSet.hpp" #endif #include "utilities/quickSort.hpp" +#include "utilities/ostream.hpp" #if INCLUDE_VM_STRUCTS #include "runtime/vmStructs.hpp" #endif @@ -5060,6 +5061,7 @@ void execute_internal_vm_tests() { run_unit_test(CollectedHeap::test_is_in()); run_unit_test(QuickSort::test_quick_sort()); run_unit_test(AltHashing::test_alt_hash()); + run_unit_test(test_loggc_filename()); #if INCLUDE_VM_STRUCTS run_unit_test(VMStructs::test()); #endif diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index d8a6f90eeef..ef4da6da740 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1839,7 +1839,7 @@ void check_gclog_consistency() { (NumberOfGCLogFiles == 0) || (GCLogFileSize == 0)) { jio_fprintf(defaultStream::output_stream(), - "To enable GC log rotation, use -Xloggc: -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles= -XX:GCLogFileSize=\n" + "To enable GC log rotation, use -Xloggc: -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles= -XX:GCLogFileSize=[k|K|m|M|g|G]\n" "where num_of_file > 0 and num_of_size > 0\n" "GC log rotation is turned off\n"); UseGCLogFileRotation = false; @@ -1853,6 +1853,51 @@ void check_gclog_consistency() { } } +// This function is called for -Xloggc:, it can be used +// to check if a given file name(or string) conforms to the following +// specification: +// A valid string only contains "[A-Z][a-z][0-9].-_%[p|t]" +// %p and %t only allowed once. We only limit usage of filename not path +bool is_filename_valid(const char *file_name) { + const char* p = file_name; + char file_sep = os::file_separator()[0]; + const char* cp; + // skip prefix path + for (cp = file_name; *cp != '\0'; cp++) { + if (*cp == '/' || *cp == file_sep) { + p = cp + 1; + } + } + + int count_p = 0; + int count_t = 0; + while (*p != '\0') { + if ((*p >= '0' && *p <= '9') || + (*p >= 'A' && *p <= 'Z') || + (*p >= 'a' && *p <= 'z') || + *p == '-' || + *p == '_' || + *p == '.') { + p++; + continue; + } + if (*p == '%') { + if(*(p + 1) == 'p') { + p += 2; + count_p ++; + continue; + } + if (*(p + 1) == 't') { + p += 2; + count_t ++; + continue; + } + } + return false; + } + return count_p < 2 && count_t < 2; +} + // Check consistency of GC selection bool Arguments::check_gc_consistency() { check_gclog_consistency(); @@ -2806,6 +2851,13 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, // ostream_init_log(), when called will use this filename // to initialize a fileStream. _gc_log_filename = strdup(tail); + if (!is_filename_valid(_gc_log_filename)) { + jio_fprintf(defaultStream::output_stream(), + "Invalid file name for use with -Xloggc: Filename can only contain the " + "characters [A-Z][a-z][0-9]-_.%%[p|t] but it has been %s\n" + "Note %%p or %%t can only be used once\n", _gc_log_filename); + return JNI_EINVAL; + } FLAG_SET_CMDLINE(bool, PrintGC, true); FLAG_SET_CMDLINE(bool, PrintGCTimeStamps, true); diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp index 2f04fa0e437..0ad9b9eb0dd 100644 --- a/hotspot/src/share/vm/utilities/ostream.cpp +++ b/hotspot/src/share/vm/utilities/ostream.cpp @@ -342,7 +342,7 @@ void stringStream::write(const char* s, size_t len) { } char* stringStream::as_string() { - char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1); + char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1); strncpy(copy, buffer, buffer_pos); copy[buffer_pos] = 0; // terminating null return copy; @@ -355,14 +355,190 @@ outputStream* tty; outputStream* gclog_or_tty; extern Mutex* tty_lock; +#define EXTRACHARLEN 32 +#define CURRENTAPPX ".current" +#define FILENAMEBUFLEN 1024 +// convert YYYY-MM-DD HH:MM:SS to YYYY-MM-DD_HH-MM-SS +char* get_datetime_string(char *buf, size_t len) { + os::local_time_string(buf, len); + int i = (int)strlen(buf); + while (i-- >= 0) { + if (buf[i] == ' ') buf[i] = '_'; + else if (buf[i] == ':') buf[i] = '-'; + } + return buf; +} + +static const char* make_log_name_internal(const char* log_name, const char* force_directory, + int pid, const char* tms) { + const char* basename = log_name; + char file_sep = os::file_separator()[0]; + const char* cp; + char pid_text[32]; + + for (cp = log_name; *cp != '\0'; cp++) { + if (*cp == '/' || *cp == file_sep) { + basename = cp + 1; + } + } + const char* nametail = log_name; + // Compute buffer length + size_t buffer_length; + if (force_directory != NULL) { + buffer_length = strlen(force_directory) + strlen(os::file_separator()) + + strlen(basename) + 1; + } else { + buffer_length = strlen(log_name) + 1; + } + + // const char* star = strchr(basename, '*'); + const char* pts = strstr(basename, "%p"); + int pid_pos = (pts == NULL) ? -1 : (pts - nametail); + + if (pid_pos >= 0) { + jio_snprintf(pid_text, sizeof(pid_text), "pid%u", pid); + buffer_length += strlen(pid_text); + } + + pts = strstr(basename, "%t"); + int tms_pos = (pts == NULL) ? -1 : (pts - nametail); + if (tms_pos >= 0) { + buffer_length += strlen(tms); + } + + // Create big enough buffer. + char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal); + + strcpy(buf, ""); + if (force_directory != NULL) { + strcat(buf, force_directory); + strcat(buf, os::file_separator()); + nametail = basename; // completely skip directory prefix + } + + // who is first, %p or %t? + int first = -1, second = -1; + const char *p1st = NULL; + const char *p2nd = NULL; + + if (pid_pos >= 0 && tms_pos >= 0) { + // contains both %p and %t + if (pid_pos < tms_pos) { + // case foo%pbar%tmonkey.log + first = pid_pos; + p1st = pid_text; + second = tms_pos; + p2nd = tms; + } else { + // case foo%tbar%pmonkey.log + first = tms_pos; + p1st = tms; + second = pid_pos; + p2nd = pid_text; + } + } else if (pid_pos >= 0) { + // contains %p only + first = pid_pos; + p1st = pid_text; + } else if (tms_pos >= 0) { + // contains %t only + first = tms_pos; + p1st = tms; + } + + int buf_pos = (int)strlen(buf); + const char* tail = nametail; + + if (first >= 0) { + tail = nametail + first + 2; + strncpy(&buf[buf_pos], nametail, first); + strcpy(&buf[buf_pos + first], p1st); + buf_pos = (int)strlen(buf); + if (second >= 0) { + strncpy(&buf[buf_pos], tail, second - first - 2); + strcpy(&buf[buf_pos + second - first - 2], p2nd); + tail = nametail + second + 2; + } + } + strcat(buf, tail); // append rest of name, or all of name + return buf; +} + +// log_name comes from -XX:LogFile=log_name or -Xloggc:log_name +// in log_name, %p => pipd1234 and +// %t => YYYY-MM-DD_HH-MM-SS +static const char* make_log_name(const char* log_name, const char* force_directory) { + char timestr[32]; + get_datetime_string(timestr, sizeof(timestr)); + return make_log_name_internal(log_name, force_directory, os::current_process_id(), + timestr); +} + +#ifndef PRODUCT +void test_loggc_filename() { + int pid; + char tms[32]; + char i_result[FILENAMEBUFLEN]; + const char* o_result; + get_datetime_string(tms, sizeof(tms)); + pid = os::current_process_id(); + + // test.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test.log", tms); + o_result = make_log_name_internal("test.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); + + // test-%t-%p.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%s-pid%u.log", tms, pid); + o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); + + // test-%t%p.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%spid%u.log", tms, pid); + o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); + + // %p%t.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u%s.log", pid, tms); + o_result = make_log_name_internal("%p%t.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); + + // %p-test.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u-test.log", pid); + o_result = make_log_name_internal("%p-test.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); + + // %t.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "%s.log", tms); + o_result = make_log_name_internal("%t.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); +} +#endif // PRODUCT + fileStream::fileStream(const char* file_name) { _file = fopen(file_name, "w"); - _need_close = true; + if (_file != NULL) { + _need_close = true; + } else { + warning("Cannot open file %s due to %s\n", file_name, strerror(errno)); + _need_close = false; + } } fileStream::fileStream(const char* file_name, const char* opentype) { _file = fopen(file_name, opentype); - _need_close = true; + if (_file != NULL) { + _need_close = true; + } else { + warning("Cannot open file %s due to %s\n", file_name, strerror(errno)); + _need_close = false; + } } void fileStream::write(const char* s, size_t len) { @@ -423,34 +599,51 @@ void fdStream::write(const char* s, size_t len) { update_position(s, len); } -rotatingFileStream::~rotatingFileStream() { +// dump vm version, os version, platform info, build id, +// memory usage and command line flags into header +void gcLogFileStream::dump_loggc_header() { + if (is_open()) { + print_cr(Abstract_VM_Version::internal_vm_info_string()); + os::print_memory_info(this); + print("CommandLine flags: "); + CommandLineFlags::printSetFlags(this); + } +} + +gcLogFileStream::~gcLogFileStream() { if (_file != NULL) { if (_need_close) fclose(_file); - _file = NULL; + _file = NULL; + } + if (_file_name != NULL) { FREE_C_HEAP_ARRAY(char, _file_name, mtInternal); _file_name = NULL; } } -rotatingFileStream::rotatingFileStream(const char* file_name) { +gcLogFileStream::gcLogFileStream(const char* file_name) { _cur_file_num = 0; _bytes_written = 0L; - _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal); - jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num); - _file = fopen(_file_name, "w"); - _need_close = true; + _file_name = make_log_name(file_name, NULL); + + // gc log file rotation + if (UseGCLogFileRotation && NumberOfGCLogFiles > 1) { + char tempbuf[FILENAMEBUFLEN]; + jio_snprintf(tempbuf, sizeof(tempbuf), "%s.%d" CURRENTAPPX, _file_name, _cur_file_num); + _file = fopen(tempbuf, "w"); + } else { + _file = fopen(_file_name, "w"); + } + if (_file != NULL) { + _need_close = true; + dump_loggc_header(); + } else { + warning("Cannot open file %s due to %s\n", _file_name, strerror(errno)); + _need_close = false; + } } -rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) { - _cur_file_num = 0; - _bytes_written = 0L; - _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal); - jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num); - _file = fopen(_file_name, opentype); - _need_close = true; -} - -void rotatingFileStream::write(const char* s, size_t len) { +void gcLogFileStream::write(const char* s, size_t len) { if (_file != NULL) { size_t count = fwrite(s, 1, len, _file); _bytes_written += count; @@ -466,7 +659,12 @@ void rotatingFileStream::write(const char* s, size_t len) { // write to gc log file at safepoint. If in future, changes made for mutator threads or // concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log // must be synchronized. -void rotatingFileStream::rotate_log() { +void gcLogFileStream::rotate_log() { + char time_msg[FILENAMEBUFLEN]; + char time_str[EXTRACHARLEN]; + char current_file_name[FILENAMEBUFLEN]; + char renamed_file_name[FILENAMEBUFLEN]; + if (_bytes_written < (jlong)GCLogFileSize) { return; } @@ -481,27 +679,89 @@ void rotatingFileStream::rotate_log() { // rotate in same file rewind(); _bytes_written = 0L; + jio_snprintf(time_msg, sizeof(time_msg), "File %s rotated at %s\n", + _file_name, os::local_time_string((char *)time_str, sizeof(time_str))); + write(time_msg, strlen(time_msg)); + dump_loggc_header(); return; } - // rotate file in names file.0, file.1, file.2, ..., file. - // close current file, rotate to next file +#if defined(_WINDOWS) +#ifndef F_OK +#define F_OK 0 +#endif +#endif // _WINDOWS + + // rotate file in names extended_filename.0, extended_filename.1, ..., + // extended_filename.. Current rotation file name will + // have a form of extended_filename..current where i is the current rotation + // file number. After it reaches max file size, the file will be saved and renamed + // with .current removed from its tail. + size_t filename_len = strlen(_file_name); if (_file != NULL) { - _cur_file_num ++; - if (_cur_file_num >= NumberOfGCLogFiles) _cur_file_num = 0; - jio_snprintf(_file_name, strlen(Arguments::gc_log_filename()) + 10, "%s.%d", - Arguments::gc_log_filename(), _cur_file_num); + jio_snprintf(renamed_file_name, filename_len + EXTRACHARLEN, "%s.%d", + _file_name, _cur_file_num); + jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX, + _file_name, _cur_file_num); + jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file has reached the" + " maximum size. Saved as %s\n", + os::local_time_string((char *)time_str, sizeof(time_str)), + renamed_file_name); + write(time_msg, strlen(time_msg)); + fclose(_file); _file = NULL; + + bool can_rename = true; + if (access(current_file_name, F_OK) != 0) { + // current file does not exist? + warning("No source file exists, cannot rename\n"); + can_rename = false; + } + if (can_rename) { + if (access(renamed_file_name, F_OK) == 0) { + if (remove(renamed_file_name) != 0) { + warning("Could not delete existing file %s\n", renamed_file_name); + can_rename = false; + } + } else { + // file does not exist, ok to rename + } + } + if (can_rename && rename(current_file_name, renamed_file_name) != 0) { + warning("Could not rename %s to %s\n", _file_name, renamed_file_name); + } } - _file = fopen(_file_name, "w"); + + _cur_file_num++; + if (_cur_file_num > NumberOfGCLogFiles - 1) _cur_file_num = 0; + jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX, + _file_name, _cur_file_num); + _file = fopen(current_file_name, "w"); + if (_file != NULL) { _bytes_written = 0L; _need_close = true; + // reuse current_file_name for time_msg + jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, + "%s.%d", _file_name, _cur_file_num); + jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file created %s\n", + os::local_time_string((char *)time_str, sizeof(time_str)), + current_file_name); + write(time_msg, strlen(time_msg)); + dump_loggc_header(); + // remove the existing file + if (access(current_file_name, F_OK) == 0) { + if (remove(current_file_name) != 0) { + warning("Could not delete existing file %s\n", current_file_name); + } + } } else { - tty->print_cr("failed to open rotation log file %s due to %s\n", + warning("failed to open rotation log file %s due to %s\n" + "Turned off GC log file rotation\n", _file_name, strerror(errno)); _need_close = false; + FLAG_SET_DEFAULT(UseGCLogFileRotation, false); } } @@ -530,66 +790,6 @@ bool defaultStream::has_log_file() { return _log_file != NULL; } -static const char* make_log_name(const char* log_name, const char* force_directory) { - const char* basename = log_name; - char file_sep = os::file_separator()[0]; - const char* cp; - for (cp = log_name; *cp != '\0'; cp++) { - if (*cp == '/' || *cp == file_sep) { - basename = cp+1; - } - } - const char* nametail = log_name; - - // Compute buffer length - size_t buffer_length; - if (force_directory != NULL) { - buffer_length = strlen(force_directory) + strlen(os::file_separator()) + - strlen(basename) + 1; - } else { - buffer_length = strlen(log_name) + 1; - } - - const char* star = strchr(basename, '*'); - int star_pos = (star == NULL) ? -1 : (star - nametail); - int skip = 1; - if (star == NULL) { - // Try %p - star = strstr(basename, "%p"); - if (star != NULL) { - skip = 2; - } - } - star_pos = (star == NULL) ? -1 : (star - nametail); - - char pid[32]; - if (star_pos >= 0) { - jio_snprintf(pid, sizeof(pid), "%u", os::current_process_id()); - buffer_length += strlen(pid); - } - - // Create big enough buffer. - char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal); - - strcpy(buf, ""); - if (force_directory != NULL) { - strcat(buf, force_directory); - strcat(buf, os::file_separator()); - nametail = basename; // completely skip directory prefix - } - - if (star_pos >= 0) { - // convert foo*bar.log or foo%pbar.log to foo123bar.log - int buf_pos = (int) strlen(buf); - strncpy(&buf[buf_pos], nametail, star_pos); - strcpy(&buf[buf_pos + star_pos], pid); - nametail += star_pos + skip; // skip prefix and pid format - } - - strcat(buf, nametail); // append rest of name, or all of name - return buf; -} - void defaultStream::init_log() { // %%% Need a MutexLocker? const char* log_name = LogFile != NULL ? LogFile : "hotspot.log"; @@ -877,11 +1077,8 @@ void ostream_init_log() { gclog_or_tty = tty; // default to tty if (Arguments::gc_log_filename() != NULL) { - fileStream * gclog = UseGCLogFileRotation ? - new(ResourceObj::C_HEAP, mtInternal) - rotatingFileStream(Arguments::gc_log_filename()) : - new(ResourceObj::C_HEAP, mtInternal) - fileStream(Arguments::gc_log_filename()); + fileStream * gclog = new(ResourceObj::C_HEAP, mtInternal) + gcLogFileStream(Arguments::gc_log_filename()); if (gclog->is_open()) { // now we update the time stamp of the GC log to be synced up // with tty. diff --git a/hotspot/src/share/vm/utilities/ostream.hpp b/hotspot/src/share/vm/utilities/ostream.hpp index 4d13847663e..9b1b1217b49 100644 --- a/hotspot/src/share/vm/utilities/ostream.hpp +++ b/hotspot/src/share/vm/utilities/ostream.hpp @@ -231,20 +231,24 @@ class fdStream : public outputStream { void flush() {}; }; -class rotatingFileStream : public fileStream { +class gcLogFileStream : public fileStream { protected: - char* _file_name; + const char* _file_name; jlong _bytes_written; - uintx _cur_file_num; // current logfile rotation number, from 0 to MaxGCLogFileNumbers-1 + uintx _cur_file_num; // current logfile rotation number, from 0 to NumberOfGCLogFiles-1 public: - rotatingFileStream(const char* file_name); - rotatingFileStream(const char* file_name, const char* opentype); - rotatingFileStream(FILE* file) : fileStream(file) {} - ~rotatingFileStream(); + gcLogFileStream(const char* file_name); + ~gcLogFileStream(); virtual void write(const char* c, size_t len); virtual void rotate_log(); + void dump_loggc_header(); }; +#ifndef PRODUCT +// unit test for checking -Xloggc: parsing result +void test_loggc_filename(); +#endif + void ostream_init(); void ostream_init_log(); void ostream_exit(); From d11f6f252b8abc75927b658f44a32fab9a21f8fb Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Tue, 17 Sep 2013 08:39:20 +0200 Subject: [PATCH 0388/1294] 8024128: guarantee(codelet_size > 0 && (size_t)codelet_size > 2*K) failed: not enough space for interpreter generation Increase interpreter size for x86 template interpreter Reviewed-by: kvn, iveresov --- hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp index c828c90fba1..a632fbab313 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp @@ -34,9 +34,9 @@ // Run with +PrintInterpreter to get the VM to print out the size. // Max size with JVMTI #ifdef AMD64 - const static int InterpreterCodeSize = 200 * 1024; + const static int InterpreterCodeSize = 208 * 1024; #else - const static int InterpreterCodeSize = 168 * 1024; + const static int InterpreterCodeSize = 176 * 1024; #endif // AMD64 #endif // CPU_X86_VM_TEMPLATEINTERPRETER_X86_HPP From 7e77954221a2ef8c24f9686c047be45af1b511d8 Mon Sep 17 00:00:00 2001 From: Dan Horak Date: Tue, 17 Sep 2013 12:04:11 +0200 Subject: [PATCH 0389/1294] 8024914: Swapped usage of idx_t and bm_word_t types in bitMap.inline.hpp Incorrect usage of idx_t where bm_word_t is appropriate. Reviewed-by: tschatzl, brutisso --- .../src/share/vm/utilities/bitMap.inline.hpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/hotspot/src/share/vm/utilities/bitMap.inline.hpp b/hotspot/src/share/vm/utilities/bitMap.inline.hpp index 7bb244795fc..2171e849f8f 100644 --- a/hotspot/src/share/vm/utilities/bitMap.inline.hpp +++ b/hotspot/src/share/vm/utilities/bitMap.inline.hpp @@ -52,16 +52,16 @@ inline void BitMap::clear_bit(idx_t bit) { inline bool BitMap::par_set_bit(idx_t bit) { verify_index(bit); - volatile idx_t* const addr = word_addr(bit); - const idx_t mask = bit_mask(bit); - idx_t old_val = *addr; + volatile bm_word_t* const addr = word_addr(bit); + const bm_word_t mask = bit_mask(bit); + bm_word_t old_val = *addr; do { - const idx_t new_val = old_val | mask; + const bm_word_t new_val = old_val | mask; if (new_val == old_val) { return false; // Someone else beat us to it. } - const idx_t cur_val = (idx_t) Atomic::cmpxchg_ptr((void*) new_val, + const bm_word_t cur_val = (bm_word_t) Atomic::cmpxchg_ptr((void*) new_val, (volatile void*) addr, (void*) old_val); if (cur_val == old_val) { @@ -73,16 +73,16 @@ inline bool BitMap::par_set_bit(idx_t bit) { inline bool BitMap::par_clear_bit(idx_t bit) { verify_index(bit); - volatile idx_t* const addr = word_addr(bit); - const idx_t mask = ~bit_mask(bit); - idx_t old_val = *addr; + volatile bm_word_t* const addr = word_addr(bit); + const bm_word_t mask = ~bit_mask(bit); + bm_word_t old_val = *addr; do { - const idx_t new_val = old_val & mask; + const bm_word_t new_val = old_val & mask; if (new_val == old_val) { return false; // Someone else beat us to it. } - const idx_t cur_val = (idx_t) Atomic::cmpxchg_ptr((void*) new_val, + const bm_word_t cur_val = (bm_word_t) Atomic::cmpxchg_ptr((void*) new_val, (volatile void*) addr, (void*) old_val); if (cur_val == old_val) { From 508e958dfe7856e132e0b9c42573220ce5002ceb Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Tue, 17 Sep 2013 07:56:56 -0400 Subject: [PATCH 0390/1294] 7097386: Correct error in Predicate javadoc example Reviewed-by: alanb, shade --- .../classes/javax/sql/rowset/Predicate.java | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/jdk/src/share/classes/javax/sql/rowset/Predicate.java b/jdk/src/share/classes/javax/sql/rowset/Predicate.java index 63d76fdca6b..5b9676d67f4 100644 --- a/jdk/src/share/classes/javax/sql/rowset/Predicate.java +++ b/jdk/src/share/classes/javax/sql/rowset/Predicate.java @@ -56,44 +56,43 @@ import java.sql.*; *
    {@code
      *    public class Range implements Predicate {
      *
    - *       private Object lo[];
    - *       private Object hi[];
    - *       private int idx[];
    + *       private int[] lo;
    + *       private int[] hi;
    + *       private int[] idx;
      *
    - *       public Range(Object[] lo, Object[] hi, int[] idx) {
    + *       public Range(int[] lo, int[] hi, int[] idx) {
      *          this.lo = lo;
      *          this.hi = hi;
      *          this.idx = idx;
      *       }
      *
      *      public boolean evaluate(RowSet rs) {
    - *          CachedRowSet crs = (CachedRowSet)rs;
    - *          boolean bool1,bool2;
      *
      *          // Check the present row determine if it lies
      *          // within the filtering criteria.
      *
      *          for (int i = 0; i < idx.length; i++) {
    + *             int value;
    + *             try {
    + *                 value = (Integer) rs.getObject(idx[i]);
    + *             } catch (SQLException ex) {
    + *                 Logger.getLogger(Range.class.getName()).log(Level.SEVERE, null, ex);
    + *                 return false;
    + *             }
      *
    - *              if ((rs.getObject(idx[i]) >= lo[i]) &&
    - *                  (rs.getObject(idx[i]) >= hi[i]) {
    - *                  bool1 = true; // within filter constraints
    - *              } else {
    - *                  bool2 = true; // outside of filter constraints
    - *              }
    - *          }
    - *
    - *          if (bool2) {
    - *             return false;
    - *          } else {
    - *             return true;
    - *          }
    + *             if (value < lo[i] && value > hi[i]) {
    + *                 // outside of filter constraints
    + *                 return false;
    + *             }
    + *         }
    + *         // Within filter constraints
    + *        return true;
      *      }
    - *  }
    + *   }
      * }
    *

    * The example above implements a simple range predicate. Note, that - * implementations should but are not required to provider String + * implementations should but are not required to provide String * and integer index based constructors to provide for JDBC RowSet Implementation * applications that use both column identification conventions. * From e6c8a775ed5dc5105af44858bc22317665a8dc3b Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Tue, 17 Sep 2013 14:02:53 +0200 Subject: [PATCH 0391/1294] 8024884: Test name changed, test list not updated Updated the test list with the new test name. Reviewed-by: brutisso, ehelin --- hotspot/test/TEST.groups | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index bf5e3f088fb..a75ac20ce62 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -62,7 +62,7 @@ jdk = \ # needs_jdk = \ gc/TestG1ZeroPGCTJcmdThreadPrint.java \ - gc/metaspace/ClassMetaspaceSizeInJmapHeap.java \ + gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java \ gc/metaspace/TestMetaspacePerfCounters.java \ runtime/6819213/TestBootNativeLibraryPath.java \ runtime/6878713/Test6878713.sh \ From 0051ace82a86bb3cfa9cf825d4c7d025f5ac901e Mon Sep 17 00:00:00 2001 From: Christian Tornqvist Date: Tue, 17 Sep 2013 16:55:53 +0200 Subject: [PATCH 0392/1294] 8014905: [TESTBUG] Some hotspot tests should be updated to divide test jdk and compile jdk Change JDKToolFinder to look in compile.jdk if the executable cannot be found in test.jdk Reviewed-by: dholmes, hseigel --- hotspot/test/TEST.groups | 11 --- hotspot/test/gc/TestVerifyDuringStartup.java | 2 +- .../java/testlibrary/JDKToolFinder.java | 81 ++++++++++++++----- 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index bf5e3f088fb..e6d88dc4b06 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -72,18 +72,7 @@ needs_jdk = \ runtime/7194254/Test7194254.java \ runtime/jsig/Test8017498.sh \ runtime/Metaspace/FragmentMetaspace.java \ - runtime/NMT/BaselineWithParameter.java \ - runtime/NMT/JcmdScale.java \ - runtime/NMT/JcmdWithNMTDisabled.java \ - runtime/NMT/MallocTestType.java \ runtime/NMT/ReleaseCommittedMemory.java \ - runtime/NMT/ShutdownTwice.java \ - runtime/NMT/SummaryAfterShutdown.java \ - runtime/NMT/SummarySanityCheck.java \ - runtime/NMT/ThreadedMallocTestType.java \ - runtime/NMT/ThreadedVirtualAllocTestType.java \ - runtime/NMT/VirtualAllocTestType.java \ - runtime/RedefineObject/TestRedefineObject.java \ serviceability/attach/AttachWithStalePidFile.java # JRE adds further tests to compact3 diff --git a/hotspot/test/gc/TestVerifyDuringStartup.java b/hotspot/test/gc/TestVerifyDuringStartup.java index 4ac32bf118e..f4ac347f80e 100644 --- a/hotspot/test/gc/TestVerifyDuringStartup.java +++ b/hotspot/test/gc/TestVerifyDuringStartup.java @@ -48,7 +48,7 @@ public class TestVerifyDuringStartup { "-XX:+VerifyDuringStartup", "-version"}); - System.out.print("Testing:\n" + JDKToolFinder.getCurrentJDKTool("java")); + System.out.print("Testing:\n" + JDKToolFinder.getJDKTool("java")); for (int i = 0; i < vmOpts.size(); i += 1) { System.out.print(" " + vmOpts.get(i)); } diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java index a39abbd3626..6434135c108 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java @@ -23,7 +23,9 @@ package com.oracle.java.testlibrary; -import java.io.File; +import java.io.FileNotFoundException; +import java.nio.file.Path; +import java.nio.file.Paths; public final class JDKToolFinder { @@ -32,38 +34,73 @@ public final class JDKToolFinder { /** * Returns the full path to an executable in jdk/bin based on System - * property {@code compile.jdk} (set by jtreg test suite) + * property {@code test.jdk} or {@code compile.jdk} (both are set by the jtreg test suite) * * @return Full path to an executable in jdk/bin */ public static String getJDKTool(String tool) { - String binPath = System.getProperty("compile.jdk"); - if (binPath == null) { - throw new RuntimeException("System property 'compile.jdk' not set. " - + "This property is normally set by jtreg. " - + "When running test separately, set this property using " - + "'-Dcompile.jdk=/path/to/jdk'."); - } - binPath += File.separatorChar + "bin" + File.separatorChar + tool; - return binPath; + // First try to find the executable in test.jdk + try { + return getTool(tool, "test.jdk"); + } catch (FileNotFoundException e) { + + } + + // Now see if it's available in compile.jdk + try { + return getTool(tool, "compile.jdk"); + } catch (FileNotFoundException e) { + throw new RuntimeException("Failed to find " + tool + + ", looked in test.jdk (" + System.getProperty("test.jdk") + + ") and compile.jdk (" + System.getProperty("compile.jdk") + ")"); + } } + /** - * Returns the full path to an executable in <current jdk>/bin based - * on System property {@code test.jdk} (set by jtreg test suite) + * Returns the full path to an executable in jdk/bin based on System + * property {@code compile.jdk} * * @return Full path to an executable in jdk/bin */ - public static String getCurrentJDKTool(String tool) { - String binPath = System.getProperty("test.jdk"); - if (binPath == null) { - throw new RuntimeException("System property 'test.jdk' not set. " - + "This property is normally set by jtreg. " - + "When running test separately, set this property using " - + "'-Dtest.jdk=/path/to/jdk'."); + public static String getCompileJDKTool(String tool) { + try { + return getTool(tool, "compile.jdk"); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); } - binPath += File.separatorChar + "bin" + File.separatorChar + tool; + } - return binPath; + /** + * Returns the full path to an executable in jdk/bin based on System + * property {@code test.jdk} + * + * @return Full path to an executable in jdk/bin + */ + public static String getTestJDKTool(String tool) { + try { + return getTool(tool, "test.jdk"); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + + private static String getTool(String tool, String property) throws FileNotFoundException { + String jdkPath = System.getProperty(property); + + if (jdkPath == null) { + throw new RuntimeException( + "System property '" + property + "' not set. This property is normally set by jtreg. " + + "When running test separately, set this property using '-D" + property + "=/path/to/jdk'."); + } + + Path toolName = Paths.get("bin", tool + (Platform.isWindows() ? ".exe" : "")); + + Path jdkTool = Paths.get(jdkPath, toolName.toString()); + if (!jdkTool.toFile().exists()) { + throw new FileNotFoundException("Could not find file " + jdkTool.toAbsolutePath()); + } + + return jdkTool.toAbsolutePath().toString(); } } From 86d8a77b06c526275a547f0d2a20f675746a9294 Mon Sep 17 00:00:00 2001 From: Peter Allwin Date: Tue, 17 Sep 2013 17:16:28 +0200 Subject: [PATCH 0393/1294] 7196151: ParserTest SEGv on solaris Reviewed-by: sla, coleenp, ctornqvi, dsamersoff --- hotspot/src/share/vm/services/diagnosticArgument.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/services/diagnosticArgument.cpp b/hotspot/src/share/vm/services/diagnosticArgument.cpp index 0a1c20d8a2c..51126f063b4 100644 --- a/hotspot/src/share/vm/services/diagnosticArgument.cpp +++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp @@ -61,7 +61,7 @@ void GenDCmdArgument::to_string(MemorySizeArgument m, char* buf, size_t len) { } void GenDCmdArgument::to_string(char* c, char* buf, size_t len) { - jio_snprintf(buf, len, "%s", c); + jio_snprintf(buf, len, "%s", (c != NULL) ? c : ""); } void GenDCmdArgument::to_string(StringArrayArgument* f, char* buf, size_t len) { From a19b450d568a4b09b78fbaf5b23ffe9b2eaed03a Mon Sep 17 00:00:00 2001 From: Mikhailo Seledtsov Date: Tue, 17 Sep 2013 20:09:32 +0200 Subject: [PATCH 0394/1294] 8016029: test runtime/6878713/Test6878713.sh failed Rewrote test in Java; updated the test condition to reflect latest changes in the source Reviewed-by: dholmes, ctornqvi --- hotspot/test/runtime/6878713/Test6878713.sh | 137 ------------------ .../ClassFile/OomWhileParsingRepeatedJsr.java | 74 ++++++++++ .../{6878713 => ClassFile}/testcase.jar | Bin 3 files changed, 74 insertions(+), 137 deletions(-) delete mode 100644 hotspot/test/runtime/6878713/Test6878713.sh create mode 100644 hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java rename hotspot/test/runtime/{6878713 => ClassFile}/testcase.jar (100%) diff --git a/hotspot/test/runtime/6878713/Test6878713.sh b/hotspot/test/runtime/6878713/Test6878713.sh deleted file mode 100644 index a2b5b2d2eb7..00000000000 --- a/hotspot/test/runtime/6878713/Test6878713.sh +++ /dev/null @@ -1,137 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2011, 2013, 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 6878713 -## @bug 7030610 -## @bug 7037122 -## @bug 7123945 -## @summary Verifier heap corruption, relating to backward jsrs -## @run shell Test6878713.sh -## -## some tests require path to find test source dir -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -TARGET_CLASS=OOMCrashClass1960_2 - -echo "INFO: extracting the target class." -${COMPILEJAVA}${FS}bin${FS}jar xvf \ - ${TESTSRC}${FS}testcase.jar ${TARGET_CLASS}.class - -# remove any hs_err_pid that might exist here -rm -f hs_err_pid*.log - -echo "INFO: checking for 32-bit versus 64-bit VM." -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version 2>&1 \ - | grep "64-Bit [^ ][^ ]* VM" > /dev/null 2>&1 -status="$?" -if [ "$status" = 0 ]; then - echo "INFO: testing a 64-bit VM." - is_64_bit=true -else - echo "INFO: testing a 32-bit VM." -fi - -if [ "$is_64_bit" = true ]; then - # limit is 768MB in 8-byte words (1024 * 1024 * 768 / 8) == 100663296 - MALLOC_MAX=100663296 -else - # limit is 768MB in 4-byte words (1024 * 1024 * 768 / 4) == 201326592 - MALLOC_MAX=201326592 -fi -echo "INFO: MALLOC_MAX=$MALLOC_MAX" - -echo "INFO: executing the target class." -# -XX:+PrintCommandLineFlags for debugging purposes -# -XX:+IgnoreUnrecognizedVMOptions so test will run on a VM without -# the new -XX:MallocMaxTestWords option -# -XX:+UnlockDiagnosticVMOptions so we can use -XX:MallocMaxTestWords -# -XX:MallocMaxTestWords limits malloc to $MALLOC_MAX -${TESTJAVA}${FS}bin${FS}java \ - -XX:+PrintCommandLineFlags \ - -XX:+IgnoreUnrecognizedVMOptions \ - -XX:+UnlockDiagnosticVMOptions \ - -XX:MallocMaxTestWords=$MALLOC_MAX \ - ${TESTVMOPTS} ${TARGET_CLASS} > test.out 2>&1 - -echo "INFO: begin contents of test.out:" -cat test.out -echo "INFO: end contents of test.out." - -echo "INFO: checking for memory allocation error message." -# We are looking for this specific memory allocation failure mesg so -# we know we exercised the right allocation path with the test class: -MESG1="Native memory allocation (malloc) failed to allocate 25696531[0-9][0-9] bytes" -grep "$MESG1" test.out -status="$?" -if [ "$status" = 0 ]; then - echo "INFO: found expected memory allocation error message." -else - echo "INFO: did not find expected memory allocation error message." - - # If we didn't find MESG1 above, then there are several scenarios: - # 1) -XX:MallocMaxTestWords is not supported by the current VM and we - # didn't fail TARGET_CLASS's memory allocation attempt; instead - # we failed to find TARGET_CLASS's main() method. The TARGET_CLASS - # is designed to provoke a memory allocation failure during class - # loading; we actually don't care about running the class which is - # why it doesn't have a main() method. - # 2) we failed a memory allocation, but not the one we were looking - # so it might be that TARGET_CLASS no longer tickles the same - # memory allocation code path - # 3) TARGET_CLASS reproduces the failure mode (SIGSEGV) fixed by - # 6878713 because the test is running on a pre-fix VM. - echo "INFO: checking for no main() method message." - MESG2="Error: Main method not found in class" - grep "$MESG2" test.out - status="$?" - if [ "$status" = 0 ]; then - echo "INFO: found no main() method message." - else - echo "FAIL: did not find no main() method message." - # status is non-zero for exit below - - if [ -s hs_err_pid*.log ]; then - echo "INFO: begin contents of hs_err_pid file:" - cat hs_err_pid*.log - echo "INFO: end contents of hs_err_pid file." - fi - fi -fi - -if [ "$status" = 0 ]; then - echo "PASS: test found one of the expected messages." -fi -exit "$status" diff --git a/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java b/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java new file mode 100644 index 00000000000..ad08b183e59 --- /dev/null +++ b/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011, 2013, 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 OomWhileParsingRepeatedJsr + * @summary Testing class file parser; specifically parsing + * a file with repeated JSR (jump local subroutine) + * bytecode command. + * @bug 6878713 + * @bug 7030610 + * @bug 7037122 + * @bug 7123945 + * @bug 8016029 + * @library /testlibrary + * @run main OomWhileParsingRepeatedJsr + */ + +import com.oracle.java.testlibrary.*; + + +public class OomWhileParsingRepeatedJsr { + + public static void main(String[] args) throws Exception { + + // ======= Configure the test + String jarFile = System.getProperty("test.src") + "/testcase.jar"; + String className = "OOMCrashClass1960_2"; + + // limit is 768MB in native words + int mallocMaxTestWords = (1024 * 1024 * 768 / 4); + if (Platform.is64bit()) + mallocMaxTestWords = (mallocMaxTestWords / 2); + + // ======= extract the test class + ProcessBuilder pb = new ProcessBuilder(new String[] { + JDKToolFinder.getJDKTool("jar"), + "xvf", jarFile } ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + // ======= execute the test + pb = ProcessTools.createJavaProcessBuilder( + "-cp", ".", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:MallocMaxTestWords=" + mallocMaxTestWords, + className ); + + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Cannot reserve enough memory"); + } +} + diff --git a/hotspot/test/runtime/6878713/testcase.jar b/hotspot/test/runtime/ClassFile/testcase.jar similarity index 100% rename from hotspot/test/runtime/6878713/testcase.jar rename to hotspot/test/runtime/ClassFile/testcase.jar From 876967ae1f16b587efc44c93334b2155b8931a9d Mon Sep 17 00:00:00 2001 From: Mikhailo Seledtsov Date: Tue, 17 Sep 2013 20:20:03 +0200 Subject: [PATCH 0395/1294] 7149464: [TESTBUG] Test runtime/7020373/Test7020373.sh failed to clean up files after test Re-wrote in Java, this also eliminated temporary result file; set upper limit on malloc'd memory Reviewed-by: dcubed, dholmes, ccheung --- hotspot/test/runtime/7020373/Test7020373.sh | 43 -------- .../test/runtime/ClassFile/JsrRewriting.java | 102 ++++++++++++++++++ .../JsrRewritingTestCase.jar} | Bin 3 files changed, 102 insertions(+), 43 deletions(-) delete mode 100644 hotspot/test/runtime/7020373/Test7020373.sh create mode 100644 hotspot/test/runtime/ClassFile/JsrRewriting.java rename hotspot/test/runtime/{7020373/testcase.jar => ClassFile/JsrRewritingTestCase.jar} (100%) diff --git a/hotspot/test/runtime/7020373/Test7020373.sh b/hotspot/test/runtime/7020373/Test7020373.sh deleted file mode 100644 index 83b7028c82f..00000000000 --- a/hotspot/test/runtime/7020373/Test7020373.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -## -## @test -## @bug 7020373 7055247 7053586 7185550 -## @key cte_test -## @summary JSR rewriting can overflow memory address size variables -## @ignore Ignore it as 7053586 test uses lots of memory. See bug report for detail. -## @run shell Test7020373.sh -## - -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -${COMPILEJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar - -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass4000_1 > test.out 2>&1 - -cat test.out - -egrep "SIGSEGV|An unexpected error has been detected" test.out - -if [ $? = 0 ] -then - echo "Test Failed" - exit 1 -else - egrep "java.lang.LinkageError|java.lang.NoSuchMethodError|Main method not found in class OOMCrashClass4000_1|insufficient memory" test.out - if [ $? = 0 ] - then - echo "Test Passed" - exit 0 - else - echo "Test Failed" - exit 1 - fi -fi diff --git a/hotspot/test/runtime/ClassFile/JsrRewriting.java b/hotspot/test/runtime/ClassFile/JsrRewriting.java new file mode 100644 index 00000000000..856658f9bf3 --- /dev/null +++ b/hotspot/test/runtime/ClassFile/JsrRewriting.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011, 2013, 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 JsrRewriting + * @summary JSR (jump local subroutine) + * rewriting can overflow memory address size variables + * @bug 7020373 + * @bug 7055247 + * @bug 7053586 + * @bug 7185550 + * @bug 7149464 + * @key cte_test + * @library /testlibrary + * @run main JsrRewriting + */ + +import com.oracle.java.testlibrary.*; +import java.io.File; + +public class JsrRewriting { + + public static void main(String[] args) throws Exception { + + // ======= Configure the test + String jarFile = System.getProperty("test.src") + + File.separator + "JsrRewritingTestCase.jar"; + String className = "OOMCrashClass4000_1"; + + // limit is 768MB in native words + int mallocMaxTestWords = (1024 * 1024 * 768 / 4); + if (Platform.is64bit()) + mallocMaxTestWords = (mallocMaxTestWords / 2); + + // ======= extract the test class + ProcessBuilder pb = new ProcessBuilder(new String[] { + JDKToolFinder.getJDKTool("jar"), + "xvf", jarFile } ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + // ======= execute the test + pb = ProcessTools.createJavaProcessBuilder( + "-cp", ".", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:MallocMaxTestWords=" + mallocMaxTestWords, + className); + + output = new OutputAnalyzer(pb.start()); + String[] expectedMsgs = { + "java.lang.LinkageError", + "java.lang.NoSuchMethodError", + "Main method not found in class " + className, + "insufficient memory" + }; + + MultipleOrMatch(output, expectedMsgs); + } + + private static void + MultipleOrMatch(OutputAnalyzer analyzer, String[] whatToMatch) { + String output = analyzer.getOutput(); + + for (String expected : whatToMatch) + if (output.contains(expected)) + return; + + String err = + " stdout: [" + analyzer.getOutput() + "];\n" + + " exitValue = " + analyzer.getExitValue() + "\n"; + System.err.println(err); + + StringBuilder msg = new StringBuilder("Output did not contain " + + "any of the following expected messages: \n"); + for (String expected : whatToMatch) + msg.append(expected).append(System.lineSeparator()); + throw new RuntimeException(msg.toString()); + } +} + diff --git a/hotspot/test/runtime/7020373/testcase.jar b/hotspot/test/runtime/ClassFile/JsrRewritingTestCase.jar similarity index 100% rename from hotspot/test/runtime/7020373/testcase.jar rename to hotspot/test/runtime/ClassFile/JsrRewritingTestCase.jar From 2cab7ea037453442645008267f6e63b94fbbcd81 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Tue, 17 Sep 2013 20:59:07 +0200 Subject: [PATCH 0396/1294] 8024718: Metaspace performance counters and memory pools should report the same data Reviewed-by: stefank, dholmes, coleenp --- .../src/share/vm/memory/metaspaceCounters.cpp | 62 ++++++------- .../src/share/vm/memory/metaspaceCounters.hpp | 11 ++- hotspot/src/share/vm/services/memoryPool.cpp | 19 ++-- hotspot/src/share/vm/services/memoryPool.hpp | 2 - hotspot/src/share/vm/services/memoryUsage.hpp | 4 +- .../gc/metaspace/TestMetaspaceMemoryPool.java | 71 ++++----------- .../metaspace/TestMetaspacePerfCounters.java | 35 ++++++-- .../TestPerfCountersAndMemoryPools.java | 86 +++++++++++++++++++ .../java/testlibrary/InputArguments.java | 25 ++++++ 9 files changed, 201 insertions(+), 114 deletions(-) create mode 100644 hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.cpp b/hotspot/src/share/vm/memory/metaspaceCounters.cpp index 6f443466ffb..60e26b8c714 100644 --- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp +++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp @@ -65,26 +65,25 @@ class MetaspacePerfCounters: public CHeapObj { MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL; -size_t MetaspaceCounters::calculate_capacity() { - // The total capacity is the sum of - // 1) capacity of Metachunks in use by all Metaspaces - // 2) unused space at the end of each Metachunk - // 3) space in the freelist - size_t total_capacity = MetaspaceAux::allocated_capacity_bytes() - + MetaspaceAux::free_bytes() + MetaspaceAux::free_chunks_total_bytes(); - return total_capacity; +size_t MetaspaceCounters::used() { + return MetaspaceAux::allocated_used_bytes(); +} + +size_t MetaspaceCounters::capacity() { + return MetaspaceAux::committed_bytes(); +} + +size_t MetaspaceCounters::max_capacity() { + return MetaspaceAux::reserved_bytes(); } void MetaspaceCounters::initialize_performance_counters() { if (UsePerfData) { assert(_perf_counters == NULL, "Should only be initialized once"); - size_t min_capacity = MetaspaceAux::min_chunk_size_bytes(); - size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_bytes(); - size_t used = MetaspaceAux::allocated_used_bytes(); - - _perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, capacity, max_capacity, used); + size_t min_capacity = 0; + _perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, + capacity(), max_capacity(), used()); } } @@ -92,31 +91,29 @@ void MetaspaceCounters::update_performance_counters() { if (UsePerfData) { assert(_perf_counters != NULL, "Should be initialized"); - size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_bytes(); - size_t used = MetaspaceAux::allocated_used_bytes(); - - _perf_counters->update(capacity, max_capacity, used); + _perf_counters->update(capacity(), max_capacity(), used()); } } MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL; -size_t CompressedClassSpaceCounters::calculate_capacity() { - return MetaspaceAux::allocated_capacity_bytes(_class_type) + - MetaspaceAux::free_bytes(_class_type) + - MetaspaceAux::free_chunks_total_bytes(_class_type); +size_t CompressedClassSpaceCounters::used() { + return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType); +} + +size_t CompressedClassSpaceCounters::capacity() { + return MetaspaceAux::committed_bytes(Metaspace::ClassType); +} + +size_t CompressedClassSpaceCounters::max_capacity() { + return MetaspaceAux::reserved_bytes(Metaspace::ClassType); } void CompressedClassSpaceCounters::update_performance_counters() { if (UsePerfData && UseCompressedClassPointers) { assert(_perf_counters != NULL, "Should be initialized"); - size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_bytes(_class_type); - size_t used = MetaspaceAux::allocated_used_bytes(_class_type); - - _perf_counters->update(capacity, max_capacity, used); + _perf_counters->update(capacity(), max_capacity(), used()); } } @@ -126,12 +123,9 @@ void CompressedClassSpaceCounters::initialize_performance_counters() { const char* ns = "compressedclassspace"; if (UseCompressedClassPointers) { - size_t min_capacity = MetaspaceAux::min_chunk_size_bytes(); - size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_bytes(_class_type); - size_t used = MetaspaceAux::allocated_used_bytes(_class_type); - - _perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity, max_capacity, used); + size_t min_capacity = 0; + _perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity(), + max_capacity(), used()); } else { _perf_counters = new MetaspacePerfCounters(ns, 0, 0, 0, 0); } diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.hpp b/hotspot/src/share/vm/memory/metaspaceCounters.hpp index 5b481d59b4d..0fa991291a1 100644 --- a/hotspot/src/share/vm/memory/metaspaceCounters.hpp +++ b/hotspot/src/share/vm/memory/metaspaceCounters.hpp @@ -25,13 +25,15 @@ #ifndef SHARE_VM_MEMORY_METASPACECOUNTERS_HPP #define SHARE_VM_MEMORY_METASPACECOUNTERS_HPP -#include "memory/metaspace.hpp" +#include "memory/allocation.hpp" class MetaspacePerfCounters; class MetaspaceCounters: public AllStatic { static MetaspacePerfCounters* _perf_counters; - static size_t calculate_capacity(); + static size_t used(); + static size_t capacity(); + static size_t max_capacity(); public: static void initialize_performance_counters(); @@ -40,8 +42,9 @@ class MetaspaceCounters: public AllStatic { class CompressedClassSpaceCounters: public AllStatic { static MetaspacePerfCounters* _perf_counters; - static size_t calculate_capacity(); - static const Metaspace::MetadataType _class_type = Metaspace::ClassType; + static size_t used(); + static size_t capacity(); + static size_t max_capacity(); public: static void initialize_performance_counters(); diff --git a/hotspot/src/share/vm/services/memoryPool.cpp b/hotspot/src/share/vm/services/memoryPool.cpp index 7a17f0bd138..cfae726cf7b 100644 --- a/hotspot/src/share/vm/services/memoryPool.cpp +++ b/hotspot/src/share/vm/services/memoryPool.cpp @@ -260,10 +260,10 @@ MemoryUsage CodeHeapPool::get_memory_usage() { } MetaspacePool::MetaspacePool() : - MemoryPool("Metaspace", NonHeap, capacity_in_bytes(), calculate_max_size(), true, false) { } + MemoryPool("Metaspace", NonHeap, 0, calculate_max_size(), true, false) { } MemoryUsage MetaspacePool::get_memory_usage() { - size_t committed = align_size_down_(capacity_in_bytes(), os::vm_page_size()); + size_t committed = MetaspaceAux::committed_bytes(); return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size()); } @@ -271,26 +271,19 @@ size_t MetaspacePool::used_in_bytes() { return MetaspaceAux::allocated_used_bytes(); } -size_t MetaspacePool::capacity_in_bytes() const { - return MetaspaceAux::allocated_capacity_bytes(); -} - size_t MetaspacePool::calculate_max_size() const { - return FLAG_IS_CMDLINE(MaxMetaspaceSize) ? MaxMetaspaceSize : max_uintx; + return FLAG_IS_CMDLINE(MaxMetaspaceSize) ? MaxMetaspaceSize : + MemoryUsage::undefined_size(); } CompressedKlassSpacePool::CompressedKlassSpacePool() : - MemoryPool("Compressed Class Space", NonHeap, capacity_in_bytes(), CompressedClassSpaceSize, true, false) { } + MemoryPool("Compressed Class Space", NonHeap, 0, CompressedClassSpaceSize, true, false) { } size_t CompressedKlassSpacePool::used_in_bytes() { return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType); } -size_t CompressedKlassSpacePool::capacity_in_bytes() const { - return MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); -} - MemoryUsage CompressedKlassSpacePool::get_memory_usage() { - size_t committed = align_size_down_(capacity_in_bytes(), os::vm_page_size()); + size_t committed = MetaspaceAux::committed_bytes(Metaspace::ClassType); return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size()); } diff --git a/hotspot/src/share/vm/services/memoryPool.hpp b/hotspot/src/share/vm/services/memoryPool.hpp index 08efe08e838..4ec810a985f 100644 --- a/hotspot/src/share/vm/services/memoryPool.hpp +++ b/hotspot/src/share/vm/services/memoryPool.hpp @@ -224,7 +224,6 @@ public: class MetaspacePool : public MemoryPool { size_t calculate_max_size() const; - size_t capacity_in_bytes() const; public: MetaspacePool(); MemoryUsage get_memory_usage(); @@ -232,7 +231,6 @@ class MetaspacePool : public MemoryPool { }; class CompressedKlassSpacePool : public MemoryPool { - size_t capacity_in_bytes() const; public: CompressedKlassSpacePool(); MemoryUsage get_memory_usage(); diff --git a/hotspot/src/share/vm/services/memoryUsage.hpp b/hotspot/src/share/vm/services/memoryUsage.hpp index efc6f2966d1..9027f8e76b7 100644 --- a/hotspot/src/share/vm/services/memoryUsage.hpp +++ b/hotspot/src/share/vm/services/memoryUsage.hpp @@ -63,10 +63,12 @@ public: size_t committed() const { return _committed; } size_t max_size() const { return _maxSize; } + static size_t undefined_size() { return (size_t) -1; } + inline static jlong convert_to_jlong(size_t val) { // In the 64-bit vm, a size_t can overflow a jlong (which is signed). jlong ret; - if (val == (size_t)-1) { + if (val == undefined_size()) { ret = -1L; } else { NOT_LP64(ret = val;) diff --git a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java index 105ba240ddf..bf9e74c8ab0 100644 --- a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java +++ b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java @@ -22,18 +22,15 @@ */ import java.util.List; -import java.lang.management.ManagementFactory; -import java.lang.management.MemoryManagerMXBean; -import java.lang.management.MemoryPoolMXBean; -import java.lang.management.MemoryUsage; - -import java.lang.management.RuntimeMXBean; -import java.lang.management.ManagementFactory; +import java.lang.management.*; +import com.oracle.java.testlibrary.*; +import static com.oracle.java.testlibrary.Asserts.*; /* @test TestMetaspaceMemoryPool * @bug 8000754 * @summary Tests that a MemoryPoolMXBeans is created for metaspace and that a * MemoryManagerMXBean is created. + * @library /testlibrary * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops TestMetaspaceMemoryPool * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:MaxMetaspaceSize=60m TestMetaspaceMemoryPool * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers TestMetaspaceMemoryPool @@ -42,35 +39,18 @@ import java.lang.management.ManagementFactory; public class TestMetaspaceMemoryPool { public static void main(String[] args) { verifyThatMetaspaceMemoryManagerExists(); - verifyMemoryPool(getMemoryPool("Metaspace"), isFlagDefined("MaxMetaspaceSize")); - if (runsOn64bit()) { - if (usesCompressedOops()) { + boolean isMetaspaceMaxDefined = InputArguments.containsPrefix("-XX:MaxMetaspaceSize"); + verifyMemoryPool(getMemoryPool("Metaspace"), isMetaspaceMaxDefined); + + if (Platform.is64bit()) { + if (InputArguments.contains("-XX:+UseCompressedOops")) { MemoryPoolMXBean cksPool = getMemoryPool("Compressed Class Space"); verifyMemoryPool(cksPool, true); } } } - private static boolean runsOn64bit() { - return !System.getProperty("sun.arch.data.model").equals("32"); - } - - private static boolean usesCompressedOops() { - return isFlagDefined("+UseCompressedOops"); - } - - private static boolean isFlagDefined(String name) { - RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean(); - List args = runtimeMxBean.getInputArguments(); - for (String arg : args) { - if (arg.startsWith("-XX:" + name)) { - return true; - } - } - return false; - } - private static void verifyThatMetaspaceMemoryManagerExists() { List managers = ManagementFactory.getMemoryManagerMXBeans(); for (MemoryManagerMXBean manager : managers) { @@ -95,32 +75,19 @@ public class TestMetaspaceMemoryPool { private static void verifyMemoryPool(MemoryPoolMXBean pool, boolean isMaxDefined) { MemoryUsage mu = pool.getUsage(); - assertDefined(mu.getInit(), "init"); - assertDefined(mu.getUsed(), "used"); - assertDefined(mu.getCommitted(), "committed"); + long init = mu.getInit(); + long used = mu.getUsed(); + long committed = mu.getCommitted(); + long max = mu.getMax(); + + assertGTE(init, 0L); + assertGTE(used, init); + assertGTE(committed, used); if (isMaxDefined) { - assertDefined(mu.getMax(), "max"); + assertGTE(max, committed); } else { - assertUndefined(mu.getMax(), "max"); - } - } - - private static void assertDefined(long value, String name) { - assertTrue(value != -1, "Expected " + name + " to be defined"); - } - - private static void assertUndefined(long value, String name) { - assertEquals(value, -1, "Expected " + name + " to be undefined"); - } - - private static void assertEquals(long actual, long expected, String msg) { - assertTrue(actual == expected, msg); - } - - private static void assertTrue(boolean condition, String msg) { - if (!condition) { - throw new RuntimeException(msg); + assertEQ(max, -1L); } } } diff --git a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java index 9672d90a5d0..974066cba56 100644 --- a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java +++ b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java @@ -61,10 +61,15 @@ public class TestMetaspacePerfCounters { } private static void checkPerfCounters(String ns) throws Exception { - for (PerfCounter counter : countersInNamespace(ns)) { - String msg = "Expected " + counter.getName() + " to be larger than 0"; - assertGT(counter.longValue(), 0L, msg); - } + long minCapacity = getMinCapacity(ns); + long maxCapacity = getMaxCapacity(ns); + long capacity = getCapacity(ns); + long used = getUsed(ns); + + assertGTE(minCapacity, 0L); + assertGTE(used, minCapacity); + assertGTE(capacity, used); + assertGTE(maxCapacity, capacity); } private static void checkEmptyPerfCounters(String ns) throws Exception { @@ -75,12 +80,10 @@ public class TestMetaspacePerfCounters { } private static void checkUsedIncreasesWhenLoadingClass(String ns) throws Exception { - PerfCounter used = PerfCounters.findByName(ns + ".used"); - - long before = used.longValue(); + long before = getUsed(ns); fooClass = compileAndLoad("Foo", "public class Foo { }"); System.gc(); - long after = used.longValue(); + long after = getUsed(ns); assertGT(after, before); } @@ -101,4 +104,20 @@ public class TestMetaspacePerfCounters { private static boolean isUsingCompressedClassPointers() { return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedClassPointers"); } + + private static long getMinCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".minCapacity").longValue(); + } + + private static long getCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".capacity").longValue(); + } + + private static long getMaxCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".maxCapacity").longValue(); + } + + private static long getUsed(String ns) throws Exception { + return PerfCounters.findByName(ns + ".used").longValue(); + } } diff --git a/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java b/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java new file mode 100644 index 00000000000..e26aa6eee57 --- /dev/null +++ b/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.List; +import java.lang.management.*; + +import com.oracle.java.testlibrary.*; +import static com.oracle.java.testlibrary.Asserts.*; + +/* @test TestPerfCountersAndMemoryPools + * @bug 8023476 + * @summary Tests that a MemoryPoolMXBeans and PerfCounters for metaspace + * report the same data. + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools + */ +public class TestPerfCountersAndMemoryPools { + public static void main(String[] args) throws Exception { + checkMemoryUsage("Metaspace", "sun.gc.metaspace"); + + if (InputArguments.contains("-XX:+UseCompressedKlassPointers") && Platform.is64bit()) { + checkMemoryUsage("Compressed Class Space", "sun.gc.compressedclassspace"); + } + } + + private static MemoryUsage getMemoryUsage(String memoryPoolName) { + List pools = ManagementFactory.getMemoryPoolMXBeans(); + for (MemoryPoolMXBean pool : pools) { + if (pool.getName().equals(memoryPoolName)) { + return pool.getUsage(); + } + } + + throw new RuntimeException("Excpted to find a memory pool with name " + + memoryPoolName); + } + + private static void checkMemoryUsage(String memoryPoolName, String perfNS) + throws Exception { + // Need to do a gc before each comparison to update the perf counters + + System.gc(); + MemoryUsage mu = getMemoryUsage(memoryPoolName); + assertEQ(getMinCapacity(perfNS), mu.getInit()); + + System.gc(); + mu = getMemoryUsage(memoryPoolName); + assertEQ(getUsed(perfNS), mu.getUsed()); + + System.gc(); + mu = getMemoryUsage(memoryPoolName); + assertEQ(getCapacity(perfNS), mu.getCommitted()); + } + + private static long getMinCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".minCapacity").longValue(); + } + + private static long getCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".capacity").longValue(); + } + + private static long getUsed(String ns) throws Exception { + return PerfCounters.findByName(ns + ".used").longValue(); + } +} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java index 650d6c23390..6f40b4050be 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java @@ -41,6 +41,9 @@ public class InputArguments { /** * Returns true if {@code arg} is an input argument to the VM. * + * This is useful for checking boolean flags such as -XX:+UseSerialGC or + * -XX:-UsePerfData. + * * @param arg The name of the argument. * @return {@code true} if the given argument is an input argument, * otherwise {@code false}. @@ -48,4 +51,26 @@ public class InputArguments { public static boolean contains(String arg) { return args.contains(arg); } + + /** + * Returns true if {@code prefix} is the start of an input argument to the + * VM. + * + * This is useful for checking if flags describing a quantity, such as + * -XX:+MaxMetaspaceSize=100m, is set without having to know the quantity. + * To check if the flag -XX:MaxMetaspaceSize is set, use + * {@code InputArguments.containsPrefix("-XX:MaxMetaspaceSize")}. + * + * @param prefix The start of the argument. + * @return {@code true} if the given argument is the start of an input + * argument, otherwise {@code false}. + */ + public static boolean containsPrefix(String prefix) { + for (String arg : args) { + if (arg.startsWith(prefix)) { + return true; + } + } + return false; + } } From 7cc012b008641662edc9fbaa84b4b1be7527540a Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 17 Sep 2013 14:17:13 -0700 Subject: [PATCH 0397/1294] 8024538: -Xdoclint + -Xprefer:source + incremental compilation == FAIL Reviewed-by: darcy --- .../com/sun/tools/doclint/DocLint.java | 19 ++++++++-- .../com/sun/tools/javac/comp/Enter.java | 4 ++- .../implicitSource/ImplicitSourceTest.java | 35 +++++++++++++++++++ .../javac/doclint/implicitSource/Other.java | 25 +++++++++++++ 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 langtools/test/tools/javac/doclint/implicitSource/ImplicitSourceTest.java create mode 100644 langtools/test/tools/javac/doclint/implicitSource/Other.java diff --git a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java index 20151d1f360..a7b6fb6a15c 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java @@ -29,9 +29,14 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; +import java.util.Queue; +import java.util.Set; import javax.lang.model.element.Name; +import javax.tools.JavaFileObject; import javax.tools.StandardLocation; import com.sun.source.doctree.DocCommentTree; @@ -278,15 +283,25 @@ public class DocLint implements Plugin { TaskListener tl = new TaskListener() { @Override public void started(TaskEvent e) { + switch (e.getKind()) { + case ANALYZE: + CompilationUnitTree tree; + while ((tree = todo.poll()) != null) + ds.scan(tree, null); + break; + } } @Override public void finished(TaskEvent e) { switch (e.getKind()) { - case ENTER: - ds.scan(e.getCompilationUnit(), null); + case PARSE: + todo.add(e.getCompilationUnit()); + break; } } + + Queue todo = new LinkedList(); }; task.addTaskListener(tl); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java index 41c0792acf2..697a6921d01 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java @@ -288,7 +288,9 @@ public class Enter extends JCTree.Visitor { JavaFileObject.Kind.SOURCE); if (tree.pid != null) { tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid)); - if (tree.packageAnnotations.nonEmpty() || pkginfoOpt == PkgInfo.ALWAYS) { + if (tree.packageAnnotations.nonEmpty() + || pkginfoOpt == PkgInfo.ALWAYS + || tree.docComments != null) { if (isPkgInfo) { addEnv = true; } else if (tree.packageAnnotations.nonEmpty()){ diff --git a/langtools/test/tools/javac/doclint/implicitSource/ImplicitSourceTest.java b/langtools/test/tools/javac/doclint/implicitSource/ImplicitSourceTest.java new file mode 100644 index 00000000000..6ae67ce2819 --- /dev/null +++ b/langtools/test/tools/javac/doclint/implicitSource/ImplicitSourceTest.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, 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 8024538 + * @summary -Xdoclint + -Xprefer:source + incremental compilation == FAIL + * @compile -Xdoclint -Xprefer:source ImplicitSourceTest.java + */ + +/** ImplicitSourceTest. */ +class ImplicitSourceTest { + /**

    {@link Other}

    */ + int i; +} diff --git a/langtools/test/tools/javac/doclint/implicitSource/Other.java b/langtools/test/tools/javac/doclint/implicitSource/Other.java new file mode 100644 index 00000000000..65a5dd5b45a --- /dev/null +++ b/langtools/test/tools/javac/doclint/implicitSource/Other.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2013, 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. + */ + +/** Other. */ +class Other { } From 73fa61708235e102fde7475399427e295ed3873c Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Wed, 18 Sep 2013 07:22:20 +0200 Subject: [PATCH 0398/1294] 8022883: Assertion failed: sweptCount >= flushedCount + markedCount + zombifiedCount Provide correct number of visited nmethods to Tracing Reviewed-by: kvn, iveresov --- hotspot/src/share/vm/runtime/sweeper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp index ebecda50be0..37315aec328 100644 --- a/hotspot/src/share/vm/runtime/sweeper.cpp +++ b/hotspot/src/share/vm/runtime/sweeper.cpp @@ -269,6 +269,7 @@ void NMethodSweeper::sweep_code_cache() { // the number of nmethods changes during the sweep so the final // stage must iterate until it there are no more nmethods. int todo = (CodeCache::nof_nmethods() - _seen) / _invocations; + int swept_count = 0; assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); assert(!CodeCache_lock->owned_by_self(), "just checking"); @@ -278,6 +279,7 @@ void NMethodSweeper::sweep_code_cache() { // The last invocation iterates until there are no more nmethods for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) { + swept_count++; if (SafepointSynchronize::is_synchronizing()) { // Safepoint request if (PrintMethodFlushing && Verbose) { tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _invocations); @@ -331,7 +333,7 @@ void NMethodSweeper::sweep_code_cache() { event.set_endtime(sweep_end_counter); event.set_sweepIndex(_traversals); event.set_sweepFractionIndex(NmethodSweepFraction - _invocations + 1); - event.set_sweptCount(todo); + event.set_sweptCount(swept_count); event.set_flushedCount(_flushed_count); event.set_markedCount(_marked_count); event.set_zombifiedCount(_zombified_count); From e287ff4ec907bfb39052cb1516ba2d81381415db Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 18 Sep 2013 13:06:17 +0530 Subject: [PATCH 0399/1294] 8024972: for (LeftHandSideExpression in Expression) crashes the compiler Reviewed-by: lagergren, hannesw --- .../internal/codegen/CodeGenerator.java | 1 - nashorn/test/script/basic/JDK-8024972.js | 43 +++++++++++++++++++ .../test/script/basic/JDK-8024972.js.EXPECTED | 6 +++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8024972.js create mode 100644 nashorn/test/script/basic/JDK-8024972.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 809b2ec21e2..6307e2f9dbe 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -852,7 +852,6 @@ final class CodeGenerator extends NodeOperatorVisitor"+ arr[obj.x]); +} + +var abc = { foo: 'bar', hello: 'world' }; +for (obj.x in abc) { + print(obj.x + "->" + abc[obj.x]); +} + +for (obj.x in 0) {} diff --git a/nashorn/test/script/basic/JDK-8024972.js.EXPECTED b/nashorn/test/script/basic/JDK-8024972.js.EXPECTED new file mode 100644 index 00000000000..aa4692fb2cc --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024972.js.EXPECTED @@ -0,0 +1,6 @@ +0->2 +1->45 +2->-1 +3->445 +foo->bar +hello->world From 3e4a59f7973775bea3d1bebce1e095178854df42 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 18 Sep 2013 10:02:19 +0200 Subject: [PATCH 0400/1294] 8024662: gc/arguments/TestUseCompressedOopsErgo.java does not compile Fix compilation error and use of an outdated VM option in the test Reviewed-by: stefank, jwilhelm --- .../TestUseCompressedOopsErgoTools.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java b/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java index 49d0a8a1d21..54c70672d04 100644 --- a/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java +++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java @@ -42,10 +42,10 @@ class DetermineMaxHeapForCompressedOops { class TestUseCompressedOopsErgoTools { - private static long getClassMetaspaceSize() { + private static long getCompressedClassSpaceSize() { HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); - VMOption option = diagnostic.getVMOption("ClassMetaspaceSize"); + VMOption option = diagnostic.getVMOption("CompressedClassSpaceSize"); return Long.parseLong(option.getValue()); } @@ -132,13 +132,13 @@ class TestUseCompressedOopsErgoTools { checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops - 1, true); checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops + 1, false); - // use a different ClassMetaspaceSize - String classMetaspaceSizeArg = "-XX:ClassMetaspaceSize=" + 2 * getClassMetaspaceSize(); - maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, classMetaspaceSizeArg)); + // use a different CompressedClassSpaceSize + String compressedClassSpaceSizeArg = "-XX:CompressedClassSpaceSize=" + 2 * getCompressedClassSpaceSize(); + maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, compressedClassSpaceSizeArg)); - checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops, true); - checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops - 1, true); - checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops + 1, false); + checkUseCompressedOops(join(gcflags, compressedClassSpaceSizeArg), maxHeapForCompressedOops, true); + checkUseCompressedOops(join(gcflags, compressedClassSpaceSizeArg), maxHeapForCompressedOops - 1, true); + checkUseCompressedOops(join(gcflags, compressedClassSpaceSizeArg), maxHeapForCompressedOops + 1, false); } private static void checkUseCompressedOops(String[] args, long heapsize, boolean expectUseCompressedOops) throws Exception { @@ -152,9 +152,7 @@ class TestUseCompressedOopsErgoTools { boolean actualUseCompressedOops = getFlagBoolValue(" UseCompressedOops", output); - if (expectUseCompressedOops != actualUseCompressedOops) { - throw new RuntimeException("Expected use of compressed oops: " + expectUseCompressedOops + " but was: " + actualUseCompressedOops); - } + Asserts.assertEQ(expectUseCompressedOops, actualUseCompressedOops); } private static boolean getFlagBoolValue(String flag, String where) { @@ -162,7 +160,7 @@ class TestUseCompressedOopsErgoTools { if (!m.find()) { throw new RuntimeException("Could not find value for flag " + flag + " in output string"); } - String match = m.group(1).equals("true"); + return m.group(1).equals("true"); } private static String expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception { From cebaf1314e74464e14fe70d851bd1275fbdb5729 Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Wed, 18 Sep 2013 12:25:13 +0400 Subject: [PATCH 0401/1294] 8024839: [Unified Swing/Fx threading] don't schedule an event dispatching from the event dispatch thread Reviewed-by: anthony, pchelko --- jdk/src/share/classes/java/awt/EventQueue.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/awt/EventQueue.java b/jdk/src/share/classes/java/awt/EventQueue.java index 76795eb5ed6..1a04dcb507a 100644 --- a/jdk/src/share/classes/java/awt/EventQueue.java +++ b/jdk/src/share/classes/java/awt/EventQueue.java @@ -690,7 +690,10 @@ public class EventQueue { final Object src = event.getSource(); final PrivilegedAction action = new PrivilegedAction() { public Void run() { - if (fwDispatcher == null) { + // In case fwDispatcher is installed and we're already on the + // dispatch thread (e.g. performing DefaultKeyboardFocusManager.sendMessage), + // dispatch the event straight away. + if (fwDispatcher == null || isDispatchThreadImpl()) { dispatchEventImpl(event, src); } else { fwDispatcher.scheduleDispatch(new Runnable() { From 862bc33d7aa704d7513b9a1fea0d80e5fcb4366f Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 18 Sep 2013 12:37:54 +0200 Subject: [PATCH 0402/1294] 8024815: Make --with-dxsdk and friends deprecated Reviewed-by: erikj --- common/autoconf/basics.m4 | 9 ++++++ common/autoconf/generated-configure.sh | 42 +++++++++++++++++++++++++- common/autoconf/toolchain.m4 | 3 ++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/common/autoconf/basics.m4 b/common/autoconf/basics.m4 index 126993b5cd7..f3911ff9bd9 100644 --- a/common/autoconf/basics.m4 +++ b/common/autoconf/basics.m4 @@ -203,6 +203,15 @@ AC_DEFUN([BASIC_REMOVE_SYMBOLIC_LINKS], fi ]) +# Register a --with argument but mark it as deprecated +# $1: The name of the with argument to deprecate, not including --with- +AC_DEFUN([BASIC_DEPRECATED_ARG_WITH], +[ + AC_ARG_WITH($1, [AS_HELP_STRING([--with-$1], + [Deprecated. Option is kept for backwards compatibility and is ignored])], + [AC_MSG_WARN([Option --with-$1 is deprecated and will be ignored.])]) +]) + AC_DEFUN_ONCE([BASIC_INIT], [ # Save the original command line. This is passed to us by the wrapper configure script. diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index bc9d07da3f3..cf14b82ccfd 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -1032,6 +1032,9 @@ with_override_nashorn with_override_jdk with_import_hotspot with_msvcr_dll +with_dxsdk +with_dxsdk_lib +with_dxsdk_include with_jtreg with_extra_cflags with_extra_cxxflags @@ -1786,6 +1789,12 @@ Optional Packages: source --with-msvcr-dll copy this msvcr100.dll into the built JDK (Windows only) [probed] + --with-dxsdk Deprecated. Option is kept for backwards + compatibility and is ignored + --with-dxsdk-lib Deprecated. Option is kept for backwards + compatibility and is ignored + --with-dxsdk-include Deprecated. Option is kept for backwards + compatibility and is ignored --with-jtreg Regression Test Harness [probed] --with-extra-cflags extra flags to be used when compiling jdk c-files --with-extra-cxxflags extra flags to be used when compiling jdk c++-files @@ -3135,6 +3144,10 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. +# Register a --with argument but mark it as deprecated +# $1: The name of the with argument to deprecate, not including --with- + + # Test that variable $1 denoting a program is not empty. If empty, exit with an error. @@ -3805,7 +3818,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1379077060 +DATE_WHEN_GENERATED=1379500606 ############################################################################### # @@ -17584,6 +17597,33 @@ $as_echo "$as_me: The path of MSVCR_DLL, which resolves as \"$path\", is invalid fi + + +# Check whether --with-dxsdk was given. +if test "${with_dxsdk+set}" = set; then : + withval=$with_dxsdk; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --with-dxsdk is deprecated and will be ignored." >&2;} +fi + + + + +# Check whether --with-dxsdk-lib was given. +if test "${with_dxsdk_lib+set}" = set; then : + withval=$with_dxsdk_lib; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk-lib is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --with-dxsdk-lib is deprecated and will be ignored." >&2;} +fi + + + + +# Check whether --with-dxsdk-include was given. +if test "${with_dxsdk_include+set}" = set; then : + withval=$with_dxsdk_include; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk-include is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --with-dxsdk-include is deprecated and will be ignored." >&2;} +fi + + fi diff --git a/common/autoconf/toolchain.m4 b/common/autoconf/toolchain.m4 index b60f3e3c583..21733003023 100644 --- a/common/autoconf/toolchain.m4 +++ b/common/autoconf/toolchain.m4 @@ -176,6 +176,9 @@ AC_DEFUN([TOOLCHAIN_SETUP_PATHS], [ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV + BASIC_DEPRECATED_ARG_WITH([dxsdk]) + BASIC_DEPRECATED_ARG_WITH([dxsdk-lib]) + BASIC_DEPRECATED_ARG_WITH([dxsdk-include]) fi AC_SUBST(MSVCR_DLL) From 8f9057132237247776d8e2ce6b5308356b5154dd Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 18 Sep 2013 16:36:25 +0530 Subject: [PATCH 0403/1294] 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException Reviewed-by: jlaskey, hannesw --- .../api/scripting/NashornScriptEngine.java | 69 +++++++++++-------- .../jdk/nashorn/internal/runtime/Source.java | 2 +- nashorn/test/script/trusted/JDK-8008305.js | 2 +- .../api/scripting/ScriptEngineTest.java | 13 ++++ 4 files changed, 56 insertions(+), 30 deletions(-) diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 45eddd117aa..4629665f98b 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -185,21 +185,12 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C @Override public Object eval(final Reader reader, final ScriptContext ctxt) throws ScriptException { - try { - if (reader instanceof URLReader) { - final URL url = ((URLReader)reader).getURL(); - final Charset cs = ((URLReader)reader).getCharset(); - return evalImpl(compileImpl(new Source(url.toString(), url, cs), ctxt), ctxt); - } - return evalImpl(Source.readFully(reader), ctxt); - } catch (final IOException e) { - throw new ScriptException(e); - } + return evalImpl(makeSource(reader, ctxt), ctxt); } @Override public Object eval(final String script, final ScriptContext ctxt) throws ScriptException { - return evalImpl(script.toCharArray(), ctxt); + return evalImpl(makeSource(script, ctxt), ctxt); } @Override @@ -221,16 +212,12 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C @Override public CompiledScript compile(final Reader reader) throws ScriptException { - try { - return asCompiledScript(compileImpl(Source.readFully(reader), context)); - } catch (final IOException e) { - throw new ScriptException(e); - } + return asCompiledScript(makeSource(reader, context)); } @Override public CompiledScript compile(final String str) throws ScriptException { - return asCompiledScript(compileImpl(str.toCharArray(), context)); + return asCompiledScript(makeSource(str, context)); } // Invocable methods @@ -292,6 +279,29 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C // Implementation only below this point + private static Source makeSource(final Reader reader, final ScriptContext ctxt) throws ScriptException { + try { + if (reader instanceof URLReader) { + final URL url = ((URLReader)reader).getURL(); + final Charset cs = ((URLReader)reader).getCharset(); + return new Source(url.toString(), url, cs); + } else { + return new Source(getScriptName(ctxt), Source.readFully(reader)); + } + } catch (final IOException ioExp) { + throw new ScriptException(ioExp); + } + } + + private static Source makeSource(final String src, final ScriptContext ctxt) { + return new Source(getScriptName(ctxt), src); + } + + private static String getScriptName(final ScriptContext ctxt) { + final Object val = ctxt.getAttribute(ScriptEngine.FILENAME); + return (val != null) ? val.toString() : ""; + } + private T getInterfaceInner(final Object thiz, final Class clazz) { if (clazz == null || !clazz.isInterface()) { throw new IllegalArgumentException(getMessage("interface.class.expected")); @@ -429,7 +439,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C // current ScriptContext exposed as "context" // "context" is non-writable from script - but script engine still // needs to set it and so save the context Property object - contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, null); + contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, ctxt); // current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as // NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property // in the Global of a Context we just created - both the Context and the Global were just created and can not be @@ -509,8 +519,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C throw new IllegalArgumentException(getMessage("interface.on.non.script.object")); } - private Object evalImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException { - return evalImpl(compileImpl(buf, ctxt), ctxt); + private Object evalImpl(final Source src, final ScriptContext ctxt) throws ScriptException { + return evalImpl(compileImpl(src, ctxt), ctxt); } private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException { @@ -561,11 +571,20 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } } - private CompiledScript asCompiledScript(final ScriptFunction script) { + private CompiledScript asCompiledScript(final Source source) throws ScriptException { + final ScriptFunction func = compileImpl(source, context); return new CompiledScript() { @Override public Object eval(final ScriptContext ctxt) throws ScriptException { - return evalImpl(script, ctxt); + final ScriptObject global = getNashornGlobalFrom(ctxt); + // Are we running the script in the correct global? + if (func.getScope() == global) { + return evalImpl(func, ctxt, global); + } else { + // ScriptContext with a different global. Compile again! + // Note that we may still hit per-global compilation cache. + return evalImpl(compileImpl(source, ctxt), ctxt, global); + } } @Override public ScriptEngine getEngine() { @@ -574,12 +593,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C }; } - private ScriptFunction compileImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException { - final Object val = ctxt.getAttribute(ScriptEngine.FILENAME); - final String fileName = (val != null) ? val.toString() : ""; - return compileImpl(new Source(fileName, buf), ctxt); - } - private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException { return compileImpl(source, getNashornGlobalFrom(ctxt)); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Source.java b/nashorn/src/jdk/nashorn/internal/runtime/Source.java index 7e3c8684e91..9273e7a8bac 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Source.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Source.java @@ -169,7 +169,7 @@ public final class Source { final Source src = (Source)obj; // Only compare content as a last resort measure - return length == src.length && Objects.equals(name, src.name) && Arrays.equals(content, src.content); + return length == src.length && Objects.equals(url, src.url) && Objects.equals(name, src.name) && Arrays.equals(content, src.content); } @Override diff --git a/nashorn/test/script/trusted/JDK-8008305.js b/nashorn/test/script/trusted/JDK-8008305.js index e4d052cbce8..d57b5208048 100644 --- a/nashorn/test/script/trusted/JDK-8008305.js +++ b/nashorn/test/script/trusted/JDK-8008305.js @@ -54,6 +54,6 @@ try { fail("Expected SecurityException from script!"); } catch (e) { if (! (e instanceof SecurityException)) { - faile("Expected SecurityException, but got " + e); + fail("Expected SecurityException, but got " + e); } } diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java index 416669fbcf3..99207de0d6e 100644 --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java @@ -37,10 +37,12 @@ import java.lang.reflect.Method; import java.util.concurrent.Callable; import javax.script.Compilable; import javax.script.CompiledScript; +import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; import javax.script.ScriptException; +import javax.script.SimpleScriptContext; import org.testng.annotations.Test; /** @@ -230,6 +232,17 @@ public class ScriptEngineTest { } } + @Test + public void compileAndEvalInDiffContextTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine engine = m.getEngineByName("js"); + final Compilable compilable = (Compilable) engine; + final CompiledScript compiledScript = compilable.compile("foo"); + final ScriptContext ctxt = new SimpleScriptContext(); + ctxt.setAttribute("foo", "hello", ScriptContext.ENGINE_SCOPE); + assertEquals(compiledScript.eval(ctxt), "hello"); + } + @Test public void accessGlobalTest() { final ScriptEngineManager m = new ScriptEngineManager(); From dae6feeefd0f1f68ceebed180ecd7a5c210b6f7f Mon Sep 17 00:00:00 2001 From: Mikhail Cherkasov Date: Wed, 18 Sep 2013 15:12:13 +0400 Subject: [PATCH 0404/1294] 8016746: Test javax/swing/JTable/7068740/bug7068740.java fails Reviewed-by: serb, alexsch --- .../swing/JTable/7068740/bug7068740.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/jdk/test/javax/swing/JTable/7068740/bug7068740.java b/jdk/test/javax/swing/JTable/7068740/bug7068740.java index 7073779f6e6..4dac9cd288c 100644 --- a/jdk/test/javax/swing/JTable/7068740/bug7068740.java +++ b/jdk/test/javax/swing/JTable/7068740/bug7068740.java @@ -37,6 +37,7 @@ import javax.swing.table.DefaultTableModel; import java.awt.*; import java.awt.event.KeyEvent; import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicInteger; public class bug7068740 extends JFrame { @@ -66,6 +67,7 @@ public class bug7068740 extends JFrame { }; table = new JTable(model); + table.setRowSelectionInterval(0, 0); LayerUI layerUI = new LayerUI<>(); JLayer layer = new JLayer<>(table, layerUI); JScrollPane scrollPane = new JScrollPane(layer); @@ -78,7 +80,7 @@ public class bug7068740 extends JFrame { try { if (robot == null) { robot = new Robot(); - robot.setAutoDelay(20); + robot.setAutoDelay(50); } if (toolkit == null) { @@ -104,24 +106,37 @@ public class bug7068740 extends JFrame { } } - private static void doTest() { + private static int getSelectedRow() throws Exception { + final AtomicInteger row = new AtomicInteger(-1); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + row.set(table.getSelectedRow()); + } + }); + return row.intValue(); + } + + private static void doTest() throws Exception { toolkit.realSync(); - table.setRowSelectionInterval(0, 0); robot.keyPress(KeyEvent.VK_PAGE_DOWN); + robot.keyRelease(KeyEvent.VK_PAGE_DOWN); toolkit.realSync(); - if (table.getSelectedRow() != 19) { + + if (getSelectedRow() != 19) { throw new RuntimeException("Test failed"); } robot.keyPress(KeyEvent.VK_PAGE_UP); + robot.keyRelease(KeyEvent.VK_PAGE_UP); toolkit.realSync(); - if (table.getSelectedRow() != 0) { + if (getSelectedRow() != 0) { throw new RuntimeException("Test failed"); } } - public static void main(String[] args) { + public static void main(String[] args) throws Exception { try { UIManager.setLookAndFeel(new MetalLookAndFeel()); setUp(); From f6e98b818159cabd05ad21cadc906c8ef1b5cba6 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 18 Sep 2013 13:18:52 +0200 Subject: [PATCH 0405/1294] 8024669: Native OOME when allocating after changes to maximum heap supporting Coops sizing on sparcv9 After changes in 8010722 the ergonomics for calculating the size of the heap that supports zero based compressed oops changed. This lead to the VM actually using zero based compressed oops. Due to low default HeapBaseMinAddress, the OS mapping in the application image at the same address, and limitations of the malloc implementation on Solaris this resulted in very little C heap available for the VM. So the VM immediately gives a native OOME when the machine has lots of physical memory (>=32G). The solution is to increase the HeapBaseMinAddress so that the VM has enough C heap. Reviewed-by: kvn, brutisso --- hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp b/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp index 595cd781447..e0ed6961e3a 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp @@ -35,7 +35,9 @@ define_pd_global(intx, CompilerThreadStackSize, 0); // Used on 64 bit platforms for UseCompressedOops base address #ifdef _LP64 -define_pd_global(uintx, HeapBaseMinAddress, CONST64(4)*G); +// use 6G as default base address because by default the OS maps the application +// to 4G on Solaris-Sparc. This leaves at least 2G for the native heap. +define_pd_global(uintx, HeapBaseMinAddress, CONST64(6)*G); #else define_pd_global(uintx, HeapBaseMinAddress, 2*G); #endif From c36b6491454999553a5fc55146fa1c7ff73b35ed Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 18 Sep 2013 13:49:49 +0200 Subject: [PATCH 0406/1294] 8024849: Don't remove upper case letters from username when setting USER_RELEASE_SUFFIX Reviewed-by: erikj --- common/autoconf/basics_windows.m4 | 2 +- common/autoconf/generated-configure.sh | 68 +++++++++++++------------- common/autoconf/jdk-options.m4 | 2 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/common/autoconf/basics_windows.m4 b/common/autoconf/basics_windows.m4 index 9ddb9e8c5c0..0a26d830239 100644 --- a/common/autoconf/basics_windows.m4 +++ b/common/autoconf/basics_windows.m4 @@ -211,7 +211,7 @@ AC_DEFUN([BASIC_FIXUP_EXECUTABLE_CYGWIN], # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index cf14b82ccfd..7a65a92ecc4 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -3818,7 +3818,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1379500606 +DATE_WHEN_GENERATED=1379504921 ############################################################################### # @@ -8352,7 +8352,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -8709,7 +8709,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -9063,7 +9063,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -9422,7 +9422,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -9775,7 +9775,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -11075,7 +11075,7 @@ elif test "x$with_user_release_suffix" != x; then else BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` # Avoid [:alnum:] since it depends on the locale. - CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` + CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'` USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` fi @@ -17101,7 +17101,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -17747,7 +17747,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -18058,7 +18058,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -18364,7 +18364,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -18957,7 +18957,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -19393,7 +19393,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -20529,7 +20529,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -20965,7 +20965,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -21866,7 +21866,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -22247,7 +22247,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -22594,7 +22594,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -22931,7 +22931,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -23252,7 +23252,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -23627,7 +23627,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -23933,7 +23933,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -24344,7 +24344,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -24744,7 +24744,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -25073,7 +25073,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -25385,7 +25385,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -25691,7 +25691,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -25997,7 +25997,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -26303,7 +26303,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -26662,7 +26662,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -27022,7 +27022,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -27395,7 +27395,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -27766,7 +27766,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -28075,7 +28075,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index ba14373e593..b1c99bbe7dc 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -446,7 +446,7 @@ elif test "x$with_user_release_suffix" != x; then else BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` # Avoid [:alnum:] since it depends on the locale. - CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` + CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'` USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` fi AC_SUBST(USER_RELEASE_SUFFIX) From 775822bed7ad6b5df862bf28fc8b462c203cf247 Mon Sep 17 00:00:00 2001 From: Andreas Lundblad Date: Wed, 18 Sep 2013 14:39:27 +0200 Subject: [PATCH 0407/1294] 8024127: javac, Code_attribute.exception_table_langth should be Code_attribute.exception_table_length Exception_table_langth renamed to exception_table_length Reviewed-by: jfranck, jjg --- .../classes/com/sun/tools/classfile/Code_attribute.java | 8 ++++---- .../src/share/classes/com/sun/tools/javap/CodeWriter.java | 2 +- langtools/test/tools/javac/T7093325.java | 2 +- .../javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java | 2 +- langtools/test/tools/javac/multicatch/Pos05.java | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/classfile/Code_attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/Code_attribute.java index 5d7c81474f2..6d5b7e6bef8 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/Code_attribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/Code_attribute.java @@ -61,9 +61,9 @@ public class Code_attribute extends Attribute { code_length = cr.readInt(); code = new byte[code_length]; cr.readFully(code); - exception_table_langth = cr.readUnsignedShort(); - exception_table = new Exception_data[exception_table_langth]; - for (int i = 0; i < exception_table_langth; i++) + exception_table_length = cr.readUnsignedShort(); + exception_table = new Exception_data[exception_table_length]; + for (int i = 0; i < exception_table_length; i++) exception_table[i] = new Exception_data(cr); attributes = new Attributes(cr); } @@ -139,7 +139,7 @@ public class Code_attribute extends Attribute { public final int max_locals; public final int code_length; public final byte[] code; - public final int exception_table_langth; + public final int exception_table_length; public final Exception_data[] exception_table; public final Attributes attributes; diff --git a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java index 657194d19c6..6211a2a13cf 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java @@ -208,7 +208,7 @@ public class CodeWriter extends BasicWriter { public void writeExceptionTable(Code_attribute attr) { - if (attr.exception_table_langth > 0) { + if (attr.exception_table_length > 0) { println("Exception table:"); indent(+1); println(" from to target type"); diff --git a/langtools/test/tools/javac/T7093325.java b/langtools/test/tools/javac/T7093325.java index dcdc6e62856..fb11a87e77e 100644 --- a/langtools/test/tools/javac/T7093325.java +++ b/langtools/test/tools/javac/T7093325.java @@ -208,7 +208,7 @@ public class T7093325 } int actualGapsCount = 0; - for (int i = 0; i < code.exception_table_langth ; i++) { + for (int i = 0; i < code.exception_table_length ; i++) { int catchType = code.exception_table[i].catch_type; if (catchType == 0) { //any actualGapsCount++; diff --git a/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java b/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java index 0dd25871f3a..9b69b074624 100644 --- a/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java +++ b/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java @@ -100,7 +100,7 @@ public class NoDeadCodeGenerationOnTrySmtTest { if (method.getName(classFile.constant_pool).equals(methodToFind)) { numberOfmethodsFound++; Code_attribute code = (Code_attribute) method.attributes.get("Code"); - Assert.check(code.exception_table_langth == expectedExceptionTable.length, + Assert.check(code.exception_table_length == expectedExceptionTable.length, "The ExceptionTable found has a length different to the expected one"); int i = 0; for (Exception_data entry: code.exception_table) { diff --git a/langtools/test/tools/javac/multicatch/Pos05.java b/langtools/test/tools/javac/multicatch/Pos05.java index e3c3d50d321..32d76b2368b 100644 --- a/langtools/test/tools/javac/multicatch/Pos05.java +++ b/langtools/test/tools/javac/multicatch/Pos05.java @@ -95,7 +95,7 @@ public class Pos05 { throw new Error("Code attribute for test() method not found"); } Exception_data firstExceptionTable = null; - for (int i = 0 ; i < ea.exception_table_langth; i++) { + for (int i = 0 ; i < ea.exception_table_length; i++) { if (firstExceptionTable == null) { firstExceptionTable = ea.exception_table[i]; } From c5c705217bf51ac2a2e329fbffe1db3e0de366f7 Mon Sep 17 00:00:00 2001 From: Sergey Gabdurakhmanov Date: Wed, 18 Sep 2013 16:48:49 +0400 Subject: [PATCH 0408/1294] 8022836: JVM crashes in JVMTIENVBASE::GET_CURRENT_CONTENDED_MONITOR and GET_OWNED_MONITOR Check that the _java_thread parameter is valid when it is possible that the JavaThread has exited after the initial checks were made in generated/jvmtifiles/jvmtiEnter.cpp: jvmti_GetCurrentContendedMonitor() Reviewed-by: dcubed, dsamersoff --- hotspot/src/share/vm/prims/jvmtiEnvBase.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp b/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp index 929dcf22260..265154683ba 100644 --- a/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp +++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp @@ -406,7 +406,11 @@ public: VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; } jvmtiError result() { return _result; } void doit() { - _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr); + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; + if (Threads::includes(_java_thread) && !_java_thread->is_exiting() && + _java_thread->threadObj() != NULL) { + _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr); + } } }; From 41bce440a4f08849888aff8042a6663e9942745c Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 18 Sep 2013 07:02:10 -0700 Subject: [PATCH 0409/1294] 8019835: Strings interned in different threads equal but does not == Add -XX:+VerifyStringTableAtExit option and code to verify StringTable invariants. Reviewed-by: rdurbin, sspitsyn, coleenp --- .../src/share/vm/classfile/javaClasses.cpp | 23 +++ .../src/share/vm/classfile/javaClasses.hpp | 1 + .../src/share/vm/classfile/symbolTable.cpp | 158 ++++++++++++++++++ .../src/share/vm/classfile/symbolTable.hpp | 20 +++ hotspot/src/share/vm/runtime/globals.hpp | 3 + hotspot/src/share/vm/runtime/java.cpp | 13 ++ 6 files changed, 218 insertions(+) diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 8e94d834ad9..9331cc1246f 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -438,6 +438,29 @@ bool java_lang_String::equals(oop java_string, jchar* chars, int len) { return true; } +bool java_lang_String::equals(oop str1, oop str2) { + assert(str1->klass() == SystemDictionary::String_klass(), + "must be java String"); + assert(str2->klass() == SystemDictionary::String_klass(), + "must be java String"); + typeArrayOop value1 = java_lang_String::value(str1); + int offset1 = java_lang_String::offset(str1); + int length1 = java_lang_String::length(str1); + typeArrayOop value2 = java_lang_String::value(str2); + int offset2 = java_lang_String::offset(str2); + int length2 = java_lang_String::length(str2); + + if (length1 != length2) { + return false; + } + for (int i = 0; i < length1; i++) { + if (value1->char_at(i + offset1) != value2->char_at(i + offset2)) { + return false; + } + } + return true; +} + void java_lang_String::print(Handle java_string, outputStream* st) { oop obj = java_string(); assert(obj->klass() == SystemDictionary::String_klass(), "must be java_string"); diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 8a8e801f387..ffccf2f0e0c 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -182,6 +182,7 @@ class java_lang_String : AllStatic { static unsigned int hash_string(oop java_string); static bool equals(oop java_string, jchar* chars, int len); + static bool equals(oop str1, oop str2); // Conversion between '.' and '/' formats static Handle externalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '/', '.', THREAD); } diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index c00e9581759..747ca870c2b 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -807,6 +807,8 @@ void StringTable::possibly_parallel_oops_do(OopClosure* f) { } } +// This verification is part of Universe::verify() and needs to be quick. +// See StringTable::verify_and_compare() below for exhaustive verification. void StringTable::verify() { for (int i = 0; i < the_table()->table_size(); ++i) { HashtableEntry* p = the_table()->bucket(i); @@ -825,6 +827,162 @@ void StringTable::dump(outputStream* st) { the_table()->dump_table(st, "StringTable"); } +StringTable::VerifyRetTypes StringTable::compare_entries( + int bkt1, int e_cnt1, + HashtableEntry* e_ptr1, + int bkt2, int e_cnt2, + HashtableEntry* e_ptr2) { + // These entries are sanity checked by verify_and_compare_entries() + // before this function is called. + oop str1 = e_ptr1->literal(); + oop str2 = e_ptr2->literal(); + + if (str1 == str2) { + tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") " + "in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]", + str1, bkt1, e_cnt1, bkt2, e_cnt2); + return _verify_fail_continue; + } + + if (java_lang_String::equals(str1, str2)) { + tty->print_cr("ERROR: identical String values in entry @ " + "bucket[%d][%d] and entry @ bucket[%d][%d]", + bkt1, e_cnt1, bkt2, e_cnt2); + return _verify_fail_continue; + } + + return _verify_pass; +} + +StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt, + HashtableEntry* e_ptr, + StringTable::VerifyMesgModes mesg_mode) { + + VerifyRetTypes ret = _verify_pass; // be optimistic + + oop str = e_ptr->literal(); + if (str == NULL) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt, + e_cnt); + } + // NULL oop means no more verifications are possible + return _verify_fail_done; + } + + if (str->klass() != SystemDictionary::String_klass()) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]", + bkt, e_cnt); + } + // not a String means no more verifications are possible + return _verify_fail_done; + } + + unsigned int h = java_lang_String::hash_string(str); + if (e_ptr->hash() != h) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], " + "bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h); + } + ret = _verify_fail_continue; + } + + if (the_table()->hash_to_index(h) != bkt) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], " + "str_hash=%d, hash_to_index=%d", bkt, e_cnt, h, + the_table()->hash_to_index(h)); + } + ret = _verify_fail_continue; + } + + return ret; +} + +// See StringTable::verify() above for the quick verification that is +// part of Universe::verify(). This verification is exhaustive and +// reports on every issue that is found. StringTable::verify() only +// reports on the first issue that is found. +// +// StringTable::verify_entry() checks: +// - oop value != NULL (same as verify()) +// - oop value is a String +// - hash(String) == hash in entry (same as verify()) +// - index for hash == index of entry (same as verify()) +// +// StringTable::compare_entries() checks: +// - oops are unique across all entries +// - String values are unique across all entries +// +int StringTable::verify_and_compare_entries() { + assert(StringTable_lock->is_locked(), "sanity check"); + + int fail_cnt = 0; + + // first, verify all the entries individually: + for (int bkt = 0; bkt < the_table()->table_size(); bkt++) { + HashtableEntry* e_ptr = the_table()->bucket(bkt); + for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) { + VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs); + if (ret != _verify_pass) { + fail_cnt++; + } + } + } + + // Optimization: if the above check did not find any failures, then + // the comparison loop below does not need to call verify_entry() + // before calling compare_entries(). If there were failures, then we + // have to call verify_entry() to see if the entry can be passed to + // compare_entries() safely. When we call verify_entry() in the loop + // below, we do so quietly to void duplicate messages and we don't + // increment fail_cnt because the failures have already been counted. + bool need_entry_verify = (fail_cnt != 0); + + // second, verify all entries relative to each other: + for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) { + HashtableEntry* e_ptr1 = the_table()->bucket(bkt1); + for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) { + if (need_entry_verify) { + VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1, + _verify_quietly); + if (ret == _verify_fail_done) { + // cannot use the current entry to compare against other entries + continue; + } + } + + for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) { + HashtableEntry* e_ptr2 = the_table()->bucket(bkt2); + int e_cnt2; + for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) { + if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) { + // skip the entries up to and including the one that + // we're comparing against + continue; + } + + if (need_entry_verify) { + VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2, + _verify_quietly); + if (ret == _verify_fail_done) { + // cannot compare against this entry + continue; + } + } + + // compare two entries, report and count any failures: + if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2) + != _verify_pass) { + fail_cnt++; + } + } + } + } + } + return fail_cnt; +} // Create a new table and using alternate hash code, populate the new table // with the existing strings. Set flag to use the alternate hash code afterwards. diff --git a/hotspot/src/share/vm/classfile/symbolTable.hpp b/hotspot/src/share/vm/classfile/symbolTable.hpp index 7a0031c9ab4..dc7d0337a0e 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.hpp +++ b/hotspot/src/share/vm/classfile/symbolTable.hpp @@ -311,6 +311,26 @@ public: static void verify(); static void dump(outputStream* st); + enum VerifyMesgModes { + _verify_quietly = 0, + _verify_with_mesgs = 1 + }; + + enum VerifyRetTypes { + _verify_pass = 0, + _verify_fail_continue = 1, + _verify_fail_done = 2 + }; + + static VerifyRetTypes compare_entries(int bkt1, int e_cnt1, + HashtableEntry* e_ptr1, + int bkt2, int e_cnt2, + HashtableEntry* e_ptr2); + static VerifyRetTypes verify_entry(int bkt, int e_cnt, + HashtableEntry* e_ptr, + VerifyMesgModes mesg_mode); + static int verify_and_compare_entries(); + // Sharing static void copy_buckets(char** top, char*end) { the_table()->Hashtable::copy_buckets(top, end); diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 7fdf668bac5..bdee0be3c32 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -2525,6 +2525,9 @@ class CommandLineFlags { product(bool, PrintStringTableStatistics, false, \ "print statistics about the StringTable and SymbolTable") \ \ + diagnostic(bool, VerifyStringTableAtExit, false, \ + "verify StringTable contents at exit") \ + \ notproduct(bool, PrintSymbolTableSizeHistogram, false, \ "print histogram of the symbol table") \ \ diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp index ebc4e087578..874765fa3e5 100644 --- a/hotspot/src/share/vm/runtime/java.cpp +++ b/hotspot/src/share/vm/runtime/java.cpp @@ -544,6 +544,19 @@ void before_exit(JavaThread * thread) { // it will run into trouble when system destroys static variables. MemTracker::shutdown(MemTracker::NMT_normal); + if (VerifyStringTableAtExit) { + int fail_cnt = 0; + { + MutexLocker ml(StringTable_lock); + fail_cnt = StringTable::verify_and_compare_entries(); + } + + if (fail_cnt != 0) { + tty->print_cr("ERROR: fail_cnt=%d", fail_cnt); + guarantee(fail_cnt == 0, "unexpected StringTable verification failures"); + } + } + #undef BEFORE_EXIT_NOT_RUN #undef BEFORE_EXIT_RUNNING #undef BEFORE_EXIT_DONE From 5108c579fee9c92686e3ba9d43f4a723e14075e2 Mon Sep 17 00:00:00 2001 From: Leonid Romanov Date: Wed, 18 Sep 2013 18:36:57 +0400 Subject: [PATCH 0410/1294] 7188071: closed/java/awt/TrayIcon/TrayIconSecurity/GrantedTrayIconTest fails Reviewed-by: anthony, serb --- jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java index 24f2656f891..e2da468f440 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -459,7 +459,7 @@ public class XTrayIconPeer implements TrayIconPeer, // other class tries to cast source field to Component). // We already filter DRAG events out (CR 6565779). e.setSource(xtiPeer.target); - Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e); + XToolkit.postEvent(XToolkit.targetToAppContext(e.getSource()), e); } public void mouseClicked(MouseEvent e) { if ((e.getClickCount() > 1 || xtiPeer.balloon.isVisible()) && From 3debf156b12b2f2a2d9b964886b5db3e993c2cf2 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Mon, 30 Sep 2013 16:15:49 -0700 Subject: [PATCH 0411/1294] 8016110: Japanese char (MS932) 0x5C cannot be used as an argument when quoted Reviewed-by: ksrini, akhil --- jdk/src/windows/bin/cmdtoargs.c | 76 ++++++++++------ jdk/test/tools/launcher/I18NArgTest.java | 111 +++++++++++++++++++++++ 2 files changed, 160 insertions(+), 27 deletions(-) create mode 100644 jdk/test/tools/launcher/I18NArgTest.java diff --git a/jdk/src/windows/bin/cmdtoargs.c b/jdk/src/windows/bin/cmdtoargs.c index 69f1aef7383..352b1553a08 100644 --- a/jdk/src/windows/bin/cmdtoargs.c +++ b/jdk/src/windows/bin/cmdtoargs.c @@ -53,6 +53,16 @@ typedef struct { static StdArg *stdargs; static int stdargc; +static int copyCh(USHORT ch, char* dest) { + if (HIBYTE(ch) == 0) { + *dest = (char)ch; + return 1; + } else { + *((USHORT *)dest) = ch; + return 2; + } +} + static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { char* src = cmdline; @@ -61,31 +71,43 @@ static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { int quotes = 0; int slashes = 0; - char prev = 0; - char ch = 0; + // "prev"/"ch" may contain either a single byte, or a double byte + // character encoded in CP_ACP. + USHORT prev = 0; + USHORT ch = 0; int i; jboolean done = JNI_FALSE; + int charLength; *wildcard = JNI_FALSE; - while ((ch = *src) != 0 && !done) { + while (!done) { + charLength = CharNextExA(CP_ACP, src, 0) - src; + if (charLength == 0) { + break; + } else if (charLength == 1) { + ch = (USHORT)(UCHAR)src[0]; + } else { + ch = ((USHORT *)src)[0]; + } + switch (ch) { - case '"': + case L'"': if (separator) { done = JNI_TRUE; break; } - if (prev == '\\') { + if (prev == L'\\') { for (i = 1; i < slashes; i += 2) { - *dest++ = prev; + dest += copyCh(prev, dest); } if (slashes % 2 == 1) { - *dest++ = ch; + dest += copyCh(ch, dest); } else { quotes++; } - } else if (prev == '"' && quotes % 2 == 0) { + } else if (prev == L'"' && quotes % 2 == 0) { quotes++; - *dest++ = ch; // emit every other consecutive quote + dest += copyCh(ch, dest); // emit every other consecutive quote } else if (quotes == 0) { quotes++; // starting quote } else { @@ -94,7 +116,7 @@ static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { slashes = 0; break; - case '\\': + case L'\\': slashes++; if (separator) { done = JNI_TRUE; @@ -102,23 +124,23 @@ static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { } break; - case ' ': - case '\t': - if (prev == '\\') { + case L' ': + case L'\t': + if (prev == L'\\') { for (i = 0 ; i < slashes; i++) { - *dest++ = prev; + dest += copyCh(prev, dest); } } if (quotes % 2 == 1) { - *dest++ = ch; + dest += copyCh(ch, dest); } else { separator = JNI_TRUE; } slashes = 0; break; - case '*': - case '?': + case L'*': + case L'?': if (separator) { done = JNI_TRUE; separator = JNI_FALSE; @@ -127,36 +149,36 @@ static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { if (quotes % 2 == 0) { *wildcard = JNI_TRUE; } - if (prev == '\\') { + if (prev == L'\\') { for (i = 0 ; i < slashes ; i++) { - *dest++ = prev; + dest += copyCh(prev, dest); } } - *dest++ = ch; + dest += copyCh(ch, dest); break; default: - if (prev == '\\') { + if (prev == L'\\') { for (i = 0 ; i < slashes ; i++) { - *dest++ = prev; + dest += copyCh(prev, dest); } - *dest++ = ch; + dest += copyCh(ch, dest); } else if (separator) { done = JNI_TRUE; } else { - *dest++ = ch; + dest += copyCh(ch, dest); } slashes = 0; } if (!done) { prev = ch; - src++; + src += charLength; } } - if (prev == '\\') { + if (prev == L'\\') { for (i = 0; i < slashes; i++) { - *dest++ = prev; + dest += copyCh(prev, dest); } } *dest = 0; diff --git a/jdk/test/tools/launcher/I18NArgTest.java b/jdk/test/tools/launcher/I18NArgTest.java new file mode 100644 index 00000000000..d3a28be1b64 --- /dev/null +++ b/jdk/test/tools/launcher/I18NArgTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013, 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 8016110 + * @summary verify Japanese character in an argument are treated correctly + * @compile -XDignore.symbol.file I18NArgTest.java + * @run main I18NArgTest + */ +import java.io.IOException; + +public class I18NArgTest extends TestHelper { + public static void main(String... args) throws IOException { + if (!isWindows) { + return; + } + if (!"MS932".equals(System.getProperty("sun.jnu.encoding"))) { + System.err.println("MS932 encoding not set, test skipped"); + return; + } + if (args.length == 0) { + execTest(0x30bd); // MS932 Katakana SO, 0x835C + } else { + testCharacters(args); + } + } + static void execTest(int unicodeValue) { + String hexValue = Integer.toHexString(unicodeValue); + String unicodeStr = Character.toString((char)unicodeValue); + execTest("\"" + unicodeStr + "\"", hexValue); + execTest("\\" + unicodeStr + "\\", hexValue); + execTest(" " + unicodeStr + " ", hexValue); + execTest("'" + unicodeStr + "'", hexValue); + execTest("\t" + unicodeStr + "\t", hexValue); + execTest("*" + unicodeStr + "*", hexValue); + execTest("?" + unicodeStr + "?", hexValue); + + execTest("\"" + unicodeStr + unicodeStr + "\"", hexValue + hexValue); + execTest("\\" + unicodeStr + unicodeStr + "\\", hexValue + hexValue); + execTest(" " + unicodeStr + unicodeStr + " ", hexValue + hexValue); + execTest("'" + unicodeStr + unicodeStr + "'", hexValue + hexValue); + execTest("\t" + unicodeStr + unicodeStr + "\t", hexValue + hexValue); + execTest("*" + unicodeStr + unicodeStr + "*", hexValue + hexValue); + execTest("?" + unicodeStr + unicodeStr + "?", hexValue + hexValue); + + execTest("\"" + unicodeStr + "a" + unicodeStr + "\"", hexValue + "61" + hexValue); + execTest("\\" + unicodeStr + "a" + unicodeStr + "\\", hexValue + "61" + hexValue); + execTest(" " + unicodeStr + "a" + unicodeStr + " ", hexValue + "61"+ hexValue); + execTest("'" + unicodeStr + "a" + unicodeStr + "'", hexValue + "61"+ hexValue); + execTest("\t" + unicodeStr + "a" + unicodeStr + "\t", hexValue + "61"+ hexValue); + execTest("*" + unicodeStr + "a" + unicodeStr + "*", hexValue + "61"+ hexValue); + execTest("?" + unicodeStr + "a" + unicodeStr + "?", hexValue + "61"+ hexValue); + + execTest("\"" + unicodeStr + "\u00b1" + unicodeStr + "\"", hexValue + "b1" + hexValue); + execTest("\\" + unicodeStr + "\u00b1" + unicodeStr + "\\", hexValue + "b1" + hexValue); + execTest(" " + unicodeStr + "\u00b1" + unicodeStr + " ", hexValue + "b1"+ hexValue); + execTest("'" + unicodeStr + "\u00b1" + unicodeStr + "'", hexValue + "b1"+ hexValue); + execTest("\t" + unicodeStr + "\u00b1" + unicodeStr + "\t", hexValue + "b1"+ hexValue); + execTest("*" + unicodeStr + "\u00b1" + unicodeStr + "*", hexValue + "b1"+ hexValue); + execTest("?" + unicodeStr + "\u00b1" + unicodeStr + "?", hexValue + "b1"+ hexValue); + } + static void execTest(String unicodeStr, String hexValue) { + TestResult tr = doExec(javaCmd, + "-Dtest.src=" + TEST_SOURCES_DIR.getAbsolutePath(), + "-Dtest.classes=" + TEST_CLASSES_DIR.getAbsolutePath(), + "-cp", TEST_CLASSES_DIR.getAbsolutePath(), + "I18NArgTest", unicodeStr, hexValue); + System.out.println(tr.testOutput); + if (!tr.isOK()) { + System.err.println(tr); + throw new RuntimeException("test fails"); + } + } + static void testCharacters(String... args) { + String input = args[0]; + String expected = args[1]; + String hexValue = ""; + for (int i = 0; i < input.length(); i++) { + hexValue = hexValue.concat(Integer.toHexString((int)input.charAt(i))); + } + System.out.println("input:" + input); + System.out.println("expected:" + expected); + System.out.println("obtained:" + hexValue); + if (!hexValue.contains(expected)) { + String message = "Error: output does not contain expected value" + + "expected:" + expected + " obtained:" + hexValue; + throw new RuntimeException(message); + } + } +} From 223c6bf379d4e03e38dacc6069978e1bf958a9a7 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Tue, 1 Oct 2013 12:19:20 +0200 Subject: [PATCH 0412/1294] 8024408: Specifications for Collection/List/Set/SortedSet.spliterator() need to document if all the (subclass) instances are required to return SIZED spliterators Reviewed-by: alanb --- jdk/src/share/classes/java/util/Collection.java | 14 +++++++------- jdk/src/share/classes/java/util/Set.java | 9 ++++++--- jdk/src/share/classes/java/util/SortedSet.java | 11 +++++++---- .../Spliterator/SpliteratorCharacteristics.java | 8 +++++++- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/jdk/src/share/classes/java/util/Collection.java b/jdk/src/share/classes/java/util/Collection.java index 8e8fd5a76dc..36c7b9d9de1 100644 --- a/jdk/src/share/classes/java/util/Collection.java +++ b/jdk/src/share/classes/java/util/Collection.java @@ -503,12 +503,10 @@ public interface Collection extends Iterable { /** * Creates a {@link Spliterator} over the elements in this collection. * - *

    The returned {@code Spliterator} must report the characteristic - * {@link Spliterator#SIZED}; implementations should document any additional - * characteristic values reported by the returned spliterator. If - * this collection contains no elements then the returned spliterator is - * only required to report {@link Spliterator#SIZED} and is not required to - * report additional characteristic values (if any). + * Implementations should document characteristic values reported by the + * spliterator. Such characteristic values are not required to be reported + * if the spliterator reports {@link Spliterator#SIZED} and this collection + * contains no elements. * *

    The default implementation should be overridden by subclasses that * can return a more efficient spliterator. In order to @@ -534,9 +532,11 @@ public interface Collection extends Iterable { * late-binding spliterator * from the collections's {@code Iterator}. The spliterator inherits the * fail-fast properties of the collection's iterator. + *

    + * The created {@code Spliterator} reports {@link Spliterator#SIZED}. * * @implNote - * The returned {@code Spliterator} additionally reports + * The created {@code Spliterator} additionally reports * {@link Spliterator#SUBSIZED}. * *

    If a spliterator covers no elements then the reporting of additional diff --git a/jdk/src/share/classes/java/util/Set.java b/jdk/src/share/classes/java/util/Set.java index d47a06a4a8a..2703049b30d 100644 --- a/jdk/src/share/classes/java/util/Set.java +++ b/jdk/src/share/classes/java/util/Set.java @@ -386,15 +386,18 @@ public interface Set extends Collection { /** * Creates a {@code Spliterator} over the elements in this set. * - *

    The {@code Spliterator} reports {@link Spliterator#SIZED} and - * {@link Spliterator#DISTINCT}. Implementations should document the - * reporting of additional characteristic values. + *

    The {@code Spliterator} reports {@link Spliterator#DISTINCT}. + * Implementations should document the reporting of additional + * characteristic values. * * @implSpec * The default implementation creates a * late-binding spliterator * from the set's {@code Iterator}. The spliterator inherits the * fail-fast properties of the set's iterator. + *

    + * The created {@code Spliterator} additionally reports + * {@link Spliterator#SIZED}. * * @implNote * The created {@code Spliterator} additionally reports diff --git a/jdk/src/share/classes/java/util/SortedSet.java b/jdk/src/share/classes/java/util/SortedSet.java index 3e64804e7b5..3ea932949a3 100644 --- a/jdk/src/share/classes/java/util/SortedSet.java +++ b/jdk/src/share/classes/java/util/SortedSet.java @@ -223,10 +223,10 @@ public interface SortedSet extends Set { /** * Creates a {@code Spliterator} over the elements in this sorted set. * - *

    The {@code Spliterator} reports {@link Spliterator#SIZED}, - * {@link Spliterator#DISTINCT}, {@link Spliterator#SORTED} and - * {@link Spliterator#ORDERED}. Implementations should document the - * reporting of additional characteristic values. + *

    The {@code Spliterator} reports {@link Spliterator#DISTINCT}, + * {@link Spliterator#SORTED} and {@link Spliterator#ORDERED}. + * Implementations should document the reporting of additional + * characteristic values. * *

    The spliterator's comparator (see * {@link java.util.Spliterator#getComparator()}) must be {@code null} if @@ -240,6 +240,9 @@ public interface SortedSet extends Set { * from the sorted set's {@code Iterator}. The spliterator inherits the * fail-fast properties of the set's iterator. The * spliterator's comparator is the same as the sorted set's comparator. + *

    + * The created {@code Spliterator} additionally reports + * {@link Spliterator#SIZED}. * * @implNote * The created {@code Spliterator} additionally reports diff --git a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java index 37fbcc769d0..f226a82b439 100644 --- a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java +++ b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8020156 8020009 8022326 8012913 8024405 + * @bug 8020156 8020009 8022326 8012913 8024405 8024408 * @run testng SpliteratorCharacteristics */ @@ -46,6 +46,7 @@ import java.util.Spliterator; import java.util.Spliterators; import java.util.TreeMap; import java.util.TreeSet; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListSet; import java.util.function.Supplier; @@ -185,6 +186,11 @@ public class SpliteratorCharacteristics { Spliterator.SIZED | Spliterator.DISTINCT); } + public void testWeakHashMap() { + assertMapCharacteristics(new WeakHashMap<>(), + Spliterator.DISTINCT); + } + public void testHashSet() { assertSetCharacteristics(new HashSet<>(), Spliterator.SIZED | Spliterator.DISTINCT); From 2a5d8d6d8cdf11401312c5fab199abf4825d78fa Mon Sep 17 00:00:00 2001 From: Aleksei Efimov Date: Tue, 1 Oct 2013 17:15:43 +0400 Subject: [PATCH 0413/1294] 8024707: TransformerException : item() return null with node list of length != 1 Reviewed-by: joehw, lancea --- .../xml/jaxp/parsers/8024707/TestFunc.java | 35 +++++++++++++ .../javax/xml/jaxp/parsers/8024707/XSLT.java | 51 +++++++++++++++++++ .../javax/xml/jaxp/parsers/8024707/in.xml | 4 ++ .../javax/xml/jaxp/parsers/8024707/test.xsl | 10 ++++ 4 files changed, 100 insertions(+) create mode 100644 jdk/test/javax/xml/jaxp/parsers/8024707/TestFunc.java create mode 100644 jdk/test/javax/xml/jaxp/parsers/8024707/XSLT.java create mode 100644 jdk/test/javax/xml/jaxp/parsers/8024707/in.xml create mode 100644 jdk/test/javax/xml/jaxp/parsers/8024707/test.xsl diff --git a/jdk/test/javax/xml/jaxp/parsers/8024707/TestFunc.java b/jdk/test/javax/xml/jaxp/parsers/8024707/TestFunc.java new file mode 100644 index 00000000000..69f181d7f07 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/parsers/8024707/TestFunc.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * bug 8024707 + */ + +public class TestFunc { + public static Node test( NodeList list ) { + return list.item(0); + } +} diff --git a/jdk/test/javax/xml/jaxp/parsers/8024707/XSLT.java b/jdk/test/javax/xml/jaxp/parsers/8024707/XSLT.java new file mode 100644 index 00000000000..e6a03f5af68 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/parsers/8024707/XSLT.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013, 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 8024707 + * @summary Test for XSLT extension function with 1 element sized nodelist + * @compile TestFunc.java XSLT.java + * @run main/othervm XSLT + * @author aleksej.efimov@oracle.com + */ + +import javax.xml.transform.*; +import javax.xml.transform.stream.*; +import java.io.ByteArrayOutputStream; + +public class XSLT { + static final String XMLTOTRANSFORM = "/in.xml"; + static final String XSLTRANSFORMER = "/test.xsl"; + static final String EXPECTEDRESULT = "inp1_1"; + + public static void main(String[] args) throws Exception { + ByteArrayOutputStream resStream = new ByteArrayOutputStream(); + TransformerFactory trf = TransformerFactory.newInstance(); + Transformer tr = trf.newTransformer( new StreamSource(System.getProperty("test.src", ".")+XSLTRANSFORMER)); + tr.transform( new StreamSource(System.getProperty("test.src", ".")+XMLTOTRANSFORM), new StreamResult(resStream)); + System.out.println("Transformation completed. Result:"+resStream.toString()); + if (!resStream.toString().equals(EXPECTEDRESULT)) + throw new RuntimeException("Incorrect transformation result"); + } +} diff --git a/jdk/test/javax/xml/jaxp/parsers/8024707/in.xml b/jdk/test/javax/xml/jaxp/parsers/8024707/in.xml new file mode 100644 index 00000000000..2cd31165815 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/parsers/8024707/in.xml @@ -0,0 +1,4 @@ + + +inp1_1 + diff --git a/jdk/test/javax/xml/jaxp/parsers/8024707/test.xsl b/jdk/test/javax/xml/jaxp/parsers/8024707/test.xsl new file mode 100644 index 00000000000..59c506370a9 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/parsers/8024707/test.xsl @@ -0,0 +1,10 @@ + + + + + + From 8fd60ce581a797dc26c2d34da7cbd33b25e5b939 Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Mon, 30 Sep 2013 15:50:06 -0700 Subject: [PATCH 0414/1294] 7057785: Add note about optional support of recursive methods for self-referential Collection/Map Reviewed-by: scolebourne, darcy, mduigou --- jdk/src/share/classes/java/util/Collection.java | 7 +++++++ jdk/src/share/classes/java/util/Map.java | 15 +++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/util/Collection.java b/jdk/src/share/classes/java/util/Collection.java index 36c7b9d9de1..2ae88727a06 100644 --- a/jdk/src/share/classes/java/util/Collection.java +++ b/jdk/src/share/classes/java/util/Collection.java @@ -104,6 +104,13 @@ import java.util.stream.StreamSupport; * the specified behavior of underlying {@link Object} methods wherever the * implementor deems it appropriate. * + *

    Some collection operations which perform recursive traversal of the + * collection may fail with an exception for self-referential instances where + * the collection directly or indirectly contains itself. This includes the + * {@code clone()}, {@code equals()}, {@code hashCode()} and {@code toString()} + * methods. Implementations may optionally handle the self-referential scenario, + * however most current implementations do not do so. + * *

    This interface is a member of the * * Java Collections Framework. diff --git a/jdk/src/share/classes/java/util/Map.java b/jdk/src/share/classes/java/util/Map.java index bf1ba8391c8..d1695ef23ee 100644 --- a/jdk/src/share/classes/java/util/Map.java +++ b/jdk/src/share/classes/java/util/Map.java @@ -86,10 +86,6 @@ import java.io.Serializable; * Such exceptions are marked as "optional" in the specification for this * interface. * - *

    This interface is a member of the - * - * Java Collections Framework. - * *

    Many methods in Collections Framework interfaces are defined * in terms of the {@link Object#equals(Object) equals} method. For * example, the specification for the {@link #containsKey(Object) @@ -107,6 +103,17 @@ import java.io.Serializable; * the specified behavior of underlying {@link Object} methods wherever the * implementor deems it appropriate. * + *

    Some map operations which perform recursive traversal of the map may fail + * with an exception for self-referential instances where the map directly or + * indirectly contains itself. This includes the {@code clone()}, + * {@code equals()}, {@code hashCode()} and {@code toString()} methods. + * Implementations may optionally handle the self-referential scenario, however + * most current implementations do not do so. + * + *

    This interface is a member of the + * + * Java Collections Framework. + * * @param the type of keys maintained by this map * @param the type of mapped values * From bf7051420838ce8ea89b9419d455622107343a1d Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Tue, 1 Oct 2013 10:23:00 -0700 Subject: [PATCH 0415/1294] 8025067: Unconditionally throw NPE if null op provided to Arrays.parallelPrefix Reviewed-by: henryjen, chegar, psandoz --- jdk/src/share/classes/java/util/Arrays.java | 8 + jdk/test/java/util/Arrays/ParallelPrefix.java | 146 +++++++++++++++++- 2 files changed, 147 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/java/util/Arrays.java b/jdk/src/share/classes/java/util/Arrays.java index 47c99ef7f82..43463a5aff6 100644 --- a/jdk/src/share/classes/java/util/Arrays.java +++ b/jdk/src/share/classes/java/util/Arrays.java @@ -1583,6 +1583,7 @@ public class Arrays { * @since 1.8 */ public static void parallelPrefix(T[] array, BinaryOperator op) { + Objects.requireNonNull(op); if (array.length > 0) new ArrayPrefixHelpers.CumulateTask<> (null, op, array, 0, array.length).invoke(); @@ -1606,6 +1607,7 @@ public class Arrays { */ public static void parallelPrefix(T[] array, int fromIndex, int toIndex, BinaryOperator op) { + Objects.requireNonNull(op); rangeCheck(array.length, fromIndex, toIndex); if (fromIndex < toIndex) new ArrayPrefixHelpers.CumulateTask<> @@ -1627,6 +1629,7 @@ public class Arrays { * @since 1.8 */ public static void parallelPrefix(long[] array, LongBinaryOperator op) { + Objects.requireNonNull(op); if (array.length > 0) new ArrayPrefixHelpers.LongCumulateTask (null, op, array, 0, array.length).invoke(); @@ -1649,6 +1652,7 @@ public class Arrays { */ public static void parallelPrefix(long[] array, int fromIndex, int toIndex, LongBinaryOperator op) { + Objects.requireNonNull(op); rangeCheck(array.length, fromIndex, toIndex); if (fromIndex < toIndex) new ArrayPrefixHelpers.LongCumulateTask @@ -1673,6 +1677,7 @@ public class Arrays { * @since 1.8 */ public static void parallelPrefix(double[] array, DoubleBinaryOperator op) { + Objects.requireNonNull(op); if (array.length > 0) new ArrayPrefixHelpers.DoubleCumulateTask (null, op, array, 0, array.length).invoke(); @@ -1695,6 +1700,7 @@ public class Arrays { */ public static void parallelPrefix(double[] array, int fromIndex, int toIndex, DoubleBinaryOperator op) { + Objects.requireNonNull(op); rangeCheck(array.length, fromIndex, toIndex); if (fromIndex < toIndex) new ArrayPrefixHelpers.DoubleCumulateTask @@ -1716,6 +1722,7 @@ public class Arrays { * @since 1.8 */ public static void parallelPrefix(int[] array, IntBinaryOperator op) { + Objects.requireNonNull(op); if (array.length > 0) new ArrayPrefixHelpers.IntCumulateTask (null, op, array, 0, array.length).invoke(); @@ -1738,6 +1745,7 @@ public class Arrays { */ public static void parallelPrefix(int[] array, int fromIndex, int toIndex, IntBinaryOperator op) { + Objects.requireNonNull(op); rangeCheck(array.length, fromIndex, toIndex); if (fromIndex < toIndex) new ArrayPrefixHelpers.IntCumulateTask diff --git a/jdk/test/java/util/Arrays/ParallelPrefix.java b/jdk/test/java/util/Arrays/ParallelPrefix.java index 072de79c42c..8d0d788247a 100644 --- a/jdk/test/java/util/Arrays/ParallelPrefix.java +++ b/jdk/test/java/util/Arrays/ParallelPrefix.java @@ -22,7 +22,7 @@ */ /** - * @test + * @test 8014076 8025067 * @summary unit test for Arrays.ParallelPrefix(). * @author Tristan Yan * @run testng ParallelPrefix @@ -54,30 +54,44 @@ public class ParallelPrefix { private final static int LARGE_ARRAY_SIZE = 1 << 12; private final static int[] ARRAY_SIZE_COLLECTION = new int[]{ - SMALL_ARRAY_SIZE, THRESHOLD_ARRAY_SIZE,MEDIUM_ARRAY_SIZE, LARGE_ARRAY_SIZE}; + SMALL_ARRAY_SIZE, + THRESHOLD_ARRAY_SIZE, + MEDIUM_ARRAY_SIZE, + LARGE_ARRAY_SIZE + }; @DataProvider public static Object[][] intSet(){ - return genericData(size -> IntStream.range(0, size).toArray(), new IntBinaryOperator[]{Integer::sum, Integer::min}); + return genericData(size -> IntStream.range(0, size).toArray(), + new IntBinaryOperator[]{ + Integer::sum, + Integer::min}); } @DataProvider public static Object[][] longSet(){ - return genericData(size -> LongStream.range(0, size).toArray(), new LongBinaryOperator[]{Long::sum, Long::min}); + return genericData(size -> LongStream.range(0, size).toArray(), + new LongBinaryOperator[]{ + Long::sum, + Long::min}); } @DataProvider public static Object[][] doubleSet(){ return genericData(size -> IntStream.range(0, size).mapToDouble(i -> (double)i).toArray(), - new DoubleBinaryOperator[]{Double::sum, Double::min}); + new DoubleBinaryOperator[]{ + Double::sum, + Double::min}); } @DataProvider public static Object[][] stringSet(){ Function stringsFunc = size -> IntStream.range(0, size).mapToObj(Integer::toString).toArray(String[]::new); - BinaryOperator cancatBop = String::concat; - return genericData(stringsFunc, new BinaryOperator[]{cancatBop}); + BinaryOperator concat = String::concat; + return genericData(stringsFunc, + (BinaryOperator[]) new BinaryOperator[]{ + concat }); } private static Object[][] genericData(Function generateFunc, OPS[] ops) { @@ -161,5 +175,123 @@ public class ParallelPrefix { Arrays.parallelPrefix(parallelRangeResult, op); assertEquals(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex)); } + + @Test + public void testNPEs() { + // null array + assertThrows( () -> Arrays.parallelPrefix((int[]) null, Integer::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((long []) null, Long::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((double []) null, Double::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((String []) null, String::concat), + NullPointerException.class, "should throw NPE"); + + // null array w/ range + assertThrows( () -> Arrays.parallelPrefix((int[]) null, 0, 0, Integer::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((long []) null, 0, 0, Long::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((double []) null, 0, 0, Double::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((String []) null, 0, 0, String::concat), + NullPointerException.class, "should throw NPE"); + + // null op + assertThrows( () -> Arrays.parallelPrefix(new int[] {}, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new long[] {}, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new double[] {}, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new String[] {}, null), + NullPointerException.class, "should throw NPE"); + + // null op w/ range + assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 0, 0, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 0, 0, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 0, 0, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 0, 0, null), + NullPointerException.class, "should throw NPE"); + } + + @Test + public void testIAEs() { + assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 1, 0, Integer::max), + IllegalArgumentException.class, "should throw IAE"); + assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 1, 0, Long::max), + IllegalArgumentException.class, "should throw IAE"); + assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 1, 0, Double::max), + IllegalArgumentException.class, "should throw IAE"); + assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 1, 0, String::concat), + IllegalArgumentException.class, "should throw IAE"); + } + + @Test + public void testAIOBEs() { + // bad "fromIndex" + assertThrows( () -> Arrays.parallelPrefix(new int[] {}, -1, 0, Integer::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new long[] {}, -1, 0, Long::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new double[] {}, -1, 0, Double::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new String[] {}, -1, 0, String::concat), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + + // bad "toIndex" + assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 0, 1, Integer::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 0, 1, Long::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 0, 1, Double::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 0, 1, String::concat), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + } + + // "library" code + + public interface Thrower { + + public void run() throws T; + } + + + public static void assertThrows(Thrower thrower, Class throwable) { + assertThrows(thrower, throwable, null); + } + + public static void assertThrows(Thrower thrower, Class throwable, String message) { + Throwable thrown; + try { + thrower.run(); + thrown = null; + } catch (Throwable caught) { + thrown = caught; + } + + assertInstance(thrown, throwable, + ((null != message) ? message : "") + + " Failed to throw " + throwable.getCanonicalName()); + } + + public static void assertThrows(Class throwable, String message, Thrower... throwers) { + for(Thrower thrower : throwers) { + assertThrows(thrower, throwable, message); + } + } + + public static void assertInstance(Object actual, Class expected) { + assertInstance(expected.isInstance(actual), null); + } + + public static void assertInstance(Object actual, Class expected, String message) { + assertTrue(expected.isInstance(actual), message); + } } From 2a3c1e97b2c2625ee66904abb195ece71f41b093 Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Tue, 1 Oct 2013 10:37:05 -0700 Subject: [PATCH 0416/1294] 8025686: Update jdk repo netbeans projects to support NetBeans 7.4 for Java 8 support Reviewed-by: lancea, chegar --- jdk/make/netbeans/common/java-data-native.ent | 4 ++-- jdk/make/netbeans/common/java-data-no-native.ent | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/make/netbeans/common/java-data-native.ent b/jdk/make/netbeans/common/java-data-native.ent index 54c7486aafb..b50ea59afe7 100644 --- a/jdk/make/netbeans/common/java-data-native.ent +++ b/jdk/make/netbeans/common/java-data-native.ent @@ -31,14 +31,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - + ${root}/src/share/classes ${root}/src/macosx/classes ${root}/src/solaris/classes ${root}/src/windows/classes ${bootstrap.jdk}/jre/lib/rt.jar - ${root}/build/${platform}-${arch}/classes + ${root}/../build/${platform}-${arch}/jdk/classes ${root}/build/${platform}-${arch}/docs/api 1.8 diff --git a/jdk/make/netbeans/common/java-data-no-native.ent b/jdk/make/netbeans/common/java-data-no-native.ent index 8e06c66c348..882072e0e9c 100644 --- a/jdk/make/netbeans/common/java-data-no-native.ent +++ b/jdk/make/netbeans/common/java-data-no-native.ent @@ -31,11 +31,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - + ${root}/src/share/classes ${bootstrap.jdk}/jre/lib/rt.jar - ${root}/build/${platform}-${arch}/classes + ${root}/../build/${platform}-${arch}/jdk/classes ${root}/build/${platform}-${arch}/docs/api 1.8 From b91ee238953c6148264605205a7bab4d7fcc8347 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Mon, 23 Sep 2013 19:51:40 +0400 Subject: [PATCH 0417/1294] 8001107: @Stable annotation for constant folding of lazily evaluated variables Co-authored-by: John Rose Reviewed-by: twisti, kvn, rbackman --- .../classes/java/lang/invoke/LambdaForm.java | 8 +- .../classes/java/lang/invoke/MethodType.java | 6 +- .../java/lang/invoke/MethodTypeForm.java | 9 ++- .../classes/java/lang/invoke/Stable.java | 73 +++++++++++++++++++ 4 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 jdk/src/share/classes/java/lang/invoke/Stable.java diff --git a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java index f5dcf40fd4d..96d83fb4705 100644 --- a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java +++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java @@ -120,7 +120,7 @@ import java.util.Objects; class LambdaForm { final int arity; final int result; - final Name[] names; + @Stable final Name[] names; final String debugName; MemberName vmentry; // low-level behavior, or null if not yet prepared private boolean isCompiled; @@ -971,8 +971,8 @@ class LambdaForm { static class NamedFunction { final MemberName member; - MethodHandle resolvedHandle; - MethodHandle invoker; + @Stable MethodHandle resolvedHandle; + @Stable MethodHandle invoker; NamedFunction(MethodHandle resolvedHandle) { this(resolvedHandle.internalMemberName(), resolvedHandle); @@ -1267,7 +1267,7 @@ class LambdaForm { final char type; private short index; final NamedFunction function; - final Object[] arguments; + @Stable final Object[] arguments; private Name(int index, char type, NamedFunction function, Object[] arguments) { this.index = (short)index; diff --git a/jdk/src/share/classes/java/lang/invoke/MethodType.java b/jdk/src/share/classes/java/lang/invoke/MethodType.java index f55479f1345..5fc1f377b90 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodType.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodType.java @@ -94,9 +94,9 @@ class MethodType implements java.io.Serializable { private final Class[] ptypes; // The remaining fields are caches of various sorts: - private MethodTypeForm form; // erased form, plus cached data about primitives - private MethodType wrapAlt; // alternative wrapped/unwrapped version - private Invokers invokers; // cache of handy higher-order adapters + private @Stable MethodTypeForm form; // erased form, plus cached data about primitives + private @Stable MethodType wrapAlt; // alternative wrapped/unwrapped version + private @Stable Invokers invokers; // cache of handy higher-order adapters /** * Check the given parameters for validity and store them into the final fields. diff --git a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java index 1106e97baa3..f279035c447 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java @@ -51,12 +51,13 @@ final class MethodTypeForm { final MethodType basicType; // the canonical erasure, with primitives simplified // Cached adapter information: - /*lazy*/ MethodHandle genericInvoker; // JVM hook for inexact invoke - /*lazy*/ MethodHandle basicInvoker; // cached instance of MH.invokeBasic - /*lazy*/ MethodHandle namedFunctionInvoker; // cached helper for LF.NamedFunction + @Stable String typeString; // argument type signature characters + @Stable MethodHandle genericInvoker; // JVM hook for inexact invoke + @Stable MethodHandle basicInvoker; // cached instance of MH.invokeBasic + @Stable MethodHandle namedFunctionInvoker; // cached helper for LF.NamedFunction // Cached lambda form information, for basic types only: - final LambdaForm[] lambdaForms; + final @Stable LambdaForm[] lambdaForms; // Indexes into lambdaForms: static final int LF_INVVIRTUAL = 0, // DMH invokeVirtual diff --git a/jdk/src/share/classes/java/lang/invoke/Stable.java b/jdk/src/share/classes/java/lang/invoke/Stable.java new file mode 100644 index 00000000000..67a3b4fb67a --- /dev/null +++ b/jdk/src/share/classes/java/lang/invoke/Stable.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.invoke; + +import java.lang.annotation.*; + +/** + * A field may be annotated as stable if all of its component variables + * changes value at most once. + * A field's value counts as its component value. + * If the field is typed as an array, then all the non-null components + * of the array, of depth up to the rank of the field's array type, + * also count as component values. + * By extension, any variable (either array or field) which has annotated + * as stable is called a stable variable, and its non-null or non-zero + * value is called a stable value. + *

    + * Since all fields begin with a default value of null for references + * (resp., zero for primitives), it follows that this annotation indicates + * that the first non-null (resp., non-zero) value stored in the field + * will never be changed. + *

    + * If the field is not of an array type, there are no array elements, + * then the value indicated as stable is simply the value of the field. + * If the dynamic type of the field value is an array but the static type + * is not, the components of the array are not regarded as stable. + *

    + * If the field is an array type, then both the field value and + * all the components of the field value (if the field value is non-null) + * are indicated to be stable. + * If the field type is an array type with rank {@code N > 1}, + * then each component of the field value (if the field value is non-null), + * is regarded as a stable array of rank {@code N-1}. + *

    + * Fields which are declared {@code final} may also be annotated as stable. + * Since final fields already behave as stable values, such an annotation + * indicates no additional information, unless the type of the field is + * an array type. + *

    + * It is (currently) undefined what happens if a field annotated as stable + * is given a third value. In practice, if the JVM relies on this annotation + * to promote a field reference to a constant, it may be that the Java memory + * model would appear to be broken, if such a constant (the second value of the field) + * is used as the value of the field even after the field value has changed. + */ +/* package-private */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@interface Stable { +} From 8e924e70a6cea5014feb17e6065c485153157ba8 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Wed, 18 Sep 2013 20:12:05 +0400 Subject: [PATCH 0418/1294] 8024616: JSR292: lazily initialize core NamedFunctions used for bootstrapping Reviewed-by: jrose --- .../java/lang/invoke/DirectMethodHandle.java | 110 +++++++++--------- .../java/lang/invoke/MethodHandleImpl.java | 24 ++-- 2 files changed, 73 insertions(+), 61 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java index b9c10d827d2..9c054519b43 100644 --- a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java @@ -257,12 +257,12 @@ class DirectMethodHandle extends MethodHandle { assert(names.length == nameCursor); if (doesAlloc) { // names = { argx,y,z,... new C, init method } - names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]); - names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]); + names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]); } else if (needsInit) { - names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]); } else { - names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]); } Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class); assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args! @@ -637,18 +637,18 @@ class DirectMethodHandle extends MethodHandle { final int RESULT = nameCursor-1; // either the call or the cast Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); if (needsInit) - names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]); + names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]); if (needsCast && !isGetter) - names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]); + names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]); Object[] outArgs = new Object[1 + linkerType.parameterCount()]; assert(outArgs.length == (isGetter ? 3 : 4)); outArgs[0] = UNSAFE; if (isStatic) { - outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]); - outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]); + outArgs[1] = names[F_HOLDER] = new Name(Lazy.NF_staticBase, names[DMH_THIS]); + outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_staticOffset, names[DMH_THIS]); } else { - outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]); - outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]); + outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]); + outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]); } if (!isGetter) { outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]); @@ -656,7 +656,7 @@ class DirectMethodHandle extends MethodHandle { for (Object a : outArgs) assert(a != null); names[LINKER_CALL] = new Name(linker, outArgs); if (needsCast && isGetter) - names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); + names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); for (Name n : names) assert(n != null); String fieldOrStatic = (isStatic ? "Static" : "Field"); String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging @@ -665,48 +665,54 @@ class DirectMethodHandle extends MethodHandle { return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT); } - private static final NamedFunction - NF_internalMemberName, - NF_internalMemberNameEnsureInit, - NF_ensureInitialized, - NF_fieldOffset, - NF_checkBase, - NF_staticBase, - NF_staticOffset, - NF_checkCast, - NF_allocateInstance, - NF_constructorMethod; - static { - try { - NamedFunction nfs[] = { - NF_internalMemberName = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("internalMemberName", Object.class)), - NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), - NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("ensureInitialized", Object.class)), - NF_fieldOffset = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("fieldOffset", Object.class)), - NF_checkBase = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("checkBase", Object.class)), - NF_staticBase = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("staticBase", Object.class)), - NF_staticOffset = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("staticOffset", Object.class)), - NF_checkCast = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("checkCast", Object.class, Object.class)), - NF_allocateInstance = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("allocateInstance", Object.class)), - NF_constructorMethod = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("constructorMethod", Object.class)) - }; - for (NamedFunction nf : nfs) { - // Each nf must be statically invocable or we get tied up in our bootstraps. - assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; - nf.resolve(); + /** + * Pre-initialized NamedFunctions for bootstrapping purposes. + * Factored in an inner class to delay initialization until first usage. + */ + private static class Lazy { + static final NamedFunction + NF_internalMemberName, + NF_internalMemberNameEnsureInit, + NF_ensureInitialized, + NF_fieldOffset, + NF_checkBase, + NF_staticBase, + NF_staticOffset, + NF_checkCast, + NF_allocateInstance, + NF_constructorMethod; + static { + try { + NamedFunction nfs[] = { + NF_internalMemberName = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("internalMemberName", Object.class)), + NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), + NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("ensureInitialized", Object.class)), + NF_fieldOffset = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("fieldOffset", Object.class)), + NF_checkBase = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("checkBase", Object.class)), + NF_staticBase = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("staticBase", Object.class)), + NF_staticOffset = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("staticOffset", Object.class)), + NF_checkCast = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("checkCast", Object.class, Object.class)), + NF_allocateInstance = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("allocateInstance", Object.class)), + NF_constructorMethod = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("constructorMethod", Object.class)) + }; + for (NamedFunction nf : nfs) { + // Each nf must be statically invocable or we get tied up in our bootstraps. + assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; + nf.resolve(); + } + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); } - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); } } } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java index 5ab7f7adb7b..6918fec1cca 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -435,7 +435,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; // Spread the array. MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType); Name array = names[argIndex]; - names[nameCursor++] = new Name(NF_checkSpreadArgument, array, spreadArgCount); + names[nameCursor++] = new Name(Lazy.NF_checkSpreadArgument, array, spreadArgCount); for (int j = 0; j < spreadArgCount; i++, j++) { indexes[i] = nameCursor; names[nameCursor++] = new Name(aload, array, j); @@ -480,14 +480,20 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; throw new WrongMethodTypeException("Array is not of length "+n); } - private static final NamedFunction NF_checkSpreadArgument; - static { - try { - NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class - .getDeclaredMethod("checkSpreadArgument", Object.class, int.class)); - NF_checkSpreadArgument.resolve(); - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); + /** + * Pre-initialized NamedFunctions for bootstrapping purposes. + * Factored in an inner class to delay initialization until first usage. + */ + private static class Lazy { + static final NamedFunction NF_checkSpreadArgument; + static { + try { + NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class + .getDeclaredMethod("checkSpreadArgument", Object.class, int.class)); + NF_checkSpreadArgument.resolve(); + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); + } } } From f99391ee6f088383a785637b63dbce56fe3f6f5c Mon Sep 17 00:00:00 2001 From: Igor Veresov Date: Wed, 18 Sep 2013 14:10:21 -0700 Subject: [PATCH 0419/1294] 8023542: Test java/io/File/CheckPermission.java fails due to unfinished recursion (java.lang.StackOverflowError) when JIT'ed code (-client,-server) is running Move null check before klass reference materialization in checkcast Reviewed-by: kvn, roland --- hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index 334d0cc92db..952e1adbc52 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -1724,14 +1724,6 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L } assert_different_registers(obj, k_RInfo, klass_RInfo); - if (!k->is_loaded()) { - klass2reg_with_patching(k_RInfo, op->info_for_patch()); - } else { -#ifdef _LP64 - __ mov_metadata(k_RInfo, k->constant_encoding()); -#endif // _LP64 - } - assert(obj != k_RInfo, "must be different"); __ cmpptr(obj, (int32_t)NULL_WORD); if (op->should_profile()) { @@ -1748,6 +1740,14 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L } else { __ jcc(Assembler::equal, *obj_is_null); } + + if (!k->is_loaded()) { + klass2reg_with_patching(k_RInfo, op->info_for_patch()); + } else { +#ifdef _LP64 + __ mov_metadata(k_RInfo, k->constant_encoding()); +#endif // _LP64 + } __ verify_oop(obj); if (op->fast_check()) { From 82705bda51b399bf0901d948fd5846d30107718d Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Wed, 18 Sep 2013 20:08:00 -0400 Subject: [PATCH 0420/1294] 8024826: (s) : Remove alt-rt.jar, used by +AggressiveOps Reviewed-by: alanb, chegar, dholmes, ksrini --- hotspot/src/share/vm/runtime/arguments.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index ef4da6da740..78b8338265d 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -2409,21 +2409,6 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) { return result; } - if (AggressiveOpts) { - // Insert alt-rt.jar between user-specified bootclasspath - // prefix and the default bootclasspath. os::set_boot_path() - // uses meta_index_dir as the default bootclasspath directory. - const char* altclasses_jar = "alt-rt.jar"; - size_t altclasses_path_len = strlen(get_meta_index_dir()) + 1 + - strlen(altclasses_jar); - char* altclasses_path = NEW_C_HEAP_ARRAY(char, altclasses_path_len, mtInternal); - strcpy(altclasses_path, get_meta_index_dir()); - strcat(altclasses_path, altclasses_jar); - scp.add_suffix_to_prefix(altclasses_path); - scp_assembly_required = true; - FREE_C_HEAP_ARRAY(char, altclasses_path, mtInternal); - } - // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM) result = parse_java_options_environment_variable(&scp, &scp_assembly_required); if (result != JNI_OK) { From 484e378a9d7a1c3a3c6dd4c8b1e2ddc0b4c1e884 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Wed, 18 Sep 2013 17:13:26 -0700 Subject: [PATCH 0421/1294] 8015249: javadoc fails to document static final fields in annotation types Reviewed-by: jjg --- .../html/AnnotationTypeFieldWriterImpl.java | 301 ++++++++++++++++++ ...nnotationTypeRequiredMemberWriterImpl.java | 14 + .../html/AnnotationTypeWriterImpl.java | 24 +- .../formats/html/HtmlDocletWriter.java | 5 + .../formats/html/WriterFactoryImpl.java | 13 + .../formats/html/markup/HtmlConstants.java | 12 + .../toolkit/AnnotationTypeFieldWriter.java | 132 ++++++++ .../AnnotationTypeRequiredMemberWriter.java | 16 +- .../toolkit/AnnotationTypeWriter.java | 9 +- .../internal/toolkit/WriterFactory.java | 12 + .../builders/AnnotationTypeBuilder.java | 17 +- .../builders/AnnotationTypeFieldBuilder.java | 240 ++++++++++++++ .../AnnotationTypeRequiredMemberBuilder.java | 13 +- .../toolkit/builders/BuilderFactory.java | 20 +- .../builders/MemberSummaryBuilder.java | 14 + .../internal/toolkit/resources/doclet.xml | 9 + .../toolkit/util/VisibleMemberMap.java | 12 +- .../TestAnnotationTypes.java | 35 +- .../pkg/AnnotationTypeField.java | 35 ++ .../TestNewLanguageFeatures.java | 4 +- 20 files changed, 897 insertions(+), 40 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeFieldWriter.java create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeFieldBuilder.java create mode 100644 langtools/test/com/sun/javadoc/testAnnotationTypes/pkg/AnnotationTypeField.java diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java new file mode 100644 index 00000000000..f4c7c68f565 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclets.formats.html; + +import java.io.*; + +import com.sun.javadoc.*; +import com.sun.tools.doclets.formats.html.markup.*; +import com.sun.tools.doclets.internal.toolkit.*; + +/** + * Writes annotation type field documentation in HTML format. + * + *

    This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + * + * @author Bhavesh Patel + */ +public class AnnotationTypeFieldWriterImpl extends AbstractMemberWriter + implements AnnotationTypeFieldWriter, MemberSummaryWriter { + + /** + * Construct a new AnnotationTypeFieldWriterImpl. + * + * @param writer the writer that will write the output. + * @param annotationType the AnnotationType that holds this member. + */ + public AnnotationTypeFieldWriterImpl(SubWriterHolderWriter writer, + AnnotationTypeDoc annotationType) { + super(writer, annotationType); + } + + /** + * {@inheritDoc} + */ + public Content getMemberSummaryHeader(ClassDoc classDoc, + Content memberSummaryTree) { + memberSummaryTree.addContent( + HtmlConstants.START_OF_ANNOTATION_TYPE_FIELD_SUMMARY); + Content memberTree = writer.getMemberTreeHeader(); + writer.addSummaryHeader(this, classDoc, memberTree); + return memberTree; + } + + /** + * {@inheritDoc} + */ + public Content getMemberTreeHeader() { + return writer.getMemberTreeHeader(); + } + + /** + * {@inheritDoc} + */ + public void addAnnotationFieldDetailsMarker(Content memberDetails) { + memberDetails.addContent(HtmlConstants.START_OF_ANNOTATION_TYPE_FIELD_DETAILS); + } + + /** + * {@inheritDoc} + */ + public void addAnnotationDetailsTreeHeader(ClassDoc classDoc, + Content memberDetailsTree) { + if (!writer.printedAnnotationFieldHeading) { + memberDetailsTree.addContent(writer.getMarkerAnchor( + "annotation_type_field_detail")); + Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING, + writer.fieldDetailsLabel); + memberDetailsTree.addContent(heading); + writer.printedAnnotationFieldHeading = true; + } + } + + /** + * {@inheritDoc} + */ + public Content getAnnotationDocTreeHeader(MemberDoc member, + Content annotationDetailsTree) { + annotationDetailsTree.addContent( + writer.getMarkerAnchor(member.name())); + Content annotationDocTree = writer.getMemberTreeHeader(); + Content heading = new HtmlTree(HtmlConstants.MEMBER_HEADING); + heading.addContent(member.name()); + annotationDocTree.addContent(heading); + return annotationDocTree; + } + + /** + * {@inheritDoc} + */ + public Content getSignature(MemberDoc member) { + Content pre = new HtmlTree(HtmlTag.PRE); + writer.addAnnotationInfo(member, pre); + addModifiers(member, pre); + Content link = + writer.getLink(new LinkInfoImpl(configuration, + LinkInfoImpl.Kind.MEMBER, getType(member))); + pre.addContent(link); + pre.addContent(writer.getSpace()); + if (configuration.linksource) { + Content memberName = new StringContent(member.name()); + writer.addSrcLink(member, memberName, pre); + } else { + addName(member.name(), pre); + } + return pre; + } + + /** + * {@inheritDoc} + */ + public void addDeprecated(MemberDoc member, Content annotationDocTree) { + addDeprecatedInfo(member, annotationDocTree); + } + + /** + * {@inheritDoc} + */ + public void addComments(MemberDoc member, Content annotationDocTree) { + addComment(member, annotationDocTree); + } + + /** + * {@inheritDoc} + */ + public void addTags(MemberDoc member, Content annotationDocTree) { + writer.addTagsInfo(member, annotationDocTree); + } + + /** + * {@inheritDoc} + */ + public Content getAnnotationDetails(Content annotationDetailsTree) { + return getMemberTree(annotationDetailsTree); + } + + /** + * {@inheritDoc} + */ + public Content getAnnotationDoc(Content annotationDocTree, + boolean isLastContent) { + return getMemberTree(annotationDocTree, isLastContent); + } + + /** + * Close the writer. + */ + public void close() throws IOException { + writer.close(); + } + + /** + * {@inheritDoc} + */ + public void addSummaryLabel(Content memberTree) { + Content label = HtmlTree.HEADING(HtmlConstants.SUMMARY_HEADING, + writer.getResource("doclet.Field_Summary")); + memberTree.addContent(label); + } + + /** + * {@inheritDoc} + */ + public String getTableSummary() { + return configuration.getText("doclet.Member_Table_Summary", + configuration.getText("doclet.Field_Summary"), + configuration.getText("doclet.fields")); + } + + /** + * {@inheritDoc} + */ + public Content getCaption() { + return configuration.getResource("doclet.Fields"); + } + + /** + * {@inheritDoc} + */ + public String[] getSummaryTableHeader(ProgramElementDoc member) { + String[] header = new String[] { + writer.getModifierTypeHeader(), + configuration.getText("doclet.0_and_1", + configuration.getText("doclet.Fields"), + configuration.getText("doclet.Description")) + }; + return header; + } + + /** + * {@inheritDoc} + */ + public void addSummaryAnchor(ClassDoc cd, Content memberTree) { + memberTree.addContent(writer.getMarkerAnchor( + "annotation_type_field_summary")); + } + + /** + * {@inheritDoc} + */ + public void addInheritedSummaryAnchor(ClassDoc cd, Content inheritedTree) { + } + + /** + * {@inheritDoc} + */ + public void addInheritedSummaryLabel(ClassDoc cd, Content inheritedTree) { + } + + /** + * {@inheritDoc} + */ + protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member, + Content tdSummary) { + Content strong = HtmlTree.SPAN(HtmlStyle.strong, + writer.getDocLink(context, (MemberDoc) member, member.name(), false)); + Content code = HtmlTree.CODE(strong); + tdSummary.addContent(code); + } + + /** + * {@inheritDoc} + */ + protected void addInheritedSummaryLink(ClassDoc cd, + ProgramElementDoc member, Content linksTree) { + //Not applicable. + } + + /** + * {@inheritDoc} + */ + protected void addSummaryType(ProgramElementDoc member, Content tdSummaryType) { + MemberDoc m = (MemberDoc)member; + addModifierAndType(m, getType(m), tdSummaryType); + } + + /** + * {@inheritDoc} + */ + protected Content getDeprecatedLink(ProgramElementDoc member) { + return writer.getDocLink(LinkInfoImpl.Kind.MEMBER, + (MemberDoc) member, ((MemberDoc)member).qualifiedName()); + } + + /** + * {@inheritDoc} + */ + protected Content getNavSummaryLink(ClassDoc cd, boolean link) { + if (link) { + return writer.getHyperLink("annotation_type_field_summary", + writer.getResource("doclet.navField")); + } else { + return writer.getResource("doclet.navField"); + } + } + + /** + * {@inheritDoc} + */ + protected void addNavDetailLink(boolean link, Content liNav) { + if (link) { + liNav.addContent(writer.getHyperLink("annotation_type_field_detail", + writer.getResource("doclet.navField"))); + } else { + liNav.addContent(writer.getResource("doclet.navField")); + } + } + + private Type getType(MemberDoc member) { + if (member instanceof FieldDoc) { + return ((FieldDoc) member).type(); + } else { + return ((MethodDoc) member).returnType(); + } + } +} diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java index a2fa33b68a5..1833d262db3 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java @@ -68,6 +68,20 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter return memberTree; } + /** + * {@inheritDoc} + */ + public Content getMemberTreeHeader() { + return writer.getMemberTreeHeader(); + } + + /** + * {@inheritDoc} + */ + public void addAnnotationDetailsMarker(Content memberDetails) { + memberDetails.addContent(HtmlConstants.START_OF_ANNOTATION_TYPE_DETAILS); + } + /** * {@inheritDoc} */ diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java index c1c4c9d40e6..c90ae08c27e 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java @@ -275,13 +275,6 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter } } - /** - * {@inheritDoc} - */ - public void addAnnotationDetailsMarker(Content memberDetails) { - memberDetails.addContent(HtmlConstants.START_OF_ANNOTATION_TYPE_DETAILS); - } - /** * {@inheritDoc} */ @@ -319,6 +312,12 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder) configuration.getBuilderFactory().getMemberSummaryBuilder(this); + Content liNavField = new HtmlTree(HtmlTag.LI); + addNavSummaryLink(memberSummaryBuilder, + "doclet.navField", + VisibleMemberMap.ANNOTATION_TYPE_FIELDS, liNavField); + addNavGap(liNavField); + ulNav.addContent(liNavField); Content liNavReq = new HtmlTree(HtmlTag.LI); addNavSummaryLink(memberSummaryBuilder, "doclet.navAnnotationTypeRequiredMember", @@ -364,12 +363,23 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder) configuration.getBuilderFactory().getMemberSummaryBuilder(this); + AbstractMemberWriter writerField = + ((AbstractMemberWriter) memberSummaryBuilder. + getMemberSummaryWriter(VisibleMemberMap.ANNOTATION_TYPE_FIELDS)); AbstractMemberWriter writerOptional = ((AbstractMemberWriter) memberSummaryBuilder. getMemberSummaryWriter(VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL)); AbstractMemberWriter writerRequired = ((AbstractMemberWriter) memberSummaryBuilder. getMemberSummaryWriter(VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED)); + Content liNavField = new HtmlTree(HtmlTag.LI); + if (writerField != null){ + writerField.addNavDetailLink(annotationType.fields().length > 0, liNavField); + } else { + liNavField.addContent(getResource("doclet.navField")); + } + addNavGap(liNavField); + ulNav.addContent(liNavField); if (writerOptional != null){ Content liNavOpt = new HtmlTree(HtmlTag.LI); writerOptional.addNavDetailLink(annotationType.elements().length > 0, liNavOpt); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java index da36fedcff0..b3bfdcb1c3c 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java @@ -84,6 +84,11 @@ public class HtmlDocletWriter extends HtmlDocWriter { */ protected boolean printedAnnotationHeading = false; + /** + * To check whether annotation field heading is printed or not. + */ + protected boolean printedAnnotationFieldHeading = false; + /** * To check whether the repeated annotations is documented or not. */ diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java index b8a1775c7be..70bace904ab 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java @@ -104,6 +104,16 @@ public class WriterFactoryImpl implements WriterFactory { annotationType, prevType, nextType); } + /** + * {@inheritDoc} + */ + public AnnotationTypeFieldWriter + getAnnotationTypeFieldWriter(AnnotationTypeWriter annotationTypeWriter) throws Exception { + return new AnnotationTypeFieldWriterImpl( + (SubWriterHolderWriter) annotationTypeWriter, + annotationTypeWriter.getAnnotationTypeDoc()); + } + /** * {@inheritDoc} */ @@ -202,6 +212,9 @@ public class WriterFactoryImpl implements WriterFactory { AnnotationTypeWriter annotationTypeWriter, int memberType) throws Exception { switch (memberType) { + case VisibleMemberMap.ANNOTATION_TYPE_FIELDS: + return (AnnotationTypeFieldWriterImpl) + getAnnotationTypeFieldWriter(annotationTypeWriter); case VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL: return (AnnotationTypeOptionalMemberWriterImpl) getAnnotationTypeOptionalMemberWriter(annotationTypeWriter); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java index 7c32503e625..98651468f95 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java @@ -93,6 +93,12 @@ public class HtmlConstants { public static final Content START_OF_ANNOTATION_TYPE_REQUIRED_MEMBER_SUMMARY = new Comment("=========== ANNOTATION TYPE REQUIRED MEMBER SUMMARY ==========="); + /** + * Marker to identify start of annotation type required member summary. + */ + public static final Content START_OF_ANNOTATION_TYPE_FIELD_SUMMARY = + new Comment("=========== ANNOTATION TYPE FIELD SUMMARY ==========="); + /** * Marker to identify start of constructor summary. */ @@ -129,6 +135,12 @@ public class HtmlConstants { public static final Content START_OF_ANNOTATION_TYPE_DETAILS = new Comment("============ ANNOTATION TYPE MEMBER DETAIL ==========="); + /** + * Marker to identify start of annotation type field details. + */ + public static final Content START_OF_ANNOTATION_TYPE_FIELD_DETAILS = + new Comment("============ ANNOTATION TYPE FIELD DETAIL ==========="); + /** * Marker to identify start of method details. */ diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeFieldWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeFieldWriter.java new file mode 100644 index 00000000000..b556ccc7c86 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeFieldWriter.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclets.internal.toolkit; + +import java.io.*; +import com.sun.javadoc.*; + +/** + * The interface for writing annotation type field output. + * + *

    This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + * + * + * @author Bhavesh Patel + * @since 1.8 + */ + +public interface AnnotationTypeFieldWriter { + + /** + * Add the annotation type member tree header. + * + * @return content tree for the member tree header + */ + public Content getMemberTreeHeader(); + + /** + * Add the annotation type field details marker. + * + * @param memberDetails the content tree representing field details marker + */ + public void addAnnotationFieldDetailsMarker(Content memberDetails); + + /** + * Add the annotation type details tree header. + * + * @param classDoc the annotation type being documented + * @param memberDetailsTree the content tree representing member details + */ + public void addAnnotationDetailsTreeHeader(ClassDoc classDoc, + Content memberDetailsTree); + + /** + * Get the annotation type documentation tree header. + * + * @param member the annotation type being documented + * @param annotationDetailsTree the content tree representing annotation type details + * @return content tree for the annotation type documentation header + */ + public Content getAnnotationDocTreeHeader(MemberDoc member, + Content annotationDetailsTree); + + /** + * Get the annotation type details tree. + * + * @param annotationDetailsTree the content tree representing annotation type details + * @return content tree for the annotation type details + */ + public Content getAnnotationDetails(Content annotationDetailsTree); + + /** + * Get the annotation type documentation. + * + * @param annotationDocTree the content tree representing annotation type documentation + * @param isLastContent true if the content to be added is the last content + * @return content tree for the annotation type documentation + */ + public Content getAnnotationDoc(Content annotationDocTree, boolean isLastContent); + + /** + * Get the signature for the given member. + * + * @param member the member being documented + * @return content tree for the annotation type signature + */ + public Content getSignature(MemberDoc member); + + /** + * Add the deprecated output for the given member. + * + * @param member the member being documented + * @param annotationDocTree content tree to which the deprecated information will be added + */ + public void addDeprecated(MemberDoc member, Content annotationDocTree); + + /** + * Add the comments for the given member. + * + * @param member the member being documented + * @param annotationDocTree the content tree to which the comments will be added + */ + public void addComments(MemberDoc member, Content annotationDocTree); + + /** + * Add the tags for the given member. + * + * @param member the member being documented + * @param annotationDocTree the content tree to which the tags will be added + */ + public void addTags(MemberDoc member, Content annotationDocTree); + + /** + * Close the writer. + */ + public void close() throws IOException; +} diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeRequiredMemberWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeRequiredMemberWriter.java index 28a18f9eaad..294d3217195 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeRequiredMemberWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeRequiredMemberWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,20 @@ import com.sun.javadoc.*; public interface AnnotationTypeRequiredMemberWriter { + /** + * Add the annotation type member tree header. + * + * @return content tree for the member tree header + */ + public Content getMemberTreeHeader(); + + /** + * Add the annotation type details marker. + * + * @param memberDetails the content tree representing details marker + */ + public void addAnnotationDetailsMarker(Content memberDetails); + /** * Add the annotation type details tree header. * diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeWriter.java index b65740edf87..c11dfd8527e 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -103,13 +103,6 @@ public interface AnnotationTypeWriter { */ public void addAnnotationTypeDeprecationInfo (Content annotationInfoTree); - /** - * Add the annotation type details marker. - * - * @param memberDetails the content tree representing member details marker - */ - public void addAnnotationDetailsMarker(Content memberDetails); - /** * Get the member tree header for the annotation type. * diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java index 1fa4c2f00e9..985fb646647 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java @@ -129,6 +129,18 @@ public interface WriterFactory { public abstract MethodWriter getMethodWriter(ClassWriter classWriter) throws Exception; + /** + * Return the annotation type field writer for a given annotation type. + * + * @param annotationTypeWriter the writer for the annotation type + * being documented. + * @return the member writer for the given annotation type. Return null if + * this writer is not supported by the doclet. + */ + public abstract AnnotationTypeFieldWriter + getAnnotationTypeFieldWriter( + AnnotationTypeWriter annotationTypeWriter) throws Exception; + /** * Return the annotation type optional member writer for a given annotation * type. diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java index 4de54026794..ae1de88d587 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java @@ -223,13 +223,22 @@ public class AnnotationTypeBuilder extends AbstractBuilder { Content memberDetailsTree = writer.getMemberTreeHeader(); buildChildren(node, memberDetailsTree); if (memberDetailsTree.isValid()) { - Content memberDetails = writer.getMemberTreeHeader(); - writer.addAnnotationDetailsMarker(memberDetails); - memberDetails.addContent(writer.getMemberTree(memberDetailsTree)); - annotationContentTree.addContent(writer.getMemberDetailsTree(memberDetails)); + annotationContentTree.addContent(writer.getMemberDetailsTree(memberDetailsTree)); } } + /** + * Build the annotation type field documentation. + * + * @param node the XML element that specifies which components to document + * @param memberDetailsTree the content tree to which the documentation will be added + */ + public void buildAnnotationTypeFieldDetails(XMLNode node, Content memberDetailsTree) + throws Exception { + configuration.getBuilderFactory(). + getAnnotationTypeFieldsBuilder(writer).buildChildren(node, memberDetailsTree); + } + /** * Build the annotation type optional member documentation. * diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeFieldBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeFieldBuilder.java new file mode 100644 index 00000000000..4cbd4a20213 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeFieldBuilder.java @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclets.internal.toolkit.builders; + +import java.util.*; + +import com.sun.javadoc.*; +import com.sun.tools.doclets.internal.toolkit.*; +import com.sun.tools.doclets.internal.toolkit.util.*; + +/** + * Builds documentation for annotation type fields. + * + *

    This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + * + * @author Bhavesh Patel + * @since 1.8 + */ +public class AnnotationTypeFieldBuilder extends AbstractMemberBuilder { + + /** + * The annotation type whose members are being documented. + */ + protected ClassDoc classDoc; + + /** + * The visible members for the given class. + */ + protected VisibleMemberMap visibleMemberMap; + + /** + * The writer to output the member documentation. + */ + protected AnnotationTypeFieldWriter writer; + + /** + * The list of members being documented. + */ + protected List members; + + /** + * The index of the current member that is being documented at this point + * in time. + */ + protected int currentMemberIndex; + + /** + * Construct a new AnnotationTypeFieldsBuilder. + * + * @param context the build context. + * @param classDoc the class whose members are being documented. + * @param writer the doclet specific writer. + * @param memberType the type of member that is being documented. + */ + protected AnnotationTypeFieldBuilder(Context context, + ClassDoc classDoc, + AnnotationTypeFieldWriter writer, + int memberType) { + super(context); + this.classDoc = classDoc; + this.writer = writer; + this.visibleMemberMap = new VisibleMemberMap(classDoc, memberType, + configuration); + this.members = new ArrayList( + this.visibleMemberMap.getMembersFor(classDoc)); + if (configuration.getMemberComparator() != null) { + Collections.sort(this.members, configuration.getMemberComparator()); + } + } + + + /** + * Construct a new AnnotationTypeFieldBuilder. + * + * @param context the build context. + * @param classDoc the class whose members are being documented. + * @param writer the doclet specific writer. + */ + public static AnnotationTypeFieldBuilder getInstance( + Context context, ClassDoc classDoc, + AnnotationTypeFieldWriter writer) { + return new AnnotationTypeFieldBuilder(context, classDoc, + writer, VisibleMemberMap.ANNOTATION_TYPE_FIELDS); + } + + /** + * {@inheritDoc} + */ + public String getName() { + return "AnnotationTypeFieldDetails"; + } + + /** + * Returns a list of members that will be documented for the given class. + * This information can be used for doclet specific documentation + * generation. + * + * @param classDoc the {@link ClassDoc} we want to check. + * @return a list of members that will be documented. + */ + public List members(ClassDoc classDoc) { + return visibleMemberMap.getMembersFor(classDoc); + } + + /** + * Returns the visible member map for the members of this class. + * + * @return the visible member map for the members of this class. + */ + public VisibleMemberMap getVisibleMemberMap() { + return visibleMemberMap; + } + + /** + * summaryOrder.size() + */ + public boolean hasMembersToDocument() { + return members.size() > 0; + } + + /** + * Build the annotation type field documentation. + * + * @param node the XML element that specifies which components to document + * @param memberDetailsTree the content tree to which the documentation will be added + */ + public void buildAnnotationTypeField(XMLNode node, Content memberDetailsTree) { + buildAnnotationTypeMember(node, memberDetailsTree); + } + + /** + * Build the member documentation. + * + * @param node the XML element that specifies which components to document + * @param memberDetailsTree the content tree to which the documentation will be added + */ + public void buildAnnotationTypeMember(XMLNode node, Content memberDetailsTree) { + if (writer == null) { + return; + } + int size = members.size(); + if (size > 0) { + writer.addAnnotationFieldDetailsMarker(memberDetailsTree); + for (currentMemberIndex = 0; currentMemberIndex < size; + currentMemberIndex++) { + Content detailsTree = writer.getMemberTreeHeader(); + writer.addAnnotationDetailsTreeHeader(classDoc, detailsTree); + Content annotationDocTree = writer.getAnnotationDocTreeHeader( + (MemberDoc) members.get(currentMemberIndex), + detailsTree); + buildChildren(node, annotationDocTree); + detailsTree.addContent(writer.getAnnotationDoc( + annotationDocTree, (currentMemberIndex == size - 1))); + memberDetailsTree.addContent(writer.getAnnotationDetails(detailsTree)); + } + } + } + + /** + * Build the signature. + * + * @param node the XML element that specifies which components to document + * @param annotationDocTree the content tree to which the documentation will be added + */ + public void buildSignature(XMLNode node, Content annotationDocTree) { + annotationDocTree.addContent( + writer.getSignature((MemberDoc) members.get(currentMemberIndex))); + } + + /** + * Build the deprecation information. + * + * @param node the XML element that specifies which components to document + * @param annotationDocTree the content tree to which the documentation will be added + */ + public void buildDeprecationInfo(XMLNode node, Content annotationDocTree) { + writer.addDeprecated((MemberDoc) members.get(currentMemberIndex), + annotationDocTree); + } + + /** + * Build the comments for the member. Do nothing if + * {@link Configuration#nocomment} is set to true. + * + * @param node the XML element that specifies which components to document + * @param annotationDocTree the content tree to which the documentation will be added + */ + public void buildMemberComments(XMLNode node, Content annotationDocTree) { + if(! configuration.nocomment){ + writer.addComments((MemberDoc) members.get(currentMemberIndex), + annotationDocTree); + } + } + + /** + * Build the tag information. + * + * @param node the XML element that specifies which components to document + * @param annotationDocTree the content tree to which the documentation will be added + */ + public void buildTagInfo(XMLNode node, Content annotationDocTree) { + writer.addTags((MemberDoc) members.get(currentMemberIndex), + annotationDocTree); + } + + /** + * Return the annotation type field writer for this builder. + * + * @return the annotation type field writer for this builder. + */ + public AnnotationTypeFieldWriter getWriter() { + return writer; + } +} diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java index 84ded901668..29ad9df370d 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java @@ -167,16 +167,17 @@ public class AnnotationTypeRequiredMemberBuilder extends AbstractMemberBuilder { } int size = members.size(); if (size > 0) { - writer.addAnnotationDetailsTreeHeader( - classDoc, memberDetailsTree); + writer.addAnnotationDetailsMarker(memberDetailsTree); for (currentMemberIndex = 0; currentMemberIndex < size; - currentMemberIndex++) { + currentMemberIndex++) { + Content detailsTree = writer.getMemberTreeHeader(); + writer.addAnnotationDetailsTreeHeader(classDoc, detailsTree); Content annotationDocTree = writer.getAnnotationDocTreeHeader( - (MemberDoc) members.get(currentMemberIndex), - memberDetailsTree); + (MemberDoc) members.get(currentMemberIndex), detailsTree); buildChildren(node, annotationDocTree); - memberDetailsTree.addContent(writer.getAnnotationDoc( + detailsTree.addContent(writer.getAnnotationDoc( annotationDocTree, (currentMemberIndex == size - 1))); + memberDetailsTree.addContent(writer.getAnnotationDetails(detailsTree)); } } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java index 7152f2bd4f2..3509a06eac9 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java @@ -173,11 +173,27 @@ public class BuilderFactory { writerFactory.getMethodWriter(classWriter)); } + /** + * Return an instance of the annotation type fields builder for the given + * class. + * + * @return an instance of the annotation type field builder for the given + * annotation type. + */ + public AbstractBuilder getAnnotationTypeFieldsBuilder( + AnnotationTypeWriter annotationTypeWriter) + throws Exception { + return AnnotationTypeFieldBuilder.getInstance(context, + annotationTypeWriter.getAnnotationTypeDoc(), + writerFactory.getAnnotationTypeFieldWriter( + annotationTypeWriter)); + } + /** * Return an instance of the annotation type member builder for the given * class. * - * @return an instance of the annotation type memebr builder for the given + * @return an instance of the annotation type member builder for the given * annotation type. */ public AbstractBuilder getAnnotationTypeOptionalMemberBuilder( @@ -193,7 +209,7 @@ public class BuilderFactory { * Return an instance of the annotation type member builder for the given * class. * - * @return an instance of the annotation type memebr builder for the given + * @return an instance of the annotation type member builder for the given * annotation type. */ public AbstractBuilder getAnnotationTypeRequiredMemberBuilder( diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java index 8edb5dd2bad..fb4f14c8253 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java @@ -212,6 +212,20 @@ public class MemberSummaryBuilder extends AbstractMemberBuilder { addSummary(writer, visibleMemberMap, false, memberSummaryTree); } + /** + * Build the summary for fields. + * + * @param node the XML element that specifies which components to document + * @param memberSummaryTree the content tree to which the documentation will be added + */ + public void buildAnnotationTypeFieldsSummary(XMLNode node, Content memberSummaryTree) { + MemberSummaryWriter writer = + memberSummaryWriters[VisibleMemberMap.ANNOTATION_TYPE_FIELDS]; + VisibleMemberMap visibleMemberMap = + visibleMemberMaps[VisibleMemberMap.ANNOTATION_TYPE_FIELDS]; + addSummary(writer, visibleMemberMap, false, memberSummaryTree); + } + /** * Build the summary for the optional members. * diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml index aabaafff250..f7f2f9c7458 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml @@ -66,10 +66,19 @@ + + + + + + + + + diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java index 6c9870405f3..15d41773b4e 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java @@ -55,14 +55,15 @@ public class VisibleMemberMap { public static final int FIELDS = 2; public static final int CONSTRUCTORS = 3; public static final int METHODS = 4; - public static final int ANNOTATION_TYPE_MEMBER_OPTIONAL = 5; - public static final int ANNOTATION_TYPE_MEMBER_REQUIRED = 6; - public static final int PROPERTIES = 7; + public static final int ANNOTATION_TYPE_FIELDS = 5; + public static final int ANNOTATION_TYPE_MEMBER_OPTIONAL = 6; + public static final int ANNOTATION_TYPE_MEMBER_REQUIRED = 7; + public static final int PROPERTIES = 8; /** * The total number of member types is {@value}. */ - public static final int NUM_MEMBER_TYPES = 8; + public static final int NUM_MEMBER_TYPES = 9; public static final String STARTLEVEL = "start"; @@ -433,6 +434,9 @@ public class VisibleMemberMap { } ProgramElementDoc[] members = null; switch (kind) { + case ANNOTATION_TYPE_FIELDS: + members = cd.fields(filter); + break; case ANNOTATION_TYPE_MEMBER_OPTIONAL: members = cd.isAnnotationType() ? filter((AnnotationTypeDoc) cd, false) : diff --git a/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java b/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java index 65a8e5d7cfa..5ffdbab12b2 100644 --- a/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java +++ b/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,20 +23,19 @@ /* * @test - * @bug 4973609 + * @bug 4973609 8015249 * @summary Make sure that annotation types with 0 members does not have * extra HR tags. * @author jamieh * @library ../lib/ - * @build JavadocTester - * @build TestAnnotationTypes + * @build JavadocTester TestAnnotationTypes * @run main TestAnnotationTypes */ public class TestAnnotationTypes extends JavadocTester { //Test information. - private static final String BUG_ID = "4973609"; + private static final String BUG_ID = "4973609-8015249"; //Javadoc arguments. private static final String[] ARGS = new String[] { @@ -44,7 +43,31 @@ public class TestAnnotationTypes extends JavadocTester { }; //Input for string search tests. - private static final String[][] TEST = NO_TEST; + private static final String[][] TEST = { + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + "

  • Summary: 
  • " + NL + "
  • Field | 
  • "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + "
  • Detail: 
  • " + NL + "
  • Field | 
  • "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + ""}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + "

    Field Summary

    "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + "

  • DEFAULT_NAME" + + " 
    Methods " + "
    + * * * * @@ -985,25 +986,25 @@ public class HTMLDocument extends DefaultStyledDocument { * parameter is in bold).

    * *
    -     *     <body>
    +     *     <body>
          *       |
    -     *     <div>
    +     *     <div>
          *      /  \
    -     *    <p>   <p>
    +     *    <p>   <p>
          * 
    * - *

    Invoking setInnerHTML(elem, "<ul><li>") + *

    Invoking setInnerHTML(elem, "<ul><li>") * results in the following structure (new elements are in red).

    * *
    -     *     <body>
    +     *     <body>
          *       |
    -     *     <div>
    +     *     <div>
          *         \
    -     *         <ul>
    +     *         <ul>
          *           \
    -     *           <li>
    +     *           <li>
          * 
    * *

    Parameter elem must not be a leaf element, @@ -1066,23 +1067,23 @@ public class HTMLDocument extends DefaultStyledDocument { * parameter is in bold).

    * *
    -     *     <body>
    +     *     <body>
          *       |
    -     *     <div>
    +     *     <div>
          *      /  \
    -     *    <p>   <p>
    +     *    <p>   <p>
          * 
    * - *

    Invoking setOuterHTML(elem, "<ul><li>") + *

    Invoking setOuterHTML(elem, "<ul><li>") * results in the following structure (new elements are in red).

    * *
    -     *    <body>
    +     *    <body>
          *      |
    -     *     <ul>
    +     *     <ul>
          *       \
    -     *       <li>
    +     *       <li>
          * 
    * *

    If either elem or htmlText @@ -1136,25 +1137,25 @@ public class HTMLDocument extends DefaultStyledDocument { * parameter is in bold).

    * *
    -     *     <body>
    +     *     <body>
          *       |
    -     *     <div>
    +     *     <div>
          *      /  \
    -     *    <p>   <p>
    +     *    <p>   <p>
          * 
    * *

    Invoking insertAfterStart(elem, - * "<ul><li>") results in the following structure + * "<ul><li>") results in the following structure * (new elements are in red).

    * *
    -     *        <body>
    +     *        <body>
          *          |
    -     *        <div>
    +     *        <div>
          *       /  |  \
    -     *    <ul> <p> <p>
    +     *    <ul> <p> <p>
          *     /
    -     *  <li>
    +     *  <li>
          * 
    * *

    Unlike the insertBeforeStart method, new @@ -1206,25 +1207,25 @@ public class HTMLDocument extends DefaultStyledDocument { * parameter is in bold).

    * *
    -     *     <body>
    +     *     <body>
          *       |
    -     *     <div>
    +     *     <div>
          *      /  \
    -     *    <p>   <p>
    +     *    <p>   <p>
          * 
    * - *

    Invoking insertBeforeEnd(elem, "<ul><li>") + *

    Invoking insertBeforeEnd(elem, "<ul><li>") * results in the following structure (new elements are in red).

    * *
    -     *        <body>
    +     *        <body>
          *          |
    -     *        <div>
    +     *        <div>
          *       /  |  \
    -     *     <p> <p> <ul>
    +     *     <p> <p> <ul>
          *               \
    -     *               <li>
    +     *               <li>
          * 
    * *

    Unlike the insertAfterEnd method, new elements @@ -1273,23 +1274,23 @@ public class HTMLDocument extends DefaultStyledDocument { * parameter is in bold).

    * *
    -     *     <body>
    +     *     <body>
          *       |
    -     *     <div>
    +     *     <div>
          *      /  \
    -     *    <p>   <p>
    +     *    <p>   <p>
          * 
    * *

    Invoking insertBeforeStart(elem, - * "<ul><li>") results in the following structure + * "<ul><li>") results in the following structure * (new elements are in red).

    * *
    -     *        <body>
    +     *        <body>
          *         /  \
    -     *      <ul> <div>
    +     *      <ul> <div>
          *       /    /  \
    -     *     <li> <p>  <p>
    +     *     <li> <p>  <p>
          * 
    * *

    Unlike the insertAfterStart method, new @@ -1331,23 +1332,23 @@ public class HTMLDocument extends DefaultStyledDocument { * parameter is in bold).

    * *
    -     *     <body>
    +     *     <body>
          *       |
    -     *     <div>
    +     *     <div>
          *      /  \
    -     *    <p>   <p>
    +     *    <p>   <p>
          * 
    * - *

    Invoking insertAfterEnd(elem, "<ul><li>") + *

    Invoking insertAfterEnd(elem, "<ul><li>") * results in the following structure (new elements are in red).

    * *
    -     *        <body>
    +     *        <body>
          *         /  \
    -     *      <div> <ul>
    +     *      <div> <ul>
          *       / \    \
    -     *     <p> <p>  <li>
    +     *     <p> <p>  <li>
          * 
    * *

    Unlike the insertBeforeEnd method, new elements @@ -2166,7 +2167,7 @@ public class HTMLDocument extends DefaultStyledDocument { *

    ExampleinsertAfterStart
    HTML.Tag.VAR CharacterAction *
    *

    - * Once </html> is encountered, the Actions are no longer notified. + * Once </html> is encountered, the Actions are no longer notified. */ public class HTMLReader extends HTMLEditorKit.ParserCallback { From 602931b7cee62d117b1117135a62125afa418dcd Mon Sep 17 00:00:00 2001 From: Vera Akulova Date: Tue, 24 Sep 2013 17:46:19 +0400 Subject: [PATCH 0480/1294] 7124320: [TEST_BUG] [macosx] JComboBox doesn't change selection on mouse over Reviewed-by: alexsch, serb --- .../swing/JComboBox/6236162/bug6236162.java | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 jdk/test/javax/swing/JComboBox/6236162/bug6236162.java diff --git a/jdk/test/javax/swing/JComboBox/6236162/bug6236162.java b/jdk/test/javax/swing/JComboBox/6236162/bug6236162.java new file mode 100644 index 00000000000..6e0ad44e734 --- /dev/null +++ b/jdk/test/javax/swing/JComboBox/6236162/bug6236162.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013, 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 6236162 + @summary Checks that there is no an inconsistence in combo box + behavior when user points an item in combo popup + by mouse and then uses UP/DOWN keys. + @library ../../regtesthelpers + @build Util + @author Mikhail Lapshin + @run main bug6236162 +*/ + +import sun.awt.SunToolkit; + +import javax.swing.*; +import javax.swing.plaf.basic.*; +import javax.swing.plaf.metal.MetalComboBoxUI; +import java.awt.*; +import java.awt.event.KeyEvent; + +public class bug6236162 { + private static final SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + private static JFrame frame; + private static JComboBox combo; + private static MyComboUI comboUI; + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + toolkit.realSync(); + test(); + System.out.println("Test passed"); + } + + private static void createAndShowGUI() { + frame = new JFrame("bug6236162"); + + combo = new JComboBox(new String[]{"one", "two", "three", "four", "five"}); + combo.setEditable(true); + comboUI = new MyComboUI(); + combo.setUI(comboUI); + combo.setSelectedIndex(3); + frame.getContentPane().add(combo); + + frame.pack(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + private static void test() throws AWTException { + Robot robot = new Robot(); + robot.setAutoDelay(50); + + // Open popup menu + realSync(); + Util.hitKeys(robot, KeyEvent.VK_DOWN); + + // Move mouse to the first popup menu item + realSync(); + Point p = combo.getLocationOnScreen(); + Dimension size = combo.getSize(); + p.x += size.width / 2; + p.y += size.height; + float dy = 1; + robot.mouseMove(p.x, p.y - 5); + for (int i=1; i <= 10; i++) { + robot.mouseMove((int)(p.x), (int)(p.y - 5 + dy*i)); + } + + // Select the second popup menu item + realSync(); + Util.hitKeys(robot, KeyEvent.VK_DOWN); + + realSync(); + JList list = comboUI.getComboPopup().getList(); + if (list.getSelectedIndex() != 1) { + throw new RuntimeException("There is an inconsistence in combo box " + + "behavior when user points an item in combo popup " + + "by mouse and then uses UP/DOWN keys."); + } + } + + private static void realSync() { + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + } + + // Gives access to BasicComboBoxUI.popup field + private static class MyComboUI extends MetalComboBoxUI { + public ComboPopup getComboPopup() { + return popup; + } + } +} From a2889becd991625fb922b1916a6adcb4129d3fd7 Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Tue, 24 Sep 2013 15:56:25 +0200 Subject: [PATCH 0481/1294] 7009641: Don't fail VM when CodeCache is full Allocation in the code cache returns NULL instead of failing the entire VM Reviewed-by: kvn, iveresov --- hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp | 10 ++++++++++ hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp | 10 ++++++++++ hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp | 10 ++++++++++ hotspot/src/share/vm/code/compiledIC.cpp | 10 ++++++++-- hotspot/src/share/vm/code/compiledIC.hpp | 5 ++++- hotspot/src/share/vm/code/vtableStubs.cpp | 11 +++++++---- hotspot/src/share/vm/runtime/sharedRuntime.cpp | 7 +++++-- 7 files changed, 54 insertions(+), 9 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp index ce19d4d7e7b..cdbb57fbecd 100644 --- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp @@ -52,6 +52,11 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread, oopDesc* receiver, VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { const int sparc_code_length = VtableStub::pd_code_size_limit(true); VtableStub* s = new(sparc_code_length) VtableStub(true, vtable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), sparc_code_length); MacroAssembler* masm = new MacroAssembler(&cb); @@ -125,6 +130,11 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { VtableStub* VtableStubs::create_itable_stub(int itable_index) { const int sparc_code_length = VtableStub::pd_code_size_limit(false); VtableStub* s = new(sparc_code_length) VtableStub(false, itable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), sparc_code_length); MacroAssembler* masm = new MacroAssembler(&cb); diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp index c470004ebc8..7c49d737fa5 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp @@ -58,6 +58,11 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { const int i486_code_length = VtableStub::pd_code_size_limit(true); VtableStub* s = new(i486_code_length) VtableStub(true, vtable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), i486_code_length); MacroAssembler* masm = new MacroAssembler(&cb); @@ -132,6 +137,11 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) { // add code here, bump the code stub size returned by pd_code_size_limit! const int i486_code_length = VtableStub::pd_code_size_limit(false); VtableStub* s = new(i486_code_length) VtableStub(false, itable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), i486_code_length); MacroAssembler* masm = new MacroAssembler(&cb); diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp index 5f5f94f41a5..911341736d8 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp @@ -49,6 +49,11 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread, VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { const int amd64_code_length = VtableStub::pd_code_size_limit(true); VtableStub* s = new(amd64_code_length) VtableStub(true, vtable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), amd64_code_length); MacroAssembler* masm = new MacroAssembler(&cb); @@ -126,6 +131,11 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) { // returned by pd_code_size_limit! const int amd64_code_length = VtableStub::pd_code_size_limit(false); VtableStub* s = new(amd64_code_length) VtableStub(false, itable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), amd64_code_length); MacroAssembler* masm = new MacroAssembler(&cb); diff --git a/hotspot/src/share/vm/code/compiledIC.cpp b/hotspot/src/share/vm/code/compiledIC.cpp index b9db323e5b2..489e649fadc 100644 --- a/hotspot/src/share/vm/code/compiledIC.cpp +++ b/hotspot/src/share/vm/code/compiledIC.cpp @@ -160,7 +160,7 @@ address CompiledIC::stub_address() const { // High-level access to an inline cache. Guaranteed to be MT-safe. -void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { +bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic"); assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?"); @@ -170,8 +170,10 @@ void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod assert(bytecode == Bytecodes::_invokeinterface, ""); int itable_index = call_info->itable_index(); entry = VtableStubs::find_itable_stub(itable_index); + if (entry == false) { + return false; + } #ifdef ASSERT - assert(entry != NULL, "entry not computed"); int index = call_info->resolved_method()->itable_index(); assert(index == itable_index, "CallInfo pre-computes this"); #endif //ASSERT @@ -184,6 +186,9 @@ void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod int vtable_index = call_info->vtable_index(); assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check"); entry = VtableStubs::find_vtable_stub(vtable_index); + if (entry == NULL) { + return false; + } InlineCacheBuffer::create_transition_stub(this, NULL, entry); } @@ -200,6 +205,7 @@ void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod // race because the IC entry was complete when we safepointed so // cleaning it immediately is harmless. // assert(is_megamorphic(), "sanity check"); + return true; } diff --git a/hotspot/src/share/vm/code/compiledIC.hpp b/hotspot/src/share/vm/code/compiledIC.hpp index 96cb0a582bb..598cbe949e2 100644 --- a/hotspot/src/share/vm/code/compiledIC.hpp +++ b/hotspot/src/share/vm/code/compiledIC.hpp @@ -226,7 +226,10 @@ class CompiledIC: public ResourceObj { // void set_to_clean(); // Can only be called during a safepoint operation void set_to_monomorphic(CompiledICInfo& info); - void set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS); + + // Returns true if successful and false otherwise. The call can fail if memory + // allocation in the code cache fails. + bool set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS); static void compute_monomorphic_entry(methodHandle method, KlassHandle receiver_klass, bool is_optimized, bool static_bound, CompiledICInfo& info, TRAPS); diff --git a/hotspot/src/share/vm/code/vtableStubs.cpp b/hotspot/src/share/vm/code/vtableStubs.cpp index 7d9d7efaf67..5af91a3a6ee 100644 --- a/hotspot/src/share/vm/code/vtableStubs.cpp +++ b/hotspot/src/share/vm/code/vtableStubs.cpp @@ -46,12 +46,9 @@ address VtableStub::_chunk = NULL; address VtableStub::_chunk_end = NULL; VMReg VtableStub::_receiver_location = VMRegImpl::Bad(); -static int num_vtable_chunks = 0; - void* VtableStub::operator new(size_t size, int code_size) throw() { assert(size == sizeof(VtableStub), "mismatched size"); - num_vtable_chunks++; // compute real VtableStub size (rounded to nearest word) const int real_size = round_to(code_size + sizeof(VtableStub), wordSize); // malloc them in chunks to minimize header overhead @@ -60,7 +57,7 @@ void* VtableStub::operator new(size_t size, int code_size) throw() { const int bytes = chunk_factor * real_size + pd_code_alignment(); BufferBlob* blob = BufferBlob::create("vtable chunks", bytes); if (blob == NULL) { - vm_exit_out_of_memory(bytes, OOM_MALLOC_ERROR, "CodeCache: no room for vtable chunks"); + return NULL; } _chunk = blob->content_begin(); _chunk_end = _chunk + bytes; @@ -121,6 +118,12 @@ address VtableStubs::find_stub(bool is_vtable_stub, int vtable_index) { } else { s = create_itable_stub(vtable_index); } + + // Creation of vtable or itable can fail if there is not enough free space in the code cache. + if (s == NULL) { + return NULL; + } + enter(is_vtable_stub, vtable_index, s); if (PrintAdapterHandlers) { tty->print_cr("Decoding VtableStub %s[%d]@%d", diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index d014eda2f80..17ea65ae716 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -1506,8 +1506,11 @@ methodHandle SharedRuntime::handle_ic_miss_helper(JavaThread *thread, TRAPS) { info, CHECK_(methodHandle())); inline_cache->set_to_monomorphic(info); } else if (!inline_cache->is_megamorphic() && !inline_cache->is_clean()) { - // Change to megamorphic - inline_cache->set_to_megamorphic(&call_info, bc, CHECK_(methodHandle())); + // Potential change to megamorphic + bool successful = inline_cache->set_to_megamorphic(&call_info, bc, CHECK_(methodHandle())); + if (!successful) { + inline_cache->set_to_clean(); + } } else { // Either clean or megamorphic } From 036eee04735b37db761c1ce2f689d2c0633e81d1 Mon Sep 17 00:00:00 2001 From: Vera Akulova Date: Tue, 24 Sep 2013 17:56:32 +0400 Subject: [PATCH 0482/1294] 7133154: [TEST_BUG] [macosx] closed/javax/swing/JInternalFrame/4251301/bug4251301.java fails on MacOS Reviewed-by: alexsch, serb --- .../JInternalFrame/4251301/bug4251301.java | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 jdk/test/javax/swing/JInternalFrame/4251301/bug4251301.java diff --git a/jdk/test/javax/swing/JInternalFrame/4251301/bug4251301.java b/jdk/test/javax/swing/JInternalFrame/4251301/bug4251301.java new file mode 100644 index 00000000000..304d0582407 --- /dev/null +++ b/jdk/test/javax/swing/JInternalFrame/4251301/bug4251301.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013, 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 4251301 + @summary Keybinding for show/hide the system menu. + @author Andrey Pikalev + @run main/manual bug4251301 +*/ + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.*; +import sun.awt.OSInfo; +import sun.awt.SunToolkit; + + +public class bug4251301 { + private static final SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + static Test test = new Test(); + public static void main(String[] args) throws Exception { + if (OSInfo.getOSType() == OSInfo.OSType.MACOSX) { + System.out.println("This test is not applicable for MacOS. Passed."); + return; + } + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + toolkit.realSync(); + test.waitTestResult(); + } + + public static void createAndShowGUI() { + final StringBuilder instructions = new StringBuilder(); + instructions.append("Click with your mouse the content area of the internal frame with the title \"IFrame\" "); + instructions.append("and press Ctrl+Space. \n"); + instructions.append("If the system menu shows up, press Esc. Then system menu should hide. \n"); + instructions.append("If you success then press \"Pass\", else press \"Fail\".\n"); + + JDesktopPane dp = new JDesktopPane(); + JInternalFrame jif = new JInternalFrame("IFrame",true,true,true,true); + dp.add(jif); + jif.setBounds(20, 20, 220, 100); + jif.setVisible(true); + try { + jif.setSelected(true); + } catch(PropertyVetoException pve) { + pve.printStackTrace(); + throw new Error("Occures PropertyVetoException while set selection..."); + } + JScrollPane dtScrollPane = new JScrollPane(dp); + JFrame testFrame = test.createTestFrame("Instructions", dtScrollPane, instructions.toString(), 500); + testFrame.setSize(500, 400); + testFrame.setVisible(true); + } + static class Test { + private boolean pass; + JFrame createTestFrame(String name, Component topComponent, String instructions, int instrHeight) { + final String PASS = "Pass"; + final String FAIL = "Fail"; + JFrame frame = new JFrame(name); + frame.setLayout(new BorderLayout()); + + JPanel testButtonsPanel = new JPanel(); + testButtonsPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 20)); + + ActionListener btnAL = new ActionListener() { + public void actionPerformed(ActionEvent event) { + switch (event.getActionCommand()) { + case PASS: + pass(); + break; + default: + throw new RuntimeException("Test failed."); + } + } + }; + JButton passBtn = new JButton(PASS); + passBtn.addActionListener(btnAL); + passBtn.setActionCommand(PASS); + + JButton failBtn = new JButton(FAIL); + failBtn.addActionListener(btnAL); + failBtn.setActionCommand(FAIL); + + testButtonsPanel.add(BorderLayout.WEST, passBtn); + testButtonsPanel.add(BorderLayout.EAST, failBtn); + + JTextArea instrText = new JTextArea(); + instrText.setLineWrap(true); + instrText.setEditable(false); + JScrollPane instrScrollPane = new JScrollPane(instrText); + instrScrollPane.setMaximumSize(new Dimension(Integer.MAX_VALUE, instrHeight)); + instrText.append(instructions); + + JPanel servicePanel = new JPanel(); + servicePanel.setLayout(new BorderLayout()); + servicePanel.add(BorderLayout.CENTER, instrScrollPane); + servicePanel.add(BorderLayout.SOUTH, testButtonsPanel); + + frame.add(BorderLayout.SOUTH, servicePanel); + frame.add(BorderLayout.CENTER, topComponent); + return frame; + } + synchronized void pass() { + pass = true; + notifyAll(); + } + synchronized void waitTestResult() throws InterruptedException { + while (!pass) { + wait(); + } + } + } +} From 91047d3b0737f2889c768a39dd3ed6cdb026c975 Mon Sep 17 00:00:00 2001 From: Vera Akulova Date: Tue, 24 Sep 2013 18:13:24 +0400 Subject: [PATCH 0483/1294] 7133146: [macosx] closed/javax/swing/JInternalFrame/4193219/IconCoord fails on MacOS Reviewed-by: alexsch, serb --- .../JInternalFrame/4193219/IconCoord.java | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 jdk/test/javax/swing/JInternalFrame/4193219/IconCoord.java diff --git a/jdk/test/javax/swing/JInternalFrame/4193219/IconCoord.java b/jdk/test/javax/swing/JInternalFrame/4193219/IconCoord.java new file mode 100644 index 00000000000..709a197f2ae --- /dev/null +++ b/jdk/test/javax/swing/JInternalFrame/4193219/IconCoord.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2013, 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 4193219 + @summary + @author Your Name: Hania Gajewska area=swing + @run main/manual IconCoord +*/ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class IconCoord { + static Test test = new Test(); + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + new IconCoord().createAndShowGUI(); + } + }); + test.waitTestResult(); + } + + private void createAndShowGUI() { + StringBuilder instrText = new StringBuilder(); + instrText.append("First, iconify internal frame \"Frame 1\" by clicking on its iconify button.\n"); + instrText.append("Now, maximize the top-level window \"IconCoord\".\n"); + instrText.append("The \"Frame 1\" icon should stay in the lower left corner of the desktop; "); + instrText.append("if it doesn't, press \"Fail\".\n"); + instrText.append("Now move the icon to the middle of the desktop by dragging it by its "); + instrText.append("bumpy left side. Then iconify \"Frame 2\" by clicking on its iconify button.\n"); + instrText.append("If the icon for frame two gets placed in the lower left corner of the "); + instrText.append("desktop (where the icon for \"Frame 1\" used to be before you moved it), "); + instrText.append("press \"Pass\". Otherwise, press \"Fail\".\n"); + + JDesktopPane dt = new JDesktopPane(); + + JButton tf; + JInternalFrame if1 = new JInternalFrame("Frame 1", false, false, false, true); + JComponent c = (JComponent) if1.getContentPane(); + c.setLayout(new BorderLayout()); + + tf = new JButton ("ignore"); + c.add (tf, BorderLayout.NORTH); + + tf = new JButton ("ignore"); + c.add (tf, BorderLayout.CENTER); + + JInternalFrame if2 = new JInternalFrame("Frame 2", false, false, false, true); + c = (JComponent) if2.getContentPane(); + c.setLayout(new BorderLayout()); + + tf = new JButton ("ignore"); + c.add (tf, BorderLayout.NORTH); + + tf = new JButton ("ignore"); + c.add (tf, BorderLayout.CENTER); + + if1.pack(); + if1.setBounds(300, 0, 300, 80); + if2.pack(); + if2.setBounds(0, 0, 300, 80); + dt.add(if1); + dt.add(if2); + + if1.setVisible(true); + if2.setVisible(true); + + int frameHeight = 500; + + JScrollPane dtScrollPane = new JScrollPane(dt); + JFrame frame = test.createTestFrame("IconCoord", dtScrollPane, instrText.toString(), 250); + dt.setPreferredSize(new Dimension(650, frameHeight - 250)); + frame.setSize (600,500); + frame.setVisible(true); + } + + static class Test { + private boolean pass; + JFrame createTestFrame(String name, Component topComponent, String instructions, int instrHeight) { + final String PASS = "Pass"; + final String FAIL = "Fail"; + JFrame frame = new JFrame(name); + frame.setLayout(new BorderLayout()); + + JPanel testButtonsPanel = new JPanel(); + testButtonsPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 20)); + + ActionListener btnAL = new ActionListener() { + public void actionPerformed(ActionEvent event) { + switch (event.getActionCommand()) { + case PASS: + pass(); + break; + default: + throw new RuntimeException("Test failed."); + } + } + }; + JButton passBtn = new JButton(PASS); + passBtn.addActionListener(btnAL); + passBtn.setActionCommand(PASS); + + JButton failBtn = new JButton(FAIL); + failBtn.addActionListener(btnAL); + failBtn.setActionCommand(FAIL); + + testButtonsPanel.add(BorderLayout.WEST, passBtn); + testButtonsPanel.add(BorderLayout.EAST, failBtn); + + JTextArea instrText = new JTextArea(); + instrText.setLineWrap(true); + instrText.setEditable(false); + JScrollPane instrScrollPane = new JScrollPane(instrText); + instrScrollPane.setMaximumSize(new Dimension(Integer.MAX_VALUE, instrHeight)); + instrText.append(instructions); + + JPanel servicePanel = new JPanel(); + servicePanel.setLayout(new BorderLayout()); + servicePanel.add(BorderLayout.CENTER, instrScrollPane); + servicePanel.add(BorderLayout.SOUTH, testButtonsPanel); + + frame.add(BorderLayout.SOUTH, servicePanel); + frame.add(BorderLayout.CENTER, topComponent); + return frame; + } + synchronized void pass() { + pass = true; + notifyAll(); + } + synchronized void waitTestResult() throws InterruptedException { + while (!pass) { + wait(); + } + } + } +} From bdcfc36ee6df88404308ae946b2cadb9dc3ff42c Mon Sep 17 00:00:00 2001 From: Konstantin Shefov Date: Tue, 24 Sep 2013 18:20:31 +0400 Subject: [PATCH 0484/1294] 8015599: [TEST_BUG] [macosx] Test closed/javax/swing/Popup/TaskbarPositionTest.java fails since JDK 8 b75 on MacOSX Reviewed-by: alexsch, serb --- .../swing/Popup/TaskbarPositionTest.java | 340 ++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 jdk/test/javax/swing/Popup/TaskbarPositionTest.java diff --git a/jdk/test/javax/swing/Popup/TaskbarPositionTest.java b/jdk/test/javax/swing/Popup/TaskbarPositionTest.java new file mode 100644 index 00000000000..b4f8989c9db --- /dev/null +++ b/jdk/test/javax/swing/Popup/TaskbarPositionTest.java @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.*; + +/** + * @test @bug 4245587 4474813 4425878 4767478 8015599 + * @author Mark Davidson + * @summary Tests the location of the heavy weight popup portion of JComboBox, + * JMenu and JPopupMenu. + * @library ../regtesthelpers + * @build Util + * @run main TaskbarPositionTest + */ +public class TaskbarPositionTest extends JFrame implements ActionListener { + + private boolean done; + private Throwable error; + private static TaskbarPositionTest test; + private static JPopupMenu popupMenu; + private static JPanel panel; + private static JComboBox combo1; + private static JComboBox combo2; + private static JMenuBar menubar; + private static JMenu menu1; + private static JMenu menu2; + private static Rectangle fullScreenBounds; + // The usable desktop space: screen size - screen insets. + private static Rectangle screenBounds; + private static String[] numData = { + "One", "Two", "Three", "Four", "Five", "Six", "Seven" + }; + private static String[] dayData = { + "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" + }; + private static char[] mnDayData = { + 'M', 'T', 'W', 'R', 'F', 'S', 'U' + }; + + public TaskbarPositionTest() { + super("Use CTRL-down to show a JPopupMenu"); + setContentPane(panel = createContentPane()); + setJMenuBar(createMenuBar("1 - First Menu", true)); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // CTRL-down will show the popup. + panel.getInputMap().put(KeyStroke.getKeyStroke( + KeyEvent.VK_DOWN, InputEvent.CTRL_MASK), "OPEN_POPUP"); + panel.getActionMap().put("OPEN_POPUP", new PopupHandler()); + + pack(); + + Toolkit toolkit = Toolkit.getDefaultToolkit(); + fullScreenBounds = new Rectangle(new Point(), toolkit.getScreenSize()); + screenBounds = new Rectangle(new Point(), toolkit.getScreenSize()); + + // Place the frame near the bottom. This is a pretty wild guess. + this.setLocation(0, (int) screenBounds.getHeight() - 2 * this.getHeight()); + + // Reduce the screen bounds by the insets. + GraphicsConfiguration gc = this.getGraphicsConfiguration(); + if (gc != null) { + Insets screenInsets = toolkit.getScreenInsets(gc); + screenBounds = gc.getBounds(); + screenBounds.width -= (screenInsets.left + screenInsets.right); + screenBounds.height -= (screenInsets.top + screenInsets.bottom); + screenBounds.x += screenInsets.left; + screenBounds.y += screenInsets.top; + } + + setVisible(true); + } + + public static class ComboPopupCheckListener implements PopupMenuListener { + + public void popupMenuCanceled(PopupMenuEvent ev) { + } + + public void popupMenuWillBecomeVisible(PopupMenuEvent ev) { + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent ev) { + Point cpos = combo1.getLocation(); + SwingUtilities.convertPointToScreen(cpos, panel); + + JPopupMenu pm = (JPopupMenu) combo1.getUI().getAccessibleChild(combo1, 0); + + if (pm != null) { + Point p = pm.getLocation(); + SwingUtilities.convertPointToScreen(p, pm); + if (p.y < cpos.y) { + throw new RuntimeException("ComboBox popup is wrongly aligned"); + } // check that popup was opened down + } + } + } + + private class PopupHandler extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + if (!popupMenu.isVisible()) { + popupMenu.show((Component) e.getSource(), 40, 40); + } + isPopupOnScreen(popupMenu, fullScreenBounds); + } + } + + class PopupListener extends MouseAdapter { + + private JPopupMenu popup; + + public PopupListener(JPopupMenu popup) { + this.popup = popup; + } + + public void mousePressed(MouseEvent e) { + maybeShowPopup(e); + } + + public void mouseReleased(MouseEvent e) { + maybeShowPopup(e); + } + + private void maybeShowPopup(MouseEvent e) { + if (e.isPopupTrigger()) { + popup.show(e.getComponent(), e.getX(), e.getY()); + isPopupOnScreen(popup, fullScreenBounds); + } + } + } + + /** + * Tests if the popup is on the screen. + */ + public static void isPopupOnScreen(JPopupMenu popup, Rectangle checkBounds) { + Dimension dim = popup.getSize(); + Point pt = new Point(); + SwingUtilities.convertPointToScreen(pt, popup); + Rectangle bounds = new Rectangle(pt, dim); + + if (!SwingUtilities.isRectangleContainingRectangle(checkBounds, bounds)) { + throw new RuntimeException("We do not match! " + checkBounds + " / " + bounds); + } + + } + + private JPanel createContentPane() { + JPanel panel = new JPanel(); + + combo1 = new JComboBox<>(numData); + panel.add(combo1); + combo2 = new JComboBox<>(dayData); + combo2.setEditable(true); + panel.add(combo2); + panel.setSize(300, 200); + + popupMenu = new JPopupMenu(); + JMenuItem item; + for (int i = 0; i < dayData.length; i++) { + item = popupMenu.add(new JMenuItem(dayData[i], mnDayData[i])); + item.addActionListener(this); + } + panel.addMouseListener(new PopupListener(popupMenu)); + + JTextField field = new JTextField("CTRL+down for Popup"); + // CTRL-down will show the popup. + field.getInputMap().put(KeyStroke.getKeyStroke( + KeyEvent.VK_DOWN, InputEvent.CTRL_MASK), "OPEN_POPUP"); + field.getActionMap().put("OPEN_POPUP", new PopupHandler()); + + panel.add(field); + + return panel; + } + + /** + * @param str name of Menu + * @param bFlag set mnemonics on menu items + */ + private JMenuBar createMenuBar(String str, boolean bFlag) { + menubar = new JMenuBar(); + + menu1 = new JMenu(str); + menu1.setMnemonic(str.charAt(0)); + menu1.addActionListener(this); + + menubar.add(menu1); + for (int i = 0; i < 8; i++) { + JMenuItem menuitem = new JMenuItem("1 JMenuItem" + i); + menuitem.addActionListener(this); + if (bFlag) { + menuitem.setMnemonic('0' + i); + } + menu1.add(menuitem); + } + + // second menu + menu2 = new JMenu("2 - Second Menu"); + menu2.addActionListener(this); + menu2.setMnemonic('2'); + + menubar.add(menu2); + for (int i = 0; i < 5; i++) { + JMenuItem menuitem = new JMenuItem("2 JMenuItem" + i); + menuitem.addActionListener(this); + + if (bFlag) { + menuitem.setMnemonic('0' + i); + } + menu2.add(menuitem); + } + JMenu submenu = new JMenu("Sub Menu"); + submenu.setMnemonic('S'); + submenu.addActionListener(this); + for (int i = 0; i < 5; i++) { + JMenuItem menuitem = new JMenuItem("S JMenuItem" + i); + menuitem.addActionListener(this); + if (bFlag) { + menuitem.setMnemonic('0' + i); + } + submenu.add(menuitem); + } + menu2.add(new JSeparator()); + menu2.add(submenu); + + return menubar; + } + + public void actionPerformed(ActionEvent evt) { + Object obj = evt.getSource(); + if (obj instanceof JMenuItem) { + // put the focus on the noneditable combo. + combo1.requestFocus(); + } + } + + public static void main(String[] args) throws Throwable { + + sun.awt.SunToolkit toolkit = (sun.awt.SunToolkit) Toolkit.getDefaultToolkit(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + test = new TaskbarPositionTest(); + } + }); + + // Use Robot to automate the test + Robot robot; + robot = new Robot(); + robot.setAutoDelay(125); + + // 1 - menu + Util.hitMnemonics(robot, KeyEvent.VK_1); + + toolkit.realSync(); + isPopupOnScreen(menu1.getPopupMenu(), screenBounds); + + // 2 menu with sub menu + robot.keyPress(KeyEvent.VK_RIGHT); + robot.keyRelease(KeyEvent.VK_RIGHT); + Util.hitMnemonics(robot, KeyEvent.VK_S); + + toolkit.realSync(); + isPopupOnScreen(menu2.getPopupMenu(), screenBounds); + + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + + // Focus should go to non editable combo box + toolkit.realSync(); + Thread.sleep(500); + + robot.keyPress(KeyEvent.VK_DOWN); + + // How do we check combo boxes? + + // Editable combo box + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + + // combo1.getUI(); + + // Popup from Text field + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_CONTROL); + + // Popup from a mouse click. + Point pt = new Point(2, 2); + SwingUtilities.convertPointToScreen(pt, panel); + robot.mouseMove((int) pt.getX(), (int) pt.getY()); + robot.mousePress(InputEvent.BUTTON3_MASK); + robot.mouseRelease(InputEvent.BUTTON3_MASK); + + toolkit.realSync(); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + test.setLocation(-30, 100); + combo1.addPopupMenuListener(new ComboPopupCheckListener()); + combo1.requestFocus(); + } + }); + + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + + toolkit.realSync(); + Thread.sleep(500); + } +} From c31deb38acef708cfc2418904b00bfd6a47c4fcf Mon Sep 17 00:00:00 2001 From: Leonid Romanov Date: Tue, 24 Sep 2013 18:24:03 +0400 Subject: [PATCH 0485/1294] 8022555: [macosx] AppleScriptEngine.jar MUST call java.awt.Toolkit.getDefaultToolkit() lazily Reviewed-by: anthony, serb --- .../applescript/AppleScriptEngineFactory.java | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/jdk/src/macosx/classes/apple/applescript/AppleScriptEngineFactory.java b/jdk/src/macosx/classes/apple/applescript/AppleScriptEngineFactory.java index 564dfe063f7..8c50b9d9301 100644 --- a/jdk/src/macosx/classes/apple/applescript/AppleScriptEngineFactory.java +++ b/jdk/src/macosx/classes/apple/applescript/AppleScriptEngineFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,14 +30,9 @@ import java.util.*; import javax.script.*; public class AppleScriptEngineFactory implements ScriptEngineFactory { - private static native void initNative(); + private static volatile boolean initialized = false; - static { - java.awt.Toolkit.getDefaultToolkit(); - System.loadLibrary("AppleScriptEngine"); - initNative(); - TRACE(""); - } + private static native void initNative(); static void TRACE(final String str) { // System.out.println(AppleScriptEngineFactory.class.getName() + "." + str); @@ -80,6 +75,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * * @return full name of the ScriptEngine */ + @Override public String getEngineName() { TRACE("getEngineName()"); return ENGINE_NAME; @@ -90,6 +86,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * * @return version of the ScriptEngine */ + @Override public String getEngineVersion() { TRACE("getEngineVersion()"); return ENGINE_VERSION; @@ -100,6 +97,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * * @return name of the language supported by the ScriptEngine(Factory) */ + @Override public String getLanguageName() { TRACE("getLanguageName()"); return LANGUAGE; @@ -110,11 +108,12 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * * @return language version supported by the ScriptEngine(Factory) */ + @Override public String getLanguageVersion() { TRACE("getLanguageVersion()"); return AccessController.doPrivileged(new PrivilegedAction() { public String run() { - final AppleScriptEngine engine = new AppleScriptEngine(AppleScriptEngineFactory.this); + final AppleScriptEngine engine = getScriptEngine(); return engine.getLanguageVersion(); } }); @@ -126,6 +125,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * * @return ArrayList of file extensions AppleScript associates with */ + @Override public List getExtensions() { TRACE("getExtensions()"); return Arrays.asList("scpt", "applescript", "app"); @@ -137,6 +137,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * * @return ArrayList of mimetypes that AppleScript associates with */ + @Override public List getMimeTypes() { TRACE("getMimeTypes()"); return Arrays.asList("application/x-applescript", "text/plain", "text/applescript"); @@ -148,6 +149,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * * @return */ + @Override public List getNames() { TRACE("getNames()"); return Arrays.asList("AppleScriptEngine", "AppleScript", "OSA"); @@ -165,6 +167,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * arguments to the function * @return the AppleScript string calling the method */ + @Override public String getMethodCallSyntax(final String obj, final String fname, final String ... args) { // StringBuilder builder = new StringBuilder(); // builder.append("my " + fname + "("); @@ -181,6 +184,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * @param toDisplay * @return */ + @Override public String getOutputStatement(final String toDisplay) { // TODO -- this might even be good enough? XD return getMethodCallSyntax(null, "print", toDisplay); @@ -193,8 +197,9 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * the key to look up * @return the static preseeded value for the key in the ScriptEngine, if it exists, otherwise null */ + @Override public Object getParameter(final String key) { - final AppleScriptEngine engine = new AppleScriptEngine(this); + final AppleScriptEngine engine = getScriptEngine(); if (!engine.getBindings(ScriptContext.ENGINE_SCOPE).containsKey(key)) return null; return engine.getBindings(ScriptContext.ENGINE_SCOPE).get(key); } @@ -205,6 +210,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * @param statements * @return */ + @Override public String getProgram(final String ... statements) { final StringBuilder program = new StringBuilder(); for (final String statement : statements) { @@ -218,8 +224,21 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory { * * @return new AppleScriptEngine with this factory as it's parent */ - public ScriptEngine getScriptEngine() { + @Override + public AppleScriptEngine getScriptEngine() { AppleScriptEngine.checkSecurity(); + ensureInitialized(); + return new AppleScriptEngine(this); } + + private static synchronized void ensureInitialized() { + if (!initialized) { + initialized = true; + + java.awt.Toolkit.getDefaultToolkit(); + System.loadLibrary("AppleScriptEngine"); + initNative(); + } + } } From 93c8cbec9c0d600ea74c4ad3adf6e0d5edc85b53 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Tue, 24 Sep 2013 20:43:42 +0530 Subject: [PATCH 0486/1294] 8025312: parseInt should convert 'radix' argument to ToInt32 even if empty string is parsed Reviewed-by: jlaskey, hannesw --- .../internal/runtime/GlobalFunctions.java | 2 +- nashorn/test/script/basic/JDK-8025312.js | 35 +++++++++++++++++++ .../test/script/basic/JDK-8025312.js.EXPECTED | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8025312.js create mode 100644 nashorn/test/script/basic/JDK-8025312.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java index c504276f41c..9ddc7090b2b 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java @@ -90,6 +90,7 @@ public final class GlobalFunctions { public static double parseInt(final Object self, final Object string, final Object rad) { final String str = JSType.trimLeft(JSType.toString(string)); final int length = str.length(); + int radix = JSType.toInt32(rad); // empty string is not valid if (length == 0) { @@ -113,7 +114,6 @@ public final class GlobalFunctions { } boolean stripPrefix = true; - int radix = JSType.toInt32(rad); if (radix != 0) { if (radix < 2 || radix > 36) { diff --git a/nashorn/test/script/basic/JDK-8025312.js b/nashorn/test/script/basic/JDK-8025312.js new file mode 100644 index 00000000000..6f2b42f38af --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025312.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8025312: parseInt should convert 'radix' argument to ToInt32 even if empty string is parsed + * + * @test + * @run + */ + +parseInt("", { + valueOf: function() { + print("inside valueOf of 'radix'"); + } +}); diff --git a/nashorn/test/script/basic/JDK-8025312.js.EXPECTED b/nashorn/test/script/basic/JDK-8025312.js.EXPECTED new file mode 100644 index 00000000000..31ffef83890 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025312.js.EXPECTED @@ -0,0 +1 @@ +inside valueOf of 'radix' From 14ceb05e0ea4914bffb6db708b8dd8e6992137c9 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 24 Sep 2013 10:48:11 -0700 Subject: [PATCH 0487/1294] 8025050: Doclint doesn't recognize tag Reviewed-by: bpatel --- langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java | 3 +++ langtools/test/tools/doclint/html/InlineTagsTest.java | 1 + 2 files changed, 4 insertions(+) diff --git a/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java b/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java index 3b8f8599e09..2ea92af9ac0 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java @@ -86,6 +86,9 @@ public enum HtmlTag { DD(BlockType.LIST_ITEM, EndKind.OPTIONAL, EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)), + DFN(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + DIV(BlockType.BLOCK, EndKind.REQUIRED, EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)), diff --git a/langtools/test/tools/doclint/html/InlineTagsTest.java b/langtools/test/tools/doclint/html/InlineTagsTest.java index 4835b36a9a0..5dda7c27c55 100644 --- a/langtools/test/tools/doclint/html/InlineTagsTest.java +++ b/langtools/test/tools/doclint/html/InlineTagsTest.java @@ -39,6 +39,7 @@ public class InlineTagsTest { *
    * abc * abc + * abc * abc * abc * abc From 026c5d762097591e6e60244ed4fd40cb80a5cd53 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 24 Sep 2013 10:51:28 -0700 Subject: [PATCH 0488/1294] 8025246: [doclint] doclint is showing error on anchor already defined when it's not Reviewed-by: bpatel --- .../com/sun/tools/doclint/Checker.java | 25 +++++++-- .../tools/doclint/anchorTests/p/Test.java | 53 +++++++++++++++++++ .../doclint/anchorTests/p/Test.javac.out | 7 +++ .../test/tools/doclint/anchorTests/p/Test.out | 19 +++++++ .../doclint/anchorTests/p/package-info.java | 15 ++++++ .../anchorTests/p/package-info.javac.out | 2 + .../doclint/anchorTests/p/package-info.out | 4 ++ 7 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 langtools/test/tools/doclint/anchorTests/p/Test.java create mode 100644 langtools/test/tools/doclint/anchorTests/p/Test.javac.out create mode 100644 langtools/test/tools/doclint/anchorTests/p/Test.out create mode 100644 langtools/test/tools/doclint/anchorTests/p/package-info.java create mode 100644 langtools/test/tools/doclint/anchorTests/p/package-info.javac.out create mode 100644 langtools/test/tools/doclint/anchorTests/p/package-info.out diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index d7d8ada40f0..fad2e9f46d4 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -93,7 +93,7 @@ public class Checker extends DocTreePathScanner { Set foundParams = new HashSet<>(); Set foundThrows = new HashSet<>(); - Map> foundAnchors = new HashMap<>(); + Map> foundAnchors = new HashMap<>(); boolean foundInheritDoc = false; boolean foundReturn = false; @@ -576,13 +576,30 @@ public class Checker extends DocTreePathScanner { } private boolean checkAnchor(String name) { - JavaFileObject fo = env.currPath.getCompilationUnit().getSourceFile(); - Set set = foundAnchors.get(fo); + Element e = getEnclosingPackageOrClass(env.currElement); + if (e == null) + return true; + Set set = foundAnchors.get(e); if (set == null) - foundAnchors.put(fo, set = new HashSet<>()); + foundAnchors.put(e, set = new HashSet<>()); return set.add(name); } + private Element getEnclosingPackageOrClass(Element e) { + while (e != null) { + switch (e.getKind()) { + case CLASS: + case ENUM: + case INTERFACE: + case PACKAGE: + return e; + default: + e = e.getEnclosingElement(); + } + } + return e; + } + // http://www.w3.org/TR/html401/types.html#type-name private static final Pattern validName = Pattern.compile("[A-Za-z][A-Za-z0-9-_:.]*"); diff --git a/langtools/test/tools/doclint/anchorTests/p/Test.java b/langtools/test/tools/doclint/anchorTests/p/Test.java new file mode 100644 index 00000000000..131629d7ac6 --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/Test.java @@ -0,0 +1,53 @@ +/* @test /nodynamiccopyright/ + * @bug 8025246 + * @summary doclint is showing error on anchor already defined when it's not + * @library ../.. + * @build DocLintTester + * @run main DocLintTester -ref Test.out Test.java + * @compile/fail/ref=Test.javac.out -XDrawDiagnostics -Werror -Xdoclint:all Test.java + */ + +package p; + +/** + * dupTest + * dupTest again + * + * dupTestField + * dupTestMethod + + * okClass + * okField + * okMethod + */ +public class Test { + /** dupTestField again */ + public int f; + + /** dupTestMethod again */ + public void m() { } + + /** + * dupNested + * dupNested again + * dupNestedField + * dupNestedMethod + * + * okClass again + */ + public class Nested { + /** + * dupNestedField + * + * okField again + */ + public int f; + + /** + * dupNestedMethod + * + * okMethod again + */ + public void m() { } + } +} diff --git a/langtools/test/tools/doclint/anchorTests/p/Test.javac.out b/langtools/test/tools/doclint/anchorTests/p/Test.javac.out new file mode 100644 index 00000000000..44a723969eb --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/Test.javac.out @@ -0,0 +1,7 @@ +Test.java:14:7: compiler.err.proc.messager: anchor already defined: dupTest +Test.java:24:12: compiler.err.proc.messager: anchor already defined: dupTestField +Test.java:27:12: compiler.err.proc.messager: anchor already defined: dupTestMethod +Test.java:32:11: compiler.err.proc.messager: anchor already defined: dupNested +Test.java:40:15: compiler.err.proc.messager: anchor already defined: dupNestedField +Test.java:47:15: compiler.err.proc.messager: anchor already defined: dupNestedMethod +6 errors diff --git a/langtools/test/tools/doclint/anchorTests/p/Test.out b/langtools/test/tools/doclint/anchorTests/p/Test.out new file mode 100644 index 00000000000..6f39fcf1e28 --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/Test.out @@ -0,0 +1,19 @@ +Test.java:14: error: anchor already defined: dupTest + * dupTest again + ^ +Test.java:24: error: anchor already defined: dupTestField + /** dupTestField again */ + ^ +Test.java:27: error: anchor already defined: dupTestMethod + /** dupTestMethod again */ + ^ +Test.java:32: error: anchor already defined: dupNested + * dupNested again + ^ +Test.java:40: error: anchor already defined: dupNestedField + * dupNestedField + ^ +Test.java:47: error: anchor already defined: dupNestedMethod + * dupNestedMethod + ^ +6 errors diff --git a/langtools/test/tools/doclint/anchorTests/p/package-info.java b/langtools/test/tools/doclint/anchorTests/p/package-info.java new file mode 100644 index 00000000000..af7682a3676 --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/package-info.java @@ -0,0 +1,15 @@ +/* @test /nodynamiccopyright/ + * @bug 8025246 + * @summary doclint is showing error on anchor already defined when it's not + * @library ../.. + * @build DocLintTester + * @run main DocLintTester -ref package-info.out package-info.java + * @compile/fail/ref=package-info.javac.out -XDrawDiagnostics -Werror -Xdoclint:all package-info.java + */ + +/** + * here + * here again + */ +package p; + diff --git a/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out b/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out new file mode 100644 index 00000000000..0a859df5894 --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out @@ -0,0 +1,2 @@ +package-info.java:12:7: compiler.err.proc.messager: anchor already defined: here +1 error diff --git a/langtools/test/tools/doclint/anchorTests/p/package-info.out b/langtools/test/tools/doclint/anchorTests/p/package-info.out new file mode 100644 index 00000000000..dda1b19f0dd --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/package-info.out @@ -0,0 +1,4 @@ +package-info.java:12: error: anchor already defined: here + * here again + ^ +1 error From e762b2997d71aae9de597d0c74a8748a0187aed0 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 24 Sep 2013 11:46:25 -0700 Subject: [PATCH 0489/1294] 8025272: doclint needs to check for valid usage of @value tag Reviewed-by: bpatel --- .../com/sun/tools/doclint/Checker.java | 24 +++++++ .../doclint/resources/doclint.properties | 2 + langtools/test/tools/doclint/ValueTest.java | 67 +++++++++++++++++++ langtools/test/tools/doclint/ValueTest.out | 22 ++++++ 4 files changed, 115 insertions(+) create mode 100644 langtools/test/tools/doclint/ValueTest.java create mode 100644 langtools/test/tools/doclint/ValueTest.out diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index fad2e9f46d4..c8d331a43c0 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -44,6 +44,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Name; +import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.tools.Diagnostic.Kind; @@ -822,10 +823,33 @@ public class Checker extends DocTreePathScanner { @Override public Void visitValue(ValueTree tree, Void ignore) { + ReferenceTree ref = tree.getReference(); + if (ref == null || ref.getSignature().isEmpty()) { + if (!isConstant(env.currElement)) + env.messages.error(REFERENCE, tree, "dc.value.not.allowed.here"); + } else { + Element e = env.trees.getElement(new DocTreePath(getCurrentPath(), ref)); + if (!isConstant(e)) + env.messages.error(REFERENCE, tree, "dc.value.not.a.constant"); + } + markEnclosingTag(Flag.HAS_INLINE_TAG); return super.visitValue(tree, ignore); } + private boolean isConstant(Element e) { + if (e == null) + return false; + + switch (e.getKind()) { + case FIELD: + Object value = ((VariableElement) e).getConstantValue(); + return (value != null); // can't distinguish "not a constant" from "constant is null" + default: + return false; + } + } + @Override public Void visitVersion(VersionTree tree, Void ignore) { warnIfEmpty(tree, tree.getBody()); diff --git a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties index 37470976141..24c3aac76e6 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties +++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties @@ -68,6 +68,8 @@ dc.tag.start.unmatched = end tag missing: dc.tag.unknown = unknown tag: {0} dc.text.not.allowed = text not allowed in <{0}> element dc.unexpected.comment=documentation comment not expected here +dc.value.not.allowed.here='{@value}' not allowed here +dc.value.not.a.constant=value does not refer to a constant dc.main.ioerror=IO error: {0} dc.main.no.files.given=No files given diff --git a/langtools/test/tools/doclint/ValueTest.java b/langtools/test/tools/doclint/ValueTest.java new file mode 100644 index 00000000000..f9de36daf15 --- /dev/null +++ b/langtools/test/tools/doclint/ValueTest.java @@ -0,0 +1,67 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8025272 + * @summary doclint needs to check for valid usage of at-value tag + * @build DocLintTester + * @run main DocLintTester -ref ValueTest.out ValueTest.java + */ + +/** */ +public class ValueTest { + /* + * Tests for {@value} without a reference + */ + + /** valid: {@value} */ + public static final boolean cBoolean = false; + + /** valid: {@value} */ + public static final byte cByte = 0; + + /** valid: {@value} */ + public static final short cShort = 0; + + /** valid: {@value} */ + public static final int cInt = 0; + + /** valid: {@value} */ + public static final long cLong = 0L; + + /** valid: {@value} */ + public static final float cFloat = 0.0f; + + /** valid: {@value} */ + public static final double cDouble = 0.0; + + /** valid: {@value} */ + public static final String cString = ""; + + /** invalid class C: {@value} */ + public class C { } + + /** invalid enum E: {@value} */ + public enum E { + /** invalid enum constant E1: {@value} */ + E1 + } + + /** invalid field 1: {@value} */ + public int f1; + + /** invalid field 2: {@value} */ + public int f2 = 3; + + + /* + * Tests for {@value} with a reference + */ + + /** valid: {@value Integer#SIZE} */ + public int intRef; + + /** invalid method: {@value Object#toString} */ + public int badMethod; + + /** invalid enum constant: {@value Thread.State#NEW} */ + public int badEnum; +} diff --git a/langtools/test/tools/doclint/ValueTest.out b/langtools/test/tools/doclint/ValueTest.out new file mode 100644 index 00000000000..3b2977f9f72 --- /dev/null +++ b/langtools/test/tools/doclint/ValueTest.out @@ -0,0 +1,22 @@ +ValueTest.java:39: error: {@value} not allowed here + /** invalid class C: {@value} */ + ^ +ValueTest.java:42: error: {@value} not allowed here + /** invalid enum E: {@value} */ + ^ +ValueTest.java:44: error: {@value} not allowed here + /** invalid enum constant E1: {@value} */ + ^ +ValueTest.java:48: error: {@value} not allowed here + /** invalid field 1: {@value} */ + ^ +ValueTest.java:51: error: {@value} not allowed here + /** invalid field 2: {@value} */ + ^ +ValueTest.java:62: error: value does not refer to a constant + /** invalid method: {@value Object#toString} */ + ^ +ValueTest.java:65: error: value does not refer to a constant + /** invalid enum constant: {@value Thread.State#NEW} */ + ^ +7 errors From 48d1808d53cb8b4a4b841fc70081e4fcb2cb47c5 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 24 Sep 2013 13:48:12 -0700 Subject: [PATCH 0490/1294] 8002154: [doclint] doclint should check for issues which are errors in javadoc Reviewed-by: bpatel --- .../classes/com/sun/tools/doclint/Checker.java | 4 ++++ .../sun/tools/doclint/resources/doclint.properties | 1 + langtools/test/tools/doclint/ReferenceTest.java | 10 +++++++++- langtools/test/tools/doclint/ReferenceTest.out | 14 +++++++++++++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index c8d331a43c0..bc4b86b0a09 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -730,6 +730,10 @@ public class Checker extends DocTreePathScanner { @Override public Void visitReference(ReferenceTree tree, Void ignore) { + String sig = tree.getSignature(); + if (sig.contains("<") || sig.contains(">")) + env.messages.error(REFERENCE, tree, "dc.type.arg.not.allowed"); + Element e = env.trees.getElement(getCurrentPath()); if (e == null) env.messages.error(REFERENCE, tree, "dc.ref.not.found"); diff --git a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties index 24c3aac76e6..b51af2a7358 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties +++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties @@ -67,6 +67,7 @@ dc.tag.self.closing = self-closing element not allowed dc.tag.start.unmatched = end tag missing: dc.tag.unknown = unknown tag: {0} dc.text.not.allowed = text not allowed in <{0}> element +dc.type.arg.not.allowed = type arguments not allowed here dc.unexpected.comment=documentation comment not expected here dc.value.not.allowed.here='{@value}' not allowed here dc.value.not.a.constant=value does not refer to a constant diff --git a/langtools/test/tools/doclint/ReferenceTest.java b/langtools/test/tools/doclint/ReferenceTest.java index 57b26aeff24..1ffd633e866 100644 --- a/langtools/test/tools/doclint/ReferenceTest.java +++ b/langtools/test/tools/doclint/ReferenceTest.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8004832 8020556 + * @bug 8004832 8020556 8002154 * @summary Add new doclint package * @build DocLintTester * @run main DocLintTester -Xmsgs:-reference ReferenceTest.java @@ -54,5 +54,13 @@ public class ReferenceTest { * @throws T description */ public void valid_throws_generic() throws T { } + + /** + * {@link java.util.List} + * {@link java.util.List#equals} + * @see java.util.List + * @see java.util.List#equals + */ + public void invalid_type_args() { } } diff --git a/langtools/test/tools/doclint/ReferenceTest.out b/langtools/test/tools/doclint/ReferenceTest.out index df21e5ef990..ab288a34b00 100644 --- a/langtools/test/tools/doclint/ReferenceTest.out +++ b/langtools/test/tools/doclint/ReferenceTest.out @@ -25,6 +25,18 @@ ReferenceTest.java:43: error: invalid use of @return ReferenceTest.java:48: error: exception not thrown: java.lang.Exception * @throws Exception description ^ -8 errors +ReferenceTest.java:59: error: type arguments not allowed here + * {@link java.util.List} + ^ +ReferenceTest.java:60: error: type arguments not allowed here + * {@link java.util.List#equals} + ^ +ReferenceTest.java:61: error: type arguments not allowed here + * @see java.util.List + ^ +ReferenceTest.java:62: error: type arguments not allowed here + * @see java.util.List#equals + ^ +12 errors 1 warning From c5bb090fff3b984b956bd42ed2663982db626400 Mon Sep 17 00:00:00 2001 From: Michael Fang Date: Tue, 24 Sep 2013 14:17:42 -0700 Subject: [PATCH 0491/1294] 8025215: jdk8 l10n resource file translation update 4 Reviewed-by: naoto, yhuang --- .../apple/laf/resources/aqua_ko.properties | 2 +- .../resources/accessibility_de.properties | 2 +- .../resources/accessibility_es.properties | 2 +- .../resources/accessibility_fr.properties | 2 +- .../resources/accessibility_it.properties | 2 +- .../resources/accessibility_pt_BR.properties | 2 +- .../resources/accessibility_sv.properties | 2 +- .../plaf/motif/resources/motif_de.properties | 2 +- .../plaf/motif/resources/motif_ko.properties | 4 +- .../java/util/jar/pack/DriverResource_ja.java | 131 ++++++++++++++++++ .../util/jar/pack/DriverResource_zh_CN.java | 131 ++++++++++++++++++ .../rowset/RowSetResourceBundle_ko.properties | 6 +- .../plaf/basic/resources/basic_ko.properties | 4 +- .../plaf/metal/resources/metal_sv.properties | 4 +- .../applet/resources/MsgAppletViewer_de.java | 2 +- .../launcher/resources/launcher_de.properties | 4 +- .../launcher/resources/launcher_es.properties | 2 - .../launcher/resources/launcher_fr.properties | 4 +- .../launcher/resources/launcher_it.properties | 2 - .../launcher/resources/launcher_ja.properties | 8 +- .../launcher/resources/launcher_ko.properties | 7 +- .../resources/launcher_pt_BR.properties | 4 +- .../launcher/resources/launcher_sv.properties | 2 - .../resources/launcher_zh_CN.properties | 2 - .../resources/launcher_zh_TW.properties | 2 - .../print/resources/serviceui_de.properties | 18 +-- .../print/resources/serviceui_es.properties | 12 +- .../print/resources/serviceui_fr.properties | 16 +-- .../print/resources/serviceui_it.properties | 6 +- .../resources/serviceui_pt_BR.properties | 22 +-- .../print/resources/serviceui_sv.properties | 12 +- .../resources/rmiregistry_de.properties | 2 +- .../rmi/server/resources/rmid_ko.properties | 2 +- .../tools/jarsigner/Resources_ja.java | 40 +++--- .../tools/jarsigner/Resources_zh_CN.java | 8 +- .../security/tools/keytool/Resources_de.java | 20 +-- .../security/tools/keytool/Resources_es.java | 20 +-- .../security/tools/keytool/Resources_fr.java | 20 +-- .../security/tools/keytool/Resources_it.java | 18 ++- .../security/tools/keytool/Resources_ja.java | 16 ++- .../security/tools/keytool/Resources_ko.java | 18 ++- .../tools/keytool/Resources_pt_BR.java | 26 ++-- .../security/tools/keytool/Resources_sv.java | 22 +-- .../tools/keytool/Resources_zh_CN.java | 44 +++--- .../tools/keytool/Resources_zh_TW.java | 18 ++- .../tools/policytool/Resources_de.java | 5 +- .../tools/policytool/Resources_es.java | 3 + .../tools/policytool/Resources_fr.java | 3 + .../tools/policytool/Resources_it.java | 5 +- .../tools/policytool/Resources_ja.java | 3 + .../tools/policytool/Resources_ko.java | 3 + .../tools/policytool/Resources_pt_BR.java | 3 + .../tools/policytool/Resources_sv.java | 3 + .../tools/policytool/Resources_zh_CN.java | 21 +-- .../tools/policytool/Resources_zh_TW.java | 3 + .../sun/security/util/Resources_fr.java | 8 +- .../sun/tools/jar/resources/jar_de.properties | 5 +- .../sun/tools/jar/resources/jar_es.properties | 5 +- .../sun/tools/jar/resources/jar_fr.properties | 5 +- .../sun/tools/jar/resources/jar_it.properties | 5 +- .../sun/tools/jar/resources/jar_ja.properties | 5 +- .../sun/tools/jar/resources/jar_ko.properties | 7 +- .../tools/jar/resources/jar_pt_BR.properties | 9 +- .../sun/tools/jar/resources/jar_sv.properties | 3 +- .../tools/jar/resources/jar_zh_CN.properties | 3 +- .../tools/jar/resources/jar_zh_TW.properties | 5 +- .../jconsole/resources/messages_ja.properties | 17 ++- .../resources/messages_zh_CN.properties | 17 ++- 68 files changed, 583 insertions(+), 258 deletions(-) create mode 100644 jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java create mode 100644 jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_zh_CN.java diff --git a/jdk/src/macosx/classes/com/apple/laf/resources/aqua_ko.properties b/jdk/src/macosx/classes/com/apple/laf/resources/aqua_ko.properties index 3fbfbe7e76e..82c4ce2f2dc 100644 --- a/jdk/src/macosx/classes/com/apple/laf/resources/aqua_ko.properties +++ b/jdk/src/macosx/classes/com/apple/laf/resources/aqua_ko.properties @@ -46,7 +46,7 @@ FileChooser.saveButton.textAndMnemonic=\uC800\uC7A5 FileChooser.openButton.textAndMnemonic=\uC5F4\uAE30 FileChooser.saveDialogTitle.textAndMnemonic=\uC800\uC7A5 FileChooser.openDialogTitle.textAndMnemonic=\uC5F4\uAE30 -FileChooser.updateButton.textAndMnemonic=\uAC31\uC2E0 +FileChooser.updateButton.textAndMnemonic=\uC5C5\uB370\uC774\uD2B8 FileChooser.helpButton.textAndMnemonic=\uB3C4\uC6C0\uB9D0 FileChooser.directoryOpenButton.textAndMnemonic=\uC5F4\uAE30 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_de.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_de.properties index fe0f918d9bf..45148664672 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_de.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_de.properties @@ -102,7 +102,7 @@ horizontal=horizontal # # accessible actions # -toggleexpand=ein-/ausblenden +toggleexpand=einblenden umschalten # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_es.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_es.properties index c3f90416a30..ce185a10dd1 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_es.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_es.properties @@ -102,7 +102,7 @@ horizontal=horizontal # # accessible actions # -toggleexpand=activar/desactivar ampliaci\u00F3n +toggleexpand=conmutar ampliaci\u00F3n # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_fr.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_fr.properties index c399d9a0b32..88e8ae304b4 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_fr.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_fr.properties @@ -102,7 +102,7 @@ horizontal=horizontal # # accessible actions # -toggleexpand=basculer le d\u00E9veloppement +toggleexpand=activer/d\u00E9sactiver d\u00E9veloppement # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_it.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_it.properties index 94eefb0a2a3..a8af9705d19 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_it.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_it.properties @@ -102,7 +102,7 @@ horizontal=orizzontale # # accessible actions # -toggleexpand=abilita/disabilita espansione +toggleexpand=attiva/disattiva espansione # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_pt_BR.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_pt_BR.properties index f8aaf355040..638b46a7219 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_pt_BR.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_pt_BR.properties @@ -102,7 +102,7 @@ horizontal=horizontal # # accessible actions # -toggleexpand=alternar expans\u00E3o +toggleexpand=alternar expandir # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_sv.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_sv.properties index 962b9d35dc5..3261b2c9be3 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_sv.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_sv.properties @@ -102,7 +102,7 @@ horizontal=horisontell # # accessible actions # -toggleexpand=v\u00E4xla ut\u00F6ka +toggleexpand=v\u00E4xla expandering # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties index 43ba5b6d32b..0c177f8b122 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties @@ -30,7 +30,7 @@ FileChooser.pathLabel.textAndMnemonic=&Pfad- oder Ordnername eingeben: FileChooser.filterLabel.textAndMnemonic=Filte&r FileChooser.foldersLabel.textAndMnemonic=Ord&ner FileChooser.filesLabel.textAndMnemonic=Date&ien -FileChooser.enterFileNameLabel.textAndMnemonic=Dateiname ei&ngeben: +FileChooser.enterFileNameLabel.textAndMnemonic=Dateina&me eingeben: FileChooser.enterFolderNameLabel.textAndMnemonic=Ordnernamen eingeben: FileChooser.cancelButtonToolTip.textAndMnemonic=Dialogfeld f\u00FCr Dateiauswahl schlie\u00DFen. diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties index f7e2625e9c9..7090ef5a7c4 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties @@ -24,7 +24,7 @@ FileChooser.saveButton.textAndMnemonic=\uC800\uC7A5 FileChooser.openButton.textAndMnemonic=\uD655\uC778 FileChooser.saveDialogTitle.textAndMnemonic=\uC800\uC7A5 FileChooser.openDialogTitle.textAndMnemonic=\uC5F4\uAE30 -FileChooser.updateButton.textAndMnemonic=\uAC31\uC2E0 +FileChooser.updateButton.textAndMnemonic=\uC5C5\uB370\uC774\uD2B8 FileChooser.helpButton.textAndMnemonic=\uB3C4\uC6C0\uB9D0 FileChooser.pathLabel.textAndMnemonic=\uACBD\uB85C \uB610\uB294 \uD3F4\uB354 \uC774\uB984 \uC785\uB825(&P): FileChooser.filterLabel.textAndMnemonic=\uD544\uD130(&R) @@ -36,5 +36,5 @@ FileChooser.enterFolderNameLabel.textAndMnemonic=\uD3F4\uB354 \uC774\uB984 \uC78 FileChooser.cancelButtonToolTip.textAndMnemonic=\uD30C\uC77C \uC120\uD0DD\uAE30 \uB300\uD654\uC0C1\uC790\uB97C \uC911\uB2E8\uD569\uB2C8\uB2E4. FileChooser.saveButtonToolTip.textAndMnemonic=\uC120\uD0DD\uB41C \uD30C\uC77C\uC744 \uC800\uC7A5\uD569\uB2C8\uB2E4. FileChooser.openButtonToolTip.textAndMnemonic=\uC120\uD0DD\uB41C \uD30C\uC77C\uC744 \uC5FD\uB2C8\uB2E4. -FileChooser.updateButtonToolTip.textAndMnemonic=\uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D\uC744 \uAC31\uC2E0\uD569\uB2C8\uB2E4. +FileChooser.updateButtonToolTip.textAndMnemonic=\uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D\uC744 \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4. FileChooser.helpButtonToolTip.textAndMnemonic=FileChooser \uB3C4\uC6C0\uB9D0\uC785\uB2C8\uB2E4. diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java new file mode 100644 index 00000000000..de35d5ac0eb --- /dev/null +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.util.jar.pack; + +import java.util.ListResourceBundle; + +public class DriverResource_ja extends ListResourceBundle { + public static final String VERSION ="VERSION"; + public static final String BAD_ARGUMENT ="BAD_ARGUMENT"; + public static final String BAD_OPTION ="BAD_OPTION"; + public static final String BAD_REPACK_OUTPUT="BAD_REPACK_OUTPUT"; + public static final String DETECTED_ZIP_COMMENT="DETECTED_ZIP_COMMENT"; + public static final String SKIP_FOR_REPACKED ="SKIP_FOR_REPACKED"; + public static final String WRITE_PACK_FILE ="WRITE_PACK_FILE"; + public static final String WIRTE_PACKGZ_FILE="WIRTE_PACKGZ_FILE"; + public static final String SKIP_FOR_MOVE_FAILED="SKIP_FOR_MOVE_FAILED"; + public static final String PACK_HELP="PACK_HELP"; + public static final String UNPACK_HELP ="UNPACK_HELP"; + public static final String MORE_INFO = "MORE_INFO"; + public static final String DUPLICATE_OPTION = "DUPLICATE_OPTION"; + public static final String BAD_SPEC = "BAD_SPEC"; + + //The following string is duplicate in PACK and UNPACK comment,which was draw out to ruduce translation work. + private static final String PARAMETER_V = " -v, --verbose increase program verbosity"; + private static final String PARAMETER_Q = " -q, --quiet set verbosity to lowest level"; + private static final String PARAMETER_LF = " -l{F}, --log-file={F} output to the given log file, or '-' for System.out"; + private static final String PARAMETER_H = " -?, -h, --help print this message"; + private static final String PARAMETER_VER = " -V, --version print program version"; + private static final String PARAMETER_J = " -J{X} pass option X to underlying Java VM"; + + + //The following are outputs of command 'pack200' and 'unpack200'. + //Don't translate command arguments ,words with a prefix of '-' or '--'. + // + private static final Object[][] resource= { + {VERSION,"{0}\u30D0\u30FC\u30B8\u30E7\u30F3{1}"},//parameter 0:class name;parameter 1: version value + {BAD_ARGUMENT,"\u7121\u52B9\u306A\u5F15\u6570: {0}"}, + {BAD_OPTION,"\u7121\u52B9\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}={1}"},//parameter 0:option name;parameter 1:option value + {BAD_REPACK_OUTPUT,"\u7121\u52B9\u306A--repack\u51FA\u529B: {0}"},//parameter 0:filename + {DETECTED_ZIP_COMMENT,"\u691C\u51FA\u3055\u308C\u305FZIP\u30B3\u30E1\u30F3\u30C8: {0}"},//parameter 0:comment + {SKIP_FOR_REPACKED,"\u3059\u3067\u306B\u518D\u5727\u7E2E\u3055\u308C\u3066\u3044\u308B\u305F\u3081\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u3044\u307E\u3059: {0}"},//parameter 0:filename + {WRITE_PACK_FILE,"*.pack\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080\u306B\u306F\u3001--no-gzip\u3092\u6307\u5B9A\u3057\u307E\u3059: {0}"},//parameter 0:filename + {WIRTE_PACKGZ_FILE,"*.pack.gz\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080\u306B\u306F\u3001--gzip\u3092\u6307\u5B9A\u3057\u307E\u3059: {0}"},//parameter 0:filename + {SKIP_FOR_MOVE_FAILED,"\u79FB\u52D5\u304C\u5931\u6557\u3057\u305F\u305F\u3081\u89E3\u51CD\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u3044\u307E\u3059: {0}"},//parameter 0:filename + {PACK_HELP,new String[]{ + "\u4F7F\u7528\u65B9\u6CD5: pack200 [-opt... | --option=value]... x.pack[.gz] y.jar", + "", + "\u5727\u7E2E\u30AA\u30D7\u30B7\u30E7\u30F3", + " -g\u3001--no-gzip \u30D7\u30EC\u30FC\u30F3\u306A*.pack\u30D5\u30A1\u30A4\u30EB\u3092\u5727\u7E2E\u305B\u305A\u306B\u51FA\u529B\u3057\u307E\u3059", + " --gzip (\u30C7\u30D5\u30A9\u30EB\u30C8)\u5727\u7E2E\u51FA\u529B\u3092gzip\u3067\u5F8C\u51E6\u7406\u3057\u307E\u3059", + " -G\u3001--strip-debug \u5727\u7E2E\u4E2D\u306B\u30C7\u30D0\u30C3\u30B0\u5C5E\u6027\u3092\u524A\u9664\u3057\u307E\u3059", + " -O\u3001--no-keep-file-order \u30D5\u30A1\u30A4\u30EB\u306E\u9806\u5E8F\u4ED8\u3051\u60C5\u5831\u3092\u8EE2\u9001\u3057\u307E\u305B\u3093", + " --keep-file-order (\u30C7\u30D5\u30A9\u30EB\u30C8)\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u9806\u5E8F\u4ED8\u3051\u3092\u4FDD\u6301\u3057\u307E\u3059", + " -S{N}\u3001--segment-limit={N} \u30BB\u30B0\u30E1\u30F3\u30C8\u5236\u9650\u3092\u51FA\u529B\u3057\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8N=1Mb)", + " -E{N}\u3001--effort={N} \u5727\u7E2E\u306E\u8A66\u884C(\u30C7\u30D5\u30A9\u30EB\u30C8N=5)", + " -H{h}\u3001--deflate-hint={h} \u30C7\u30D5\u30EC\u30FC\u30C8\u30FB\u30D2\u30F3\u30C8\u3092\u8EE2\u9001\u3057\u307E\u3059: true\u3001false\u307E\u305F\u306Fkeep(\u30C7\u30D5\u30A9\u30EB\u30C8)", + " -m{V}\u3001--modification-time={V} \u5909\u66F4\u6642\u9593\u3092\u8EE2\u9001\u3057\u307E\u3059: latest\u307E\u305F\u306Fkeep(\u30C7\u30D5\u30A9\u30EB\u30C8)", + " -P{F}\u3001--pass-file={F} \u6307\u5B9A\u3055\u308C\u305F\u5727\u7E2E\u3055\u308C\u3066\u3044\u306A\u3044\u5165\u529B\u8981\u7D20\u3092\u8EE2\u9001\u3057\u307E\u3059", + " -U{a}\u3001--unknown-attribute={a} \u4E0D\u660E\u306E\u5C5E\u6027\u30A2\u30AF\u30B7\u30E7\u30F3: error\u3001strip\u307E\u305F\u306Fpass(\u30C7\u30D5\u30A9\u30EB\u30C8)", + " -C{N}={L}\u3001--class-attribute={N}={L} (\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u5C5E\u6027)", + " -F{N}={L}\u3001--field-attribute={N}={L} (\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u5C5E\u6027)", + " -M{N}={L}\u3001--method-attribute={N}={L} (\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u5C5E\u6027)", + " -D{N}={L}\u3001--code-attribute={N}={L} (\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u5C5E\u6027)", + " -f{F}\u3001--config-file={F} Pack200.Packer\u30D7\u30ED\u30D1\u30C6\u30A3\u306B\u30D5\u30A1\u30A4\u30EBF\u3092\u8AAD\u307F\u8FBC\u307F\u307E\u3059", + PARAMETER_V , + PARAMETER_Q , + PARAMETER_LF , + PARAMETER_H , + PARAMETER_VER , + PARAMETER_J, + "", + "\u6CE8\u610F:", + " -P\u3001-C\u3001-F\u3001-M\u304A\u3088\u3073-D\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u7D2F\u7A4D\u3055\u308C\u307E\u3059\u3002", + " \u5C5E\u6027\u5B9A\u7FA9\u306E\u4F8B: -C SourceFile=RUH .", + " Config.\u30D5\u30A1\u30A4\u30EB\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u306F\u3001Pack200 API\u306B\u3088\u3063\u3066\u5B9A\u7FA9\u3055\u308C\u307E\u3059\u3002", + " -S\u3001-E\u3001-H\u3001-m\u3001-U\u306E\u5024\u306E\u610F\u5473\u306F\u3001Pack200 API\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002", + " \u30EC\u30A4\u30A2\u30A6\u30C8\u5B9A\u7FA9(RUH\u306A\u3069)\u306FJSR 200\u306B\u3088\u3063\u3066\u5B9A\u7FA9\u3055\u308C\u307E\u3059\u3002", + "", + "\u518D\u5727\u7E2E\u30E2\u30FC\u30C9\u3067\u306F\u3001JAR\u30D5\u30A1\u30A4\u30EB\u304C\u5727\u7E2E/\u89E3\u51CD\u30B5\u30A4\u30AF\u30EB\u3067\u66F4\u65B0\u3055\u308C\u307E\u3059:", + " pack200 [-r|--repack] [-opt | --option=value]... [repackedy.jar] y.jar\n" + } + }, + {UNPACK_HELP,new String[]{ + "\u4F7F\u7528\u65B9\u6CD5: unpack200 [-opt... | --option=value]... x.pack[.gz] y.jar\n", + "", + "\u89E3\u51CD\u30AA\u30D7\u30B7\u30E7\u30F3", + " -H{h}\u3001--deflate-hint={h} \u8EE2\u9001\u3055\u308C\u305F\u30C7\u30D5\u30EC\u30FC\u30C8\u30FB\u30D2\u30F3\u30C8\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u307E\u3059: true\u3001false\u307E\u305F\u306Fkeep(\u30C7\u30D5\u30A9\u30EB\u30C8)", + " -r\u3001--remove-pack-file \u89E3\u51CD\u5F8C\u306B\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u524A\u9664\u3057\u307E\u3059", + PARAMETER_V , + PARAMETER_Q , + PARAMETER_LF , + PARAMETER_H , + PARAMETER_VER , + PARAMETER_J, + } + }, + + {MORE_INFO,"(\u8A73\u7D30\u306F\u3001{0} --help\u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002)"},//parameter 0:command name + {DUPLICATE_OPTION,"\u91CD\u8907\u30AA\u30D7\u30B7\u30E7\u30F3: {0}"},//parameter 0:option + {BAD_SPEC,"{0}\u306E\u7121\u52B9\u306A\u4ED5\u69D8: {1}"},//parameter 0:option;parameter 1:specifier + }; + + protected Object[][] getContents() { + return resource; + } + + +} diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_zh_CN.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_zh_CN.java new file mode 100644 index 00000000000..25cc710e61f --- /dev/null +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_zh_CN.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.util.jar.pack; + +import java.util.ListResourceBundle; + +public class DriverResource_zh_CN extends ListResourceBundle { + public static final String VERSION ="VERSION"; + public static final String BAD_ARGUMENT ="BAD_ARGUMENT"; + public static final String BAD_OPTION ="BAD_OPTION"; + public static final String BAD_REPACK_OUTPUT="BAD_REPACK_OUTPUT"; + public static final String DETECTED_ZIP_COMMENT="DETECTED_ZIP_COMMENT"; + public static final String SKIP_FOR_REPACKED ="SKIP_FOR_REPACKED"; + public static final String WRITE_PACK_FILE ="WRITE_PACK_FILE"; + public static final String WIRTE_PACKGZ_FILE="WIRTE_PACKGZ_FILE"; + public static final String SKIP_FOR_MOVE_FAILED="SKIP_FOR_MOVE_FAILED"; + public static final String PACK_HELP="PACK_HELP"; + public static final String UNPACK_HELP ="UNPACK_HELP"; + public static final String MORE_INFO = "MORE_INFO"; + public static final String DUPLICATE_OPTION = "DUPLICATE_OPTION"; + public static final String BAD_SPEC = "BAD_SPEC"; + + //The following string is duplicate in PACK and UNPACK comment,which was draw out to ruduce translation work. + private static final String PARAMETER_V = " -v, --verbose increase program verbosity"; + private static final String PARAMETER_Q = " -q, --quiet set verbosity to lowest level"; + private static final String PARAMETER_LF = " -l{F}, --log-file={F} output to the given log file, or '-' for System.out"; + private static final String PARAMETER_H = " -?, -h, --help print this message"; + private static final String PARAMETER_VER = " -V, --version print program version"; + private static final String PARAMETER_J = " -J{X} pass option X to underlying Java VM"; + + + //The following are outputs of command 'pack200' and 'unpack200'. + //Don't translate command arguments ,words with a prefix of '-' or '--'. + // + private static final Object[][] resource= { + {VERSION,"{0}\u7248\u672C{1}"},//parameter 0:class name;parameter 1: version value + {BAD_ARGUMENT,"\u9519\u8BEF\u53C2\u6570: {0}"}, + {BAD_OPTION,"\u9519\u8BEF\u9009\u9879: {0}={1}"},//parameter 0:option name;parameter 1:option value + {BAD_REPACK_OUTPUT,"--repack \u8F93\u51FA\u9519\u8BEF: {0}"},//parameter 0:filename + {DETECTED_ZIP_COMMENT,"\u68C0\u6D4B\u5230 ZIP \u6CE8\u91CA: {0}"},//parameter 0:comment + {SKIP_FOR_REPACKED,"\u7531\u4E8E\u5DF2\u91CD\u65B0\u6253\u5305\u800C\u8DF3\u8FC7: {0}"},//parameter 0:filename + {WRITE_PACK_FILE,"\u8981\u5199\u5165 *.pack \u6587\u4EF6, \u8BF7\u6307\u5B9A --no-gzip: {0}"},//parameter 0:filename + {WIRTE_PACKGZ_FILE,"\u8981\u5199\u5165 *.pack.gz \u6587\u4EF6, \u8BF7\u6307\u5B9A --gzip: {0}"},//parameter 0:filename + {SKIP_FOR_MOVE_FAILED,"\u7531\u4E8E\u79FB\u52A8\u5931\u8D25\u800C\u8DF3\u8FC7\u91CD\u65B0\u6253\u5305: {0}"},//parameter 0:filename + {PACK_HELP,new String[]{ + "\u7528\u6CD5: pack200 [-opt... | --option=value]... x.pack[.gz] y.jar", + "", + "\u6253\u5305\u9009\u9879", + " -g, --no-gzip \u8F93\u51FA\u65E0\u683C\u5F0F\u7684 *.pack \u6587\u4EF6, \u4E0D\u538B\u7F29", + " --gzip (\u9ED8\u8BA4\u503C) \u4F7F\u7528 gzip \u5BF9\u6253\u5305\u8FDB\u884C\u540E\u5904\u7406", + " -G, --strip-debug \u6253\u5305\u65F6\u5220\u9664\u8C03\u8BD5\u5C5E\u6027", + " -O, --no-keep-file-order \u4E0D\u4F20\u8F93\u6587\u4EF6\u6392\u5E8F\u4FE1\u606F", + " --keep-file-order (\u9ED8\u8BA4\u503C) \u4FDD\u7559\u8F93\u5165\u6587\u4EF6\u6392\u5E8F", + " -S{N}, --segment-limit={N} \u8F93\u51FA\u6BB5\u9650\u5236 (\u9ED8\u8BA4\u503C N=1Mb)", + " -E{N}, --effort={N} \u6253\u5305\u6548\u679C (\u9ED8\u8BA4\u503C N=5)", + " -H{h}, --deflate-hint={h} \u4F20\u8F93\u538B\u7F29\u63D0\u793A: true, false \u6216 keep (\u9ED8\u8BA4\u503C)", + " -m{V}, --modification-time={V} \u4F20\u8F93 modtimes: latest \u6216 keep (\u9ED8\u8BA4\u503C)", + " -P{F}, --pass-file={F} \u4F20\u8F93\u672A\u89E3\u538B\u7F29\u7684\u7ED9\u5B9A\u8F93\u5165\u5143\u7D20", + " -U{a}, --unknown-attribute={a} \u672A\u77E5\u5C5E\u6027\u64CD\u4F5C: error, strip \u6216 pass (\u9ED8\u8BA4\u503C)", + " -C{N}={L}, --class-attribute={N}={L} (\u7528\u6237\u5B9A\u4E49\u7684\u5C5E\u6027)", + " -F{N}={L}, --field-attribute={N}={L} (\u7528\u6237\u5B9A\u4E49\u7684\u5C5E\u6027)", + " -M{N}={L}, --method-attribute={N}={L} (\u7528\u6237\u5B9A\u4E49\u7684\u5C5E\u6027)", + " -D{N}={L}, --code-attribute={N}={L} (\u7528\u6237\u5B9A\u4E49\u7684\u5C5E\u6027)", + " -f{F}, --config-file={F} \u8BFB\u53D6\u6587\u4EF6 F \u7684 Pack200.Packer \u5C5E\u6027", + PARAMETER_V , + PARAMETER_Q , + PARAMETER_LF , + PARAMETER_H , + PARAMETER_VER , + PARAMETER_J, + "", + "\u6CE8:", + " -P, -C, -F, -M \u548C -D \u9009\u9879\u7D2F\u8BA1\u3002", + " \u793A\u4F8B\u5C5E\u6027\u5B9A\u4E49: -C SourceFile=RUH\u3002", + " Config. \u6587\u4EF6\u5C5E\u6027\u7531 Pack200 API \u5B9A\u4E49\u3002", + " \u6709\u5173 -S, -E, -H-, -m, -U \u503C\u7684\u542B\u4E49, \u8BF7\u53C2\u9605 Pack200 API\u3002", + " \u5E03\u5C40\u5B9A\u4E49 (\u4F8B\u5982 RUH) \u7531 JSR 200 \u5B9A\u4E49\u3002", + "", + "\u91CD\u65B0\u6253\u5305\u6A21\u5F0F\u901A\u8FC7\u6253\u5305/\u89E3\u5305\u5468\u671F\u66F4\u65B0 JAR \u6587\u4EF6:", + " pack200 [-r|--repack] [-opt | --option=value]... [repackedy.jar] y.jar\n" + } + }, + {UNPACK_HELP,new String[]{ + "\u7528\u6CD5: unpack200 [-opt... | --option=value]... x.pack[.gz] y.jar\n", + "", + "\u89E3\u5305\u9009\u9879", + " -H{h}, --deflate-hint={h} \u8986\u76D6\u5DF2\u4F20\u8F93\u7684\u538B\u7F29\u63D0\u793A: true, false \u6216 keep (\u9ED8\u8BA4\u503C)", + " -r, --remove-pack-file \u89E3\u5305\u4E4B\u540E\u5220\u9664\u8F93\u5165\u6587\u4EF6", + PARAMETER_V , + PARAMETER_Q , + PARAMETER_LF , + PARAMETER_H , + PARAMETER_VER , + PARAMETER_J, + } + }, + + {MORE_INFO,"(\u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u8FD0\u884C {0} --help\u3002)"},//parameter 0:command name + {DUPLICATE_OPTION,"\u91CD\u590D\u7684\u9009\u9879: {0}"},//parameter 0:option + {BAD_SPEC,"{0}\u7684\u89C4\u8303\u9519\u8BEF: {1}"},//parameter 0:option;parameter 1:specifier + }; + + protected Object[][] getContents() { + return resource; + } + + +} diff --git a/jdk/src/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties b/jdk/src/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties index 3dd9ee0d1b9..89bbf67ec53 100644 --- a/jdk/src/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties +++ b/jdk/src/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties @@ -44,7 +44,7 @@ cachedrowsetimpl.doublefail = {1} \uC5F4\uC758 \uAC12({0})\uC5D0\uC11C getDouble cachedrowsetimpl.dtypemismt = \uB370\uC774\uD130 \uC720\uD615\uC774 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. cachedrowsetimpl.datefail = {1} \uC5F4\uC758 \uAC12({0})\uC5D0\uC11C getDate\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uBCC0\uD658\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. cachedrowsetimpl.timefail = {1} \uC5F4\uC758 \uAC12({0})\uC5D0\uC11C getTime\uC744 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uBCC0\uD658\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. -cachedrowsetimpl.posupdate = \uC704\uCE58\uAC00 \uC9C0\uC815\uB41C \uAC31\uC2E0\uC774 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. +cachedrowsetimpl.posupdate = \uC704\uCE58\uAC00 \uC9C0\uC815\uB41C \uC5C5\uB370\uC774\uD2B8\uAC00 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. cachedrowsetimpl.unableins = \uC778\uC2A4\uD134\uC2A4\uD654\uD560 \uC218 \uC5C6\uC74C: {0} cachedrowsetimpl.beforefirst = beforeFirst: \uCEE4\uC11C \uC791\uC5C5\uC774 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. cachedrowsetimpl.first = \uCC98\uC74C: \uCEE4\uC11C \uC791\uC5C5\uC774 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. @@ -110,7 +110,7 @@ jdbcrowsetimpl.matchcols2 = \uC77C\uCE58 \uC5F4\uC740 \uB110 \uB610\uB294 \uBE48 jdbcrowsetimpl.unsetmatch = \uC124\uC815\uC744 \uD574\uC81C\uD558\uB824\uB294 \uC5F4\uC774 \uC124\uC815\uB41C \uC5F4\uACFC \uB2E4\uB985\uB2C8\uB2E4. jdbcrowsetimpl.usecolname = \uC5F4 \uC774\uB984\uC744 unsetMatchColumn\uC758 \uC778\uC218\uB85C \uC0AC\uC6A9\uD558\uC2ED\uC2DC\uC624. jdbcrowsetimpl.usecolid = \uC5F4 ID\uB97C unsetMatchColumn\uC758 \uC778\uC218\uB85C \uC0AC\uC6A9\uD558\uC2ED\uC2DC\uC624. -jdbcrowsetimpl.resnotupd = ResultSet\uB97C \uAC31\uC2E0\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. +jdbcrowsetimpl.resnotupd = ResultSet\uB97C \uC5C5\uB370\uC774\uD2B8\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. jdbcrowsetimpl.opnotysupp = \uC791\uC5C5\uC774 \uC544\uC9C1 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. jdbcrowsetimpl.featnotsupp = \uAE30\uB2A5\uC774 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. @@ -157,7 +157,7 @@ xmlrch.errdel = \uD589\uC744 \uC0AD\uC81C\uD558\uB294 \uC911 \uC624\uB958 \uBC1C xmlrch.errinsert = insert \uD589\uC744 \uC0DD\uC131\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD: {0} xmlrch.errinsdel = insdel \uD589\uC744 \uC0DD\uC131\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD: {0} xmlrch.errupdate = update \uD589\uC744 \uC0DD\uC131\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD: {0} -xmlrch.errupdrow = \uD589\uC744 \uAC31\uC2E0\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD: {0} +xmlrch.errupdrow = \uD589\uC744 \uC5C5\uB370\uC774\uD2B8\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD: {0} xmlrch.chars = \uBB38\uC790: xmlrch.badvalue = \uC798\uBABB\uB41C \uAC12: \uB110\uC77C \uC218 \uC5C6\uB294 \uC18D\uC131\uC785\uB2C8\uB2E4. xmlrch.badvalue1 = \uC798\uBABB\uB41C \uAC12: \uB110\uC77C \uC218 \uC5C6\uB294 \uBA54\uD0C0 \uB370\uC774\uD130\uC785\uB2C8\uB2E4. diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties index 86f010204dc..a8504f7872c 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties @@ -46,7 +46,7 @@ FileChooser.saveButton.textAndMnemonic=\uC800\uC7A5(&S) FileChooser.openButton.textAndMnemonic=\uC5F4\uAE30(&O) FileChooser.saveDialogTitle.textAndMnemonic=\uC800\uC7A5 FileChooser.openDialogTitle.textAndMnemonic=\uC5F4\uAE30 -FileChooser.updateButton.textAndMnemonic=\uAC31\uC2E0(&U) +FileChooser.updateButton.textAndMnemonic=\uC5C5\uB370\uC774\uD2B8(&U) FileChooser.helpButton.textAndMnemonic=\uB3C4\uC6C0\uB9D0(&H) FileChooser.directoryOpenButton.textAndMnemonic=\uC5F4\uAE30(&O) @@ -66,7 +66,7 @@ FileChooser.other.newFolder.subsequent=NewFolder.{0} FileChooser.cancelButtonToolTip.textAndMnemonic=\uD30C\uC77C \uC120\uD0DD\uAE30 \uB300\uD654\uC0C1\uC790 \uC911\uB2E8 FileChooser.saveButtonToolTip.textAndMnemonic=\uC120\uD0DD\uB41C \uD30C\uC77C \uC800\uC7A5 FileChooser.openButtonToolTip.textAndMnemonic=\uC120\uD0DD\uB41C \uD30C\uC77C \uC5F4\uAE30 -FileChooser.updateButtonToolTip.textAndMnemonic=\uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D \uAC31\uC2E0 +FileChooser.updateButtonToolTip.textAndMnemonic=\uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D \uC5C5\uB370\uC774\uD2B8 FileChooser.helpButtonToolTip.textAndMnemonic=FileChooser \uB3C4\uC6C0\uB9D0 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=\uC120\uD0DD\uB41C \uB514\uB809\uD1A0\uB9AC \uC5F4\uAE30 diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties index 3d799b58a80..1b9b7e217c7 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties @@ -20,8 +20,8 @@ FileChooser.lookInLabel.textAndMnemonic=Leta &i: FileChooser.saveInLabel.textAndMnemonic=Spara i: -FileChooser.fileNameLabel.textAndMnemonic=Fil&namn: -FileChooser.folderNameLabel.textAndMnemonic=Mapp&namn: +FileChooser.fileNameLabel.textAndMnemonic=&Fil: +FileChooser.folderNameLabel.textAndMnemonic=&Mapp: FileChooser.filesOfTypeLabel.textAndMnemonic=Mapp&namn: FileChooser.upFolderToolTip.textAndMnemonic=Upp en niv\u00E5 FileChooser.upFolderAccessibleName=Upp diff --git a/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer_de.java b/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer_de.java index 7163bb5b1a1..b99d3bbd75d 100644 --- a/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer_de.java +++ b/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer_de.java @@ -73,7 +73,7 @@ public class MsgAppletViewer_de extends ListResourceBundle { {"appletviewer.parse.warning.embed.requiresheight", "Warnung: F\u00FCr -Tag ist ein \"height\"-Attribut erforderlich."}, {"appletviewer.parse.warning.embed.requireswidth", "Warnung: F\u00FCr -Tag ist ein \"width\"-Attribut erforderlich."}, {"appletviewer.parse.warning.appnotLongersupported", "Warnung: -Tag wird nicht mehr unterst\u00FCtzt. Verwenden Sie stattdessen :"}, - {"appletviewer.usage", "Verwendung: appletviewer url(s)\n\nwobei die Folgendes umfassen:\n -debug Applet Viewer im Java-Debugger starten\n -encoding Zeichencodierung f\u00FCr HTML-Dateien angeben\n -J Argument an den Java-Interpreter \u00FCbergeben\n\nDie Option \"-J\" ist nicht standardm\u00E4\u00DFig und kann ohne vorherige Ank\u00FCndigung ge\u00E4ndert werden."}, + {"appletviewer.usage", "Verwendung: appletviewer url(s)\n\nwobei die Folgendes umfassen:\n -debug Applet Viewer im Java-Debugger starten\n -encoding Zeichencodierung f\u00FCr HTML-Dateien angeben\n -J Argument an den Java-Interpreter \u00FCbergeben\n\nDie Option \"-J\" ist nicht standardm\u00E4\u00DFig und kann ohne vorherige Ank\u00FCndigung ge\u00E4ndert werden."}, {"appletviewer.main.err.unsupportedopt", "Nicht unterst\u00FCtzte Option: {0}"}, {"appletviewer.main.err.unrecognizedarg", "Unbekanntes Argument: {0}"}, {"appletviewer.main.err.dupoption", "Doppelte Verwendung von Option: {0}"}, diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties index 4d5ef284277..9720e4626bc 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ Die Standard-VM ist {0} java.launcher.ergo.message2 =\ weil die Ausf\u00FChrung auf einem Server-Class-Rechner erfolgt.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n -classpath \n Eine durch {0} getrennte Liste mit Verzeichnissen, JAR-Archiven\n und ZIP-Archiven zur Suche nach Klassendateien.\n -D=\n Legt eine Systemeigenschaft fest\n -verbose[:class|gc|jni]\n Aktiviert die Verbose-Ausgabe\n -version Druckt Produktversion und beendet das Programm\n -version:\n Erfordert die angegebene Version zur Ausf\u00FChrung\n -showversion Druckt Produktversion und f\u00E4hrt fort\n -jre-restrict-search | -no-jre-restrict-search\n Bezieht private JREs des Benutzers in Versionssuche ein bzw. schlie\u00DFt sie aus\n -? -help Druckt diese Hilfemeldung\n -X Druckt Hilfe zu Nicht-Standardoptionen\n -ea[:...|:]\n -enableassertions[:...|:]\n Aktiviert Assertionen mit angegebener Granularit\u00E4t\n -da[:...|:]\n -disableassertions[:...|:]\n Deaktiviert Assertionen mit angegebener Granularit\u00E4t\n -esa | -enablesystemassertions\n Aktiviert Systemassertionen\n -dsa | -disablesystemassertions\n Deaktiviert Systemassertionen\n -agentlib:[=]\n L\u00E4dt native Agent Library , z.B. -agentlib:hprof\n siehe auch -agentlib:jdwp=help und -agentlib:hprof=help\n -agentpath:[=]\n L\u00E4dt native Agent Library nach vollem Pfadnamen\n -javaagent:[=]\n L\u00E4dt Java-Programmiersprachen-Agent, siehe java.lang.instrument\n -splash:\n Zeigt Startbildschirm mit angegebenem Bild\nWeitere Einzelheiten finden Sie unter http://www.oracle.com/technetwork/java/javase/documentation/index.html +java.launcher.opt.footer =\ -cp \n -classpath \n Eine durch {0} getrennte Liste mit Verzeichnissen, JAR-Archiven\n und ZIP-Archiven zur Suche nach Klassendateien.\n -D=\n Legt eine Systemeigenschaft fest\n -verbose:[class|gc|jni]\n Aktiviert die Verbose-Ausgabe\n -version Druckt Produktversion und beendet das Programm\n -version:\n Erfordert die angegebene Version zur Ausf\u00FChrung\n -showversion Druckt Produktversion und f\u00E4hrt fort\n -jre-restrict-search | -no-jre-restrict-search\n Bezieht private JREs des Benutzers in Versionssuche ein bzw. schlie\u00DFt sie aus\n -? -help Druckt diese Hilfemeldung\n -X Druckt Hilfe zu Nicht-Standardoptionen\n -ea[:...|:]\n -enableassertions[:...|:]\n Aktiviert Assertionen mit angegebener Granularit\u00E4t\n -da[:...|:]\n -disableassertions[:...|:]\n Deaktiviert Assertionen mit angegebener Granularit\u00E4t\n -esa | -enablesystemassertions\n Aktiviert Systemassertionen\n -dsa | -disablesystemassertions\n Deaktiviert Systemassertionen\n -agentlib:[=]\n L\u00E4dt native Agent Library , z.B. -agentlib:hprof\n siehe auch -agentlib:jdwp=help und -agentlib:hprof=help\n -agentpath:[=]\n L\u00E4dt native Agent Library nach vollem Pfadnamen\n -javaagent:[=]\n L\u00E4dt Java-Programmiersprachen-Agent, siehe java.lang.instrument\n -splash:\n Zeigt Startbildschirm mit angegebenem Bild\nWeitere Einzelheiten finden Sie unter http://www.oracle.com/technetwork/java/javase/documentation/index.html # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed Ausf\u00FChrung im gemischten Modus (Standard)\n -Xint Nur Ausf\u00FChrung im interpretierten Modus\n -Xbootclasspath:\n Legt Suchpfad f\u00FCr Bootstrap-Klassen und Ressourcen fest\n -Xbootclasspath/a:\n H\u00E4ngt an das Ende des Bootstrap Classpath an\n -Xbootclasspath/p:\n Stellt Bootstrap Classpath voran\n -Xdiag Zeigt zus\u00E4tzliche Diagnosemeldungen an\n -Xnoclassgc Deaktiviert Klassen-Garbage Collection\n -Xincgc Aktiviert inkrementelle Garbage Collection\n -Xloggc: Loggt GC-Status in einer Datei mit Zeitstempeln\n -Xbatch Deaktiviert Hintergrundkompilierung\n -Xms Legt anf\u00E4ngliche Java Heap-Gr\u00F6\u00DFe fest\n -Xmx Legt maximale Java Heap-Gr\u00F6\u00DFe fest\n -Xss Legt Java-Thread-Stackgr\u00F6\u00DFe fest\n -Xprof Gibt CPU-Profiling-Daten aus\n -Xfuture Aktiviert strengste Pr\u00FCfungen, antizipiert zuk\u00FCnftigen Standardwert\n -Xrs Reduziert Verwendung von BS-Signalen durch Java/VM (siehe Dokumentation)\n -Xcheck:jni F\u00FChrt zus\u00E4tzliche Pr\u00FCfungen f\u00FCr JNI-Funktionen durch\n -Xshare:off Kein Versuch, gemeinsame Klassendaten zu verwenden\n -Xshare:auto Verwendet gemeinsame Klassendaten, wenn m\u00F6glich (Standard)\n -Xshare:on Erfordert die Verwendung gemeinsamer Klassendaten, sonst verl\u00E4uft der Vorgang nicht erfolgreich.\n -XshowSettings Zeigt alle Einstellungen und f\u00E4hrt fort\n -XshowSettings:all\n Zeigt alle Einstellungen und f\u00E4hrt fort\n -XshowSettings:vm Zeigt alle VM-bezogenen Einstellungen und f\u00E4hrt fort\n -XshowSettings:properties\n Zeigt alle Eigenschaftseinstellungen und f\u00E4hrt fort\n -XshowSettings:locale\n Zeigt alle gebietsschemabezogenen Einstellungen und f\u00E4hrt fort\n\nDie -X-Optionen sind keine Standardoptionen und k\u00F6nnen ohne Vorank\u00FCndigung ge\u00E4ndert werden.\n @@ -50,7 +50,5 @@ java.launcher.cls.error5=Fehler: Zum Ausf\u00FChren dieser Anwendung ben\u00F6ti java.launcher.jar.error1=Fehler: Beim Versuch, Datei {0} zu \u00F6ffnen, ist ein unerwarteter Fehler aufgetreten java.launcher.jar.error2=Manifest in {0} nicht gefunden java.launcher.jar.error3=kein Hauptmanifestattribut, in {0} -java.launcher.jar.error4=kein Profilmanifestattribut in {0} -java.launcher.jar.error5=Das f\u00FCr {1} erforderliche Profil {0} wird von dieser Runtime-Anwendung nicht unterst\u00FCtzt java.launcher.init.error=Initialisierungsfehler java.launcher.javafx.error1=Fehler: Die JavaFX-Methode launchApplication hat die falsche Signatur, sie\nmuss als statisch deklariert werden und einen Wert vom Typ VOID zur\u00FCckgeben diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties index 1aefa5f0194..b2bdab3f63d 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties @@ -50,7 +50,5 @@ java.launcher.cls.error5=Error: faltan los componentes de JavaFX runtime y son n java.launcher.jar.error1=Error: se ha producido un error inesperado al intentar abrir el archivo {0} java.launcher.jar.error2=no se ha encontrado el manifiesto en {0} java.launcher.jar.error3=no hay ning\u00FAn atributo de manifiesto principal en {0} -java.launcher.jar.error4=no hay ning\u00FAn atributo de manifiesto de perfil en {0} -java.launcher.jar.error5=El perfil {0} que necesita {1} no est\u00E1 soportado por este tiempo de ejecuci\u00F3n java.launcher.init.error=error de inicializaci\u00F3n java.launcher.javafx.error1=Error: el m\u00E9todo launchApplication de JavaFX tiene una firma que no es correcta.\\nSe debe declarar est\u00E1tico y devolver un valor de tipo nulo diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties index 6e5d9891828..11f64e009fa 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ La machine virtuelle par d\u00E java.launcher.ergo.message2 =\ car vous ex\u00E9cutez une machine de classe de serveur.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n -classpath \n Liste de r\u00E9pertoires, d''archives JAR et\n d''archives ZIP s\u00E9par\u00E9s par des {0}, dans laquelle rechercher les fichiers de classe.\n -D=\n d\u00E9finition d''une propri\u00E9t\u00E9 syst\u00E8me\n -verbose[:class|gc|jni]\n activation de la sortie en mode verbose\n -version impression de la version du produit et fin de l''op\u00E9ration\n -version:\n ex\u00E9cution de la version sp\u00E9cifi\u00E9e obligatoire\n -showversion impression de la version du produit et poursuite de l''op\u00E9ration\n -jre-restrict-search | -no-jre-restrict-search\n inclusion/exclusion des environnements JRE priv\u00E9s de l''utilisateur dans la recherche de version\n -? -help impression du message d''aide\n -X impression de l''aide sur les options non standard\n -ea[:...|:]\n -enableassertions[:...|:]\n activation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n -da[:...|:]\n -disableassertions[:...|:]\n d\u00E9sactivation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n -esa | -enablesystemassertions\n activation des assertions syst\u00E8me\n -dsa | -disablesystemassertions\n d\u00E9sactivation des assertions syst\u00E8me\n -agentlib:[=]\n chargement de la biblioth\u00E8que d''agent natif , par exemple -agentlib:hprof\n voir \u00E9galement, -agentlib:jdwp=help et -agentlib:hprof=help\n -agentpath:[=]\n chargement de la biblioth\u00E8que d''agent natif via le chemin d''acc\u00E8s complet\n -javaagent:[=]\n chargement de l''agent du langage de programmation Java, voir java.lang.instrument\n -splash:\n affichage de l''\u00E9cran d''accueil avec l''image sp\u00E9cifi\u00E9e\nVoir http://www.oracle.com/technetwork/java/javase/documentation/index.html pour plus de d\u00E9tails. +java.launcher.opt.footer =\ -cp \n -classpath \n Liste de r\u00E9pertoires, d''archives JAR et\n d''archives ZIP s\u00E9par\u00E9s par des {0}, dans laquelle rechercher les fichiers de classe.\n -D=\n d\u00E9finition d''une propri\u00E9t\u00E9 syst\u00E8me\n -verbose:[class|gc|jni]\n activation de la sortie en mode verbose\n -version impression de la version du produit et fin de l''op\u00E9ration\n -version:\n ex\u00E9cution de la version sp\u00E9cifi\u00E9e obligatoire\n -showversion impression de la version du produit et poursuite de l''op\u00E9ration\n -jre-restrict-search | -no-jre-restrict-search\n inclusion/exclusion des environnements JRE priv\u00E9s de l''utilisateur dans la recherche de version\n -? -help impression du message d''aide\n -X impression de l''aide sur les options non standard\n -ea[:...|:]\n -enableassertions[:...|:]\n activation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n -da[:...|:]\n -disableassertions[:...|:]\n d\u00E9sactivation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n -esa | -enablesystemassertions\n activation des assertions syst\u00E8me\n -dsa | -disablesystemassertions\n d\u00E9sactivation des assertions syst\u00E8me\n -agentlib:[=]\n chargement de la biblioth\u00E8que d''agent natif , par exemple -agentlib:hprof\n voir \u00E9galement, -agentlib:jdwp=help et -agentlib:hprof=help\n -agentpath:[=]\n chargement de la biblioth\u00E8que d''agent natif via le chemin d''acc\u00E8s complet\n -javaagent:[=]\n chargement de l''agent du langage de programmation Java, voir java.lang.instrument\n -splash:\n affichage de l''\u00E9cran d''accueil avec l''image sp\u00E9cifi\u00E9e\nVoir http://www.oracle.com/technetwork/java/javase/documentation/index.html pour plus de d\u00E9tails. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed ex\u00E9cution en mode mixte (valeur par d\u00E9faut)\n -Xint ex\u00E9cution en mode interpr\u00E9t\u00E9 uniquement\n -Xbootclasspath:\n d\u00E9finition du chemin de recherche pour les ressources et classes bootstrap\n -Xbootclasspath/a:\n ajout \u00E0 la fin du chemin de classe bootstrap\n -Xbootclasspath/p:\n ajout au d\u00E9but du chemin de classe bootstrap\n -Xdiag affichage de messages de diagnostic suppl\u00E9mentaires\n -Xnoclassgc d\u00E9sactivation de l''op\u00E9ration de ramasse-miette (garbage collection) de la classe\n -Xincgc activation de l''op\u00E9ration de ramasse-miette (garbage collection) incr\u00E9mentielle\n -Xloggc: journalisation du statut de l''op\u00E9ration de ramasse-miette (garbage collection) dans un fichier avec horodatages\n -Xbatch d\u00E9sactivation de la compilation en arri\u00E8re-plan\n -Xms d\u00E9finition de la taille initiale des portions de m\u00E9moire Java\n -Xmx d\u00E9finition de la taille maximale des portions de m\u00E9moire Java\n -Xss d\u00E9finition de la taille de pile de thread Java\n -Xprof sortie des donn\u00E9es de profilage de l''unit\u00E9 centrale\n -Xfuture activation des contr\u00F4les les plus stricts en vue d''anticiper la future valeur par d\u00E9faut\n -Xrs r\u00E9duction de l''utilisation des signaux OS par Java/la machine virtuelle (voir documentation)\n -Xcheck:jni ex\u00E9cution de contr\u00F4les suppl\u00E9mentaires pour les fonctions JNI\n -Xshare:off aucune tentative d''utilisation des donn\u00E9es de classe partag\u00E9es\n -Xshare:auto utilisation des donn\u00E9es de classe partag\u00E9es si possible (valeur par d\u00E9faut)\n -Xshare:on utilisation des donn\u00E9es de classe partag\u00E9es obligatoire ou \u00E9chec de l''op\u00E9ration\n -XshowSettings affichage de tous les param\u00E8tres et poursuite de l''op\u00E9ration\n -XshowSettings:all\n affichage de tous les param\u00E8tres et poursuite de l''op\u00E9ration\n -XshowSettings:vm affichage de tous les param\u00E8tres de machine virtuelle et poursuite de l''op\u00E9ration\n -XshowSettings:properties\n affichage de tous les param\u00E8tres de propri\u00E9t\u00E9 et poursuite de l''op\u00E9ration\n -XshowSettings:locale\n affichage de tous les param\u00E8tres d''environnement local et poursuite de l''op\u00E9ration\n\nLes options -X ne sont pas des options standard et peuvent faire l''objet de modifications sans pr\u00E9avis.\n @@ -50,7 +50,5 @@ java.launcher.cls.error5=Erreur : des composants d'ex\u00E9cution JavaFX obligat java.launcher.jar.error1=Erreur : une erreur inattendue est survenue lors de la tentative d''ouverture du fichier {0} java.launcher.jar.error2=fichier manifeste introuvable dans {0} java.launcher.jar.error3=aucun attribut manifest principal dans {0} -java.launcher.jar.error4=aucun attribut manifest ''Profile'' dans {0} -java.launcher.jar.error5=Profil {0} requis par {1} non pris en charge par cette ex\u00E9cution java.launcher.init.error=erreur d'initialisation java.launcher.javafx.error1=Erreur : la signature de la m\u00E9thode launchApplication JavaFX est incorrecte, la\nm\u00E9thode doit \u00EAtre d\u00E9clar\u00E9e statique et renvoyer une valeur de type void diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties index 7ca3cf357c8..492b6755111 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties @@ -50,7 +50,5 @@ java.launcher.cls.error5=Errore: non sono presenti i componenti runtime di JavaF java.launcher.jar.error1=Errore: si \u00E8 verificato un errore imprevisto durante il tentativo di aprire il file {0} java.launcher.jar.error2=manifest non trovato in {0} java.launcher.jar.error3=nessun attributo manifest principale in {0} -java.launcher.jar.error4=nessun attributo manifest di profilo in {0} -java.launcher.jar.error5=Il profilo {0} richiesto da {1} non \u00E8 supportato da questo runtime java.launcher.init.error=errore di inizializzazione java.launcher.javafx.error1=Errore: il metodo JavaFX launchApplication dispone di una firma errata, \nla firma deve essere dichiarata static e restituire un valore di tipo void diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties index 52c220a6926..d1f2f699f2e 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties @@ -34,11 +34,11 @@ java.launcher.ergo.message1 =\ \u30C7\u30D5\u30A9\u30EB\u30C8V java.launcher.ergo.message2 =\ \u3053\u308C\u306F\u30B5\u30FC\u30D0\u30FC\u30AF\u30E9\u30B9\u306E\u30DE\u30B7\u30F3\u3067\u5B9F\u884C\u3057\u3066\u3044\u308B\u305F\u3081\u3067\u3059\u3002\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n -classpath \n \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001\n JAR\u30A2\u30FC\u30AB\u30A4\u30D6\u304A\u3088\u3073ZIP\u30A2\u30FC\u30AB\u30A4\u30D6\u306E{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30EA\u30B9\u30C8\u3067\u3059\u3002\n -D=\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u8A2D\u5B9A\u3059\u308B\n -verbose:[class|gc|jni]\n \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n -version \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D42\u4E86\u3059\u308B\n -version:\n \u6307\u5B9A\u3057\u305F\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u5B9F\u884C\u306B\u5FC5\u9808\u306B\u3059\u308B\n -showversion \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D9A\u884C\u3059\u308B\n -jre-restrict-search | -no-jre-restrict-search\n \u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8JRE\u3092\u30D0\u30FC\u30B8\u30E7\u30F3\u691C\u7D22\u306B\u542B\u3081\u308B/\u9664\u5916\u3059\u308B\n -? -help \u3053\u306E\u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n -X \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u95A2\u3059\u308B\u30D8\u30EB\u30D7\u3092\u51FA\u529B\u3059\u308B\n -ea[:...|:]\n -enableassertions[:...|:]\n \u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -da[:...|:]\n -disableassertions[:...|:]\n \u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -esa | -enablesystemassertions\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -dsa | -disablesystemassertions\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -agentlib:[=]\n \u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002\u4F8B: -agentlib:hprof\n -agentlib:jdwp=help\u3068-agentlib:hprof=help\u3082\u53C2\u7167\n -agentpath:[=]\n \u30D5\u30EB\u30D1\u30B9\u540D\u3067\u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA\u3092\u30ED\u30FC\u30C9\u3059\u308B\n -javaagent:[=]\n Java\u30D7\u30ED\u30B0\u30E9\u30DF\u30F3\u30B0\u8A00\u8A9E\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002java.lang.instrument\u3092\u53C2\u7167\n -splash:\n \u6307\u5B9A\u3057\u305F\u30A4\u30E1\u30FC\u30B8\u3067\u30B9\u30D7\u30E9\u30C3\u30B7\u30E5\u753B\u9762\u3092\u8868\u793A\u3059\u308B\n\u8A73\u7D30\u306Fhttp://www.oracle.com/technetwork/java/javase/documentation/index.html\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002 +java.launcher.opt.footer =\ -cp <\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB\u306E\u30AF\u30E9\u30B9\u691C\u7D22\u30D1\u30B9>\n -classpath <\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB\u306E\u30AF\u30E9\u30B9\u691C\u7D22\u30D1\u30B9>\n \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001\n JAR\u30A2\u30FC\u30AB\u30A4\u30D6\u304A\u3088\u3073ZIP\u30A2\u30FC\u30AB\u30A4\u30D6\u306E{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30EA\u30B9\u30C8\u3067\u3059\u3002\n -D=\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u8A2D\u5B9A\u3059\u308B\n -verbose:[class|gc|jni]\n \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n -version \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D42\u4E86\u3059\u308B\n -version:\n \u6307\u5B9A\u3057\u305F\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u5B9F\u884C\u306B\u5FC5\u9808\u306B\u3059\u308B\n -showversion \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D9A\u884C\u3059\u308B\n -jre-restrict-search | -no-jre-restrict-search\n \u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8JRE\u3092\u30D0\u30FC\u30B8\u30E7\u30F3\u691C\u7D22\u306B\u542B\u3081\u308B/\u9664\u5916\u3059\u308B\n -? -help \u3053\u306E\u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n -X \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u95A2\u3059\u308B\u30D8\u30EB\u30D7\u3092\u51FA\u529B\u3059\u308B\n -ea[:...|:]\n -enableassertions[:...|:]\n \u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -da[:...|:]\n -disableassertions[:...|:]\n \u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -esa | -enablesystemassertions\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -dsa | -disablesystemassertions\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -agentlib:[=]\n \u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002\u4F8B: -agentlib:hprof\n -agentlib:jdwp=help\u3068-agentlib:hprof=help\u3082\u53C2\u7167\n -agentpath:[=]\n \u30D5\u30EB\u30D1\u30B9\u540D\u3067\u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA\u3092\u30ED\u30FC\u30C9\u3059\u308B\n -javaagent:[=]\n Java\u30D7\u30ED\u30B0\u30E9\u30DF\u30F3\u30B0\u8A00\u8A9E\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002java.lang.instrument\u3092\u53C2\u7167\n -splash:\n \u6307\u5B9A\u3057\u305F\u30A4\u30E1\u30FC\u30B8\u3067\u30B9\u30D7\u30E9\u30C3\u30B7\u30E5\u753B\u9762\u3092\u8868\u793A\u3059\u308B\n\u8A73\u7D30\u306Fhttp://www.oracle.com/technetwork/java/javase/documentation/index.html\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002 # Translators please note do not translate the options themselves -java.launcher.X.usage=\ -Xmixed \u6DF7\u5408\u30E2\u30FC\u30C9\u306E\u5B9F\u884C(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xint \u30A4\u30F3\u30BF\u30D7\u30EA\u30BF\u30FB\u30E2\u30FC\u30C9\u306E\u5B9F\u884C\u306E\u307F\n -Xbootclasspath:\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u306E\u30AF\u30E9\u30B9\u3068\u30EA\u30BD\u30FC\u30B9\u306E\u691C\u7D22\u30D1\u30B9\u3092\u8A2D\u5B9A\u3059\u308B\n -Xbootclasspath/a:\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u6700\u5F8C\u306B\u8FFD\u52A0\u3059\u308B\n -Xbootclasspath/p:\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u524D\u306B\u4ED8\u52A0\u3059\u308B\n -Xdiag \u8FFD\u52A0\u306E\u8A3A\u65AD\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3059\u308B\n -Xnoclassgc \u30AF\u30E9\u30B9\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -Xincgc \u5897\u5206\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -Xloggc: \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u304C\u4ED8\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u306BGC\u30B9\u30C6\u30FC\u30BF\u30B9\u306E\u30ED\u30B0\u3092\u8A18\u9332\u3059\u308B\n -Xbatch \u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u7121\u52B9\u306B\u3059\u308B\n -Xms Java\u306E\u521D\u671F\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xmx Java\u306E\u6700\u5927\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xss Java\u306E\u30B9\u30EC\u30C3\u30C9\u30FB\u30B9\u30BF\u30C3\u30AF\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xprof CPU\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u30FB\u30C7\u30FC\u30BF\u3092\u51FA\u529B\u3059\u308B\n -Xfuture \u5C06\u6765\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u3092\u898B\u8D8A\u3057\u3066\u3001\u6700\u3082\u53B3\u5BC6\u306A\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3059\u308B\n -Xrs Java/VM\u306B\u3088\u308BOS\u30B7\u30B0\u30CA\u30EB\u306E\u4F7F\u7528\u3092\u524A\u6E1B\u3059\u308B(\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167)\n -Xcheck:jni JNI\u95A2\u6570\u306B\u5BFE\u3059\u308B\u8FFD\u52A0\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u5B9F\u884C\u3059\u308B\n -Xshare:off \u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u306A\u3044\n -Xshare:auto \u53EF\u80FD\u3067\u3042\u308C\u3070\u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xshare:on \u5171\u6709\u30AF\u30E9\u30B9\u30FB\u30C7\u30FC\u30BF\u306E\u4F7F\u7528\u3092\u5FC5\u9808\u306B\u3057\u3001\u3067\u304D\u306A\u3051\u308C\u3070\u5931\u6557\u3059\u308B\u3002\n -XshowSettings \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:all\n \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:vm \u3059\u3079\u3066\u306EVM\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:properties\n \u3059\u3079\u3066\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:locale\n \ -\u3059\u3079\u3066\u306E\u30ED\u30B1\u30FC\u30EB\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n\n-X\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u975E\u6A19\u6E96\u306A\u306E\u3067\u3001\u4E88\u544A\u306A\u304F\u5909\u66F4\u3055\u308C\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002\n +java.launcher.X.usage=\ -Xmixed \u6DF7\u5408\u30E2\u30FC\u30C9\u306E\u5B9F\u884C(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xint \u30A4\u30F3\u30BF\u30D7\u30EA\u30BF\u30FB\u30E2\u30FC\u30C9\u306E\u5B9F\u884C\u306E\u307F\n -Xbootclasspath:<{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB>\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u306E\u30AF\u30E9\u30B9\u3068\u30EA\u30BD\u30FC\u30B9\u306E\u691C\u7D22\u30D1\u30B9\u3092\u8A2D\u5B9A\u3059\u308B\n -Xbootclasspath/a:<{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB>\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u6700\u5F8C\u306B\u8FFD\u52A0\u3059\u308B\n -Xbootclasspath/p:<{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB>\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u524D\u306B\u4ED8\u52A0\u3059\u308B\n -Xdiag \u8FFD\u52A0\u306E\u8A3A\u65AD\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3059\u308B\n -Xnoclassgc \u30AF\u30E9\u30B9\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -Xincgc \u5897\u5206\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -Xloggc: \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u304C\u4ED8\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u306BGC\u30B9\u30C6\u30FC\u30BF\u30B9\u306E\u30ED\u30B0\u3092\u8A18\u9332\u3059\u308B\n -Xbatch \u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u7121\u52B9\u306B\u3059\u308B\n -Xms Java\u306E\u521D\u671F\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xmx Java\u306E\u6700\u5927\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xss Java\u306E\u30B9\u30EC\u30C3\u30C9\u30FB\u30B9\u30BF\u30C3\u30AF\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xprof CPU\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u30FB\u30C7\u30FC\u30BF\u3092\u51FA\u529B\u3059\u308B\n -Xfuture \u5C06\u6765\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u3092\u898B\u8D8A\u3057\u3066\u3001\u6700\u3082\u53B3\u5BC6\u306A\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3059\u308B\n -Xrs Java/VM\u306B\u3088\u308BOS\u30B7\u30B0\u30CA\u30EB\u306E\u4F7F\u7528\u3092\u524A\u6E1B\u3059\u308B(\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167)\n -Xcheck:jni JNI\u95A2\u6570\u306B\u5BFE\u3059\u308B\u8FFD\u52A0\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u5B9F\u884C\u3059\u308B\n -Xshare:off \u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u306A\u3044\n -Xshare:auto \u53EF\u80FD\u3067\u3042\u308C\u3070\u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xshare:on \u5171\u6709\u30AF\u30E9\u30B9\u30FB\u30C7\u30FC\u30BF\u306E\u4F7F\u7528\u3092\u5FC5\u9808\u306B\u3057\u3001\u3067\u304D\u306A\u3051\u308C\u3070\u5931\u6557\u3059\u308B\u3002\n -XshowSettings \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:all\n \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:vm \u3059\u3079\u3066\u306EVM\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:properties\n \ +\u3059\u3079\u3066\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:locale\n \u3059\u3079\u3066\u306E\u30ED\u30B1\u30FC\u30EB\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n\n-X\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u975E\u6A19\u6E96\u306A\u306E\u3067\u3001\u4E88\u544A\u306A\u304F\u5909\u66F4\u3055\u308C\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002\n # Translators please note do not translate the options themselves java.launcher.X.macosx.usage=\n\u6B21\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306FMac OS X\u56FA\u6709\u3067\u3059\u3002\n -XstartOnFirstThread\n main()\u30E1\u30BD\u30C3\u30C9\u3092\u6700\u521D(AppKit)\u306E\u30B9\u30EC\u30C3\u30C9\u3067\u5B9F\u884C\u3059\u308B\n -Xdock:name="\n Dock\u306B\u8868\u793A\u3055\u308C\u308B\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u540D\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n -Xdock:icon=\n Dock\u306B\u8868\u793A\u3055\u308C\u308B\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n\n @@ -51,7 +51,5 @@ java.launcher.cls.error5=\u30A8\u30E9\u30FC: JavaFX\u30E9\u30F3\u30BF\u30A4\u30E java.launcher.jar.error1=\u30A8\u30E9\u30FC: \u30D5\u30A1\u30A4\u30EB{0}\u3092\u958B\u3053\u3046\u3068\u3057\u3066\u3044\u308B\u3068\u304D\u306B\u3001\u4E88\u671F\u3057\u306A\u3044\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F java.launcher.jar.error2={0}\u306B\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 java.launcher.jar.error3={0}\u306B\u30E1\u30A4\u30F3\u30FB\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5C5E\u6027\u304C\u3042\u308A\u307E\u305B\u3093 -java.launcher.jar.error4={0}\u306B\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u30FB\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5C5E\u6027\u304C\u3042\u308A\u307E\u305B\u3093 -java.launcher.jar.error5={1}\u306B\u5FC5\u8981\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB{0}\u306F\u3053\u306E\u30E9\u30F3\u30BF\u30A4\u30E0\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093 java.launcher.init.error=\u521D\u671F\u5316\u30A8\u30E9\u30FC java.launcher.javafx.error1=\u30A8\u30E9\u30FC: JavaFX launchApplication\u30E1\u30BD\u30C3\u30C9\u306B\u8AA4\u3063\u305F\u30B7\u30B0\u30CD\u30C1\u30E3\u304C\u3042\u308A\u3001\nstatic\u3092\u5BA3\u8A00\u3057\u3066void\u578B\u306E\u5024\u3092\u8FD4\u3059\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059 diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties index a4c3d800c2d..d9d471eec9f 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties @@ -34,10 +34,11 @@ java.launcher.ergo.message1 =\ \uAE30\uBCF8 VM\uC740 {0}\uC785 java.launcher.ergo.message2 =\ \uC11C\uBC84\uAE09 \uC2DC\uC2A4\uD15C\uC5D0\uC11C \uC2E4\uD589 \uC911\uC774\uAE30 \uB54C\uBB38\uC785\uB2C8\uB2E4.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \\n -classpath \\n \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uAC80\uC0C9\uD560 {0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC,\\n JAR \uC544\uCE74\uC774\uBE0C \uBC0F ZIP \uC544\uCE74\uC774\uBE0C \uBAA9\uB85D\uC785\uB2C8\uB2E4.\\n -D=\\n \uC2DC\uC2A4\uD15C \uC18D\uC131\uC744 \uC124\uC815\uD569\uB2C8\uB2E4.\\n -verbose:[class|gc|jni]\\n \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\\n -version \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uC885\uB8CC\uD569\uB2C8\uB2E4.\\n -version:\\n \uC2E4\uD589\uD560 \uBC84\uC804\uC744 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4.\\n -showversion \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\\n -jre-restrict-search | -no-jre-restrict-search\\n \uBC84\uC804 \uAC80\uC0C9\uC5D0\uC11C \uC0AC\uC6A9\uC790 \uC804\uC6A9 JRE\uB97C \uD3EC\uD568/\uC81C\uC678\uD569\uB2C8\uB2E4.\\n -? -help \uC774 \uB3C4\uC6C0\uB9D0 \uBA54\uC2DC\uC9C0\uB97C \uC778\uC1C4\uD569\uB2C8\uB2E4.\\n -X \uBE44\uD45C\uC900 \uC635\uC158\uC5D0 \uB300\uD55C \uB3C4\uC6C0\uB9D0\uC744 \uC778\uC1C4\uD569\uB2C8\uB2E4.\\n -ea[:...|:]\\n -enableassertions[:...|:]\\n \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\\n -da[:...|:]\\n -disableassertions[:...|:]\\n \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\\n -esa | -enablesystemassertions\\n \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\\n -dsa | -disablesystemassertions\\n \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\\n -agentlib:[=]\\n \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4(\uC608: -agentlib:hprof).\\n -agentlib:jdwp=help \uBC0F -agentlib:hprof=help\uB3C4 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\\n -agentpath:[=]\\n \uC804\uCCB4 \uACBD\uB85C\uBA85\uC744 \uC0AC\uC6A9\uD558\uC5EC \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4.\\n -javaagent:[=]\\n Java \uD504\uB85C\uADF8\uB798\uBC0D \uC5B8\uC5B4 \uC5D0\uC774\uC804\uD2B8\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4. java.lang.instrument\uB97C \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\\n -splash:\\n \uC774\uBBF8\uC9C0\uAC00 \uC9C0\uC815\uB41C \uC2A4\uD50C\uB798\uC2DC \uD654\uBA74\uC744 \uD45C\uC2DC\uD569\uB2C8\uB2E4.\\n\uC790\uC138\uD55C \uB0B4\uC6A9\uC740 http://www.oracle.com/technetwork/java/javase/documentation/index.html\uC744 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624. +java.launcher.opt.footer =\ -cp <\uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C\uC758 \uD074\uB798\uC2A4 \uAC80\uC0C9 \uACBD\uB85C>\n -classpath <\uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C\uC758 \uD074\uB798\uC2A4 \uAC80\uC0C9 \uACBD\uB85C>\n \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uAC80\uC0C9\uD560 {0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC,\n JAR \uC544\uCE74\uC774\uBE0C \uBC0F ZIP \uC544\uCE74\uC774\uBE0C \uBAA9\uB85D\uC785\uB2C8\uB2E4.\n -D=\n \uC2DC\uC2A4\uD15C \uC18D\uC131\uC744 \uC124\uC815\uD569\uB2C8\uB2E4.\n -verbose:[class|gc|jni]\n \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -version \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uC885\uB8CC\uD569\uB2C8\uB2E4.\n -version:\n \uC2E4\uD589\uD560 \uBC84\uC804\uC744 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4.\n -showversion \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -jre-restrict-search | -no-jre-restrict-search\n \uBC84\uC804 \uAC80\uC0C9\uC5D0\uC11C \uC0AC\uC6A9\uC790 \uC804\uC6A9 JRE\uB97C \uD3EC\uD568/\uC81C\uC678\uD569\uB2C8\uB2E4.\n -? -help \uC774 \uB3C4\uC6C0\uB9D0 \uBA54\uC2DC\uC9C0\uB97C \uC778\uC1C4\uD569\uB2C8\uB2E4.\n -X \uBE44\uD45C\uC900 \uC635\uC158\uC5D0 \uB300\uD55C \uB3C4\uC6C0\uB9D0\uC744 \uC778\uC1C4\uD569\uB2C8\uB2E4.\n -ea[:...|:]\n -enableassertions[:...|:]\n \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -da[:...|:]\n -disableassertions[:...|:]\n \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -esa | -enablesystemassertions\n \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -dsa | -disablesystemassertions\n \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -agentlib:[=]\n \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4(\uC608: -agentlib:hprof).\n -agentlib:jdwp=help \uBC0F -agentlib:hprof=help\uB3C4 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\n -agentpath:[=]\n \uC804\uCCB4 \uACBD\uB85C\uBA85\uC744 \uC0AC\uC6A9\uD558\uC5EC \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4.\n -javaagent:[=]\n Java \uD504\uB85C\uADF8\uB798\uBC0D \uC5B8\uC5B4 \uC5D0\uC774\uC804\uD2B8\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4. java.lang.instrument\uB97C \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\n -splash:\n \uC774\uBBF8\uC9C0\uAC00 \uC9C0\uC815\uB41C \uC2A4\uD50C\uB798\uC2DC \uD654\uBA74\uC744 \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n\uC790\uC138\uD55C \uB0B4\uC6A9\uC740 http://www.oracle.com/technetwork/java/javase/documentation/index.html\uC744 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624. # Translators please note do not translate the options themselves -java.launcher.X.usage=\ -Xmixed \uD63C\uD569 \uBAA8\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n -Xint \uD574\uC11D\uB41C \uBAA8\uB4DC\uB9CC \uC2E4\uD589\uD569\uB2C8\uB2E4.\n -Xbootclasspath:\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uBC0F \uB9AC\uC18C\uC2A4\uC5D0 \uB300\uD55C \uAC80\uC0C9 \uACBD\uB85C\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xbootclasspath/a:\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uACBD\uB85C \uB05D\uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.\n -Xbootclasspath/p:\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uACBD\uB85C \uC55E\uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.\n -Xdiag \uCD94\uAC00 \uC9C4\uB2E8 \uBA54\uC2DC\uC9C0\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n -Xnoclassgc \uD074\uB798\uC2A4\uC758 \uBD88\uD544\uC694\uD55C \uC815\uBCF4 \uBAA8\uC74C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xincgc \uC99D\uBD84\uC801\uC778 \uBD88\uD544\uC694\uD55C \uC815\uBCF4 \uBAA8\uC74C\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xloggc: \uC2DC\uAC04 \uAE30\uB85D\uACFC \uD568\uAED8 \uD30C\uC77C\uC5D0 GC \uC0C1\uD0DC\uB97C \uAE30\uB85D\uD569\uB2C8\uB2E4.\n -Xbatch \uBC31\uADF8\uB77C\uC6B4\uB4DC \uCEF4\uD30C\uC77C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xms \uCD08\uAE30 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xmx \uCD5C\uB300 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xss Java \uC2A4\uB808\uB4DC \uC2A4\uD0DD \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xprof CPU \uD504\uB85C\uD30C\uC77C \uC791\uC131 \uB370\uC774\uD130\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4.\n -Xfuture \uBBF8\uB798 \uAE30\uBCF8\uAC12\uC744 \uC608\uCE21\uD558\uC5EC \uAC00\uC7A5 \uC5C4\uACA9\uD55C \uAC80\uC0AC\uB97C \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xrs Java/VM\uC5D0 \uC758\uD55C OS \uC2E0\uD638 \uC0AC\uC6A9\uC744 \uC904\uC785\uB2C8\uB2E4(\uC124\uBA85\uC11C \uCC38\uC870).\n -Xcheck:jni JNI \uD568\uC218\uC5D0 \uB300\uD55C \uCD94\uAC00 \uAC80\uC0AC\uB97C \uC218\uD589\uD569\uB2C8\uB2E4.\n -Xshare:off \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130 \uC0AC\uC6A9\uC744 \uC2DC\uB3C4\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -Xshare:auto \uAC00\uB2A5\uD55C \uACBD\uC6B0 \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n -Xshare:on \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD574\uC57C \uD569\uB2C8\uB2E4. \uADF8\uB807\uC9C0 \uC54A\uC744 \uACBD\uC6B0 \uC2E4\uD328\uD569\uB2C8\uB2E4.\n -XshowSettings \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:all\n \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:vm \uBAA8\uB4E0 VM \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:properties\n \uBAA8\uB4E0 \uC18D\uC131 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:locale\n \uBAA8\uB4E0 \uB85C\uCF00\uC77C \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n\n-X \uC635\uC158\uC740 \uBE44\uD45C\uC900 \uC635\uC158\uC774\uBBC0\uB85C \uD1B5\uC9C0 \uC5C6\uC774 \uBCC0\uACBD\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n +java.launcher.X.usage=\ -Xmixed \uD63C\uD569 \uBAA8\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n -Xint \uD574\uC11D\uB41C \uBAA8\uB4DC\uB9CC \uC2E4\uD589\uD569\uB2C8\uB2E4.\n -Xbootclasspath:<{0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C>\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uBC0F \uB9AC\uC18C\uC2A4\uC5D0 \uB300\uD55C \uAC80\uC0C9 \uACBD\uB85C\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xbootclasspath/a:<{0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C>\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uACBD\uB85C \uB05D\uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.\n -Xbootclasspath/p:<{0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C>\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uACBD\uB85C \uC55E\uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.\n -Xdiag \uCD94\uAC00 \uC9C4\uB2E8 \uBA54\uC2DC\uC9C0\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n -Xnoclassgc \uD074\uB798\uC2A4\uC758 \uBD88\uD544\uC694\uD55C \uC815\uBCF4 \uBAA8\uC74C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xincgc \uC99D\uBD84\uC801\uC778 \uBD88\uD544\uC694\uD55C \uC815\uBCF4 \uBAA8\uC74C\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xloggc: \uC2DC\uAC04 \uAE30\uB85D\uACFC \uD568\uAED8 \uD30C\uC77C\uC5D0 GC \uC0C1\uD0DC\uB97C \uAE30\uB85D\uD569\uB2C8\uB2E4.\n -Xbatch \uBC31\uADF8\uB77C\uC6B4\uB4DC \uCEF4\uD30C\uC77C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xms \uCD08\uAE30 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xmx \uCD5C\uB300 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xss Java \uC2A4\uB808\uB4DC \uC2A4\uD0DD \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xprof CPU \uD504\uB85C\uD30C\uC77C \uC791\uC131 \uB370\uC774\uD130\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4.\n -Xfuture \uBBF8\uB798 \uAE30\uBCF8\uAC12\uC744 \uC608\uCE21\uD558\uC5EC \uAC00\uC7A5 \uC5C4\uACA9\uD55C \uAC80\uC0AC\uB97C \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xrs Java/VM\uC5D0 \uC758\uD55C OS \uC2E0\uD638 \uC0AC\uC6A9\uC744 \uC904\uC785\uB2C8\uB2E4(\uC124\uBA85\uC11C \uCC38\uC870).\n -Xcheck:jni JNI \uD568\uC218\uC5D0 \uB300\uD55C \uCD94\uAC00 \uAC80\uC0AC\uB97C \uC218\uD589\uD569\uB2C8\uB2E4.\n -Xshare:off \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130 \uC0AC\uC6A9\uC744 \uC2DC\uB3C4\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -Xshare:auto \uAC00\uB2A5\uD55C \uACBD\uC6B0 \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n -Xshare:on \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD574\uC57C \uD569\uB2C8\uB2E4. \uADF8\uB807\uC9C0 \uC54A\uC744 \uACBD\uC6B0 \uC2E4\uD328\uD569\uB2C8\uB2E4.\n -XshowSettings \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:all\n \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:vm \uBAA8\uB4E0 VM \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:properties\n \uBAA8\uB4E0 \uC18D\uC131 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:locale\n \uBAA8\uB4E0 \uB85C\uCF00\uC77C \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n\n-X \uC635\uC158\uC740 \uBE44\uD45C\uC900 \uC635\uC158\uC774\uBBC0\uB85C \uD1B5\uC9C0 \uC5C6\uC774 \uBCC0\uACBD\uB420 \uC218 \ +\uC788\uC2B5\uB2C8\uB2E4.\n # Translators please note do not translate the options themselves java.launcher.X.macosx.usage=\n\uB2E4\uC74C\uC740 Mac OS X\uC5D0 \uD2B9\uC815\uB41C \uC635\uC158\uC785\uB2C8\uB2E4.\n -XstartOnFirstThread\n \uCCAB\uBC88\uC9F8 (AppKit) \uC2A4\uB808\uB4DC\uC5D0 main() \uBA54\uC18C\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4.\n -Xdock:name="\n \uACE0\uC815\uC73C\uB85C \uD45C\uC2DC\uB41C \uAE30\uBCF8 \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8 \uC774\uB984\uC744 \uBB34\uD6A8\uD654\uD569\uB2C8\uB2E4.\n -Xdock:icon=\n \uACE0\uC815\uC73C\uB85C \uD45C\uC2DC\uB41C \uAE30\uBCF8 \uC544\uC774\uCF58\uC744 \uBB34\uD6A8\uD654\uD569\uB2C8\uB2E4.\n\n @@ -50,7 +51,5 @@ java.launcher.cls.error5=\uC624\uB958: \uC774 \uC751\uC6A9 \uD504\uB85C\uADF8\uB java.launcher.jar.error1=\uC624\uB958: {0} \uD30C\uC77C\uC744 \uC5F4\uB824\uACE0 \uC2DC\uB3C4\uD558\uB294 \uC911 \uC608\uC0C1\uCE58 \uC54A\uC740 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. java.launcher.jar.error2={0}\uC5D0\uC11C Manifest\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. java.launcher.jar.error3={0}\uC5D0 \uAE30\uBCF8 Manifest \uC18D\uC131\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. -java.launcher.jar.error4={0}\uC5D0 Profile manifest \uC18D\uC131\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. -java.launcher.jar.error5={1}\uC5D0 \uD544\uC694\uD55C {0} \uD504\uB85C\uD30C\uC77C\uC740 \uC774 \uB7F0\uD0C0\uC784\uC5D0\uC11C \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. java.launcher.init.error=\uCD08\uAE30\uD654 \uC624\uB958 java.launcher.javafx.error1=\uC624\uB958: JavaFX launchApplication \uBA54\uC18C\uB4DC\uC5D0 \uC798\uBABB\uB41C \uC11C\uBA85\uC774 \uC788\uC2B5\uB2C8\uB2E4.\\n\uB530\uB77C\uC11C static\uC73C\uB85C \uC120\uC5B8\uD558\uACE0 void \uC720\uD615\uC758 \uAC12\uC744 \uBC18\uD658\uD574\uC57C \uD569\uB2C8\uB2E4. diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_pt_BR.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_pt_BR.properties index 00425f64412..17d88fef80d 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_pt_BR.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_pt_BR.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ A VM default \u00E9 {0} java.launcher.ergo.message2 =\ porque a execu\u00E7\u00E3o est\u00E1 sendo feita em uma m\u00E1quina de classe de servidor.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n -classpath \n Uma lista separada por {0} de diret\u00F3rios, archives JAR\n e archives ZIP nos quais ser\u00E3o procurados os arquivos de classe.\n -D=\n define uma propriedade do sistema\n -verbose[:classe|gc|jni]\n ativa a sa\u00EDda detalhada\n -version imprime a vers\u00E3o do produto e sai do programa\n -version:\n requer a execu\u00E7\u00E3o da vers\u00E3o especificada\n -showversion imprime a vers\u00E3o do produto e continua\n -jre-restrict-search | -no-jre-restrict-search\n inclui/exclui JREs privados do usu\u00E1rio na pesquisa de vers\u00E3o\n -? -help imprime esta mensagem de ajuda\n -X imprime a ajuda sobre op\u00E7\u00F5es n\u00E3o padronizadas\n -ea[:...|:]\n -enableassertions[:...|:]\n ativa asser\u00E7\u00F5es com granularidade especificada\n -da[:...|:]\n -disableassertions[:...|:]\n desativa asser\u00E7\u00F5es com granularidade especificada\n -esa | -enablesystemassertions\n ativa asser\u00E7\u00F5es do sistema\n -dsa | -disablesystemassertions\n desativa asser\u00E7\u00F5es do sistema\n -agentlib:[=]\n carrega a biblioteca de agentes nativa , por exemplo: -agentlib:hprof\n consulte tamb\u00E9m: -agentlib:jdwp=help e -agentlib:hprof=help\n -agentpath:[=]\n carrega a biblioteca de agentes nativa com base no nome do caminho completo\n -javaagent:[=]\n carrega o agente da linguagem de programa\u00E7\u00E3o Java; consulte java.lang.instrument\n -splash:\n mostra a tela de abertura com a imagem especificada\nConsulte http://www.oracle.com/technetwork/java/javase/documentation/index.html para obter mais detalhes. +java.launcher.opt.footer =\ -cp \n -classpath \n Uma lista separada por {0} de diret\u00F3rios, archives JAR\n e archives ZIP nos quais ser\u00E3o procurados os arquivos de classe.\n -D=\n define uma propriedade do sistema\n -verbose:[classe|gc|jni]\n ativa a sa\u00EDda detalhada\n -version imprime a vers\u00E3o do produto e sai do programa\n -version:\n requer a execu\u00E7\u00E3o da vers\u00E3o especificada\n -showversion imprime a vers\u00E3o do produto e continua\n -jre-restrict-search | -no-jre-restrict-search\n inclui/exclui JREs privados do usu\u00E1rio na pesquisa de vers\u00E3o\n -? -help imprime esta mensagem de ajuda\n -X imprime a ajuda sobre op\u00E7\u00F5es n\u00E3o padronizadas\n -ea[:...|:]\n -enableassertions[:...|:]\n ativa asser\u00E7\u00F5es com granularidade especificada\n -da[:...|:]\n -disableassertions[:...|:]\n desativa asser\u00E7\u00F5es com granularidade especificada\n -esa | -enablesystemassertions\n ativa asser\u00E7\u00F5es do sistema\n -dsa | -disablesystemassertions\n desativa asser\u00E7\u00F5es do sistema\n -agentlib:[=]\n carrega a biblioteca de agentes nativa , por exemplo: -agentlib:hprof\n consulte tamb\u00E9m: -agentlib:jdwp=help e -agentlib:hprof=help\n -agentpath:[=]\n carrega a biblioteca de agentes nativa com base no nome do caminho completo\n -javaagent:[=]\n carrega o agente da linguagem de programa\u00E7\u00E3o Java; consulte java.lang.instrument\n -splash:\n mostra a tela de abertura com a imagem especificada\nConsulte http://www.oracle.com/technetwork/java/javase/documentation/index.html para obter mais detalhes. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed execu\u00E7\u00E3o no modo misto (default)\n -Xint execu\u00E7\u00E3o somente no modo interpretado\n -Xbootclasspath:\n define o caminho de pesquisa para classes e recursos de inicializa\u00E7\u00E3o\n -Xbootclasspath/a:\n anexa no final do caminho da classe de inicializa\u00E7\u00E3o\n -Xbootclasspath/p:\n anexa no in\u00EDcio do caminho da classe de inicializa\u00E7\u00E3o\n -Xdiag mostra mensagens de diagn\u00F3stico adicionais\n -Xnoclassgc desativa a coleta de lixo da classe\n -Xincgc ativa a coleta de lixo incremental\n -Xloggc: registra o status do GC status em um arquivo com marca\u00E7\u00F5es de data e hor\u00E1rio\n -Xbatch desativa a compila\u00E7\u00E3o em segundo plano\n -Xms define o tamanho inicial do heap Java\n -Xmx define o tamanho m\u00E1ximo do heap Java\n -Xss define o tamanho da pilha de threads java\n -Xprof produz dados de perfil da cpu\n -Xfuture ativa verifica\u00E7\u00F5es de n\u00EDvel m\u00E1ximo de exig\u00EAncia, prevendo o valor default futuro\n -Xrs reduz o uso de sinais do SO pelo(a) Java/VM (consulte a documenta\u00E7\u00E3o)\n -Xcheck:jni executa verifica\u00E7\u00F5es adicionais de fun\u00E7\u00F5es da JNI\n -Xshare:off n\u00E3o tenta usar dados da classe compartilhada\n -Xshare:auto se poss\u00EDvel, usa dados da classe compartilhada (default)\n -Xshare:on requer o uso de dados da classe compartilhada, caso contr\u00E1rio haver\u00E1 falha.\n -XshowSettings mostra todas as defini\u00E7\u00F5es e continua\n -XshowSettings:all\n mostra todas as defini\u00E7\u00F5es e continua\n -XshowSettings:vm mostra todas as defini\u00E7\u00F5es relacionadas \u00E0 vm e continua\n -XshowSettings:properties\n mostra todas as defini\u00E7\u00F5es da propriedade e continua\n -XshowSettings:locale\n mostra todas as defini\u00E7\u00F5es relativas \u00E0s configura\u00E7\u00F5es regionais e continua\n\nAs -X options n\u00E3o s\u00E3o padronizadas e est\u00E3o sujeitas a altera\u00E7\u00F5es sem aviso.\n @@ -50,7 +50,5 @@ java.launcher.cls.error5=Erro: os componentes de runtime do JavaFX n\u00E3o fora java.launcher.jar.error1=Erro: ocorreu um erro inesperado ao tentar abrir o arquivo {0} java.launcher.jar.error2=manifesto n\u00E3o encontrado em {0} java.launcher.jar.error3=nenhum atributo de manifesto principal em {0} -java.launcher.jar.error4=nenhum atributo de manifesto de Perfil em {0} -java.launcher.jar.error5=O perfil {0} exigido por {1} n\u00E3o \u00E9 suportado por este runtime java.launcher.init.error=erro de inicializa\u00E7\u00E3o java.launcher.javafx.error1=Erro: O m\u00E9todo launchApplication do JavaFX tem a assinatura errada. Ele\\ndeve ser declarado como est\u00E1tico e retornar um valor do tipo void diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties index 9577f39477a..d64c3f6f347 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties @@ -50,7 +50,5 @@ java.launcher.cls.error5=Fel: JavaFX-k\u00F6rningskomponenter saknas, och de kr\ java.launcher.jar.error1=Fel: Ett ov\u00E4ntat fel intr\u00E4ffade n\u00E4r filen {0} skulle \u00F6ppnas java.launcher.jar.error2=manifest finns inte i {0} java.launcher.jar.error3=inget huvudmanifestattribut i {0} -java.launcher.jar.error4=inget profilmanifestattribut i {0} -java.launcher.jar.error5=Profil {0} som kr\u00E4vs av {1} kan inte anv\u00E4ndas av den h\u00E4r k\u00F6rningen java.launcher.init.error=initieringsfel java.launcher.javafx.error1=Fel: JavaFX launchApplication-metoden har fel signatur, den \nm\u00E5ste ha deklarerats som statisk och returnera ett v\u00E4rde av typen void diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties index a536e68bfbc..1e352765d39 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties @@ -50,7 +50,5 @@ java.launcher.cls.error5=\u9519\u8BEF: \u7F3A\u5C11 JavaFX \u8FD0\u884C\u65F6\u7 java.launcher.jar.error1=\u9519\u8BEF: \u5C1D\u8BD5\u6253\u5F00\u6587\u4EF6{0}\u65F6\u51FA\u73B0\u610F\u5916\u9519\u8BEF java.launcher.jar.error2=\u5728{0}\u4E2D\u627E\u4E0D\u5230\u6E05\u5355 java.launcher.jar.error3={0}\u4E2D\u6CA1\u6709\u4E3B\u6E05\u5355\u5C5E\u6027 -java.launcher.jar.error4={0}\u4E2D\u6CA1\u6709\u914D\u7F6E\u6587\u4EF6\u6E05\u5355\u5C5E\u6027 -java.launcher.jar.error5=\u6B64\u8FD0\u884C\u65F6\u4E0D\u652F\u6301{1}\u6240\u9700\u7684\u914D\u7F6E\u6587\u4EF6{0} java.launcher.init.error=\u521D\u59CB\u5316\u9519\u8BEF java.launcher.javafx.error1=\u9519\u8BEF: JavaFX launchApplication \u65B9\u6CD5\u5177\u6709\u9519\u8BEF\u7684\u7B7E\u540D, \u5FC5\u987B\n\u5C06\u65B9\u6CD5\u58F0\u660E\u4E3A\u9759\u6001\u65B9\u6CD5\u5E76\u8FD4\u56DE\u7A7A\u7C7B\u578B\u7684\u503C diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties index 9fd5ff272a7..57e301d7558 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties @@ -50,7 +50,5 @@ java.launcher.cls.error5=\u932F\u8AA4: \u907A\u6F0F\u57F7\u884C\u6B64\u61C9\u752 java.launcher.jar.error1=\u932F\u8AA4: \u5617\u8A66\u958B\u555F\u6A94\u6848 {0} \u6642\u767C\u751F\u672A\u9810\u671F\u7684\u932F\u8AA4 java.launcher.jar.error2=\u5728 {0} \u4E2D\u627E\u4E0D\u5230\u8CC7\u8A0A\u6E05\u55AE java.launcher.jar.error3={0} \u4E2D\u6C92\u6709\u4E3B\u8981\u8CC7\u8A0A\u6E05\u55AE\u5C6C\u6027 -java.launcher.jar.error4={0} \u4E2D\u6C92\u6709 Profile \u8CC7\u8A0A\u6E05\u55AE\u5C6C\u6027 -java.launcher.jar.error5=\u6B64\u7A0B\u5F0F\u5BE6\u969B\u57F7\u884C\u4E0D\u652F\u63F4 {1} \u6240\u9700\u7684\u8A2D\u5B9A\u6A94 {0} java.launcher.init.error=\u521D\u59CB\u5316\u932F\u8AA4 java.launcher.javafx.error1=\u932F\u8AA4: JavaFX launchApplication \u65B9\u6CD5\u7684\u7C3D\u7AE0\u932F\u8AA4\uFF0C\u5B83\n\u5FC5\u9808\u5BA3\u544A\u70BA\u975C\u614B\u4E26\u50B3\u56DE void \u985E\u578B\u7684\u503C diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_de.properties b/jdk/src/share/classes/sun/print/resources/serviceui_de.properties index c7a48fcab41..51dac99f71c 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_de.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_de.properties @@ -17,8 +17,8 @@ button.print=Drucken button.properties=E&igenschaften... # checkbox.collate=&Sortieren -checkbox.jobsheets=&Bannerseite -checkbox.printtofile=Ausgabe in &Datei +checkbox.jobsheets=Banner&seite +checkbox.printtofile=Aus&gabe in Datei # dialog.printtitle=Drucken dialog.pstitle=Seite einrichten @@ -29,7 +29,7 @@ dialog.noprintermsg=Kein Druckservice gefunden. dialog.writeerror=Schreiben in Datei nicht m\u00F6glich: # label.info=Info: -label.jobname=&Job-Name: +label.jobname=&Jobname: label.numcopies=Anzahl &Kopien: label.priority=P&riorit\u00E4t: label.psname=&Name: @@ -42,21 +42,21 @@ label.username=&Benutzername: label.millimetres=(mm) label.inches=(Zoll) label.topmargin=&oben -label.bottommargin=&unten +label.bottommargin=u&nten label.leftmargin=&links -label.rightmargin=&rechts +label.rightmargin=re&chts # radiobutton.color=&Farbe radiobutton.draftq=Ent&wurf -radiobutton.duplex=&Duplex +radiobutton.duplex=Du&plex radiobutton.highq=&Hoch -radiobutton.landscape=&Querformat +radiobutton.landscape=Querforma&t radiobutton.monochrome=&Monochrom radiobutton.normalq=&Normal -radiobutton.oneside=&Einseitig +radiobutton.oneside=E&inseitig radiobutton.portrait=Hochfor&mat radiobutton.rangeall=A&lle -radiobutton.rangepages=S&eiten +radiobutton.rangepages=Sei&ten radiobutton.revlandscape=Umgekehrtes Q&uerformat radiobutton.revportrait=Umgekehrtes &Hochformat radiobutton.tumble=&Kalenderdruck diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_es.properties b/jdk/src/share/classes/sun/print/resources/serviceui_es.properties index 70c31fe9506..a0af46041a7 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_es.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_es.properties @@ -36,29 +36,29 @@ label.psname=&Nombre: label.pstype=Tipo: label.rangeto=A label.size=Tama&\u00F1o: -label.source=Ori&gen: +label.source=Orig&en: label.status=Estado: label.username=&Usuario: label.millimetres=(mm) label.inches=(pulg.) -label.topmargin=&superior +label.topmargin=s&uperior label.bottommargin=in&ferior label.leftmargin=iz&quierdo label.rightmargin=d&erecho # radiobutton.color=&Color -radiobutton.draftq=Bo&rrador +radiobutton.draftq=B&orrador radiobutton.duplex=&D\u00FAplex -radiobutton.highq=&Alta +radiobutton.highq=Al&ta radiobutton.landscape=Hori&zontal radiobutton.monochrome=&Monocromo radiobutton.normalq=&Normal radiobutton.oneside=Una Ca&ra radiobutton.portrait=&Vertical radiobutton.rangeall=&Todo -radiobutton.rangepages=P\u00E1&ginas +radiobutton.rangepages=P\u00E1gina&s radiobutton.revlandscape=&Horizontal Inverso -radiobutton.revportrait=Vertical Inver&so +radiobutton.revportrait=Vertical I&nverso radiobutton.tumble=Cam&bio de Cara # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties b/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties index a09df3e5846..366aa3ba3e3 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties @@ -29,7 +29,7 @@ dialog.noprintermsg=Service d'impression introuvable. dialog.writeerror=Impossible d'\u00E9crire dans le fichier : # label.info=Infos : -label.jobname=Nom du &travail : +label.jobname=Nom du tra&vail : label.numcopies=Nombre de c&opies : label.priority=P&riorit\u00E9 : label.psname=&Nom : @@ -38,22 +38,22 @@ label.rangeto=A label.size=Tai&lle : label.source=Sour&ce : label.status=Statut : -label.username=Nom &utilisateur : +label.username=Nom ut&ilisateur : label.millimetres=(mm) label.inches=(po) label.topmargin=&haut label.bottommargin=&bas -label.leftmargin=&gauche +label.leftmargin=gauc&he label.rightmargin=&droite # -radiobutton.color=Coule&ur +radiobutton.color=Coul&eur radiobutton.draftq=Broui&llon radiobutton.duplex=&Duplex radiobutton.highq=Ma&x. -radiobutton.landscape=Pay&sage -radiobutton.monochrome=&Monochrome +radiobutton.landscape=Pa&ysage +radiobutton.monochrome=Monoc&hrome radiobutton.normalq=&Normal -radiobutton.oneside=&Un c\u00F4t\u00E9 +radiobutton.oneside=Un &c\u00F4t\u00E9 radiobutton.portrait=&Portrait radiobutton.rangeall=&Tout radiobutton.rangepages=Pag&es @@ -64,7 +64,7 @@ radiobutton.tumble=&T\u00EAte-b\u00EAche # 65 = KeyEvent.VK_A tab.appearance=&Apparence tab.general=&G\u00E9n\u00E9ral -tab.pagesetup=Mi&se en page +tab.pagesetup=&Mise en page # error.pagerange=Plage de pages non valide. Sp\u00E9cifiez les valeurs de nouveau (ex. : 1-3,5,7-10) error.destination=Nom de fichier non valide ; recommencez diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_it.properties b/jdk/src/share/classes/sun/print/resources/serviceui_it.properties index b5f5382216c..e87efcd27bd 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_it.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_it.properties @@ -47,8 +47,8 @@ label.leftmargin=sinis&tro label.rightmargin=&destro # radiobutton.color=&Colore -radiobutton.draftq=&Bozza -radiobutton.duplex=F&ronte retro +radiobutton.draftq=Bo&zza +radiobutton.duplex=&Fronte retro radiobutton.highq=A<a radiobutton.landscape=Orizzonta&le radiobutton.monochrome=Monocrom&atico @@ -62,7 +62,7 @@ radiobutton.revportrait=Vert&icale capovolto radiobutton.tumble=La&to corto # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=&Aspetto +tab.appearance=As&petto tab.general=&Generale tab.pagesetup=Impo&sta pagina # diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties b/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties index 437b432f78e..13d4d72d0ab 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties @@ -31,7 +31,7 @@ dialog.writeerror=N\u00E3o \u00E9 poss\u00EDvel gravar no arquivo: label.info=Informa\u00E7\u00F5es: label.jobname=Nome do &Job: label.numcopies=N\u00FAmer&o de c\u00F3pias: -label.priority=P&rioridade: +label.priority=Pri&oridade: label.psname=&Nome: label.pstype=Tipo: label.rangeto=At\u00E9 @@ -44,27 +44,27 @@ label.inches=(pol) label.topmargin=&superior label.bottommargin=&inferior label.leftmargin=es&querda: -label.rightmargin=di&reita +label.rightmargin=&direita # -radiobutton.color=C&or -radiobutton.draftq=&Rascunho -radiobutton.duplex=&Duplex -radiobutton.highq=&Alta +radiobutton.color=&Cor +radiobutton.draftq=Rascun&ho +radiobutton.duplex=Duple&x +radiobutton.highq=A<a radiobutton.landscape=&Paisagem radiobutton.monochrome=&Monocrom\u00E1tico radiobutton.normalq=&Normal -radiobutton.oneside=Um Lad&o -radiobutton.portrait=&Retrato +radiobutton.oneside=Um La&do +radiobutton.portrait=Re&trato radiobutton.rangeall=T&udo radiobutton.rangepages=&P\u00E1ginas radiobutton.revlandscape=Paisagem I&nvertida -radiobutton.revportrait=Retrato &Invertido +radiobutton.revportrait=Retrato In&vertido radiobutton.tumble=&Virar # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=&Apar\u00EAncia +tab.appearance=Apa&r\u00EAncia tab.general=&Geral -tab.pagesetup=Configura\u00E7\u00E3o de &P\u00E1gina +tab.pagesetup=Con&figura\u00E7\u00E3o da P\u00E1gina # error.pagerange=Faixa de p\u00E1ginas inv\u00E1lida; insira novamente os valores (por exemplo, 1-3,5,7-10) error.destination=Nome de arquivo inv\u00E1lido; tente novamente diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties b/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties index 16f04f634b3..f6475df9f59 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties @@ -17,7 +17,7 @@ button.print=Skriv ut button.properties=&Egenskaper... # checkbox.collate=&Sortera -checkbox.jobsheets=&F\u00F6rs\u00E4ttsblad +checkbox.jobsheets=F&\u00F6rs\u00E4ttsblad checkbox.printtofile=Skriv ut till &fil # dialog.printtitle=Skriv ut @@ -30,13 +30,13 @@ dialog.writeerror=Kan inte skriva till filen: # label.info=Information: label.jobname=&Utskrift: -label.numcopies=Antal &exemplar: +label.numcopies=Antal e&xemplar: label.priority=P&rioritet: label.psname=&Namn: label.pstype=Typ: label.rangeto=Till label.size=Stor&lek: -label.source=K\u00E4l&la: +label.source=&K\u00E4lla: label.status=Status: label.username=A&nv\u00E4ndarnamn: label.millimetres=(mm) @@ -50,7 +50,7 @@ radiobutton.color=&F\u00E4rg radiobutton.draftq=Utka&st radiobutton.duplex=&Dubbelsidig radiobutton.highq=&H\u00F6g -radiobutton.landscape=&Liggande +radiobutton.landscape=Liggan&de radiobutton.monochrome=&Monokrom radiobutton.normalq=&Normal radiobutton.oneside=&Ensidig @@ -62,9 +62,9 @@ radiobutton.revportrait=Omv\u00E4nt st\u00E5en&de radiobutton.tumble=&V\u00E4nd # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=&Format +tab.appearance=Fo&rmat tab.general=&Allm\u00E4nt -tab.pagesetup=Utskrifts&format +tab.pagesetup=&Utskriftsformat # error.pagerange=Ogiltigt sidintervall. Skriv in v\u00E4rdena igen (t ex 1-3,5,7-10) error.destination=Ogiltigt filnamn. F\u00F6rs\u00F6k igen. diff --git a/jdk/src/share/classes/sun/rmi/registry/resources/rmiregistry_de.properties b/jdk/src/share/classes/sun/rmi/registry/resources/rmiregistry_de.properties index 51068bff8de..ae2c6bf5cd1 100644 --- a/jdk/src/share/classes/sun/rmi/registry/resources/rmiregistry_de.properties +++ b/jdk/src/share/classes/sun/rmi/registry/resources/rmiregistry_de.properties @@ -24,5 +24,5 @@ # questions. # -rmiregistry.usage=Verwendung: {0} \n\nwobei die Folgendes beinhalten:\n -J Argument an den Java-Interpreter \u00FCbergeben +rmiregistry.usage=Verwendung: {0} \n\nwobei die Folgendes beinhalten:\n -J Argument an den Java-Interpreter \u00FCbergeben rmiregistry.port.badnumber=Portargument {0} ist keine Zahl. diff --git a/jdk/src/share/classes/sun/rmi/server/resources/rmid_ko.properties b/jdk/src/share/classes/sun/rmi/server/resources/rmid_ko.properties index e744d9cc433..ea728a6dedb 100644 --- a/jdk/src/share/classes/sun/rmi/server/resources/rmid_ko.properties +++ b/jdk/src/share/classes/sun/rmi/server/resources/rmid_ko.properties @@ -87,7 +87,7 @@ rmid.restart.group.warning=\nrmid: (\uACBD\uACE0) \uADF8\uB8F9 \uC7AC\uC2DC\uC79 rmid.restart.service.warning=\nrmid: (\uACBD\uACE0) \uC11C\uBE44\uC2A4 \uC7AC\uC2DC\uC791\uC73C\uB85C \uC778\uD574 \uBC1C\uC0DD\uD55C \uC624\uB958: # "rmid" should not be translated -rmid.log.update.warning=\nrmid: (\uACBD\uACE0) \uB85C\uADF8 \uAC31\uC2E0\uC73C\uB85C \uC778\uD574 \uBC1C\uC0DD\uD55C \uC624\uB958: +rmid.log.update.warning=\nrmid: (\uACBD\uACE0) \uB85C\uADF8 \uC5C5\uB370\uC774\uD2B8\uB85C \uC778\uD574 \uBC1C\uC0DD\uD55C \uC624\uB958: # "rmid" should not be translated rmid.log.snapshot.warning=\nrmid: (\uC2EC\uAC01) \uB85C\uADF8 \uC2A4\uB0C5\uC0F7\uC73C\uB85C \uC778\uD574 \uBC1C\uC0DD\uD55C \uC624\uB958: diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java index d5048af0bf9..397a859bcbe 100644 --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java @@ -57,49 +57,51 @@ public class Resources_ja extends java.util.ListResourceBundle { {".jarsigner.verify.options.jar.file.alias.", " jarsigner -verify [options] jar-file [alias...]"}, {".keystore.url.keystore.location", - "[-keystore ] \u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u4F4D\u7F6E"}, + "[-keystore ] \u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u4F4D\u7F6E"}, {".storepass.password.password.for.keystore.integrity", - "[-storepass ] \u30AD\u30FC\u30B9\u30C8\u30A2\u6574\u5408\u6027\u306E\u305F\u3081\u306E\u30D1\u30B9\u30EF\u30FC\u30C9"}, + "[-storepass ] \u30AD\u30FC\u30B9\u30C8\u30A2\u6574\u5408\u6027\u306E\u305F\u3081\u306E\u30D1\u30B9\u30EF\u30FC\u30C9"}, {".storetype.type.keystore.type", - "[-storetype ] \u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u578B"}, + "[-storetype ] \u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u578B"}, {".keypass.password.password.for.private.key.if.different.", - "[-keypass ] \u79D8\u5BC6\u9375\u306E\u30D1\u30B9\u30EF\u30FC\u30C9(\u7570\u306A\u308B\u5834\u5408)"}, + "[-keypass ] \u79D8\u5BC6\u9375\u306E\u30D1\u30B9\u30EF\u30FC\u30C9(\u7570\u306A\u308B\u5834\u5408)"}, {".certchain.file.name.of.alternative.certchain.file", "[-certchain ] \u4EE3\u66FF\u8A3C\u660E\u66F8\u30C1\u30A7\u30FC\u30F3\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D"}, {".sigfile.file.name.of.SF.DSA.file", - "[-sigfile ] .SF/.DSA\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D"}, + "[-sigfile ] .SF/.DSA\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D"}, {".signedjar.file.name.of.signed.JAR.file", - "[-signedjar ] \u7F72\u540D\u4ED8\u304DJAR\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D"}, + "[-signedjar ] \u7F72\u540D\u4ED8\u304DJAR\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D"}, {".digestalg.algorithm.name.of.digest.algorithm", - "[-digestalg ] \u30C0\u30A4\u30B8\u30A7\u30B9\u30C8\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u306E\u540D\u524D"}, + "[-digestalg ] \u30C0\u30A4\u30B8\u30A7\u30B9\u30C8\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u306E\u540D\u524D"}, {".sigalg.algorithm.name.of.signature.algorithm", - "[-sigalg ] \u30B7\u30B0\u30CD\u30C1\u30E3\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u306E\u540D\u524D"}, + "[-sigalg ] \u30B7\u30B0\u30CD\u30C1\u30E3\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u306E\u540D\u524D"}, {".verify.verify.a.signed.JAR.file", - "[-verify] \u7F72\u540D\u4ED8\u304DJAR\u30D5\u30A1\u30A4\u30EB\u306E\u691C\u8A3C"}, + "[-verify] \u7F72\u540D\u4ED8\u304DJAR\u30D5\u30A1\u30A4\u30EB\u306E\u691C\u8A3C"}, {".verbose.suboptions.verbose.output.when.signing.verifying.", "[-verbose[:suboptions]] \u7F72\u540D/\u691C\u8A3C\u6642\u306E\u8A73\u7D30\u51FA\u529B\u3002"}, {".suboptions.can.be.all.grouped.or.summary", " \u30B5\u30D6\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u3057\u3066\u3001\u3059\u3079\u3066\u3001\u30B0\u30EB\u30FC\u30D7\u307E\u305F\u306F\u30B5\u30DE\u30EA\u30FC\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059"}, {".certs.display.certificates.when.verbose.and.verifying", - "[-certs] \u8A73\u7D30\u51FA\u529B\u304A\u3088\u3073\u691C\u8A3C\u6642\u306B\u8A3C\u660E\u66F8\u3092\u8868\u793A"}, + "[-certs] \u8A73\u7D30\u51FA\u529B\u304A\u3088\u3073\u691C\u8A3C\u6642\u306B\u8A3C\u660E\u66F8\u3092\u8868\u793A"}, {".tsa.url.location.of.the.Timestamping.Authority", - "[-tsa ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306E\u5834\u6240"}, + "[-tsa ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306E\u5834\u6240"}, {".tsacert.alias.public.key.certificate.for.Timestamping.Authority", - "[-tsacert ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306E\u516C\u958B\u9375\u8A3C\u660E\u66F8"}, + "[-tsacert ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306E\u516C\u958B\u9375\u8A3C\u660E\u66F8"}, + {".tsapolicyid.tsapolicyid.for.Timestamping.Authority", + "[-tsapolicyid ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306ETSAPolicyID"}, {".altsigner.class.class.name.of.an.alternative.signing.mechanism", - "[-altsigner ] \u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u30AF\u30E9\u30B9\u540D"}, + "[-altsigner ] \u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u30AF\u30E9\u30B9\u540D"}, {".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism", - "[-altsignerpath ]\u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u4F4D\u7F6E"}, + "[-altsignerpath ] \u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u5834\u6240"}, {".internalsf.include.the.SF.file.inside.the.signature.block", - "[-internalsf] \u30B7\u30B0\u30CD\u30C1\u30E3\u30FB\u30D6\u30ED\u30C3\u30AF\u306B.SF\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u308B"}, + "[-internalsf] \u30B7\u30B0\u30CD\u30C1\u30E3\u30FB\u30D6\u30ED\u30C3\u30AF\u306B.SF\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u308B"}, {".sectionsonly.don.t.compute.hash.of.entire.manifest", - "[-sectionsonly] \u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5168\u4F53\u306E\u30CF\u30C3\u30B7\u30E5\u306F\u8A08\u7B97\u3057\u306A\u3044"}, + "[-sectionsonly] \u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5168\u4F53\u306E\u30CF\u30C3\u30B7\u30E5\u306F\u8A08\u7B97\u3057\u306A\u3044"}, {".protected.keystore.has.protected.authentication.path", - "[-protected] \u30AD\u30FC\u30B9\u30C8\u30A2\u306B\u306F\u4FDD\u8B77\u3055\u308C\u305F\u8A8D\u8A3C\u30D1\u30B9\u304C\u3042\u308B"}, + "[-protected] \u30AD\u30FC\u30B9\u30C8\u30A2\u306B\u306F\u4FDD\u8B77\u3055\u308C\u305F\u8A8D\u8A3C\u30D1\u30B9\u304C\u3042\u308B"}, {".providerName.name.provider.name", - "[-providerName ] \u30D7\u30ED\u30D0\u30A4\u30C0\u540D"}, + "[-providerName ] \u30D7\u30ED\u30D0\u30A4\u30C0\u540D"}, {".providerClass.class.name.of.cryptographic.service.provider.s", - "[-providerClass \u6697\u53F7\u5316\u30B5\u30FC\u30D3\u30B9\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u306E\u540D\u524D"}, + "[-providerClass \u6697\u53F7\u5316\u30B5\u30FC\u30D3\u30B9\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u306E\u540D\u524D"}, {".providerArg.arg.master.class.file.and.constructor.argument", " [-providerArg ]] ... \u30DE\u30B9\u30BF\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3068\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u306E\u5F15\u6570"}, {".strict.treat.warnings.as.errors", diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java index e3a34a7f59d..ee2334d9118 100644 --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java @@ -71,9 +71,9 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {".signedjar.file.name.of.signed.JAR.file", "[-signedjar <\u6587\u4EF6>] \u5DF2\u7B7E\u540D\u7684 JAR \u6587\u4EF6\u7684\u540D\u79F0"}, {".digestalg.algorithm.name.of.digest.algorithm", - "[-digestalg <\u7B97\u6CD5>] \u6458\u8981\u7B97\u6CD5\u7684\u540D\u79F0"}, + "[-digestalg <\u7B97\u6CD5>] \u6458\u8981\u7B97\u6CD5\u7684\u540D\u79F0"}, {".sigalg.algorithm.name.of.signature.algorithm", - "[-sigalg <\u7B97\u6CD5>] \u7B7E\u540D\u7B97\u6CD5\u7684\u540D\u79F0"}, + "[-sigalg <\u7B97\u6CD5>] \u7B7E\u540D\u7B97\u6CD5\u7684\u540D\u79F0"}, {".verify.verify.a.signed.JAR.file", "[-verify] \u9A8C\u8BC1\u5DF2\u7B7E\u540D\u7684 JAR \u6587\u4EF6"}, {".verbose.suboptions.verbose.output.when.signing.verifying.", @@ -86,6 +86,8 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "[-tsa ] \u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684\u4F4D\u7F6E"}, {".tsacert.alias.public.key.certificate.for.Timestamping.Authority", "[-tsacert <\u522B\u540D>] \u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684\u516C\u5171\u5BC6\u94A5\u8BC1\u4E66"}, + {".tsapolicyid.tsapolicyid.for.Timestamping.Authority", + "[-tsapolicyid ] \u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684 TSAPolicyID"}, {".altsigner.class.class.name.of.an.alternative.signing.mechanism", "[-altsigner <\u7C7B>] \u66FF\u4EE3\u7684\u7B7E\u540D\u673A\u5236\u7684\u7C7B\u540D"}, {".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism", @@ -132,7 +134,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {".Signature.related.entries.","(\u4E0E\u7B7E\u540D\u76F8\u5173\u7684\u6761\u76EE)"}, {".Unsigned.entries.", "(\u672A\u7B7E\u540D\u6761\u76EE)"}, {"jar.is.unsigned.signatures.missing.or.not.parsable.", - "jar \u672A\u7B7E\u540D\u3002(\u7F3A\u5C11\u7B7E\u540D\u6216\u65E0\u6CD5\u5BF9\u7B7E\u540D\u8FDB\u884C\u8BED\u6CD5\u5206\u6790)"}, + "jar \u672A\u7B7E\u540D\u3002(\u7F3A\u5C11\u7B7E\u540D\u6216\u65E0\u6CD5\u89E3\u6790\u7B7E\u540D)"}, {"jar.verified.", "jar \u5DF2\u9A8C\u8BC1\u3002"}, {"jarsigner.", "jarsigner: "}, {"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.", diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java index 087362c7cec..623bf76be44 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java @@ -40,8 +40,7 @@ public class Resources_de extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Option]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Optionen:"}, {"Use.keytool.help.for.all.available.commands", "\"keytool -help\" f\u00FCr alle verf\u00FCgbaren Befehle verwenden"}, @@ -61,7 +60,6 @@ public class Resources_de extends java.util.ListResourceBundle { "Exportiert ein Zertifikat"}, //-exportcert {"Generates.a.key.pair", "Generiert ein Schl\u00FCsselpaar"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "Generiert einen Secret Key"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_de extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "Zertifizierungsanforderung in Datei <{0}> gespeichert"}, {"Submit.this.to.your.CA", "Leiten Sie dies an die CA weiter"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "Wenn kein Alias angegeben ist, d\u00FCrfen destalias, srckeypass und destkeypass nicht angegeben werden"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "Wenn kein Alias angegeben ist, d\u00FCrfen destalias und srckeypass nicht angegeben werden"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "Der Ziel-Keystore pkcs12 hat unterschiedliche Kennw\u00F6rter f\u00FCr storepass und keypass. Wiederholen Sie den Vorgang, indem Sie -destkeypass angeben."}, {"Certificate.stored.in.file.filename.", "Zertifikat in Datei <{0}> gespeichert"}, {"Certificate.reply.was.installed.in.keystore", @@ -324,7 +324,7 @@ public class Resources_de extends java.util.ListResourceBundle { {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", "M\u00F6chten Sie es trotzdem zu Ihrem eigenen Keystore hinzuf\u00FCgen? [Nein]: "}, {"Trust.this.certificate.no.", "Diesem Zertifikat vertrauen? [Nein]: "}, - {"YES", "Ja"}, + {"YES", "JA"}, {"New.prompt.", "Neues {0}: "}, {"Passwords.must.differ", "Kennw\u00F6rter m\u00FCssen sich unterscheiden"}, {"Re.enter.new.prompt.", "Neues {0} erneut eingeben: "}, @@ -361,7 +361,7 @@ public class Resources_de extends java.util.ListResourceBundle { "Alias <{0}> verweist auf einen Eintragstyp, der kein Private Key-Eintrag ist. Der Befehl -keyclone unterst\u00FCtzt nur das Clonen von Private Key-Eintr\u00E4gen"}, {".WARNING.WARNING.WARNING.", - "***************** Warnung Warnung Warnung *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "Signaturgeber #%d:"}, {"Timestamp.", "Zeitstempel:"}, {"Signature.", "Signatur:"}, @@ -386,7 +386,7 @@ public class Resources_de extends java.util.ListResourceBundle { "Zertifikat der obersten Ebene in Antwort:\n"}, {".is.not.trusted.", "... ist nicht vertrauensw\u00FCrdig. "}, {"Install.reply.anyway.no.", "Antwort trotzdem installieren? [Nein]: "}, - {"NO", "Nein"}, + {"NO", "NEIN"}, {"Public.keys.in.reply.and.keystore.don.t.match", "Public Keys in Antwort und Keystore stimmen nicht \u00FCberein"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_de extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Geben Sie -keysize zum Erstellen eines Secret Keys an"}, + {"verified.by.s.in.s", "Gepr\u00FCft von %s in %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "WARNUNG: Nicht gepr\u00FCft. Stellen Sie sicher, dass -keystore korrekt ist."}, + {"Extensions.", "Erweiterungen: "}, {".Empty.value.", "(Leerer Wert)"}, {"Extension.Request.", "Erweiterungsanforderung:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java index 942c0ecf086..ac12dd0c027 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java @@ -40,8 +40,7 @@ public class Resources_es extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Opci\u00F3n]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Opciones:"}, {"Use.keytool.help.for.all.available.commands", "Utilice\"keytool -help\" para todos los comandos disponibles"}, @@ -61,7 +60,6 @@ public class Resources_es extends java.util.ListResourceBundle { "Exporta el certificado"}, //-exportcert {"Generates.a.key.pair", "Genera un par de claves"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "Genera un clave secreta"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_es extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "Solicitud de certificaci\u00F3n almacenada en el archivo <{0}>"}, {"Submit.this.to.your.CA", "Enviar a la CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "si no se especifica el alias, no se puede especificar destalias, srckeypass ni destkeypass"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "si no se especifica el alias, no se debe especificar destalias ni srckeypass"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "El almac\u00E9n de claves pkcs12 de destino tiene storepass y keypass diferentes. Vuelva a intentarlo con -destkeypass especificado."}, {"Certificate.stored.in.file.filename.", "Certificado almacenado en el archivo <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -324,7 +324,7 @@ public class Resources_es extends java.util.ListResourceBundle { {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", "\u00BFA\u00FAn desea agregarlo a su propio almac\u00E9n de claves? [no]: "}, {"Trust.this.certificate.no.", "\u00BFConfiar en este certificado? [no]: "}, - {"YES", "S\u00ED"}, + {"YES", "S\u00CD"}, {"New.prompt.", "Nuevo {0}: "}, {"Passwords.must.differ", "Las contrase\u00F1as deben ser distintas"}, {"Re.enter.new.prompt.", "Vuelva a escribir el nuevo {0}: "}, @@ -361,7 +361,7 @@ public class Resources_es extends java.util.ListResourceBundle { "El alias <{0}> hace referencia a un tipo de entrada que no es una clave privada. El comando -keyclone s\u00F3lo permite la clonaci\u00F3n de entradas de claves privadas"}, {".WARNING.WARNING.WARNING.", - "***************** Advertencia Advertencia Advertencia *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "#%d de Firmante:"}, {"Timestamp.", "Registro de Hora:"}, {"Signature.", "Firma:"}, @@ -386,7 +386,7 @@ public class Resources_es extends java.util.ListResourceBundle { "Certificado de nivel superior en la respuesta:\n"}, {".is.not.trusted.", "... no es de confianza. "}, {"Install.reply.anyway.no.", "\u00BFInstalar respuesta de todos modos? [no]: "}, - {"NO", "No"}, + {"NO", "NO"}, {"Public.keys.in.reply.and.keystore.don.t.match", "Las claves p\u00FAblicas en la respuesta y en el almac\u00E9n de claves no coinciden"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_es extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Proporcione el valor de -keysize para la generaci\u00F3n de claves secretas"}, + {"verified.by.s.in.s", "Verificado por %s en %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "ADVERTENCIA: no se ha verificado. Aseg\u00FArese de que el valor de -keystore es correcto."}, + {"Extensions.", "Extensiones: "}, {".Empty.value.", "(Valor vac\u00EDo)"}, {"Extension.Request.", "Solicitud de Extensi\u00F3n:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java index 2ae14764d79..aaa7c2e60d5 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java @@ -40,8 +40,7 @@ public class Resources_fr extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Option]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Options :"}, {"Use.keytool.help.for.all.available.commands", "Utiliser \"keytool -help\" pour toutes les commandes disponibles"}, @@ -61,7 +60,6 @@ public class Resources_fr extends java.util.ListResourceBundle { "Exporte le certificat"}, //-exportcert {"Generates.a.key.pair", "G\u00E9n\u00E8re une paire de cl\u00E9s"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "G\u00E9n\u00E8re une cl\u00E9 secr\u00E8te"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_fr extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "Demande de certification stock\u00E9e dans le fichier <{0}>"}, {"Submit.this.to.your.CA", "Soumettre \u00E0 votre CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "si l'alias n'est pas sp\u00E9cifi\u00E9, destalias, srckeypass et destkeypass ne doivent pas \u00EAtre sp\u00E9cifi\u00E9s"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "si l'alias n'est pas sp\u00E9cifi\u00E9, destalias et srckeypass ne doivent pas \u00EAtre sp\u00E9cifi\u00E9s"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "Le fichier de cl\u00E9s pkcs12 de destination contient un mot de passe de fichier de cl\u00E9s et un mot de passe de cl\u00E9 diff\u00E9rents. R\u00E9essayez en sp\u00E9cifiant -destkeypass."}, {"Certificate.stored.in.file.filename.", "Certificat stock\u00E9 dans le fichier <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -324,7 +324,7 @@ public class Resources_fr extends java.util.ListResourceBundle { {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", "Voulez-vous toujours l'ajouter \u00E0 votre fichier de cl\u00E9s ? [non] : "}, {"Trust.this.certificate.no.", "Faire confiance \u00E0 ce certificat ? [non] : "}, - {"YES", "Oui"}, + {"YES", "OUI"}, {"New.prompt.", "Nouveau {0} : "}, {"Passwords.must.differ", "Les mots de passe doivent diff\u00E9rer"}, {"Re.enter.new.prompt.", "Indiquez encore le nouveau {0} : "}, @@ -361,7 +361,7 @@ public class Resources_fr extends java.util.ListResourceBundle { "L''entr\u00E9e \u00E0 laquelle l''alias <{0}> fait r\u00E9f\u00E9rence n''est pas une entr\u00E9e de type cl\u00E9 priv\u00E9e. La commande -keyclone prend uniquement en charge le clonage des cl\u00E9s priv\u00E9es"}, {".WARNING.WARNING.WARNING.", - "***************** Avertissement Avertissement Avertissement *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "Signataire n\u00B0%d :"}, {"Timestamp.", "Horodatage :"}, {"Signature.", "Signature :"}, @@ -386,7 +386,7 @@ public class Resources_fr extends java.util.ListResourceBundle { "Certificat de niveau sup\u00E9rieur dans la r\u00E9ponse :\n"}, {".is.not.trusted.", "... non s\u00E9curis\u00E9. "}, {"Install.reply.anyway.no.", "Installer la r\u00E9ponse quand m\u00EAme ? [non] : "}, - {"NO", "Non"}, + {"NO", "NON"}, {"Public.keys.in.reply.and.keystore.don.t.match", "Les cl\u00E9s publiques de la r\u00E9ponse et du fichier de cl\u00E9s ne concordent pas"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_fr extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Indiquez -keysize pour la g\u00E9n\u00E9ration de la cl\u00E9 secr\u00E8te"}, + {"verified.by.s.in.s", "V\u00E9rifi\u00E9 par %s dans %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "AVERTISSEMENT : non v\u00E9rifi\u00E9. Assurez-vous que -keystore est correct."}, + {"Extensions.", "Extensions\u00A0: "}, {".Empty.value.", "(Valeur vide)"}, {"Extension.Request.", "Demande d'extension :"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java index 0557fdc0943..a47c97fab2a 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java @@ -40,8 +40,7 @@ public class Resources_it extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Opzione]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Opzioni:"}, {"Use.keytool.help.for.all.available.commands", "Utilizzare \"keytool -help\" per visualizzare tutti i comandi disponibili"}, @@ -61,7 +60,6 @@ public class Resources_it extends java.util.ListResourceBundle { "Esporta il certificato"}, //-exportcert {"Generates.a.key.pair", "Genera una coppia di chiavi"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "Genera una chiave segreta"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_it extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "La richiesta di certificazione \u00E8 memorizzata nel file <{0}>"}, {"Submit.this.to.your.CA", "Sottomettere alla propria CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "Se l'alias non \u00E8 specificato, destalias, srckeypass e destkeypass non dovranno essere specificati"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "Se l'alias non \u00E8 specificato, destalias e srckeypass non dovranno essere specificati"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "Keystore pkcs12 di destinazione con storepass e keypass differenti. Riprovare con -destkeypass specificato."}, {"Certificate.stored.in.file.filename.", "Il certificato \u00E8 memorizzato nel file <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -361,7 +361,7 @@ public class Resources_it extends java.util.ListResourceBundle { "L''alias <{0}> fa riferimento a un tipo di voce che non \u00E8 una voce di chiave privata. Il comando -keyclone supporta solo la copia delle voci di chiave private."}, {".WARNING.WARNING.WARNING.", - "***************** Avvertenza Avvertenza Avvertenza *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "Firmatario #%d:"}, {"Timestamp.", "Indicatore orario:"}, {"Signature.", "Firma:"}, @@ -386,7 +386,7 @@ public class Resources_it extends java.util.ListResourceBundle { "Certificato di primo livello nella risposta:\n"}, {".is.not.trusted.", "...non \u00E8 considerato sicuro. "}, {"Install.reply.anyway.no.", "Installare la risposta? [no]: "}, - {"NO", "No"}, + {"NO", "NO"}, {"Public.keys.in.reply.and.keystore.don.t.match", "Le chiavi pubbliche nella risposta e nel keystore non corrispondono"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_it extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Specificare il valore -keysize per la generazione della chiave segreta"}, + {"verified.by.s.in.s", "Verificato da %s in %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "AVVERTENZA: non verificato. Assicurarsi che -keystore sia corretto."}, + {"Extensions.", "Estensioni: "}, {".Empty.value.", "(valore vuoto)"}, {"Extension.Request.", "Richiesta di estensione:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java index 9b6e6be1cf6..b40b046f06c 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java @@ -40,8 +40,7 @@ public class Resources_ja extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [\u30AA\u30D7\u30B7\u30E7\u30F3]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "\u30AA\u30D7\u30B7\u30E7\u30F3:"}, {"Use.keytool.help.for.all.available.commands", "\u4F7F\u7528\u53EF\u80FD\u306A\u3059\u3079\u3066\u306E\u30B3\u30DE\u30F3\u30C9\u306B\u3064\u3044\u3066\u306F\"keytool -help\"\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044"}, @@ -61,7 +60,6 @@ public class Resources_ja extends java.util.ListResourceBundle { "\u8A3C\u660E\u66F8\u3092\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3057\u307E\u3059"}, //-exportcert {"Generates.a.key.pair", "\u9375\u30DA\u30A2\u3092\u751F\u6210\u3057\u307E\u3059"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "\u79D8\u5BC6\u9375\u3092\u751F\u6210\u3057\u307E\u3059"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_ja extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "\u8A3C\u660E\u66F8\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u30D5\u30A1\u30A4\u30EB<{0}>\u306B\u4FDD\u5B58\u3055\u308C\u307E\u3057\u305F"}, {"Submit.this.to.your.CA", "\u3053\u308C\u3092CA\u306B\u63D0\u51FA\u3057\u3066\u304F\u3060\u3055\u3044"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "\u5225\u540D\u3092\u6307\u5B9A\u3057\u306A\u3044\u5834\u5408\u3001\u51FA\u529B\u5148\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u5225\u540D\u3001\u30BD\u30FC\u30B9\u30FB\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u304A\u3088\u3073\u51FA\u529B\u5148\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "\u5225\u540D\u3092\u6307\u5B9A\u3057\u306A\u3044\u5834\u5408\u3001\u51FA\u529B\u5148\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u5225\u540D\u304A\u3088\u3073\u30BD\u30FC\u30B9\u30FB\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "\u51FA\u529B\u5148pkcs12\u30AD\u30FC\u30B9\u30C8\u30A2\u306B\u3001\u7570\u306A\u308Bstorepass\u304A\u3088\u3073keypass\u304C\u3042\u308A\u307E\u3059\u3002-destkeypass\u3092\u6307\u5B9A\u3057\u3066\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002"}, {"Certificate.stored.in.file.filename.", "\u8A3C\u660E\u66F8\u304C\u30D5\u30A1\u30A4\u30EB<{0}>\u306B\u4FDD\u5B58\u3055\u308C\u307E\u3057\u305F"}, {"Certificate.reply.was.installed.in.keystore", @@ -361,7 +361,7 @@ public class Resources_ja extends java.util.ListResourceBundle { "\u5225\u540D<{0}>\u304C\u53C2\u7167\u3057\u3066\u3044\u308B\u30A8\u30F3\u30C8\u30EA\u30FB\u30BF\u30A4\u30D7\u306F\u79D8\u5BC6\u9375\u30A8\u30F3\u30C8\u30EA\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002-keyclone\u30B3\u30DE\u30F3\u30C9\u306F\u79D8\u5BC6\u9375\u30A8\u30F3\u30C8\u30EA\u306E\u30AF\u30ED\u30FC\u30F3\u4F5C\u6210\u306E\u307F\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059"}, {".WARNING.WARNING.WARNING.", - "*****************\u8B66\u544A \u8B66\u544A \u8B66\u544A*****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "\u7F72\u540D\u8005\u756A\u53F7%d:"}, {"Timestamp.", "\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7:"}, {"Signature.", "\u7F72\u540D:"}, @@ -400,6 +400,10 @@ public class Resources_ja extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "\u79D8\u5BC6\u9375\u306E\u751F\u6210\u6642\u306B\u306F -keysize\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"}, + {"verified.by.s.in.s", "%s(%s\u5185)\u306B\u3088\u308A\u691C\u8A3C\u3055\u308C\u307E\u3057\u305F"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "\u8B66\u544A: \u691C\u8A3C\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002-keystore\u304C\u6B63\u3057\u3044\u3053\u3068\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002"}, + {"Extensions.", "\u62E1\u5F35: "}, {".Empty.value.", "(\u7A7A\u306E\u5024)"}, {"Extension.Request.", "\u62E1\u5F35\u30EA\u30AF\u30A8\u30B9\u30C8:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java index 9f3f70f5024..6140bc722c0 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java @@ -40,8 +40,7 @@ public class Resources_ko extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [\uC635\uC158]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "\uC635\uC158:"}, {"Use.keytool.help.for.all.available.commands", "\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBAA8\uB4E0 \uBA85\uB839\uC5D0 \"keytool -help\" \uC0AC\uC6A9"}, @@ -61,7 +60,6 @@ public class Resources_ko extends java.util.ListResourceBundle { "\uC778\uC99D\uC11C\uB97C \uC775\uC2A4\uD3EC\uD2B8\uD569\uB2C8\uB2E4."}, //-exportcert {"Generates.a.key.pair", "\uD0A4 \uC30D\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4."}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "\uBCF4\uC548 \uD0A4\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4."}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -174,7 +172,7 @@ public class Resources_ko extends java.util.ListResourceBundle { "\uCCA0\uD68C\uD560 \uC778\uC99D\uC11C\uC758 \uC77C\uB828 ID"}, //-id // keytool: Running part {"keytool.error.", "keytool \uC624\uB958: "}, - {"Illegal.option.", "\uC798\uBABB\uB41C \uC635\uC158: "}, + {"Illegal.option.", "\uC798\uBABB\uB41C \uC635\uC158: "}, {"Illegal.value.", "\uC798\uBABB\uB41C \uAC12: "}, {"Unknown.password.type.", "\uC54C \uC218 \uC5C6\uB294 \uBE44\uBC00\uBC88\uD638 \uC720\uD615: "}, {"Cannot.find.environment.variable.", @@ -244,8 +242,10 @@ public class Resources_ko extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "\uC778\uC99D \uC694\uCCAD\uC774 <{0}> \uD30C\uC77C\uC5D0 \uC800\uC7A5\uB418\uC5C8\uC2B5\uB2C8\uB2E4."}, {"Submit.this.to.your.CA", "CA\uC5D0\uAC8C \uC81C\uCD9C\uD558\uC2ED\uC2DC\uC624."}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "\uBCC4\uCE6D\uC744 \uC9C0\uC815\uD558\uC9C0 \uC54A\uC740 \uACBD\uC6B0 destalias, srckeypass \uBC0F destkeypass\uB97C \uC9C0\uC815\uD558\uC9C0 \uC54A\uC544\uC57C \uD569\uB2C8\uB2E4."}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "\uBCC4\uCE6D\uC744 \uC9C0\uC815\uD558\uC9C0 \uC54A\uC740 \uACBD\uC6B0 destalias \uBC0F srckeypass\uB97C \uC9C0\uC815\uD558\uC9C0 \uC54A\uC544\uC57C \uD569\uB2C8\uB2E4."}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "\uB300\uC0C1 pkcs12 \uD0A4 \uC800\uC7A5\uC18C\uC5D0 \uB2E4\uB978 storepass \uBC0F keypass\uAC00 \uC788\uC2B5\uB2C8\uB2E4. \uC9C0\uC815\uB41C -destkeypass\uB85C \uC7AC\uC2DC\uB3C4\uD558\uC2ED\uC2DC\uC624."}, {"Certificate.stored.in.file.filename.", "\uC778\uC99D\uC11C\uAC00 <{0}> \uD30C\uC77C\uC5D0 \uC800\uC7A5\uB418\uC5C8\uC2B5\uB2C8\uB2E4."}, {"Certificate.reply.was.installed.in.keystore", @@ -361,7 +361,7 @@ public class Resources_ko extends java.util.ListResourceBundle { "<{0}> \uBCC4\uCE6D\uC740 \uC804\uC6A9 \uD0A4 \uD56D\uBAA9\uC774 \uC544\uB2CC \uD56D\uBAA9 \uC720\uD615\uC744 \uCC38\uC870\uD569\uB2C8\uB2E4. -keyclone \uBA85\uB839\uC740 \uC804\uC6A9 \uD0A4 \uD56D\uBAA9\uC758 \uBCF5\uC81C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4."}, {".WARNING.WARNING.WARNING.", - "***************** \uACBD\uACE0 \uACBD\uACE0 \uACBD\uACE0 *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "\uC11C\uBA85\uC790 #%d:"}, {"Timestamp.", "\uC2DC\uAC04 \uAE30\uB85D:"}, {"Signature.", "\uC11C\uBA85:"}, @@ -400,6 +400,10 @@ public class Resources_ko extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "\uBCF4\uC548 \uD0A4\uB97C \uC0DD\uC131\uD558\uB824\uBA74 -keysize\uB97C \uC81C\uACF5\uD558\uC2ED\uC2DC\uC624."}, + {"verified.by.s.in.s", "%s(%s)\uC5D0 \uC758\uD574 \uD655\uC778\uB428"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "\uACBD\uACE0: \uD655\uC778\uB418\uC9C0 \uC54A\uC74C. -keystore\uAC00 \uC62C\uBC14\uB978\uC9C0 \uD655\uC778\uD558\uC2ED\uC2DC\uC624."}, + {"Extensions.", "\uD655\uC7A5: "}, {".Empty.value.", "(\uBE44\uC5B4 \uC788\uB294 \uAC12)"}, {"Extension.Request.", "\uD655\uC7A5 \uC694\uCCAD:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java index 50b4d26067e..0080342146b 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java @@ -40,8 +40,7 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Op\u00E7\u00E3o]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Op\u00E7\u00F5es:"}, {"Use.keytool.help.for.all.available.commands", "Use \"keytool -help\" para todos os comandos dispon\u00EDveis"}, @@ -61,9 +60,8 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { "Exporta o certificado"}, //-exportcert {"Generates.a.key.pair", "Gera um par de chaves"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", - "Gera uma chave Secreta"}, //-genseckey + "Gera uma chave secreta"}, //-genseckey {"Generates.certificate.from.a.certificate.request", "Gera um certificado de uma solicita\u00E7\u00E3o de certificado"}, //-gencert {"Generates.CRL", "Gera CRL"}, //-gencrl @@ -244,8 +242,10 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "Solicita\u00E7\u00E3o de certificado armazenada no arquivo <{0}>"}, {"Submit.this.to.your.CA", "Submeter \u00E0 CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "se o alias n\u00E3o estiver especificado, destalias, srckeypass e destkeypass n\u00E3o dever\u00E3o ser especificados"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "se o alias n\u00E3o estiver especificado, destalias e srckeypass n\u00E3o dever\u00E3o ser especificados"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "O armazenamento de chaves pkcs12 de destino tem storepass e keypass diferentes. Tente novamente especificando -destkeypass."}, {"Certificate.stored.in.file.filename.", "Certificado armazenado no arquivo <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -298,14 +298,14 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { {"Entry.type.type.", "Tipo de entrada: {0}"}, {"Certificate.chain.length.", "Comprimento da cadeia de certificados: "}, {"Certificate.i.1.", "Certificado[{0,number,integer}]:"}, - {"Certificate.fingerprint.SHA1.", "Fingerprint (MD5) do certificado: "}, + {"Certificate.fingerprint.SHA1.", "Fingerprint (SHA1) do certificado: "}, {"Keystore.type.", "Tipo de \u00E1rea de armazenamento de chaves: "}, {"Keystore.provider.", "Fornecedor da \u00E1rea de armazenamento de chaves: "}, {"Your.keystore.contains.keyStore.size.entry", "Sua \u00E1rea de armazenamento de chaves cont\u00E9m {0,number,integer} entrada"}, {"Your.keystore.contains.keyStore.size.entries", "Sua \u00E1rea de armazenamento de chaves cont\u00E9m {0,number,integer} entradas"}, - {"Failed.to.parse.input", "Falha durante o parse da entrada"}, + {"Failed.to.parse.input", "Falha durante o parsing da entrada"}, {"Empty.input", "Entrada vazia"}, {"Not.X.509.certificate", "N\u00E3o \u00E9 um certificado X.509"}, {"alias.has.no.public.key", "{0} n\u00E3o tem chave p\u00FAblica"}, @@ -324,7 +324,7 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", "Ainda deseja adicion\u00E1-lo \u00E0 sua \u00E1rea de armazenamento de chaves? [n\u00E3o]: "}, {"Trust.this.certificate.no.", "Confiar neste certificado? [n\u00E3o]: "}, - {"YES", "Sim"}, + {"YES", "SIM"}, {"New.prompt.", "Nova {0}: "}, {"Passwords.must.differ", "As senhas devem ser diferentes"}, {"Re.enter.new.prompt.", "Informe novamente a nova {0}: "}, @@ -361,7 +361,7 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { "O alias <{0}> faz refer\u00EAncia a um tipo de entrada que n\u00E3o \u00E9 uma entrada de chave privada. O comando -keyclone oferece suporte somente \u00E0 clonagem de entradas de chave privada"}, {".WARNING.WARNING.WARNING.", - "***************** Advert\u00EAncia Advert\u00EAncia Advert\u00EAncia *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "Signat\u00E1rio #%d:"}, {"Timestamp.", "Timestamp:"}, {"Signature.", "Assinatura:"}, @@ -386,7 +386,7 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { "Certificado de n\u00EDvel superior na resposta:\n"}, {".is.not.trusted.", "... n\u00E3o \u00E9 confi\u00E1vel. "}, {"Install.reply.anyway.no.", "Instalar resposta assim mesmo? [n\u00E3o]: "}, - {"NO", "N\u00E3o"}, + {"NO", "N\u00C3O"}, {"Public.keys.in.reply.and.keystore.don.t.match", "As chaves p\u00FAblicas da resposta e da \u00E1rea de armazenamento de chaves n\u00E3o correspondem"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Forne\u00E7a o -keysize para a gera\u00E7\u00E3o da chave secreta"}, + {"verified.by.s.in.s", "Verificado por %s em %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "ADVERT\u00CANCIA: n\u00E3o verificado. Certifique-se que -keystore esteja correto."}, + {"Extensions.", "Extens\u00F5es: "}, {".Empty.value.", "(Valor vazio)"}, {"Extension.Request.", "Solicita\u00E7\u00E3o de Extens\u00E3o:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java index a4727e64c88..7c2aa3cba43 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java @@ -40,8 +40,7 @@ public class Resources_sv extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Alternativ]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Alternativ:"}, {"Use.keytool.help.for.all.available.commands", "L\u00E4s \"Hj\u00E4lp - Nyckelverktyg\" f\u00F6r alla tillg\u00E4ngliga kommandon"}, @@ -61,7 +60,6 @@ public class Resources_sv extends java.util.ListResourceBundle { "Exporterar certifikat"}, //-exportcert {"Generates.a.key.pair", "Genererar nyckelpar"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "Genererar hemlig nyckel"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -178,7 +176,7 @@ public class Resources_sv extends java.util.ListResourceBundle { {"Illegal.value.", "Otill\u00E5tet v\u00E4rde: "}, {"Unknown.password.type.", "Ok\u00E4nd l\u00F6senordstyp: "}, {"Cannot.find.environment.variable.", - "Kan inte hitta milj\u00F6variabel: "}, + "Hittar inte milj\u00F6variabel: "}, {"Cannot.find.file.", "Hittar inte fil: "}, {"Command.option.flag.needs.an.argument.", "Kommandoalternativet {0} beh\u00F6ver ett argument."}, {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.", @@ -244,8 +242,10 @@ public class Resources_sv extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "Certifikatbeg\u00E4ran har lagrats i filen <{0}>"}, {"Submit.this.to.your.CA", "Skicka detta till certifikatutf\u00E4rdaren"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "om n\u00E5got alias inte anges f\u00E5r destalias, srckeypass och destkeypass inte anges"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "om alias inte angivits ska inte heller destalias och srckeypass anges"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "Destinationsnyckellagret pkcs12 har olika storepass och keypass. F\u00F6rs\u00F6k igen med -destkeypass angivet."}, {"Certificate.stored.in.file.filename.", "Certifikatet har lagrats i filen <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -324,7 +324,7 @@ public class Resources_sv extends java.util.ListResourceBundle { {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", "Vill du fortfarande l\u00E4gga till det i ditt eget nyckellagret? [nej]: "}, {"Trust.this.certificate.no.", "Litar du p\u00E5 det h\u00E4r certifikatet? [nej]: "}, - {"YES", "Ja"}, + {"YES", "JA"}, {"New.prompt.", "Nytt {0}: "}, {"Passwords.must.differ", "L\u00F6senorden m\u00E5ste vara olika"}, {"Re.enter.new.prompt.", "Ange nytt {0} igen: "}, @@ -361,7 +361,7 @@ public class Resources_sv extends java.util.ListResourceBundle { "Aliaset <{0}> refererar till en posttyp som inte \u00E4r n\u00E5gon privat nyckelpost. Kommandot -keyclone har endast st\u00F6d f\u00F6r kloning av privata nyckelposter"}, {".WARNING.WARNING.WARNING.", - "***************** Varning Varning Varning *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "Signerare #%d:"}, {"Timestamp.", "Tidsst\u00E4mpel:"}, {"Signature.", "Underskrift:"}, @@ -386,7 +386,7 @@ public class Resources_sv extends java.util.ListResourceBundle { "Toppniv\u00E5certifikatet i svaret:\n"}, {".is.not.trusted.", "... \u00E4r inte betrott. "}, {"Install.reply.anyway.no.", "Vill du installera svaret \u00E4nd\u00E5? [nej]: "}, - {"NO", "Nej"}, + {"NO", "NEJ"}, {"Public.keys.in.reply.and.keystore.don.t.match", "De offentliga nycklarna i svaret och nyckellagret matchar inte varandra"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_sv extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Ange -keysize f\u00F6r att skapa hemlig nyckel"}, + {"verified.by.s.in.s", "Verifierad av %s i %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "VARNING: ej verifierad. Se till att -nyckellager \u00E4r korrekt."}, + {"Extensions.", "Till\u00E4gg: "}, {".Empty.value.", "(Tomt v\u00E4rde)"}, {"Extension.Request.", "Till\u00E4ggsbeg\u00E4ran:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java index 6836bd769f9..814e0fe78c2 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java @@ -40,8 +40,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [\u9009\u9879]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "\u9009\u9879:"}, {"Use.keytool.help.for.all.available.commands", "\u4F7F\u7528 \"keytool -help\" \u83B7\u53D6\u6240\u6709\u53EF\u7528\u547D\u4EE4"}, @@ -61,9 +60,8 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "\u5BFC\u51FA\u8BC1\u4E66"}, //-exportcert {"Generates.a.key.pair", "\u751F\u6210\u5BC6\u94A5\u5BF9"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", - "\u751F\u6210\u5BF9\u79F0\u5BC6\u94A5"}, //-genseckey + "\u751F\u6210\u5BC6\u94A5"}, //-genseckey {"Generates.certificate.from.a.certificate.request", "\u6839\u636E\u8BC1\u4E66\u8BF7\u6C42\u751F\u6210\u8BC1\u4E66"}, //-gencert {"Generates.CRL", "\u751F\u6210 CRL"}, //-gencrl @@ -182,7 +180,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Cannot.find.file.", "\u627E\u4E0D\u5230\u6587\u4EF6: "}, {"Command.option.flag.needs.an.argument.", "\u547D\u4EE4\u9009\u9879{0}\u9700\u8981\u4E00\u4E2A\u53C2\u6570\u3002"}, {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.", - "\u8B66\u544A: PKCS12 KeyStore \u4E0D\u652F\u6301\u5176\u4ED6\u5B58\u50A8\u548C\u5BC6\u94A5\u53E3\u4EE4\u3002\u6B63\u5728\u5FFD\u7565\u7528\u6237\u6307\u5B9A\u7684{0}\u503C\u3002"}, + "\u8B66\u544A: PKCS12 \u5BC6\u94A5\u5E93\u4E0D\u652F\u6301\u5176\u4ED6\u5B58\u50A8\u548C\u5BC6\u94A5\u53E3\u4EE4\u3002\u6B63\u5728\u5FFD\u7565\u7528\u6237\u6307\u5B9A\u7684{0}\u503C\u3002"}, {".keystore.must.be.NONE.if.storetype.is.{0}", "\u5982\u679C -storetype \u4E3A {0}, \u5219 -keystore \u5FC5\u987B\u4E3A NONE"}, {"Too.many.retries.program.terminated", @@ -203,13 +201,13 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "\u5982\u679C\u6E90\u5BC6\u94A5\u5E93\u672A\u53D7\u53E3\u4EE4\u4FDD\u62A4, \u5219\u4E0D\u80FD\u6307\u5B9A -srcstorepass \u548C -srckeypass"}, {"Illegal.startdate.value", "\u975E\u6CD5\u5F00\u59CB\u65E5\u671F\u503C"}, {"Validity.must.be.greater.than.zero", - "\u6709\u6548\u671F\u5FC5\u987B\u5927\u4E8E\u96F6"}, + "\u6709\u6548\u6027\u5FC5\u987B\u5927\u4E8E\u96F6"}, {"provName.not.a.provider", "{0}\u4E0D\u662F\u63D0\u4F9B\u65B9"}, {"Usage.error.no.command.provided", "\u7528\u6CD5\u9519\u8BEF: \u6CA1\u6709\u63D0\u4F9B\u547D\u4EE4"}, {"Source.keystore.file.exists.but.is.empty.", "\u6E90\u5BC6\u94A5\u5E93\u6587\u4EF6\u5B58\u5728, \u4F46\u4E3A\u7A7A: "}, {"Please.specify.srckeystore", "\u8BF7\u6307\u5B9A -srckeystore"}, {"Must.not.specify.both.v.and.rfc.with.list.command", - "'list' \u547D\u4EE4\u4E0D\u80FD\u540C\u65F6\u6307\u5B9A -v \u53CA -rfc"}, + "\u4E0D\u80FD\u4F7F\u7528 'list' \u547D\u4EE4\u6765\u6307\u5B9A -v \u53CA -rfc"}, {"Key.password.must.be.at.least.6.characters", "\u5BC6\u94A5\u53E3\u4EE4\u81F3\u5C11\u5FC5\u987B\u4E3A 6 \u4E2A\u5B57\u7B26"}, {"New.password.must.be.at.least.6.characters", @@ -239,13 +237,15 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Warning.Overwriting.existing.alias.alias.in.destination.keystore", "\u8B66\u544A: \u6B63\u5728\u8986\u76D6\u76EE\u6807\u5BC6\u94A5\u5E93\u4E2D\u7684\u73B0\u6709\u522B\u540D {0}"}, {"Existing.entry.alias.alias.exists.overwrite.no.", - "\u5B58\u5728\u73B0\u6709\u6761\u76EE\u522B\u540D {0}, \u662F\u5426\u8986\u76D6? [no]: "}, + "\u5B58\u5728\u73B0\u6709\u6761\u76EE\u522B\u540D {0}, \u662F\u5426\u8986\u76D6? [\u5426]: "}, {"Too.many.failures.try.later", "\u6545\u969C\u592A\u591A - \u8BF7\u7A0D\u540E\u518D\u8BD5"}, {"Certification.request.stored.in.file.filename.", "\u5B58\u50A8\u5728\u6587\u4EF6 <{0}> \u4E2D\u7684\u8BA4\u8BC1\u8BF7\u6C42"}, {"Submit.this.to.your.CA", "\u5C06\u6B64\u63D0\u4EA4\u7ED9\u60A8\u7684 CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "\u5982\u679C\u6CA1\u6709\u6307\u5B9A\u522B\u540D, \u5219\u4E0D\u80FD\u6307\u5B9A\u76EE\u6807\u522B\u540D, \u6E90\u5BC6\u94A5\u5E93\u53E3\u4EE4\u548C\u76EE\u6807\u5BC6\u94A5\u5E93\u53E3\u4EE4"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "\u5982\u679C\u6CA1\u6709\u6307\u5B9A\u522B\u540D, \u5219\u4E0D\u80FD\u6307\u5B9A\u76EE\u6807\u522B\u540D\u548C\u6E90\u5BC6\u94A5\u5E93\u53E3\u4EE4"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "\u76EE\u6807 pkcs12 \u5BC6\u94A5\u5E93\u5177\u6709\u4E0D\u540C\u7684 storepass \u548C keypass\u3002\u8BF7\u5728\u6307\u5B9A\u4E86 -destkeypass \u65F6\u91CD\u8BD5\u3002"}, {"Certificate.stored.in.file.filename.", "\u5B58\u50A8\u5728\u6587\u4EF6 <{0}> \u4E2D\u7684\u8BC1\u4E66"}, {"Certificate.reply.was.installed.in.keystore", @@ -305,7 +305,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "\u60A8\u7684\u5BC6\u94A5\u5E93\u5305\u542B {0,number,integer} \u4E2A\u6761\u76EE"}, {"Your.keystore.contains.keyStore.size.entries", "\u60A8\u7684\u5BC6\u94A5\u5E93\u5305\u542B {0,number,integer} \u4E2A\u6761\u76EE"}, - {"Failed.to.parse.input", "\u65E0\u6CD5\u5BF9\u8F93\u5165\u8FDB\u884C\u8BED\u6CD5\u5206\u6790"}, + {"Failed.to.parse.input", "\u65E0\u6CD5\u89E3\u6790\u8F93\u5165"}, {"Empty.input", "\u7A7A\u8F93\u5165"}, {"Not.X.509.certificate", "\u975E X.509 \u8BC1\u4E66"}, {"alias.has.no.public.key", "{0}\u6CA1\u6709\u516C\u5171\u5BC6\u94A5"}, @@ -318,13 +318,13 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Certificate.already.exists.in.keystore.under.alias.trustalias.", "\u5728\u522B\u540D <{0}> \u4E4B\u4E0B, \u8BC1\u4E66\u5DF2\u7ECF\u5B58\u5728\u4E8E\u5BC6\u94A5\u5E93\u4E2D"}, {"Do.you.still.want.to.add.it.no.", - "\u662F\u5426\u4ECD\u8981\u6DFB\u52A0? [no]: "}, + "\u662F\u5426\u4ECD\u8981\u6DFB\u52A0? [\u5426]: "}, {"Certificate.already.exists.in.system.wide.CA.keystore.under.alias.trustalias.", "\u5728\u522B\u540D <{0}> \u4E4B\u4E0B, \u8BC1\u4E66\u5DF2\u7ECF\u5B58\u5728\u4E8E\u7CFB\u7EDF\u8303\u56F4\u7684 CA \u5BC6\u94A5\u5E93\u4E2D"}, {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", - "\u662F\u5426\u4ECD\u8981\u5C06\u5B83\u6DFB\u52A0\u5230\u81EA\u5DF1\u7684\u5BC6\u94A5\u5E93? [no]: "}, - {"Trust.this.certificate.no.", "\u662F\u5426\u4FE1\u4EFB\u6B64\u8BC1\u4E66? [no]: "}, - {"YES", "\u662F"}, + "\u662F\u5426\u4ECD\u8981\u5C06\u5B83\u6DFB\u52A0\u5230\u81EA\u5DF1\u7684\u5BC6\u94A5\u5E93? [\u5426]: "}, + {"Trust.this.certificate.no.", "\u662F\u5426\u4FE1\u4EFB\u6B64\u8BC1\u4E66? [\u5426]: "}, + {"YES", "YES"}, {"New.prompt.", "\u65B0{0}: "}, {"Passwords.must.differ", "\u53E3\u4EE4\u4E0D\u80FD\u76F8\u540C"}, {"Re.enter.new.prompt.", "\u91CD\u65B0\u8F93\u5165\u65B0{0}: "}, @@ -332,7 +332,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"They.don.t.match.Try.again", "\u5B83\u4EEC\u4E0D\u5339\u914D\u3002\u8BF7\u91CD\u8BD5"}, {"Enter.prompt.alias.name.", "\u8F93\u5165{0}\u522B\u540D: "}, {"Enter.new.alias.name.RETURN.to.cancel.import.for.this.entry.", - "\u8F93\u5165\u65B0\u7684\u522B\u540D\t(\u6309\u56DE\u8F66\u4EE5\u53D6\u6D88\u5BF9\u6B64\u6761\u76EE\u7684\u5BFC\u5165): "}, + "\u5BFC\u5165\u65B0\u7684\u522B\u540D\t(\u6309\u56DE\u8F66\u4EE5\u53D6\u6D88\u5BF9\u6B64\u6761\u76EE\u7684\u5BFC\u5165): "}, {"Enter.alias.name.", "\u8F93\u5165\u522B\u540D: "}, {".RETURN.if.same.as.for.otherAlias.", "\t(\u5982\u679C\u548C <{0}> \u76F8\u540C, \u5219\u6309\u56DE\u8F66)"}, @@ -361,7 +361,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "\u522B\u540D <{0}> \u5F15\u7528\u4E86\u4E0D\u5C5E\u4E8E\u79C1\u6709\u5BC6\u94A5\u6761\u76EE\u7684\u6761\u76EE\u7C7B\u578B\u3002-keyclone \u547D\u4EE4\u4EC5\u652F\u6301\u5BF9\u79C1\u6709\u5BC6\u94A5\u6761\u76EE\u7684\u514B\u9686"}, {".WARNING.WARNING.WARNING.", - "***************** \u8B66\u544A \u8B66\u544A \u8B66\u544A *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "\u7B7E\u540D\u8005 #%d:"}, {"Timestamp.", "\u65F6\u95F4\u6233:"}, {"Signature.", "\u7B7E\u540D:"}, @@ -385,8 +385,8 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Top.level.certificate.in.reply.", "\u56DE\u590D\u4E2D\u7684\u9876\u7EA7\u8BC1\u4E66:\n"}, {".is.not.trusted.", "... \u662F\u4E0D\u53EF\u4FE1\u7684\u3002"}, - {"Install.reply.anyway.no.", "\u662F\u5426\u4ECD\u8981\u5B89\u88C5\u56DE\u590D? [no]: "}, - {"NO", "\u5426"}, + {"Install.reply.anyway.no.", "\u662F\u5426\u4ECD\u8981\u5B89\u88C5\u56DE\u590D? [\u5426]: "}, + {"NO", "NO"}, {"Public.keys.in.reply.and.keystore.don.t.match", "\u56DE\u590D\u4E2D\u7684\u516C\u5171\u5BC6\u94A5\u4E0E\u5BC6\u94A5\u5E93\u4E0D\u5339\u914D"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -398,7 +398,11 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Secret.key.not.generated.alias.alias.already.exists", "\u6CA1\u6709\u751F\u6210\u5BC6\u94A5, \u522B\u540D <{0}> \u5DF2\u7ECF\u5B58\u5728"}, {"Please.provide.keysize.for.secret.key.generation", - "\u8BF7\u63D0\u4F9B -keysize \u4EE5\u751F\u6210\u5BF9\u79F0\u5BC6\u94A5"}, + "\u8BF7\u63D0\u4F9B -keysize \u4EE5\u751F\u6210\u5BC6\u94A5"}, + + {"verified.by.s.in.s", "\u7531 %s \u9A8C\u8BC1(\u5728 %s \u4E2D)"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "\u8B66\u544A: \u672A\u9A8C\u8BC1\u3002\u8BF7\u786E\u4FDD\u5BC6\u94A5\u5E93\u662F\u6B63\u786E\u7684\u3002"}, {"Extensions.", "\u6269\u5C55: "}, {".Empty.value.", "(\u7A7A\u503C)"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java index 2c7bdf5e1b7..0b6afb8a74f 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java @@ -40,8 +40,7 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [\u9078\u9805]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "\u9078\u9805:"}, {"Use.keytool.help.for.all.available.commands", "\u4F7F\u7528 \"keytool -help\" \u53D6\u5F97\u6240\u6709\u53EF\u7528\u7684\u547D\u4EE4"}, @@ -61,7 +60,6 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { "\u532F\u51FA\u6191\u8B49"}, //-exportcert {"Generates.a.key.pair", "\u7522\u751F\u91D1\u9470\u7D44"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "\u7522\u751F\u79D8\u5BC6\u91D1\u9470"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "\u8A8D\u8B49\u8981\u6C42\u5132\u5B58\u5728\u6A94\u6848 <{0}>"}, {"Submit.this.to.your.CA", "\u5C07\u6B64\u9001\u51FA\u81F3\u60A8\u7684 CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "\u5982\u679C\u672A\u6307\u5B9A\u5225\u540D\uFF0C\u5247\u4E0D\u80FD\u6307\u5B9A destalias\u3001srckeypass \u53CA destkeypass"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "\u5982\u679C\u672A\u6307\u5B9A\u5225\u540D\uFF0C\u5247\u4E0D\u80FD\u6307\u5B9A destalias \u548C srckeypass"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "\u76EE\u7684\u5730 pkcs12 \u91D1\u9470\u5132\u5B58\u5EAB\u7684 storepass \u548C keypass \u4E0D\u540C\u3002\u8ACB\u91CD\u65B0\u4EE5 -destkeypass \u6307\u5B9A\u3002"}, {"Certificate.stored.in.file.filename.", "\u6191\u8B49\u5132\u5B58\u5728\u6A94\u6848 <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -361,7 +361,7 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { "\u5225\u540D <{0}> \u6240\u53C3\u7167\u7684\u9805\u76EE\u4E0D\u662F\u79C1\u5BC6\u91D1\u9470\u985E\u578B\u3002-keyclone \u547D\u4EE4\u50C5\u652F\u63F4\u79C1\u5BC6\u91D1\u9470\u9805\u76EE\u7684\u8907\u88FD"}, {".WARNING.WARNING.WARNING.", - "***************** \u8B66\u544A \u8B66\u544A \u8B66\u544A *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "\u7C3D\u7F72\u8005 #%d:"}, {"Timestamp.", "\u6642\u6233:"}, {"Signature.", "\u7C3D\u7AE0:"}, @@ -383,7 +383,7 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { {"Certificate.chain.in.reply.does.not.verify.", "\u56DE\u8986\u6642\u7684\u6191\u8B49\u93C8\u672A\u9A57\u8B49: "}, {"Top.level.certificate.in.reply.", - "\u56DE\u8986\u6642\u7684\u6700\u9AD8\u7D1A\u6191\u8B49:\\n"}, + "\u56DE\u8986\u6642\u7684\u6700\u9AD8\u7D1A\u6191\u8B49:\n"}, {".is.not.trusted.", "... \u662F\u4E0D\u88AB\u4FE1\u4EFB\u7684\u3002"}, {"Install.reply.anyway.no.", "\u9084\u662F\u8981\u5B89\u88DD\u56DE\u8986\uFF1F [\u5426]: "}, {"NO", "\u5426"}, @@ -400,6 +400,10 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "\u8ACB\u63D0\u4F9B -keysize \u4EE5\u7522\u751F\u79D8\u5BC6\u91D1\u9470"}, + {"verified.by.s.in.s", "\u7531 %s \u9A57\u8B49 (\u5728 %s \u4E2D)"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "\u8B66\u544A: \u672A\u9A57\u8B49\u3002\u8ACB\u78BA\u5B9A -keystore \u6B63\u78BA\u3002"}, + {"Extensions.", "\u64F4\u5145\u5957\u4EF6: "}, {".Empty.value.", "(\u7A7A\u767D\u503C)"}, {"Extension.Request.", "\u64F4\u5145\u5957\u4EF6\u8981\u6C42:"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_de.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_de.java index 4ca4c7e3394..a00f9e9d809 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_de.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_de.java @@ -57,7 +57,7 @@ public class Resources_de extends java.util.ListResourceBundle { {"Retain", "Beibehalten"}, {"Warning.File.name.may.include.escaped.backslash.characters.It.is.not.necessary.to.escape.backslash.characters.the.tool.escapes", - "Warnung: M\u00F6glicherweise enth\u00E4lt der Dateiname Escape-Zeichen mit Backslash. Es ist nicht notwendig, Backslash-Zeichen zu escapen (das Tool f\u00FChrt dies automatisch beim Schreiben des Policy-Contents in den persistenten Speicher aus).\n\nKlicken Sie auf \"Beibehalten\", um den eingegebenen Namen beizubehalten oder auf \"Bearbeiten\", um den Namen zu bearbeiten."}, + "Warnung: M\u00F6glicherweise enth\u00E4lt der Dateiname Escapezeichen mit Backslash. Es ist nicht notwendig, Backslash-Zeichen zu escapen (das Tool f\u00FChrt dies automatisch beim Schreiben des Policy-Contents in den persistenten Speicher aus).\n\nKlicken Sie auf \"Beibehalten\", um den eingegebenen Namen beizubehalten oder auf \"Bearbeiten\", um den Namen zu bearbeiten."}, {"Add.Public.Key.Alias", "Public Key-Alias hinzuf\u00FCgen"}, {"Remove.Public.Key.Alias", "Public Key-Alias entfernen"}, @@ -134,6 +134,9 @@ public class Resources_de extends java.util.ListResourceBundle { {"policy.type", "Policy-Typ"}, {"property.name", "Eigenschaftsname"}, {"provider.name", "Providername"}, + {"url", "URL"}, + {"method.list", "Methodenliste"}, + {"request.headers.list", "Headerliste anfordern"}, {"Principal.List", "Principal-Liste"}, {"Permission.List", "Berechtigungsliste"}, {"Code.Base", "Codebase"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_es.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_es.java index 142550094bd..6e92889c1bd 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_es.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_es.java @@ -134,6 +134,9 @@ public class Resources_es extends java.util.ListResourceBundle { {"policy.type", "tipo de pol\u00EDtica"}, {"property.name", "nombre de la propiedad"}, {"provider.name", "nombre del proveedor"}, + {"url", "url"}, + {"method.list", "lista de m\u00E9todos"}, + {"request.headers.list", "lista de cabeceras de solicitudes"}, {"Principal.List", "Lista de Principales"}, {"Permission.List", "Lista de Permisos"}, {"Code.Base", "Base de C\u00F3digo"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_fr.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_fr.java index 898e9cc8c9b..adba418d9b4 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_fr.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_fr.java @@ -134,6 +134,9 @@ public class Resources_fr extends java.util.ListResourceBundle { {"policy.type", "type de r\u00E8gle"}, {"property.name", "nom de propri\u00E9t\u00E9"}, {"provider.name", "nom du fournisseur"}, + {"url", "url"}, + {"method.list", "liste des m\u00E9thodes"}, + {"request.headers.list", "liste des en-t\u00EAtes de demande"}, {"Principal.List", "Liste de principaux"}, {"Permission.List", "Liste de droits"}, {"Code.Base", "Base de code"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_it.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_it.java index 3daf8616bee..813be7cfb19 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_it.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_it.java @@ -41,7 +41,7 @@ public class Resources_it extends java.util.ListResourceBundle { "Avvertenza: argomento o argomenti non validi per il costruttore {0}"}, {"Illegal.Principal.Type.type", "Tipo principal non valido: {0}"}, {"Illegal.option.option", "Opzione non valida: {0}"}, - {"Usage.policytool.options.", "Utilizzo: policytool [opzioni]"}, + {"Usage.policytool.options.", "Uso: policytool [opzioni]"}, {".file.file.policy.file.location", " [-file ] posizione del file dei criteri"}, {"New", "Nuovo"}, @@ -134,6 +134,9 @@ public class Resources_it extends java.util.ListResourceBundle { {"policy.type", "tipo di criteri"}, {"property.name", "nome propriet\u00E0"}, {"provider.name", "nome provider"}, + {"url", "url"}, + {"method.list", "lista metodi"}, + {"request.headers.list", "lista intestazioni di richiesta"}, {"Principal.List", "Lista principal"}, {"Permission.List", "Lista autorizzazioni"}, {"Code.Base", "Codebase"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_ja.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_ja.java index a3f901aa8f5..bd07eb0ee70 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_ja.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_ja.java @@ -134,6 +134,9 @@ public class Resources_ja extends java.util.ListResourceBundle { {"policy.type", "\u30DD\u30EA\u30B7\u30FC\u30FB\u30BF\u30A4\u30D7"}, {"property.name", "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D"}, {"provider.name", "\u30D7\u30ED\u30D0\u30A4\u30C0\u540D"}, + {"url", "URL"}, + {"method.list", "\u30E1\u30BD\u30C3\u30C9\u30FB\u30EA\u30B9\u30C8"}, + {"request.headers.list", "\u30EA\u30AF\u30A8\u30B9\u30C8\u30FB\u30D8\u30C3\u30C0\u30FC\u30FB\u30EA\u30B9\u30C8"}, {"Principal.List", "\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u306E\u30EA\u30B9\u30C8"}, {"Permission.List", "\u30A2\u30AF\u30BB\u30B9\u6A29\u306E\u30EA\u30B9\u30C8"}, {"Code.Base", "\u30B3\u30FC\u30C9\u30FB\u30D9\u30FC\u30B9"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_ko.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_ko.java index 7797ec803a0..3dc58f2eeb2 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_ko.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_ko.java @@ -134,6 +134,9 @@ public class Resources_ko extends java.util.ListResourceBundle { {"policy.type", "\uC815\uCC45 \uC720\uD615"}, {"property.name", "\uC18D\uC131 \uC774\uB984"}, {"provider.name", "\uC81C\uACF5\uC790 \uC774\uB984"}, + {"url", "URL"}, + {"method.list", "\uBA54\uC18C\uB4DC \uBAA9\uB85D"}, + {"request.headers.list", "\uC694\uCCAD \uD5E4\uB354 \uBAA9\uB85D"}, {"Principal.List", "\uC8FC\uCCB4 \uBAA9\uB85D"}, {"Permission.List", "\uAD8C\uD55C \uBAA9\uB85D"}, {"Code.Base", "\uCF54\uB4DC \uBCA0\uC774\uC2A4"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_pt_BR.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_pt_BR.java index 9bd9808d0b5..2290701f755 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_pt_BR.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_pt_BR.java @@ -134,6 +134,9 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { {"policy.type", "tipo de pol\u00EDtica"}, {"property.name", "nome da propriedade"}, {"provider.name", "nome do fornecedor"}, + {"url", "url"}, + {"method.list", "lista de m\u00E9todos"}, + {"request.headers.list", "solicitar lista de cabe\u00E7alhos"}, {"Principal.List", "Lista de Principais"}, {"Permission.List", "Lista de Permiss\u00F5es"}, {"Code.Base", "Base de C\u00F3digo"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_sv.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_sv.java index f0bf734ae40..0929eec984e 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_sv.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_sv.java @@ -134,6 +134,9 @@ public class Resources_sv extends java.util.ListResourceBundle { {"policy.type", "policytyp"}, {"property.name", "egenskapsnamn"}, {"provider.name", "leverant\u00F6rsnamn"}, + {"url", "url"}, + {"method.list", "metodlista"}, + {"request.headers.list", "beg\u00E4ranrubriklista"}, {"Principal.List", "Lista \u00F6ver identitetshavare"}, {"Permission.List", "Beh\u00F6righetslista"}, {"Code.Base", "Kodbas"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_CN.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_CN.java index fcf8e126d4c..d96dc07d71b 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_CN.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_CN.java @@ -35,7 +35,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { private static final Object[][] contents = { {"NEWLINE", "\n"}, {"Warning.A.public.key.for.alias.signers.i.does.not.exist.Make.sure.a.KeyStore.is.properly.configured.", - "\u8B66\u544A: \u522B\u540D {0} \u7684\u516C\u5171\u5BC6\u94A5\u4E0D\u5B58\u5728\u3002\u8BF7\u786E\u4FDD\u5DF2\u6B63\u786E\u914D\u7F6E KeyStore\u3002"}, + "\u8B66\u544A: \u522B\u540D {0} \u7684\u516C\u5171\u5BC6\u94A5\u4E0D\u5B58\u5728\u3002\u8BF7\u786E\u4FDD\u5DF2\u6B63\u786E\u914D\u7F6E\u5BC6\u94A5\u5E93\u3002"}, {"Warning.Class.not.found.class", "\u8B66\u544A: \u627E\u4E0D\u5230\u7C7B: {0}"}, {"Warning.Invalid.argument.s.for.constructor.arg", "\u8B66\u544A: \u6784\u9020\u5668\u7684\u53C2\u6570\u65E0\u6548: {0}"}, @@ -62,7 +62,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Add.Public.Key.Alias", "\u6DFB\u52A0\u516C\u5171\u5BC6\u94A5\u522B\u540D"}, {"Remove.Public.Key.Alias", "\u5220\u9664\u516C\u5171\u5BC6\u94A5\u522B\u540D"}, {"File", "\u6587\u4EF6"}, - {"KeyStore", "KeyStore"}, + {"KeyStore", "\u5BC6\u94A5\u5E93"}, {"Policy.File.", "\u7B56\u7565\u6587\u4EF6:"}, {"Could.not.open.policy.file.policyFile.e.toString.", "\u65E0\u6CD5\u6253\u5F00\u7B56\u7565\u6587\u4EF6: {0}: {1}"}, @@ -94,10 +94,10 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {".Edit.Permission", " \u7F16\u8F91\u6743\u9650"}, {"Remove.Permission", "\u5220\u9664\u6743\u9650"}, {"Done", "\u5B8C\u6210"}, - {"KeyStore.URL.", "KeyStore URL:"}, - {"KeyStore.Type.", "KeyStore \u7C7B\u578B:"}, - {"KeyStore.Provider.", "KeyStore \u63D0\u4F9B\u65B9:"}, - {"KeyStore.Password.URL.", "KeyStore \u53E3\u4EE4 URL:"}, + {"KeyStore.URL.", "\u5BC6\u94A5\u5E93 URL:"}, + {"KeyStore.Type.", "\u5BC6\u94A5\u5E93\u7C7B\u578B:"}, + {"KeyStore.Provider.", "\u5BC6\u94A5\u5E93\u63D0\u4F9B\u65B9:"}, + {"KeyStore.Password.URL.", "\u5BC6\u94A5\u5E93\u53E3\u4EE4 URL:"}, {"Principals", "\u4E3B\u7528\u6237"}, {".Edit.Principal.", " \u7F16\u8F91\u4E3B\u7528\u6237:"}, {".Add.New.Principal.", " \u6DFB\u52A0\u65B0\u4E3B\u7528\u6237:"}, @@ -123,7 +123,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Save.Changes", "\u4FDD\u5B58\u66F4\u6539"}, {"No.Policy.Entry.selected", "\u6CA1\u6709\u9009\u62E9\u7B56\u7565\u6761\u76EE"}, {"Unable.to.open.KeyStore.ex.toString.", - "\u65E0\u6CD5\u6253\u5F00 KeyStore: {0}"}, + "\u65E0\u6CD5\u6253\u5F00\u5BC6\u94A5\u5E93: {0}"}, {"No.principal.selected", "\u672A\u9009\u62E9\u4E3B\u7528\u6237"}, {"No.permission.selected", "\u6CA1\u6709\u9009\u62E9\u6743\u9650"}, {"name", "\u540D\u79F0"}, @@ -134,11 +134,14 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"policy.type", "\u7B56\u7565\u7C7B\u578B"}, {"property.name", "\u5C5E\u6027\u540D\u79F0"}, {"provider.name", "\u63D0\u4F9B\u65B9\u540D\u79F0"}, + {"url", "URL"}, + {"method.list", "\u65B9\u6CD5\u5217\u8868"}, + {"request.headers.list", "\u8BF7\u6C42\u6807\u5934\u5217\u8868"}, {"Principal.List", "\u4E3B\u7528\u6237\u5217\u8868"}, {"Permission.List", "\u6743\u9650\u5217\u8868"}, {"Code.Base", "\u4EE3\u7801\u5E93"}, - {"KeyStore.U.R.L.", "KeyStore URL:"}, - {"KeyStore.Password.U.R.L.", "KeyStore \u53E3\u4EE4 URL:"} + {"KeyStore.U.R.L.", "\u5BC6\u94A5\u5E93 URL:"}, + {"KeyStore.Password.U.R.L.", "\u5BC6\u94A5\u5E93\u53E3\u4EE4 URL:"} }; diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java index 1c241a6afa1..5a9af4ed40f 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java @@ -134,6 +134,9 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { {"policy.type", "\u539F\u5247\u985E\u578B"}, {"property.name", "\u5C6C\u6027\u540D\u7A31"}, {"provider.name", "\u63D0\u4F9B\u8005\u540D\u7A31"}, + {"url", "URL"}, + {"method.list", "\u65B9\u6CD5\u6E05\u55AE"}, + {"request.headers.list", "\u8981\u6C42\u6A19\u982D\u6E05\u55AE"}, {"Principal.List", "Principal \u6E05\u55AE"}, {"Permission.List", "\u6B0A\u9650\u6E05\u55AE"}, {"Code.Base", "\u4EE3\u78BC\u57FA\u6E96"}, diff --git a/jdk/src/share/classes/sun/security/util/Resources_fr.java b/jdk/src/share/classes/sun/security/util/Resources_fr.java index 44a6d5f9e79..f31968fcf42 100644 --- a/jdk/src/share/classes/sun/security/util/Resources_fr.java +++ b/jdk/src/share/classes/sun/security/util/Resources_fr.java @@ -65,12 +65,12 @@ public class Resources_fr extends java.util.ListResourceBundle { {"invalid.null.Class.provided", "classe NULL fournie non valide"}, {"Subject.", "Objet :\n"}, {".Principal.", "\tPrincipal : "}, - {".Public.Credential.", "\tInformations d'identification et de connexion publiques : "}, + {".Public.Credential.", "\tInformations d'identification publiques : "}, {".Private.Credentials.inaccessible.", - "\tInformations d'identification et de connexion priv\u00E9es inaccessibles\n"}, - {".Private.Credential.", "\tInformations d'identification et de connexion priv\u00E9es : "}, + "\tInformations d'identification priv\u00E9es inaccessibles\n"}, + {".Private.Credential.", "\tInformations d'identification priv\u00E9es : "}, {".Private.Credential.inaccessible.", - "\tInformations d'identification et de connexion priv\u00E9es inaccessibles\n"}, + "\tInformations d'identification priv\u00E9es inaccessibles\n"}, {"Subject.is.read.only", "Sujet en lecture seule"}, {"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set", "tentative d'ajout d'un objet qui n'est pas une instance de java.security.Principal dans un ensemble de principaux du sujet"}, diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_de.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_de.properties index 678d292b4f2..4dd5d5f9129 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_de.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_de.properties @@ -29,7 +29,6 @@ error.bad.option=Eine der Optionen -{ctxu} muss angegeben werden. error.bad.cflag=Kennzeichen "c" erfordert Angabe von Manifest oder Eingabedateien. error.bad.uflag=Kennzeichen "u" erfordert Angabe von Manifest, Kennzeichen "e" oder Eingabedateien. error.bad.eflag=Kennzeichen "e" und Manifest mit dem Attribut "Main-Class" k\u00F6nnen nicht zusammen angegeben\nwerden. -error.bad.pvalue=ung\u00FCltiger Wert f\u00FCr Attribut "Profil": {0} error.nosuch.fileordir={0}: Datei oder Verzeichnis nicht vorhanden error.write.file=Fehler beim Schreiben in vorhandener JAR-Datei error.create.dir={0}: Verzeichnis konnte nicht erstellt werden @@ -42,7 +41,7 @@ out.deflated=({0} % verkleinert) out.stored=(0 % gespeichert) out.create=\ erstellt: {0} out.extracted=extrahiert: {0} -out.inflated=\ \\vergr\u00F6\u00DFert: {0} +out.inflated=\ vergr\u00F6\u00DFert: {0} out.size=(ein = {0}) (aus = {1}) -usage=Verwendung: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] Dateien...\nOptionen:\n -c Neues Archiv erstellen\n -t Inhaltsverzeichnis f\u00FCr Archiv auflisten\n -x Genannte (oder alle) Dateien aus Archiv extrahieren\n -u Vorhandenes Archiv aktualisieren\n -v Verbose-Ausgabe f\u00FCr Standardausgabe generieren\n -f Namen der Archivdatei angeben\n -m Manifestinformationen von angegebener Manifestdatei einschlie\u00DFen\n -e Anwendungseinstiegspunkt f\u00FCr die \n in einer ausf\u00FChrbaren JAR-Datei geb\u00FCndelte Standalone-Anwendung angeben\n -p Profilnamen angeben\n -0 Nur speichern (keine ZIP-Komprimierung)\n -M Keine Manifest-Datei f\u00FCr die Eintr\u00E4ge erstellen\n -i Indexinformationen f\u00FCr angegebene JAR-Dateien erstellen\n -C zum angegebenen Verzeichnis wechseln und folgende Datei einschlie\u00DFen\nFalls eine Datei ein Verzeichnis ist, wird dieses rekursiv verarbeitet.\nDer Name der Manifestdatei, der Name der Archivdatei und der Name des Einstiegspunkts werden\nin derselben Reihenfolge wie die Kennzeichen "m", "f" und "e" angegeben.\n\nBeispiel 1: Archivieren Sie zwei Klassendateien in ein Archiv mit dem Namen "classes.jar": \n jar cvf classes.jar Foo.class Bar.class \nBeispiel 2: Verwenden Sie die vorhandenen Manifestdatei "mymanifest", und archivieren Sie\n alle Dateien im Verzeichnis foo/ in "classes.jar": \n jar cvfm classes.jar mymanifest -C foo/ .\n +usage=Verwendung: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] Dateien...\nOptionen:\n -c Neues Archiv erstellen\n -t Inhaltsverzeichnis f\u00FCr Archiv auflisten\n -x Genannte (oder alle) Dateien aus Archiv extrahieren\n -u Vorhandenes Archiv aktualisieren\n -v Verbose-Ausgabe f\u00FCr Standardausgabe generieren\n -f Namen der Archivdatei angeben\n -m Manifest-Informationen von angegebener Manifest-Datei einschlie\u00DFen\n -e Anwendungs-Einstiegspunkt f\u00FCr die \n in einer ausf\u00FChrbaren JAR-Datei geb\u00FCndelte Standalone-Anwendung angeben\n -0 Nur speichern (keine ZIP-Komprimierung)\n -M Keine Manifest-Datei f\u00FCr die Eintr\u00E4ge erstellen\n -i Indexinformationen f\u00FCr angegebenen JAR-Dateien erstellen\n -C zum angegebenen Verzeichnis wechseln und folgende Datei einschlie\u00DFen\nFalls eine Datei ein Verzeichnis ist, wird dieses rekursiv verarbeitet.\nDer Name der Manifest-Datei, der Name der Archivdatei und der Name des Einstiegspunkts werden\nin derselben Reihenfolge wie die Kennzeichen "m", "f" und "e" angegeben.\n\nBeispiel 1: Archivieren Sie zwei Klassendateien in ein Archiv mit Namen "classes.jar": \n jar cvf classes.jar Foo.class Bar.class \nBeispiel 2: Verwenden Sie die vorhandenen Manifest-Datei "mymanifest", und archivieren Sie\n alle Dateien im Verzeichnis foo/ in "classes.jar": \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_es.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_es.properties index ff24bed068d..e5ce11bda79 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_es.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_es.properties @@ -29,7 +29,6 @@ error.bad.option=Se debe especificar una de las opciones -{ctxu}. error.bad.cflag=El indicador 'c' necesita la especificaci\u00F3n de archivos de manifiesto o de entrada. error.bad.uflag=El indicador 'u' necesita la especificaci\u00F3n de archivos de manifiesto, de entrada o indicador 'e'. error.bad.eflag=El indicador 'e' y el manifiesto con el atributo 'Main-Class' no pueden especificarse \na la vez. -error.bad.pvalue=valor err\u00F3neo para el atributo ''Profile'': {0} error.nosuch.fileordir={0} : no existe tal archivo o directorio error.write.file=Error al escribir un archivo jar existente error.create.dir={0} : no se ha podido crear el directorio @@ -42,7 +41,7 @@ out.deflated=(desinflado {0}%) out.stored=(almacenado 0%) out.create=\ creado: {0} out.extracted=extra\u00EDdo: {0} -out.inflated=\ \\inflado: {0} +out.inflated=\ inflado: {0} out.size=(entrada = {0}) (salida = {1}) -usage=Sintaxis: archivos jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] ...\nOpciones:\n -c crear nuevo archivo\n -t mostrar la tabla de contenido del archivo\n -x extraer los archivos mencionados (o todos) del archivo\n -u actualizar archivo existente\n -v generar salida detallada de los datos de salida est\u00E1ndar\n -f especificar nombre de archivo de almacenamiento\n -m incluir informaci\u00F3n de manifiesto del archivo de manifiesto especificado\n -e especificar punto de entrada de la aplicaci\u00F3n para la aplicaci\u00F3n aut\u00F3noma \n que se incluye dentro de un archivo jar ejecutable\n -p especificar nombre de perfil\n -0 solo almacenar; no utilizar compresi\u00F3n ZIP\n -M no crear un archivo de manifiesto para las entradas\n -i generar informaci\u00F3n de \u00EDndice para los archivos jar especificados\n -C cambiar al directorio especificado e incluir el archivo siguiente\nSi alg\u00FAn archivo es un directorio, se procesar\u00E1 de forma recurrente.\nEl nombre del archivo de manifiesto, el nombre del archivo de almacenamiento y el nombre del punto de entrada se\nespecifican en el mismo orden que los indicadores 'm', 'f' y 'e'.\n\nEjemplo 1: para archivar archivos de dos clases en un archivo llamado classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEjemplo 2: utilice un archivo de manifiesto existente 'mymanifest' y archive todos los\narchivos del directorio foo/ en'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n +usage=Sintaxis: jar {ctxui}[vfm0Me] [archive-jar] [archive-manifiesto] [punto-entrada] [-C dir] archivos...\nOpciones:\n -c crear nuevo archivo\n -t crear la tabla de contenido del archivo\n -x extraer el archive mencionado (o todos) del archivo\n -u actualizar archive existente\n -v generar salida detallada de los datos de salida est\u00E1ndar\n -f especificar nombre de archive de almacenamiento\n -m incluir informaci\u00F3n de manifiesto del archive de manifiesto especificado\n -e especificar punto de entrada de la aplicaci\u00F3n para la aplicaci\u00F3n aut\u00F3noma \n que se incluye dentro de un archive jar ejecutable\n -0 s\u00F3lo almacenar; no utilizar compresi\u00F3n ZIP\n -M no crear un archive de manifiesto para las entradas\n -i generar informaci\u00F3n de \u00EDndice para los archives jar especificados\n -C cambiar al directorio especificado e incluir el archivo siguiente\nSi alg\u00FAn archivo es un directorio, se procesar\u00E1 de forma recurrente.\nEl nombre del archivo de manifiesto, el nombre del archivo de almacenamiento y el nombre del punto de entrada se\nespecifican en el mismo orden que los indicadores 'm', 'f' y 'e'.\n\nEjemplo 1: para archivar archivos de dos clases en un archivo llamado classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEjemplo 2: utilice un archivo de manifiesto existente 'mymanifest' y archive todos los\n archivos del directorio foo/ en 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_fr.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_fr.properties index f26335287fb..c7cae813be4 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_fr.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_fr.properties @@ -29,7 +29,6 @@ error.bad.option=Une des options -{ctxu} doit \u00EAtre sp\u00E9cifi\u00E9e. error.bad.cflag=L'indicateur c requiert la sp\u00E9cification d'un fichier manifeste ou d'un fichier d'entr\u00E9e. error.bad.uflag=L'indicateur u requiert la sp\u00E9cification d'un fichier manifeste, d'un fichier d'entr\u00E9e ou d'un indicateur e. error.bad.eflag=L'indicateur e et le fichier manifeste portant l'attribut Main-Class ne peuvent pas \u00EAtre sp\u00E9cifi\u00E9s \nensemble. -error.bad.pvalue=valeur incorrecte pour l''attribut ''Profile'' : {0} error.nosuch.fileordir={0} : fichier ou r\u00E9pertoire introuvable error.write.file=Erreur lors de l'\u00E9criture d'un fichier JAR existant error.create.dir={0} : impossible de cr\u00E9er le r\u00E9pertoire @@ -42,7 +41,7 @@ out.deflated=(compression : {0} %) out.stored=(stockage : 0 %) out.create=\ cr\u00E9\u00E9 : {0} out.extracted=extrait : {0} -out.inflated=\ \\d\u00E9compress\u00E9 : {0} +out.inflated=\ d\u00E9compress\u00E9 : {0} out.size=(entr\u00E9e = {0}) (sortie = {1}) -usage=Syntaxe : jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nOptions :\n -c cr\u00E9e une archive\n -t affiche la table des mati\u00E8res de l'archive\n -x extrait les fichiers nomm\u00E9s (ou tous les fichiers) de l'archive\n -u met \u00E0 jour l'archive existante\n -v g\u00E9n\u00E8re une sortie en mode verbose d'une sortie standard\n -f sp\u00E9cifie le nom du fichier d'archive\n -m inclut les informations de manifest \u00E0 partir du fichier manifest sp\u00E9cifi\u00E9\n -e sp\u00E9cifie le point d'entr\u00E9e d'une application en mode autonome \n int\u00E9gr\u00E9e \u00E0 un fichier JAR ex\u00E9cutable\n -p indique le nom de profil\n -0 stockage uniquement, pas de compression ZIP\n -M ne cr\u00E9e pas de fichier manifest pour les entr\u00E9es\n -i g\u00E9n\u00E8re les informations d'index des fichiers JAR sp\u00E9cifi\u00E9s\n -C passe au r\u00E9pertoire sp\u00E9cifi\u00E9 et inclut le fichier suivant\nSi l'un des fichiers est un r\u00E9pertoire, celui-ci est trait\u00E9 r\u00E9cursivement.\nLes noms du fichier manifest, du fichier d'archive et du point d'entr\u00E9e sont\nsp\u00E9cifi\u00E9s dans le m\u00EAme ordre que celui des indicateurs m, f et e.\n\nExemple 1 : pour archiver deux fichiers de classe dans une archive intitul\u00E9e classes.jar : \n jar cvf classes.jar Foo.class Bar.class \nExemple 2 : pour utiliser un fichier manifest existant 'mymanifest', puis archiver tous les\n fichiers du r\u00E9pertoire foo/ dans 'classes.jar' : \n jar cvfm classes.jar mymanifest -C foo/ .\n +usage=Syntaxe : jar {ctxui}[vfm0Me] [fichier-jar] [fichier-manifeste] [point-entr\u00E9e] [-C r\u00E9p] fichiers...\nOptions :\n -c cr\u00E9e une archive\n -t affiche la table des mati\u00E8res de l'archive\n -x extrait les fichiers nomm\u00E9s (ou tous les fichiers) de l'archive\n -u met \u00E0 jour l'archive existante\n -v g\u00E9n\u00E8re une version d\u00E9taill\u00E9e d'une sortie standard\n -f sp\u00E9cifie le nom du fichier archive\n -m inclut les informations de manifeste \u00E0 partir du fichier de manifeste sp\u00E9cifi\u00E9\n -e sp\u00E9cifie le point d'entr\u00E9e d'une application en mode autonome \n int\u00E9gr\u00E9e \u00E0 un fichier JAR ex\u00E9cutable\n -0 stockage uniquement, pas de compression ZIP\n -M ne cr\u00E9e pas de fichier manifeste pour les entr\u00E9es\n -i g\u00E9n\u00E8re les informations d'index des fichiers JAR sp\u00E9cifi\u00E9s\n -C passe au r\u00E9pertoire sp\u00E9cifi\u00E9 et inclut le fichier suivant\nSi l'un des fichiers est un r\u00E9pertoire, celui-ci est trait\u00E9 r\u00E9cursivement.\nLes noms du fichier manifeste, du fichier archive et du point d'entr\u00E9e sont\nsp\u00E9cifi\u00E9s dans le m\u00EAme ordre que celui des indicateurs m, f et e.\n\nExemple 1 : pour archiver deux fichiers de classe dans une archive intitul\u00E9e classes.jar : \n jar cvf classes.jar Foo.class Bar.class \nExemple 2 : pour utiliser un fichier manifeste existant 'monmanifeste', puis archiver tous les\n fichiers du r\u00E9pertoire foo/ dans 'classes.jar' : \n jar cvfm classes.jar monmanifeste -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_it.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_it.properties index 313169c83b0..50652a82056 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_it.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_it.properties @@ -29,7 +29,6 @@ error.bad.option=\u00C8 necessario specificare una delle opzioni -{ctxu}. error.bad.cflag=Per il flag 'c' \u00E8 necessario specificare file manifest o di input. error.bad.uflag=Per il flag 'u' \u00E8 necessario specificare il flag 'e' oppure file manifest o di input. error.bad.eflag=Il flag 'e' e il manifest con l'attributo 'Main-Class' non possono essere specificati\ninsieme. -error.bad.pvalue=valore non valido per l''attributo ''Profile'': {0} error.nosuch.fileordir={0} : file o directory inesistente error.write.file=Errore durante la scrittura del file jar esistente error.create.dir={0} : impossibile creare la directory @@ -42,7 +41,7 @@ out.deflated=(compresso {0}%) out.stored=(memorizzato 0%) out.create=\ creato: {0} out.extracted=estratto: {0} -out.inflated=\ \\decompresso: {0} +out.inflated=\ decompresso: {0} out.size=(in = {0}) (out = {1}) -usage=Uso: jar {ctxui}[vfm0Me] [jar-file] [file manifest] [punto di accesso] [-C dir] file ...\nOpzioni:\n -c crea un nuovo archivio\n -t visualizza il sommario dell'archivio\n -x estrae i file specificati (o tutti i file) dall'archivio\n -u aggiorna un archivio esistente\n -v genera un output descrittivo dall'output standard\n -f specifica il nome file dell'archivio\n -m include le informazioni manifest dal file manifest specificato\n -e specifica il punto di accesso per l'applicazione standalone \n inclusa in un file JAR eseguibile\n -p specifica il nome del profilo\n -0 esegue solo la memorizzazione; non utilizza la compressione ZIP\n -M non crea un file manifest per le voci\n -i genera le informazioni di indice per i file JAR specificati\n -C passa alla directory specificata e include il file seguente\nSe un file qualsiasi \u00E8 una directory, viene elaborato in modo ricorsivo.\nIl nome del file manifest, del file di archivio e del punto di accesso devono\nessere specificati nello stesso ordine dei flag 'm', 'f' e 'e'.\n\nEsempio 1: archiviazione di due file di classe nell'archivio denominato classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEsempio 2: uso del file manifest esistente 'mymanifest' e archiviazione di tutti i\n file della directory foo/ in 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/.\n +usage=Uso: jar {ctxui}[vfm0Me] [file-jar] [file-manifest] [punto di ingresso] [-C dir] file ...\nOpzioni:\n -c crea un nuovo archivio\n -t visualizza l'indice dell'archivio\n -x estrae i file con nome (o tutti i file) dall'archivio\n -u aggiorna l'archivio esistente\n -v genera output commentato dall'output standard\n -f specifica il nome file dell'archivio\n -m include informazioni manifest dal file manifest specificato\n -e specifica il punto di ingresso per l'applicazione stand-alone \n inclusa nel file jar eseguibile\n -0 solo memorizzazione; senza compressione ZIP\n -M consente di non creare un file manifest per le voci\n -i genera informazioni sull'indice per i file jar specificati\n -C imposta la directory specificata e include il file seguente\nSe un file \u00E8 una directory, verr\u00E0 elaborato in modo ricorsivo.\nIl nome del file manifest, del file di archivio e del punto di ingresso devono\nessere specificati nello stesso ordine dei flag 'm', 'f' ed 'e'.\n\nEsempio 1: archiviazione di due file di classe in un archivio con il nome classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEsempio 2: utilizzo del file manifest esistente 'mymanifest' e archiviazione di tutti i\n file della directory foo/ in 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/.\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_ja.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_ja.properties index b909c46d04a..7167ef10ec0 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_ja.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_ja.properties @@ -29,7 +29,6 @@ error.bad.option=\u30AA\u30D7\u30B7\u30E7\u30F3-{ctxu}\u306E\u3046\u3061\u306E1\ error.bad.cflag=\u30D5\u30E9\u30B0'c'\u3067\u306F\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u307E\u305F\u306F\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u6307\u5B9A\u304C\u5FC5\u8981\u3067\u3059\u3002 error.bad.uflag=\u30D5\u30E9\u30B0'u'\u3067\u306F\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304B'e'\u30D5\u30E9\u30B0\u3001\u307E\u305F\u306F\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u6307\u5B9A\u304C\u5FC5\u8981\u3067\u3059\u3002 error.bad.eflag='e'\u30D5\u30E9\u30B0\u3068'Main-Class'\u5C5E\u6027\u3092\u6301\u3064\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u306F\u540C\u6642\u306B\n\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002 -error.bad.pvalue=''Profile''\u5C5E\u6027\u306E\u5024\u304C\u4E0D\u6B63\u3067\u3059: {0} error.nosuch.fileordir={0}\u3068\u3044\u3046\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\u3042\u308A\u307E\u305B\u3093 error.write.file=\u65E2\u5B58jar\u30D5\u30A1\u30A4\u30EB\u306E\u66F8\u8FBC\u307F\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F error.create.dir=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F @@ -42,7 +41,7 @@ out.deflated=({0}%\u53CE\u7E2E\u3055\u308C\u307E\u3057\u305F) out.stored=(0%\u683C\u7D0D\u3055\u308C\u307E\u3057\u305F) out.create=\ {0}\u304C\u4F5C\u6210\u3055\u308C\u307E\u3057\u305F out.extracted={0}\u304C\u62BD\u51FA\u3055\u308C\u307E\u3057\u305F -out.inflated=\ \\{0}\u304C\u5C55\u958B\u3055\u308C\u307E\u3057\u305F +out.inflated=\ {0}\u304C\u5C55\u958B\u3055\u308C\u307E\u3057\u305F out.size=(\u5165={0})(\u51FA={1}) -usage=\u4F7F\u7528\u65B9\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u30AA\u30D7\u30B7\u30E7\u30F3:\n -c \u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u65B0\u898F\u4F5C\u6210\u3059\u308B\n -t \u30A2\u30FC\u30AB\u30A4\u30D6\u306E\u5185\u5BB9\u3092\u4E00\u89A7\u8868\u793A\u3059\u308B\n -x \u6307\u5B9A\u306E(\u307E\u305F\u306F\u3059\u3079\u3066\u306E)\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6\u304B\u3089\u62BD\u51FA\u3059\u308B\n -u \u65E2\u5B58\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u66F4\u65B0\u3059\u308B\n -v \u6A19\u6E96\u51FA\u529B\u306B\u8A73\u7D30\u306A\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n -f \u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3059\u308B\n -m \u6307\u5B9A\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u60C5\u5831\u3092\u53D6\u308A\u8FBC\u3080\n -e \u5B9F\u884C\u53EF\u80FDjar\u30D5\u30A1\u30A4\u30EB\u306B\u30D0\u30F3\u30C9\u30EB\u3055\u308C\u305F\u30B9\u30BF\u30F3\u30C9\u30A2\u30ED\u30F3\u30FB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\n \u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u3092\u6307\u5B9A\u3059\u308B\n -p \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3059\u308B\n -0 \u683C\u7D0D\u306E\u307F\u3002ZIP\u5727\u7E2E\u3092\u4F7F\u7528\u3057\u306A\u3044\n -M \u30A8\u30F3\u30C8\u30EA\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210\u3057\u306A\u3044\n -i \u6307\u5B9A\u306Ejar\u30D5\u30A1\u30A4\u30EB\u306E\u7D22\u5F15\u60C5\u5831\u3092\u751F\u6210\u3059\u308B\n -C \u6307\u5B9A\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u5909\u66F4\u3057\u3001\u4EE5\u4E0B\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u53D6\u308A\u8FBC\u3080\n\u30D5\u30A1\u30A4\u30EB\u304C\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u5834\u5408\u306F\u518D\u5E30\u7684\u306B\u51E6\u7406\u3055\u308C\u307E\u3059\u3002\n\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3001\u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u304A\u3088\u3073\u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u540D\u306F\u3001\n\u30D5\u30E9\u30B0'm'\u3001'f'\u3001'e'\u3068\u540C\u3058\u9806\u5E8F\u3067\u6307\u5B9A\u3057\u307E\u3059\u3002\n\n\u4F8B1: 2\u3064\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6classes.jar\u306B\u4FDD\u5B58\u3059\u308B:\n jar cvf classes.jar Foo.class Bar.class\n\u4F8B2: \u65E2\u5B58\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB'mymanifest'\u3092\u4F7F\u7528\u3057\u3001foo/\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\n \u5168\u30D5\u30A1\u30A4\u30EB\u3092'classes.jar'\u306B\u30A2\u30FC\u30AB\u30A4\u30D6\u3059\u308B:\n jar cvfm classes.jar mymanifest -C foo/ \n +usage=\u4F7F\u7528\u65B9\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u30AA\u30D7\u30B7\u30E7\u30F3:\n -c \u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u65B0\u898F\u4F5C\u6210\u3059\u308B\n -t \u30A2\u30FC\u30AB\u30A4\u30D6\u306E\u5185\u5BB9\u3092\u4E00\u89A7\u8868\u793A\u3059\u308B\n -x \u6307\u5B9A\u306E(\u307E\u305F\u306F\u3059\u3079\u3066\u306E)\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6\u304B\u3089\u62BD\u51FA\u3059\u308B\n -u \u65E2\u5B58\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u66F4\u65B0\u3059\u308B\n -v \u6A19\u6E96\u51FA\u529B\u306B\u8A73\u7D30\u306A\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n -f \u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3059\u308B\n -m \u6307\u5B9A\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u60C5\u5831\u3092\u53D6\u308A\u8FBC\u3080\n -e \u5B9F\u884C\u53EF\u80FDjar\u30D5\u30A1\u30A4\u30EB\u306B\u30D0\u30F3\u30C9\u30EB\u3055\u308C\u305F\u30B9\u30BF\u30F3\u30C9\u30A2\u30ED\u30F3\u30FB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\n \u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u3092\u6307\u5B9A\u3059\u308B\n -0 \u683C\u7D0D\u306E\u307F\u3002ZIP\u5727\u7E2E\u3092\u4F7F\u7528\u3057\u306A\u3044\n -M \u30A8\u30F3\u30C8\u30EA\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210\u3057\u306A\u3044\n -i \u6307\u5B9A\u306Ejar\u30D5\u30A1\u30A4\u30EB\u306E\u7D22\u5F15\u60C5\u5831\u3092\u751F\u6210\u3059\u308B\n -C \u6307\u5B9A\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u5909\u66F4\u3057\u3001\u4EE5\u4E0B\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u53D6\u308A\u8FBC\u3080\n\u30D5\u30A1\u30A4\u30EB\u304C\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u5834\u5408\u306F\u518D\u5E30\u7684\u306B\u51E6\u7406\u3055\u308C\u307E\u3059\u3002\n\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3001\u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u304A\u3088\u3073\u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u540D\u306F\u3001\n\u30D5\u30E9\u30B0'm'\u3001'f'\u3001'e'\u306E\u6307\u5B9A\u3068\u540C\u3058\u9806\u756A\u3067\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n\n\u4F8B1: 2\u3064\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6classes.jar\u306B\u4FDD\u5B58\u3059\u308B:\n jar cvf classes.jar Foo.class Bar.class\n\u4F8B2: \u65E2\u5B58\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB'mymanifest'\u3092\u4F7F\u7528\u3057\u3001foo/\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\n \u5168\u30D5\u30A1\u30A4\u30EB\u3092'classes.jar'\u306B\u30A2\u30FC\u30AB\u30A4\u30D6\u3059\u308B:\n jar cvfm classes.jar mymanifest -C foo/ \n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_ko.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_ko.properties index 472d2d94dc2..2b414a0369d 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_ko.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_ko.properties @@ -29,20 +29,19 @@ error.bad.option=\uC635\uC158 -{ctxu} \uC911 \uD558\uB098\uB97C \uC9C0\uC815\uD5 error.bad.cflag='c' \uD50C\uB798\uADF8\uB97C \uC0AC\uC6A9\uD558\uB824\uBA74 Manifest \uB610\uB294 \uC785\uB825 \uD30C\uC77C\uC744 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4! error.bad.uflag='u' \uD50C\uB798\uADF8\uB97C \uC0AC\uC6A9\uD558\uB824\uBA74 Manifest, 'e' \uD50C\uB798\uADF8 \uB610\uB294 \uC785\uB825 \uD30C\uC77C\uC744 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4! error.bad.eflag='e' \uD50C\uB798\uADF8 \uBC0F Manifest\uB97C 'Main-Class' \uC18D\uC131\uACFC \uD568\uAED8 \uC9C0\uC815\uD560 \uC218\n\uC5C6\uC2B5\uB2C8\uB2E4! -error.bad.pvalue=''Profile'' \uC18D\uC131\uC5D0 \uB300\uD574 \uC798\uBABB\uB41C \uAC12: {0} error.nosuch.fileordir={0}: \uD574\uB2F9 \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD1A0\uB9AC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. error.write.file=\uAE30\uC874 jar \uD30C\uC77C\uC5D0 \uC4F0\uB294 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. error.create.dir={0}: \uB514\uB809\uD1A0\uB9AC\uB97C \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. error.incorrect.length=\uCC98\uB9AC \uC911 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC740 \uAE38\uC774\uAC00 \uBC1C\uACAC\uB428: {0} out.added.manifest=Manifest\uB97C \uCD94\uAC00\uD568 -out.update.manifest=Manifest\uB97C \uAC31\uC2E0\uD568 +out.update.manifest=Manifest\uB97C \uC5C5\uB370\uC774\uD2B8\uD568 out.ignore.entry={0} \uD56D\uBAA9\uC744 \uBB34\uC2DC\uD558\uB294 \uC911 out.adding=\uCD94\uAC00\uD558\uB294 \uC911: {0} out.deflated=({0}%\uB97C \uAC10\uC18C\uD568) out.stored=(0%\uB97C \uC800\uC7A5\uD568) out.create=\ \uC0DD\uC131\uB428: {0} out.extracted=\uCD94\uCD9C\uB428: {0} -out.inflated=\ \\\uC99D\uAC00\uB428: {0} +out.inflated=\ \uC99D\uAC00\uB428: {0} out.size=(\uC785\uB825 = {0}) (\uCD9C\uB825 = {1}) -usage=\uC0AC\uC6A9\uBC95: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\uC635\uC158:\n -c \uC0C8 \uC544\uCE74\uC774\uBE0C\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -t \uC544\uCE74\uC774\uBE0C\uC5D0 \uB300\uD55C \uBAA9\uCC28\uB97C \uB098\uC5F4\uD569\uB2C8\uB2E4.\n -x \uBA85\uBA85\uB41C(\uB610\uB294 \uBAA8\uB4E0) \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uC5D0\uC11C \uCD94\uCD9C\uD569\uB2C8\uB2E4.\n -u \uAE30\uC874 \uC544\uCE74\uC774\uBE0C\uB97C \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4.\n -v \uD45C\uC900 \uCD9C\uB825\uC5D0 \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -f \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -m \uC9C0\uC815\uB41C Manifest \uD30C\uC77C\uC758 Manifest \uC815\uBCF4\uB97C \uD3EC\uD568\uD569\uB2C8\uB2E4.\n -e jar \uC2E4\uD589 \uD30C\uC77C\uC5D0 \uBC88\uB4E4\uB85C \uC81C\uACF5\uB41C \uB3C5\uB9BD\uD615 \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8\uC758 \n \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8 \uC2DC\uC791 \uC9C0\uC810\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -p \uD504\uB85C\uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -0 \uC800\uC7A5 \uC804\uC6A9: ZIP \uC555\uCD95\uC744 \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -M \uD56D\uBAA9\uC5D0 \uB300\uD574 Manifest \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -i \uC9C0\uC815\uB41C jar \uD30C\uC77C\uC5D0 \uB300\uD55C \uC778\uB371\uC2A4 \uC815\uBCF4\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -C \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uB85C \uBCC0\uACBD\uD558\uACE0 \uB2E4\uC74C \uD30C\uC77C\uC744 \uD3EC\uD568\uD569\uB2C8\uB2E4.\n\uD2B9\uC815 \uD30C\uC77C\uC774 \uB514\uB809\uD1A0\uB9AC\uC77C \uACBD\uC6B0 \uC21C\uD658\uC801\uC73C\uB85C \uCC98\uB9AC\uB429\uB2C8\uB2E4.\nManifest \uD30C\uC77C \uC774\uB984, \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984 \uBC0F \uC2DC\uC791 \uC9C0\uC810 \uC774\uB984\uC740\n'm', 'f' \uBC0F 'e' \uD50C\uB798\uADF8\uC640 \uB3D9\uC77C\uD55C \uC21C\uC11C\uB85C \uC9C0\uC815\uB429\uB2C8\uB2E4.\n\n\uC608 1: classes.jar\uB77C\uB294 \uC544\uCE74\uC774\uBE0C\uC5D0 \uB450 \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n jar cvf classes.jar Foo.class Bar.class \n\uC608 2: \uAE30\uC874 Manifest \uD30C\uC77C 'mymanifest'\uB97C \uC0AC\uC6A9\uD558\uC5EC\n foo/ \uB514\uB809\uD1A0\uB9AC\uC758 \uBAA8\uB4E0 \uD30C\uC77C\uC744 'classes.jar'\uB85C \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n jar cvfm classes.jar mymanifest -C foo/\n +usage=\uC0AC\uC6A9\uBC95: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\uC635\uC158:\n -c \uC0C8 \uC544\uCE74\uC774\uBE0C\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -t \uC544\uCE74\uC774\uBE0C\uC5D0 \uB300\uD55C \uBAA9\uCC28\uB97C \uB098\uC5F4\uD569\uB2C8\uB2E4.\n -x \uBA85\uBA85\uB41C(\uB610\uB294 \uBAA8\uB4E0) \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uC5D0\uC11C \uCD94\uCD9C\uD569\uB2C8\uB2E4.\n -u \uAE30\uC874 \uC544\uCE74\uC774\uBE0C\uB97C \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4.\n -v \uD45C\uC900 \uCD9C\uB825\uC5D0 \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -f \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -m \uC9C0\uC815\uB41C Manifest \uD30C\uC77C\uC758 Manifest \uC815\uBCF4\uB97C \uD3EC\uD568\uD569\uB2C8\uB2E4.\n -e jar \uC2E4\uD589 \uD30C\uC77C\uC5D0 \uBC88\uB4E4\uB85C \uC81C\uACF5\uB41C \uB3C5\uB9BD\uD615 \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8\uC758 \n \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8 \uC2DC\uC791 \uC9C0\uC810\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -0 \uC800\uC7A5 \uC804\uC6A9: ZIP \uC555\uCD95\uC744 \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -M \uD56D\uBAA9\uC5D0 \uB300\uD574 Manifest \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -i \uC9C0\uC815\uB41C jar \uD30C\uC77C\uC5D0 \uB300\uD55C \uC778\uB371\uC2A4 \uC815\uBCF4\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -C \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uB85C \uBCC0\uACBD\uD558\uACE0 \uB2E4\uC74C \uD30C\uC77C\uC744 \uD3EC\uD568\uD569\uB2C8\uB2E4.\n\uD2B9\uC815 \uD30C\uC77C\uC774 \uB514\uB809\uD1A0\uB9AC\uC77C \uACBD\uC6B0 \uC21C\uD658\uC801\uC73C\uB85C \uCC98\uB9AC\uB429\uB2C8\uB2E4.\nManifest \uD30C\uC77C \uC774\uB984, \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984 \uBC0F \uC2DC\uC791 \uC9C0\uC810 \uC774\uB984\uC740\n'm', 'f' \uBC0F 'e' \uD50C\uB798\uADF8\uC640 \uB3D9\uC77C\uD55C \uC21C\uC11C\uB85C \uC9C0\uC815\uB429\uB2C8\uB2E4.\n\n\uC608 1: classes.jar\uB77C\uB294 \uC544\uCE74\uC774\uBE0C\uC5D0 \uB450 \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n jar cvf classes.jar Foo.class Bar.class \n\uC608 2: \uAE30\uC874 Manifest \uD30C\uC77C 'mymanifest'\uB97C \uC0AC\uC6A9\uD558\uC5EC\n foo/ \uB514\uB809\uD1A0\uB9AC\uC758 \uBAA8\uB4E0 \uD30C\uC77C\uC744 'classes.jar'\uB85C \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_pt_BR.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_pt_BR.properties index 4c4c9f89e21..db6bd74b1e3 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_pt_BR.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_pt_BR.properties @@ -29,7 +29,6 @@ error.bad.option=Uma das op\u00E7\u00F5es -{ctxu} deve ser especificada. error.bad.cflag=flag 'c' requer que os arquivos de manifesto ou entrada sejam especificados! error.bad.uflag=o flag 'u' requer que arquivos de manifesto, o flag 'e' ou arquivos de entrada sejam especificados! error.bad.eflag=o flag 'e' e manifesto com o atributo 'Main-Class' n\u00E3o podem ser especificados \njuntos! -error.bad.pvalue=valor inv\u00E1lido do atributo de ''Perfil'': {0} error.nosuch.fileordir={0} : n\u00E3o h\u00E1 tal arquivo ou diret\u00F3rio error.write.file=Erro ao gravar o arquivo jar existente error.create.dir={0} : n\u00E3o foi poss\u00EDvel criar o diret\u00F3rio @@ -38,11 +37,11 @@ out.added.manifest=manifesto adicionado out.update.manifest=manifesto atualizado out.ignore.entry=ignorando entrada {0} out.adding=adicionando: {0} -out.deflated=(vazio {0}%) +out.deflated=(compactado {0}%) out.stored=(armazenado 0%) out.create=\ criado: {0} out.extracted=extra\u00EDdo: {0} -out.inflated=\ \\cheio: {0} -out.size=(dentro = {0}) (fora= {1}) +out.inflated=\ inflado: {0} +out.size=(entrada = {0}) (sa\u00EDda= {1}) -usage=Uso: arquivos jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] ...\nOp\u00E7\u00F5es:\n -c cria novo arquivo compactado\n -t lista o sum\u00E1rio do arquivo compactado\n -x extrai arquivos com o nome (ou todos) do arquivo compactado\n -u atualizar o arquivo compactado existente\n -v gera sa\u00EDda detalhada na sa\u00EDda padr\u00E3o\n -f especifica o nome do arquivo do arquivo compactado\n -m inclui as informa\u00E7\u00F5es do manifesto do arquivo de manifesto especificado\n -e especifica o ponto de entrada da aplica\u00E7\u00E3o para aplica\u00E7\u00E3o independente \n empacotado em um arquivo jar execut\u00E1vel\n -p especifca o nome do perfil\n -0 armazena somente; n\u00E3o usa compacta\u00E7\u00E3o ZIP\n -M n\u00E3o cria um arquivo de manifesto para as entradas\n -i gera informa\u00E7\u00F5es de \u00EDndice para os arquivos especificados\n -C altera para o diret\u00F3rio e inclui o arquivo seguinte\nSe nenhum arquivo for um diret\u00F3rio, ent\u00E3o ser\u00E1 processado repetidamente.\nO nome do arquivo de manifesto, o nome do arquivo compactado e o nome do ponto de entrada s\u00E3o\nespecificados na mesma ordem dos flags 'm', 'f' e 'e'.\n\nExemplo 1: para arquivar dois arquivos de classe em um arquivo compactado com o nome classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nExemplo 2: use um arquivo de manifesto existente 'mymanifest' e arquive todos os\n arquivos no diret\u00F3rio foo/ na 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n +usage=Uso: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] arquivos ...\nOp\u00E7\u00F5es:\n -c cria novo arquivo compactado\n -t lista o sum\u00E1rio do arquivo compactado\n -x extrai arquivos com o nome (ou todos) do arquivo compactado\n -u atualizar o arquivo compactado existente\n -v gera sa\u00EDda detalhada na sa\u00EDda padr\u00E3o\n -f especifica o nome do arquivo do arquivo compactado\n -m inclui as informa\u00E7\u00F5es do manifesto do arquivo de manifesto especificado\n -e especifica o ponto de entrada da aplica\u00E7\u00E3o para aplica\u00E7\u00E3o independente \n empacotando em um arquivo jar execut\u00E1vel\n -0 armazena somente; n\u00E3o usa compacta\u00E7\u00E3o ZIP\n -M n\u00E3o cria um arquivo de manifesto para as entradas\n -i gera informa\u00E7\u00F5es de \u00EDndice para os arquivos especificados\n -C altera para o diret\u00F3rio e inclui o arquivo seguinte\nSe nenhum arquivo for um diret\u00F3rio, ent\u00E3o ser\u00E1 processado repetidamente.\nO nome do arquivo de manifesto, o nome do arquivo compactado e o nome do ponto de entrada s\u00E3o\nespecificados na mesma ordem dos flags 'm', 'f' e 'e'.\n\nExemplo 1: para arquivar dois arquivos de classe em um arquivo compactado com o nome classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nExemplo 2: use um arquivo de manifesto existente 'mymanifest' e arquive todos os\n arquivos no diret\u00F3rio foo/ na 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_sv.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_sv.properties index e91207a7151..a90708825c1 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_sv.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_sv.properties @@ -29,7 +29,6 @@ error.bad.option=Ett av alternativen -{ctxu} m\u00E5ste anges. error.bad.cflag=f\u00F6r c-flaggan m\u00E5ste manifest- eller indatafiler anges. error.bad.uflag=f\u00F6r u-flaggan m\u00E5ste manifest-, e-flagg- eller indatafiler anges. error.bad.eflag=e-flaggan och manifest med attributet Main-Class kan inte anges \ntillsammans. -error.bad.pvalue=felaktigt v\u00E4rde f\u00F6r ''Profile''-attribut: {0} error.nosuch.fileordir={0} : det finns ingen s\u00E5dan fil eller katalog error.write.file=Det uppstod ett fel vid skrivning till befintlig jar-fil. error.create.dir={0} : kunde inte skapa n\u00E5gon katalog @@ -45,4 +44,4 @@ out.extracted=extraherat: {0} out.inflated=\ uppackat: {0} out.size=(in = {0}) (ut = {1}) -usage=Syntax: jar {ctxui}[vfm0Me] [jar-fil] [manifestfil] [startpunkt] [-C katalog] filer ...\nAlternativ:\n -c skapa nytt arkiv\n -t lista inneh\u00E5llsf\u00F6rteckning f\u00F6r arkiv\n -x extrahera namngivna (eller alla) filer fr\u00E5n arkiv\n -u uppdatera befintligt arkiv\n -v generera utf\u00F6rliga utdata vid standardutmatning\n -f ange arkivfilens namn\n -m inkludera manifestinformation fr\u00E5n angivet manifest\n -e ange programstartpunkt f\u00F6r frist\u00E5ende applikation \n som medf\u00F6ljer i en jar-programfil\n -p ange profilnamn\n -0 endast lagra (ingen zip-komprimering)\n -M skapa inte n\u00E5gon manifestfil f\u00F6r posterna\n -i generera indexinformation f\u00F6r de angivna jar-filerna\n -C \u00E4ndra till den angivna katalogen och inkludera f\u00F6ljande fil\nOm en fil \u00E4r en katalog bearbetas den rekursivt.\nNamnen p\u00E5 manifestfilen, arkivfilen och startpunkten anges\ni samma ordning som m-, f- och e-flaggorna.\n\nExempel 1: S\u00E5 h\u00E4r arkiverar du tv\u00E5 klassfiler i ett arkiv med namnet classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nExempel 2: Anv\u00E4nd en befintlig manifestfil (mymanifest) och arkivera alla\n filer fr\u00E5n katalogen foo/ i classes.jar: \n jar cvfm classes.jar mymanifest -C foo/ .\n +usage=Syntax: jar {ctxui}[vfm0Me] [jar fil] [manifestfil] [startpunkt] [-C-katalog] ...\nAlternativ:\n -c skapa nytt arkiv\n -t lista inneh\u00E5llsf\u00F6rteckning f\u00F6r arkiv\n -x extrahera namngivna (eller alla) filer fr\u00E5n arkiv\n -u uppdatera befintligt arkiv\n -v generera utf\u00F6rliga utdata vid standardutmatning\n -f ange arkivfilens namn\n -m inkludera manifestinformation fr\u00E5n angivet manifest\n -e ange programstartpunkt f\u00F6r frist\u00E5ende applikation \n som medf\u00F6ljer i en jar-programfil\n -0 endast lagra (ingen zip-komprimering)\n -M skapa inte n\u00E5gon manifestfil f\u00F6r posterna\n -i generera indexinformation f\u00F6r de angivna jar-filerna\n -C \u00E4ndra till den angivna katalogen och inkludera f\u00F6ljande fil\nOm en fil \u00E4r en katalog bearbetas den rekursivt.\nNamnen p\u00E5 manifestfilen, arkivfilen och startpunkten anges i samma\nordning som m-, f- och e-flaggorna.\n\nExempel 1: S\u00E5 h\u00E4r arkiverar du tv\u00E5 klassfiler i ett arkiv med namnet classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nExempel 2: Anv\u00E4nd en befintlig manifestfil (mymanifest) och arkivera alla\n filer fr\u00E5n katalogen foo/ i classes.jar: \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_CN.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_CN.properties index 250bf2b783e..2ee8e568ffa 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_CN.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_CN.properties @@ -29,7 +29,6 @@ error.bad.option=\u5FC5\u987B\u6307\u5B9A {ctxu} \u4E2D\u7684\u4EFB\u4E00\u9009\ error.bad.cflag='c' \u6807\u8BB0\u8981\u6C42\u6307\u5B9A\u6E05\u5355\u6216\u8F93\u5165\u6587\u4EF6! error.bad.uflag='u' \u6807\u8BB0\u8981\u6C42\u6307\u5B9A\u6E05\u5355, 'e' \u6807\u8BB0\u6216\u8F93\u5165\u6587\u4EF6! error.bad.eflag=\u4E0D\u80FD\u540C\u65F6\u6307\u5B9A 'e' \u6807\u8BB0\u548C\u5177\u6709 'Main-Class' \u5C5E\u6027\u7684\n\u6E05\u5355! -error.bad.pvalue=''Profile'' \u5C5E\u6027\u7684\u503C\u9519\u8BEF: {0} error.nosuch.fileordir={0}: \u6CA1\u6709\u8FD9\u4E2A\u6587\u4EF6\u6216\u76EE\u5F55 error.write.file=\u5199\u5165\u73B0\u6709\u7684 jar \u6587\u4EF6\u65F6\u51FA\u9519 error.create.dir={0}: \u65E0\u6CD5\u521B\u5EFA\u76EE\u5F55 @@ -45,4 +44,4 @@ out.extracted=\u5DF2\u63D0\u53D6: {0} out.inflated=\ \u5DF2\u89E3\u538B: {0} out.size=(\u8F93\u5165 = {0}) (\u8F93\u51FA = {1}) -usage=\u7528\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u9009\u9879:\n -c \u521B\u5EFA\u65B0\u6863\u6848\n -t \u5217\u51FA\u6863\u6848\u76EE\u5F55\n -x \u4ECE\u6863\u6848\u4E2D\u63D0\u53D6\u6307\u5B9A\u7684 (\u6216\u6240\u6709) \u6587\u4EF6\n -u \u66F4\u65B0\u73B0\u6709\u6863\u6848\n -v \u5728\u6807\u51C6\u8F93\u51FA\u4E2D\u751F\u6210\u8BE6\u7EC6\u8F93\u51FA\n -f \u6307\u5B9A\u6863\u6848\u6587\u4EF6\u540D\n -m \u5305\u542B\u6307\u5B9A\u6E05\u5355\u6587\u4EF6\u4E2D\u7684\u6E05\u5355\u4FE1\u606F\n -e \u4E3A\u7ED1\u5B9A\u5230\u53EF\u6267\u884C jar \u6587\u4EF6\u7684\u72EC\u7ACB\u5E94\u7528\u7A0B\u5E8F\n \u6307\u5B9A\u5E94\u7528\u7A0B\u5E8F\u5165\u53E3\u70B9\n -p \u6307\u5B9A\u914D\u7F6E\u6587\u4EF6\u540D\u79F0\n -0 \u4EC5\u5B58\u50A8; \u4E0D\u4F7F\u7528\u4EFB\u4F55 ZIP \u538B\u7F29\n -M \u4E0D\u521B\u5EFA\u6761\u76EE\u7684\u6E05\u5355\u6587\u4EF6\n -i \u4E3A\u6307\u5B9A\u7684 jar \u6587\u4EF6\u751F\u6210\u7D22\u5F15\u4FE1\u606F\n -C \u66F4\u6539\u4E3A\u6307\u5B9A\u7684\u76EE\u5F55\u5E76\u5305\u542B\u4EE5\u4E0B\u6587\u4EF6\n\u5982\u679C\u6587\u4EF6\u4E3A\u76EE\u5F55, \u5219\u5BF9\u5176\u8FDB\u884C\u9012\u5F52\u5904\u7406\u3002\n\u6E05\u5355\u6587\u4EF6\u540D, \u6863\u6848\u6587\u4EF6\u540D\u548C\u5165\u53E3\u70B9\u540D\u79F0\u7684\u6307\u5B9A\u987A\u5E8F\n\u4E0E 'm', 'f' \u548C 'e' \u6807\u8BB0\u7684\u6307\u5B9A\u987A\u5E8F\u76F8\u540C\u3002\n\n\u793A\u4F8B 1: \u5C06\u4E24\u4E2A\u7C7B\u6587\u4EF6\u5F52\u6863\u5230\u4E00\u4E2A\u540D\u4E3A classes.jar \u7684\u6863\u6848\u4E2D: \n jar cvf classes.jar Foo.class Bar.class \n\u793A\u4F8B 2: \u4F7F\u7528\u73B0\u6709\u7684\u6E05\u5355\u6587\u4EF6 'mymanifest' \u5E76\n \u5C06 foo/ \u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u5F52\u6863\u5230 'classes.jar' \u4E2D: \n jar cvfm classes.jar mymanifest -C foo/\u3002\n +usage=\u7528\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u9009\u9879\u5305\u62EC: \n -c \u521B\u5EFA\u65B0\u7684\u5F52\u6863\u6587\u4EF6\n -t \u5217\u51FA\u5F52\u6863\u76EE\u5F55\n -x \u4ECE\u6863\u6848\u4E2D\u63D0\u53D6\u6307\u5B9A\u7684 (\u6216\u6240\u6709) \u6587\u4EF6\n -u \u66F4\u65B0\u73B0\u6709\u7684\u5F52\u6863\u6587\u4EF6\n -v \u5728\u6807\u51C6\u8F93\u51FA\u4E2D\u751F\u6210\u8BE6\u7EC6\u8F93\u51FA\n -f \u6307\u5B9A\u5F52\u6863\u6587\u4EF6\u540D\n -m \u5305\u542B\u6307\u5B9A\u6E05\u5355\u6587\u4EF6\u4E2D\u7684\u6E05\u5355\u4FE1\u606F\n -e \u4E3A\u6346\u7ED1\u5230\u53EF\u6267\u884C jar \u6587\u4EF6\u7684\u72EC\u7ACB\u5E94\u7528\u7A0B\u5E8F\n \u6307\u5B9A\u5E94\u7528\u7A0B\u5E8F\u5165\u53E3\u70B9\n -0 \u4EC5\u5B58\u50A8; \u4E0D\u4F7F\u7528\u60C5\u51B5\u4EFB\u4F55 ZIP \u538B\u7F29\n -M \u4E0D\u521B\u5EFA\u6761\u76EE\u7684\u6E05\u5355\u6587\u4EF6\n -i \u4E3A\u6307\u5B9A\u7684 jar \u6587\u4EF6\u751F\u6210\u7D22\u5F15\u4FE1\u606F\n -C \u66F4\u6539\u4E3A\u6307\u5B9A\u7684\u76EE\u5F55\u5E76\u5305\u542B\u5176\u4E2D\u7684\u6587\u4EF6\n\u5982\u679C\u6709\u4EFB\u4F55\u76EE\u5F55\u6587\u4EF6, \u5219\u5BF9\u5176\u8FDB\u884C\u9012\u5F52\u5904\u7406\u3002\n\u6E05\u5355\u6587\u4EF6\u540D, \u5F52\u6863\u6587\u4EF6\u540D\u548C\u5165\u53E3\u70B9\u540D\u79F0\u7684\u6307\u5B9A\u987A\u5E8F\n\u4E0E 'm', 'f' \u548C 'e' \u6807\u8BB0\u7684\u6307\u5B9A\u987A\u5E8F\u76F8\u540C\u3002\n\n\u793A\u4F8B 1: \u5C06\u4E24\u4E2A\u7C7B\u6587\u4EF6\u5F52\u6863\u5230\u4E00\u4E2A\u540D\u4E3A classes.jar \u7684\u5F52\u6863\u6587\u4EF6\u4E2D: \n jar cvf classes.jar Foo.class Bar.class \n\u793A\u4F8B 2: \u4F7F\u7528\u73B0\u6709\u7684\u6E05\u5355\u6587\u4EF6 'mymanifest' \u5E76\n \u5C06 foo/ \u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u5F52\u6863\u5230 'classes.jar' \u4E2D: \n jar cvfm classes.jar mymanifest -C foo/\u3002\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_TW.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_TW.properties index ff5eedccaa8..7dd4f65390b 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_TW.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_TW.properties @@ -29,7 +29,6 @@ error.bad.option=\u5176\u4E2D\u4E00\u500B\u9078\u9805 -{ctxu} \u5FC5\u9808\u52A0 error.bad.cflag='c' \u65D7\u6A19\u8981\u6C42\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u6216\u8F38\u5165\u6A94\u6848\uFF01 error.bad.uflag='u' \u65D7\u6A19\u8981\u6C42\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u3001'e' \u65D7\u6A19\u6216\u8F38\u5165\u6A94\u6848\uFF01 error.bad.eflag=\u7121\u6CD5\u540C\u6642\u6307\u5B9A 'e' \u65D7\u6A19\u548C\u5177\u6709 'Main-Class' \u5C6C\u6027\u7684\n\u8CC7\u8A0A\u6E05\u55AE\uFF01 -error.bad.pvalue=''Profile'' \u5C6C\u6027\u503C\u7121\u6548: {0} error.nosuch.fileordir={0} : \u6C92\u6709\u9019\u985E\u6A94\u6848\u6216\u76EE\u9304 error.write.file=\u5BEB\u5165\u73FE\u6709\u7684 jar \u6A94\u6848\u6642\u767C\u751F\u932F\u8AA4 error.create.dir={0} : \u7121\u6CD5\u5EFA\u7ACB\u76EE\u9304 @@ -42,7 +41,7 @@ out.deflated=(\u58D3\u7E2E {0}%) out.stored=(\u5132\u5B58 0%) out.create=\ \u5EFA\u7ACB: {0} out.extracted=\u64F7\u53D6: {0} -out.inflated=\ \\\u64F4\u5C55: {0} +out.inflated=\ \u64F4\u5C55: {0} out.size=\ (\u8B80={0})(\u5BEB={1}) -usage=\u7528\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u9078\u9805:\n -c \u5EFA\u7ACB\u65B0\u7684\u5B58\u6A94\n -t \u5217\u51FA\u5B58\u6A94\u7684\u76EE\u9304\n -x \u5F9E\u5B58\u6A94\u4E2D\u64F7\u53D6\u6307\u5B9A\u7684 (\u6216\u6240\u6709) \u6A94\u6848\n -u \u66F4\u65B0\u73FE\u6709\u5B58\u6A94\n -v \u5728\u6A19\u6E96\u8F38\u51FA\u7522\u751F\u8A73\u7D30\u8F38\u51FA\n -f \u6307\u5B9A\u5B58\u6A94\u6A94\u6848\u540D\u7A31\n -m \u5305\u542B\u6307\u5B9A\u4E4B\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\u4E2D\u7684\u8CC7\u8A0A\u6E05\u55AE\u8CC7\u8A0A\n -e \u6307\u5B9A\u7368\u7ACB\u61C9\u7528\u7A0B\u5F0F\u7684\u61C9\u7528\u7A0B\u5F0F\u9032\u5165\u9EDE \n \u5DF2\u96A8\u9644\u65BC\u53EF\u57F7\u884C jar \u6A94\u6848\u4E2D\n -p \u6307\u5B9A\u8A2D\u5B9A\u6A94\u540D\u7A31\n -0 \u53EA\u5132\u5B58; \u4E0D\u4F7F\u7528 ZIP \u58D3\u7E2E\u65B9\u5F0F\n -M \u4E0D\u66FF\u9805\u76EE\u5EFA\u7ACB\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\n -i \u7522\u751F\u6307\u5B9A\u4E4B jar \u6A94\u6848\u7684\u7D22\u5F15\u8CC7\u8A0A\n -C \u8B8A\u66F4\u81F3\u6307\u5B9A\u7684\u76EE\u9304\u4E26\u5305\u542B\u4E0B\u5217\u6A94\u6848\n\u5982\u679C\u6709\u4EFB\u4F55\u6A94\u6848\u662F\u76EE\u9304\uFF0C\u5247\u6703\u905E\u8FF4\u5730\u8655\u7406\u6A94\u6848\u3002\n\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\u540D\u7A31\u3001\u5B58\u6A94\u6A94\u6848\u540D\u7A31\u4EE5\u53CA\u9032\u5165\u9EDE\u540D\u7A31\u7684\n\u6307\u5B9A\u9806\u5E8F\u8207 'm' \u65D7\u6A19\u3001'f' \u65D7\u6A19\u548C 'e' \u65D7\u6A19\u7684\u9806\u5E8F\u76F8\u540C\u3002\n\n\u7BC4\u4F8B 1: \u5C07\u5169\u500B\u985E\u5225\u6A94\u6848\u5B58\u6A94\u81F3\u540D\u70BA classes.jar \u7684\u5B58\u6A94\u4E2D: \n jar cvf classes.jar Foo.class Bar.class \n\u7BC4\u4F8B 2: \u4F7F\u7528\u73FE\u6709\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848 'mymanifest'\uFF0C\u5C07 foo/ \u76EE\u9304\n \u4E2D\u7684\u6240\u6709\u6A94\u6848\u5B58\u6A94\u81F3 'classes.jar' \u4E2D: \n jar cvfm classes.jar mymanifest -C foo/ \n +usage=\u7528\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] \u6A94\u6848 ...\n\u9078\u9805:\n -c \u5EFA\u7ACB\u65B0\u7684\u6B78\u6A94\n -t \u5217\u51FA\u6B78\u6A94\u7684\u76EE\u9304\n -x \u5F9E\u6B78\u6A94\u4E2D\u64F7\u53D6\u5DF2\u547D\u540D\u7684 (\u6216\u6240\u6709) \u6A94\u6848\n -u \u66F4\u65B0\u73FE\u6709\u6B78\u6A94\n -v \u5728\u6A19\u6E96\u8F38\u51FA\u4E2D\u7522\u751F\u8A73\u7D30\u8F38\u51FA\n -f \u6307\u5B9A\u6B78\u6A94\u6A94\u6848\u540D\u7A31\n -m \u5305\u542B\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u4E2D\u7684\u8CC7\u8A0A\u6E05\u55AE\u8CC7\u8A0A\n -e \u70BA\u7368\u7ACB\u61C9\u7528\u7A0B\u5F0F\u6307\u5B9A\u61C9\u7528\u7A0B\u5F0F\u9032\u5165\u9EDE\n \u5DF2\u96A8\u9644\u65BC\u53EF\u57F7\u884C jar \u6A94\u6848\u4E2D\n -0 \u50C5\u5132\u5B58; \u4E0D\u4F7F\u7528 ZIP \u58D3\u7E2E\u65B9\u5F0F\n -M \u4E0D\u70BA\u9805\u76EE\u5EFA\u7ACB\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\n -i \u70BA\u6307\u5B9A\u7684 jar \u6A94\u6848\u7522\u751F\u7D22\u5F15\u8CC7\u8A0A\n -C \u8B8A\u66F4\u81F3\u6307\u5B9A\u76EE\u9304\u4E26\u5305\u542B\u5F8C\u9762\u6240\u5217\u7684\u6A94\u6848\n\u5982\u679C\u6709\u4EFB\u4F55\u6A94\u6848\u662F\u76EE\u9304\uFF0C\u5247\u6703\u5C0D\u5176\u9032\u884C\u905E\u8FF4\u8655\u7406\u3002\n\u6E05\u55AE\u6A94\u6848\u540D\u7A31\u3001\u6B78\u6A94\u6A94\u6848\u540D\u7A31\u548C\u9032\u5165\u9EDE\u540D\u7A31\n\u7684\u6307\u5B9A\u9806\u5E8F\u8207\u6307\u5B9A 'm' \u65D7\u6A19\u3001'f' \u65D7\u6A19\u548C 'e' \u65D7\u6A19\u7684\u9806\u5E8F\u76F8\u540C\u3002\n\n\u7BC4\u4F8B 1: \u5C07\u5169\u500B\u985E\u5225\u6A94\u6848\u6B78\u6A94\u81F3\u540D\u70BA classes.jar \u7684\u6B78\u6A94\u4E2D: \n jar cvf classes.jar Foo.class Bar.class\n\u7BC4\u4F8B 2: \u4F7F\u7528\u73FE\u6709\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848 'mymanifest' \u4E26\u5C07\n foo/ \u76EE\u9304\u4E2D\u7684\u6240\u6709\u6A94\u6848\u6B78\u6A94\u81F3 'classes.jar' \u4E2D: \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties index c66ace77035..7c14da631e1 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties @@ -113,6 +113,7 @@ HOTSPOT_MBEANS_DIALOG_ACCESSIBLE_DESCRIPTION=Hotspot MBeans\u306E\u7BA1\u7406\u7 IMPACT=\u5F71\u97FF INFO=\u60C5\u5831 INFO_CAPITALIZED=INFO +INSECURE=\u4FDD\u8B77\u3055\u308C\u3066\u3044\u306A\u3044\u63A5\u7D9A INVALID_PLUGIN_PATH=\u8B66\u544A: \u7121\u52B9\u306A\u30D7\u30E9\u30B0\u30A4\u30F3\u30FB\u30D1\u30B9: {0} INVALID_URL=\u7121\u52B9\u306AURL: {0} IS=\u6B21\u306B\u4E00\u81F4\u3059\u308B @@ -135,14 +136,14 @@ MBEAN_OPERATION_INFO=MBeanOperationInfo MBEANS=MBeans MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON=\u30AF\u30EA\u30A2(&C) MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP=\u901A\u77E5\u306E\u30AF\u30EA\u30A2 -MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=\u30B3\u30F3\u30DD\u30B8\u30C3\u30C8\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3{0}/{1} -MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=\u30B3\u30F3\u30DD\u30B8\u30C3\u30C8\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3 +MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=\u30B3\u30F3\u30DD\u30B8\u30C3\u30C8\u30FB\u30C7\u30FC\u30BF\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3{0}/{1} +MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=\u30B3\u30F3\u30DD\u30B8\u30C3\u30C8\u30FB\u30C7\u30FC\u30BF\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3 MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON=\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5(&R) MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP=\u5C5E\u6027\u306E\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5 MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON=\u30B5\u30D6\u30B9\u30AF\u30E9\u30A4\u30D6(&S) MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=\u901A\u77E5\u30EA\u30B9\u30CB\u30F3\u30B0\u306E\u958B\u59CB -MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=\u30BF\u30D6\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3{0}/{1} -MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=\u30BF\u30D6\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3 +MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=\u30BF\u30D6\u30FB\u30C7\u30FC\u30BF\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3{0}/{1} +MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=\u30BF\u30D6\u30FB\u30C7\u30FC\u30BF\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3 MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON=\u30B5\u30D6\u30B9\u30AF\u30E9\u30A4\u30D6\u89E3\u9664(&U) MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=\u901A\u77E5\u30EA\u30B9\u30CB\u30F3\u30B0\u306E\u505C\u6B62 MANAGE_HOTSPOT_MBEANS_IN_COLON_=Hotspot MBeans\u306E\u7BA1\u7406: @@ -196,6 +197,11 @@ PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE={0}={1}\n PLOTTER_ACCESSIBLE_NAME_NO_DATA=\u30C7\u30FC\u30BF\u304C\u30D7\u30ED\u30C3\u30C8\u3055\u308C\u307E\u305B\u3093\u3002 PLOTTER_SAVE_AS_MENU_ITEM=\u540D\u524D\u3092\u4ED8\u3051\u3066\u30C7\u30FC\u30BF\u3092\u4FDD\u5B58(&A)... PLOTTER_TIME_RANGE_MENU=\u6642\u9593\u7BC4\u56F2(&T) +PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT=\u7D42\u4E86 +PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE=\u7121\u8996 +PLUGIN_EXCEPTION_DIALOG_BUTTON_OK=OK +PLUGIN_EXCEPTION_DIALOG_MESSAGE=%s\u3067\u4E88\u671F\u3057\u306A\u3044\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F:\n\n%s\n\n\u8A73\u7D30\u306F\u3001\u5148\u982D\u306B-debug\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u7121\u8996\u3059\u308B\u3068\u3001\u4F8B\u5916\u306F\u3053\u308C\u4EE5\u4E0A\u8868\u793A\u3055\u308C\u306A\u304F\u306A\u308A\u307E\u3059\u3002 +PLUGIN_EXCEPTION_DIALOG_TITLE=\u30D7\u30E9\u30B0\u30A4\u30F3\u4F8B\u5916 PROBLEM_ADDING_LISTENER=\u30EA\u30B9\u30CA\u30FC\u8FFD\u52A0\u4E2D\u306E\u554F\u984C PROBLEM_DISPLAYING_MBEAN=MBean\u8868\u793A\u4E2D\u306E\u554F\u984C PROBLEM_INVOKING=\u547C\u51FA\u3057\u4E2D\u306E\u554F\u984C @@ -223,6 +229,7 @@ SUMMARY_TAB_VM_VERSION={0}\u30D0\u30FC\u30B8\u30E7\u30F3{1} THREADS=\u30B9\u30EC\u30C3\u30C9 THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=\u30B9\u30EC\u30C3\u30C9\u60C5\u5831 THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=\u30B9\u30EC\u30C3\u30C9\u6570\u306E\u30C1\u30E3\u30FC\u30C8\u3002 +THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE=[\u30B9\u30EC\u30C3\u30C9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093] THRESHOLD=\u3057\u304D\u3044\u5024 TILE=\u4E26\u3079\u3066\u8868\u793A(&T) TIME_RANGE_COLON=\u6642\u9593\u7BC4\u56F2(&T): @@ -260,6 +267,8 @@ WINDOWS=\u30A6\u30A3\u30F3\u30C9\u30A6 WRITABLE=\u66F8\u8FBC\u307F\u53EF\u80FD CONNECTION_FAILED1=\u63A5\u7D9A\u306B\u5931\u6557\u3057\u307E\u3057\u305F: \u518D\u8A66\u884C\u3057\u307E\u3059\u304B\u3002 CONNECTION_FAILED2={0}\u3078\u306E\u63A5\u7D9A\u304C\u6210\u529F\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002
    \u3082\u3046\u4E00\u5EA6\u8A66\u3057\u307E\u3059\u304B\u3002 +CONNECTION_FAILED_SSL1=\u4FDD\u8B77\u3055\u308C\u305F\u63A5\u7D9A\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u4FDD\u8B77\u305B\u305A\u306B\u518D\u8A66\u884C\u3057\u307E\u3059\u304B\u3002 +CONNECTION_FAILED_SSL2=SSL\u3092\u4F7F\u7528\u3057\u3066{0}\u306B\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093\u3002
    SSL\u306A\u3057\u3067\u63A5\u7D9A\u3057\u307E\u3059\u304B\u3002
    (\u30E6\u30FC\u30B6\u30FC\u540D\u304A\u3088\u3073\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u30D7\u30EC\u30FC\u30F3\u30FB\u30C6\u30AD\u30B9\u30C8\u3067\u9001\u4FE1\u3055\u308C\u307E\u3059\u3002) CONNECTION_LOST1=\u63A5\u7D9A\u304C\u5931\u308F\u308C\u307E\u3057\u305F: \u518D\u63A5\u7D9A\u3057\u307E\u3059\u304B\u3002 CONNECTING_TO1={0}\u306B\u63A5\u7D9A\u4E2D CONNECTING_TO2={0}\u306B\u73FE\u5728\u63A5\u7D9A\u4E2D\u3067\u3059\u3002
    \u3053\u308C\u306B\u306F\u6570\u5206\u304B\u304B\u308A\u307E\u3059\u3002 diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties index 3f782adc620..eff5155bce7 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties @@ -113,6 +113,7 @@ HOTSPOT_MBEANS_DIALOG_ACCESSIBLE_DESCRIPTION=\u7528\u4E8E\u7BA1\u7406 HotSpot MB IMPACT=\u5F71\u54CD INFO=\u4FE1\u606F INFO_CAPITALIZED=\u4FE1\u606F +INSECURE=\u4E0D\u5B89\u5168\u7684\u8FDE\u63A5 INVALID_PLUGIN_PATH=\u8B66\u544A: \u63D2\u4EF6\u8DEF\u5F84\u65E0\u6548: {0} INVALID_URL=URL \u65E0\u6548: {0} IS=\u662F @@ -135,14 +136,14 @@ MBEAN_OPERATION_INFO=MBeanOperationInfo MBEANS=MBean MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON=\u6E05\u9664(&C) MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP=\u6E05\u9664\u901A\u77E5 -MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=\u7EC4\u5408\u5BFC\u822A{0}/{1} -MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=\u7EC4\u5408\u5BFC\u822A +MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=\u7EC4\u5408\u6570\u636E\u5BFC\u822A{0}/{1} +MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=\u7EC4\u5408\u6570\u636E\u5BFC\u822A MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON=\u5237\u65B0(&R) MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP=\u5237\u65B0\u5C5E\u6027 MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON=\u8BA2\u9605(&S) MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=\u5F00\u59CB\u76D1\u542C\u901A\u77E5 -MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=\u8868\u683C\u5F0F\u5BFC\u822A{0}/{1} -MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=\u8868\u683C\u5F0F\u5BFC\u822A +MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=\u8868\u683C\u5F0F\u6570\u636E\u5BFC\u822A{0}/{1} +MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=\u8868\u683C\u5F0F\u6570\u636E\u5BFC\u822A MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON=\u53D6\u6D88\u8BA2\u9605(&U) MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=\u505C\u6B62\u76D1\u542C\u901A\u77E5 MANAGE_HOTSPOT_MBEANS_IN_COLON_=\u7BA1\u7406\u4EE5\u4E0B\u4F4D\u7F6E\u7684 HotSpot MBean: @@ -196,6 +197,11 @@ PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE={0}={1}\n PLOTTER_ACCESSIBLE_NAME_NO_DATA=\u672A\u7ED8\u5236\u6570\u636E\u3002 PLOTTER_SAVE_AS_MENU_ITEM=\u5C06\u6570\u636E\u53E6\u5B58\u4E3A(&A)... PLOTTER_TIME_RANGE_MENU=\u65F6\u95F4\u8303\u56F4(&T) +PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT=\u9000\u51FA +PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE=\u5FFD\u7565 +PLUGIN_EXCEPTION_DIALOG_BUTTON_OK=\u786E\u5B9A +PLUGIN_EXCEPTION_DIALOG_MESSAGE=%s \u4E2D\u51FA\u73B0\u610F\u5916\u7684\u5F02\u5E38\u9519\u8BEF:\n\n%s\n\n\u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u8FD0\u884C\u4EE5 -debug \u5F00\u5934\u7684\u547D\u4EE4\u83B7\u53D6\u3002\u5982\u679C\u5FFD\u7565, \u5219\u5C06\u9690\u85CF\u540E\u9762\u7684\u5F02\u5E38\u9519\u8BEF\u3002 +PLUGIN_EXCEPTION_DIALOG_TITLE=\u63D2\u4EF6\u5F02\u5E38\u9519\u8BEF PROBLEM_ADDING_LISTENER=\u6DFB\u52A0\u76D1\u542C\u7A0B\u5E8F\u65F6\u51FA\u73B0\u95EE\u9898 PROBLEM_DISPLAYING_MBEAN=\u663E\u793A MBean \u65F6\u51FA\u73B0\u95EE\u9898 PROBLEM_INVOKING=\u8C03\u7528\u65F6\u51FA\u73B0\u95EE\u9898 @@ -223,6 +229,7 @@ SUMMARY_TAB_VM_VERSION={0}\u7248\u672C {1} THREADS=\u7EBF\u7A0B THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=\u7EBF\u7A0B\u4FE1\u606F THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=\u8868\u793A\u7EBF\u7A0B\u6570\u7684\u56FE\u8868\u3002 +THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE=[\u672A\u9009\u62E9\u7EBF\u7A0B] THRESHOLD=\u9608\u503C TILE=\u5E73\u94FA(&T) TIME_RANGE_COLON=\u65F6\u95F4\u8303\u56F4(&T): @@ -260,6 +267,8 @@ WINDOWS=\u7A97\u53E3 WRITABLE=\u53EF\u5199\u5165 CONNECTION_FAILED1=\u8FDE\u63A5\u5931\u8D25: \u662F\u5426\u91CD\u8BD5? CONNECTION_FAILED2=\u672A\u6210\u529F\u8FDE\u63A5\u5230{0}\u3002
    \u662F\u5426\u8981\u91CD\u8BD5? +CONNECTION_FAILED_SSL1=\u5B89\u5168\u8FDE\u63A5\u5931\u8D25\u3002\u662F\u5426\u4EE5\u4E0D\u5B89\u5168\u7684\u65B9\u5F0F\u91CD\u8BD5? +CONNECTION_FAILED_SSL2=\u65E0\u6CD5\u4F7F\u7528 SSL \u8FDE\u63A5\u5230{0}\u3002
    \u662F\u5426\u5728\u4E0D\u4F7F\u7528 SSL \u7684\u60C5\u51B5\u4E0B\u8FDB\u884C\u5C1D\u8BD5?
    (\u7528\u6237\u540D\u548C\u53E3\u4EE4\u5C06\u4EE5\u7EAF\u6587\u672C\u683C\u5F0F\u53D1\u9001\u3002) CONNECTION_LOST1=\u8FDE\u63A5\u4E22\u5931: \u662F\u5426\u91CD\u65B0\u8FDE\u63A5? CONNECTING_TO1=\u6B63\u5728\u8FDE\u63A5\u5230{0} CONNECTING_TO2=\u60A8\u5F53\u524D\u6B63\u5728\u8FDE\u63A5\u5230{0}\u3002
    \u8FD9\u5C06\u9700\u8981\u51E0\u5206\u949F\u7684\u65F6\u95F4\u3002 From 072f43e117657352a099187cbf051e407038b70b Mon Sep 17 00:00:00 2001 From: Michael Fang Date: Tue, 24 Sep 2013 14:20:33 -0700 Subject: [PATCH 0492/1294] 8025215: jdk8 l10n resource file translation update 4 Reviewed-by: naoto, yhuang --- .../html/resources/standard_ja.properties | 8 ++--- .../html/resources/standard_zh_CN.properties | 6 ++-- .../toolkit/resources/doclets_ja.properties | 14 ++++++-- .../resources/doclets_zh_CN.properties | 14 ++++++-- .../doclint/resources/doclint_ja.properties | 9 +++++- .../resources/doclint_zh_CN.properties | 8 ++++- .../javac/resources/compiler_ja.properties | 32 ++++++++++++++++--- .../javac/resources/compiler_zh_CN.properties | 32 ++++++++++++++++--- .../tools/javac/resources/javac_ja.properties | 11 +++++-- .../javac/resources/javac_zh_CN.properties | 11 +++++-- .../javadoc/resources/javadoc_ja.properties | 11 +++++-- .../resources/javadoc_zh_CN.properties | 11 +++++-- .../tools/javah/resources/l10n_ja.properties | 7 ++-- .../javah/resources/l10n_zh_CN.properties | 5 +-- .../tools/javap/resources/javap_ja.properties | 4 ++- .../javap/resources/javap_zh_CN.properties | 4 ++- 16 files changed, 145 insertions(+), 42 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_ja.properties b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_ja.properties index 373b5334c42..5592f1032d6 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_ja.properties @@ -185,9 +185,9 @@ doclet.Error_in_packagelist=-group\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u4F7F\u75 doclet.Groupname_already_used=-group\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u304A\u3044\u3066\u3001\u3059\u3067\u306B\u30B0\u30EB\u30FC\u30D7\u540D\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059: {0} doclet.Same_package_name_used=\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u5F62\u5F0F\u304C2\u56DE\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059: {0} doclet.exception_encountered={1}\u306E\u51E6\u7406\u4E2D\u306B\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\n{0} -doclet.usage=\u6A19\u6E96\u306Edoclet\u306B\u3088\u308A\u63D0\u4F9B\u3055\u308C\u308B\u3082\u306E:\n-d \u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u8EE2\u9001\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n-use \u30AF\u30E9\u30B9\u3068\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u4F7F\u7528\u30DA\u30FC\u30B8\u3092\u4F5C\u6210\u3059\u308B\n-version @version\u30D1\u30E9\u30B0\u30E9\u30D5\u3092\u542B\u3081\u308B\n-author @author\u30D1\u30E9\u30B0\u30E9\u30D5\u3092\u542B\u3081\u308B\n-docfilessubdirs doc-file\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u518D\u5E30\u7684\u306B\u30B3\u30D4\u30FC\u3059\u308B\n-splitindex 1\u5B57\u3054\u3068\u306B1\u30D5\u30A1\u30A4\u30EB\u306B\u7D22\u5F15\u3092\u5206\u5272\u3059\u308B\n-windowtitle \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u7528\u306E\u30D6\u30E9\u30A6\u30B6\u30FB\u30A6\u30A3\u30F3\u30C9\u30A6\u30FB\u30BF\u30A4\u30C8\u30EB\n-doctitle \u6982\u8981\u30DA\u30FC\u30B8\u306B\u30BF\u30A4\u30C8\u30EB\u3092\u542B\u3081\u308B\n-header \u5404\u30DA\u30FC\u30B8\u306B\u30D8\u30C3\u30C0\u30FC\u3092\u542B\u3081\u308B\n-footer \u5404\u30DA\u30FC\u30B8\u306B\u30D5\u30C3\u30BF\u30FC\u3092\u542B\u3081\u308B\n-top \u5404\u30DA\u30FC\u30B8\u306B\u4E0A\u90E8\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u308B\n-bottom \u5404\u30DA\u30FC\u30B8\u306B\u4E0B\u90E8\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u308B\n-link \u306Bjavadoc\u51FA\u529B\u3078\u306E\u30EA\u30F3\u30AF\u3092\u4F5C\u6210\u3059\u308B\n-linkoffline \u306B\u3042\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u4F7F\u7528\u3057\u3066\u306Edocs\u306B\u30EA\u30F3\u30AF\u3059\u308B\n-excludedocfilessubdir :.. \u6307\u5B9A\u3055\u308C\u305F\u540D\u524D\u306Edoc-files\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u3059\u3079\u3066\u9664\u5916\u3059\u308B\n-group :.. \u6307\u5B9A\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6982\u8981\u30DA\u30FC\u30B8\u306B\u304A\u3044\u3066\u30B0\u30EB\u30FC\u30D7\u5316\u3059\u308B\n-nocomment \u8A18\u8FF0\u304A\u3088\u3073\u30BF\u30B0\u3092\u6291\u5236\u3057\u3066\u5BA3\u8A00\u306E\u307F\u3092\u751F\u6210\u3059\u308B\n-nodeprecated @deprecated\u60C5\u5831\u3092\u9664\u5916\u3059\u308B\n-noqualifier ::... \u51FA\u529B\u304B\u3089\u4FEE\u98FE\u5B50\u306E\u30EA\u30B9\u30C8\u3092\u9664\u5916\u3059\u308B\n-nosince @since\u60C5\u5831\u3092\u9664\u5916\u3059\u308B\n-notimestamp \u975E\u8868\u793A\u306E\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u3092\u9664\u5916\u3059\u308B\n-nodeprecatedlist \u975E\u63A8\u5968\u306E\u30EA\u30B9\u30C8\u3092\u751F\u6210\u3057\u306A\u3044\n-notree \u30AF\u30E9\u30B9\u968E\u5C64\u3092\u751F\u6210\u3057\u306A\u3044\n-noindex \u7D22\u5F15\u3092\u751F\u6210\u3057\u306A\u3044\n-nohelp \u30D8\u30EB\u30D7\u30FB\u30EA\u30F3\u30AF\u3092\u751F\u6210\u3057\u306A\u3044\n-nonavbar \u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3\u30FB\u30D0\u30FC\u3092\u751F\u6210\u3057\u306A\u3044\n-serialwarn @serial\u30BF\u30B0\u306B\u95A2\u3059\u308B\u8B66\u544A\u3092\u751F\u6210\u3059\u308B\n-tag ::
    \u5358\u4E00\u306E\u5F15\u6570\u3092\u6301\u3064\u30AB\u30B9\u30BF\u30E0\u30FB\u30BF\u30B0\u3092\u6307\u5B9A\u3059\u308B\n-taglet \u30BF\u30B0\u30EC\u30C3\u30C8\u306E\u5B8C\u5168\u4FEE\u98FE\u540D\u3092\u767B\u9332\u3059\u308B\n-tagletpath \u30BF\u30B0\u30EC\u30C3\u30C8\u306E\u30D1\u30B9\n-Xdocrootparent \ - \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30B3\u30E1\u30F3\u30C8\u5185\u306E@docRoot(\u3053\u306E\u5F8C\u306B\u306F/..\u304C\u7D9A\u304F)\u306E\u3059\u3079\u3066\u306E\u51FA\u73FE\u7B87\u6240\u3092\u3067\u7F6E\u63DB\u3059\u308B\n-charset \u751F\u6210\u3055\u308C\u308B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30AF\u30ED\u30B9\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u3067\u306E\u6587\u5B57\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\n-helpfile \u30D8\u30EB\u30D7\u30FB\u30EA\u30F3\u30AF\u306E\u30EA\u30F3\u30AF\u5148\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u308B\n-linksource HTML\u5F62\u5F0F\u3067\u30BD\u30FC\u30B9\u3092\u751F\u6210\u3059\u308B\n-sourcetab \u30BD\u30FC\u30B9\u5185\u306E\u30BF\u30D6\u306E\u7A7A\u767D\u6587\u5B57\u306E\u6570\u3092\u6307\u5B9A\u3059\u308B\n-keywords HTML\u306Emeta\u30BF\u30B0\u306B\u3001\u30D1\u30C3\u30B1\u30FC\u30B8\u3001\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u60C5\u5831\u3092\u542B\u3081\u308B\n-stylesheetfile \u751F\u6210\u3055\u308C\u305F\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30B9\u30BF\u30A4\u30EB\u5909\u66F4\u7528\u30D5\u30A1\u30A4\u30EB\n-docencoding \u51FA\u529B\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u540D - - +doclet.usage=\u6A19\u6E96\u306Edoclet\u306B\u3088\u308A\u63D0\u4F9B\u3055\u308C\u308B\u3082\u306E:\n-d \u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u8EE2\u9001\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n-use \u30AF\u30E9\u30B9\u3068\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u4F7F\u7528\u30DA\u30FC\u30B8\u3092\u4F5C\u6210\u3059\u308B\n-version @version\u30D1\u30E9\u30B0\u30E9\u30D5\u3092\u542B\u3081\u308B\n-author @author\u30D1\u30E9\u30B0\u30E9\u30D5\u3092\u542B\u3081\u308B\n-docfilessubdirs doc-file\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u518D\u5E30\u7684\u306B\u30B3\u30D4\u30FC\u3059\u308B\n-splitindex 1\u5B57\u3054\u3068\u306B1\u30D5\u30A1\u30A4\u30EB\u306B\u7D22\u5F15\u3092\u5206\u5272\u3059\u308B\n-windowtitle \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u7528\u306E\u30D6\u30E9\u30A6\u30B6\u30FB\u30A6\u30A3\u30F3\u30C9\u30A6\u30FB\u30BF\u30A4\u30C8\u30EB\n-doctitle \u6982\u8981\u30DA\u30FC\u30B8\u306B\u30BF\u30A4\u30C8\u30EB\u3092\u542B\u3081\u308B\n-header \u5404\u30DA\u30FC\u30B8\u306B\u30D8\u30C3\u30C0\u30FC\u3092\u542B\u3081\u308B\n-footer \u5404\u30DA\u30FC\u30B8\u306B\u30D5\u30C3\u30BF\u30FC\u3092\u542B\u3081\u308B\n-top \u5404\u30DA\u30FC\u30B8\u306B\u4E0A\u90E8\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u308B\n-bottom \u5404\u30DA\u30FC\u30B8\u306B\u4E0B\u90E8\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u308B\n-link \u306Bjavadoc\u51FA\u529B\u3078\u306E\u30EA\u30F3\u30AF\u3092\u4F5C\u6210\u3059\u308B\n-linkoffline \u306B\u3042\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u4F7F\u7528\u3057\u3066\u306Edocs\u306B\u30EA\u30F3\u30AF\u3059\u308B\n-excludedocfilessubdir :.. \u6307\u5B9A\u3055\u308C\u305F\u540D\u524D\u306Edoc-files\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u3059\u3079\u3066\u9664\u5916\u3059\u308B\n-group :.. \u6307\u5B9A\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6982\u8981\u30DA\u30FC\u30B8\u306B\u304A\u3044\u3066\u30B0\u30EB\u30FC\u30D7\u5316\u3059\u308B\n-nocomment \u8A18\u8FF0\u304A\u3088\u3073\u30BF\u30B0\u3092\u6291\u5236\u3057\u3066\u5BA3\u8A00\u306E\u307F\u3092\u751F\u6210\u3059\u308B\n-nodeprecated @deprecated\u60C5\u5831\u3092\u9664\u5916\u3059\u308B\n-noqualifier ::... \u51FA\u529B\u304B\u3089\u4FEE\u98FE\u5B50\u306E\u30EA\u30B9\u30C8\u3092\u9664\u5916\u3059\u308B\n-nosince @since\u60C5\u5831\u3092\u9664\u5916\u3059\u308B\n-notimestamp \u975E\u8868\u793A\u306E\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u3092\u9664\u5916\u3059\u308B\n-nodeprecatedlist \u975E\u63A8\u5968\u306E\u30EA\u30B9\u30C8\u3092\u751F\u6210\u3057\u306A\u3044\n-notree \u30AF\u30E9\u30B9\u968E\u5C64\u3092\u751F\u6210\u3057\u306A\u3044\n-noindex \u7D22\u5F15\u3092\u751F\u6210\u3057\u306A\u3044\n-nohelp \u30D8\u30EB\u30D7\u30FB\u30EA\u30F3\u30AF\u3092\u751F\u6210\u3057\u306A\u3044\n-nonavbar \u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3\u30FB\u30D0\u30FC\u3092\u751F\u6210\u3057\u306A\u3044\n-serialwarn @serial\u30BF\u30B0\u306B\u95A2\u3059\u308B\u8B66\u544A\u3092\u751F\u6210\u3059\u308B\n-tag ::
    \u5358\u4E00\u306E\u5F15\u6570\u3092\u6301\u3064\u30AB\u30B9\u30BF\u30E0\u30FB\u30BF\u30B0\u3092\u6307\u5B9A\u3059\u308B\n-taglet \u30BF\u30B0\u30EC\u30C3\u30C8\u306E\u5B8C\u5168\u4FEE\u98FE\u540D\u3092\u767B\u9332\u3059\u308B\n-tagletpath \u30BF\u30B0\u30EC\u30C3\u30C8\u306E\u30D1\u30B9\n-charset \ + \u751F\u6210\u3055\u308C\u308B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30AF\u30ED\u30B9\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u3067\u306E\u6587\u5B57\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\n-helpfile \u30D8\u30EB\u30D7\u30FB\u30EA\u30F3\u30AF\u306E\u30EA\u30F3\u30AF\u5148\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u308B\n-linksource HTML\u5F62\u5F0F\u3067\u30BD\u30FC\u30B9\u3092\u751F\u6210\u3059\u308B\n-sourcetab \u30BD\u30FC\u30B9\u5185\u306E\u30BF\u30D6\u306E\u7A7A\u767D\u6587\u5B57\u306E\u6570\u3092\u6307\u5B9A\u3059\u308B\n-keywords HTML\u306Emeta\u30BF\u30B0\u306B\u3001\u30D1\u30C3\u30B1\u30FC\u30B8\u3001\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u60C5\u5831\u3092\u542B\u3081\u308B\n-stylesheetfile \u751F\u6210\u3055\u308C\u305F\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30B9\u30BF\u30A4\u30EB\u5909\u66F4\u7528\u30D5\u30A1\u30A4\u30EB\n-docencoding \u51FA\u529B\u306E\u6587\u5B57\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u3092\u6307\u5B9A\u3059\u308B +# L10N: do not localize these words: all none accessibility html missing reference syntax +doclet.X.usage=\u6A19\u6E96\u306Edoclet\u306B\u3088\u308A\u63D0\u4F9B\u3055\u308C\u308B\u3082\u306E:\n -Xdocrootparent doc\u30B3\u30E1\u30F3\u30C8\u5185\u306E/..\u304C\u5F8C\u306B\u7D9A\u304F@docRoot\u306E\u3059\u3079\u3066\u3092\n \u3067\u7F6E\u63DB\u3057\u307E\u3059\n -Xdoclint javadoc\u30B3\u30E1\u30F3\u30C8\u5185\u306E\u554F\u984C\u306B\u5BFE\u3059\u308B\u63A8\u5968\u3055\u308C\u308B\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3057\u307E\u3059\n -Xdoclint:(all|none|[-]) \n javadoc\u30B3\u30E1\u30F3\u30C8\u5185\u306E\u554F\u984C\u306B\u5BFE\u3059\u308B\u7279\u5B9A\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002\n \u3053\u3053\u3067\u3001\u306Fhtml\u3001missing\u3001reference\u307E\u305F\u306Fsyntax\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002\n diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_zh_CN.properties index 61fd72cbe10..23d1b9b46d1 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_zh_CN.properties @@ -185,8 +185,8 @@ doclet.Error_in_packagelist=\u4F7F\u7528 -group \u9009\u9879\u65F6\u51FA\u9519: doclet.Groupname_already_used=\u5728 -group \u9009\u9879\u4E2D, groupname \u5DF2\u4F7F\u7528: {0} doclet.Same_package_name_used=\u7A0B\u5E8F\u5305\u540D\u79F0\u5F62\u5F0F\u4F7F\u7528\u4E86\u4E24\u6B21: {0} doclet.exception_encountered=\u5904\u7406{1}\u65F6\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF\n{0} -doclet.usage=\u901A\u8FC7\u6807\u51C6 doclet \u63D0\u4F9B:\n-d \u8F93\u51FA\u6587\u4EF6\u7684\u76EE\u6807\u76EE\u5F55\n-use \u521B\u5EFA\u7C7B\u548C\u7A0B\u5E8F\u5305\u7528\u6CD5\u9875\u9762\n-version \u5305\u542B @version \u6BB5\n-author \u5305\u542B @author \u6BB5\n-docfilessubdirs \u9012\u5F52\u590D\u5236\u6587\u6863\u6587\u4EF6\u5B50\u76EE\u5F55\n-splitindex \u5C06\u7D22\u5F15\u5206\u4E3A\u6BCF\u4E2A\u5B57\u6BCD\u5BF9\u5E94\u4E00\u4E2A\u6587\u4EF6\n-windowtitle \u6587\u6863\u7684\u6D4F\u89C8\u5668\u7A97\u53E3\u6807\u9898\n-doctitle \u5305\u542B\u6982\u89C8\u9875\u9762\u7684\u6807\u9898\n-header \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u7709\u6587\u672C\n-footer \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u811A\u6587\u672C\n-top \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9876\u90E8\u6587\u672C\n-bottom \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u5E95\u90E8\u6587\u672C\n-link \u521B\u5EFA\u6307\u5411\u4F4D\u4E8E \u7684 javadoc \u8F93\u51FA\u7684\u94FE\u63A5\n-linkoffline \u5229\u7528\u4F4D\u4E8E \u7684\u7A0B\u5E8F\u5305\u5217\u8868\u94FE\u63A5\u81F3\u4F4D\u4E8E \u7684\u6587\u6863\n-excludedocfilessubdir :.. \u6392\u9664\u5177\u6709\u7ED9\u5B9A\u540D\u79F0\u7684\u6240\u6709\u6587\u6863\u6587\u4EF6\u5B50\u76EE\u5F55\u3002\n-group :.. \u5728\u6982\u89C8\u9875\u9762\u4E2D, \u5C06\u6307\u5B9A\u7684\u7A0B\u5E8F\u5305\u5206\u7EC4\n-nocomment \u4E0D\u751F\u6210\u8BF4\u660E\u548C\u6807\u8BB0, \u53EA\u751F\u6210\u58F0\u660E\u3002\n-nodeprecated \u4E0D\u5305\u542B @deprecated \u4FE1\u606F\n-noqualifier ::... \u8F93\u51FA\u4E2D\u4E0D\u5305\u62EC\u9650\u5B9A\u7B26\u7684\u5217\u8868\u3002\n-nosince \u4E0D\u5305\u542B @since \u4FE1\u606F\n-notimestamp \u4E0D\u5305\u542B\u9690\u85CF\u65F6\u95F4\u6233\n-nodeprecatedlist \u4E0D\u751F\u6210\u5DF2\u8FC7\u65F6\u7684\u5217\u8868\n-notree \u4E0D\u751F\u6210\u7C7B\u5206\u5C42\u7ED3\u6784\n-noindex \u4E0D\u751F\u6210\u7D22\u5F15\n-nohelp \u4E0D\u751F\u6210\u5E2E\u52A9\u94FE\u63A5\n-nonavbar \u4E0D\u751F\u6210\u5BFC\u822A\u680F\n-serialwarn \u751F\u6210\u6709\u5173 @serial \u6807\u8BB0\u7684\u8B66\u544A\n-tag ::
    \u6307\u5B9A\u5355\u4E2A\u53C2\u6570\u5B9A\u5236\u6807\u8BB0\n-taglet \u8981\u6CE8\u518C\u7684 Taglet \u7684\u5168\u9650\u5B9A\u540D\u79F0\n-tagletpath Taglet \u7684\u8DEF\u5F84\n-Xdocrootparent \u5C06\u6587\u6863\u6CE8\u91CA\u4E2D\u51FA\u73B0\u7684\u6240\u6709\u540E\u8DDF /.. \u7684 @docRoot \u66FF\u6362\u4E3A \n-charset \u7528\u4E8E\u8DE8\u5E73\u53F0\u67E5\u770B\u751F\u6210\u7684\u6587\u6863\u7684\u5B57\u7B26\u96C6\u3002\n-helpfile \u5305\u542B\u5E2E\u52A9\u94FE\u63A5\u6240\u94FE\u63A5\u5230\u7684\u6587\u4EF6\n-linksource \u4EE5 HTML \u683C\u5F0F\u751F\u6210\u6E90\u6587\u4EF6\n-sourcetab \u6307\u5B9A\u6E90\u4E2D\u6BCF\u4E2A\u5236\u8868\u7B26\u5360\u636E\u7684\u7A7A\u683C\u6570\n-keywords \u4F7F\u7A0B\u5E8F\u5305, \u7C7B\u548C\u6210\u5458\u4FE1\u606F\u9644\u5E26 HTML \u5143\u6807\u8BB0\n-stylesheetfile \u7528\u4E8E\u66F4\u6539\u751F\u6210\u6587\u6863\u7684\u6837\u5F0F\u7684\u6587\u4EF6\n-docencoding \u8F93\u51FA\u7F16\u7801\u540D\u79F0 - - +doclet.usage=\u901A\u8FC7\u6807\u51C6 doclet \u63D0\u4F9B:\n -d \u8F93\u51FA\u6587\u4EF6\u7684\u76EE\u6807\u76EE\u5F55\n -use \u521B\u5EFA\u7C7B\u548C\u7A0B\u5E8F\u5305\u7528\u6CD5\u9875\u9762\n -version \u5305\u542B @version \u6BB5\n -author \u5305\u542B @author \u6BB5\n -docfilessubdirs \u9012\u5F52\u590D\u5236\u6587\u6863\u6587\u4EF6\u5B50\u76EE\u5F55\n -splitindex \u5C06\u7D22\u5F15\u5206\u4E3A\u6BCF\u4E2A\u5B57\u6BCD\u5BF9\u5E94\u4E00\u4E2A\u6587\u4EF6\n -windowtitle \u6587\u6863\u7684\u6D4F\u89C8\u5668\u7A97\u53E3\u6807\u9898\n -doctitle \u5305\u542B\u6982\u89C8\u9875\u9762\u7684\u6807\u9898\n -header \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u7709\u6587\u672C\n -footer \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u811A\u6587\u672C\n -top \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9876\u90E8\u6587\u672C\n -bottom \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u5E95\u90E8\u6587\u672C\n -link \u521B\u5EFA\u6307\u5411\u4F4D\u4E8E \u7684 javadoc \u8F93\u51FA\u7684\u94FE\u63A5\n -linkoffline \u5229\u7528\u4F4D\u4E8E \u7684\u7A0B\u5E8F\u5305\u5217\u8868\u94FE\u63A5\u81F3\u4F4D\u4E8E \u7684\u6587\u6863\n -excludedocfilessubdir :.. \u6392\u9664\u5177\u6709\u7ED9\u5B9A\u540D\u79F0\u7684\u6240\u6709\u6587\u6863\u6587\u4EF6\u5B50\u76EE\u5F55\u3002\n -group :.. \u5728\u6982\u89C8\u9875\u9762\u4E2D, \u5C06\u6307\u5B9A\u7684\u7A0B\u5E8F\u5305\u5206\u7EC4\n -nocomment \u4E0D\u751F\u6210\u8BF4\u660E\u548C\u6807\u8BB0, \u53EA\u751F\u6210\u58F0\u660E\u3002\n -nodeprecated \u4E0D\u5305\u542B @deprecated \u4FE1\u606F\n -noqualifier ::... \u8F93\u51FA\u4E2D\u4E0D\u5305\u62EC\u6307\u5B9A\u9650\u5B9A\u7B26\u7684\u5217\u8868\u3002\n -nosince \u4E0D\u5305\u542B @since \u4FE1\u606F\n -notimestamp \u4E0D\u5305\u542B\u9690\u85CF\u65F6\u95F4\u6233\n -nodeprecatedlist \u4E0D\u751F\u6210\u5DF2\u8FC7\u65F6\u7684\u5217\u8868\n -notree \u4E0D\u751F\u6210\u7C7B\u5206\u5C42\u7ED3\u6784\n -noindex \u4E0D\u751F\u6210\u7D22\u5F15\n -nohelp \u4E0D\u751F\u6210\u5E2E\u52A9\u94FE\u63A5\n -nonavbar \u4E0D\u751F\u6210\u5BFC\u822A\u680F\n -serialwarn \u751F\u6210\u6709\u5173 @serial \u6807\u8BB0\u7684\u8B66\u544A\n -tag ::
    \u6307\u5B9A\u5355\u4E2A\u53C2\u6570\u5B9A\u5236\u6807\u8BB0\n -taglet \u8981\u6CE8\u518C\u7684 Taglet \u7684\u5168\u9650\u5B9A\u540D\u79F0\n -tagletpath Taglet \u7684\u8DEF\u5F84\n -charset \u7528\u4E8E\u8DE8\u5E73\u53F0\u67E5\u770B\u751F\u6210\u7684\u6587\u6863\u7684\u5B57\u7B26\u96C6\u3002\n -helpfile \u5305\u542B\u5E2E\u52A9\u94FE\u63A5\u6240\u94FE\u63A5\u5230\u7684\u6587\u4EF6\n -linksource \u4EE5 HTML \u683C\u5F0F\u751F\u6210\u6E90\u6587\u4EF6\n -sourcetab \u6307\u5B9A\u6E90\u4E2D\u6BCF\u4E2A\u5236\u8868\u7B26\u5360\u636E\u7684\u7A7A\u683C\u6570\n -keywords \u4F7F\u7A0B\u5E8F\u5305, \u7C7B\u548C\u6210\u5458\u4FE1\u606F\u9644\u5E26 HTML \u5143\u6807\u8BB0\n -stylesheetfile \u7528\u4E8E\u66F4\u6539\u751F\u6210\u6587\u6863\u7684\u6837\u5F0F\u7684\u6587\u4EF6\n -docencoding \u6307\u5B9A\u8F93\u51FA\u7684\u5B57\u7B26\u7F16\u7801 +# L10N: do not localize these words: all none accessibility html missing reference syntax +doclet.X.usage=\u901A\u8FC7\u6807\u51C6 doclet \u63D0\u4F9B:\n -Xdocrootparent \u4F7F\u7528 \u66FF\u6362\u6587\u6863\u6CE8\u91CA\u4E2D\u51FA\u73B0\u7684\n \u6240\u6709\u5176\u540E\u8DDF\u968F /.. \u7684 @docRoot\n -Xdoclint \u4E3A javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u5EFA\u8BAE\u7684\u68C0\u67E5\n -Xdoclint:(all|none|[-]) \n \u5BF9 javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u68C0\u67E5\u3002\n \u5176\u4E2D \u662F accessibility, html, missing, reference \u6216 syntax \u4E4B\u4E00\u3002\n diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_ja.properties b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_ja.properties index 82509fc3a63..24909fe13c1 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_ja.properties @@ -174,6 +174,16 @@ doclet.Value=\u5024 doclet.0_and_1={0}\u3068{1} #Documentation for Enums -doclet.enum_values_doc=\n\u3053\u306E\u5217\u6319\u578B\u306E\u5B9A\u6570\u3092\u542B\u3080\u914D\u5217\u3092\u5BA3\u8A00\u3055\u308C\u3066\u3044\u308B\u9806\u5E8F\u3067\u8FD4\u3057\u307E\u3059\u3002\n\u3053\u306E\u30E1\u30BD\u30C3\u30C9\u306F\u6B21\u306E\u3088\u3046\u306B\u3057\u3066\u5B9A\u6570\u3092\u53CD\u5FA9\u3059\u308B\u305F\u3081\u306B\n\u4F7F\u7528\u3067\u304D\u307E\u3059:\n
    \nfor({0} c: {0}.values())\n  System.out.println(c);\n
    \n@return\u3053\u306E\u5217\u6319\u578B\u306E\u5B9A\u6570\u3092\u5BA3\u8A00\u3055\u308C\u3066\u3044\u308B\u9806\u5E8F\u3067\n\u542B\u3080\u914D\u5217 +doclet.enum_values_doc.main=\n\u3053\u306E\u5217\u6319\u578B\u306E\u5B9A\u6570\u3092\u542B\u3080\u914D\u5217\u3092\u5BA3\u8A00\u3055\u308C\u3066\u3044\u308B\u9806\u5E8F\u3067\u8FD4\u3057\u307E\u3059\u3002\n\u3053\u306E\u30E1\u30BD\u30C3\u30C9\u306F\u6B21\u306E\u3088\u3046\u306B\u3057\u3066\u5B9A\u6570\u3092\u53CD\u5FA9\u3059\u308B\u305F\u3081\u306B\n\u4F7F\u7528\u3067\u304D\u307E\u3059:\n
    \nfor({0} c: {0}.values())\n  System.out.println(c);\n
    \n -doclet.enum_valueof_doc=\n\u6307\u5B9A\u3057\u305F\u540D\u524D\u3092\u6301\u3064\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u8FD4\u3057\u307E\u3059\u3002\n\u6587\u5B57\u5217\u306F\u3001\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u5BA3\u8A00\u3059\u308B\u306E\u306B\u4F7F\u7528\u3057\u305F\u8B58\u5225\u5B50\u3068\u6B63\u78BA\u306B\n\u4E00\u81F4\u3057\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n(\u4F59\u5206\u306A\u7A7A\u767D\u6587\u5B57\u3092\u542B\u3081\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002)\n\n@param name\u8FD4\u3055\u308C\u308B\u5217\u6319\u578B\u5B9A\u6570\u306E\u540D\u524D\n@return\u6307\u5B9A\u3055\u308C\u305F\u540D\u524D\u3092\u6301\u3064\u5217\u6319\u578B\u5B9A\u6570\n@throws IllegalArgumentException\u6307\u5B9A\u3055\u308C\u305F\u540D\u524D\u3092\u6301\u3064\u5B9A\u6570\u3092\n\u3053\u306E\u5217\u6319\u578B\u304C\u6301\u3063\u3066\u3044\u306A\u3044\u5834\u5408\n@throws NullPointerException\u5F15\u6570\u304Cnull\u306E\u5834\u5408 +doclet.enum_values_doc.return=\n\u3053\u306E\u5217\u6319\u578B\u306E\u5B9A\u6570\u3092\u542B\u3080\u3001\u5BA3\u8A00\u3055\u308C\u3066\u3044\u308B\u9806\u5E8F\u3067\u306E\u914D\u5217 + +doclet.enum_valueof_doc.main=\n\u6307\u5B9A\u3057\u305F\u540D\u524D\u3092\u6301\u3064\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u8FD4\u3057\u307E\u3059\u3002\n\u6587\u5B57\u5217\u306F\u3001\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u5BA3\u8A00\u3059\u308B\u306E\u306B\u4F7F\u7528\u3057\u305F\u8B58\u5225\u5B50\u3068\u6B63\u78BA\u306B\n\u4E00\u81F4\u3057\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n(\u4F59\u5206\u306A\u7A7A\u767D\u6587\u5B57\u3092\u542B\u3081\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002)\n + +doclet.enum_valueof_doc.param_name=\u8FD4\u3055\u308C\u308B\u5217\u6319\u578B\u5B9A\u6570\u306E\u540D\u524D\u3002 + +doclet.enum_valueof_doc.return=\u6307\u5B9A\u3057\u305F\u540D\u524D\u306E\u5217\u6319\u578B\u5B9A\u6570 + +doclet.enum_valueof_doc.throws_ila=\u3053\u306E\u5217\u6319\u578B\u306B\u3001\u6307\u5B9A\u3057\u305F\u540D\u524D\u306E\u5B9A\u6570\u304C\u306A\u3044\u5834\u5408 + +doclet.enum_valueof_doc.throws_npe=\u5F15\u6570\u304Cnull\u306E\u5834\u5408 diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_zh_CN.properties index 602682459a4..905a179fdb4 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_zh_CN.properties @@ -174,6 +174,16 @@ doclet.Value=\u503C doclet.0_and_1={0}\u548C{1} #Documentation for Enums -doclet.enum_values_doc=\n\u6309\u7167\u58F0\u660E\u8BE5\u679A\u4E3E\u7C7B\u578B\u7684\u5E38\u91CF\u7684\u987A\u5E8F, \u8FD4\u56DE\n\u5305\u542B\u8FD9\u4E9B\u5E38\u91CF\u7684\u6570\u7EC4\u3002\u8BE5\u65B9\u6CD5\u53EF\u7528\u4E8E\u8FED\u4EE3\n\u5E38\u91CF, \u5982\u4E0B\u6240\u793A:\n
    \nfor ({0} c : {0}.values())\n    System.out.println(c);\n
    \n@return \u6309\u7167\u58F0\u660E\u8BE5\u679A\u4E3E\u7C7B\u578B\u7684\u5E38\u91CF\u7684\u987A\u5E8F, \u8FD4\u56DE\n\u5305\u542B\u8FD9\u4E9B\u5E38\u91CF\u7684\u6570\u7EC4 +doclet.enum_values_doc.main=\n\u6309\u7167\u58F0\u660E\u8BE5\u679A\u4E3E\u7C7B\u578B\u7684\u5E38\u91CF\u7684\u987A\u5E8F, \u8FD4\u56DE\n\u5305\u542B\u8FD9\u4E9B\u5E38\u91CF\u7684\u6570\u7EC4\u3002\u8BE5\u65B9\u6CD5\u53EF\u7528\u4E8E\u8FED\u4EE3\n\u5E38\u91CF, \u5982\u4E0B\u6240\u793A:\n
    \nfor ({0} c : {0}.values())\n    System.out.println(c);\n
    -doclet.enum_valueof_doc=\n\u8FD4\u56DE\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u3002\n\u5B57\u7B26\u4E32\u5FC5\u987B\u4E0E\u7528\u4E8E\u58F0\u660E\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u7684\n\u6807\u8BC6\u7B26\u5B8C\u5168\u5339\u914D\u3002(\u4E0D\u5141\u8BB8\u6709\u591A\u4F59\n\u7684\u7A7A\u683C\u5B57\u7B26\u3002)\n\n@param name \u8981\u8FD4\u56DE\u7684\u679A\u4E3E\u5E38\u91CF\u7684\u540D\u79F0\u3002\n@return \u8FD4\u56DE\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u679A\u4E3E\u5E38\u91CF\n@throws \u5982\u679C\u8BE5\u679A\u4E3E\u7C7B\u578B\u6CA1\u6709\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u5E38\u91CF, \n\u5219\u629B\u51FA IllegalArgumentException\n@throws \u5982\u679C\u53C2\u6570\u4E3A\u7A7A\u503C, \u5219\u629B\u51FA NullPointerException +doclet.enum_values_doc.return=\n\u6309\u7167\u58F0\u660E\u8BE5\u679A\u4E3E\u7C7B\u578B\u7684\u5E38\u91CF\u7684\u987A\u5E8F\u8FD4\u56DE\u7684\u5305\u542B\u8FD9\u4E9B\u5E38\u91CF\u7684\u6570\u7EC4 + +doclet.enum_valueof_doc.main=\n\u8FD4\u56DE\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u3002\n\u5B57\u7B26\u4E32\u5FC5\u987B\u4E0E\u7528\u4E8E\u58F0\u660E\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u7684\n\u6807\u8BC6\u7B26\u5B8C\u5168\u5339\u914D\u3002(\u4E0D\u5141\u8BB8\u6709\u591A\u4F59\n\u7684\u7A7A\u683C\u5B57\u7B26\u3002) + +doclet.enum_valueof_doc.param_name=\u8981\u8FD4\u56DE\u7684\u679A\u4E3E\u5E38\u91CF\u7684\u540D\u79F0\u3002 + +doclet.enum_valueof_doc.return=\u8FD4\u56DE\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u679A\u4E3E\u5E38\u91CF + +doclet.enum_valueof_doc.throws_ila=\u5982\u679C\u8BE5\u679A\u4E3E\u7C7B\u578B\u6CA1\u6709\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u5E38\u91CF + +doclet.enum_valueof_doc.throws_npe=\u5982\u679C\u53C2\u6570\u4E3A\u7A7A\u503C diff --git a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_ja.properties b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_ja.properties index 10282be9632..6089737db60 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_ja.properties @@ -26,6 +26,7 @@ dc.anchor.already.defined = \u30A2\u30F3\u30AB\u30FC\u304C\u3059\u3067\u306B\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u307E\u3059: {0} dc.anchor.value.missing = \u30A2\u30F3\u30AB\u30FC\u306B\u5024\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093 dc.attr.lacks.value = \u5C5E\u6027\u306B\u5024\u304C\u3042\u308A\u307E\u305B\u3093 +dc.attr.not.number = \u5C5E\u6027\u5024\u304C\u6570\u5B57\u3067\u306F\u3042\u308A\u307E\u305B\u3093 dc.attr.obsolete = \u5C5E\u6027\u306F\u5EC3\u6B62\u3055\u308C\u3066\u3044\u307E\u3059: {0} dc.attr.obsolete.use.css = \u5C5E\u6027\u306F\u5EC3\u6B62\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u304B\u308F\u308A\u306BCSS\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044: {0} dc.attr.repeated = \u7E70\u308A\u8FD4\u3055\u308C\u305F\u5C5E\u6027: {0} @@ -46,7 +47,7 @@ dc.missing.return = @return\u304C\u3042\u308A\u307E\u305B\u3093 dc.missing.throws = {0}\u306E@throws\u304C\u3042\u308A\u307E\u305B\u3093 dc.no.alt.attr.for.image = \u30A4\u30E1\u30FC\u30B8\u306E"alt"\u5C5E\u6027\u304C\u3042\u308A\u307E\u305B\u3093 dc.no.summary.or.caption.for.table=\u8868\u306E\u8981\u7D04\u307E\u305F\u306F\u30AD\u30E3\u30D7\u30B7\u30E7\u30F3\u304C\u3042\u308A\u307E\u305B\u3093 -dc.param.name.not.found = @param\u540D\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 +dc.param.name.not.found = @param name\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 dc.ref.not.found = \u53C2\u7167\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 dc.tag.code.within.code = \u5185\u306E'{@code'} dc.tag.empty = \u7A7A\u306E<{0}>\u30BF\u30B0 @@ -66,3 +67,9 @@ dc.tag.self.closing = \u81EA\u5DF1\u7D42\u4E86\u8981\u7D20\u306F\u4F7F\u7528\u30 dc.tag.start.unmatched = \u7D42\u4E86\u30BF\u30B0\u304C\u3042\u308A\u307E\u305B\u3093: dc.tag.unknown = \u4E0D\u660E\u306A\u30BF\u30B0: {0} dc.text.not.allowed = <{0}>\u8981\u7D20\u3067\u306F\u30C6\u30AD\u30B9\u30C8\u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093 +dc.unexpected.comment=\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u30FB\u30B3\u30E1\u30F3\u30C8\u306F\u3053\u3053\u3067\u306F\u5FC5\u8981\u3042\u308A\u307E\u305B\u3093 + +dc.main.ioerror=IO\u30A8\u30E9\u30FC: {0} +dc.main.no.files.given=\u30D5\u30A1\u30A4\u30EB\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093 +dc.main.usage=\u4F7F\u7528\u65B9\u6CD5:\n doclint [options] source-files...\n\n\u30AA\u30D7\u30B7\u30E7\u30F3:\n -Xmsgs \n -Xmsgs:all\u3068\u540C\u3058\n -Xmsgs:values\n \u30C1\u30A7\u30C3\u30AF\u3059\u308B\u554F\u984C\u306E\u30AB\u30C6\u30B4\u30EA\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\u3053\u3053\u3067\u306E''values''\u306F\u3001\n \u30AB\u30F3\u30DE\u3067\u533A\u5207\u3089\u308C\u305F\u6B21\u306E\u5024\u306E\u30EA\u30B9\u30C8\u3067\u3059:\n reference Java\u30BD\u30FC\u30B9\u30FB\u30B3\u30FC\u30C9\u8981\u7D20\u3078\u306E\u4E0D\u6B63\u306A\u53C2\u7167\u3092\u542B\u3080\u30B3\u30E1\u30F3\u30C8\u306E\n \u5834\u6240\u3092\u8868\u793A\u3057\u307E\u3059\n syntax \u30B3\u30E1\u30F3\u30C8\u5185\u306E\u57FA\u672C\u69CB\u6587\u30A8\u30E9\u30FC\u3092\u8868\u793A\u3057\u307E\u3059\n html HTML\u30BF\u30D6\u304A\u3088\u3073\u5C5E\u6027\u306E\u554F\u984C\u3092\u8868\u793A\u3057\u307E\u3059\n accessibility \u30A2\u30AF\u30BB\u30B7\u30D3\u30EA\u30C6\u30A3\u306E\u554F\u984C\u3092\u8868\u793A\u3057\u307E\u3059\n missing \u6B20\u843D\u3057\u3066\u3044\u308B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u554F\u984C\u3092\u8868\u793A\u3057\u307E\u3059\n all \u524D\u8FF0\u306E\u3059\u3079\u3066\n \u3053\u308C\u3092\u5426\u5B9A\u3059\u308B\u306B\u306F\u3001\u5024\u306E\u524D\u306B''-''\u3092\u6307\u5B9A\u3057\u307E\u3059\n \u30AB\u30C6\u30B4\u30EA\u306F\u3001\u6B21\u306E\u3044\u305A\u308C\u304B\u3067\u4FEE\u98FE\u3067\u304D\u307E\u3059:\n /public /protected /package /private\n \u6B63\u306E\u30AB\u30C6\u30B4\u30EA(''-''\u3067\u59CB\u307E\u3089\u306A\u3044)\u306E\u5834\u5408\n \u4FEE\u98FE\u5B50\u306F\u3001\u305D\u306E\u30A2\u30AF\u30BB\u30B9\u30FB\u30EC\u30D9\u30EB\u4EE5\u4E0A\u306B\u9069\u7528\u3055\u308C\u307E\u3059\u3002\n \u8CA0\u306E\u30AB\u30C6\u30B4\u30EA(''-''\u3067\u59CB\u307E\u308B)\u306E\u5834\u5408\n \u4FEE\u98FE\u5B50\u306F\u3001\u305D\u306E\u30A2\u30AF\u30BB\u30B9\u30FB\u30EC\u30D9\u30EB\u4EE5\u4E0B\u306B\u9069\u7528\u3055\u308C\u307E\u3059\u3002\n \u4FEE\u98FE\u5B50\u304C\u306A\u3044\u5834\u5408\u3001\u30AB\u30C6\u30B4\u30EA\u306F\u3059\u3079\u3066\u306E\u30A2\u30AF\u30BB\u30B9\u30FB\u30EC\u30D9\u30EB\u306B\n \u9069\u7528\u3055\u308C\u307E\u3059\u3002\n \u4F8B: -Xmsgs:all,-syntax/private\n \u3053\u306E\u5834\u5408\u3001private\u30E1\u30BD\u30C3\u30C9\u306Edoc\u30B3\u30E1\u30F3\u30C8\u5185\u306E\u69CB\u6587\u30A8\u30E9\u30FC\u3092\u9664\u304D\u3001\n \u3059\u3079\u3066\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u304C\u6709\u52B9\u5316\u3055\u308C\u307E\u3059\u3002\n -Xmsgs\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u306A\u3044\u5834\u5408\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u306F\u3001\n -Xmsgs:all/protected\u3068\u540C\u7B49\u306B\u306A\u308A\u3001\u3053\u308C\u306F\n \u3059\u3079\u3066\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u304C\u3001protected\u304A\u3088\u3073public\u306E\u5BA3\u8A00\u306E\u307F\u306B\u5831\u544A\u3055\u308C\u308B\u3053\u3068\u3092\n \u610F\u5473\u3057\u307E\u3059\u3002\n -stats\n \u5831\u544A\u3055\u308C\u305F\u554F\u984C\u306B\u5BFE\u3057\u3066\u7D71\u8A08\u3092\u5831\u544A\u3057\u307E\u3059\u3002\n -h -help --help -usage -?\n \u3053\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002\n\n\u6B21\u306Ejavac\u30AA\u30D7\u30B7\u30E7\u30F3\u3082\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u3059\n \ +-bootclasspath\u3001-classpath\u3001-cp\u3001-sourcepath\u3001-Xmaxerrs\u3001-Xmaxwarns\n\n\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u4E00\u90E8\u306B\u5BFE\u3057\u3066doclint\u3092\u5B9F\u884C\u3059\u308B\u306B\u306F\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3055\u308C\u305F\u30AF\u30E9\u30B9\u3092\n\u30AF\u30E9\u30B9\u30D1\u30B9(\u307E\u305F\u306F\u30D6\u30FC\u30C8\u30FB\u30AF\u30E9\u30B9\u30D1\u30B9)\u306B\u6307\u5B9A\u3057\u3001\u30B3\u30DE\u30F3\u30C9\u30FB\u30E9\u30A4\u30F3\u3067\n\u30C1\u30A7\u30C3\u30AF\u3059\u308B\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002 diff --git a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_zh_CN.properties index b3a9c7041bc..4d25a4d5c71 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_zh_CN.properties @@ -26,6 +26,7 @@ dc.anchor.already.defined = \u951A\u5B9A\u70B9\u5DF2\u5B9A\u4E49: {0} dc.anchor.value.missing = \u6CA1\u6709\u4E3A\u951A\u5B9A\u70B9\u6307\u5B9A\u503C dc.attr.lacks.value = \u5C5E\u6027\u7F3A\u5C11\u503C +dc.attr.not.number = \u5C5E\u6027\u503C\u4E0D\u662F\u6570\u5B57 dc.attr.obsolete = \u5C5E\u6027\u5DF2\u8FC7\u65F6: {0} dc.attr.obsolete.use.css = \u5C5E\u6027\u5DF2\u8FC7\u65F6, \u8BF7\u6539\u7528 CSS: {0} dc.attr.repeated = \u5C5E\u6027\u91CD\u590D: {0} @@ -46,7 +47,7 @@ dc.missing.return = \u6CA1\u6709 @return dc.missing.throws = {0}\u6CA1\u6709 @throws dc.no.alt.attr.for.image = \u56FE\u50CF\u6CA1\u6709 "alt" \u5C5E\u6027 dc.no.summary.or.caption.for.table=\u8868\u6CA1\u6709\u6982\u8981\u6216\u6807\u9898 -dc.param.name.not.found = \u627E\u4E0D\u5230 @param \u540D\u79F0 +dc.param.name.not.found = @param name \u672A\u627E\u5230 dc.ref.not.found = \u627E\u4E0D\u5230\u5F15\u7528 dc.tag.code.within.code = '{@code'} \u5728 \u4E2D dc.tag.empty = <{0}> \u6807\u8BB0\u4E3A\u7A7A @@ -66,3 +67,8 @@ dc.tag.self.closing = \u4E0D\u5141\u8BB8\u4F7F\u7528\u81EA\u5173\u95ED\u5143\u7D dc.tag.start.unmatched = \u7F3A\u5C11\u7ED3\u675F\u6807\u8BB0: dc.tag.unknown = \u672A\u77E5\u6807\u8BB0: {0} dc.text.not.allowed = <{0}> \u5143\u7D20\u4E2D\u4E0D\u5141\u8BB8\u4F7F\u7528\u6587\u672C +dc.unexpected.comment=\u6B64\u5904\u672A\u9884\u671F\u6587\u6863\u6CE8\u91CA + +dc.main.ioerror=IO \u9519\u8BEF: {0} +dc.main.no.files.given=\u672A\u6307\u5B9A\u6587\u4EF6 +dc.main.usage=\u7528\u6CD5:\n doclint [options] source-files...\n\n\u9009\u9879:\n -Xmsgs \n \u4E0E -Xmsgs:all \u76F8\u540C\n -Xmsgs:values\n \u6307\u5B9A\u8981\u68C0\u67E5\u7684\u95EE\u9898\u7684\u7C7B\u522B, \u5176\u4E2D ''values''\n \u662F\u4EFB\u610F\u4EE5\u4E0B\u5185\u5BB9\u7684\u4EE5\u9017\u53F7\u5206\u9694\u7684\u5217\u8868:\n reference \u663E\u793A\u5305\u542B\u5BF9 Java \u6E90\u4EE3\u7801\u5143\u7D20\n \u9519\u8BEF\u5F15\u7528\u7684\u6CE8\u91CA\u7684\u4F4D\u7F6E\n syntax \u663E\u793A\u6CE8\u91CA\u4E2D\u7684\u57FA\u672C\u8BED\u6CD5\u9519\u8BEF\n html \u663E\u793A HTML \u6807\u8BB0\u548C\u5C5E\u6027\u95EE\u9898\n accessibility \u663E\u793A\u53EF\u8BBF\u95EE\u6027\u7684\u95EE\u9898\n missing \u663E\u793A\u7F3A\u5C11\u6587\u6863\u7684\u95EE\u9898\n all \u6240\u6709\u4EE5\u4E0A\u5185\u5BB9\n \u5728\u503C\u4E4B\u524D\u4F7F\u7528 ''-'' \u53EF\u4F7F\u7528\u5176\u53CD\u503C\n \u53EF\u4EE5\u4F7F\u7528\u4EE5\u4E0B\u4E00\u9879\u6765\u9650\u5B9A\u7C7B\u522B:\n /public /protected /package /private\n \u5BF9\u4E8E\u6B63\u7C7B\u522B (\u4E0D\u4EE5 ''-'' \u5F00\u5934)\n \u9650\u5B9A\u7B26\u9002\u7528\u4E8E\u8BE5\u8BBF\u95EE\u7EA7\u522B\u53CA\u66F4\u9AD8\u7EA7\u522B\u3002\n \u5BF9\u4E8E\u8D1F\u7C7B\u522B (\u4EE5 ''-'' \u5F00\u5934)\n \u9650\u5B9A\u7B26\u9002\u7528\u4E8E\u8BE5\u8BBF\u95EE\u7EA7\u522B\u53CA\u66F4\u4F4E\u7EA7\u522B\u3002\n \u5982\u679C\u6CA1\u6709\u9650\u5B9A\u7B26, \u5219\u8BE5\u7C7B\u522B\u9002\u7528\u4E8E\n \u6240\u6709\u8BBF\u95EE\u7EA7\u522B\u3002\n \u4F8B\u5982, -Xmsgs:all,-syntax/private\n \u8FD9\u5C06\u5728\u4E13\u7528\u65B9\u6CD5\u7684\u6587\u6863\u6CE8\u91CA\u4E2D\n \u542F\u7528\u9664\u8BED\u6CD5\u9519\u8BEF\u4E4B\u5916\u7684\u6240\u6709\u6D88\u606F\u3002\n \u5982\u679C\u672A\u63D0\u4F9B -Xmsgs \u9009\u9879, \u5219\u9ED8\u8BA4\u503C\n \u7B49\u540C\u4E8E -Xmsgs:all/protected, \u8868\u793A\n \u4EC5\u62A5\u544A\u53D7\u4FDD\u62A4\u548C\u516C\u5171\u58F0\u660E\u4E2D\u7684\n \u6240\u6709\u6D88\u606F\n -stats\n \u62A5\u544A\u6240\u62A5\u544A\u95EE\u9898\u7684\u7EDF\u8BA1\u4FE1\u606F\u3002\n -h -help --help -usage -?\n \u663E\u793A\u6B64\u6D88\u606F\u3002\n\n\u8FD8\u652F\u6301\u4EE5\u4E0B javac \u9009\u9879\n -bootclasspath, -classpath, -cp, -sourcepath, -Xmaxerrs, -Xmaxwarns\n\n\u8981\u5728\u9879\u76EE\u7684\u4E00\u90E8\u5206\u4E0A\u8FD0\u884C doclint, \u8BF7\u5C06\u9879\u76EE\u4E2D\u5DF2\u7F16\u8BD1\u7684\u7C7B\n\u653E\u5728\u7C7B\u8DEF\u5F84 (\u6216\u5F15\u5BFC\u7C7B\u8DEF\u5F84) \u4E0A, \u7136\u540E\u5728\u547D\u4EE4\u884C\u4E0A\u6307\u5B9A\n\u8981\u68C0\u67E5\u7684\u6E90\u6587\u4EF6\u3002 diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties index bff4e9a217b..9702e684c78 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties @@ -524,9 +524,6 @@ compiler.misc.incompatible.ret.type.in.lambda=\u30E9\u30E0\u30C0\u5F0F\u306E\u62 # 0: type compiler.misc.incompatible.ret.type.in.mref=\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u306E\u623B\u308A\u578B\u304C\u4E0D\u6B63\u3067\u3059\n{0} -# 0: list of type -compiler.err.incompatible.thrown.types.in.lambda=\u30E9\u30E0\u30C0\u5F0F\u3067\u30B9\u30ED\u30FC\u3055\u308C\u305F\u30BF\u30A4\u30D7{0}\u306F\u4E0D\u9069\u5408\u3067\u3059 - # 0: list of type compiler.err.incompatible.thrown.types.in.mref=\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u306E\u30B9\u30ED\u30FC\u3055\u308C\u305F\u30BF\u30A4\u30D7{0}\u306F\u4E0D\u9069\u5408\u3067\u3059 @@ -642,12 +639,18 @@ compiler.err.repeated.modifier=\u4FEE\u98FE\u5B50\u304C\u7E70\u308A\u8FD4\u3055\ # 0: symbol, 1: set of modifier, 2: symbol compiler.err.report.access={0}\u306F{2}\u3067{1}\u30A2\u30AF\u30BB\u30B9\u3055\u308C\u307E\u3059 +# 0: symbol, 1: set of modifier, 2: symbol +compiler.misc.report.access={0}\u306F{2}\u3067{1}\u30A2\u30AF\u30BB\u30B9\u3055\u308C\u307E\u3059 + compiler.err.ret.outside.meth=\u30E1\u30BD\u30C3\u30C9\u306E\u5916\u306Ereturn\u6587\u3067\u3059 compiler.err.signature.doesnt.match.supertype=\u30B7\u30B0\u30CD\u30C1\u30E3\u304C{0}\u306B\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002\u4E0D\u9069\u5408\u306A\u30B9\u30FC\u30D1\u30FC\u30BF\u30A4\u30D7\u3067\u3059 compiler.err.signature.doesnt.match.intf=\u30B7\u30B0\u30CD\u30C1\u30E3\u304C{0}\u306B\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002\u4E0D\u9069\u5408\u306A\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u3067\u3059 +# 0: number, 1: number +compiler.err.method.invoked.with.incorrect.number.arguments=\u30E1\u30BD\u30C3\u30C9\u3092\u8D77\u52D5\u3057\u305F\u5F15\u6570\u306E\u6570\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093\u3002\u4E88\u671F\u3055\u308C\u308B\u6570\u306F{0}\u3067\u3059\u304C\u3001{1}\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F + # 0: symbol, 1: symbol, 2: symbol compiler.err.does.not.override.abstract={0}\u306Fabstract\u3067\u306A\u304F\u3001{2}\u5185\u306Eabstract\u30E1\u30BD\u30C3\u30C9{1}\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u307E\u305B\u3093 @@ -755,6 +758,9 @@ compiler.err.var.might.already.be.assigned=\u5909\u6570{0}\u306F\u3059\u3067\u30 # 0: symbol compiler.err.var.might.not.have.been.initialized=\u5909\u6570{0}\u306F\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u306A\u3044\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059 +# 0: symbol +compiler.err.var.not.initialized.in.default.constructor=\u5909\u6570{0}\u306F\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u3067\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093 + # 0: symbol compiler.err.var.might.be.assigned.in.loop=\u5909\u6570{0}\u306F\u30EB\u30FC\u30D7\u5185\u3067\u4EE3\u5165\u3055\u308C\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059 @@ -829,6 +835,14 @@ compiler.note.compressed.diags=\u4E00\u90E8\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\ compiler.note.potential.lambda.found=\u3053\u306E\u533F\u540D\u5185\u90E8\u30AF\u30E9\u30B9\u3092\u30E9\u30E0\u30C0\u5F0F\u306B\u5909\u63DB\u3067\u304D\u307E\u3059\u3002 +# 0: boolean, 1: symbol +compiler.note.lambda.stat=\u30E9\u30E0\u30C0\u5F0F\u3092\u5909\u63DB\u3057\u3066\u3044\u307E\u3059\n\u4EE3\u66FFmetafactory = {0}\n\u5408\u6210\u30E1\u30BD\u30C3\u30C9 = {1} + +# 0: boolean, 1: unused +compiler.note.mref.stat=\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u3092\u5909\u63DB\u3057\u3066\u3044\u307E\u3059\n\u4EE3\u66FFmetafactory = {0}\n +# 0: boolean, 1: symbol +compiler.note.mref.stat.1=\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u3092\u5909\u63DB\u3057\u3066\u3044\u307E\u3059\n\u4EE3\u66FFmetafactory = {0}\n\u30D6\u30EA\u30C3\u30B8\u30FB\u30E1\u30BD\u30C3\u30C9 = {1} + compiler.note.note=\u6CE8\u610F: # 0: file name @@ -1015,6 +1029,14 @@ compiler.warn.static.not.qualified.by.type=static {0}\u306F\u5F0F\u3067\u306F\u3 # 0: string compiler.warn.source.no.bootclasspath=\u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30D1\u30B9\u304C-source {0}\u3068\u4E00\u7DD2\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093 +# 0: string +compiler.warn.option.obsolete.source=\u30BD\u30FC\u30B9\u5024{0}\u306F\u5EC3\u6B62\u3055\u308C\u3066\u3044\u3066\u3001\u4ECA\u5F8C\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3059 + +# 0: string +compiler.warn.option.obsolete.target=\u30BF\u30FC\u30B2\u30C3\u30C8\u5024{0}\u306F\u5EC3\u6B62\u3055\u308C\u3066\u3044\u3066\u3001\u4ECA\u5F8C\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3059 + +compiler.warn.option.obsolete.suppression=\u5EC3\u6B62\u3055\u308C\u305F\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u3064\u3044\u3066\u306E\u8B66\u544A\u3092\u8868\u793A\u3057\u306A\u3044\u3088\u3046\u306B\u3059\u308B\u306B\u306F\u3001-Xlint:\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002 + # 0: name, 1: number, 2: number, 3: number, 4: number compiler.warn.future.attr=\u30D0\u30FC\u30B8\u30E7\u30F3{1}.{2}\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3067\u5C0E\u5165\u3055\u308C\u305F{0}\u5C5E\u6027\u306F\u3001\u30D0\u30FC\u30B8\u30E7\u30F3{3}.{4}\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u7121\u8996\u3055\u308C\u307E\u3059 @@ -1550,7 +1572,7 @@ compiler.warn.enum.as.identifier=\u30EA\u30EA\u30FC\u30B95\u304B\u3089''enum''\u compiler.warn.assert.as.identifier=\u30EA\u30EA\u30FC\u30B91.4\u304B\u3089''assert''\u306F\u30AD\u30FC\u30EF\u30FC\u30C9\u306A\u306E\u3067\u3001\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\n(''assert''\u3092\u30AD\u30FC\u30EF\u30FC\u30C9\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u306B\u306F\u3001-source 1.4\u4EE5\u964D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044) -compiler.warn.underscore.as.identifier=\u8B58\u5225\u5B50\u3068\u3057\u3066''_''\u304C\u4F7F\u7528\u3055\u308C\u307E\u3057\u305F\n(\u8B58\u5225\u5B50\u3068\u3057\u3066\u306E''_''\u306E\u4F7F\u7528\u306F\u3001\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u306A\u3044\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059) +compiler.warn.underscore.as.identifier=\u8B58\u5225\u5B50\u3068\u3057\u3066''_''\u304C\u4F7F\u7528\u3055\u308C\u307E\u3057\u305F\n(\u8B58\u5225\u5B50\u3068\u3057\u3066\u306E''_''\u306E\u4F7F\u7528\u306F\u3001Java SE 8\u3088\u308A\u5F8C\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u306A\u3044\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059) compiler.err.enum.as.identifier=\u30EA\u30EA\u30FC\u30B95\u304B\u3089''enum''\u306F\u30AD\u30FC\u30EF\u30FC\u30C9\u306A\u306E\u3067\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\n(''enum''\u3092\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u306B\u306F-source 1.4\u4EE5\u524D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044) @@ -1567,7 +1589,7 @@ compiler.err.cant.annotate.static.class=\u5305\u542B\u3059\u308Bstatic\u306E\u30 # TODO 308: make a better error message # 0: unused -compiler.err.cant.annotate.nested.type=\u30CD\u30B9\u30C8\u3055\u308C\u305F\u30BF\u30A4\u30D7\u306F\u6CE8\u91C8\u4ED8\u3051\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093 +compiler.err.cant.annotate.nested.type=static\u306E\u30CD\u30B9\u30C8\u3055\u308C\u305F\u30BF\u30A4\u30D7\u306E\u30B9\u30B3\u30FC\u30D7\u30FB\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30C8\u306B\u306F\u6CE8\u91C8\u4ED8\u3051\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093 # 0: type, 1: type compiler.err.incorrect.receiver.name=\u53D7\u53D6\u308A\u5074\u306E\u540D\u524D\u304C\u3001\u5305\u542B\u3059\u308B\u30AF\u30E9\u30B9\u30FB\u30BF\u30A4\u30D7\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\n\u5FC5\u9808: {0}\n\u691C\u51FA: {1} diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties index b2e76c037f4..d4f1a214cd0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties @@ -524,9 +524,6 @@ compiler.misc.incompatible.ret.type.in.lambda=lambda \u8868\u8FBE\u5F0F\u4E2D\u7 # 0: type compiler.misc.incompatible.ret.type.in.mref=\u65B9\u6CD5\u5F15\u7528\u4E2D\u7684\u8FD4\u56DE\u7C7B\u578B\u9519\u8BEF\n{0} -# 0: list of type -compiler.err.incompatible.thrown.types.in.lambda=lambda \u8868\u8FBE\u5F0F\u4E2D\u629B\u51FA\u7684\u7C7B\u578B{0}\u4E0D\u517C\u5BB9 - # 0: list of type compiler.err.incompatible.thrown.types.in.mref=\u65B9\u6CD5\u5F15\u7528\u4E2D\u629B\u51FA\u7684\u7C7B\u578B{0}\u4E0D\u517C\u5BB9 @@ -642,12 +639,18 @@ compiler.err.repeated.modifier=\u4FEE\u9970\u7B26\u91CD\u590D # 0: symbol, 1: set of modifier, 2: symbol compiler.err.report.access={0}\u53EF\u4EE5\u5728{2}\u4E2D\u8BBF\u95EE{1} +# 0: symbol, 1: set of modifier, 2: symbol +compiler.misc.report.access={0}\u53EF\u4EE5\u5728{2}\u4E2D\u8BBF\u95EE{1} + compiler.err.ret.outside.meth=\u8FD4\u56DE\u5916\u90E8\u65B9\u6CD5 compiler.err.signature.doesnt.match.supertype=\u7B7E\u540D\u4E0E{0}\u4E0D\u5339\u914D; \u4E0D\u517C\u5BB9\u7684\u8D85\u7C7B\u578B compiler.err.signature.doesnt.match.intf=\u7B7E\u540D\u4E0E{0}\u4E0D\u5339\u914D; \u4E0D\u517C\u5BB9\u7684\u63A5\u53E3 +# 0: number, 1: number +compiler.err.method.invoked.with.incorrect.number.arguments=\u4F7F\u7528\u4E0D\u6B63\u786E\u6570\u91CF\u7684\u53C2\u6570\u8C03\u7528\u4E86\u65B9\u6CD5; \u9884\u671F\u4E3A {0} \u4E2A, \u627E\u5230 {1} \u4E2A + # 0: symbol, 1: symbol, 2: symbol compiler.err.does.not.override.abstract={0}\u4E0D\u662F\u62BD\u8C61\u7684, \u5E76\u4E14\u672A\u8986\u76D6{2}\u4E2D\u7684\u62BD\u8C61\u65B9\u6CD5{1} @@ -755,6 +758,9 @@ compiler.err.var.might.already.be.assigned=\u53EF\u80FD\u5DF2\u5206\u914D\u53D8\ # 0: symbol compiler.err.var.might.not.have.been.initialized=\u53EF\u80FD\u5C1A\u672A\u521D\u59CB\u5316\u53D8\u91CF{0} +# 0: symbol +compiler.err.var.not.initialized.in.default.constructor=\u53D8\u91CF {0} \u672A\u5728\u9ED8\u8BA4\u6784\u9020\u5668\u4E2D\u521D\u59CB\u5316 + # 0: symbol compiler.err.var.might.be.assigned.in.loop=\u53EF\u80FD\u5728 loop \u4E2D\u5206\u914D\u4E86\u53D8\u91CF{0} @@ -829,6 +835,14 @@ compiler.note.compressed.diags=\u67D0\u4E9B\u6D88\u606F\u5DF2\u7ECF\u8FC7\u7B80\ compiler.note.potential.lambda.found=\u53EF\u5C06\u6B64\u533F\u540D\u5185\u90E8\u7C7B\u521B\u5EFA\u8F6C\u6362\u4E3A lambda \u8868\u8FBE\u5F0F\u3002 +# 0: boolean, 1: symbol +compiler.note.lambda.stat=\u8F6C\u6362 lambda \u8868\u8FBE\u5F0F\n\u66FF\u4EE3 metafactory = {0}\n\u5408\u6210\u65B9\u6CD5 = {1} + +# 0: boolean, 1: unused +compiler.note.mref.stat=\u8F6C\u6362\u65B9\u6CD5\u5F15\u7528\n\u66FF\u4EE3 metafactory = {0}\n +# 0: boolean, 1: symbol +compiler.note.mref.stat.1=\u8F6C\u6362\u65B9\u6CD5\u5F15\u7528\n\u66FF\u4EE3 metafactory = {0}\nbridge \u65B9\u6CD5 = {1} + compiler.note.note=\u6CE8: # 0: file name @@ -1015,6 +1029,14 @@ compiler.warn.static.not.qualified.by.type=static {0}\u5E94\u7531\u7C7B\u578B\u5 # 0: string compiler.warn.source.no.bootclasspath=\u672A\u4E0E -source {0} \u4E00\u8D77\u8BBE\u7F6E\u5F15\u5BFC\u7C7B\u8DEF\u5F84 +# 0: string +compiler.warn.option.obsolete.source=\u6E90\u503C{0}\u5DF2\u8FC7\u65F6, \u5C06\u5728\u672A\u6765\u6240\u6709\u53D1\u884C\u7248\u4E2D\u5220\u9664 + +# 0: string +compiler.warn.option.obsolete.target=\u76EE\u6807\u503C{0}\u5DF2\u8FC7\u65F6, \u5C06\u5728\u672A\u6765\u6240\u6709\u53D1\u884C\u7248\u4E2D\u5220\u9664 + +compiler.warn.option.obsolete.suppression=\u8981\u9690\u85CF\u6709\u5173\u5DF2\u8FC7\u65F6\u9009\u9879\u7684\u8B66\u544A, \u8BF7\u4F7F\u7528 -Xlint:-options\u3002 + # 0: name, 1: number, 2: number, 3: number, 4: number compiler.warn.future.attr={1}.{2} \u7248\u7C7B\u6587\u4EF6\u4E2D\u5F15\u5165\u7684 {0} \u5C5E\u6027\u5728 {3}.{4} \u7248\u7C7B\u6587\u4EF6\u4E2D\u88AB\u5FFD\u7565 @@ -1550,7 +1572,7 @@ compiler.warn.enum.as.identifier=\u4ECE\u53D1\u884C\u7248 5 \u5F00\u59CB, ''enum compiler.warn.assert.as.identifier=\u4ECE\u53D1\u884C\u7248 1.4 \u5F00\u59CB, ''assert'' \u662F\u4E00\u4E2A\u5173\u952E\u5B57, \u4F46\u4E0D\u80FD\u7528\u4F5C\u6807\u8BC6\u7B26\n(\u8BF7\u4F7F\u7528 -source 1.4 \u6216\u66F4\u9AD8\u7248\u672C\u4EE5\u5C06 ''assert'' \u7528\u4F5C\u5173\u952E\u5B57) -compiler.warn.underscore.as.identifier=''_'' \u5DF2\u7528\u4F5C\u6807\u8BC6\u7B26\n(\u4EE5\u540E\u7684\u53D1\u884C\u7248\u53EF\u80FD\u4E0D\u652F\u6301\u5C06 ''_'' \u7528\u4F5C\u6807\u8BC6\u7B26) +compiler.warn.underscore.as.identifier=''_'' \u7528\u4F5C\u6807\u8BC6\u7B26\n(Java SE 8 \u4E4B\u540E\u7684\u53D1\u884C\u7248\u4E2D\u53EF\u80FD\u4E0D\u652F\u6301\u4F7F\u7528 ''_'' \u4F5C\u4E3A\u6807\u8BC6\u7B26) compiler.err.enum.as.identifier=\u4ECE\u53D1\u884C\u7248 5 \u5F00\u59CB, ''enum'' \u4E3A\u5173\u952E\u5B57, \u800C\u4E0D\u7528\u4F5C\u6807\u8BC6\u7B26\n(\u8BF7\u4F7F\u7528 -source 1.4 \u6216\u66F4\u4F4E\u7248\u672C\u4EE5\u5C06 ''enum'' \u7528\u4F5C\u6807\u8BC6\u7B26) @@ -1567,7 +1589,7 @@ compiler.err.cant.annotate.static.class=\u65E0\u6CD5\u5BF9\u5C01\u95ED\u9759\u60 # TODO 308: make a better error message # 0: unused -compiler.err.cant.annotate.nested.type=\u65E0\u6CD5\u5BF9\u5D4C\u5957\u7C7B\u578B\u8FDB\u884C\u6CE8\u91CA +compiler.err.cant.annotate.nested.type=\u65E0\u6CD5\u6CE8\u91CA\u7528\u4E8E\u9759\u6001\u5D4C\u5957\u7C7B\u578B\u7684\u786E\u5B9A\u4F5C\u7528\u57DF\u7ED3\u6784 # 0: type, 1: type compiler.err.incorrect.receiver.name=\u63A5\u6536\u65B9\u540D\u79F0\u4E0E\u5C01\u95ED\u7C7B\u7C7B\u578B\u4E0D\u5339\u914D\n\u9700\u8981: {0}\n\u627E\u5230: {1} diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties index 0170a70384d..2c68780c9a6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2013, 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 @@ -87,8 +87,12 @@ javac.opt.arg.file= javac.opt.Xlint=\u63A8\u5968\u306E\u8B66\u544A\u3092\u6709\u52B9\u306B\u3059\u308B javac.opt.Xlint.suboptlist=\u7279\u5B9A\u306E\u8B66\u544A\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3059\u308B javac.opt.Xdoclint=javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u63A8\u5968\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3059\u308B -javac.opt.Xdoclint.subopts = (all|[-])[/] -javac.opt.Xdoclint.custom=\n javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u7279\u5B9A\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002\n \u3053\u3053\u3067\u3001\u306Faccessibility\u3001html\u3001reference\u307E\u305F\u306Fsyntax\u306E\u3044\u305A\u308C\u304B\u3067\u3001\n \u306Fpublic\u3001protected\u3001package\u307E\u305F\u306Fprivate\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002 +# L10N: do not localize: all none +javac.opt.Xdoclint.subopts = (all|none|[-])[/] + +# L10N: do not localize: accessibility html missing reference syntax +# L10N: do not localize: public protected package private +javac.opt.Xdoclint.custom=\n javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u7279\u5B9A\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002\n \u3053\u3053\u3067\u3001\u306Faccessibility\u3001html\u3001missing\u3001reference\u307E\u305F\u306Fsyntax\u306E\u3044\u305A\u308C\u304B\u3067\u3001\n \u306Fpublic\u3001protected\u3001package\u307E\u305F\u306Fprivate\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002 javac.opt.Xstdout=\u6A19\u6E96\u51FA\u529B\u3092\u30EA\u30C0\u30A4\u30EC\u30AF\u30C8\u3059\u308B javac.opt.X=\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3059\u308B javac.opt.help=\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3059\u308B @@ -105,6 +109,7 @@ javac.err.empty.A.argument=-A\u306B\u306F\u5F15\u6570\u304C\u5FC5\u8981\u3067\u3 javac.err.invalid.arg={0}\u306F\u7121\u52B9\u306A\u5F15\u6570\u3067\u3059 javac.err.invalid.A.key=\u6CE8\u91C8\u30D7\u30ED\u30BB\u30C3\u30B5\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3''{0}''\u306E\u30AD\u30FC\u306B\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u4E00\u9023\u306E\u8B58\u5225\u5B50\u304C\u3001\u30C9\u30C3\u30C8\u3067\u533A\u5207\u3089\u308C\u3066\u3044\u307E\u305B\u3093 javac.err.invalid.flag={0}\u306F\u7121\u52B9\u306A\u30D5\u30E9\u30B0\u3067\u3059 +javac.err.profile.bootclasspath.conflict=profile\u3068bootclasspath\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u540C\u6642\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093 javac.err.invalid.profile=\u7121\u52B9\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: {0} javac.err.invalid.target={0}\u306F\u7121\u52B9\u306A\u30BF\u30FC\u30B2\u30C3\u30C8\u30FB\u30EA\u30EA\u30FC\u30B9\u3067\u3059 javac.err.no.source.files=\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308A\u307E\u305B\u3093 diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties index 79e497f1f87..2ad0c68edbd 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2013, 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 @@ -87,8 +87,12 @@ javac.opt.arg.file=<\u6587\u4EF6\u540D> javac.opt.Xlint=\u542F\u7528\u5EFA\u8BAE\u7684\u8B66\u544A javac.opt.Xlint.suboptlist=\u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u7684\u8B66\u544A javac.opt.Xdoclint=\u4E3A javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u5EFA\u8BAE\u7684\u68C0\u67E5 -javac.opt.Xdoclint.subopts = (all|[-])[/] -javac.opt.Xdoclint.custom=\n \u4E3A javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u68C0\u67E5,\n \u5176\u4E2D \u4E3A\u53EF\u8BBF\u95EE\u6027, html, \u5F15\u7528\u6216\u8BED\u6CD5\u4E4B\u4E00,\n \u4E3A public, protected, package \u6216 private \u4E4B\u4E00\u3002 +# L10N: do not localize: all none +javac.opt.Xdoclint.subopts = (all|none|[-])[/] + +# L10N: do not localize: accessibility html missing reference syntax +# L10N: do not localize: public protected package private +javac.opt.Xdoclint.custom=\n \u4E3A javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u68C0\u67E5,\n \u5176\u4E2D \u4E3A accessibility, html, missing, reference \u6216 syntax \u4E4B\u4E00\u3002\n \u4E3A public, protected, package \u6216 private \u4E4B\u4E00\u3002 javac.opt.Xstdout=\u91CD\u5B9A\u5411\u6807\u51C6\u8F93\u51FA javac.opt.X=\u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981 javac.opt.help=\u8F93\u51FA\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981 @@ -105,6 +109,7 @@ javac.err.empty.A.argument=-A \u9700\u8981\u4E00\u4E2A\u53C2\u6570; \u4F7F\u7528 javac.err.invalid.arg=\u65E0\u6548\u7684\u53C2\u6570: {0} javac.err.invalid.A.key=\u6CE8\u91CA\u5904\u7406\u7A0B\u5E8F\u9009\u9879 ''{0}'' \u4E2D\u7684\u5173\u952E\u5B57\u4E0D\u662F\u4EE5\u70B9\u5206\u9694\u7684\u6807\u8BC6\u7B26\u5E8F\u5217 javac.err.invalid.flag=\u65E0\u6548\u7684\u6807\u8BB0: {0} +javac.err.profile.bootclasspath.conflict=\u6982\u8981\u4FE1\u606F\u548C\u5F15\u5BFC\u7C7B\u8DEF\u5F84\u9009\u9879\u4E0D\u80FD\u540C\u65F6\u4F7F\u7528 javac.err.invalid.profile=\u914D\u7F6E\u6587\u4EF6\u65E0\u6548: {0} javac.err.invalid.target=\u65E0\u6548\u7684\u76EE\u6807\u53D1\u884C\u7248: {0} javac.err.no.source.files=\u65E0\u6E90\u6587\u4EF6 diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties index a31ba5973da..b95a435689f 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,13 @@ main.errors=\u30A8\u30E9\u30FC{0}\u500B main.error=\u30A8\u30E9\u30FC{0}\u500B main.warnings=\u8B66\u544A{0}\u500B main.warning=\u8B66\u544A{0}\u500B -main.usage=\u4F7F\u7528\u65B9\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n-overview HTML\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u6982\u8981\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u8AAD\u307F\u8FBC\u3080\n-public public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u793A\u3059\n-protected protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)\n-package package/protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n-private \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n-help \u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n-doclet \u4EE3\u66FFdoclet\u3092\u4ECB\u3057\u3066\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n-docletpath doclet\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u63A2\u3059\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n-sourcepath \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n-classpath \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n-exclude \u9664\u5916\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u6307\u5B9A\u3059\u308B\n-subpackages \u518D\u5E30\u7684\u306B\u30ED\u30FC\u30C9\u3059\u308B\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3059\u308B\n-breakiterator BreakIterator\u3067\u6700\u521D\u306E\u6587\u3092\u8A08\u7B97\u3059\u308B\n-bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30ED\u30FC\u30C0\u30FC\u306B\u3088\u308A\u30ED\u30FC\u30C9\u3055\u308C\u305F\n\t\t\t \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n-source \u6307\u5B9A\u3055\u308C\u305F\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u63D0\u4F9B\u3059\u308B\n-extdirs \u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3055\u308C\u305F\u62E1\u5F35\u6A5F\u80FD\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n-verbose Javadoc\u306E\u52D5\u4F5C\u306B\u3064\u3044\u3066\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n-locale en_US\u3084en_US_WIN\u306A\u3069\u306E\u4F7F\u7528\u3059\u308B\u30ED\u30B1\u30FC\u30EB\n-encoding \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u540D\n-quiet \u72B6\u614B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u306A\u3044\n-J \u3092\u5B9F\u884C\u6642\u30B7\u30B9\u30C6\u30E0\u306B\u76F4\u63A5\u6E21\u3059\n-X \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3059\u308B\n -main.Xusage=-Xmaxerrs \u51FA\u529B\u3059\u308B\u30A8\u30E9\u30FC\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B\n-Xmaxwarns \u51FA\u529B\u3059\u308B\u8B66\u544A\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B\n\n\u3053\u308C\u3089\u306F\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002 + +main.usage=\u4F7F\u7528\u65B9\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n -overview HTML\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u6982\u8981\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u8AAD\u307F\u8FBC\u3080\n -public public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u793A\u3059\n -protected protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -package package/protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n -private \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n -help \u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n -doclet \u4EE3\u66FFdoclet\u3092\u4ECB\u3057\u3066\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n -docletpath doclet\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u63A2\u3059\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n -sourcepath \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n -classpath \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n -cp \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\r\n -exclude \u9664\u5916\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u6307\u5B9A\u3059\u308B\n -subpackages \u518D\u5E30\u7684\u306B\u30ED\u30FC\u30C9\u3059\u308B\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3059\u308B\n -breakiterator BreakIterator\u3067\u6700\u521D\u306E\u6587\u3092\u8A08\u7B97\u3059\u308B\n -bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30ED\u30FC\u30C0\u30FC\u306B\u3088\u308A\u30ED\u30FC\u30C9\u3055\u308C\u305F\n \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n -source \u6307\u5B9A\u3055\u308C\u305F\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u63D0\u4F9B\u3059\u308B\n -extdirs \u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3055\u308C\u305F\u62E1\u5F35\u6A5F\u80FD\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n -verbose Javadoc\u306E\u52D5\u4F5C\u306B\u3064\u3044\u3066\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n -locale en_US\u3084en_US_WIN\u306A\u3069\u306E\u4F7F\u7528\u3059\u308B\u30ED\u30B1\u30FC\u30EB\n -encoding \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u540D\n -quiet \u72B6\u614B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u306A\u3044\n -J \u3092\u5B9F\u884C\u6642\u30B7\u30B9\u30C6\u30E0\u306B\u76F4\u63A5\u6E21\u3059\n -X \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3057\u7D42\u4E86\u3059\u308B\n + +main.Xusage=\ -Xmaxerrs \u51FA\u529B\u3059\u308B\u30A8\u30E9\u30FC\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B\n -Xmaxwarns \u51FA\u529B\u3059\u308B\u8B66\u544A\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B\n + +main.Xusage.foot=\u3053\u308C\u3089\u306F\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002 + main.option.already.seen={0}\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u8907\u6570\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u3002 main.requires_argument=\u30AA\u30D7\u30B7\u30E7\u30F3{0}\u306B\u306F\u5F15\u6570\u304C\u5FC5\u8981\u3067\u3059\u3002 main.locale_first=\u30AA\u30D7\u30B7\u30E7\u30F3-locale\u306F\u3001\u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u306E\u6700\u521D\u306B\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002 diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties index bb16ec27d9b..591f5771a07 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,13 @@ main.errors={0} \u4E2A\u9519\u8BEF main.error={0} \u4E2A\u9519\u8BEF main.warnings={0} \u4E2A\u8B66\u544A main.warning={0} \u4E2A\u8B66\u544A -main.usage=\u7528\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n-overview \u4ECE HTML \u6587\u4EF6\u8BFB\u53D6\u6982\u89C8\u6587\u6863\n-public \u4EC5\u663E\u793A public \u7C7B\u548C\u6210\u5458\n-protected \u663E\u793A protected/public \u7C7B\u548C\u6210\u5458 (\u9ED8\u8BA4\u503C)\n-package \u663E\u793A package/protected/public \u7C7B\u548C\u6210\u5458\n-private \u663E\u793A\u6240\u6709\u7C7B\u548C\u6210\u5458\n-help \u663E\u793A\u547D\u4EE4\u884C\u9009\u9879\u5E76\u9000\u51FA\n-doclet \u901A\u8FC7\u66FF\u4EE3 doclet \u751F\u6210\u8F93\u51FA\n-docletpath \u6307\u5B9A\u67E5\u627E doclet \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n-sourcepath \u6307\u5B9A\u67E5\u627E\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E\n-classpath \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n-exclude \u6307\u5B9A\u8981\u6392\u9664\u7684\u7A0B\u5E8F\u5305\u5217\u8868\n-subpackages \u6307\u5B9A\u8981\u9012\u5F52\u52A0\u8F7D\u7684\u5B50\u7A0B\u5E8F\u5305\n-breakiterator \u8BA1\u7B97\u5E26\u6709 BreakIterator \u7684\u7B2C\u4E00\u4E2A\u8BED\u53E5\n-bootclasspath \u8986\u76D6\u7531\u5F15\u5BFC\u7C7B\u52A0\u8F7D\u5668\u6240\u52A0\u8F7D\u7684\n\t\t\t \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n-source \u63D0\u4F9B\u4E0E\u6307\u5B9A\u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027\n-extdirs \u8986\u76D6\u6240\u5B89\u88C5\u6269\u5C55\u7684\u4F4D\u7F6E\n-verbose \u8F93\u51FA\u6709\u5173 Javadoc \u6B63\u5728\u6267\u884C\u7684\u64CD\u4F5C\u7684\u4FE1\u606F\n-locale \u8981\u4F7F\u7528\u7684\u533A\u57DF\u8BBE\u7F6E, \u4F8B\u5982 en_US \u6216 en_US_WIN\n-encoding \u6E90\u6587\u4EF6\u7F16\u7801\u540D\u79F0\n-quiet \u4E0D\u663E\u793A\u72B6\u6001\u6D88\u606F\n-J \u76F4\u63A5\u5C06 \u4F20\u9012\u5230\u8FD0\u884C\u65F6\u7CFB\u7EDF\n-X \u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981\n -main.Xusage=-Xmaxerrs \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u6700\u5927\u9519\u8BEF\u6570\n-Xmaxwarns \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u6700\u5927\u8B66\u544A\u6570\n\n\u8FD9\u4E9B\u9009\u9879\u90FD\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002 + +main.usage=\u7528\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n -overview \u4ECE HTML \u6587\u4EF6\u8BFB\u53D6\u6982\u89C8\u6587\u6863\n -public \u4EC5\u663E\u793A public \u7C7B\u548C\u6210\u5458\n -protected \u663E\u793A protected/public \u7C7B\u548C\u6210\u5458 (\u9ED8\u8BA4\u503C)\n -package \u663E\u793A package/protected/public \u7C7B\u548C\u6210\u5458\n -private \u663E\u793A\u6240\u6709\u7C7B\u548C\u6210\u5458\n -help \u663E\u793A\u547D\u4EE4\u884C\u9009\u9879\u5E76\u9000\u51FA\n -doclet \u901A\u8FC7\u66FF\u4EE3 doclet \u751F\u6210\u8F93\u51FA\n -docletpath \u6307\u5B9A\u67E5\u627E doclet \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n -sourcepath \u6307\u5B9A\u67E5\u627E\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E\n -classpath \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n -cp \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n -exclude \u6307\u5B9A\u8981\u6392\u9664\u7684\u7A0B\u5E8F\u5305\u5217\u8868\n -subpackages \u6307\u5B9A\u8981\u9012\u5F52\u52A0\u8F7D\u7684\u5B50\u7A0B\u5E8F\u5305\n -breakiterator \u8BA1\u7B97\u5E26\u6709 BreakIterator \u7684\u7B2C\u4E00\u4E2A\u8BED\u53E5\n -bootclasspath \u8986\u76D6\u7531\u5F15\u5BFC\u7C7B\u52A0\u8F7D\u5668\u6240\u52A0\u8F7D\u7684\n \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n -source \u63D0\u4F9B\u4E0E\u6307\u5B9A\u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027\n -extdirs \u8986\u76D6\u6240\u5B89\u88C5\u6269\u5C55\u7684\u4F4D\u7F6E\n -verbose \u8F93\u51FA\u6709\u5173 Javadoc \u6B63\u5728\u6267\u884C\u7684\u64CD\u4F5C\u7684\u4FE1\u606F\n -locale \u8981\u4F7F\u7528\u7684\u533A\u57DF\u8BBE\u7F6E, \u4F8B\u5982 en_US \u6216 en_US_WIN\n -encoding \u6E90\u6587\u4EF6\u7F16\u7801\u540D\u79F0\n -quiet \u4E0D\u663E\u793A\u72B6\u6001\u6D88\u606F\n -J \u76F4\u63A5\u5C06 \u4F20\u9012\u5230\u8FD0\u884C\u65F6\u7CFB\u7EDF\n -X \u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981\n + +main.Xusage=\ -Xmaxerrs \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u6700\u5927\u9519\u8BEF\u6570\n -Xmaxwarns \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u6700\u5927\u8B66\u544A\u6570\n + +main.Xusage.foot=\u8FD9\u4E9B\u9009\u9879\u90FD\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002 + main.option.already.seen={0}\u9009\u9879\u53EA\u80FD\u6307\u5B9A\u4E00\u6B21\u3002 main.requires_argument=\u9009\u9879{0}\u9700\u8981\u53C2\u6570\u3002 main.locale_first=\u5728\u547D\u4EE4\u884C\u4E2D, \u9009\u9879 -locale \u5FC5\u987B\u4E3A\u7B2C\u4E00\u4E2A\u9009\u9879\u3002 diff --git a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_ja.properties b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_ja.properties index 6a5e90e7836..27aa006bdc6 100644 --- a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_ja.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2013, 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 @@ -49,7 +49,7 @@ tracing.not.supported=\u8B66\u544A: \u30C8\u30EC\u30FC\u30B9\u306F\u73FE\u5728\u # # Usage message. # -usage=\u4F7F\u7528\u65B9\u6CD5: javah [options] \n\n[options]\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002\n\n\t-help \u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n\t-classpath \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-d \u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n\t-o \u51FA\u529B\u30D5\u30A1\u30A4\u30EB(-d\u304B-o\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u4F7F\u7528\u3059\u308B)\n\t-jni JNI\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n\t-version \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u8868\u793A\u3059\u308B\n\t-verbose \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n\t-force \u5E38\u306B\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080\n\n \u306F\u5B8C\u5168\u6307\u5B9A\u306E\u540D\u524D\u3067\u6307\u5B9A\u3057\u307E\u3059\n(java.lang.Object\u306A\u3069)\u3002\n +usage=\u4F7F\u7528\u65B9\u6CD5: javah [options] \n\n[options]\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002\n\n\t-help \u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n\t-classpath \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-cp \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\r\n\t-bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-d \u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n\t-o \u51FA\u529B\u30D5\u30A1\u30A4\u30EB(-d\u304B-o\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u4F7F\u7528\u3059\u308B)\n\t-jni JNI\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n\t-version \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u8868\u793A\u3059\u308B\n\t-verbose \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n\t-force \u5E38\u306B\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080\n\n\u306F\u5B8C\u5168\u6307\u5B9A\u306E\u540D\u524D\u3067\u6307\u5B9A\u3057\u307E\u3059\n(java.lang.Object\u306A\u3069)\u3002\n main.usage=\u4F7F\u7528\u65B9\u6CD5: \n javah [options] \n[options]\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002 main.opt.o=\ -o \u51FA\u529B\u30D5\u30A1\u30A4\u30EB(-d\u304B-o\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u4F7F\u7528\u3059\u308B) @@ -60,6 +60,7 @@ main.opt.version=\ -version \u30D0\u30FC\u30B8\u30E7\u30F3\u60C main.opt.jni=\ -jni JNI\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8) main.opt.force=\ -force \u5E38\u306B\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080 main.opt.classpath=\ -classpath \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9 +main.opt.cp=\ -cp \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9 main.opt.bootclasspath=\ -bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9 main.usage.foot=\u306F\u5B8C\u5168\u6307\u5B9A\u306E\u540D\u524D\u3067\u6307\u5B9A\u3057\u307E\u3059\n(java.lang.Object\u306A\u3069)\u3002 @@ -90,7 +91,7 @@ unknown.type.in.method.signature=\u53E4\u3044\u5F62\u5F0F\u306E\u30B9\u30BF\u30D err.prefix=\u30A8\u30E9\u30FC: err.cant.use.option.for.fm=\u6307\u5B9A\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u30FB\u30DE\u30CD\u30FC\u30B8\u30E3\u3067{0}\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093 err.internal.error=\u5185\u90E8\u30A8\u30E9\u30FC: {0} -err.ioerror=\u5165\u51FA\u529B\u30A8\u30E9\u30FC: {0} +err.ioerror=IO\u30A8\u30E9\u30FC: {0} err.missing.arg={0}\u306E\u5024\u304C\u3042\u308A\u307E\u305B\u3093 err.no.classes.specified=\u30AF\u30E9\u30B9\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093 err.unknown.option=\u4E0D\u660E\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0} diff --git a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_zh_CN.properties index 995b1cad499..e4565df67fd 100644 --- a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_zh_CN.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2013, 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 @@ -49,7 +49,7 @@ tracing.not.supported=\u8B66\u544A: \u4E0D\u518D\u652F\u6301\u8DDF\u8E2A\u3002\u # # Usage message. # -usage=\u7528\u6CD5: javah [options] \n\n\u5176\u4E2D, [options] \u5305\u62EC:\n\n\t-help \u8F93\u51FA\u6B64\u5E2E\u52A9\u6D88\u606F\u5E76\u9000\u51FA\n\t-classpath \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84\n\t-bootclasspath \u4ECE\u4E2D\u52A0\u8F7D\u5F15\u5BFC\u7C7B\u7684\u8DEF\u5F84\n\t-d \u8F93\u51FA\u76EE\u5F55\n\t-o \u8F93\u51FA\u6587\u4EF6 (\u53EA\u80FD\u4F7F\u7528 -d \u6216 -o \u4E4B\u4E00)\n\t-jni \u751F\u6210 JNI \u6837\u5F0F\u7684\u6807\u5934\u6587\u4EF6 (\u9ED8\u8BA4\u503C)\n\t-version \u8F93\u51FA\u7248\u672C\u4FE1\u606F\n\t-verbose \u542F\u7528\u8BE6\u7EC6\u8F93\u51FA\n\t-force \u59CB\u7EC8\u5199\u5165\u8F93\u51FA\u6587\u4EF6\n\n \u662F\u4F7F\u7528\u5176\u5168\u9650\u5B9A\u540D\u79F0\u6307\u5B9A\u7684,\n(\u4F8B\u5982 java.lang.Object)\u3002\n +usage=\u7528\u6CD5: javah [options] \n\n\u5176\u4E2D, [options] \u5305\u62EC:\n\n\t-help \u8F93\u51FA\u6B64\u5E2E\u52A9\u6D88\u606F\u5E76\u9000\u51FA\n\t-classpath \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84\n\t-cp \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84\n\t-bootclasspath \u4ECE\u4E2D\u52A0\u8F7D\u5F15\u5BFC\u7C7B\u7684\u8DEF\u5F84\n\t-d \u8F93\u51FA\u76EE\u5F55\n\t-o \u8F93\u51FA\u6587\u4EF6 (\u53EA\u80FD\u4F7F\u7528 -d \u6216 -o \u4E4B\u4E00)\n\t-jni \u751F\u6210 JNI \u6837\u5F0F\u7684\u6807\u5934\u6587\u4EF6 (\u9ED8\u8BA4\u503C)\n\t-version \u8F93\u51FA\u7248\u672C\u4FE1\u606F\n\t-verbose \u542F\u7528\u8BE6\u7EC6\u8F93\u51FA\n\t-force \u59CB\u7EC8\u5199\u5165\u8F93\u51FA\u6587\u4EF6\n\n \u662F\u4F7F\u7528\u5176\u5168\u9650\u5B9A\u540D\u79F0\u6307\u5B9A\u7684,\n(\u4F8B\u5982, java.lang.Object)\u3002\n main.usage=\u7528\u6CD5: \n javah [options] \n\u5176\u4E2D, [options] \u5305\u62EC: main.opt.o=\ -o \u8F93\u51FA\u6587\u4EF6 (\u53EA\u80FD\u4F7F\u7528 -d \u6216 -o \u4E4B\u4E00) @@ -60,6 +60,7 @@ main.opt.version=\ -version \u8F93\u51FA\u7248\u672C\u4FE1\u606 main.opt.jni=\ -jni \u751F\u6210 JNI \u6837\u5F0F\u7684\u6807\u5934\u6587\u4EF6 (\u9ED8\u8BA4\u503C) main.opt.force=\ -force \u59CB\u7EC8\u5199\u5165\u8F93\u51FA\u6587\u4EF6 main.opt.classpath=\ -classpath \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84 +main.opt.cp=\ -cp \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84 main.opt.bootclasspath=\ -bootclasspath \u4ECE\u4E2D\u52A0\u8F7D\u5F15\u5BFC\u7C7B\u7684\u8DEF\u5F84 main.usage.foot= \u662F\u4F7F\u7528\u5176\u5168\u9650\u5B9A\u540D\u79F0\u6307\u5B9A\u7684\n(\u4F8B\u5982, java.lang.Object)\u3002 diff --git a/langtools/src/share/classes/com/sun/tools/javap/resources/javap_ja.properties b/langtools/src/share/classes/com/sun/tools/javap/resources/javap_ja.properties index e5b96053f10..72787232d52 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/resources/javap_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/javap/resources/javap_ja.properties @@ -1,5 +1,5 @@ -err.prefix=\u30A8\u30E9\u30FC: +err.prefix=\u30A8\u30E9\u30FC: err.bad.constant.pool={0}\u306E\u5B9A\u6570\u30D7\u30FC\u30EB\u306E\u8AAD\u53D6\u308A\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {1} err.class.not.found=\u30AF\u30E9\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {0} @@ -55,6 +55,8 @@ main.opt.s=\ -s \u5185\u90E8\u30BF\u30A4\u30D7\u7F72\u540 main.opt.classpath=\ -classpath \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B +main.opt.cp=\ -cp \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B + main.opt.bootclasspath=\ -bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u4F4D\u7F6E\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B main.opt.constants=\ -constants \u9759\u7684final\u5B9A\u6570\u3092\u8868\u793A\u3059\u308B diff --git a/langtools/src/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties index 97e4f5ce972..b9027ec9500 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties @@ -1,5 +1,5 @@ -err.prefix=\u9519\u8BEF: +err.prefix=\u9519\u8BEF: err.bad.constant.pool=\u8BFB\u53D6{0}\u7684\u5E38\u91CF\u6C60\u65F6\u51FA\u9519: {1} err.class.not.found=\u627E\u4E0D\u5230\u7C7B: {0} @@ -55,6 +55,8 @@ main.opt.s=\ -s \u8F93\u51FA\u5185\u90E8\u7C7B\u578B\u7B7 main.opt.classpath=\ -classpath \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E +main.opt.cp=\ -cp \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E + main.opt.bootclasspath=\ -bootclasspath \u8986\u76D6\u5F15\u5BFC\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E main.opt.constants=\ -constants \u663E\u793A\u9759\u6001\u6700\u7EC8\u5E38\u91CF From 0ccb2841ea32b7cee8321fc6563f0d269f010d6d Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 24 Sep 2013 16:08:00 -0700 Subject: [PATCH 0493/1294] 8022585: VM crashes when ran with -XX:+PrintInlining Use adr_at() to access inline info structures in growableArray. Add ability to specify print inlining per method. Reviewed-by: twisti --- hotspot/src/share/vm/c1/c1_GraphBuilder.cpp | 4 ++- hotspot/src/share/vm/opto/bytecodeInfo.cpp | 10 +++--- hotspot/src/share/vm/opto/callGenerator.hpp | 3 +- hotspot/src/share/vm/opto/compile.cpp | 12 ++++--- hotspot/src/share/vm/opto/compile.hpp | 26 ++++++++------ hotspot/src/share/vm/opto/doCall.cpp | 4 +-- hotspot/src/share/vm/opto/library_call.cpp | 26 +++++++------- .../test/compiler/print/PrintInlining.java | 36 +++++++++++++++++++ 8 files changed, 84 insertions(+), 37 deletions(-) create mode 100644 hotspot/test/compiler/print/PrintInlining.java diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index b7ea6eebb26..03d0d75fa30 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -4219,7 +4219,9 @@ void GraphBuilder::print_inlining(ciMethod* callee, const char* msg, bool succes } } - if (!PrintInlining) return; + if (!PrintInlining && !compilation()->method()->has_option("PrintInlining")) { + return; + } CompileTask::print_inlining(callee, scope()->level(), bci(), msg); if (success && CIPrintMethodCodes) { callee->print_codes(); diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp index 45ba8d758b0..2ba7b1cf3b4 100644 --- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp +++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp @@ -123,7 +123,7 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, // Allows targeted inlining if(callee_method->should_inline()) { *wci_result = *(WarmCallInfo::always_hot()); - if (PrintInlining && Verbose) { + if (C->print_inlining() && Verbose) { CompileTask::print_inline_indent(inline_level()); tty->print_cr("Inlined method is hot: "); } @@ -137,7 +137,7 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, if(callee_method->interpreter_throwout_count() > InlineThrowCount && size < InlineThrowMaxSize ) { wci_result->set_profit(wci_result->profit() * 100); - if (PrintInlining && Verbose) { + if (C->print_inlining() && Verbose) { CompileTask::print_inline_indent(inline_level()); tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); } @@ -491,7 +491,7 @@ void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, C->log()->inline_fail(inline_msg); } } - if (PrintInlining) { + if (C->print_inlining()) { C->print_inlining(callee_method, inline_level(), caller_bci, inline_msg); if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); if (Verbose && callee_method) { @@ -540,7 +540,7 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, #ifndef PRODUCT if (UseOldInlining && InlineWarmCalls - && (PrintOpto || PrintOptoInlining || PrintInlining)) { + && (PrintOpto || C->print_inlining())) { bool cold = wci.is_cold(); bool hot = !cold && wci.is_hot(); bool old_cold = !success; @@ -617,7 +617,7 @@ InlineTree *InlineTree::build_inline_tree_for_callee( ciMethod* callee_method, J callee_method->is_compiled_lambda_form()) { max_inline_level_adjust += 1; // don't count method handle calls from java.lang.invoke implem } - if (max_inline_level_adjust != 0 && PrintInlining && (Verbose || WizardMode)) { + if (max_inline_level_adjust != 0 && C->print_inlining() && (Verbose || WizardMode)) { CompileTask::print_inline_indent(inline_level()); tty->print_cr(" \\-> discounting inline depth"); } diff --git a/hotspot/src/share/vm/opto/callGenerator.hpp b/hotspot/src/share/vm/opto/callGenerator.hpp index 0f6b2d16590..a1616de4dc7 100644 --- a/hotspot/src/share/vm/opto/callGenerator.hpp +++ b/hotspot/src/share/vm/opto/callGenerator.hpp @@ -159,8 +159,9 @@ class CallGenerator : public ResourceObj { virtual void print_inlining_late(const char* msg) { ShouldNotReachHere(); } static void print_inlining(Compile* C, ciMethod* callee, int inline_level, int bci, const char* msg) { - if (PrintInlining) + if (C->print_inlining()) { C->print_inlining(callee, inline_level, bci, msg); + } } }; diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 1c625d679b3..0fed4e06c72 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -654,7 +654,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr _inlining_progress(false), _inlining_incrementally(false), _print_inlining_list(NULL), - _print_inlining(0) { + _print_inlining_idx(0) { C = this; CompileWrapper cw(this); @@ -679,6 +679,8 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr set_print_assembly(print_opto_assembly); set_parsed_irreducible_loop(false); #endif + set_print_inlining(PrintInlining || method()->has_option("PrintInlining") NOT_PRODUCT( || PrintOptoInlining)); + set_print_intrinsics(PrintIntrinsics || method()->has_option("PrintIntrinsics")); if (ProfileTraps) { // Make sure the method being compiled gets its own MDO, @@ -710,7 +712,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr PhaseGVN gvn(node_arena(), estimated_size); set_initial_gvn(&gvn); - if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) { + if (print_inlining() || print_intrinsics()) { _print_inlining_list = new (comp_arena())GrowableArray(comp_arena(), 1, 1, PrintInliningBuffer()); } { // Scope for timing the parser @@ -937,7 +939,7 @@ Compile::Compile( ciEnv* ci_env, _inlining_progress(false), _inlining_incrementally(false), _print_inlining_list(NULL), - _print_inlining(0) { + _print_inlining_idx(0) { C = this; #ifndef PRODUCT @@ -3611,7 +3613,7 @@ void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n } void Compile::dump_inlining() { - if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) { + if (print_inlining() || print_intrinsics()) { // Print inlining message for candidates that we couldn't inline // for lack of space or non constant receiver for (int i = 0; i < _late_inlines.length(); i++) { @@ -3635,7 +3637,7 @@ void Compile::dump_inlining() { } } for (int i = 0; i < _print_inlining_list->length(); i++) { - tty->print(_print_inlining_list->at(i).ss()->as_string()); + tty->print(_print_inlining_list->adr_at(i)->ss()->as_string()); } } } diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index 8d862c24125..631372efabc 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -312,6 +312,8 @@ class Compile : public Phase { bool _do_method_data_update; // True if we generate code to update MethodData*s int _AliasLevel; // Locally-adjusted version of AliasLevel flag. bool _print_assembly; // True if we should dump assembly code for this compilation + bool _print_inlining; // True if we should print inlining for this compilation + bool _print_intrinsics; // True if we should print intrinsics for this compilation #ifndef PRODUCT bool _trace_opto_output; bool _parsed_irreducible_loop; // True if ciTypeFlow detected irreducible loops during parsing @@ -414,7 +416,7 @@ class Compile : public Phase { }; GrowableArray* _print_inlining_list; - int _print_inlining; + int _print_inlining_idx; // Only keep nodes in the expensive node list that need to be optimized void cleanup_expensive_nodes(PhaseIterGVN &igvn); @@ -426,24 +428,24 @@ class Compile : public Phase { public: outputStream* print_inlining_stream() const { - return _print_inlining_list->at(_print_inlining).ss(); + return _print_inlining_list->adr_at(_print_inlining_idx)->ss(); } void print_inlining_skip(CallGenerator* cg) { - if (PrintInlining) { - _print_inlining_list->at(_print_inlining).set_cg(cg); - _print_inlining++; - _print_inlining_list->insert_before(_print_inlining, PrintInliningBuffer()); + if (_print_inlining) { + _print_inlining_list->adr_at(_print_inlining_idx)->set_cg(cg); + _print_inlining_idx++; + _print_inlining_list->insert_before(_print_inlining_idx, PrintInliningBuffer()); } } void print_inlining_insert(CallGenerator* cg) { - if (PrintInlining) { + if (_print_inlining) { for (int i = 0; i < _print_inlining_list->length(); i++) { - if (_print_inlining_list->at(i).cg() == cg) { + if (_print_inlining_list->adr_at(i)->cg() == cg) { _print_inlining_list->insert_before(i+1, PrintInliningBuffer()); - _print_inlining = i+1; - _print_inlining_list->at(i).set_cg(NULL); + _print_inlining_idx = i+1; + _print_inlining_list->adr_at(i)->set_cg(NULL); return; } } @@ -572,6 +574,10 @@ class Compile : public Phase { int AliasLevel() const { return _AliasLevel; } bool print_assembly() const { return _print_assembly; } void set_print_assembly(bool z) { _print_assembly = z; } + bool print_inlining() const { return _print_inlining; } + void set_print_inlining(bool z) { _print_inlining = z; } + bool print_intrinsics() const { return _print_intrinsics; } + void set_print_intrinsics(bool z) { _print_intrinsics = z; } // check the CompilerOracle for special behaviours for this compile bool method_has_option(const char * option) { return method() != NULL && method()->has_option(option); diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index e55a01ba638..8784bbe2dc5 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -41,9 +41,9 @@ #include "runtime/sharedRuntime.hpp" void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) { - if (TraceTypeProfile || PrintInlining NOT_PRODUCT(|| PrintOptoInlining)) { + if (TraceTypeProfile || C->print_inlining()) { outputStream* out = tty; - if (!PrintInlining) { + if (!C->print_inlining()) { if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) { method->print_short_name(); tty->cr(); diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 2bfa25fa9c2..902ed5919f3 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -543,7 +543,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) { Compile* C = kit.C; int nodes = C->unique(); #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { char buf[1000]; const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); tty->print_cr("Intrinsic %s", str); @@ -554,7 +554,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) { // Try to inline the intrinsic. if (kit.try_to_inline()) { - if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { + if (C->print_intrinsics() || C->print_inlining()) { C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); } C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); @@ -570,7 +570,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) { } // The intrinsic bailed out - if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { + if (C->print_intrinsics() || C->print_inlining()) { if (jvms->has_method()) { // Not a root compile. const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)"; @@ -592,7 +592,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) { int nodes = C->unique(); #ifndef PRODUCT assert(is_predicted(), "sanity"); - if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { char buf[1000]; const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); tty->print_cr("Predicate for intrinsic %s", str); @@ -603,7 +603,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) { Node* slow_ctl = kit.try_to_predicate(); if (!kit.failing()) { - if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { + if (C->print_intrinsics() || C->print_inlining()) { C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); } C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); @@ -617,7 +617,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) { } // The intrinsic bailed out - if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { + if (C->print_intrinsics() || C->print_inlining()) { if (jvms->has_method()) { // Not a root compile. const char* msg = "failed to generate predicate for intrinsic"; @@ -2299,7 +2299,7 @@ const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_ const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass); #ifndef PRODUCT - if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { + if (C->print_intrinsics() || C->print_inlining()) { tty->print(" from base type: "); adr_type->dump(); tty->print(" sharpened value: "); tjp->dump(); } @@ -3260,7 +3260,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { if (mirror_con == NULL) return false; // cannot happen? #ifndef PRODUCT - if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { + if (C->print_intrinsics() || C->print_inlining()) { ciType* k = mirror_con->java_mirror_type(); if (k) { tty->print("Inlining %s on constant Class ", vmIntrinsics::name_at(intrinsic_id())); @@ -3952,14 +3952,14 @@ bool LibraryCallKit::inline_native_getClass() { // caller sensitive methods. bool LibraryCallKit::inline_native_Reflection_getCallerClass() { #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass"); } #endif if (!jvms()->has_method()) { #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { tty->print_cr(" Bailing out because intrinsic was inlined at top level"); } #endif @@ -3983,7 +3983,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() { // Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass). if (!m->caller_sensitive()) { #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { tty->print_cr(" Bailing out: CallerSensitive annotation expected at frame %d", n); } #endif @@ -3999,7 +3999,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() { set_result(makecon(TypeInstPtr::make(caller_mirror))); #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { tty->print_cr(" Succeeded: caller = %d) %s.%s, JVMS depth = %d", n, caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), jvms()->depth()); tty->print_cr(" JVM state at this point:"); for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { @@ -4015,7 +4015,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() { } #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { tty->print_cr(" Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth()); tty->print_cr(" JVM state at this point:"); for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { diff --git a/hotspot/test/compiler/print/PrintInlining.java b/hotspot/test/compiler/print/PrintInlining.java new file mode 100644 index 00000000000..877d25e8c38 --- /dev/null +++ b/hotspot/test/compiler/print/PrintInlining.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013, 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 8022585 + * @summary VM crashes when ran with -XX:+PrintInlining + * @run main/othervm -Xcomp -XX:+PrintInlining PrintInlining + * + */ + +public class PrintInlining { + public static void main(String[] args) { + System.out.println("Passed"); + } +} From 2233312946292ac77ccf9092fb50e1fc91391c34 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Tue, 24 Sep 2013 16:12:06 -0700 Subject: [PATCH 0494/1294] 8016328: Regression : Javadoc i18n regression caused by fix for 8012375 Reviewed-by: jjg --- .../doclets/formats/html/markup/HtmlTree.java | 43 ++++++++++++++++++- .../formats/html/markup/HtmlWriter.java | 9 +++- .../com/sun/javadoc/testHref/TestHref.java | 10 ++--- .../testJavascript/TestJavascript.java | 11 ++++- .../testLinkTaglet/TestLinkTaglet.java | 8 ++-- .../TestPrivateClasses.java | 4 +- .../javadoc/testUseOption/TestUseOption.java | 6 +-- 7 files changed, 73 insertions(+), 18 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java index dc59eb0f4a0..fb7c409c3f0 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java @@ -28,6 +28,7 @@ package com.sun.tools.doclets.formats.html.markup; import java.io.IOException; import java.io.Writer; import java.util.*; +import java.nio.charset.*; import com.sun.tools.doclets.internal.toolkit.Content; import com.sun.tools.doclets.internal.toolkit.util.*; @@ -163,6 +164,46 @@ public class HtmlTree extends Content { return s; } + /** + * A set of ASCII URI characters to be left unencoded. + */ + public static BitSet NONENCODING_CHARS = new BitSet(256); + + static { + // alphabetic characters + for (int i = 'a'; i <= 'z'; i++) { + NONENCODING_CHARS.set(i); + } + for (int i = 'A'; i <= 'Z'; i++) { + NONENCODING_CHARS.set(i); + } + // numeric characters + for (int i = '0'; i <= '9'; i++) { + NONENCODING_CHARS.set(i); + } + // Reserved characters as per RFC 3986. These are set of delimiting characters. + String noEnc = ":/?#[]@!$&'()*+,;="; + // Unreserved characters as per RFC 3986 which should not be percent encoded. + noEnc += "-._~"; + for (int i = 0; i < noEnc.length(); i++) { + NONENCODING_CHARS.set(noEnc.charAt(i)); + } + } + + private static String encodeURL(String url) { + byte[] urlBytes = url.getBytes(Charset.forName("UTF-8")); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < urlBytes.length; i++) { + int c = urlBytes[i]; + if (NONENCODING_CHARS.get(c & 0xFF)) { + sb.append((char) c); + } else { + sb.append(String.format("%%%02X", c & 0xFF)); + } + } + return sb.toString(); + } + /** * Generates an HTML anchor tag. * @@ -172,7 +213,7 @@ public class HtmlTree extends Content { */ public static HtmlTree A(String ref, Content body) { HtmlTree htmltree = new HtmlTree(HtmlTag.A, nullCheck(body)); - htmltree.addAttr(HtmlAttr.HREF, ref); + htmltree.addAttr(HtmlAttr.HREF, encodeURL(ref)); return htmltree; } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java index 36becd2e7ef..e1da06598a6 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java @@ -335,6 +335,12 @@ public class HtmlWriter { " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + DocletConstants.NL + " targetPage = \"undefined\";" + DocletConstants.NL + " function validURL(url) {" + DocletConstants.NL + + " try {" + DocletConstants.NL + + " url = decodeURIComponent(url);" + DocletConstants.NL + + " }" + DocletConstants.NL + + " catch (error) {" + DocletConstants.NL + + " return false;" + DocletConstants.NL + + " }" + DocletConstants.NL + " var pos = url.indexOf(\".html\");" + DocletConstants.NL + " if (pos == -1 || pos != url.length - 5)" + DocletConstants.NL + " return false;" + DocletConstants.NL + @@ -346,7 +352,8 @@ public class HtmlWriter { " if ('a' <= ch && ch <= 'z' ||" + DocletConstants.NL + " 'A' <= ch && ch <= 'Z' ||" + DocletConstants.NL + " ch == '$' ||" + DocletConstants.NL + - " ch == '_') {" + DocletConstants.NL + + " ch == '_' ||" + DocletConstants.NL + + " ch.charCodeAt(0) > 127) {" + DocletConstants.NL + " allowNumber = true;" + DocletConstants.NL + " allowSep = true;" + DocletConstants.NL + " } else if ('0' <= ch && ch <= '9'" + DocletConstants.NL + diff --git a/langtools/test/com/sun/javadoc/testHref/TestHref.java b/langtools/test/com/sun/javadoc/testHref/TestHref.java index 297ddc69164..b8c4a24ca05 100644 --- a/langtools/test/com/sun/javadoc/testHref/TestHref.java +++ b/langtools/test/com/sun/javadoc/testHref/TestHref.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4663254 + * @bug 4663254 8016328 * @summary Verify that spaces do not appear in hrefs and anchors. * @author jamieh * @library ../lib/ @@ -46,11 +46,11 @@ public class TestHref extends JavadocTester { private static final String[][] TEST = { //External link. {BUG_ID + FS + "pkg" + FS + "C1.html", - "href=\"http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html?is-external=true#wait(long, int)\"" + "href=\"http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html?is-external=true#wait(long,%20int)\"" }, //Member summary table link. {BUG_ID + FS + "pkg" + FS + "C1.html", - "href=\"../pkg/C1.html#method(int, int, java.util.ArrayList)\"" + "href=\"../pkg/C1.html#method(int,%20int,%20java.util.ArrayList)\"" }, //Anchor test. {BUG_ID + FS + "pkg" + FS + "C1.html", @@ -66,11 +66,11 @@ public class TestHref extends JavadocTester { }, //{@link} test. {BUG_ID + FS + "pkg" + FS + "C2.html", - "Link: " + "Link: " }, //@see test. {BUG_ID + FS + "pkg" + FS + "C2.html", - "See Also:" + NL + "
    " + "See Also:" + NL + "
    " }, //Header does not link to the page itself. diff --git a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java index 763566a03ac..28602092110 100644 --- a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java +++ b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4665566 4855876 7025314 8012375 8015997 + * @bug 4665566 4855876 7025314 8012375 8015997 8016328 * @summary Verify that the output has the right javascript. * @author jamieh * @library ../lib/ @@ -56,6 +56,12 @@ public class TestJavascript extends JavadocTester { " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + NL + " targetPage = \"undefined\";" + NL + " function validURL(url) {" + NL + + " try {" + NL + + " url = decodeURIComponent(url);" + NL + + " }" + NL + + " catch (error) {" + NL + + " return false;" + NL + + " }" + NL + " var pos = url.indexOf(\".html\");" + NL + " if (pos == -1 || pos != url.length - 5)" + NL + " return false;" + NL + @@ -67,7 +73,8 @@ public class TestJavascript extends JavadocTester { " if ('a' <= ch && ch <= 'z' ||" + NL + " 'A' <= ch && ch <= 'Z' ||" + NL + " ch == '$' ||" + NL + - " ch == '_') {" + NL + + " ch == '_' ||" + NL + + " ch.charCodeAt(0) > 127) {" + NL + " allowNumber = true;" + NL + " allowSep = true;" + NL + " } else if ('0' <= ch && ch <= '9'" + NL + diff --git a/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java b/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java index 4720fe4d2be..ef9dd2bbb9a 100644 --- a/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java +++ b/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4732864 6280605 7064544 8014636 + * @bug 4732864 6280605 7064544 8014636 8016328 * @summary Make sure that you can link from one member to another using * non-qualified name, furthermore, ensure the right one is linked. * @author jamieh @@ -49,9 +49,9 @@ public class TestLinkTaglet extends JavadocTester { "Qualified Link: C.InnerC.
    " + NL + " Unqualified Link1: C.InnerC.
    " + NL + " Unqualified Link2: C.InnerC.
    " + NL + - " Qualified Link: method(pkg.C.InnerC, pkg.C.InnerC2).
    " + NL + - " Unqualified Link: method(C.InnerC, C.InnerC2).
    " + NL + - " Unqualified Link: method(InnerC, InnerC2).
    " + " Qualified Link: method(pkg.C.InnerC, pkg.C.InnerC2).
    " + NL + + " Unqualified Link: method(C.InnerC, C.InnerC2).
    " + NL + + " Unqualified Link: method(InnerC, InnerC2).
    " }, {BUG_ID + FS + "pkg" + FS + "C.InnerC.html", "Link to member in outer class: C.MEMBER
    " + NL + diff --git a/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java b/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java index b6ae263d8a4..b7a9bc73a10 100644 --- a/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java +++ b/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4780441 4874845 4978816 8014017 + * @bug 4780441 4874845 4978816 8014017 8016328 * @summary Make sure that when the -private flag is not used, members * inherited from package private class are documented in the child. * @@ -177,7 +177,7 @@ public class TestPrivateClasses extends JavadocTester { // Should document that a method overrides method from private class. {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", "
    Overrides:
    " + NL + - "
    " + + "
    " + "methodOverridenFromParent in class " + "" + "PrivateParent
    "}, diff --git a/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java b/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java index 6a61e43f3b1..a1e0e970af0 100644 --- a/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java +++ b/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4496290 4985072 7006178 7068595 + * @bug 4496290 4985072 7006178 7068595 8016328 * @summary A simple test to determine if -use works. * @author jamieh * @library ../lib/ @@ -60,7 +60,7 @@ public class TestUseOption extends JavadocTester { "UsedInC in <Unnamed>" }, {BUG_ID + "-3" + FS + "package-use.html", "" + - "UsedInC " + "UsedInC " } }; From f8d5db06b9ca8423b4b5982c9c9cb8b923950d24 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 25 Sep 2013 08:17:37 +0530 Subject: [PATCH 0495/1294] 8025325: parseFloat does not handle '.' in exponent part Reviewed-by: hannesw --- .../internal/runtime/GlobalFunctions.java | 2 +- nashorn/test/script/basic/JDK-8025325.js | 35 +++++++++++++++++++ .../test/script/basic/JDK-8025325.js.EXPECTED | 5 +++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8025325.js create mode 100644 nashorn/test/script/basic/JDK-8025325.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java index 9ddc7090b2b..c750d80e913 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java @@ -211,7 +211,7 @@ loop: switch (ch) { case '.': // dot allowed only once - if (dotSeen) { + if (exponentOffset != -1 || dotSeen) { break loop; } dotSeen = true; diff --git a/nashorn/test/script/basic/JDK-8025325.js b/nashorn/test/script/basic/JDK-8025325.js new file mode 100644 index 00000000000..63dfef9d96e --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025325.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/** + * JDK-8025325: parseFloat does not handle '.' in exponent part + * + * @test + * @run + */ + +print(parseFloat("2e2.")); +print(parseFloat("2e2.3")); +print(parseFloat("2e2.fdgdf")); +print(parseFloat("2e2. gdfgdf")); +print(parseFloat("2e2. ")); diff --git a/nashorn/test/script/basic/JDK-8025325.js.EXPECTED b/nashorn/test/script/basic/JDK-8025325.js.EXPECTED new file mode 100644 index 00000000000..4ddf679a54b --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025325.js.EXPECTED @@ -0,0 +1,5 @@ +200 +200 +200 +200 +200 From ddddd1d31f770943fcf2e737a7bf5ac490be27b6 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 25 Sep 2013 09:47:24 +0200 Subject: [PATCH 0496/1294] 8025140: TEST_BUG: java/util/logging/Logger/getGlobal tests fail due to timeout Arbitrary timeouts in the tests @run lines where too agressive for some configurations. The tests will now run with default timeout. Reviewed-by: alanb, mchung --- .../Logger/getGlobal/TestGetGlobal.java | 24 +++++++++---------- .../Logger/getGlobal/TestGetGlobalByName.java | 24 +++++++++---------- .../getGlobal/TestGetGlobalConcurrent.java | 24 +++++++++---------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java index 4c6b39b0acd..e87e15f81fc 100644 --- a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java +++ b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java @@ -29,18 +29,18 @@ import java.util.logging.Logger; * @bug 7184195 * @summary checks that java.util.logging.Logger.getGlobal().info() logs without configuration * @build TestGetGlobal testgetglobal.HandlerImpl testgetglobal.LogManagerImpl1 testgetglobal.LogManagerImpl2 testgetglobal.LogManagerImpl3 testgetglobal.BadLogManagerImpl testgetglobal.DummyLogManagerImpl - * @run main/othervm/timeout=10 TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager TestGetGlobal - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobal - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobal - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobal - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobal - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobal + * @run main/othervm TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager TestGetGlobal + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobal + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobal + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobal + * @run main/othervm -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobal + * @run main/othervm -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobal * @author danielfuchs */ public class TestGetGlobal { diff --git a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalByName.java b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalByName.java index 62580a8bc3b..91968db400b 100644 --- a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalByName.java +++ b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalByName.java @@ -29,18 +29,18 @@ import java.util.logging.Logger; * @bug 7184195 * @summary checks that java.util.logging.Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info() logs without configuration * @build TestGetGlobalByName testgetglobal.HandlerImpl testgetglobal.LogManagerImpl1 testgetglobal.LogManagerImpl2 testgetglobal.LogManagerImpl3 testgetglobal.BadLogManagerImpl testgetglobal.DummyLogManagerImpl - * @run main/othervm/timeout=10 TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager TestGetGlobalByName - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl TestGetGlobalByName - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalByName - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalByName - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalByName - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalByName + * @run main/othervm TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager TestGetGlobalByName + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl TestGetGlobalByName + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalByName + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalByName + * @run main/othervm -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalByName + * @run main/othervm -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalByName * @author danielfuchs */ public class TestGetGlobalByName { diff --git a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java index e3f9d1d8872..23688e1bca5 100644 --- a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java +++ b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java @@ -30,18 +30,18 @@ import java.util.logging.Logger; * @bug 7184195 8021003 * @summary Test that the global logger can log with no configuration when accessed from multiple threads. * @build TestGetGlobalConcurrent testgetglobal.HandlerImpl testgetglobal.LogManagerImpl1 testgetglobal.LogManagerImpl2 testgetglobal.LogManagerImpl3 testgetglobal.BadLogManagerImpl testgetglobal.DummyLogManagerImpl - * @run main/othervm/timeout=10 TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager TestGetGlobalConcurrent - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalConcurrent - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalConcurrent - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalConcurrent - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalConcurrent + * @run main/othervm TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager TestGetGlobalConcurrent + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalConcurrent + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalConcurrent + * @run main/othervm -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalConcurrent + * @run main/othervm -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalConcurrent * @author danielfuchs */ public class TestGetGlobalConcurrent { From 0587e4621540c920b4c4c4579bc46d8cb1dade48 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 25 Sep 2013 14:06:15 +0400 Subject: [PATCH 0497/1294] 8023310: Thread contention in the method Beans.IsDesignTime() Reviewed-by: art, sfriberg --- .../java/beans/ThreadGroupContext.java | 18 +-- .../classes/java/beans/WeakIdentityMap.java | 139 ++++++++++-------- 2 files changed, 81 insertions(+), 76 deletions(-) diff --git a/jdk/src/share/classes/java/beans/ThreadGroupContext.java b/jdk/src/share/classes/java/beans/ThreadGroupContext.java index 6236ec2b38c..d93f1a87217 100644 --- a/jdk/src/share/classes/java/beans/ThreadGroupContext.java +++ b/jdk/src/share/classes/java/beans/ThreadGroupContext.java @@ -41,24 +41,20 @@ import java.util.WeakHashMap; */ final class ThreadGroupContext { - private static final WeakIdentityMap contexts = new WeakIdentityMap<>(); + private static final WeakIdentityMap contexts = new WeakIdentityMap() { + protected ThreadGroupContext create(Object key) { + return new ThreadGroupContext(); + } + }; /** - * Returns the appropriate {@code AppContext} for the caller, + * Returns the appropriate {@code ThreadGroupContext} for the caller, * as determined by its {@code ThreadGroup}. * * @return the application-dependent context */ static ThreadGroupContext getContext() { - ThreadGroup group = Thread.currentThread().getThreadGroup(); - synchronized (contexts) { - ThreadGroupContext context = contexts.get(group); - if (context == null) { - context = new ThreadGroupContext(); - contexts.put(group, context); - } - return context; - } + return contexts.get(Thread.currentThread().getThreadGroup()); } private volatile boolean isDesignTime; diff --git a/jdk/src/share/classes/java/beans/WeakIdentityMap.java b/jdk/src/share/classes/java/beans/WeakIdentityMap.java index 42ac821a392..83d8bfb1b50 100644 --- a/jdk/src/share/classes/java/beans/WeakIdentityMap.java +++ b/jdk/src/share/classes/java/beans/WeakIdentityMap.java @@ -33,18 +33,22 @@ import java.lang.ref.WeakReference; * and reference-equality in place of object-equality to compare them. * An entry will automatically be removed when its key is no longer * in ordinary use. Both null values and the null key are supported. + * This class does not require additional synchronization. + * A thread-safety is provided by a fragile combination + * of synchronized blocks and volatile fields. + * Be very careful during editing! * * @see java.util.IdentityHashMap * @see java.util.WeakHashMap */ -final class WeakIdentityMap { +abstract class WeakIdentityMap { private static final int MAXIMUM_CAPACITY = 1 << 30; // it MUST be a power of two private static final Object NULL = new Object(); // special object for null key private final ReferenceQueue queue = new ReferenceQueue(); - private Entry[] table = newTable(1<<3); // table's length MUST be a power of two + private volatile Entry[] table = newTable(1<<3); // table's length MUST be a power of two private int threshold = 6; // the next size value at which to resize private int size = 0; // the number of key-value mappings @@ -54,78 +58,83 @@ final class WeakIdentityMap { key = NULL; } int hash = key.hashCode(); - int index = getIndex(this.table, hash); - for (Entry entry = this.table[index]; entry != null; entry = entry.next) { + Entry[] table = this.table; + // unsynchronized search improves performance + // the null value does not mean that there are no needed entry + int index = getIndex(table, hash); + for (Entry entry = table[index]; entry != null; entry = entry.next) { if (entry.isMatched(key, hash)) { return entry.value; } } - return null; - } - - public T put(Object key, T value) { - removeStaleEntries(); - if (key == null) { - key = NULL; - } - int hash = key.hashCode(); - int index = getIndex(this.table, hash); - for (Entry entry = this.table[index]; entry != null; entry = entry.next) { - if (entry.isMatched(key, hash)) { - T oldValue = entry.value; - entry.value = value; - return oldValue; + synchronized (NULL) { + // synchronized search improves stability + // we must create and add new value if there are no needed entry + index = getIndex(this.table, hash); + for (Entry entry = this.table[index]; entry != null; entry = entry.next) { + if (entry.isMatched(key, hash)) { + return entry.value; + } } - } - this.table[index] = new Entry(key, hash, value, this.queue, this.table[index]); - if (++this.size >= this.threshold) { - if (this.table.length == MAXIMUM_CAPACITY) { - this.threshold = Integer.MAX_VALUE; - } - else { - removeStaleEntries(); - Entry[] table = newTable(this.table.length * 2); - transfer(this.table, table); - - // If ignoring null elements and processing ref queue caused massive - // shrinkage, then restore old table. This should be rare, but avoids - // unbounded expansion of garbage-filled tables. - if (this.size >= this.threshold / 2) { - this.table = table; - this.threshold *= 2; + T value = create(key); + this.table[index] = new Entry(key, hash, value, this.queue, this.table[index]); + if (++this.size >= this.threshold) { + if (this.table.length == MAXIMUM_CAPACITY) { + this.threshold = Integer.MAX_VALUE; } else { - transfer(table, this.table); - } - } - } - return null; - } - - private void removeStaleEntries() { - for (Object ref = this.queue.poll(); ref != null; ref = this.queue.poll()) { - @SuppressWarnings("unchecked") - Entry entry = (Entry) ref; - int index = getIndex(this.table, entry.hash); - - Entry prev = this.table[index]; - Entry current = prev; - while (current != null) { - Entry next = current.next; - if (current == entry) { - if (prev == entry) { - this.table[index] = next; + removeStaleEntries(); + table = newTable(this.table.length * 2); + transfer(this.table, table); + // If ignoring null elements and processing ref queue caused massive + // shrinkage, then restore old table. This should be rare, but avoids + // unbounded expansion of garbage-filled tables. + if (this.size >= this.threshold / 2) { + this.table = table; + this.threshold *= 2; } else { - prev.next = next; + transfer(table, this.table); } - entry.value = null; // Help GC - entry.next = null; // Help GC - this.size--; - break; } - prev = current; - current = next; + } + return value; + } + } + + protected abstract T create(Object key); + + private void removeStaleEntries() { + Object ref = this.queue.poll(); + if (ref != null) { + synchronized (NULL) { + do { + @SuppressWarnings("unchecked") + Entry entry = (Entry) ref; + int index = getIndex(this.table, entry.hash); + + Entry prev = this.table[index]; + Entry current = prev; + while (current != null) { + Entry next = current.next; + if (current == entry) { + if (prev == entry) { + this.table[index] = next; + } + else { + prev.next = next; + } + entry.value = null; // Help GC + entry.next = null; // Help GC + this.size--; + break; + } + prev = current; + current = next; + } + ref = this.queue.poll(); + } + while (ref != null); } } } @@ -164,8 +173,8 @@ final class WeakIdentityMap { private static class Entry extends WeakReference { private final int hash; - private T value; - private Entry next; + private volatile T value; + private volatile Entry next; Entry(Object key, int hash, T value, ReferenceQueue queue, Entry next) { super(key, queue); From ab5637182c30ed955197bdad674c7bd51f8b2f3a Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 25 Sep 2013 13:25:24 +0200 Subject: [PATCH 0498/1294] 7163191: G1: introduce a "heap spanning table" abstraction Add G1BiasedArray that is an array where each element represents a fixed-sized subdivision of the heap. Use this abstraction to refactor the HeapRegionSeq class. Reviewed-by: brutisso --- hotspot/make/excludeSrc.make | 2 +- .../vm/gc_implementation/g1/g1BiasedArray.cpp | 141 ++++++++++++++ .../vm/gc_implementation/g1/g1BiasedArray.hpp | 181 ++++++++++++++++++ .../gc_implementation/g1/g1CollectedHeap.cpp | 6 +- .../vm/gc_implementation/g1/heapRegionSeq.cpp | 49 ++--- .../vm/gc_implementation/g1/heapRegionSeq.hpp | 59 +++--- .../g1/heapRegionSeq.inline.hpp | 22 +-- .../vm/gc_implementation/g1/vmStructs_g1.hpp | 12 +- hotspot/src/share/vm/prims/jni.cpp | 4 + 9 files changed, 389 insertions(+), 87 deletions(-) create mode 100644 hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp create mode 100644 hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp diff --git a/hotspot/make/excludeSrc.make b/hotspot/make/excludeSrc.make index c3a9b4dea0e..a95dc1b114c 100644 --- a/hotspot/make/excludeSrc.make +++ b/hotspot/make/excludeSrc.make @@ -88,7 +88,7 @@ ifeq ($(INCLUDE_ALL_GCS), false) g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp \ g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp \ g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1_globals.cpp heapRegion.cpp \ - heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \ + g1BiasedArray.cpp heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \ ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp \ adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp \ cardTableExtension.cpp gcTaskManager.cpp gcTaskThread.cpp objectStartArray.cpp \ diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp new file mode 100644 index 00000000000..7f5023b422b --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/g1/g1BiasedArray.hpp" + +#ifndef PRODUCT +void G1BiasedMappedArrayBase::verify_index(idx_t index) const { + guarantee(_base != NULL, "Array not initialized"); + guarantee(index < length(), err_msg("Index out of bounds index: "SIZE_FORMAT" length: "SIZE_FORMAT, index, length())); +} + +void G1BiasedMappedArrayBase::verify_biased_index(idx_t biased_index) const { + guarantee(_biased_base != NULL, "Array not initialized"); + guarantee(biased_index >= bias() && biased_index < (bias() + length()), + err_msg("Biased index out of bounds, index: "SIZE_FORMAT" bias: "SIZE_FORMAT" length: "SIZE_FORMAT, biased_index, bias(), length())); +} + +void G1BiasedMappedArrayBase::verify_biased_index_inclusive_end(idx_t biased_index) const { + guarantee(_biased_base != NULL, "Array not initialized"); + guarantee(biased_index >= bias() && biased_index <= (bias() + length()), + err_msg("Biased index out of inclusive bounds, index: "SIZE_FORMAT" bias: "SIZE_FORMAT" length: "SIZE_FORMAT, biased_index, bias(), length())); +} + +class TestMappedArray : public G1BiasedMappedArray { +protected: + virtual int default_value() const { return 0xBAADBABE; } +public: + static void test_biasedarray() { + const size_t REGION_SIZE_IN_WORDS = 512; + const size_t NUM_REGIONS = 20; + HeapWord* fake_heap = (HeapWord*)LP64_ONLY(0xBAAA00000) NOT_LP64(0xBA000000); // Any value that is non-zero + + TestMappedArray array; + array.initialize(fake_heap, fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS, + REGION_SIZE_IN_WORDS * HeapWordSize); + // Check address calculation (bounds) + assert(array.bottom_address_mapped() == fake_heap, + err_msg("bottom mapped address should be "PTR_FORMAT", but is "PTR_FORMAT, fake_heap, array.bottom_address_mapped())); + assert(array.end_address_mapped() == (fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS), "must be"); + + int* bottom = array.address_mapped_to(fake_heap); + assert((void*)bottom == (void*) array.base(), "must be"); + int* end = array.address_mapped_to(fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS); + assert((void*)end == (void*)(array.base() + array.length()), "must be"); + // The entire array should contain default value elements + for (int* current = bottom; current < end; current++) { + assert(*current == array.default_value(), "must be"); + } + + // Test setting values in the table + + HeapWord* region_start_address = fake_heap + REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2); + HeapWord* region_end_address = fake_heap + (REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2) + REGION_SIZE_IN_WORDS - 1); + + // Set/get by address tests: invert some value; first retrieve one + int actual_value = array.get_by_index(NUM_REGIONS / 2); + array.set_by_index(NUM_REGIONS / 2, ~actual_value); + // Get the same value by address, should correspond to the start of the "region" + int value = array.get_by_address(region_start_address); + assert(value == ~actual_value, "must be"); + // Get the same value by address, at one HeapWord before the start + value = array.get_by_address(region_start_address - 1); + assert(value == array.default_value(), "must be"); + // Get the same value by address, at the end of the "region" + value = array.get_by_address(region_end_address); + assert(value == ~actual_value, "must be"); + // Make sure the next value maps to another index + value = array.get_by_address(region_end_address + 1); + assert(value == array.default_value(), "must be"); + + // Reset the value in the array + array.set_by_address(region_start_address + (region_end_address - region_start_address) / 2, actual_value); + + // The entire array should have the default value again + for (int* current = bottom; current < end; current++) { + assert(*current == array.default_value(), "must be"); + } + + // Set/get by index tests: invert some value + idx_t index = NUM_REGIONS / 2; + actual_value = array.get_by_index(index); + array.set_by_index(index, ~actual_value); + + value = array.get_by_index(index); + assert(value == ~actual_value, "must be"); + + value = array.get_by_index(index - 1); + assert(value == array.default_value(), "must be"); + + value = array.get_by_index(index + 1); + assert(value == array.default_value(), "must be"); + + array.set_by_index(0, 0); + value = array.get_by_index(0); + assert(value == 0, "must be"); + + array.set_by_index(array.length() - 1, 0); + value = array.get_by_index(array.length() - 1); + assert(value == 0, "must be"); + + array.set_by_index(index, 0); + + // The array should have three zeros, and default values otherwise + size_t num_zeros = 0; + for (int* current = bottom; current < end; current++) { + assert(*current == array.default_value() || *current == 0, "must be"); + if (*current == 0) { + num_zeros++; + } + } + assert(num_zeros == 3, "must be"); + } +}; + +void TestG1BiasedArray_test() { + TestMappedArray::test_biasedarray(); +} + +#endif diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp new file mode 100644 index 00000000000..f80c70b4e36 --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP +#define SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP + +#include "utilities/debug.hpp" +#include "memory/allocation.inline.hpp" + +// Implements the common base functionality for arrays that contain provisions +// for accessing its elements using a biased index. +// The element type is defined by the instantiating the template. +class G1BiasedMappedArrayBase VALUE_OBJ_CLASS_SPEC { + friend class VMStructs; +public: + typedef size_t idx_t; +protected: + address _base; // the real base address + size_t _length; // the length of the array + address _biased_base; // base address biased by "bias" elements + size_t _bias; // the bias, i.e. the offset biased_base is located to the right in elements + uint _shift_by; // the amount of bits to shift right when mapping to an index of the array. + +protected: + + G1BiasedMappedArrayBase() : _base(NULL), _length(0), _biased_base(NULL), + _bias(0), _shift_by(0) { } + + // Allocate a new array, generic version. + static address create_new_base_array(size_t length, size_t elem_size) { + assert(length > 0, "just checking"); + assert(elem_size > 0, "just checking"); + return NEW_C_HEAP_ARRAY(u_char, length * elem_size, mtGC); + } + + // Initialize the members of this class. The biased start address of this array + // is the bias (in elements) multiplied by the element size. + void initialize_base(address base, size_t length, size_t bias, size_t elem_size, uint shift_by) { + assert(base != NULL, "just checking"); + assert(length > 0, "just checking"); + assert(shift_by < sizeof(uintptr_t) * 8, err_msg("Shifting by %zd, larger than word size?", shift_by)); + _base = base; + _length = length; + _biased_base = base - (bias * elem_size); + _bias = bias; + _shift_by = shift_by; + } + + // Allocate and initialize this array to cover the heap addresses in the range + // of [bottom, end). + void initialize(HeapWord* bottom, HeapWord* end, size_t target_elem_size_in_bytes, size_t mapping_granularity_in_bytes) { + assert(mapping_granularity_in_bytes > 0, "just checking"); + assert(is_power_of_2(mapping_granularity_in_bytes), + err_msg("mapping granularity must be power of 2, is %zd", mapping_granularity_in_bytes)); + assert((uintptr_t)bottom % mapping_granularity_in_bytes == 0, + err_msg("bottom mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT, + mapping_granularity_in_bytes, bottom)); + assert((uintptr_t)end % mapping_granularity_in_bytes == 0, + err_msg("end mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT, + mapping_granularity_in_bytes, end)); + size_t num_target_elems = (end - bottom) / (mapping_granularity_in_bytes / HeapWordSize); + idx_t bias = (uintptr_t)bottom / mapping_granularity_in_bytes; + address base = create_new_base_array(num_target_elems, target_elem_size_in_bytes); + initialize_base(base, num_target_elems, bias, target_elem_size_in_bytes, log2_intptr(mapping_granularity_in_bytes)); + } + + size_t bias() const { return _bias; } + uint shift_by() const { return _shift_by; } + + void verify_index(idx_t index) const PRODUCT_RETURN; + void verify_biased_index(idx_t biased_index) const PRODUCT_RETURN; + void verify_biased_index_inclusive_end(idx_t biased_index) const PRODUCT_RETURN; + +public: + // Return the length of the array in elements. + size_t length() const { return _length; } +}; + +// Array that provides biased access and mapping from (valid) addresses in the +// heap into this array. +template +class G1BiasedMappedArray : public G1BiasedMappedArrayBase { +public: + typedef G1BiasedMappedArrayBase::idx_t idx_t; + + T* base() const { return (T*)G1BiasedMappedArrayBase::_base; } + // Return the element of the given array at the given index. Assume + // the index is valid. This is a convenience method that does sanity + // checking on the index. + T get_by_index(idx_t index) const { + verify_index(index); + return this->base()[index]; + } + + // Set the element of the given array at the given index to the + // given value. Assume the index is valid. This is a convenience + // method that does sanity checking on the index. + void set_by_index(idx_t index, T value) { + verify_index(index); + this->base()[index] = value; + } + + // The raw biased base pointer. + T* biased_base() const { return (T*)G1BiasedMappedArrayBase::_biased_base; } + + // Return the element of the given array that covers the given word in the + // heap. Assumes the index is valid. + T get_by_address(HeapWord* value) const { + idx_t biased_index = ((uintptr_t)value) >> this->shift_by(); + this->verify_biased_index(biased_index); + return biased_base()[biased_index]; + } + + // Set the value of the array entry that corresponds to the given array. + void set_by_address(HeapWord * address, T value) { + idx_t biased_index = ((uintptr_t)address) >> this->shift_by(); + this->verify_biased_index(biased_index); + biased_base()[biased_index] = value; + } + +protected: + // Returns the address of the element the given address maps to + T* address_mapped_to(HeapWord* address) { + idx_t biased_index = ((uintptr_t)address) >> this->shift_by(); + this->verify_biased_index_inclusive_end(biased_index); + return biased_base() + biased_index; + } + +public: + // Return the smallest address (inclusive) in the heap that this array covers. + HeapWord* bottom_address_mapped() const { + return (HeapWord*) ((uintptr_t)this->bias() << this->shift_by()); + } + + // Return the highest address (exclusive) in the heap that this array covers. + HeapWord* end_address_mapped() const { + return (HeapWord*) ((uintptr_t)(this->bias() + this->length()) << this->shift_by()); + } + +protected: + virtual T default_value() const = 0; + // Set all elements of the given array to the given value. + void clear() { + T value = default_value(); + for (idx_t i = 0; i < length(); i++) { + set_by_index(i, value); + } + } +public: + G1BiasedMappedArray() {} + + // Allocate and initialize this array to cover the heap addresses in the range + // of [bottom, end). + void initialize(HeapWord* bottom, HeapWord* end, size_t mapping_granularity) { + G1BiasedMappedArrayBase::initialize(bottom, end, sizeof(T), mapping_granularity); + this->clear(); + } +}; + +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 1d8ff8a26dc..0ecfd3ab3bb 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2069,8 +2069,10 @@ jint G1CollectedHeap::initialize() { _g1_storage.initialize(g1_rs, 0); _g1_committed = MemRegion((HeapWord*)_g1_storage.low(), (size_t) 0); _hrs.initialize((HeapWord*) _g1_reserved.start(), - (HeapWord*) _g1_reserved.end(), - _expansion_regions); + (HeapWord*) _g1_reserved.end()); + assert(_hrs.max_length() == _expansion_regions, + err_msg("max length: %u expansion regions: %u", + _hrs.max_length(), _expansion_regions)); // Do later initialization work for concurrent refinement. _cg1r->init(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp index dade3dfdfcf..eaa8e10f38d 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp @@ -71,27 +71,16 @@ uint HeapRegionSeq::find_contiguous_from(uint from, uint num) { // Public -void HeapRegionSeq::initialize(HeapWord* bottom, HeapWord* end, - uint max_length) { +void HeapRegionSeq::initialize(HeapWord* bottom, HeapWord* end) { assert((uintptr_t) bottom % HeapRegion::GrainBytes == 0, "bottom should be heap region aligned"); assert((uintptr_t) end % HeapRegion::GrainBytes == 0, "end should be heap region aligned"); - _length = 0; - _heap_bottom = bottom; - _heap_end = end; - _region_shift = HeapRegion::LogOfHRGrainBytes; _next_search_index = 0; _allocated_length = 0; - _max_length = max_length; - _regions = NEW_C_HEAP_ARRAY(HeapRegion*, max_length, mtGC); - memset(_regions, 0, (size_t) max_length * sizeof(HeapRegion*)); - _regions_biased = _regions - ((uintx) bottom >> _region_shift); - - assert(&_regions[0] == &_regions_biased[addr_to_index_biased(bottom)], - "bottom should be included in the region with index 0"); + _regions.initialize(bottom, end, HeapRegion::GrainBytes); } MemRegion HeapRegionSeq::expand_by(HeapWord* old_end, @@ -101,15 +90,15 @@ MemRegion HeapRegionSeq::expand_by(HeapWord* old_end, G1CollectedHeap* g1h = G1CollectedHeap::heap(); HeapWord* next_bottom = old_end; - assert(_heap_bottom <= next_bottom, "invariant"); + assert(heap_bottom() <= next_bottom, "invariant"); while (next_bottom < new_end) { - assert(next_bottom < _heap_end, "invariant"); + assert(next_bottom < heap_end(), "invariant"); uint index = length(); - assert(index < _max_length, "otherwise we cannot expand further"); + assert(index < max_length(), "otherwise we cannot expand further"); if (index == 0) { // We have not allocated any regions so far - assert(next_bottom == _heap_bottom, "invariant"); + assert(next_bottom == heap_bottom(), "invariant"); } else { // next_bottom should match the end of the last/previous region assert(next_bottom == at(index - 1)->end(), "invariant"); @@ -122,8 +111,8 @@ MemRegion HeapRegionSeq::expand_by(HeapWord* old_end, // allocation failed, we bail out and return what we have done so far return MemRegion(old_end, next_bottom); } - assert(_regions[index] == NULL, "invariant"); - _regions[index] = new_hr; + assert(_regions.get_by_index(index) == NULL, "invariant"); + _regions.set_by_index(index, new_hr); increment_allocated_length(); } // Have to increment the length first, otherwise we will get an @@ -228,26 +217,26 @@ uint HeapRegionSeq::shrink_by(uint num_regions_to_remove) { #ifndef PRODUCT void HeapRegionSeq::verify_optional() { - guarantee(_length <= _allocated_length, + guarantee(length() <= _allocated_length, err_msg("invariant: _length: %u _allocated_length: %u", - _length, _allocated_length)); - guarantee(_allocated_length <= _max_length, + length(), _allocated_length)); + guarantee(_allocated_length <= max_length(), err_msg("invariant: _allocated_length: %u _max_length: %u", - _allocated_length, _max_length)); - guarantee(_next_search_index <= _length, + _allocated_length, max_length())); + guarantee(_next_search_index <= length(), err_msg("invariant: _next_search_index: %u _length: %u", - _next_search_index, _length)); + _next_search_index, length())); - HeapWord* prev_end = _heap_bottom; + HeapWord* prev_end = heap_bottom(); for (uint i = 0; i < _allocated_length; i += 1) { - HeapRegion* hr = _regions[i]; + HeapRegion* hr = _regions.get_by_index(i); guarantee(hr != NULL, err_msg("invariant: i: %u", i)); guarantee(hr->bottom() == prev_end, err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT, i, HR_FORMAT_PARAMS(hr), prev_end)); guarantee(hr->hrs_index() == i, err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index())); - if (i < _length) { + if (i < length()) { // Asserts will fire if i is >= _length HeapWord* addr = hr->bottom(); guarantee(addr_to_region(addr) == hr, "sanity"); @@ -265,8 +254,8 @@ void HeapRegionSeq::verify_optional() { prev_end = hr->end(); } } - for (uint i = _allocated_length; i < _max_length; i += 1) { - guarantee(_regions[i] == NULL, err_msg("invariant i: %u", i)); + for (uint i = _allocated_length; i < max_length(); i += 1) { + guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i)); } } #endif // PRODUCT diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp index b7a58f76a7f..b0c3eb48a0b 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp @@ -25,10 +25,17 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP +#include "gc_implementation/g1/g1BiasedArray.hpp" + class HeapRegion; class HeapRegionClosure; class FreeRegionList; +class G1HeapRegionTable : public G1BiasedMappedArray { + protected: + virtual HeapRegion* default_value() const { return NULL; } +}; + // This class keeps track of the region metadata (i.e., HeapRegion // instances). They are kept in the _regions array in address // order. A region's index in the array corresponds to its index in @@ -44,35 +51,21 @@ class FreeRegionList; // // We keep track of three lengths: // -// * _length (returned by length()) is the number of currently +// * _committed_length (returned by length()) is the number of currently // committed regions. // * _allocated_length (not exposed outside this class) is the // number of regions for which we have HeapRegions. -// * _max_length (returned by max_length()) is the maximum number of -// regions the heap can have. +// * max_length() returns the maximum number of regions the heap can have. // -// and maintain that: _length <= _allocated_length <= _max_length +// and maintain that: _committed_length <= _allocated_length <= max_length() class HeapRegionSeq: public CHeapObj { friend class VMStructs; - // The array that holds the HeapRegions. - HeapRegion** _regions; - - // Version of _regions biased to address 0 - HeapRegion** _regions_biased; + G1HeapRegionTable _regions; // The number of regions committed in the heap. - uint _length; - - // The address of the first reserved word in the heap. - HeapWord* _heap_bottom; - - // The address of the last reserved word in the heap - 1. - HeapWord* _heap_end; - - // The log of the region byte size. - uint _region_shift; + uint _committed_length; // A hint for which index to start searching from for humongous // allocations. @@ -81,37 +74,33 @@ class HeapRegionSeq: public CHeapObj { // The number of regions for which we have allocated HeapRegions for. uint _allocated_length; - // The maximum number of regions in the heap. - uint _max_length; - // Find a contiguous set of empty regions of length num, starting // from the given index. uint find_contiguous_from(uint from, uint num); - // Map a heap address to a biased region index. Assume that the - // address is valid. - inline uintx addr_to_index_biased(HeapWord* addr) const; - void increment_allocated_length() { - assert(_allocated_length < _max_length, "pre-condition"); + assert(_allocated_length < max_length(), "pre-condition"); _allocated_length++; } void increment_length() { - assert(_length < _max_length, "pre-condition"); - _length++; + assert(length() < max_length(), "pre-condition"); + _committed_length++; } void decrement_length() { - assert(_length > 0, "pre-condition"); - _length--; + assert(length() > 0, "pre-condition"); + _committed_length--; } + HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); } + HeapWord* heap_end() const {return _regions.end_address_mapped(); } + public: // Empty contructor, we'll initialize it with the initialize() method. - HeapRegionSeq() { } + HeapRegionSeq() : _regions(), _committed_length(0), _next_search_index(0), _allocated_length(0) { } - void initialize(HeapWord* bottom, HeapWord* end, uint max_length); + void initialize(HeapWord* bottom, HeapWord* end); // Return the HeapRegion at the given index. Assume that the index // is valid. @@ -126,10 +115,10 @@ class HeapRegionSeq: public CHeapObj { inline HeapRegion* addr_to_region_unsafe(HeapWord* addr) const; // Return the number of regions that have been committed in the heap. - uint length() const { return _length; } + uint length() const { return _committed_length; } // Return the maximum number of regions in the heap. - uint max_length() const { return _max_length; } + uint max_length() const { return (uint)_regions.length(); } // Expand the sequence to reflect that the heap has grown from // old_end to new_end. Either create new HeapRegions, or re-use diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp index e840287edc7..96588dea042 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp @@ -28,28 +28,16 @@ #include "gc_implementation/g1/heapRegion.hpp" #include "gc_implementation/g1/heapRegionSeq.hpp" -inline uintx HeapRegionSeq::addr_to_index_biased(HeapWord* addr) const { - assert(_heap_bottom <= addr && addr < _heap_end, - err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT" end: "PTR_FORMAT, - addr, _heap_bottom, _heap_end)); - uintx index = (uintx) addr >> _region_shift; - return index; -} - inline HeapRegion* HeapRegionSeq::addr_to_region_unsafe(HeapWord* addr) const { - assert(_heap_bottom <= addr && addr < _heap_end, - err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT" end: "PTR_FORMAT, - addr, _heap_bottom, _heap_end)); - uintx index_biased = addr_to_index_biased(addr); - HeapRegion* hr = _regions_biased[index_biased]; + HeapRegion* hr = _regions.get_by_address(addr); assert(hr != NULL, "invariant"); return hr; } inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const { - if (addr != NULL && addr < _heap_end) { - assert(addr >= _heap_bottom, - err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, addr, _heap_bottom)); + if (addr != NULL && addr < heap_end()) { + assert(addr >= heap_bottom(), + err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, addr, heap_bottom())); return addr_to_region_unsafe(addr); } return NULL; @@ -57,7 +45,7 @@ inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const { inline HeapRegion* HeapRegionSeq::at(uint index) const { assert(index < length(), "pre-condition"); - HeapRegion* hr = _regions[index]; + HeapRegion* hr = _regions.get_by_index(index); assert(hr != NULL, "sanity"); assert(hr->hrs_index() == index, "sanity"); return hr; diff --git a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp index 736c2d75096..9268eb78ef4 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp @@ -34,8 +34,14 @@ static_field(HeapRegion, GrainBytes, size_t) \ static_field(HeapRegion, LogOfHRGrainBytes, int) \ \ - nonstatic_field(HeapRegionSeq, _regions, HeapRegion**) \ - nonstatic_field(HeapRegionSeq, _length, uint) \ + nonstatic_field(G1HeapRegionTable, _base, address) \ + nonstatic_field(G1HeapRegionTable, _length, size_t) \ + nonstatic_field(G1HeapRegionTable, _biased_base, address) \ + nonstatic_field(G1HeapRegionTable, _bias, size_t) \ + nonstatic_field(G1HeapRegionTable, _shift_by, uint) \ + \ + nonstatic_field(HeapRegionSeq, _regions, G1HeapRegionTable) \ + nonstatic_field(HeapRegionSeq, _committed_length, uint) \ \ nonstatic_field(G1CollectedHeap, _hrs, HeapRegionSeq) \ nonstatic_field(G1CollectedHeap, _g1_committed, MemRegion) \ @@ -58,6 +64,8 @@ #define VM_TYPES_G1(declare_type, declare_toplevel_type) \ \ + declare_toplevel_type(G1HeapRegionTable) \ + \ declare_type(G1CollectedHeap, SharedHeap) \ \ declare_type(HeapRegion, ContiguousSpace) \ diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index c7886920b3e..8b3c19c5c2d 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -5047,6 +5047,9 @@ void TestReservedSpace_test(); void TestReserveMemorySpecial_test(); void TestVirtualSpace_test(); void MetaspaceAux_test(); +#if INCLUDE_ALL_GCS +void TestG1BiasedArray_test(); +#endif void execute_internal_vm_tests() { if (ExecuteInternalVMTests) { @@ -5066,6 +5069,7 @@ void execute_internal_vm_tests() { run_unit_test(VMStructs::test()); #endif #if INCLUDE_ALL_GCS + run_unit_test(TestG1BiasedArray_test()); run_unit_test(HeapRegionRemSet::test_prt()); #endif tty->print_cr("All internal VM tests passed"); From d5157be0e8445c4b4acfc787f82144a4ab7cd921 Mon Sep 17 00:00:00 2001 From: David Simms Date: Wed, 25 Sep 2013 13:58:13 +0200 Subject: [PATCH 0499/1294] 8023956: Provide a work-around to broken Linux 32 bit "Exec Shield" using CS for NX emulation (crashing with SI_KERNEL) Execute some code at a high virtual address value, and keep mapped Reviewed-by: coleenp, zgu --- hotspot/src/os/linux/vm/os_linux.cpp | 4 ++ .../src/os_cpu/linux_x86/vm/os_linux_x86.cpp | 43 +++++++++++++++++++ .../src/os_cpu/linux_x86/vm/os_linux_x86.hpp | 13 ++++++ 3 files changed, 60 insertions(+) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 6c794793cfe..95e04681f48 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -4839,6 +4839,10 @@ jint os::init_2(void) Linux::capture_initial_stack(JavaThread::stack_size_at_create()); +#if defined(IA32) + workaround_expand_exec_shield_cs_limit(); +#endif + Linux::libpthread_init(); if (PrintMiscellaneous && (Verbose || WizardMode)) { tty->print_cr("[HotSpot is running with %s, %s(%s)]\n", diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp index 8878c0ea353..9a7605e696b 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp @@ -876,3 +876,46 @@ void os::verify_stack_alignment() { #endif } #endif + + +/* + * IA32 only: execute code at a high address in case buggy NX emulation is present. I.e. avoid CS limit + * updates (JDK-8023956). + */ +void os::workaround_expand_exec_shield_cs_limit() { +#if defined(IA32) + size_t page_size = os::vm_page_size(); + /* + * Take the highest VA the OS will give us and exec + * + * Although using -(pagesz) as mmap hint works on newer kernel as you would + * think, older variants affected by this work-around don't (search forward only). + * + * On the affected distributions, we understand the memory layout to be: + * + * TASK_LIMIT= 3G, main stack base close to TASK_LIMT. + * + * A few pages south main stack will do it. + * + * If we are embedded in an app other than launcher (initial != main stack), + * we don't have much control or understanding of the address space, just let it slide. + */ + char* hint = (char*) (Linux::initial_thread_stack_bottom() - + ((StackYellowPages + StackRedPages + 1) * page_size)); + char* codebuf = os::reserve_memory(page_size, hint); + if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) { + return; // No matter, we tried, best effort. + } + if (PrintMiscellaneous && (Verbose || WizardMode)) { + tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf); + } + + // Some code to exec: the 'ret' instruction + codebuf[0] = 0xC3; + + // Call the code in the codebuf + __asm__ volatile("call *%0" : : "r"(codebuf)); + + // keep the page mapped so CS limit isn't reduced. +#endif +} diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.hpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.hpp index 1d3fd350c68..fbca6909bb5 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.hpp +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.hpp @@ -36,4 +36,17 @@ // Note: Currently only used in 64 bit Windows implementations static bool register_code_area(char *low, char *high) { return true; } + /* + * Work-around for broken NX emulation using CS limit, Red Hat patch "Exec-Shield" + * (IA32 only). + * + * Map and execute at a high VA to prevent CS lazy updates race with SMP MM + * invalidation.Further code generation by the JVM will no longer cause CS limit + * updates. + * + * Affects IA32: RHEL 5 & 6, Ubuntu 10.04 (LTS), 10.10, 11.04, 11.10, 12.04. + * @see JDK-8023956 + */ + static void workaround_expand_exec_shield_cs_limit(); + #endif // OS_CPU_LINUX_X86_VM_OS_LINUX_X86_HPP From c0720f17f6a0edf5b88a53af14b4221f11d0b5a8 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Wed, 25 Sep 2013 16:17:42 +0400 Subject: [PATCH 0500/1294] 8007155: [macosx] Disabled panel takes mouse input in JLayeredPane Reviewed-by: serb, anthony --- .../classes/sun/lwawt/LWCursorManager.java | 5 +- jdk/src/share/classes/java/awt/Container.java | 7 +- .../share/classes/sun/awt/AWTAccessor.java | 8 + .../classes/sun/awt/GlobalCursorManager.java | 10 +- .../sun/awt/X11/XGlobalCursorManager.java | 9 +- .../sun/awt/windows/WGlobalCursorManager.java | 3 +- .../native/sun/windows/awt_Container.cpp | 7 +- .../native/sun/windows/awt_Container.h | 3 +- .../windows/native/sun/windows/awt_Cursor.cpp | 28 +-- .../CursorOverlappedPanelsTest.html | 32 +++ .../CursorOverlappedPanelsTest.java | 226 ++++++++++++++++++ 11 files changed, 286 insertions(+), 52 deletions(-) create mode 100644 jdk/test/java/awt/Cursor/CursorOverlappedPanelsTest/CursorOverlappedPanelsTest.html create mode 100644 jdk/test/java/awt/Cursor/CursorOverlappedPanelsTest/CursorOverlappedPanelsTest.java diff --git a/jdk/src/macosx/classes/sun/lwawt/LWCursorManager.java b/jdk/src/macosx/classes/sun/lwawt/LWCursorManager.java index ee9d0dd572e..e17cced7021 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWCursorManager.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWCursorManager.java @@ -106,8 +106,9 @@ public abstract class LWCursorManager { c = peer.getTarget(); if (c instanceof Container) { final Point p = peer.getLocationOnScreen(); - c = ((Container) c).findComponentAt(cursorPos.x - p.x, - cursorPos.y - p.y); + c = AWTAccessor.getContainerAccessor().findComponentAt( + (Container) c, cursorPos.x - p.x, cursorPos.y - p.y, false); + } while (c != null) { final Object p = AWTAccessor.getComponentAccessor().getPeer(c); diff --git a/jdk/src/share/classes/java/awt/Container.java b/jdk/src/share/classes/java/awt/Container.java index 9029417b2ce..14bd55dae5c 100644 --- a/jdk/src/share/classes/java/awt/Container.java +++ b/jdk/src/share/classes/java/awt/Container.java @@ -258,6 +258,12 @@ public class Container extends Component { public void validateUnconditionally(Container cont) { cont.validateUnconditionally(); } + + @Override + public Component findComponentAt(Container cont, int x, int y, + boolean ignoreEnabled) { + return cont.findComponentAt(x, y, ignoreEnabled); + } }); } @@ -2651,7 +2657,6 @@ public class Container extends Component { * behavior. Setting 'ignoreEnabled' to 'false' bypasses disabled * Components during the search. This behavior is used by the * lightweight cursor support in sun.awt.GlobalCursorManager. - * The cursor code calls this function directly via native code. * * The addition of this feature is temporary, pending the * adoption of new, public API which exports this feature. diff --git a/jdk/src/share/classes/sun/awt/AWTAccessor.java b/jdk/src/share/classes/sun/awt/AWTAccessor.java index d604768f5df..8cd84ab3d21 100644 --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java @@ -252,6 +252,14 @@ public final class AWTAccessor { * Validates the container unconditionally. */ void validateUnconditionally(Container cont); + + /** + * + * Access to the private version of findComponentAt method which has + * a controllable behavior. Setting 'ignoreEnabled' to 'false' + * bypasses disabled Components during the search. + */ + Component findComponentAt(Container cont, int x, int y, boolean ignoreEnabled); } /* diff --git a/jdk/src/share/classes/sun/awt/GlobalCursorManager.java b/jdk/src/share/classes/sun/awt/GlobalCursorManager.java index a769fd0c543..5d796f08378 100644 --- a/jdk/src/share/classes/sun/awt/GlobalCursorManager.java +++ b/jdk/src/share/classes/sun/awt/GlobalCursorManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -134,7 +134,6 @@ public abstract class GlobalCursorManager { */ protected abstract void getCursorPos(Point p); - protected abstract Component findComponentAt(Container con, int x, int y); protected abstract Point getLocationOnScreen(Component com); /** @@ -190,9 +189,10 @@ public abstract class GlobalCursorManager { if (p != null) { queryPos = new Point(); getCursorPos(queryPos); - Component c = findComponentAt((Container)comp, - queryPos.x - p.x, - queryPos.y - p.y); + Component c = AWTAccessor.getContainerAccessor(). + findComponentAt((Container) comp, + queryPos.x - p.x, queryPos.y - p.y, false); + // If findComponentAt returns null, then something bad has // happened. For example, the heavyweight Component may // have been hidden or disabled by another thread. In that diff --git a/jdk/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java b/jdk/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java index 3034fbc9f63..c309d310e0a 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -145,13 +145,8 @@ public final class XGlobalCursorManager extends GlobalCursorManager { } /* - * two native methods to call corresponding methods in Container and - * Component + * native method to call corresponding methods in Component */ - protected Component findComponentAt(Container con, int x, int y) { - return con.findComponentAt(x,y); - } - protected Point getLocationOnScreen(Component c) { return c.getLocationOnScreen(); } diff --git a/jdk/src/windows/classes/sun/awt/windows/WGlobalCursorManager.java b/jdk/src/windows/classes/sun/awt/windows/WGlobalCursorManager.java index c45c05c24d1..b579f15c367 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WGlobalCursorManager.java +++ b/jdk/src/windows/classes/sun/awt/windows/WGlobalCursorManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,6 @@ public final class WGlobalCursorManager extends GlobalCursorManager { protected native void setCursor(Component comp, Cursor cursor, boolean u); protected native void getCursorPos(Point p); - protected native Component findComponentAt(Container con, int x, int y); /* * two native methods to call corresponding methods in Container and * Component diff --git a/jdk/src/windows/native/sun/windows/awt_Container.cpp b/jdk/src/windows/native/sun/windows/awt_Container.cpp index 5e9788dabd2..c0704fe16a6 100644 --- a/jdk/src/windows/native/sun/windows/awt_Container.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Container.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,6 @@ */ jfieldID AwtContainer::layoutMgrID; -jmethodID AwtContainer::findComponentAtMID; /************************************************************************ * AwtContainer native methods @@ -46,11 +45,7 @@ Java_java_awt_Container_initIDs(JNIEnv *env, jclass cls) { AwtContainer::layoutMgrID = env->GetFieldID(cls, "layoutMgr", "Ljava/awt/LayoutManager;"); - AwtContainer::findComponentAtMID = - env->GetMethodID(cls, "findComponentAt", "(IIZ)Ljava/awt/Component;"); - DASSERT(AwtContainer::layoutMgrID != NULL); - DASSERT(AwtContainer::findComponentAtMID); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_Container.h b/jdk/src/windows/native/sun/windows/awt_Container.h index a6753905619..43fe346b3dd 100644 --- a/jdk/src/windows/native/sun/windows/awt_Container.h +++ b/jdk/src/windows/native/sun/windows/awt_Container.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -38,7 +38,6 @@ public: /* java.awt.Container field ids */ static jfieldID layoutMgrID; - static jmethodID findComponentAtMID; }; diff --git a/jdk/src/windows/native/sun/windows/awt_Cursor.cpp b/jdk/src/windows/native/sun/windows/awt_Cursor.cpp index 7901601167f..58bceb8544a 100644 --- a/jdk/src/windows/native/sun/windows/awt_Cursor.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Cursor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -552,32 +552,6 @@ Java_sun_awt_windows_WGlobalCursorManager_findHeavyweightUnderCursor( CATCH_BAD_ALLOC_RET(NULL); } -/* - * Class: sun_awt_windows_WGlobalCursorManager - * Method: findComponentAt - * Signature: (L/java/awt/Container;II)L/java/awt/Component - */ -JNIEXPORT jobject JNICALL -Java_sun_awt_windows_WGlobalCursorManager_findComponentAt( - JNIEnv *env, jobject, jobject container, jint x, jint y) -{ - TRY; - - /* - * Call private version of Container.findComponentAt with the following - * flag set -- ignoreEnabled = false (i.e., don't return or recur into - * disabled Components); - * NOTE: it may return a JRootPane's glass pane as the target Component - */ - JNI_CHECK_NULL_RETURN_NULL(container, "null container"); - jobject comp = - env->CallObjectMethod(container, AwtContainer::findComponentAtMID, - x, y, JNI_FALSE); - return comp; - - CATCH_BAD_ALLOC_RET(NULL); -} - /* * Class: sun_awt_windows_WGlobalCursorManager * Method: getLocationOnScreen diff --git a/jdk/test/java/awt/Cursor/CursorOverlappedPanelsTest/CursorOverlappedPanelsTest.html b/jdk/test/java/awt/Cursor/CursorOverlappedPanelsTest/CursorOverlappedPanelsTest.html new file mode 100644 index 00000000000..d7e6157e927 --- /dev/null +++ b/jdk/test/java/awt/Cursor/CursorOverlappedPanelsTest/CursorOverlappedPanelsTest.html @@ -0,0 +1,32 @@ + + + + + CursorOverlappedPanelsTest, bug ID 8007155 + + + +

    See the dialog box (usually in upper left corner) for instructions

    + + diff --git a/jdk/test/java/awt/Cursor/CursorOverlappedPanelsTest/CursorOverlappedPanelsTest.java b/jdk/test/java/awt/Cursor/CursorOverlappedPanelsTest/CursorOverlappedPanelsTest.java new file mode 100644 index 00000000000..40f1ae6c499 --- /dev/null +++ b/jdk/test/java/awt/Cursor/CursorOverlappedPanelsTest/CursorOverlappedPanelsTest.java @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.*; +//import java.applet.Applet; +import javax.swing.BorderFactory; +import javax.swing.JApplet; +import javax.swing.JFrame; +import javax.swing.JLayeredPane; +import javax.swing.JPanel; + +/** + * @test + * @bug 8007155 + * @summary [macosx] Disabled panel takes mouse input in JLayeredPane + * @author Alexander Scherbatiy: area=java.awt.Cursor + * @run applet/manual=yesno CursorOverlappedPanelsTest.html + */ +public class CursorOverlappedPanelsTest extends JApplet { + //Declare things used in the test, like buttons and labels here + + public void init() { + //Create instructions for the user here, as well as set up + // the environment -- set the layout manager, add buttons, + // etc. + this.setLayout(new BorderLayout()); + + String[] instructions = { + "Verify that the Crosshair cursor from enabled panel" + + " is displayed on the panels intersection", + "1) Move the mosue cursor on the Enabled and Disabled panels" + + " intersection", + "2) Check that the Crosshair cursor is displayed ", + "If so, press PASS, else press FAIL." + }; + Sysout.createDialogWithInstructions(instructions); + + }//End init() + + public void start() { + //Get things going. Request focus, set size, et cetera + setSize(200, 200); + setVisible(true); + validate(); + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + } catch (Exception e) { + throw new RuntimeException(e); + } + }// start() + + //The rest of this class is the actions which perform the test... + //Use Sysout.println to communicate with the user NOT System.out!! + //Sysout.println ("Something Happened!"); + private static JPanel createPanel(Point location, boolean enabled) { + final JPanel panel = new JPanel(); + panel.setOpaque(false); + panel.setEnabled(enabled); + panel.setSize(new Dimension(200, 200)); + panel.setLocation(location); + panel.setBorder(BorderFactory.createTitledBorder( + enabled ? "Enabled" : "Disabled")); + panel.setCursor(Cursor.getPredefinedCursor( + enabled ? Cursor.CROSSHAIR_CURSOR : Cursor.DEFAULT_CURSOR)); + System.out.println("cursor: " + Cursor.getPredefinedCursor(enabled ? Cursor.CROSSHAIR_CURSOR : Cursor.DEFAULT_CURSOR)); + return panel; + } + + private static void createAndShowGUI() { + final JFrame frame = new JFrame("Test"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JLayeredPane layeredPane = new JLayeredPane(); + layeredPane.setPreferredSize(new Dimension(400, 400)); + JPanel enabledPanel = createPanel(new Point(10, 10), true); + JPanel disabledPanel = createPanel(new Point(100, 100), false); + layeredPane.add(disabledPanel, JLayeredPane.PALETTE_LAYER); + layeredPane.add(enabledPanel, JLayeredPane.DEFAULT_LAYER); + + frame.getContentPane().add(layeredPane); + frame.pack(); + frame.setVisible(true); + } +}// class BlockedWindowTest + +/* Place other classes related to the test after this line */ +/** + * ************************************************** + * Standard Test Machinery DO NOT modify anything below -- it's a standard chunk + * of code whose purpose is to make user interaction uniform, and thereby make + * it simpler to read and understand someone else's test. + * ************************************************** + */ +/** + * This is part of the standard test machinery. It creates a dialog (with the + * instructions), and is the interface for sending text messages to the user. To + * print the instructions, send an array of strings to Sysout.createDialog + * WithInstructions method. Put one line of instructions per array entry. To + * display a message for the tester to see, simply call Sysout.println with the + * string to be displayed. This mimics System.out.println but works within the + * test harness as well as standalone. + */ +class Sysout { + + private static TestDialog dialog; + + public static void createDialogWithInstructions(String[] instructions) { + dialog = new TestDialog(new Frame(), "Instructions"); + dialog.printInstructions(instructions); + dialog.setVisible(true); + println("Any messages for the tester will display here."); + } + + public static void createDialog() { + dialog = new TestDialog(new Frame(), "Instructions"); + String[] defInstr = {"Instructions will appear here. ", ""}; + dialog.printInstructions(defInstr); + dialog.setVisible(true); + println("Any messages for the tester will display here."); + } + + public static void printInstructions(String[] instructions) { + dialog.printInstructions(instructions); + } + + public static void println(String messageIn) { + dialog.displayMessage(messageIn); + } +}// Sysout class + +/** + * This is part of the standard test machinery. It provides a place for the test + * instructions to be displayed, and a place for interactive messages to the + * user to be displayed. To have the test instructions displayed, see Sysout. To + * have a message to the user be displayed, see Sysout. Do not call anything in + * this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog(Frame frame, String name) { + super(frame, name); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); + add("North", instructionsText); + + messageText = new TextArea("", 5, maxStringLength, scrollBoth); + add("Center", messageText); + + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions(String[] instructions) { + //Clear out any current instructions + instructionsText.setText(""); + + //Go down array of instruction strings + + String printStr, remainingStr; + for (int i = 0; i < instructions.length; i++) { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i]; + while (remainingStr.length() > 0) { + //if longer than max then chop off first max chars to print + if (remainingStr.length() >= maxStringLength) { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf(' ', maxStringLength - 1); + + if (posOfSpace <= 0) { + posOfSpace = maxStringLength - 1; + } + + printStr = remainingStr.substring(0, posOfSpace + 1); + remainingStr = remainingStr.substring(posOfSpace + 1); + } //else just print + else { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append(printStr + "\n"); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage(String messageIn) { + messageText.append(messageIn + "\n"); + System.out.println(messageIn); + } +}// TestDialog class From fe092e9cf3617883e8a9721aa31ba866272f65f6 Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Wed, 25 Sep 2013 16:12:07 +0400 Subject: [PATCH 0501/1294] 8024987: Copy/paste regression since JDK8 b86 Reviewed-by: serb, anthony --- .../awt/datatransfer/SystemFlavorMap.java | 154 ++++++++++-------- 1 file changed, 83 insertions(+), 71 deletions(-) diff --git a/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java b/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java index fe69767dd33..ef154acdc2e 100644 --- a/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java +++ b/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java @@ -70,7 +70,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { /** * System singleton which maps a thread's ClassLoader to a SystemFlavorMap. */ - private static final WeakHashMap flavorMaps = new WeakHashMap(); + private static final WeakHashMap flavorMaps = new WeakHashMap<>(); /** * Copied from java.util.Properties. @@ -139,7 +139,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * native Strings. * Do not use the field directly, use getFlavorToNative() instead. */ - private final Map flavorToNative = new HashMap(); + private final Map> flavorToNative = new HashMap<>(); /** * Accessor to flavorToNative map. Since we use lazy initialization we must @@ -148,7 +148,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * * @return flavorToNative */ - private synchronized Map getFlavorToNative() { + private synchronized Map> getFlavorToNative() { if (!isMapInitialized) { initSystemFlavorMap(); } @@ -164,13 +164,13 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * Caches the result of getNativesForFlavor(). Maps DataFlavors to * SoftReferences which reference Lists of String natives. */ - private Map getNativesForFlavorCache = new HashMap(); + private Map>> getNativesForFlavorCache = new HashMap<>(); /** * Caches the result getFlavorsForNative(). Maps String natives to * SoftReferences which reference Lists of DataFlavors. */ - private Map getFlavorsForNativeCache = new HashMap(); + private Map>> getFlavorsForNativeCache = new HashMap<>(); /** * Dynamic mapping generation used for text mappings should not be applied @@ -193,7 +193,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { FlavorMap fm; synchronized(flavorMaps) { - fm = (FlavorMap)flavorMaps.get(contextClassLoader); + fm = flavorMaps.get(contextClassLoader); if (fm == null) { fm = new SystemFlavorMap(); flavorMaps.put(contextClassLoader, fm); @@ -520,10 +520,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * the appropriate Map location, but rather will be appended to a List * stored in that location. */ - private void store(Object hashed, Object listed, Map map) { - List list = (List)map.get(hashed); + private void store(H hashed, L listed, Map> map) { + List list = map.get(hashed); if (list == null) { - list = new ArrayList(1); + list = new ArrayList<>(1); map.put(hashed, list); } if (!list.contains(listed)) { @@ -537,17 +537,17 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * case, a new DataFlavor is synthesized, stored, and returned, if and * only if the specified native is encoded as a Java MIME type. */ - private List nativeToFlavorLookup(String nat) { + private List nativeToFlavorLookup(String nat) { List flavors = getNativeToFlavor().get(nat); if (nat != null && !disabledMappingGenerationKeys.contains(nat)) { DataTransferer transferer = DataTransferer.getInstance(); if (transferer != null) { - List platformFlavors = + List platformFlavors = transferer.getPlatformMappingsForNative(nat); if (!platformFlavors.isEmpty()) { if (flavors != null) { - platformFlavors.removeAll(new HashSet(flavors)); + platformFlavors.removeAll(new HashSet<>(flavors)); // Prepending the platform-specific mappings ensures // that the flavors added with // addFlavorForUnencodedNative() are at the end of @@ -573,15 +573,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } if (flavor != null) { - flavors = new ArrayList(1); + flavors = new ArrayList<>(1); getNativeToFlavor().put(nat, flavors); flavors.add(flavor); getFlavorsForNativeCache.remove(nat); getFlavorsForNativeCache.remove(null); - List natives = (List)getFlavorToNative().get(flavor); + List natives = getFlavorToNative().get(flavor); if (natives == null) { - natives = new ArrayList(1); + natives = new ArrayList<>(1); getFlavorToNative().put(flavor, natives); } natives.add(nat); @@ -590,7 +590,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } } - return (flavors != null) ? flavors : new ArrayList(0); + return (flavors != null) ? flavors : new ArrayList<>(0); } /** @@ -601,18 +601,18 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * encoding the DataFlavor's MIME type. Otherwise an empty List is returned * and 'flavorToNative' remains unaffected. */ - private List flavorToNativeLookup(final DataFlavor flav, - final boolean synthesize) { - List natives = (List)getFlavorToNative().get(flav); + private List flavorToNativeLookup(final DataFlavor flav, + final boolean synthesize) { + List natives = getFlavorToNative().get(flav); if (flav != null && !disabledMappingGenerationKeys.contains(flav)) { DataTransferer transferer = DataTransferer.getInstance(); if (transferer != null) { - List platformNatives = + List platformNatives = transferer.getPlatformMappingsForFlavor(flav); if (!platformNatives.isEmpty()) { if (natives != null) { - platformNatives.removeAll(new HashSet(natives)); + platformNatives.removeAll(new HashSet<>(natives)); // Prepend the platform-specific mappings to ensure // that the natives added with // addUnencodedNativeForFlavor() are at the end of @@ -627,7 +627,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { if (natives == null) { if (synthesize) { String encoded = encodeDataFlavor(flav); - natives = new ArrayList(1); + natives = new ArrayList<>(1); getFlavorToNative().put(flav, natives); natives.add(encoded); getNativesForFlavorCache.remove(flav); @@ -635,14 +635,14 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { List flavors = getNativeToFlavor().get(encoded); if (flavors == null) { - flavors = new ArrayList(1); + flavors = new ArrayList<>(1); getNativeToFlavor().put(encoded, flavors); } flavors.add(flav); getFlavorsForNativeCache.remove(encoded); getFlavorsForNativeCache.remove(null); } else { - natives = new ArrayList(0); + natives = new ArrayList<>(0); } } @@ -675,21 +675,21 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * @since 1.4 */ public synchronized List getNativesForFlavor(DataFlavor flav) { - List retval = null; + List retval = null; // Check cache, even for null flav - SoftReference ref = (SoftReference)getNativesForFlavorCache.get(flav); + SoftReference> ref = getNativesForFlavorCache.get(flav); if (ref != null) { - retval = (List)ref.get(); + retval = ref.get(); if (retval != null) { // Create a copy, because client code can modify the returned // list. - return new ArrayList(retval); + return new ArrayList<>(retval); } } if (flav == null) { - retval = new ArrayList(getNativeToFlavor().keySet()); + retval = new ArrayList<>(getNativeToFlavor().keySet()); } else if (disabledMappingGenerationKeys.contains(flav)) { // In this case we shouldn't synthesize a native for this flavor, // since its mappings were explicitly specified. @@ -699,7 +699,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { // For text/* flavors, flavor-to-native mappings specified in // flavormap.properties are stored per flavor's base type. if ("text".equals(flav.getPrimaryType())) { - retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType()); + retval = getAllNativesForType(flav.mimeType.getBaseType()); if (retval != null) { // To prevent the List stored in the map from modification. retval = new ArrayList(retval); @@ -707,15 +707,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } // Also include text/plain natives, but don't duplicate Strings - List textPlainList = (List)getFlavorToNative().get(TEXT_PLAIN_BASE_TYPE); + List textPlainList = getAllNativesForType(TEXT_PLAIN_BASE_TYPE); if (textPlainList != null && !textPlainList.isEmpty()) { // To prevent the List stored in the map from modification. // This also guarantees that removeAll() is supported. - textPlainList = new ArrayList(textPlainList); + textPlainList = new ArrayList<>(textPlainList); if (retval != null && !retval.isEmpty()) { // Use HashSet to get constant-time performance for search. - textPlainList.removeAll(new HashSet(retval)); + textPlainList.removeAll(new HashSet<>(retval)); retval.addAll(textPlainList); } else { retval = textPlainList; @@ -728,7 +728,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { // In this branch it is guaranteed that natives explicitly // listed for flav's MIME type were added with // addUnencodedNativeForFlavor(), so they have lower priority. - List explicitList = + List explicitList = flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND); // flavorToNativeLookup() never returns null. @@ -736,14 +736,14 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { if (!explicitList.isEmpty()) { // To prevent the List stored in the map from modification. // This also guarantees that removeAll() is supported. - explicitList = new ArrayList(explicitList); + explicitList = new ArrayList<>(explicitList); // Use HashSet to get constant-time performance for search. - explicitList.removeAll(new HashSet(retval)); + explicitList.removeAll(new HashSet<>(retval)); retval.addAll(explicitList); } } } else if (DataTransferer.isFlavorNoncharsetTextType(flav)) { - retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType()); + retval = getAllNativesForType(flav.mimeType.getBaseType()); if (retval == null || retval.isEmpty()) { retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND); @@ -751,7 +751,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { // In this branch it is guaranteed that natives explicitly // listed for flav's MIME type were added with // addUnencodedNativeForFlavor(), so they have lower priority. - List explicitList = + List explicitList = flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND); // flavorToNativeLookup() never returns null. @@ -759,10 +759,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { if (!explicitList.isEmpty()) { // To prevent the List stored in the map from modification. // This also guarantees that add/removeAll() are supported. - retval = new ArrayList(retval); - explicitList = new ArrayList(explicitList); + retval = new ArrayList<>(retval); + explicitList = new ArrayList<>(explicitList); // Use HashSet to get constant-time performance for search. - explicitList.removeAll(new HashSet(retval)); + explicitList.removeAll(new HashSet<>(retval)); retval.addAll(explicitList); } } @@ -770,9 +770,9 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND); } - getNativesForFlavorCache.put(flav, new SoftReference(retval)); + getNativesForFlavorCache.put(flav, new SoftReference<>(retval)); // Create a copy, because client code can modify the returned list. - return new ArrayList(retval); + return new ArrayList<>(retval); } /** @@ -809,11 +809,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { public synchronized List getFlavorsForNative(String nat) { // Check cache, even for null nat - SoftReference ref = (SoftReference)getFlavorsForNativeCache.get(nat); + SoftReference> ref = getFlavorsForNativeCache.get(nat); if (ref != null) { - ArrayList retval = (ArrayList)ref.get(); + List retval = ref.get(); if (retval != null) { - return (List)retval.clone(); + return new ArrayList<>(retval); } } @@ -859,16 +859,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } - final ArrayList arrayList = new ArrayList(returnValue); - getFlavorsForNativeCache.put(nat, new SoftReference(arrayList)); - return (List)arrayList.clone(); + final List arrayList = new ArrayList<>(returnValue); + getFlavorsForNativeCache.put(nat, new SoftReference<>(arrayList)); + return new ArrayList<>(arrayList); } - private static LinkedHashSet convertMimeTypeToDataFlavors( + private static Set convertMimeTypeToDataFlavors( final String baseType) { - final LinkedHashSet returnValue = - new LinkedHashSet(); + final Set returnValue = new LinkedHashSet<>(); String subType = null; @@ -1009,11 +1008,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { flavor_list.toArray(flavors); } - HashMap retval = new HashMap(flavors.length, 1.0f); - for (int i = 0; i < flavors.length; i++) { - List natives = getNativesForFlavor(flavors[i]); - String nat = (natives.isEmpty()) ? null : (String)natives.get(0); - retval.put(flavors[i], nat); + Map retval = new HashMap<>(flavors.length, 1.0f); + for (DataFlavor flavor : flavors) { + List natives = getNativesForFlavor(flavor); + String nat = (natives.isEmpty()) ? null : natives.get(0); + retval.put(flavor, nat); } return retval; @@ -1054,12 +1053,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { native_list.toArray(natives); } - HashMap retval = new HashMap(natives.length, 1.0f); - for (int i = 0; i < natives.length; i++) { - List flavors = getFlavorsForNative(natives[i]); - DataFlavor flav = (flavors.isEmpty()) - ? null : (DataFlavor)flavors.get(0); - retval.put(natives[i], flav); + Map retval = new HashMap<>(natives.length, 1.0f); + for (String aNative : natives) { + List flavors = getFlavorsForNative(aNative); + DataFlavor flav = (flavors.isEmpty())? null : flavors.get(0); + retval.put(aNative, flav); } return retval; @@ -1091,9 +1089,9 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { throw new NullPointerException("null arguments not permitted"); } - List natives = (List)getFlavorToNative().get(flav); + List natives = getFlavorToNative().get(flav); if (natives == null) { - natives = new ArrayList(1); + natives = new ArrayList<>(1); getFlavorToNative().put(flav, natives); } else if (natives.contains(nat)) { return; @@ -1138,8 +1136,8 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } getFlavorToNative().remove(flav); - for (int i = 0; i < natives.length; i++) { - addUnencodedNativeForFlavor(flav, natives[i]); + for (String aNative : natives) { + addUnencodedNativeForFlavor(flav, aNative); } disabledMappingGenerationKeys.add(flav); // Clear the cache to handle the case of empty natives. @@ -1171,9 +1169,9 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { throw new NullPointerException("null arguments not permitted"); } - List flavors = (List)getNativeToFlavor().get(nat); + List flavors = getNativeToFlavor().get(nat); if (flavors == null) { - flavors = new ArrayList(1); + flavors = new ArrayList<>(1); getNativeToFlavor().put(nat, flavors); } else if (flavors.contains(flav)) { return; @@ -1217,8 +1215,8 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } getNativeToFlavor().remove(nat); - for (int i = 0; i < flavors.length; i++) { - addFlavorForUnencodedNative(nat, flavors[i]); + for (DataFlavor flavor : flavors) { + addFlavorForUnencodedNative(nat, flavor); } disabledMappingGenerationKeys.add(nat); // Clear the cache to handle the case of empty flavors. @@ -1321,4 +1319,18 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { ? new DataFlavor(retval_str) : null; } + + private List getAllNativesForType(String type) { + List retval = null; + for (DataFlavor dataFlavor : convertMimeTypeToDataFlavors(type)) { + List natives = getFlavorToNative().get(dataFlavor); + if (!natives.isEmpty()) { + if (retval == null) { + retval = new ArrayList<>(); + } + retval.addAll(natives); + } + } + return retval; + } } From c3a64bea844254c53dd1545d201a79dd1f44f1e1 Mon Sep 17 00:00:00 2001 From: Konstantin Shefov Date: Wed, 25 Sep 2013 16:52:46 +0400 Subject: [PATCH 0502/1294] 8004032: [TEST_BUG] [macosx] There is no effect when double clicking on the Icon, after right clicking on the Icon and the Icon disappear Reviewed-by: anthony, serb --- .../ShowAfterDisposeTest.html | 43 +++ .../ShowAfterDisposeTest.java | 246 ++++++++++++++++++ 2 files changed, 289 insertions(+) create mode 100644 jdk/test/java/awt/TrayIcon/ShowAfterDisposeTest/ShowAfterDisposeTest.html create mode 100644 jdk/test/java/awt/TrayIcon/ShowAfterDisposeTest/ShowAfterDisposeTest.java diff --git a/jdk/test/java/awt/TrayIcon/ShowAfterDisposeTest/ShowAfterDisposeTest.html b/jdk/test/java/awt/TrayIcon/ShowAfterDisposeTest/ShowAfterDisposeTest.html new file mode 100644 index 00000000000..6ef452485ec --- /dev/null +++ b/jdk/test/java/awt/TrayIcon/ShowAfterDisposeTest/ShowAfterDisposeTest.html @@ -0,0 +1,43 @@ + + + + + + ShowAfterDisposeTest + + + +

    ShowAfterDisposeTest
    Bug ID: 6384984

    + +

    See the dialog box (usually in upper left corner) for instructions

    + + + + diff --git a/jdk/test/java/awt/TrayIcon/ShowAfterDisposeTest/ShowAfterDisposeTest.java b/jdk/test/java/awt/TrayIcon/ShowAfterDisposeTest/ShowAfterDisposeTest.java new file mode 100644 index 00000000000..f107492f9d9 --- /dev/null +++ b/jdk/test/java/awt/TrayIcon/ShowAfterDisposeTest/ShowAfterDisposeTest.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2013, 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 6384984 8004032 + @summary TrayIcon try to dispay a tooltip when is not visible + @author Dmitry.Cherepanov@sun.com area=awt.tray + @run applet/manual=yesno ShowAfterDisposeTest.html +*/ + +import java.applet.*; + +import java.awt.*; +import java.awt.event.*; +import java.awt.image.*; + +public class ShowAfterDisposeTest extends Applet +{ + boolean traySupported; + + public void init() + { + this.setLayout (new BorderLayout ()); + + String[] instructions; + traySupported = SystemTray.isSupported(); + if (traySupported) + { + String[] s = + { + "1) When the test starts an icon is added to the SystemTray area.", + "2a) If you use Apple OS X,", + " right click on this icon (it's important to click before the tooltip is shown).", + " The icon should disappear.", + "2b) If you use other os (Windows, Linux, Solaris),", + " double click on this icon (it's important to click before the tooltip is shown).", + " The icon should disappear.", + "3) If the bug is reproducible then the test will fail without assistance.", + "4) Just press the 'pass' button." + }; + instructions = s; + } + else + { + String[] s = + { + "The test cannot be run because SystemTray is not supported.", + "Simply press PASS button." + }; + instructions = s; + } + Sysout.createDialogWithInstructions(instructions); + } + + public void start () + { + setSize (200,200); + setVisible(true); + validate(); + + if (!traySupported) + { + return; + } + + BufferedImage img = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB); + Graphics g = img.createGraphics(); + g.setColor(Color.WHITE); + g.fillRect(0, 0, 32, 32); + g.setColor(Color.RED); + g.fillRect(6, 6, 20, 20); + g.dispose(); + + final SystemTray tray = SystemTray.getSystemTray(); + final TrayIcon icon = new TrayIcon(img); + icon.setImageAutoSize(true); + icon.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent ev) + { + tray.remove(icon); + } + } + ); + + try { + tray.add(icon); + } catch (AWTException e) { + Sysout.println(e.toString()); + Sysout.println("!!! The test coudn't be performed !!!"); + return; + } + icon.setToolTip("tooltip"); + } +} + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } +} + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + setVisible(true); + } + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + } + } + } + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } +} From 9056e0008cee5ef86deafac5213d420c94c8670f Mon Sep 17 00:00:00 2001 From: Alexander Stepanov Date: Wed, 25 Sep 2013 17:08:31 +0400 Subject: [PATCH 0503/1294] 8025070: [javadoc] fix some javadoc errors in javax/swing/plaf/synth Reviewed-by: serb, alexsch --- .../javax/swing/plaf/synth/SynthButtonUI.java | 24 +++++------ .../plaf/synth/SynthCheckBoxMenuItemUI.java | 6 +-- .../swing/plaf/synth/SynthCheckBoxUI.java | 6 +-- .../swing/plaf/synth/SynthColorChooserUI.java | 18 ++++----- .../swing/plaf/synth/SynthComboBoxUI.java | 26 ++++++------ .../swing/plaf/synth/SynthDesktopIconUI.java | 16 ++++---- .../swing/plaf/synth/SynthDesktopPaneUI.java | 20 +++++----- .../swing/plaf/synth/SynthEditorPaneUI.java | 12 +++--- .../plaf/synth/SynthFormattedTextFieldUI.java | 6 +-- .../plaf/synth/SynthInternalFrameUI.java | 22 +++++----- .../javax/swing/plaf/synth/SynthLabelUI.java | 20 +++++----- .../javax/swing/plaf/synth/SynthListUI.java | 16 ++++---- .../swing/plaf/synth/SynthMenuBarUI.java | 16 ++++---- .../swing/plaf/synth/SynthMenuItemUI.java | 20 +++++----- .../swing/plaf/synth/SynthMenuLayout.java | 2 +- .../javax/swing/plaf/synth/SynthMenuUI.java | 20 +++++----- .../swing/plaf/synth/SynthOptionPaneUI.java | 22 +++++----- .../javax/swing/plaf/synth/SynthPainter.java | 10 ++--- .../javax/swing/plaf/synth/SynthPanelUI.java | 16 ++++---- .../plaf/synth/SynthPasswordFieldUI.java | 8 ++-- .../swing/plaf/synth/SynthPopupMenuUI.java | 16 ++++---- .../swing/plaf/synth/SynthProgressBarUI.java | 24 +++++------ .../synth/SynthRadioButtonMenuItemUI.java | 6 +-- .../swing/plaf/synth/SynthRadioButtonUI.java | 6 +-- .../swing/plaf/synth/SynthRootPaneUI.java | 10 ++--- .../swing/plaf/synth/SynthScrollBarUI.java | 26 ++++++------ .../swing/plaf/synth/SynthScrollPaneUI.java | 14 +++---- .../swing/plaf/synth/SynthSeparatorUI.java | 16 ++++---- .../javax/swing/plaf/synth/SynthSliderUI.java | 40 +++++++++---------- .../swing/plaf/synth/SynthSpinnerUI.java | 18 ++++----- .../swing/plaf/synth/SynthSplitPaneUI.java | 12 +++--- .../swing/plaf/synth/SynthTabbedPaneUI.java | 40 +++++++++---------- .../swing/plaf/synth/SynthTableHeaderUI.java | 18 ++++----- .../javax/swing/plaf/synth/SynthTableUI.java | 12 +++--- .../swing/plaf/synth/SynthTextAreaUI.java | 10 ++--- .../swing/plaf/synth/SynthTextFieldUI.java | 12 +++--- .../swing/plaf/synth/SynthTextPaneUI.java | 2 +- .../swing/plaf/synth/SynthToggleButtonUI.java | 6 +-- .../swing/plaf/synth/SynthToolBarUI.java | 22 +++++----- .../swing/plaf/synth/SynthToolTipUI.java | 18 ++++----- .../javax/swing/plaf/synth/SynthTreeUI.java | 38 +++++++++--------- .../swing/plaf/synth/SynthViewportUI.java | 10 ++--- 42 files changed, 341 insertions(+), 341 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java index 0f5df434c70..2c6535c7bd9 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java @@ -34,7 +34,7 @@ import javax.swing.plaf.basic.BasicHTML; import javax.swing.text.View; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JButton}. * * @author Scott Violet @@ -55,7 +55,7 @@ public class SynthButtonUI extends BasicButtonUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults(AbstractButton b) { @@ -65,7 +65,7 @@ public class SynthButtonUI extends BasicButtonUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners(AbstractButton b) { @@ -109,7 +109,7 @@ public class SynthButtonUI extends BasicButtonUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners(AbstractButton b) { @@ -118,7 +118,7 @@ public class SynthButtonUI extends BasicButtonUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults(AbstractButton b) { @@ -130,7 +130,7 @@ public class SynthButtonUI extends BasicButtonUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -182,7 +182,7 @@ public class SynthButtonUI extends BasicButtonUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public int getBaseline(JComponent c, int width, int height) { @@ -305,7 +305,7 @@ public class SynthButtonUI extends BasicButtonUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -449,7 +449,7 @@ public class SynthButtonUI extends BasicButtonUI implements // ******************************** /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getMinimumSize(JComponent c) { @@ -470,7 +470,7 @@ public class SynthButtonUI extends BasicButtonUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getPreferredSize(JComponent c) { @@ -491,7 +491,7 @@ public class SynthButtonUI extends BasicButtonUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getMaximumSize(JComponent c) { @@ -525,7 +525,7 @@ public class SynthButtonUI extends BasicButtonUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxMenuItemUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxMenuItemUI.java index d3f50962433..41b2682598c 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxMenuItemUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxMenuItemUI.java @@ -32,7 +32,7 @@ import javax.swing.plaf.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JCheckBoxMenuItem}. * * @author Leif Samuelsson @@ -54,7 +54,7 @@ public class SynthCheckBoxMenuItemUI extends SynthMenuItemUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected String getPropertyPrefix() { @@ -68,7 +68,7 @@ public class SynthCheckBoxMenuItemUI extends SynthMenuItemUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxUI.java index c4d41ca9d07..aabec2bb3a2 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxUI.java @@ -31,7 +31,7 @@ import javax.swing.plaf.ComponentUI; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JCheckBox}. * * @author Jeff Dinkins @@ -53,7 +53,7 @@ public class SynthCheckBoxUI extends SynthRadioButtonUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected String getPropertyPrefix() { @@ -67,7 +67,7 @@ public class SynthCheckBoxUI extends SynthRadioButtonUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthColorChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthColorChooserUI.java index b85597e53be..0d0753aeb99 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthColorChooserUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthColorChooserUI.java @@ -36,7 +36,7 @@ import java.beans.PropertyChangeListener; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JColorChooser}. * * @author Tom Santos @@ -58,7 +58,7 @@ public class SynthColorChooserUI extends BasicColorChooserUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected AbstractColorChooserPanel[] createDefaultChoosers() { @@ -74,7 +74,7 @@ public class SynthColorChooserUI extends BasicColorChooserUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -89,7 +89,7 @@ public class SynthColorChooserUI extends BasicColorChooserUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -102,7 +102,7 @@ public class SynthColorChooserUI extends BasicColorChooserUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -111,7 +111,7 @@ public class SynthColorChooserUI extends BasicColorChooserUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -120,7 +120,7 @@ public class SynthColorChooserUI extends BasicColorChooserUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -188,7 +188,7 @@ public class SynthColorChooserUI extends BasicColorChooserUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -197,7 +197,7 @@ public class SynthColorChooserUI extends BasicColorChooserUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java index 37f0c85c8a8..165ba8366a1 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java @@ -35,7 +35,7 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JComboBox}. * * @author Scott Violet @@ -103,7 +103,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements } /** - * @inheritDoc + * {@inheritDoc} * * Overridden to ensure that ButtonHandler is created prior to any of * the other installXXX methods, since several of them reference @@ -152,7 +152,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -163,7 +163,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void uninstallUI(JComponent c) { @@ -175,7 +175,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -187,7 +187,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -200,7 +200,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -251,7 +251,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected ComboPopup createPopup() { @@ -261,7 +261,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected ListCellRenderer createRenderer() { @@ -269,7 +269,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected ComboBoxEditor createEditor() { @@ -281,7 +281,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements //====================== /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { @@ -291,7 +291,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected JButton createArrowButton() { @@ -360,7 +360,7 @@ public class SynthComboBoxUI extends BasicComboBoxUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java index 89a15b95f63..38f8f9fae10 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java @@ -34,7 +34,7 @@ import java.beans.*; /** - * Provides the Synth L&F UI delegate for a minimized internal frame on a desktop. + * Provides the Synth L&F UI delegate for a minimized internal frame on a desktop. * * @author Joshua Outwater * @since 1.7 @@ -55,7 +55,7 @@ public class SynthDesktopIconUI extends BasicDesktopIconUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installComponents() { @@ -82,7 +82,7 @@ public class SynthDesktopIconUI extends BasicDesktopIconUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -96,7 +96,7 @@ public class SynthDesktopIconUI extends BasicDesktopIconUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -109,7 +109,7 @@ public class SynthDesktopIconUI extends BasicDesktopIconUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -123,7 +123,7 @@ public class SynthDesktopIconUI extends BasicDesktopIconUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -134,7 +134,7 @@ public class SynthDesktopIconUI extends BasicDesktopIconUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -202,7 +202,7 @@ public class SynthDesktopIconUI extends BasicDesktopIconUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java index 8548f7ff585..a677bdb5f6d 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java @@ -34,7 +34,7 @@ import java.awt.event.*; import java.awt.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JDesktopPane}. * * @author Joshua Outwater @@ -58,7 +58,7 @@ public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -73,7 +73,7 @@ public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -123,7 +123,7 @@ public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -136,7 +136,7 @@ public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -164,7 +164,7 @@ public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDesktopManager() { @@ -180,7 +180,7 @@ public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDesktopManager() { @@ -422,7 +422,7 @@ public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -489,7 +489,7 @@ public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -498,7 +498,7 @@ public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent evt) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java index dcea1406128..d9b9ae7a0f0 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java @@ -33,7 +33,7 @@ import javax.swing.plaf.basic.BasicEditorPaneUI; import java.beans.PropertyChangeEvent; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JEditorPane}. * * @author Shannon Hickey @@ -58,7 +58,7 @@ public class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -74,7 +74,7 @@ public class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -131,7 +131,7 @@ public class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -181,7 +181,7 @@ public class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void paintBackground(Graphics g) { @@ -194,7 +194,7 @@ public class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthFormattedTextFieldUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthFormattedTextFieldUI.java index a3a2fa890a6..776d3f91b86 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthFormattedTextFieldUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthFormattedTextFieldUI.java @@ -29,7 +29,7 @@ import javax.swing.JComponent; import javax.swing.plaf.ComponentUI; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JFormattedTextField}. * * @since 1.7 @@ -58,7 +58,7 @@ public class SynthFormattedTextFieldUI extends SynthTextFieldUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override void paintBackground(SynthContext context, Graphics g, JComponent c) { @@ -67,7 +67,7 @@ public class SynthFormattedTextFieldUI extends SynthTextFieldUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameUI.java index 0c69e05dc01..a4dee16a32f 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameUI.java @@ -34,7 +34,7 @@ import java.beans.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JInternalFrame}. * * @author David Kloba @@ -61,7 +61,7 @@ public class SynthInternalFrameUI extends BasicInternalFrameUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void installDefaults() { @@ -70,7 +70,7 @@ public class SynthInternalFrameUI extends BasicInternalFrameUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -79,7 +79,7 @@ public class SynthInternalFrameUI extends BasicInternalFrameUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallComponents() { @@ -90,7 +90,7 @@ public class SynthInternalFrameUI extends BasicInternalFrameUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -118,7 +118,7 @@ public class SynthInternalFrameUI extends BasicInternalFrameUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -133,7 +133,7 @@ public class SynthInternalFrameUI extends BasicInternalFrameUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -150,7 +150,7 @@ public class SynthInternalFrameUI extends BasicInternalFrameUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected JComponent createNorthPane(JInternalFrame w) { @@ -160,7 +160,7 @@ public class SynthInternalFrameUI extends BasicInternalFrameUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected ComponentListener createComponentListener() { @@ -244,7 +244,7 @@ public class SynthInternalFrameUI extends BasicInternalFrameUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -254,7 +254,7 @@ public class SynthInternalFrameUI extends BasicInternalFrameUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent evt) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthLabelUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthLabelUI.java index e0c50e166cd..d6cae8f1b27 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthLabelUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthLabelUI.java @@ -37,7 +37,7 @@ import java.awt.FontMetrics; import java.beans.PropertyChangeEvent; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JLabel}. * * @author Scott Violet @@ -57,7 +57,7 @@ public class SynthLabelUI extends BasicLabelUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults(JLabel c) { @@ -71,7 +71,7 @@ public class SynthLabelUI extends BasicLabelUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults(JLabel c){ @@ -83,7 +83,7 @@ public class SynthLabelUI extends BasicLabelUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -105,7 +105,7 @@ public class SynthLabelUI extends BasicLabelUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public int getBaseline(JComponent c, int width, int height) { @@ -218,7 +218,7 @@ public class SynthLabelUI extends BasicLabelUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -227,7 +227,7 @@ public class SynthLabelUI extends BasicLabelUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getPreferredSize(JComponent c) { @@ -248,7 +248,7 @@ public class SynthLabelUI extends BasicLabelUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getMinimumSize(JComponent c) { @@ -269,7 +269,7 @@ public class SynthLabelUI extends BasicLabelUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getMaximumSize(JComponent c) { @@ -290,7 +290,7 @@ public class SynthLabelUI extends BasicLabelUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthListUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthListUI.java index 5166159d1cb..a949f5de22f 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthListUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthListUI.java @@ -34,7 +34,7 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JList}. * * @author Scott Violet @@ -80,7 +80,7 @@ public class SynthListUI extends BasicListUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -89,7 +89,7 @@ public class SynthListUI extends BasicListUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -98,7 +98,7 @@ public class SynthListUI extends BasicListUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { @@ -108,7 +108,7 @@ public class SynthListUI extends BasicListUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -117,7 +117,7 @@ public class SynthListUI extends BasicListUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -166,7 +166,7 @@ public class SynthListUI extends BasicListUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -180,7 +180,7 @@ public class SynthListUI extends BasicListUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuBarUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuBarUI.java index fbec6a7e2ba..a87a4ad0fd2 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuBarUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuBarUI.java @@ -32,7 +32,7 @@ import javax.swing.plaf.*; import javax.swing.plaf.basic.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JMenuBar}. * * @author Scott Violet @@ -53,7 +53,7 @@ public class SynthMenuBarUI extends BasicMenuBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -65,7 +65,7 @@ public class SynthMenuBarUI extends BasicMenuBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -87,7 +87,7 @@ public class SynthMenuBarUI extends BasicMenuBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -99,7 +99,7 @@ public class SynthMenuBarUI extends BasicMenuBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -108,7 +108,7 @@ public class SynthMenuBarUI extends BasicMenuBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -175,7 +175,7 @@ public class SynthMenuBarUI extends BasicMenuBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -184,7 +184,7 @@ public class SynthMenuBarUI extends BasicMenuBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuItemUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuItemUI.java index 36b6cf192cf..f34b732b58b 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuItemUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuItemUI.java @@ -34,7 +34,7 @@ import sun.swing.MenuItemLayoutHelper; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JMenuItem}. * * @author Georges Saab @@ -59,7 +59,7 @@ public class SynthMenuItemUI extends BasicMenuItemUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void uninstallUI(JComponent c) { @@ -73,7 +73,7 @@ public class SynthMenuItemUI extends BasicMenuItemUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -81,7 +81,7 @@ public class SynthMenuItemUI extends BasicMenuItemUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -134,7 +134,7 @@ public class SynthMenuItemUI extends BasicMenuItemUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -153,7 +153,7 @@ public class SynthMenuItemUI extends BasicMenuItemUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -162,7 +162,7 @@ public class SynthMenuItemUI extends BasicMenuItemUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -206,7 +206,7 @@ public class SynthMenuItemUI extends BasicMenuItemUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected Dimension getPreferredMenuItemSize(JComponent c, @@ -290,7 +290,7 @@ public class SynthMenuItemUI extends BasicMenuItemUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -299,7 +299,7 @@ public class SynthMenuItemUI extends BasicMenuItemUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuLayout.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuLayout.java index 5a52bc3462b..24ca48d8c4d 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuLayout.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuLayout.java @@ -31,7 +31,7 @@ import java.awt.Container; import java.awt.Dimension; /** - * @inheritDoc + * {@inheritDoc} * * @author Georges Saab */ diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuUI.java index a55aa715fe3..fb6cca06855 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthMenuUI.java @@ -32,7 +32,7 @@ import javax.swing.plaf.basic.*; import sun.swing.MenuItemLayoutHelper; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JMenu}. * * @author Georges Saab @@ -56,7 +56,7 @@ public class SynthMenuUI extends BasicMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -64,7 +64,7 @@ public class SynthMenuUI extends BasicMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -120,7 +120,7 @@ public class SynthMenuUI extends BasicMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void uninstallUI(JComponent c) { @@ -134,7 +134,7 @@ public class SynthMenuUI extends BasicMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -153,7 +153,7 @@ public class SynthMenuUI extends BasicMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -162,7 +162,7 @@ public class SynthMenuUI extends BasicMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -207,7 +207,7 @@ public class SynthMenuUI extends BasicMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected Dimension getPreferredMenuItemSize(JComponent c, @@ -286,7 +286,7 @@ public class SynthMenuUI extends BasicMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -295,7 +295,7 @@ public class SynthMenuUI extends BasicMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthOptionPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthOptionPaneUI.java index 696e83ae467..51786ba781e 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthOptionPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthOptionPaneUI.java @@ -33,7 +33,7 @@ import javax.swing.plaf.basic.*; import sun.swing.DefaultLookup; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JOptionPane}. * * @author James Gosling @@ -56,7 +56,7 @@ public class SynthOptionPaneUI extends BasicOptionPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -64,7 +64,7 @@ public class SynthOptionPaneUI extends BasicOptionPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -92,7 +92,7 @@ public class SynthOptionPaneUI extends BasicOptionPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -104,7 +104,7 @@ public class SynthOptionPaneUI extends BasicOptionPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -113,7 +113,7 @@ public class SynthOptionPaneUI extends BasicOptionPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installComponents() { @@ -132,7 +132,7 @@ public class SynthOptionPaneUI extends BasicOptionPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -199,7 +199,7 @@ public class SynthOptionPaneUI extends BasicOptionPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -208,7 +208,7 @@ public class SynthOptionPaneUI extends BasicOptionPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { @@ -218,7 +218,7 @@ public class SynthOptionPaneUI extends BasicOptionPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected boolean getSizeButtonsToSameWidth() { @@ -273,7 +273,7 @@ public class SynthOptionPaneUI extends BasicOptionPaneUI implements } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected Container createSeparator() { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthPainter.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthPainter.java index 9fcc80da258..3fa960d1d7a 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthPainter.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthPainter.java @@ -41,12 +41,12 @@ import java.awt.*; * example registers a painter for all JButtons that will * render the image myImage.png: *
    - *  <style id="buttonStyle">
    + *  <style id="buttonStyle">
      *    <imagePainter path="myImage.png" sourceInsets="2 2 2 2"
    - *                  paintCenter="true" stretch="true"/>
    - *    <insets top="2" bottom="2" left="2" right="2"/>
    - *  </style>
    - *  <bind style="buttonStyle" type="REGION" key="button"/>
    + *                  paintCenter="true" stretch="true"/>
    + *    <insets top="2" bottom="2" left="2" right="2"/>
    + *  </style>
    + *  <bind style="buttonStyle" type="REGION" key="button"/>
      *
    *

    * SynthPainter is abstract in so far as it does no painting, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthPanelUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthPanelUI.java index 6e47dd2c983..ae63c36eb0e 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthPanelUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthPanelUI.java @@ -32,7 +32,7 @@ import java.awt.*; import java.beans.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JPanel}. * * @author Steve Wilson @@ -53,7 +53,7 @@ public class SynthPanelUI extends BasicPanelUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void installUI(JComponent c) { @@ -64,7 +64,7 @@ public class SynthPanelUI extends BasicPanelUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void uninstallUI(JComponent c) { @@ -93,7 +93,7 @@ public class SynthPanelUI extends BasicPanelUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults(JPanel p) { @@ -101,7 +101,7 @@ public class SynthPanelUI extends BasicPanelUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults(JPanel p) { @@ -119,7 +119,7 @@ public class SynthPanelUI extends BasicPanelUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -187,7 +187,7 @@ public class SynthPanelUI extends BasicPanelUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -196,7 +196,7 @@ public class SynthPanelUI extends BasicPanelUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent pce) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthPasswordFieldUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthPasswordFieldUI.java index 3366dd852a7..6dafaf6284a 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthPasswordFieldUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthPasswordFieldUI.java @@ -31,7 +31,7 @@ import javax.swing.text.*; import javax.swing.plaf.ComponentUI; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JPasswordField}. * * @author Shannon Hickey @@ -73,7 +73,7 @@ public class SynthPasswordFieldUI extends SynthTextFieldUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override void paintBackground(SynthContext context, Graphics g, JComponent c) { @@ -82,7 +82,7 @@ public class SynthPasswordFieldUI extends SynthTextFieldUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -91,7 +91,7 @@ public class SynthPasswordFieldUI extends SynthTextFieldUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installKeyboardActions() { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthPopupMenuUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthPopupMenuUI.java index cacc4a8e4cd..8879d48abf6 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthPopupMenuUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthPopupMenuUI.java @@ -33,7 +33,7 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JPopupMenu}. * * @author Georges Saab @@ -56,7 +56,7 @@ public class SynthPopupMenuUI extends BasicPopupMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void installDefaults() { @@ -81,7 +81,7 @@ public class SynthPopupMenuUI extends BasicPopupMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -90,7 +90,7 @@ public class SynthPopupMenuUI extends BasicPopupMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -106,7 +106,7 @@ public class SynthPopupMenuUI extends BasicPopupMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -115,7 +115,7 @@ public class SynthPopupMenuUI extends BasicPopupMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -182,7 +182,7 @@ public class SynthPopupMenuUI extends BasicPopupMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -191,7 +191,7 @@ public class SynthPopupMenuUI extends BasicPopupMenuUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthProgressBarUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthProgressBarUI.java index 8007ffc1b15..8b09c548e1d 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthProgressBarUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthProgressBarUI.java @@ -35,7 +35,7 @@ import java.beans.PropertyChangeEvent; import sun.swing.SwingUtilities2; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JProgressBar}. * * @author Joshua Outwater @@ -61,7 +61,7 @@ public class SynthProgressBarUI extends BasicProgressBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -70,7 +70,7 @@ public class SynthProgressBarUI extends BasicProgressBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -79,7 +79,7 @@ public class SynthProgressBarUI extends BasicProgressBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -118,7 +118,7 @@ public class SynthProgressBarUI extends BasicProgressBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -130,7 +130,7 @@ public class SynthProgressBarUI extends BasicProgressBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -147,7 +147,7 @@ public class SynthProgressBarUI extends BasicProgressBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public int getBaseline(JComponent c, int width, int height) { @@ -165,7 +165,7 @@ public class SynthProgressBarUI extends BasicProgressBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected Rectangle getBox(Rectangle r) { @@ -177,7 +177,7 @@ public class SynthProgressBarUI extends BasicProgressBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void setAnimationIndex(int newValue) { @@ -386,7 +386,7 @@ public class SynthProgressBarUI extends BasicProgressBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -396,7 +396,7 @@ public class SynthProgressBarUI extends BasicProgressBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { @@ -407,7 +407,7 @@ public class SynthProgressBarUI extends BasicProgressBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getPreferredSize(JComponent c) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthRadioButtonMenuItemUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthRadioButtonMenuItemUI.java index 0e201d6826f..c31ba8369b6 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthRadioButtonMenuItemUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthRadioButtonMenuItemUI.java @@ -30,7 +30,7 @@ import java.awt.*; import javax.swing.plaf.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JRadioButtonMenuItem}. * * @author Georges Saab @@ -50,7 +50,7 @@ public class SynthRadioButtonMenuItemUI extends SynthMenuItemUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected String getPropertyPrefix() { @@ -64,7 +64,7 @@ public class SynthRadioButtonMenuItemUI extends SynthMenuItemUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthRadioButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthRadioButtonUI.java index 5adc4875da7..c380f363d4d 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthRadioButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthRadioButtonUI.java @@ -30,7 +30,7 @@ import javax.swing.*; import javax.swing.plaf.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JRadioButton}. * * @author Jeff Dinkins @@ -52,7 +52,7 @@ public class SynthRadioButtonUI extends SynthToggleButtonUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected String getPropertyPrefix() { @@ -75,7 +75,7 @@ public class SynthRadioButtonUI extends SynthToggleButtonUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthRootPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthRootPaneUI.java index 67a0a88bdc2..ce383522659 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthRootPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthRootPaneUI.java @@ -32,7 +32,7 @@ import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicRootPaneUI; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JRootPane}. * * @author Scott Violet @@ -52,7 +52,7 @@ public class SynthRootPaneUI extends BasicRootPaneUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults(JRootPane c){ @@ -60,7 +60,7 @@ public class SynthRootPaneUI extends BasicRootPaneUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults(JRootPane root) { @@ -72,7 +72,7 @@ public class SynthRootPaneUI extends BasicRootPaneUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -152,7 +152,7 @@ public class SynthRootPaneUI extends BasicRootPaneUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java index fa631ed5cb8..8a1b6e782fa 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java @@ -33,7 +33,7 @@ import javax.swing.plaf.basic.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JScrollBar}. * * @author Scott Violet @@ -53,7 +53,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -68,7 +68,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void configureScrollBarColors() { @@ -136,7 +136,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -145,7 +145,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -154,7 +154,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults(){ @@ -177,7 +177,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -212,7 +212,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public boolean getSupportsAbsolutePositioning() { @@ -283,7 +283,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -354,7 +354,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected Dimension getMinimumThumbSize() { @@ -371,7 +371,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected JButton createDecreaseButton(int orientation) { @@ -400,7 +400,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected JButton createIncreaseButton(int orientation) { @@ -431,7 +431,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void setThumbRollover(boolean active) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollPaneUI.java index 1b85204aac2..1e202749977 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollPaneUI.java @@ -41,7 +41,7 @@ import java.awt.event.FocusListener; import java.awt.event.FocusEvent; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JScrollPane}. * * @author Scott Violet @@ -119,7 +119,7 @@ public class SynthScrollPaneUI extends BasicScrollPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -128,7 +128,7 @@ public class SynthScrollPaneUI extends BasicScrollPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults(JScrollPane scrollpane) { @@ -154,7 +154,7 @@ public class SynthScrollPaneUI extends BasicScrollPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners(JScrollPane c) { @@ -171,7 +171,7 @@ public class SynthScrollPaneUI extends BasicScrollPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults(JScrollPane c) { @@ -186,7 +186,7 @@ public class SynthScrollPaneUI extends BasicScrollPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners(JComponent c) { @@ -203,7 +203,7 @@ public class SynthScrollPaneUI extends BasicScrollPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSeparatorUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSeparatorUI.java index e7baa23a5ea..b46e69c4f2b 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSeparatorUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSeparatorUI.java @@ -36,7 +36,7 @@ import javax.swing.plaf.UIResource; import javax.swing.plaf.DimensionUIResource; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JSeparator}. * * @author Shannon Hickey @@ -58,7 +58,7 @@ public class SynthSeparatorUI extends SeparatorUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void installUI(JComponent c) { @@ -67,7 +67,7 @@ public class SynthSeparatorUI extends SeparatorUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void uninstallUI(JComponent c) { @@ -191,7 +191,7 @@ public class SynthSeparatorUI extends SeparatorUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -202,7 +202,7 @@ public class SynthSeparatorUI extends SeparatorUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getPreferredSize(JComponent c) { @@ -224,7 +224,7 @@ public class SynthSeparatorUI extends SeparatorUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getMinimumSize(JComponent c) { @@ -232,7 +232,7 @@ public class SynthSeparatorUI extends SeparatorUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getMaximumSize(JComponent c) { @@ -240,7 +240,7 @@ public class SynthSeparatorUI extends SeparatorUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSliderUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSliderUI.java index cc18a05eea5..c1ce14631f4 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSliderUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSliderUI.java @@ -42,7 +42,7 @@ import sun.swing.SwingUtilities2; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link JSlider}. * * @author Joshua Outwater @@ -98,7 +98,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults(JSlider slider) { @@ -127,7 +127,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners(JSlider slider) { @@ -136,7 +136,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners(JSlider slider) { @@ -200,7 +200,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected TrackListener createTrackListener(JSlider s) { @@ -231,7 +231,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public int getBaseline(JComponent c, int width, int height) { @@ -302,7 +302,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getPreferredSize(JComponent c) { @@ -320,7 +320,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getMinimumSize(JComponent c) { @@ -335,7 +335,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void calculateGeometry() { @@ -534,7 +534,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void calculateThumbLocation() { @@ -551,7 +551,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void setThumbLocation(int x, int y) { @@ -564,7 +564,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected int xPositionForValue(int value) { @@ -593,7 +593,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected int yPositionForValue(int value, int trackY, int trackHeight) { @@ -622,7 +622,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public int valueForYPosition(int yPos) { @@ -651,7 +651,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public int valueForXPosition(int xPos) { @@ -680,7 +680,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected Dimension getThumbSize() { @@ -697,7 +697,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void recalculateIfInsetsChanged() { @@ -714,7 +714,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -851,7 +851,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -899,7 +899,7 @@ public class SynthSliderUI extends BasicSliderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSpinnerUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSpinnerUI.java index 9b86cae4beb..2c18b0f5979 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSpinnerUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSpinnerUI.java @@ -32,7 +32,7 @@ import javax.swing.plaf.basic.BasicSpinnerUI; import java.beans.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JSpinner}. * * @author Hans Muller @@ -65,7 +65,7 @@ public class SynthSpinnerUI extends BasicSpinnerUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -81,7 +81,7 @@ public class SynthSpinnerUI extends BasicSpinnerUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -156,7 +156,7 @@ public class SynthSpinnerUI extends BasicSpinnerUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected LayoutManager createLayout() { @@ -165,7 +165,7 @@ public class SynthSpinnerUI extends BasicSpinnerUI /** - * @inheritDoc + * {@inheritDoc} */ @Override protected Component createPreviousButton() { @@ -177,7 +177,7 @@ public class SynthSpinnerUI extends BasicSpinnerUI /** - * @inheritDoc + * {@inheritDoc} */ @Override protected Component createNextButton() { @@ -270,7 +270,7 @@ public class SynthSpinnerUI extends BasicSpinnerUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -334,7 +334,7 @@ public class SynthSpinnerUI extends BasicSpinnerUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -439,7 +439,7 @@ public class SynthSpinnerUI extends BasicSpinnerUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java index 0a22820b7c4..f8cec60d2f1 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java @@ -36,7 +36,7 @@ import javax.swing.plaf.basic.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JSplitPane}. * * @author Scott Violet @@ -201,7 +201,7 @@ public class SynthSplitPaneUI extends BasicSplitPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -236,7 +236,7 @@ public class SynthSplitPaneUI extends BasicSplitPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { @@ -257,7 +257,7 @@ public class SynthSplitPaneUI extends BasicSplitPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected Component createDefaultNonContinuousLayoutDivider() { @@ -322,7 +322,7 @@ public class SynthSplitPaneUI extends BasicSplitPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -343,7 +343,7 @@ public class SynthSplitPaneUI extends BasicSplitPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void finishedPaintingChildren(JSplitPane jc, Graphics g) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java index 0686967412d..5abfd8d9468 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java @@ -37,7 +37,7 @@ import java.beans.PropertyChangeEvent; import sun.swing.SwingUtilities2; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JTabbedPane}. * *

    Looks up the {@code selectedTabPadInsets} property from the Style, @@ -120,7 +120,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -183,7 +183,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -192,7 +192,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -201,7 +201,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -227,7 +227,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -256,7 +256,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected JButton createScrollButton(int direction) { @@ -272,7 +272,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { @@ -282,7 +282,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} * * Overridden to keep track of whether the selected tab is also pressed. */ @@ -333,7 +333,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected int getTabLabelShiftX(int tabPlacement, int tabIndex, boolean isSelected) { @@ -345,7 +345,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected int getTabLabelShiftY(int tabPlacement, int tabIndex, boolean isSelected) { @@ -380,7 +380,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected int getBaseline(int tab) { @@ -404,7 +404,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -556,7 +556,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void setRolloverTab(int index) { @@ -750,7 +750,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected int calculateMaxTabHeight(int tabPlacement) { @@ -766,7 +766,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected int calculateTabWidth(int tabPlacement, int tabIndex, @@ -797,7 +797,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected int calculateMaxTabWidth(int tabPlacement) { @@ -813,7 +813,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected Insets getTabInsets(int tabPlacement, int tabIndex) { @@ -823,7 +823,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected FontMetrics getFontMetrics() { @@ -867,7 +867,7 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI } /** - * @inheritDoc + * {@inheritDoc} * * Overridden to create a TabbedPaneLayout subclass which takes into * account tabOverlap. diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTableHeaderUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTableHeaderUI.java index 201e2330633..716a218d5f8 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTableHeaderUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTableHeaderUI.java @@ -35,7 +35,7 @@ import javax.swing.table.*; import sun.swing.table.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.table.JTableHeader}. * * @author Alan Chung @@ -64,7 +64,7 @@ public class SynthTableHeaderUI extends BasicTableHeaderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -89,7 +89,7 @@ public class SynthTableHeaderUI extends BasicTableHeaderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -98,7 +98,7 @@ public class SynthTableHeaderUI extends BasicTableHeaderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -114,7 +114,7 @@ public class SynthTableHeaderUI extends BasicTableHeaderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -174,7 +174,7 @@ public class SynthTableHeaderUI extends BasicTableHeaderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -185,7 +185,7 @@ public class SynthTableHeaderUI extends BasicTableHeaderUI // SynthUI // /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -198,7 +198,7 @@ public class SynthTableHeaderUI extends BasicTableHeaderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void rolloverColumnUpdated(int oldColumn, int newColumn) { @@ -207,7 +207,7 @@ public class SynthTableHeaderUI extends BasicTableHeaderUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent evt) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java index b1e6a092910..384a12076da 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java @@ -54,7 +54,7 @@ import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JTable}. * * @author Philip Milne @@ -202,7 +202,7 @@ public class SynthTableUI extends BasicTableUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -225,7 +225,7 @@ public class SynthTableUI extends BasicTableUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -238,7 +238,7 @@ public class SynthTableUI extends BasicTableUI // /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -278,7 +278,7 @@ public class SynthTableUI extends BasicTableUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -696,7 +696,7 @@ public class SynthTableUI extends BasicTableUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent event) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java index 1e34237d72f..f6b77bfd51e 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java @@ -66,7 +66,7 @@ public class SynthTextAreaUI extends BasicTextAreaUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -77,7 +77,7 @@ public class SynthTextAreaUI extends BasicTextAreaUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -110,7 +110,7 @@ public class SynthTextAreaUI extends BasicTextAreaUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -157,7 +157,7 @@ public class SynthTextAreaUI extends BasicTextAreaUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} * * Overridden to do nothing. */ @@ -167,7 +167,7 @@ public class SynthTextAreaUI extends BasicTextAreaUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java index 3d642d72069..d420d2d7264 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java @@ -36,7 +36,7 @@ import java.beans.PropertyChangeEvent; /** - * Provides the Synth L&F UI delegate for {@link javax.swing.JTextField}. + * Provides the Synth L&F UI delegate for {@link javax.swing.JTextField}. *

    * Warning: * Serialized objects of this class will not be compatible with @@ -148,7 +148,7 @@ public class SynthTextFieldUI extends BasicTextFieldUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -204,7 +204,7 @@ public class SynthTextFieldUI extends BasicTextFieldUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -213,7 +213,7 @@ public class SynthTextFieldUI extends BasicTextFieldUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} * Overridden to do nothing. */ @Override @@ -241,7 +241,7 @@ public class SynthTextFieldUI extends BasicTextFieldUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -252,7 +252,7 @@ public class SynthTextFieldUI extends BasicTextFieldUI implements SynthUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java index 5cb588e6c0f..3c5b4c2146b 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java @@ -185,7 +185,7 @@ public class SynthTextPaneUI extends SynthEditorPaneUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthToggleButtonUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthToggleButtonUI.java index f927490cb97..d308dc615b8 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthToggleButtonUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthToggleButtonUI.java @@ -31,7 +31,7 @@ import javax.swing.JComponent; import javax.swing.plaf.ComponentUI; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JToggleButton}. * * @author Jeff Dinkins @@ -53,7 +53,7 @@ public class SynthToggleButtonUI extends SynthButtonUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected String getPropertyPrefix() { @@ -70,7 +70,7 @@ public class SynthToggleButtonUI extends SynthButtonUI { } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java index 6fcc5d069cd..3fb941dc214 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java @@ -44,7 +44,7 @@ import javax.swing.plaf.basic.BasicToolBarUI; import sun.swing.plaf.synth.SynthIcon; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JToolBar}. * * @since 1.7 @@ -69,7 +69,7 @@ public class SynthToolBarUI extends BasicToolBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -78,7 +78,7 @@ public class SynthToolBarUI extends BasicToolBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -87,7 +87,7 @@ public class SynthToolBarUI extends BasicToolBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -121,7 +121,7 @@ public class SynthToolBarUI extends BasicToolBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -149,13 +149,13 @@ public class SynthToolBarUI extends BasicToolBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installComponents() {} /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallComponents() {} @@ -170,7 +170,7 @@ public class SynthToolBarUI extends BasicToolBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -239,7 +239,7 @@ public class SynthToolBarUI extends BasicToolBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -314,7 +314,7 @@ public class SynthToolBarUI extends BasicToolBarUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void paintDragWindow(Graphics g) { @@ -337,7 +337,7 @@ public class SynthToolBarUI extends BasicToolBarUI // /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthToolTipUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthToolTipUI.java index 2caf587cbf6..9d206796882 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthToolTipUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthToolTipUI.java @@ -37,7 +37,7 @@ import javax.swing.text.View; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JToolTip}. * * @author Joshua Outwater @@ -58,7 +58,7 @@ public class SynthToolTipUI extends BasicToolTipUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults(JComponent c) { @@ -72,7 +72,7 @@ public class SynthToolTipUI extends BasicToolTipUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults(JComponent c) { @@ -83,7 +83,7 @@ public class SynthToolTipUI extends BasicToolTipUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners(JComponent c) { @@ -91,7 +91,7 @@ public class SynthToolTipUI extends BasicToolTipUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners(JComponent c) { @@ -99,7 +99,7 @@ public class SynthToolTipUI extends BasicToolTipUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -144,7 +144,7 @@ public class SynthToolTipUI extends BasicToolTipUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -196,7 +196,7 @@ public class SynthToolTipUI extends BasicToolTipUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Dimension getPreferredSize(JComponent c) { @@ -224,7 +224,7 @@ public class SynthToolTipUI extends BasicToolTipUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTreeUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTreeUI.java index e1af32f73ef..401175cce99 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTreeUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTreeUI.java @@ -50,7 +50,7 @@ import javax.swing.tree.TreePath; import sun.swing.plaf.synth.SynthIcon; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JTree}. * * @author Scott Violet @@ -85,7 +85,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public Icon getExpandedIcon() { @@ -93,7 +93,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installDefaults() { @@ -156,7 +156,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void installListeners() { @@ -165,7 +165,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -193,7 +193,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected TreeCellEditor createDefaultCellEditor() { @@ -211,7 +211,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected TreeCellRenderer createDefaultCellRenderer() { @@ -219,7 +219,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallDefaults() { @@ -241,7 +241,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void uninstallListeners() { @@ -273,7 +273,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, @@ -472,7 +472,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds, @@ -489,7 +489,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void paintHorizontalLine(Graphics g, JComponent c, int y, @@ -499,7 +499,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void paintVerticalPartOfLeg(Graphics g, @@ -511,7 +511,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void paintVerticalLine(Graphics g, JComponent c, int x, int top, @@ -586,7 +586,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void paintExpandControl(Graphics g, Rectangle clipBounds, @@ -607,7 +607,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void drawCentered(Component c, Graphics graphics, Icon icon, @@ -621,7 +621,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent event) { @@ -637,7 +637,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected void paintDropLine(Graphics g) { @@ -677,7 +677,7 @@ public class SynthTreeUI extends BasicTreeUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override protected int getRowX(int row, int depth) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthViewportUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthViewportUI.java index dc2886fb6fa..444e4f049c6 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthViewportUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthViewportUI.java @@ -32,7 +32,7 @@ import java.awt.*; /** - * Provides the Synth L&F UI delegate for + * Provides the Synth L&F UI delegate for * {@link javax.swing.JViewport}. * * @since 1.7 @@ -52,7 +52,7 @@ public class SynthViewportUI extends ViewportUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void installUI(JComponent c) { @@ -62,7 +62,7 @@ public class SynthViewportUI extends ViewportUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void uninstallUI(JComponent c) { @@ -133,7 +133,7 @@ public class SynthViewportUI extends ViewportUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { @@ -217,7 +217,7 @@ public class SynthViewportUI extends ViewportUI } /** - * @inheritDoc + * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent e) { From a9d180056b50038a20b38471ea96e85afe25f692 Mon Sep 17 00:00:00 2001 From: Dmitry Zinkevich Date: Wed, 25 Sep 2013 17:35:22 +0400 Subject: [PATCH 0504/1294] 8025085: [javadoc] some errors in javax/swing Reviewed-by: alexsch --- .../share/classes/javax/swing/JButton.java | 4 +- .../share/classes/javax/swing/JCheckBox.java | 4 +- .../javax/swing/JCheckBoxMenuItem.java | 2 +- .../classes/javax/swing/JColorChooser.java | 10 ++--- .../share/classes/javax/swing/JComboBox.java | 10 ++--- .../share/classes/javax/swing/JComponent.java | 4 +- .../classes/javax/swing/JDesktopPane.java | 14 +++---- .../share/classes/javax/swing/JMenuItem.java | 4 +- .../classes/javax/swing/JToggleButton.java | 4 +- .../classes/javax/swing/SpinnerDateModel.java | 4 +- .../classes/javax/swing/SpinnerListModel.java | 6 +-- .../javax/swing/SpinnerNumberModel.java | 6 +-- .../classes/javax/swing/SpringLayout.java | 2 +- .../classes/javax/swing/TransferHandler.java | 2 +- .../share/classes/javax/swing/UIDefaults.java | 2 +- .../UnsupportedLookAndFeelException.java | 2 +- .../classes/javax/swing/ViewportLayout.java | 3 +- .../classes/javax/swing/plaf/LayerUI.java | 40 +++++++++---------- .../javax/swing/plaf/basic/BasicBorders.java | 2 +- .../swing/plaf/basic/BasicDesktopIconUI.java | 2 +- .../swing/plaf/basic/BasicDesktopPaneUI.java | 2 +- .../swing/plaf/basic/BasicFileChooserUI.java | 2 +- .../swing/plaf/basic/BasicGraphicsUtils.java | 2 +- .../swing/plaf/basic/BasicIconFactory.java | 2 +- .../basic/BasicInternalFrameTitlePane.java | 18 ++++----- .../plaf/basic/BasicInternalFrameUI.java | 2 +- .../javax/swing/plaf/basic/BasicLabelUI.java | 2 +- .../javax/swing/plaf/basic/BasicListUI.java | 4 +- .../swing/plaf/basic/BasicMenuBarUI.java | 2 +- .../javax/swing/plaf/basic/BasicMenuUI.java | 2 +- .../swing/plaf/basic/BasicOptionPaneUI.java | 6 +-- .../plaf/basic/BasicPopupMenuSeparatorUI.java | 2 +- .../swing/plaf/basic/BasicPopupMenuUI.java | 2 +- .../swing/plaf/basic/BasicProgressBarUI.java | 2 +- .../swing/plaf/basic/BasicScrollPaneUI.java | 2 +- .../swing/plaf/basic/BasicSeparatorUI.java | 2 +- .../javax/swing/plaf/basic/BasicSliderUI.java | 14 +++---- .../swing/plaf/basic/BasicSplitPaneUI.java | 4 +- .../swing/plaf/basic/BasicTabbedPaneUI.java | 4 +- .../plaf/basic/BasicToolBarSeparatorUI.java | 2 +- .../swing/plaf/basic/BasicToolBarUI.java | 2 +- .../swing/plaf/basic/BasicToolTipUI.java | 2 +- .../javax/swing/plaf/basic/BasicTreeUI.java | 2 +- .../swing/plaf/basic/DefaultMenuLayout.java | 2 +- .../javax/swing/plaf/metal/MetalBorders.java | 2 +- .../swing/plaf/metal/MetalFileChooserUI.java | 2 +- .../javax/swing/plaf/metal/MetalLabelUI.java | 2 +- .../swing/plaf/metal/MetalLookAndFeel.java | 3 +- .../plaf/metal/MetalPopupMenuSeparatorUI.java | 2 +- .../swing/plaf/metal/MetalScrollPaneUI.java | 2 +- .../swing/plaf/metal/MetalSeparatorUI.java | 2 +- .../javax/swing/plaf/metal/MetalSliderUI.java | 2 +- .../swing/plaf/metal/MetalTabbedPaneUI.java | 4 +- .../swing/plaf/metal/MetalToolTipUI.java | 2 +- .../plaf/nimbus/AbstractRegionPainter.java | 6 +-- .../swing/plaf/nimbus/NimbusLookAndFeel.java | 6 +-- .../javax/swing/plaf/nimbus/NimbusStyle.java | 16 ++++---- .../javax/swing/plaf/synth/Region.java | 6 +-- .../javax/swing/text/html/HTMLEditorKit.java | 1 - .../javax/swing/text/html/ImageView.java | 4 +- .../javax/swing/text/html/InlineView.java | 10 ++--- .../javax/swing/text/html/StyleSheet.java | 4 +- .../swing/text/html/parser/ContentModel.java | 4 +- .../text/html/parser/DocumentParser.java | 4 +- .../javax/swing/text/html/parser/Parser.java | 8 ++-- .../javax/swing/tree/AbstractLayoutCache.java | 2 +- .../swing/tree/DefaultTreeCellEditor.java | 4 +- .../swing/tree/DefaultTreeCellRenderer.java | 3 +- .../javax/swing/tree/DefaultTreeModel.java | 4 +- .../javax/swing/tree/TreeCellRenderer.java | 4 +- .../classes/javax/swing/tree/TreeModel.java | 4 +- .../classes/javax/swing/undo/UndoManager.java | 16 ++++---- 72 files changed, 170 insertions(+), 172 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JButton.java b/jdk/src/share/classes/javax/swing/JButton.java index afa1bf0e7de..45e8757315c 100644 --- a/jdk/src/share/classes/javax/swing/JButton.java +++ b/jdk/src/share/classes/javax/swing/JButton.java @@ -149,7 +149,7 @@ public class JButton extends AbstractButton implements Accessible { /** - * Returns a string that specifies the name of the L&F class + * Returns a string that specifies the name of the L&F class * that renders this component. * * @return the string "ButtonUI" @@ -157,7 +157,7 @@ public class JButton extends AbstractButton implements Accessible { * @see UIDefaults#getUI * @beaninfo * expert: true - * description: A string that specifies the name of the L&F class. + * description: A string that specifies the name of the L&F class. */ public String getUIClassID() { return uiClassID; diff --git a/jdk/src/share/classes/javax/swing/JCheckBox.java b/jdk/src/share/classes/javax/swing/JCheckBox.java index 242d95aa0ca..4d80e9549c6 100644 --- a/jdk/src/share/classes/javax/swing/JCheckBox.java +++ b/jdk/src/share/classes/javax/swing/JCheckBox.java @@ -230,7 +230,7 @@ public class JCheckBox extends JToggleButton implements Accessible { /** - * Returns a string that specifies the name of the L&F class + * Returns a string that specifies the name of the L&F class * that renders this component. * * @return the string "CheckBoxUI" @@ -238,7 +238,7 @@ public class JCheckBox extends JToggleButton implements Accessible { * @see UIDefaults#getUI * @beaninfo * expert: true - * description: A string that specifies the name of the L&F class + * description: A string that specifies the name of the L&F class */ public String getUIClassID() { return uiClassID; diff --git a/jdk/src/share/classes/javax/swing/JCheckBoxMenuItem.java b/jdk/src/share/classes/javax/swing/JCheckBoxMenuItem.java index 260ca01b117..8b42b729f14 100644 --- a/jdk/src/share/classes/javax/swing/JCheckBoxMenuItem.java +++ b/jdk/src/share/classes/javax/swing/JCheckBoxMenuItem.java @@ -168,7 +168,7 @@ public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants, } /** - * Returns the name of the L&F class + * Returns the name of the L&F class * that renders this component. * * @return "CheckBoxMenuItemUI" diff --git a/jdk/src/share/classes/javax/swing/JColorChooser.java b/jdk/src/share/classes/javax/swing/JColorChooser.java index 07a72791fa5..eb3aff69a5c 100644 --- a/jdk/src/share/classes/javax/swing/JColorChooser.java +++ b/jdk/src/share/classes/javax/swing/JColorChooser.java @@ -216,7 +216,7 @@ public class JColorChooser extends JComponent implements Accessible { } /** - * Returns the L&F object that renders this component. + * Returns the L&F object that renders this component. * * @return the ColorChooserUI object that renders * this component @@ -226,9 +226,9 @@ public class JColorChooser extends JComponent implements Accessible { } /** - * Sets the L&F object that renders this component. + * Sets the L&F object that renders this component. * - * @param ui the ColorChooserUI L&F object + * @param ui the ColorChooserUI L&F object * @see UIDefaults#getUI * * @beaninfo @@ -241,7 +241,7 @@ public class JColorChooser extends JComponent implements Accessible { } /** - * Notification from the UIManager that the L&F has changed. + * Notification from the UIManager that the L&F has changed. * Replaces the current UI object with the latest version from the * UIManager. * @@ -252,7 +252,7 @@ public class JColorChooser extends JComponent implements Accessible { } /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "ColorChooserUI" * @see JComponent#getUIClassID diff --git a/jdk/src/share/classes/javax/swing/JComboBox.java b/jdk/src/share/classes/javax/swing/JComboBox.java index 8ac710910a8..ba3bb8abb1d 100644 --- a/jdk/src/share/classes/javax/swing/JComboBox.java +++ b/jdk/src/share/classes/javax/swing/JComboBox.java @@ -242,9 +242,9 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible { } /** - * Sets the L&F object that renders this component. + * Sets the L&F object that renders this component. * - * @param ui the ComboBoxUI L&F object + * @param ui the ComboBoxUI L&F object * @see UIDefaults#getUI * * @beaninfo @@ -273,7 +273,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible { /** - * Returns the name of the L&F class that renders this component. + * Returns the name of the L&F class that renders this component. * * @return the string "ComboBoxUI" * @see JComponent#getUIClassID @@ -285,7 +285,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible { /** - * Returns the L&F object that renders this component. + * Returns the L&F object that renders this component. * * @return the ComboBoxUI object that renders this component */ @@ -607,7 +607,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible { * * @param anIndex an integer specifying the list item to select, * where 0 specifies the first item in the list and -1 indicates no selection - * @exception IllegalArgumentException if anIndex < -1 or + * @exception IllegalArgumentException if anIndex < -1 or * anIndex is greater than or equal to size * @beaninfo * preferred: true diff --git a/jdk/src/share/classes/javax/swing/JComponent.java b/jdk/src/share/classes/javax/swing/JComponent.java index dac623a37bd..13576590a39 100644 --- a/jdk/src/share/classes/javax/swing/JComponent.java +++ b/jdk/src/share/classes/javax/swing/JComponent.java @@ -86,7 +86,7 @@ import sun.swing.UIClientPropertyKey; *