From f85705002ec44bc67ce0dcbbc9b50763e8dd1a74 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Fri, 28 Dec 2012 22:21:40 -0800 Subject: [PATCH 01/28] 8003562: Provide a CLI tool to analyze class dependencies Reviewed-by: jjg, alanb, ulfzibis, erikj --- jdk/make/common/Release.gmk | 3 +++ jdk/make/docs/NON_CORE_PKGS.gmk | 2 +- jdk/make/launchers/Makefile | 1 + jdk/make/launchers/Makefile.launcher | 4 ++++ jdk/makefiles/CompileLaunchers.gmk | 5 +++++ jdk/makefiles/CreateJars.gmk | 1 + jdk/makefiles/Images.gmk | 1 + 7 files changed, 16 insertions(+), 1 deletion(-) diff --git a/jdk/make/common/Release.gmk b/jdk/make/common/Release.gmk index dc43ecf95ea..367eab8fa7e 100644 --- a/jdk/make/common/Release.gmk +++ b/jdk/make/common/Release.gmk @@ -375,6 +375,7 @@ TOOLS = \ com/sun/tools/javadoc \ com/sun/tools/javah \ com/sun/tools/javap \ + com/sun/tools/jdeps \ com/sun/tools/corba \ com/sun/tools/internal/xjc \ com/sun/tools/internal/ws \ @@ -457,6 +458,7 @@ NOTJRETOOLS = \ javadoc$(EXE_SUFFIX) \ javah$(EXE_SUFFIX) \ javap$(EXE_SUFFIX) \ + jdeps$(EXE_SUFFIX) \ jcmd$(EXE_SUFFIX) \ jdb$(EXE_SUFFIX) \ jps$(EXE_SUFFIX) \ @@ -564,6 +566,7 @@ $(NOT_RT_JAR_LIST): FRC $(ECHO) "sun/tools/javac/" >> $@ $(ECHO) "com/sun/tools/classfile/" >> $@ $(ECHO) "com/sun/tools/javap/" >> $@ + $(ECHO) "com/sun/tools/jdeps/" >> $@ $(ECHO) "sun/tools/jcmd/" >> $@ $(ECHO) "sun/tools/jconsole/" >> $@ $(ECHO) "sun/tools/jps/" >> $@ diff --git a/jdk/make/docs/NON_CORE_PKGS.gmk b/jdk/make/docs/NON_CORE_PKGS.gmk index b299938e844..949637cfeda 100644 --- a/jdk/make/docs/NON_CORE_PKGS.gmk +++ b/jdk/make/docs/NON_CORE_PKGS.gmk @@ -76,7 +76,7 @@ ATTACH_PKGS = com.sun.tools.attach \ JCONSOLE_PKGS = com.sun.tools.jconsole -TREEAPI_PKGS = com.sunsource.doctree \ +TREEAPI_PKGS = com.sun.source.doctree \ com.sun.source.tree \ com.sun.source.util diff --git a/jdk/make/launchers/Makefile b/jdk/make/launchers/Makefile index 3d9511408b0..be16512e478 100644 --- a/jdk/make/launchers/Makefile +++ b/jdk/make/launchers/Makefile @@ -63,6 +63,7 @@ $(call make-launcher, javac, com.sun.tools.javac.Main, , ) $(call make-launcher, javadoc, com.sun.tools.javadoc.Main, , ) $(call make-launcher, javah, com.sun.tools.javah.Main, , ) $(call make-launcher, javap, com.sun.tools.javap.Main, , ) +$(call make-launcher, jdeps, com.sun.tools.jdeps.Main, , ) $(call make-launcher, jcmd, sun.tools.jcmd.JCmd, , ) $(call make-launcher, jconsole, sun.tools.jconsole.JConsole, \ -J-Djconsole.showOutputViewer, ) diff --git a/jdk/make/launchers/Makefile.launcher b/jdk/make/launchers/Makefile.launcher index 1b3e51b6de8..bb06f80f7cc 100644 --- a/jdk/make/launchers/Makefile.launcher +++ b/jdk/make/launchers/Makefile.launcher @@ -62,6 +62,10 @@ ifeq ($(PROGRAM),javap) WILDCARDS=true NEVER_ACT_AS_SERVER_CLASS_MACHINE=true endif +ifeq ($(PROGRAM),jdeps) + WILDCARDS=true + NEVER_ACT_AS_SERVER_CLASS_MACHINE=true +endif ifeq ($(PROGRAM),javah) WILDCARDS=true NEVER_ACT_AS_SERVER_CLASS_MACHINE=true diff --git a/jdk/makefiles/CompileLaunchers.gmk b/jdk/makefiles/CompileLaunchers.gmk index 102a2e7831f..f97578aa087 100644 --- a/jdk/makefiles/CompileLaunchers.gmk +++ b/jdk/makefiles/CompileLaunchers.gmk @@ -267,6 +267,11 @@ $(eval $(call SetupLauncher,javap,\ -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javap.Main"$(COMMA) }')) +$(eval $(call SetupLauncher,jdeps,\ + -DEXPAND_CLASSPATH_WILDCARDS \ + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ + -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.jdeps.Main"$(COMMA) }')) + BUILD_LAUNCHER_jconsole_CFLAGS_windows:=-DJAVAW BUILD_LAUNCHER_jconsole_LDFLAGS_windows:=user32.lib diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk index 748aac94a2d..77269bd2b90 100644 --- a/jdk/makefiles/CreateJars.gmk +++ b/jdk/makefiles/CreateJars.gmk @@ -738,6 +738,7 @@ TOOLS_JAR_INCLUDES := \ com/sun/tools/javadoc \ com/sun/tools/javah \ com/sun/tools/javap \ + com/sun/tools/jdeps \ com/sun/tools/corba \ com/sun/tools/internal/xjc \ com/sun/tools/internal/ws \ diff --git a/jdk/makefiles/Images.gmk b/jdk/makefiles/Images.gmk index 5a85e6c37f3..8d8368dbf08 100644 --- a/jdk/makefiles/Images.gmk +++ b/jdk/makefiles/Images.gmk @@ -100,6 +100,7 @@ NOT_JRE_BIN_FILES := \ javadoc$(EXE_SUFFIX) \ javah$(EXE_SUFFIX) \ javap$(EXE_SUFFIX) \ + jdeps$(EXE_SUFFIX) \ jcmd$(EXE_SUFFIX) \ jdb$(EXE_SUFFIX) \ jps$(EXE_SUFFIX) \ From c2f4000a6f8f276ce45496d7237b098a9d364861 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Sat, 29 Dec 2012 11:00:15 +0000 Subject: [PATCH 02/28] 8005556: java/net/Socks/SocksV4Test.java is missing @run tag Reviewed-by: alanb --- jdk/test/java/net/Socks/SocksV4Test.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/test/java/net/Socks/SocksV4Test.java b/jdk/test/java/net/Socks/SocksV4Test.java index b61d658a78a..cc0452e5ea4 100644 --- a/jdk/test/java/net/Socks/SocksV4Test.java +++ b/jdk/test/java/net/Socks/SocksV4Test.java @@ -26,6 +26,7 @@ * @bug 4727547 * @summary SocksSocketImpl throws NullPointerException * @build SocksServer + * @run main SocksV4Test */ import java.net.*; From 2fc01efdd8af2fd8aa85c18ca6c4c6b596addb77 Mon Sep 17 00:00:00 2001 From: Jim Gish Date: Fri, 28 Dec 2012 16:56:54 -0500 Subject: [PATCH 03/28] 8005118: Javadoc styles are inconsistent Use a common javadoc style in the String classes Reviewed-by: darcy --- .../java/lang/AbstractStringBuilder.java | 10 +- jdk/src/share/classes/java/lang/String.java | 170 +++++++++--------- .../share/classes/java/lang/StringBuffer.java | 22 +-- .../classes/java/lang/StringBuilder.java | 76 ++++---- .../lang/StringIndexOutOfBoundsException.java | 10 +- 5 files changed, 147 insertions(+), 141 deletions(-) diff --git a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java index fc513f55efe..03999c445a5 100644 --- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java +++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java @@ -860,9 +860,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * @return the specified subsequence. * * @throws IndexOutOfBoundsException - * if start or end are negative, - * if end is greater than length(), - * or if start is greater than end + * if {@code start} or {@code end} are negative, + * if {@code end} is greater than {@code length()}, + * or if {@code start} is greater than {@code end} * @spec JSR-51 */ @Override @@ -1292,7 +1292,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * Returns the index within this string of the first occurrence of the * specified substring, starting at the specified index. The integer - * returned is the smallest value k for which: + * returned is the smallest value {@code k} for which: *
      *     k >= Math.min(fromIndex, str.length()) &&
      *                   this.toString().startsWith(str, k)
@@ -1418,7 +1418,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
     public abstract String toString();
 
     /**
-     * Needed by String for the contentEquals method.
+     * Needed by {@code String} for the contentEquals method.
      */
     final char[] getValue() {
         return value;
diff --git a/jdk/src/share/classes/java/lang/String.java b/jdk/src/share/classes/java/lang/String.java
index d73a2f7c2e9..a9bc2f37648 100644
--- a/jdk/src/share/classes/java/lang/String.java
+++ b/jdk/src/share/classes/java/lang/String.java
@@ -615,10 +615,10 @@ public final class String
     }
 
     /**
-     * Returns true if, and only if, {@link #length()} is 0.
+     * Returns {@code true} if, and only if, {@link #length()} is {@code 0}.
      *
-     * @return true if {@link #length()} is 0, otherwise
-     * false
+     * @return {@code true} if {@link #length()} is {@code 0}, otherwise
+     * {@code false}
      *
      * @since 1.6
      */
@@ -1229,23 +1229,23 @@ public final class String
     /**
      * Tests if two string regions are equal.
      * 

- * A substring of this String object is compared to a substring + * A substring of this {@code String} object is compared to a substring * of the argument other. The result is true if these substrings * represent identical character sequences. The substring of this - * String object to be compared begins at index toffset - * and has length len. The substring of other to be compared - * begins at index ooffset and has length len. The - * result is false if and only if at least one of the following + * {@code String} object to be compared begins at index {@code toffset} + * and has length {@code len}. The substring of other to be compared + * begins at index {@code ooffset} and has length {@code len}. The + * result is {@code false} if and only if at least one of the following * is true: - *

* - *

The protection domain contains CodeSource + *

The protection domain contains a CodeSource * object, which encapsulates its codebase (URL) and public key attributes. * It also contains the principals associated with the domain. * The Policy object evaluates the global policy in light of who the @@ -87,9 +88,6 @@ import sun.security.util.ResourcesMgr; public class PolicyParser { - // needs to be public for PolicyTool - public static final String REPLACE_NAME = "PolicyParser.REPLACE_NAME"; - private static final String EXTDIRS_PROPERTY = "java.ext.dirs"; private static final String OLD_EXTDIRS_EXPANSION = "${" + EXTDIRS_PROPERTY + "}"; @@ -452,7 +450,7 @@ public class PolicyParser { peekAndMatch(","); } else if (peekAndMatch("Principal")) { if (principals == null) { - principals = new LinkedList(); + principals = new LinkedList<>(); } String principalClass; @@ -461,7 +459,7 @@ public class PolicyParser { if (peek("\"")) { // both the principalClass and principalName // will be replaced later - principalClass = REPLACE_NAME; + principalClass = PrincipalEntry.REPLACE_NAME; principalName = match("principal type"); } else { // check for principalClass wildcard @@ -916,7 +914,7 @@ public class PolicyParser { out.print(",\n"); } if (principals != null && principals.size() > 0) { - ListIterator pli = principals.listIterator(); + Iterator pli = principals.iterator(); while (pli.hasNext()) { out.print(" "); PrincipalEntry pe = pli.next(); @@ -949,23 +947,22 @@ public class PolicyParser { /** * Principal info (class and name) in a grant entry */ - public static class PrincipalEntry { + public static class PrincipalEntry implements Principal { public static final String WILDCARD_CLASS = "WILDCARD_PRINCIPAL_CLASS"; public static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME"; + public static final String REPLACE_NAME = "PolicyParser.REPLACE_NAME"; String principalClass; String principalName; /** - * A PrincipalEntry consists of the Principal - * class and Principal name. + * A PrincipalEntry consists of the Principal class and Principal name. * - *

- * - * @param principalClass the Principal class.

- * - * @param principalName the Principal name.

+ * @param principalClass the Principal class + * @param principalName the Principal name + * @throws NullPointerException if principalClass or principalName + * are null */ public PrincipalEntry(String principalClass, String principalName) { if (principalClass == null || principalName == null) @@ -975,6 +972,18 @@ public class PolicyParser { this.principalName = principalName; } + boolean isWildcardName() { + return principalName.equals(WILDCARD_NAME); + } + + boolean isWildcardClass() { + return principalClass.equals(WILDCARD_CLASS); + } + + boolean isReplaceName() { + return principalClass.equals(REPLACE_NAME); + } + public String getPrincipalClass() { return principalClass; } @@ -984,9 +993,9 @@ public class PolicyParser { } public String getDisplayClass() { - if (principalClass.equals(WILDCARD_CLASS)) { + if (isWildcardClass()) { return "*"; - } else if (principalClass.equals(REPLACE_NAME)) { + } else if (isReplaceName()) { return ""; } else return principalClass; @@ -997,7 +1006,7 @@ public class PolicyParser { } public String getDisplayName(boolean addQuote) { - if (principalName.equals(WILDCARD_NAME)) { + if (isWildcardName()) { return "*"; } else { @@ -1006,8 +1015,14 @@ public class PolicyParser { } } + @Override + public String getName() { + return principalName; + } + + @Override public String toString() { - if (!principalClass.equals(REPLACE_NAME)) { + if (!isReplaceName()) { return getDisplayClass() + "/" + getDisplayName(); } else { return getDisplayName(); @@ -1016,15 +1031,13 @@ public class PolicyParser { /** * Test for equality between the specified object and this object. - * Two PrincipalEntries are equal if their PrincipalClass and - * PrincipalName values are equal. + * Two PrincipalEntries are equal if their class and name values + * are equal. * - *

- * - * @param obj the object to test for equality with this object. - * - * @return true if the objects are equal, false otherwise. + * @param obj the object to test for equality with this object + * @return true if the objects are equal, false otherwise */ + @Override public boolean equals(Object obj) { if (this == obj) return true; @@ -1033,27 +1046,23 @@ public class PolicyParser { return false; PrincipalEntry that = (PrincipalEntry)obj; - if (this.principalClass.equals(that.principalClass) && - this.principalName.equals(that.principalName)) { - return true; - } - - return false; + return (principalClass.equals(that.principalClass) && + principalName.equals(that.principalName)); } /** - * Return a hashcode for this PrincipalEntry. + * Return a hashcode for this PrincipalEntry. * - *

- * - * @return a hashcode for this PrincipalEntry. + * @return a hashcode for this PrincipalEntry */ + @Override public int hashCode() { return principalClass.hashCode(); } + public void write(PrintWriter out) { out.print("principal " + getDisplayClass() + " " + - getDisplayName(true)); + getDisplayName(true)); } } @@ -1101,6 +1110,7 @@ public class PolicyParser { * Calculates a hash code value for the object. Objects * which are equal will also have the same hashcode. */ + @Override public int hashCode() { int retval = permission.hashCode(); if (name != null) retval ^= name.hashCode(); @@ -1108,6 +1118,7 @@ public class PolicyParser { return retval; } + @Override public boolean equals(Object obj) { if (obj == this) return true; @@ -1210,28 +1221,18 @@ public class PolicyParser { i18nMessage = form.format(source); } + @Override public String getLocalizedMessage() { return i18nMessage; } } public static void main(String arg[]) throws Exception { - FileReader fr = null; - FileWriter fw = null; - try { + try (FileReader fr = new FileReader(arg[0]); + FileWriter fw = new FileWriter(arg[1])) { PolicyParser pp = new PolicyParser(true); - fr = new FileReader(arg[0]); pp.read(fr); - fw = new FileWriter(arg[1]); pp.write(fw); - } finally { - if (fr != null) { - fr.close(); - } - - if (fw != null) { - fw.close(); - } } } } diff --git a/jdk/src/share/classes/sun/security/tools/policytool/PolicyTool.java b/jdk/src/share/classes/sun/security/tools/policytool/PolicyTool.java index 5835ce995bf..17f9d9c5278 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/PolicyTool.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/PolicyTool.java @@ -604,7 +604,7 @@ public class PolicyTool { InstantiationException { if (type.equals(PolicyParser.PrincipalEntry.WILDCARD_CLASS) || - type.equals(PolicyParser.REPLACE_NAME)) { + type.equals(PolicyParser.PrincipalEntry.REPLACE_NAME)) { return; } Class PRIN = Class.forName("java.security.Principal"); @@ -2094,7 +2094,7 @@ class ToolDialog extends Dialog { } else if (pclass.equals("")) { // make this consistent with what PolicyParser does // when it sees an empty principal class - pclass = PolicyParser.REPLACE_NAME; + pclass = PolicyParser.PrincipalEntry.REPLACE_NAME; tool.warnings.addElement( "Warning: Principal name '" + pname + "' specified without a Principal class.\n" + diff --git a/jdk/test/java/security/Principal/Implies.java b/jdk/test/java/security/Principal/Implies.java new file mode 100644 index 00000000000..d3cfd2493e8 --- /dev/null +++ b/jdk/test/java/security/Principal/Implies.java @@ -0,0 +1,80 @@ +/* + * 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. + */ + +/* + * @test + * @bug 7019834 + * @summary test default implementation of Principal.implies + */ + +import java.security.Principal; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import javax.security.auth.Subject; +import javax.security.auth.kerberos.KerberosPrincipal; +import javax.security.auth.x500.X500Principal; + +public class Implies { + public static void main(String[] args) throws Exception { + X500Principal duke = new X500Principal("CN=Duke"); + // should not throw NullPointerException + testImplies(duke, (Subject)null, false); + + Set principals = new HashSet<>(); + principals.add(duke); + testImplies(duke, principals, true); + + X500Principal tux = new X500Principal("CN=Tux"); + principals.add(tux); + testImplies(duke, principals, true); + + principals.add(new KerberosPrincipal("duke@java.com")); + testImplies(duke, principals, true); + + principals.clear(); + principals.add(tux); + testImplies(duke, principals, false); + + System.out.println("test passed"); + } + + private static void testImplies(Principal principal, + Set principals, + boolean result) + throws SecurityException + { + Subject subject = new Subject(true, principals, Collections.emptySet(), + Collections.emptySet()); + testImplies(principal, subject, result); + } + + private static void testImplies(Principal principal, + Subject subject, boolean result) + throws SecurityException + { + if (principal.implies(subject) != result) { + throw new SecurityException("test failed"); + } + } +} diff --git a/jdk/test/sun/security/provider/PolicyFile/Comparator.java b/jdk/test/sun/security/provider/PolicyFile/Comparator.java index 5f65d464164..231d06f197e 100644 --- a/jdk/test/sun/security/provider/PolicyFile/Comparator.java +++ b/jdk/test/sun/security/provider/PolicyFile/Comparator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -39,7 +39,6 @@ import javax.security.auth.Subject; import javax.security.auth.x500.X500Principal; import sun.security.provider.PolicyFile; -import com.sun.security.auth.PrincipalComparator; import com.sun.security.auth.UnixPrincipal; import com.sun.security.auth.NTUserPrincipal; import com.sun.security.auth.SolarisPrincipal; @@ -90,7 +89,7 @@ public class Comparator { private static final Principal[] badP = new Principal[] { new SolarisPrincipal("bad") }; - public static class PCompare1 implements PrincipalComparator { + public static class PCompare1 implements Principal { private String name; @@ -98,6 +97,12 @@ public class Comparator { this.name = name; } + @Override + public String getName() { + return name; + } + + @Override public boolean implies (Subject subject) { if (subject.getPrincipals().contains(p1[0])) { return true; @@ -106,13 +111,19 @@ public class Comparator { } } - public static class PCompare2 implements PrincipalComparator { + public static class PCompare2 implements Principal { private String name; public PCompare2(String name) { this.name = name; } + @Override + public String getName() { + return name; + } + + @Override public boolean implies (Subject subject) { if (subject.getPrincipals().contains(p2[0]) && subject.getPrincipals().contains(p2[1])) { @@ -122,13 +133,19 @@ public class Comparator { } } - public static class PCompare3 implements PrincipalComparator { + public static class PCompare3 implements Principal { private String name; public PCompare3(String name) { this.name = name; } + @Override + public String getName() { + return name; + } + + @Override public boolean implies (Subject subject) { return false; } From df5b548d028f646b85e8e4d4bb282fb5a8bf806a Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 8 Jan 2013 16:08:29 -0800 Subject: [PATCH 18/28] 8005298: Add FunctionalInterface type to the core libraries Reviewed-by: mduigou --- .../java/lang/FunctionalInterface.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 jdk/src/share/classes/java/lang/FunctionalInterface.java diff --git a/jdk/src/share/classes/java/lang/FunctionalInterface.java b/jdk/src/share/classes/java/lang/FunctionalInterface.java new file mode 100644 index 00000000000..0d4ae72a697 --- /dev/null +++ b/jdk/src/share/classes/java/lang/FunctionalInterface.java @@ -0,0 +1,63 @@ +/* + * 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; + +import java.lang.annotation.*; + +/** + * Indicates that an interface type declaration is intended to be a + * functional interface as defined by the Java Language + * Specification. + * + * Conceptually, a functional interface has exactly one abstract + * method. Since {@linkplain java.lang.reflect.Method#isDefault() + * default methods} have an implementation, they are not abstract. If + * an interface declares an abstract method overriding one of the + * public methods of {@code java.lang.Object}, that also does + * not count toward the interface's abstract method count + * since any implementation of the interface will have an + * implementation from {@code java.lang.Object} or elsewhere. + * + *

Note that instances of functional interfaces can be created with + * lambda expressions, method references, or constructor references. + * + *

If a type is annotated with this annotation type, compilers are + * required to generate an error message unless: + * + *

    + *
  • The type is an interface type and not an annotation type, enum, or class. + *
  • The annotated type satisfies the requirements of a functional interface. + *
+ * + * @jls 4.3.2. The Class Object + * @jls 9.8 Functional Interfaces + * @jls 9.4.3 Interface Method Body + * @since 1.8 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface FunctionalInterface {} From 19b3fdf5eeafb0f6e43831012a2458966e600428 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Wed, 9 Jan 2013 16:52:08 +0400 Subject: [PATCH 19/28] 8005019: JTable passes row index instead of length when inserts selection interval Reviewed-by: serb, denis --- jdk/src/share/classes/javax/swing/JTable.java | 2 +- .../swing/JTable/8005019/bug8005019.java | 103 ++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 jdk/test/javax/swing/JTable/8005019/bug8005019.java diff --git a/jdk/src/share/classes/javax/swing/JTable.java b/jdk/src/share/classes/javax/swing/JTable.java index fbd61d9a9fc..c607a9a5ba9 100644 --- a/jdk/src/share/classes/javax/swing/JTable.java +++ b/jdk/src/share/classes/javax/swing/JTable.java @@ -3953,7 +3953,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable break; case TableModelEvent.INSERT: modelSelection.insertIndexInterval(change.startModelIndex, - change.endModelIndex, + change.length, true); break; default: diff --git a/jdk/test/javax/swing/JTable/8005019/bug8005019.java b/jdk/test/javax/swing/JTable/8005019/bug8005019.java new file mode 100644 index 00000000000..e0849453588 --- /dev/null +++ b/jdk/test/javax/swing/JTable/8005019/bug8005019.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8005019 + * @summary JTable passes row index instead of length when inserts selection interval + * @author Alexander Scherbatiy + * @run main bug8005019 + */ + +import java.util.*; +import javax.swing.*; +import javax.swing.table.*; + +public class bug8005019 { + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + testSelectionWithFilterTable(); + } + }); + } + + private static void testSelectionWithFilterTable() { + DefaultTableModel model = new DefaultTableModel(0, 1); + // a model with 3 elements is the minimum to demonstrate + // the bug + int last = 2; + for (int i = 0; i <= last; i++) { + model.addRow(new Object[]{i}); + } + JTable table = new JTable(model); + table.setAutoCreateRowSorter(true); + // set selection at the end + table.setRowSelectionInterval(last, last); + // exclude rows based on identifier + RowFilter filter = new GeneralFilter(new int[]{0}); + ((DefaultRowSorter) table.getRowSorter()).setRowFilter(filter); + // insertRow _before or at_ selected model index, such that + // endIndex (in event) > 1 + model.insertRow(2, new Object[]{"x"}); + } + + private static class GeneralFilter extends RowFilter { + + private int[] columns; + List excludes = Arrays.asList(0); + + GeneralFilter(int[] columns) { + this.columns = columns; + } + + public boolean include(RowFilter.Entry value) { + int count = value.getValueCount(); + if (columns.length > 0) { + for (int i = columns.length - 1; i >= 0; i--) { + int index = columns[i]; + if (index < count) { + if (include(value, index)) { + return true; + } + } + } + } else { + while (--count >= 0) { + if (include(value, count)) { + return true; + } + } + } + return false; + } + + protected boolean include( + Entry entry, + int index) { + return !excludes.contains(entry.getIdentifier()); + } + } +} From af27b8c59d003feea76b53449584373bf828cabf Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Wed, 9 Jan 2013 16:58:47 -0800 Subject: [PATCH 20/28] 7103957: NegativeArraySizeException while initializing class IntegerCache Reviewed-by: darcy, mchung --- jdk/src/share/classes/java/lang/Integer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/lang/Integer.java b/jdk/src/share/classes/java/lang/Integer.java index 3496d039c1c..af575f0b54d 100644 --- a/jdk/src/share/classes/java/lang/Integer.java +++ b/jdk/src/share/classes/java/lang/Integer.java @@ -772,7 +772,7 @@ public final class Integer extends Number implements Comparable { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE - h = Math.min(i, Integer.MAX_VALUE - (-low)); + h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } high = h; From f2c492220c5cd2a1a14ecea4e276dde3c4675d19 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 9 Jan 2013 20:20:21 -0800 Subject: [PATCH 21/28] 8005713: Simplify library support for repeating annotations in java.lang.annotation Reviewed-by: abuckley --- .../java/lang/annotation/Repeatable.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 jdk/src/share/classes/java/lang/annotation/Repeatable.java diff --git a/jdk/src/share/classes/java/lang/annotation/Repeatable.java b/jdk/src/share/classes/java/lang/annotation/Repeatable.java new file mode 100644 index 00000000000..570ed0fa5da --- /dev/null +++ b/jdk/src/share/classes/java/lang/annotation/Repeatable.java @@ -0,0 +1,48 @@ +/* + * 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.annotation; + +/** + * The annotation type {@code java.lang.annotation.Repeatable} is + * used to indicate that the annotation type whose declaration it + * (meta-)annotates is repeatable. The value of + * {@code @Repeatable} indicates the containing annotation + * type for the repeatable annotation type. + * + * @since 1.8 + * @jls 9.6 Annotation Types + * @jls 9.7 Annotations + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.ANNOTATION_TYPE) +public @interface Repeatable { + /** + * Indicates the containing annotation type for the + * repeatable annotation type. + */ + Class value(); +} From d696ea84e662be2b53cd797e20e7f76955400382 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 10 Jan 2013 09:55:25 -0800 Subject: [PATCH 22/28] Added tag jdk8-b72 for changeset a521fc006ff6 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 39cdca44b38..85a42f862f4 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -193,3 +193,4 @@ cdb401a60cea6ad5ef3f498725ed1decf8dda1ea jdk8-b68 6ee8080a6efe0639fcd00627a5e0f839bf010481 jdk8-b69 105a25ffa4a4f0af70188d4371b4a0385009b7ce jdk8-b70 51ad2a34342055333eb5f36e2fb514b027895708 jdk8-b71 +c1be681d80a1f1c848dc671d664fccb19e046a12 jdk8-b72 From 714ada87e73b2acaff43211d2c0bb204f87ab509 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 10 Jan 2013 09:55:26 -0800 Subject: [PATCH 23/28] Added tag jdk8-b72 for changeset e927c8725ba4 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 63281ba72d9..47a378ec418 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -193,3 +193,4 @@ d54dc53e223ed9ce7d5f4d2cd02ad9d5def3c2db jdk8-b59 22ddcac208a8dea894a16887d04f3ca4d3c5d267 jdk8-b69 603cceb495c8133d47b26a7502d51c7d8a67d76b jdk8-b70 8171d23e914d758836527b80b06debcfdb718f2d jdk8-b71 +cb40427f47145b01b7e53c3e02b38ff7625efbda jdk8-b72 From 0adc452e4f6469982d4940bf204c4822f83566d8 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 10 Jan 2013 09:55:30 -0800 Subject: [PATCH 24/28] Added tag jdk8-b72 for changeset 371ef2925907 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index ea060b2d1f4..13706d68127 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -305,3 +305,4 @@ cb8a4e04bc8c104de8a2f67463c7e31232bf8d68 jdk8-b69 990bbd393c239d95310ccc38094e57923bbf1d4a hs25-b14 e94068d4ff52849c8aa0786a53a59b63d1312a39 jdk8-b70 0847210f85480bf3848dc90bc2ab23c0a4791b55 jdk8-b71 +d5cb5830f570d1304ea4b196dde672a291b55f29 jdk8-b72 From 49feba985e65a6a0ff7aa2446053c4532da9e908 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 10 Jan 2013 09:55:58 -0800 Subject: [PATCH 25/28] Added tag jdk8-b72 for changeset 21fe12436601 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 9ea50bcf6b8..a48294ba6ce 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -193,3 +193,4 @@ ce9b02a3a17edd1983201002cfa0f364e4ab7524 jdk8-b67 a8012d8d7e9c5035de0bdd4887dc9f7c54008f21 jdk8-b69 a996b57e554198f4592a5f3c30f2f9f4075e545d jdk8-b70 2a5af0f766d0acd68a81fb08fe11fd66795f86af jdk8-b71 +32a57e645e012a1f0665c075969ca598e0dbb948 jdk8-b72 From f7eb6cd55615feeda2c28cc38f800dbbfed996af Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Thu, 10 Jan 2013 10:21:44 -0800 Subject: [PATCH 26/28] 8005962: TEST_BUG: java/util/Properties/MacJNUEncoding can fail in certain environments Test script now sets LC_ALL, other small changes, relocate test Reviewed-by: naoto, alanb --- .../System}/MacJNUEncoding/ExpectedEncoding.java | 4 ++-- .../System}/MacJNUEncoding/MacJNUEncoding.sh | 14 ++++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) rename jdk/test/java/{util/Properties => lang/System}/MacJNUEncoding/ExpectedEncoding.java (97%) rename jdk/test/java/{util/Properties => lang/System}/MacJNUEncoding/MacJNUEncoding.sh (86%) diff --git a/jdk/test/java/util/Properties/MacJNUEncoding/ExpectedEncoding.java b/jdk/test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java similarity index 97% rename from jdk/test/java/util/Properties/MacJNUEncoding/ExpectedEncoding.java rename to jdk/test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java index b8835b8edb7..723d45c677f 100644 --- a/jdk/test/java/util/Properties/MacJNUEncoding/ExpectedEncoding.java +++ b/jdk/test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java @@ -31,6 +31,7 @@ public class ExpectedEncoding { if (args.length != 2) { System.out.println("Usage:"); System.out.println("$ java ExpectedEncoding "); + System.exit(1); } String expectFileEnc = args[0]; String expectSunJnuEnc = args[1]; @@ -49,8 +50,7 @@ public class ExpectedEncoding { failed = true; } if (failed) { - System.err.println("Test Failed"); - System.exit(1); + throw new RuntimeException("Test Failed"); } } } diff --git a/jdk/test/java/util/Properties/MacJNUEncoding/MacJNUEncoding.sh b/jdk/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh similarity index 86% rename from jdk/test/java/util/Properties/MacJNUEncoding/MacJNUEncoding.sh rename to jdk/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh index 0131467dba1..a03bdd91f17 100644 --- a/jdk/test/java/util/Properties/MacJNUEncoding/MacJNUEncoding.sh +++ b/jdk/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh @@ -63,14 +63,16 @@ echo "Building test classes..." "$JAVAC" -d "${TESTCLASSES}" "${TESTSRC}"/ExpectedEncoding.java echo "" -echo "Running test for LANG=C" +echo "Running test for C locale" export LANG=C +export LC_ALL=C "${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding US-ASCII UTF-8 result1=$? echo "" -echo "Running test for LANG=en_US.UTF-8" +echo "Running test for en_US.UTF-8 locale" export LANG=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 "${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding UTF-8 UTF-8 result2=$? @@ -79,11 +81,15 @@ echo "Cleanup" rm ${TESTCLASSES}/ExpectedEncoding.class if [ ${result1} -ne 0 ] ; then - echo "Test failed for LANG=C" + echo "Test failed for C locale" + echo " LANG=\"${LANG}\"" + echo " LC_ALL=\"${LC_ALL}\"" exit ${result1} fi if [ ${result2} -ne 0 ] ; then - echo "Test failed for LANG=en_US.UTF-8" + echo "Test failed for en_US.UTF-8 locale" + echo " LANG=\"${LANG}\"" + echo " LC_ALL=\"${LC_ALL}\"" exit ${result2} fi exit 0 From 5c5820e9508216b2aa71f5d778342c74d3604451 Mon Sep 17 00:00:00 2001 From: Jim Gish Date: Thu, 10 Jan 2013 15:09:45 -0500 Subject: [PATCH 27/28] 8005582: java/lang/Runtime/exec/WinCommand.java intermittent test failures Remove file-deletion code at cleanup which conflicts with jtreg cleanup Reviewed-by: chegar --- .../java/lang/Runtime/exec/WinCommand.java | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/jdk/test/java/lang/Runtime/exec/WinCommand.java b/jdk/test/java/lang/Runtime/exec/WinCommand.java index 77cfe67e40a..a812bffd135 100644 --- a/jdk/test/java/lang/Runtime/exec/WinCommand.java +++ b/jdk/test/java/lang/Runtime/exec/WinCommand.java @@ -135,24 +135,19 @@ public class WinCommand { // Win9x systems don't have a cmd.exe if (new File(systemDirW, "cmd.exe").exists()) { - try { - out.println("Running cmd.exe tests..."); - writeFile("cdcmd.cmd", "@echo off\r\nCD\r\n"); - writeFile("cdbat.bat", "@echo off\r\nCD\r\n"); - checkCD("cmd", - "cmd.exe", - systemDirW + "\\cmd.exe", - // Only the ".exe" extension can be omitted - systemDirW + "\\cmd", - systemDirM + "/cmd.exe", - systemDirM + "/cmd", - "/" + systemDirM + "/cmd", - "cdcmd.cmd", "./cdcmd.cmd", ".\\cdcmd.cmd", - "cdbat.bat", "./cdbat.bat", ".\\cdbat.bat"); - } finally { - new File("cdcmd.cmd").delete(); - new File("cdbat.bat").delete(); - } + out.println("Running cmd.exe tests..."); + writeFile("cdcmd.cmd", "@echo off\r\nCD\r\n"); + writeFile("cdbat.bat", "@echo off\r\nCD\r\n"); + checkCD("cmd", + "cmd.exe", + systemDirW + "\\cmd.exe", + // Only the ".exe" extension can be omitted + systemDirW + "\\cmd", + systemDirM + "/cmd.exe", + systemDirM + "/cmd", + "/" + systemDirM + "/cmd", + "cdcmd.cmd", "./cdcmd.cmd", ".\\cdcmd.cmd", + "cdbat.bat", "./cdbat.bat", ".\\cdbat.bat"); } // 16-bit apps like command.com must have a console; From a2dea4d9f4c6260f0dfb868748915632d7804c66 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Thu, 10 Jan 2013 21:52:38 +0000 Subject: [PATCH 28/28] 8006007: j.u.c.atomic classes should use intrinsic getAndXXX provided by 7023898 Reviewed-by: dl, shade --- .../util/concurrent/atomic/AtomicBoolean.java | 14 +-- .../util/concurrent/atomic/AtomicInteger.java | 52 ++------ .../concurrent/atomic/AtomicIntegerArray.java | 28 +---- .../atomic/AtomicIntegerFieldUpdater.java | 112 ++++++++++------- .../util/concurrent/atomic/AtomicLong.java | 52 ++------ .../concurrent/atomic/AtomicLongArray.java | 28 +---- .../atomic/AtomicLongFieldUpdater.java | 116 +++++++++++------- .../concurrent/atomic/AtomicReference.java | 11 +- .../atomic/AtomicReferenceArray.java | 10 +- .../atomic/AtomicReferenceFieldUpdater.java | 23 ++-- 10 files changed, 204 insertions(+), 242 deletions(-) diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java index a4d6d8297da..04bc975f9c8 100644 --- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java +++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java @@ -111,7 +111,7 @@ public class AtomicBoolean implements java.io.Serializable { * * @param expect the expected value * @param update the new value - * @return true if successful. + * @return true if successful */ public boolean weakCompareAndSet(boolean expect, boolean update) { int e = expect ? 1 : 0; @@ -146,16 +146,16 @@ public class AtomicBoolean implements java.io.Serializable { * @return the previous value */ public final boolean getAndSet(boolean newValue) { - for (;;) { - boolean current = get(); - if (compareAndSet(current, newValue)) - return current; - } + boolean prev; + do { + prev = get(); + } while (!compareAndSet(prev, newValue)); + return prev; } /** * Returns the String representation of the current value. - * @return the String representation of the current value. + * @return the String representation of the current value */ public String toString() { return Boolean.toString(get()); diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java index 0d509cda035..f1c76b02bff 100644 --- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java +++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java @@ -115,11 +115,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { * @return the previous value */ public final int getAndSet(int newValue) { - for (;;) { - int current = get(); - if (compareAndSet(current, newValue)) - return current; - } + return unsafe.getAndSetInt(this, valueOffset, newValue); } /** @@ -145,7 +141,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { * * @param expect the expected value * @param update the new value - * @return true if successful. + * @return true if successful */ public final boolean weakCompareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); @@ -157,12 +153,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { * @return the previous value */ public final int getAndIncrement() { - for (;;) { - int current = get(); - int next = current + 1; - if (compareAndSet(current, next)) - return current; - } + return getAndAdd(1); } /** @@ -171,12 +162,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { * @return the previous value */ public final int getAndDecrement() { - for (;;) { - int current = get(); - int next = current - 1; - if (compareAndSet(current, next)) - return current; - } + return getAndAdd(-1); } /** @@ -186,12 +172,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { * @return the previous value */ public final int getAndAdd(int delta) { - for (;;) { - int current = get(); - int next = current + delta; - if (compareAndSet(current, next)) - return current; - } + return unsafe.getAndAddInt(this, valueOffset, delta); } /** @@ -200,12 +181,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { * @return the updated value */ public final int incrementAndGet() { - for (;;) { - int current = get(); - int next = current + 1; - if (compareAndSet(current, next)) - return next; - } + return getAndAdd(1) + 1; } /** @@ -214,12 +190,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { * @return the updated value */ public final int decrementAndGet() { - for (;;) { - int current = get(); - int next = current - 1; - if (compareAndSet(current, next)) - return next; - } + return getAndAdd(-1) - 1; } /** @@ -229,17 +200,12 @@ public class AtomicInteger extends Number implements java.io.Serializable { * @return the updated value */ public final int addAndGet(int delta) { - for (;;) { - int current = get(); - int next = current + delta; - if (compareAndSet(current, next)) - return next; - } + return getAndAdd(delta) + delta; } /** * Returns the String representation of the current value. - * @return the String representation of the current value. + * @return the String representation of the current value */ public String toString() { return Integer.toString(get()); diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java index 9928e5974fa..b5578ed93d8 100644 --- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java +++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java @@ -145,12 +145,7 @@ public class AtomicIntegerArray implements java.io.Serializable { * @return the previous value */ public final int getAndSet(int i, int newValue) { - long offset = checkedByteOffset(i); - while (true) { - int current = getRaw(offset); - if (compareAndSetRaw(offset, current, newValue)) - return current; - } + return unsafe.getAndSetInt(array, checkedByteOffset(i), newValue); } /** @@ -182,7 +177,7 @@ public class AtomicIntegerArray implements java.io.Serializable { * @param i the index * @param expect the expected value * @param update the new value - * @return true if successful. + * @return true if successful */ public final boolean weakCompareAndSet(int i, int expect, int update) { return compareAndSet(i, expect, update); @@ -216,12 +211,7 @@ public class AtomicIntegerArray implements java.io.Serializable { * @return the previous value */ public final int getAndAdd(int i, int delta) { - long offset = checkedByteOffset(i); - while (true) { - int current = getRaw(offset); - if (compareAndSetRaw(offset, current, current + delta)) - return current; - } + return unsafe.getAndAddInt(array, checkedByteOffset(i), delta); } /** @@ -231,7 +221,7 @@ public class AtomicIntegerArray implements java.io.Serializable { * @return the updated value */ public final int incrementAndGet(int i) { - return addAndGet(i, 1); + return getAndAdd(i, 1) + 1; } /** @@ -241,7 +231,7 @@ public class AtomicIntegerArray implements java.io.Serializable { * @return the updated value */ public final int decrementAndGet(int i) { - return addAndGet(i, -1); + return getAndAdd(i, -1) - 1; } /** @@ -252,13 +242,7 @@ public class AtomicIntegerArray implements java.io.Serializable { * @return the updated value */ public final int addAndGet(int i, int delta) { - long offset = checkedByteOffset(i); - while (true) { - int current = getRaw(offset); - int next = current + delta; - if (compareAndSetRaw(offset, current, next)) - return next; - } + return getAndAdd(i, delta) + delta; } /** diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java index a692479ad9c..e2ae9c4f5dd 100644 --- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java +++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java @@ -159,11 +159,11 @@ public abstract class AtomicIntegerFieldUpdater { * @return the previous value */ public int getAndSet(T obj, int newValue) { - for (;;) { - int current = get(obj); - if (compareAndSet(obj, current, newValue)) - return current; - } + int prev; + do { + prev = get(obj); + } while (!compareAndSet(obj, prev, newValue)); + return prev; } /** @@ -174,12 +174,12 @@ public abstract class AtomicIntegerFieldUpdater { * @return the previous value */ public int getAndIncrement(T obj) { - for (;;) { - int current = get(obj); - int next = current + 1; - if (compareAndSet(obj, current, next)) - return current; - } + int prev, next; + do { + prev = get(obj); + next = prev + 1; + } while (!compareAndSet(obj, prev, next)); + return prev; } /** @@ -190,12 +190,12 @@ public abstract class AtomicIntegerFieldUpdater { * @return the previous value */ public int getAndDecrement(T obj) { - for (;;) { - int current = get(obj); - int next = current - 1; - if (compareAndSet(obj, current, next)) - return current; - } + int prev, next; + do { + prev = get(obj); + next = prev - 1; + } while (!compareAndSet(obj, prev, next)); + return prev; } /** @@ -207,12 +207,12 @@ public abstract class AtomicIntegerFieldUpdater { * @return the previous value */ public int getAndAdd(T obj, int delta) { - for (;;) { - int current = get(obj); - int next = current + delta; - if (compareAndSet(obj, current, next)) - return current; - } + int prev, next; + do { + prev = get(obj); + next = prev + delta; + } while (!compareAndSet(obj, prev, next)); + return prev; } /** @@ -223,12 +223,12 @@ public abstract class AtomicIntegerFieldUpdater { * @return the updated value */ public int incrementAndGet(T obj) { - for (;;) { - int current = get(obj); - int next = current + 1; - if (compareAndSet(obj, current, next)) - return next; - } + int prev, next; + do { + prev = get(obj); + next = prev + 1; + } while (!compareAndSet(obj, prev, next)); + return next; } /** @@ -239,12 +239,12 @@ public abstract class AtomicIntegerFieldUpdater { * @return the updated value */ public int decrementAndGet(T obj) { - for (;;) { - int current = get(obj); - int next = current - 1; - if (compareAndSet(obj, current, next)) - return next; - } + int prev, next; + do { + prev = get(obj); + next = prev - 1; + } while (!compareAndSet(obj, prev, next)); + return next; } /** @@ -256,12 +256,12 @@ public abstract class AtomicIntegerFieldUpdater { * @return the updated value */ public int addAndGet(T obj, int delta) { - for (;;) { - int current = get(obj); - int next = current + delta; - if (compareAndSet(obj, current, next)) - return next; - } + int prev, next; + do { + prev = get(obj); + next = prev + delta; + } while (!compareAndSet(obj, prev, next)); + return next; } /** @@ -361,6 +361,36 @@ public abstract class AtomicIntegerFieldUpdater { return unsafe.getIntVolatile(obj, offset); } + public int getAndSet(T obj, int newValue) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + return unsafe.getAndSetInt(obj, offset, newValue); + } + + public int getAndIncrement(T obj) { + return getAndAdd(obj, 1); + } + + public int getAndDecrement(T obj) { + return getAndAdd(obj, -1); + } + + public int getAndAdd(T obj, int delta) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + return unsafe.getAndAddInt(obj, offset, delta); + } + + public int incrementAndGet(T obj) { + return getAndAdd(obj, 1) + 1; + } + + public int decrementAndGet(T obj) { + return getAndAdd(obj, -1) - 1; + } + + public int addAndGet(T obj, int delta) { + return getAndAdd(obj, delta) + delta; + } + private void ensureProtectedAccess(T obj) { if (cclass.isInstance(obj)) { return; diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java index 7813aad04f4..b38cf041fbb 100644 --- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java +++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java @@ -129,11 +129,7 @@ public class AtomicLong extends Number implements java.io.Serializable { * @return the previous value */ public final long getAndSet(long newValue) { - while (true) { - long current = get(); - if (compareAndSet(current, newValue)) - return current; - } + return unsafe.getAndSetLong(this, valueOffset, newValue); } /** @@ -159,7 +155,7 @@ public class AtomicLong extends Number implements java.io.Serializable { * * @param expect the expected value * @param update the new value - * @return true if successful. + * @return true if successful */ public final boolean weakCompareAndSet(long expect, long update) { return unsafe.compareAndSwapLong(this, valueOffset, expect, update); @@ -171,12 +167,7 @@ public class AtomicLong extends Number implements java.io.Serializable { * @return the previous value */ public final long getAndIncrement() { - while (true) { - long current = get(); - long next = current + 1; - if (compareAndSet(current, next)) - return current; - } + return getAndAdd(1); } /** @@ -185,12 +176,7 @@ public class AtomicLong extends Number implements java.io.Serializable { * @return the previous value */ public final long getAndDecrement() { - while (true) { - long current = get(); - long next = current - 1; - if (compareAndSet(current, next)) - return current; - } + return getAndAdd(-1); } /** @@ -200,12 +186,7 @@ public class AtomicLong extends Number implements java.io.Serializable { * @return the previous value */ public final long getAndAdd(long delta) { - while (true) { - long current = get(); - long next = current + delta; - if (compareAndSet(current, next)) - return current; - } + return unsafe.getAndAddLong(this, valueOffset, delta); } /** @@ -214,12 +195,7 @@ public class AtomicLong extends Number implements java.io.Serializable { * @return the updated value */ public final long incrementAndGet() { - for (;;) { - long current = get(); - long next = current + 1; - if (compareAndSet(current, next)) - return next; - } + return getAndAdd(1) + 1; } /** @@ -228,12 +204,7 @@ public class AtomicLong extends Number implements java.io.Serializable { * @return the updated value */ public final long decrementAndGet() { - for (;;) { - long current = get(); - long next = current - 1; - if (compareAndSet(current, next)) - return next; - } + return getAndAdd(-1) - 1; } /** @@ -243,17 +214,12 @@ public class AtomicLong extends Number implements java.io.Serializable { * @return the updated value */ public final long addAndGet(long delta) { - for (;;) { - long current = get(); - long next = current + delta; - if (compareAndSet(current, next)) - return next; - } + return getAndAdd(delta) + delta; } /** * Returns the String representation of the current value. - * @return the String representation of the current value. + * @return the String representation of the current value */ public String toString() { return Long.toString(get()); 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 856ab39e0c6..9651426c750 100644 --- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java +++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java @@ -144,12 +144,7 @@ public class AtomicLongArray implements java.io.Serializable { * @return the previous value */ public final long getAndSet(int i, long newValue) { - long offset = checkedByteOffset(i); - while (true) { - long current = getRaw(offset); - if (compareAndSetRaw(offset, current, newValue)) - return current; - } + return unsafe.getAndSetLong(array, checkedByteOffset(i), newValue); } /** @@ -181,7 +176,7 @@ public class AtomicLongArray implements java.io.Serializable { * @param i the index * @param expect the expected value * @param update the new value - * @return true if successful. + * @return true if successful */ public final boolean weakCompareAndSet(int i, long expect, long update) { return compareAndSet(i, expect, update); @@ -215,12 +210,7 @@ public class AtomicLongArray implements java.io.Serializable { * @return the previous value */ public final long getAndAdd(int i, long delta) { - long offset = checkedByteOffset(i); - while (true) { - long current = getRaw(offset); - if (compareAndSetRaw(offset, current, current + delta)) - return current; - } + return unsafe.getAndAddLong(array, checkedByteOffset(i), delta); } /** @@ -230,7 +220,7 @@ public class AtomicLongArray implements java.io.Serializable { * @return the updated value */ public final long incrementAndGet(int i) { - return addAndGet(i, 1); + return getAndAdd(i, 1) + 1; } /** @@ -240,7 +230,7 @@ public class AtomicLongArray implements java.io.Serializable { * @return the updated value */ public final long decrementAndGet(int i) { - return addAndGet(i, -1); + return getAndAdd(i, -1) - 1; } /** @@ -251,13 +241,7 @@ public class AtomicLongArray implements java.io.Serializable { * @return the updated value */ public long addAndGet(int i, long delta) { - long offset = checkedByteOffset(i); - while (true) { - long current = getRaw(offset); - long next = current + delta; - if (compareAndSetRaw(offset, current, next)) - return next; - } + return getAndAdd(i, delta) + delta; } /** diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java index 8b80684d848..a013680ce7a 100644 --- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java +++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java @@ -98,7 +98,7 @@ public abstract class AtomicLongFieldUpdater { * @param obj An object whose field to conditionally set * @param expect the expected value * @param update the new value - * @return true if successful. + * @return true if successful * @throws ClassCastException if {@code obj} is not an instance * of the class possessing the field established in the constructor. */ @@ -118,7 +118,7 @@ public abstract class AtomicLongFieldUpdater { * @param obj An object whose field to conditionally set * @param expect the expected value * @param update the new value - * @return true if successful. + * @return true if successful * @throws ClassCastException if {@code obj} is not an instance * of the class possessing the field established in the constructor. */ @@ -162,11 +162,11 @@ public abstract class AtomicLongFieldUpdater { * @return the previous value */ public long getAndSet(T obj, long newValue) { - for (;;) { - long current = get(obj); - if (compareAndSet(obj, current, newValue)) - return current; - } + long prev; + do { + prev = get(obj); + } while (!compareAndSet(obj, prev, newValue)); + return prev; } /** @@ -177,12 +177,12 @@ public abstract class AtomicLongFieldUpdater { * @return the previous value */ public long getAndIncrement(T obj) { - for (;;) { - long current = get(obj); - long next = current + 1; - if (compareAndSet(obj, current, next)) - return current; - } + long prev, next; + do { + prev = get(obj); + next = prev + 1; + } while (!compareAndSet(obj, prev, next)); + return prev; } /** @@ -193,12 +193,12 @@ public abstract class AtomicLongFieldUpdater { * @return the previous value */ public long getAndDecrement(T obj) { - for (;;) { - long current = get(obj); - long next = current - 1; - if (compareAndSet(obj, current, next)) - return current; - } + long prev, next; + do { + prev = get(obj); + next = prev - 1; + } while (!compareAndSet(obj, prev, next)); + return prev; } /** @@ -210,12 +210,12 @@ public abstract class AtomicLongFieldUpdater { * @return the previous value */ public long getAndAdd(T obj, long delta) { - for (;;) { - long current = get(obj); - long next = current + delta; - if (compareAndSet(obj, current, next)) - return current; - } + long prev, next; + do { + prev = get(obj); + next = prev + delta; + } while (!compareAndSet(obj, prev, next)); + return prev; } /** @@ -226,12 +226,12 @@ public abstract class AtomicLongFieldUpdater { * @return the updated value */ public long incrementAndGet(T obj) { - for (;;) { - long current = get(obj); - long next = current + 1; - if (compareAndSet(obj, current, next)) - return next; - } + long prev, next; + do { + prev = get(obj); + next = prev + 1; + } while (!compareAndSet(obj, prev, next)); + return next; } /** @@ -242,12 +242,12 @@ public abstract class AtomicLongFieldUpdater { * @return the updated value */ public long decrementAndGet(T obj) { - for (;;) { - long current = get(obj); - long next = current - 1; - if (compareAndSet(obj, current, next)) - return next; - } + long prev, next; + do { + prev = get(obj); + next = prev - 1; + } while (!compareAndSet(obj, prev, next)); + return next; } /** @@ -259,12 +259,12 @@ public abstract class AtomicLongFieldUpdater { * @return the updated value */ public long addAndGet(T obj, long delta) { - for (;;) { - long current = get(obj); - long next = current + delta; - if (compareAndSet(obj, current, next)) - return next; - } + long prev, next; + do { + prev = get(obj); + next = prev + delta; + } while (!compareAndSet(obj, prev, next)); + return next; } private static class CASUpdater extends AtomicLongFieldUpdater { @@ -345,6 +345,36 @@ public abstract class AtomicLongFieldUpdater { return unsafe.getLongVolatile(obj, offset); } + public long getAndSet(T obj, long newValue) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + return unsafe.getAndSetLong(obj, offset, newValue); + } + + public long getAndIncrement(T obj) { + return getAndAdd(obj, 1); + } + + public long getAndDecrement(T obj) { + return getAndAdd(obj, -1); + } + + public long getAndAdd(T obj, long delta) { + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + return unsafe.getAndAddLong(obj, offset, delta); + } + + public long incrementAndGet(T obj) { + return getAndAdd(obj, 1) + 1; + } + + public long decrementAndGet(T obj) { + return getAndAdd(obj, -1) - 1; + } + + public long addAndGet(T obj, long delta) { + return getAndAdd(obj, delta) + delta; + } + private void ensureProtectedAccess(T obj) { if (cclass.isInstance(obj)) { return; diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java index 8bbc25c696e..94c9edca52a 100644 --- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java +++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java @@ -124,7 +124,7 @@ public class AtomicReference implements java.io.Serializable { * * @param expect the expected value * @param update the new value - * @return true if successful. + * @return true if successful */ public final boolean weakCompareAndSet(V expect, V update) { return unsafe.compareAndSwapObject(this, valueOffset, expect, update); @@ -136,17 +136,14 @@ public class AtomicReference implements java.io.Serializable { * @param newValue the new value * @return the previous value */ + @SuppressWarnings("unchecked") public final V getAndSet(V newValue) { - while (true) { - V x = get(); - if (compareAndSet(x, newValue)) - return x; - } + return (V)unsafe.getAndSetObject(this, valueOffset, newValue); } /** * Returns the String representation of the current value. - * @return the String representation of the current value. + * @return the String representation of the current value */ public String toString() { return String.valueOf(get()); diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java index 015523ff393..71308618541 100644 --- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java +++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java @@ -159,13 +159,9 @@ public class AtomicReferenceArray implements java.io.Serializable { * @param newValue the new value * @return the previous value */ + @SuppressWarnings("unchecked") public final E getAndSet(int i, E newValue) { - long offset = checkedByteOffset(i); - while (true) { - E current = getRaw(offset); - if (compareAndSetRaw(offset, current, newValue)) - return current; - } + return (E)unsafe.getAndSetObject(array, checkedByteOffset(i), newValue); } /** @@ -197,7 +193,7 @@ public class AtomicReferenceArray implements java.io.Serializable { * @param i the index * @param expect the expected value * @param update the new value - * @return true if successful. + * @return true if successful */ public final boolean weakCompareAndSet(int i, E expect, E update) { return compareAndSet(i, expect, update); diff --git a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java index 2bb1fae40d7..78c636956f6 100644 --- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java +++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java @@ -116,7 +116,7 @@ public abstract class AtomicReferenceFieldUpdater { * @param obj An object whose field to conditionally set * @param expect the expected value * @param update the new value - * @return true if successful. + * @return true if successful */ public abstract boolean compareAndSet(T obj, V expect, V update); @@ -134,7 +134,7 @@ public abstract class AtomicReferenceFieldUpdater { * @param obj An object whose field to conditionally set * @param expect the expected value * @param update the new value - * @return true if successful. + * @return true if successful */ public abstract boolean weakCompareAndSet(T obj, V expect, V update); @@ -176,11 +176,11 @@ public abstract class AtomicReferenceFieldUpdater { * @return the previous value */ public V getAndSet(T obj, V newValue) { - for (;;) { - V current = get(obj); - if (compareAndSet(obj, current, newValue)) - return current; - } + V prev; + do { + prev = get(obj); + } while (!compareAndSet(obj, prev, newValue)); + return prev; } private static final class AtomicReferenceFieldUpdaterImpl @@ -321,6 +321,15 @@ public abstract class AtomicReferenceFieldUpdater { return (V)unsafe.getObjectVolatile(obj, offset); } + @SuppressWarnings("unchecked") + public V getAndSet(T obj, V newValue) { + if (obj == null || obj.getClass() != tclass || cclass != null || + (newValue != null && vclass != null && + vclass != newValue.getClass())) + updateCheck(obj, newValue); + return (V)unsafe.getAndSetObject(obj, offset, newValue); + } + private void ensureProtectedAccess(T obj) { if (cclass.isInstance(obj)) { return;