diff --git a/.hgtags b/.hgtags index 7f1a9ea9d24..937c2a48f74 100644 --- a/.hgtags +++ b/.hgtags @@ -108,3 +108,6 @@ a36beda9b9de91231d92a2c529f21cc218fcf8d5 jdk7-b130 d8af56da89bc0fc02a6b6ad78f51157a46d665ab jdk7-b131 d61280d36755d1941fb487f554e8b7a6d0bca6a1 jdk7-b132 fd444c61e7ed3d92b2a730da7c737b02191b682f jdk7-b133 +def8e16dd237a47fc067d66d4c616d7baaec6001 jdk7-b134 +f75a1efb141210901aabe00a834e0fc32bb8b337 jdk7-b135 +46acf76a533954cfd594bb88fdea79938abfbe20 jdk7-b136 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 78852de5bad..8d5bee022fb 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -109,3 +109,5 @@ cc58c11af15411042719e9c82707fdbef60a9e0f jdk7-b130 0f62a65fb666b337caa585015ab6ea2e60e709ca jdk7-b132 c6f380693342feadccc5fe2c5adf500e861361aa jdk7-b133 ddc2fcb3682ffd27f44354db666128827be7e3c3 jdk7-b134 +783bd02b4ab4596059c74b10a1793d7bd2f1c157 jdk7-b135 +2fe76e73adaa5133ac559f0b3c2c0707eca04580 jdk7-b136 diff --git a/README b/README index 722131d683f..db7346b4432 100644 --- a/README +++ b/README @@ -29,13 +29,14 @@ Simple Build Instructions: Set the environment variable ALT_BOOTDIR to the location of JDK 6. 2. Check the sanity of doing a build with your current system: - gnumake sanity + make sanity See README-builds.html if you run into problems. 3. Do a complete build of the OpenJDK: - gnumake all + make all The resulting JDK image should be found in build/*/j2sdk-image -where gnumake is GNU make 3.81 or newer, /usr/bin/make on Linux and -/usr/sfw/bin/gmake or /opt/sfw/bin/gmake on Solaris. +where make is GNU make 3.81 or newer, /usr/bin/make on Linux usually +is 3.81 or newer. +Complete details are available in README-builds.html. diff --git a/README-builds.html b/README-builds.html index b59457c74ab..87b7cd80af2 100644 --- a/README-builds.html +++ b/README-builds.html @@ -54,7 +54,11 @@
  • OpenSolaris
  • -
  • Source Directory Structure
  • +
  • Source Directory Structure + +
  • Build Information @@ -309,7 +295,7 @@ *

    * In an application which requires dynamic call sites with individually * mutable behaviors, their bootstrap methods should produce distinct - * {@link java.dyn.CallSite CallSite} objects, one for each linkage request. + * {@link java.lang.invoke.CallSite CallSite} objects, one for each linkage request. * Alternatively, an application can link a single {@code CallSite} object * to several {@code invokedynamic} instructions, in which case * a change to the target method will become visible at each of @@ -322,11 +308,12 @@ * chosen target object. * *

    - * Historic Note: Unlike some previous versions of this specification, - * these rules do not enable the JVM to duplicate dynamic call sites, + * Discussion: + * These rules do not enable the JVM to duplicate dynamic call sites, * or to issue “causeless” bootstrap method calls. * Every dynamic call site transitions at most once from unlinked to linked, * just before its first invocation. + * There is no way to undo the effect of a completed bootstrap method call. * *

    the {@code BootstrapMethods} attribute

    * Each {@code CONSTANT_InvokeDynamic} entry contains an index which references @@ -354,7 +341,7 @@ *

    static arguments to the bootstrap method

    * An {@code invokedynamic} instruction specifies at least three arguments * to pass to its bootstrap method: - * The caller class (expressed as a {@link java.dyn.MethodHandles.Lookup Lookup object}, + * The caller class (expressed as a {@link java.lang.invoke.MethodHandles.Lookup Lookup object}, * the name (extracted from the {@code CONSTANT_NameAndType} entry), * and the type (also extracted from the {@code CONSTANT_NameAndType} entry). * The {@code invokedynamic} instruction may specify additional metadata values @@ -382,8 +369,8 @@ * CONSTANT_Longjava.lang.Longthe indexed long value * CONSTANT_Floatjava.lang.Floatthe indexed float value * CONSTANT_Doublejava.lang.Doublethe indexed double value - * CONSTANT_MethodHandlejava.dyn.MethodHandlethe indexed method handle constant - * CONSTANT_MethodTypejava.dyn.MethodTypethe indexed method type constant + * CONSTANT_MethodHandlejava.lang.invoke.MethodHandlethe indexed method handle constant + * CONSTANT_MethodTypejava.lang.invoke.MethodTypethe indexed method type constant * * *

    @@ -403,7 +390,7 @@ * then some or all of the arguments specified here may be collected into a trailing array parameter. * (This is not a special rule, but rather a useful consequence of the interaction * between {@code CONSTANT_MethodHandle} constants, the modifier bit for variable arity methods, - * and the {@code java.dyn.MethodHandle#asVarargsCollector asVarargsCollector} transformation.) + * and the {@code java.lang.invoke.MethodHandle#asVarargsCollector asVarargsCollector} transformation.) *

    * Given these rules, here are examples of legal bootstrap method declarations, * given various numbers {@code N} of extra arguments. @@ -436,7 +423,7 @@ * constant as an {@code Object}, but the type matching machinery of {@code invokeGeneric} * will cast the reference back to {@code MethodHandle} before invoking the bootstrap method. * (If a string constant were passed instead, by badly generated code, that cast would then fail, - * resulting in an {@code InvokeDynamicBootstrapError}.) + * resulting in a {@code BootstrapMethodError}.) *

    * Extra bootstrap method arguments are intended to allow language implementors * to safely and compactly encode metadata. @@ -473,6 +460,7 @@ struct BootstrapMethods_attr { * * * @author John Rose, JSR 292 EG + * @since 1.7 */ -package java.dyn; +package java.lang.invoke; diff --git a/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java b/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java index 522fa3956b9..004cd408110 100644 --- a/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java +++ b/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java @@ -28,6 +28,7 @@ import java.io.FileDescriptor; import java.io.IOException; import java.io.InterruptedIOException; import java.util.Enumeration; +import sun.net.ResourceManager; /** * Abstract datagram and multicast socket implementation base class. @@ -66,7 +67,14 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl */ protected synchronized void create() throws SocketException { fd = new FileDescriptor(); - datagramSocketCreate(); + ResourceManager.beforeUdpCreate(); + try { + datagramSocketCreate(); + } catch (SocketException ioe) { + ResourceManager.afterUdpClose(); + fd = null; + throw ioe; + } } /** @@ -211,6 +219,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl protected void close() { if (fd != null) { datagramSocketClose(); + ResourceManager.afterUdpClose(); fd = null; } } diff --git a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java index 6d73cbc242c..f61fb34bdf1 100644 --- a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java +++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java @@ -32,6 +32,7 @@ import java.io.FileDescriptor; import sun.net.ConnectionResetException; import sun.net.NetHooks; +import sun.net.ResourceManager; /** * Default Socket Implementation. This implementation does @@ -68,6 +69,10 @@ abstract class AbstractPlainSocketImpl extends SocketImpl private int resetState; private final Object resetLock = new Object(); + /* whether this Socket is a stream (TCP) socket or not (UDP) + */ + private boolean stream; + /** * Load net library into runtime. */ @@ -82,7 +87,19 @@ abstract class AbstractPlainSocketImpl extends SocketImpl */ protected synchronized void create(boolean stream) throws IOException { fd = new FileDescriptor(); - socketCreate(stream); + this.stream = stream; + if (!stream) { + ResourceManager.beforeUdpCreate(); + try { + socketCreate(false); + } catch (IOException ioe) { + ResourceManager.afterUdpClose(); + fd = null; + throw ioe; + } + } else { + socketCreate(true); + } if (socket != null) socket.setCreated(); if (serverSocket != null) @@ -479,6 +496,9 @@ abstract class AbstractPlainSocketImpl extends SocketImpl protected void close() throws IOException { synchronized(fdLock) { if (fd != null) { + if (!stream) { + ResourceManager.afterUdpClose(); + } if (fdUseCount == 0) { if (closePending) { return; diff --git a/jdk/src/share/classes/java/net/URI.java b/jdk/src/share/classes/java/net/URI.java index 3465e1ab879..d1d9a87189a 100644 --- a/jdk/src/share/classes/java/net/URI.java +++ b/jdk/src/share/classes/java/net/URI.java @@ -1829,21 +1829,23 @@ public final class URI } else if (authority != null) { sb.append("//"); if (authority.startsWith("[")) { + // authority should (but may not) contain an embedded IPv6 address int end = authority.indexOf("]"); - if (end != -1 && authority.indexOf(":")!=-1) { - String doquote, dontquote; + String doquote = authority, dontquote = ""; + if (end != -1 && authority.indexOf(":") != -1) { + // the authority contains an IPv6 address if (end == authority.length()) { dontquote = authority; doquote = ""; } else { - dontquote = authority.substring(0,end+1); - doquote = authority.substring(end+1); + dontquote = authority.substring(0 , end + 1); + doquote = authority.substring(end + 1); } - sb.append (dontquote); - sb.append(quote(doquote, + } + sb.append(dontquote); + sb.append(quote(doquote, L_REG_NAME | L_SERVER, H_REG_NAME | H_SERVER)); - } } else { sb.append(quote(authority, L_REG_NAME | L_SERVER, diff --git a/jdk/src/share/classes/java/net/URLConnection.java b/jdk/src/share/classes/java/net/URLConnection.java index 6db1f6e82b3..976e8f66cea 100644 --- a/jdk/src/share/classes/java/net/URLConnection.java +++ b/jdk/src/share/classes/java/net/URLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -1422,7 +1422,7 @@ public abstract class URLConnection { if (!is.markSupported()) return null; - is.mark(12); + is.mark(16); int c1 = is.read(); int c2 = is.read(); int c3 = is.read(); @@ -1434,6 +1434,11 @@ public abstract class URLConnection { int c9 = is.read(); int c10 = is.read(); int c11 = is.read(); + int c12 = is.read(); + int c13 = is.read(); + int c14 = is.read(); + int c15 = is.read(); + int c16 = is.read(); is.reset(); if (c1 == 0xCA && c2 == 0xFE && c3 == 0xBA && c4 == 0xBE) { @@ -1461,6 +1466,13 @@ public abstract class URLConnection { } } + // big and little (identical) endian UTF-8 encodings, with BOM + if (c1 == 0xef && c2 == 0xbb && c3 == 0xbf) { + if (c4 == '<' && c5 == '?' && c6 == 'x') { + return "application/xml"; + } + } + // big and little endian UTF-16 encodings, with byte order mark if (c1 == 0xfe && c2 == 0xff) { if (c3 == 0 && c4 == '<' && c5 == 0 && c6 == '?' && @@ -1476,6 +1488,23 @@ public abstract class URLConnection { } } + // big and little endian UTF-32 encodings, with BOM + if (c1 == 0x00 && c2 == 0x00 && c3 == 0xfe && c4 == 0xff) { + if (c5 == 0 && c6 == 0 && c7 == 0 && c8 == '<' && + c9 == 0 && c10 == 0 && c11 == 0 && c12 == '?' && + c13 == 0 && c14 == 0 && c15 == 0 && c16 == 'x') { + return "application/xml"; + } + } + + if (c1 == 0xff && c2 == 0xfe && c3 == 0x00 && c4 == 0x00) { + if (c5 == '<' && c6 == 0 && c7 == 0 && c8 == 0 && + c9 == '?' && c10 == 0 && c11 == 0 && c12 == 0 && + c13 == 'x' && c14 == 0 && c15 == 0 && c16 == 0) { + return "application/xml"; + } + } + if (c1 == 'G' && c2 == 'I' && c3 == 'F' && c4 == '8') { return "image/gif"; } diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java index 3e19ca3e515..8b7af13544c 100644 --- a/jdk/src/share/classes/java/nio/file/Files.java +++ b/jdk/src/share/classes/java/nio/file/Files.java @@ -1712,10 +1712,10 @@ public final class Files { * @return the {@code path} parameter * * @throws UnsupportedOperationException - * if the attribute view is not available or it does not support - * updating the attribute + * if the attribute view is not available * @throws IllegalArgumentException - * if the attribute value is of the correct type but has an + * if the attribute name is not specified, or is not recognized, or + * the attribute value is of the correct type but has an * inappropriate value * @throws ClassCastException * if the attribute value is not of the expected type or is a @@ -1776,9 +1776,12 @@ public final class Files { * @param options * options indicating how symbolic links are handled * - * @return the attribute value or {@code null} if the attribute view - * is not available or it does not support reading the attribute + * @return the attribute value * + * @throws UnsupportedOperationException + * if the attribute view is not available + * @throws IllegalArgumentException + * if the attribute name is not specified or is not recognized * @throws IOException * if an I/O error occurs * @throws SecurityException @@ -1794,8 +1797,9 @@ public final class Files { { // only one attribute should be read if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0) - return null; + throw new IllegalArgumentException(attribute); Map map = readAttributes(path, attribute, options); + assert map.size() == 1; String name; int pos = attribute.indexOf(':'); if (pos == -1) { @@ -1868,9 +1872,14 @@ public final class Files { * @param options * options indicating how symbolic links are handled * - * @return a map of the attributes returned; may be empty. The map's keys - * are the attribute names, its values are the attribute values + * @return a map of the attributes returned; The map's keys are the + * attribute names, its values are the attribute values * + * @throws UnsupportedOperationException + * if the attribute view is not available + * @throws IllegalArgumentException + * if no attributes are specified or an unrecognized attributes is + * specified * @throws IOException * if an I/O error occurs * @throws SecurityException diff --git a/jdk/src/share/classes/java/nio/file/Path.java b/jdk/src/share/classes/java/nio/file/Path.java index 85436b01d9a..618f0226363 100644 --- a/jdk/src/share/classes/java/nio/file/Path.java +++ b/jdk/src/share/classes/java/nio/file/Path.java @@ -228,6 +228,9 @@ public interface Path * not have a root component and the given path has a root component then * this path does not start with the given path. * + *

    If the given path is associated with a different {@code FileSystem} + * to this path then {@code false} is returned. + * * @param other * the given path * @@ -270,6 +273,9 @@ public interface Path * does not have a root component and the given path has a root component * then this path does not end with the given path. * + *

    If the given path is associated with a different {@code FileSystem} + * to this path then {@code false} is returned. + * * @param other * the given path * @@ -283,7 +289,10 @@ public interface Path * the given path string, in exactly the manner specified by the {@link * #endsWith(Path) endsWith(Path)} method. On UNIX for example, the path * "{@code foo/bar}" ends with "{@code foo/bar}" and "{@code bar}". It does - * not end with "{@code r}" or "{@code /bar}". + * not end with "{@code r}" or "{@code /bar}". Note that trailing separators + * are not taken into account, and so invoking this method on the {@code + * Path}"{@code foo/bar}" with the {@code String} "{@code bar/}" returns + * {@code true}. * * @param other * the given path string @@ -724,12 +733,18 @@ public interface Path * provider, platform specific. This method does not access the file system * and neither file is required to exist. * + *

    This method may not be used to compare paths that are associated + * with different file system providers. + * * @param other the path compared to this path. * * @return zero if the argument is {@link #equals equal} to this path, a * value less than zero if this path is lexicographically less than * the argument, or a value greater than zero if this path is * lexicographically greater than the argument + * + * @throws ClassCastException + * if the paths are associated with different providers */ @Override int compareTo(Path other); @@ -738,7 +753,7 @@ public interface Path * Tests this path for equality with the given object. * *

    If the given object is not a Path, or is a Path associated with a - * different provider, then this method immediately returns {@code false}. + * different {@code FileSystem}, then this method returns {@code false}. * *

    Whether or not two path are equal depends on the file system * implementation. In some cases the paths are compared without regard diff --git a/jdk/src/share/classes/java/nio/file/WatchKey.java b/jdk/src/share/classes/java/nio/file/WatchKey.java index 23897dba454..83403e96a3b 100644 --- a/jdk/src/share/classes/java/nio/file/WatchKey.java +++ b/jdk/src/share/classes/java/nio/file/WatchKey.java @@ -146,5 +146,5 @@ public interface WatchKey { * * @return the object for which this watch key was created */ - //T watchable(); + Watchable watchable(); } diff --git a/jdk/src/share/classes/java/nio/file/attribute/FileTime.java b/jdk/src/share/classes/java/nio/file/attribute/FileTime.java index 6cac437cdce..4e77b0e0172 100644 --- a/jdk/src/share/classes/java/nio/file/attribute/FileTime.java +++ b/jdk/src/share/classes/java/nio/file/attribute/FileTime.java @@ -216,12 +216,14 @@ public final class FileTime * "2009-02-13T23:31:30Z"}, and {@code FileTime.fromMillis(1234567890123L).toString()} * yields {@code "2009-02-13T23:31:30.123Z"}. * - *

    A {@code FileTime} is primarly intended to represent the value of a + *

    A {@code FileTime} is primarily intended to represent the value of a * file's time stamp. Where used to represent extreme values, where * the year is less than "{@code 0001}" or greater than "{@code 9999}" then - * the year may be expanded to more than four digits and may be - * negative-signed. If more than four digits then leading zeros are not - * present. The year before "{@code 0001}" is "{@code -0001}". + * this method deviates from ISO 8601 in the same manner as the + * XML Schema + * language. That is, the year may be expanded to more than four digits + * and may be negative-signed. If more than four digits then leading zeros + * are not present. The year before "{@code 0001}" is "{@code -0001}". * * @return the string representation of this file time */ diff --git a/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java b/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java index ad285bd6ddb..8d43fb93769 100644 --- a/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java +++ b/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java @@ -1037,6 +1037,11 @@ public abstract class FileSystemProvider { * @return a map of the attributes returned; may be empty. The map's keys * are the attribute names, its values are the attribute values * + * @throws UnsupportedOperationException + * if the attribute view is not available + * @throws IllegalArgumentException + * if no attributes are specified or an unrecognized attributes is + * specified * @throws IOException * If an I/O error occurs * @throws SecurityException @@ -1064,10 +1069,10 @@ public abstract class FileSystemProvider { * options indicating how symbolic links are handled * * @throws UnsupportedOperationException - * if the attribute view is not available or it does not support - * updating the attribute + * if the attribute view is not available * @throws IllegalArgumentException - * if the attribute value is of the correct type but has an + * if the attribute name is not specified, or is not recognized, or + * the attribute value is of the correct type but has an * inappropriate value * @throws ClassCastException * If the attribute value is not of the expected type or is a diff --git a/jdk/src/share/classes/java/security/AccessControlContext.java b/jdk/src/share/classes/java/security/AccessControlContext.java index e80953b6696..940aff63770 100644 --- a/jdk/src/share/classes/java/security/AccessControlContext.java +++ b/jdk/src/share/classes/java/security/AccessControlContext.java @@ -29,6 +29,9 @@ import java.util.ArrayList; import java.util.List; import sun.security.util.Debug; import sun.security.util.SecurityConstants; +import sun.misc.JavaSecurityAccess; +import sun.misc.SharedSecrets; + /** * An AccessControlContext is used to make system resource access decisions @@ -196,6 +199,24 @@ public final class AccessControlContext { this.isPrivileged = isPrivileged; } + /** + * Constructor for JavaSecurityAccess.doIntersectionPrivilege() + */ + AccessControlContext(ProtectionDomain[] context, + AccessControlContext privilegedContext) + { + this.context = context; + this.privilegedContext = privilegedContext; + this.isPrivileged = true; + } + + /** + * Returns this context's context. + */ + ProtectionDomain[] getContext() { + return context; + } + /** * Returns true if this context is privileged. */ diff --git a/jdk/src/share/classes/java/security/CodeSource.java b/jdk/src/share/classes/java/security/CodeSource.java index 5ec8cebc028..b821a4ec9c1 100644 --- a/jdk/src/share/classes/java/security/CodeSource.java +++ b/jdk/src/share/classes/java/security/CodeSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -578,7 +578,7 @@ public class CodeSource implements java.io.Serializable { // Deserialize array of code signers (if any) try { - this.signers = (CodeSigner[])ois.readObject(); + this.signers = ((CodeSigner[])ois.readObject()).clone(); } catch (IOException ioe) { // no signers present } diff --git a/jdk/src/share/classes/java/security/ProtectionDomain.java b/jdk/src/share/classes/java/security/ProtectionDomain.java index 43a39028e3d..9025e81b5dc 100644 --- a/jdk/src/share/classes/java/security/ProtectionDomain.java +++ b/jdk/src/share/classes/java/security/ProtectionDomain.java @@ -36,6 +36,8 @@ import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache; import sun.misc.SharedSecrets; import sun.security.util.Debug; import sun.security.util.SecurityConstants; +import sun.misc.JavaSecurityAccess; +import sun.misc.SharedSecrets; /** * @@ -59,6 +61,36 @@ import sun.security.util.SecurityConstants; public class ProtectionDomain { + static { + // Set up JavaSecurityAccess in SharedSecrets + SharedSecrets.setJavaSecurityAccess( + new JavaSecurityAccess() { + public T doIntersectionPrivilege( + PrivilegedAction action, + final AccessControlContext stack, + final AccessControlContext context) + { + if (action == null) { + throw new NullPointerException(); + } + return AccessController.doPrivileged( + action, + new AccessControlContext( + stack.getContext(), context).optimize() + ); + } + + public T doIntersectionPrivilege( + PrivilegedAction action, + AccessControlContext context) + { + return doIntersectionPrivilege(action, + AccessController.getContext(), context); + } + } + ); + } + /* CodeSource */ private CodeSource codesource ; diff --git a/jdk/src/share/classes/java/security/Timestamp.java b/jdk/src/share/classes/java/security/Timestamp.java index 1629d9bbff9..f66d2883e62 100644 --- a/jdk/src/share/classes/java/security/Timestamp.java +++ b/jdk/src/share/classes/java/security/Timestamp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -157,7 +157,8 @@ public final class Timestamp implements Serializable { // Explicitly reset hash code value to -1 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { - ois.defaultReadObject(); - myhash = -1; + ois.defaultReadObject(); + myhash = -1; + timestamp = new Date(timestamp.getTime()); } } diff --git a/jdk/src/share/classes/java/sql/DriverManager.java b/jdk/src/share/classes/java/sql/DriverManager.java index 15273877dba..ce6c6bf4823 100644 --- a/jdk/src/share/classes/java/sql/DriverManager.java +++ b/jdk/src/share/classes/java/sql/DriverManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -26,10 +26,10 @@ package java.sql; import java.util.Iterator; -import java.sql.Driver; import java.util.ServiceLoader; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.concurrent.CopyOnWriteArrayList; /** @@ -79,6 +79,27 @@ import java.security.PrivilegedAction; public class DriverManager { + // List of registered JDBC drivers + private final static CopyOnWriteArrayList registeredDrivers = new CopyOnWriteArrayList(); + private static volatile int loginTimeout = 0; + private static volatile java.io.PrintWriter logWriter = null; + private static volatile java.io.PrintStream logStream = null; + // Used in println() to synchronize logWriter + private final static Object logSync = new Object(); + + /* Prevent the DriverManager class from being instantiated. */ + private DriverManager(){} + + + /** + * Load the initial JDBC drivers by checking the System property + * jdbc.properties and then use the {@code ServiceLoader} mechanism + */ + static { + loadInitialDrivers(); + println("JDBC DriverManager initialized"); + } + /** * The SQLPermission constant that allows the * setting of the logging stream. @@ -235,44 +256,33 @@ public class DriverManager { */ public static Driver getDriver(String url) throws SQLException { - java.util.Vector drivers = null; println("DriverManager.getDriver(\"" + url + "\")"); - if (!initialized) { - initialize(); - } - - synchronized (DriverManager.class){ - // use the read copy of the drivers vector - drivers = readDrivers; - } - // Gets the classloader of the code that called this method, may // be null. ClassLoader callerCL = DriverManager.getCallerClassLoader(); - // Walk through the loaded drivers attempting to locate someone + // Walk through the loaded registeredDrivers attempting to locate someone // who understands the given URL. - for (int i = 0; i < drivers.size(); i++) { - DriverInfo di = (DriverInfo)drivers.elementAt(i); + for (Driver aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. - if ( getCallerClass(callerCL, di.driverClassName ) != - di.driverClass ) { - println(" skipping: " + di); - continue; - } - try { - println(" trying " + di); - if (di.driver.acceptsURL(url)) { - // Success! - println("getDriver returning " + di); - return (di.driver); + if(isDriverAllowed(aDriver, callerCL)) { + try { + if(aDriver.acceptsURL(url)) { + // Success! + println("getDriver returning " + aDriver.getClass().getName()); + return (aDriver); + } + + } catch(SQLException sqe) { + // Drop through and try the next driver. } - } catch (SQLException ex) { - // Drop through and try the next driver. + } else { + println(" skipping: " + aDriver.getClass().getName()); } + } println("getDriver: no suitable driver"); @@ -292,23 +302,16 @@ public class DriverManager { */ public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException { - if (!initialized) { - initialize(); + + /* Register the driver if it has not already been added to our list */ + if(driver != null) { + registeredDrivers.addIfAbsent(driver); + } else { + // This is for compatibility with the original DriverManager + throw new NullPointerException(); } - DriverInfo di = new DriverInfo(); - - di.driver = driver; - di.driverClass = driver.getClass(); - di.driverClassName = di.driverClass.getName(); - - // Not Required -- drivers.addElement(di); - - writeDrivers.addElement(di); - println("registerDriver: " + di); - - /* update the read copy of drivers vector */ - readDrivers = (java.util.Vector) writeDrivers.clone(); + println("registerDriver: " + driver); } @@ -321,37 +324,26 @@ public class DriverManager { */ public static synchronized void deregisterDriver(Driver driver) throws SQLException { + if (driver == null) { + return; + } + // Gets the classloader of the code that called this method, // may be null. ClassLoader callerCL = DriverManager.getCallerClassLoader(); println("DriverManager.deregisterDriver: " + driver); - // Walk through the loaded drivers. - int i; - DriverInfo di = null; - for (i = 0; i < writeDrivers.size(); i++) { - di = (DriverInfo)writeDrivers.elementAt(i); - if (di.driver == driver) { - break; + if(registeredDrivers.contains(driver)) { + if (isDriverAllowed(driver, callerCL)) { + registeredDrivers.remove(driver); + } else { + // If the caller does not have permission to load the driver then + // throw a SecurityException. + throw new SecurityException(); } - } - // If we can't find the driver just return. - if (i >= writeDrivers.size()) { + } else { println(" couldn't find driver to unload"); - return; } - - // If the caller does not have permission to load the driver then - // throw a security exception. - if (getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { - throw new SecurityException(); - } - - // Remove the driver. Other entries in drivers get shuffled down. - writeDrivers.removeElementAt(i); - - /* update the read copy of drivers vector */ - readDrivers = (java.util.Vector) writeDrivers.clone(); } /** @@ -364,34 +356,22 @@ public class DriverManager { * @return the list of JDBC Drivers loaded by the caller's class loader */ public static java.util.Enumeration getDrivers() { - java.util.Vector result = new java.util.Vector<>(); - java.util.Vector drivers = null; - - if (!initialized) { - initialize(); - } - - synchronized (DriverManager.class){ - // use the readcopy of drivers - drivers = readDrivers; - } + java.util.Vector result = new java.util.Vector(); // Gets the classloader of the code that called this method, may // be null. ClassLoader callerCL = DriverManager.getCallerClassLoader(); - // Walk through the loaded drivers. - for (int i = 0; i < drivers.size(); i++) { - DriverInfo di = (DriverInfo)drivers.elementAt(i); + // Walk through the loaded registeredDrivers. + for(Driver aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. - if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { - println(" skipping: " + di); - continue; + if(isDriverAllowed(aDriver, callerCL)) { + result.addElement(aDriver); + } else { + println(" skipping: " + aDriver.getClass().getName()); } - result.addElement(di.driver); } - return (result.elements()); } @@ -481,21 +461,22 @@ public class DriverManager { //------------------------------------------------------------------------ - // Returns the class object that would be created if the code calling the - // driver manager had loaded the driver class, or null if the class - // is inaccessible. - private static Class getCallerClass(ClassLoader callerClassLoader, - String driverClassName) { - Class callerC = null; + // Indicates whether the class object that would be created if the code calling + // DriverManager is accessible. + private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) { + boolean result = false; + if(driver != null) { + Class aClass = null; + try { + aClass = Class.forName(driver.getClass().getName(), true, classLoader); + } catch (Exception ex) { + result = false; + } - try { - callerC = Class.forName(driverClassName, true, callerClassLoader); - } - catch (Exception ex) { - callerC = null; // being very careful + result = ( aClass == driver.getClass() ) ? true : false; } - return callerC; + return result; } private static void loadInitialDrivers() { @@ -544,26 +525,17 @@ public class DriverManager { }); println("DriverManager.initialize: jdbc.drivers = " + drivers); - if (drivers == null) { + + if (drivers == null || drivers.equals("")) { return; } - while (drivers.length() != 0) { - int x = drivers.indexOf(':'); - String driver; - if (x < 0) { - driver = drivers; - drivers = ""; - } else { - driver = drivers.substring(0, x); - drivers = drivers.substring(x+1); - } - if (driver.length() == 0) { - continue; - } + String[] driversList = drivers.split(":"); + println("number of Drivers:" + driversList.length); + for (String aDriver : driversList) { try { - println("DriverManager.Initialize: loading " + driver); - Class.forName(driver, true, - ClassLoader.getSystemClassLoader()); + println("DriverManager.Initialize: loading " + aDriver); + Class.forName(aDriver, true, + ClassLoader.getSystemClassLoader()); } catch (Exception ex) { println("DriverManager.Initialize: load failed: " + ex); } @@ -574,7 +546,6 @@ public class DriverManager { // Worker method called by the public getConnection() methods. private static Connection getConnection( String url, java.util.Properties info, ClassLoader callerCL) throws SQLException { - java.util.Vector drivers = null; /* * When callerCl is null, we should check the application's * (which is invoking this class indirectly) @@ -594,40 +565,32 @@ public class DriverManager { println("DriverManager.getConnection(\"" + url + "\")"); - if (!initialized) { - initialize(); - } - - synchronized (DriverManager.class){ - // use the readcopy of drivers - drivers = readDrivers; - } - - // Walk through the loaded drivers attempting to make a connection. + // Walk through the loaded registeredDrivers attempting to make a connection. // Remember the first exception that gets raised so we can reraise it. SQLException reason = null; - for (int i = 0; i < drivers.size(); i++) { - DriverInfo di = (DriverInfo)drivers.elementAt(i); + for(Driver aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. - if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { - println(" skipping: " + di); - continue; - } - try { - println(" trying " + di); - Connection result = di.driver.connect(url, info); - if (result != null) { - // Success! - println("getConnection returning " + di); - return (result); - } - } catch (SQLException ex) { - if (reason == null) { - reason = ex; + if(isDriverAllowed(aDriver, callerCL)) { + try { + println(" trying " + aDriver.getClass().getName()); + Connection con = aDriver.connect(url, info); + if (con != null) { + // Success! + println("getConnection returning " + aDriver.getClass().getName()); + return (con); + } + } catch (SQLException ex) { + if (reason == null) { + reason = ex; + } } + + } else { + println(" skipping: " + aDriver.getClass().getName()); } + } // if we got here nobody could connect. @@ -640,45 +603,7 @@ public class DriverManager { throw new SQLException("No suitable driver found for "+ url, "08001"); } - - // Class initialization. - static void initialize() { - if (initialized) { - return; - } - initialized = true; - loadInitialDrivers(); - println("JDBC DriverManager initialized"); - } - - /* Prevent the DriverManager class from being instantiated. */ - private DriverManager(){} - - /* write copy of the drivers vector */ - private static java.util.Vector writeDrivers = new java.util.Vector(); - - /* write copy of the drivers vector */ - private static java.util.Vector readDrivers = new java.util.Vector(); - - private static int loginTimeout = 0; - private static java.io.PrintWriter logWriter = null; - private static java.io.PrintStream logStream = null; - private static boolean initialized = false; - - private static Object logSync = new Object(); - /* Returns the caller's class loader, or null if none */ private static native ClassLoader getCallerClassLoader(); } - -// DriverInfo is a package-private support class. -class DriverInfo { - Driver driver; - Class driverClass; - String driverClassName; - - public String toString() { - return ("driver[className=" + driverClassName + "," + driver + "]"); - } -} diff --git a/jdk/src/share/classes/java/text/SimpleDateFormat.java b/jdk/src/share/classes/java/text/SimpleDateFormat.java index fd2876aca05..a91a2344eca 100644 --- a/jdk/src/share/classes/java/text/SimpleDateFormat.java +++ b/jdk/src/share/classes/java/text/SimpleDateFormat.java @@ -504,8 +504,8 @@ public class SimpleDateFormat extends DateFormat { /** * Cache to hold the DateTimePatterns of a Locale. */ - private static final ConcurrentMap cachedLocaleData - = new ConcurrentHashMap(3); + private static final ConcurrentMap cachedLocaleData + = new ConcurrentHashMap(3); /** * Cache NumberFormat instances with Locale key. @@ -619,8 +619,7 @@ public class SimpleDateFormat extends DateFormat { initializeCalendar(loc); /* try the cache first */ - String key = getKey(); - String[] dateTimePatterns = cachedLocaleData.get(key); + String[] dateTimePatterns = cachedLocaleData.get(loc); if (dateTimePatterns == null) { /* cache miss */ ResourceBundle r = LocaleData.getDateFormatData(loc); if (!isGregorianCalendar()) { @@ -633,7 +632,7 @@ public class SimpleDateFormat extends DateFormat { dateTimePatterns = r.getStringArray("DateTimePatterns"); } /* update cache */ - cachedLocaleData.putIfAbsent(key, dateTimePatterns); + cachedLocaleData.putIfAbsent(loc, dateTimePatterns); } formatData = DateFormatSymbols.getInstanceRef(loc); if ((timeStyle >= 0) && (dateStyle >= 0)) { @@ -684,13 +683,6 @@ public class SimpleDateFormat extends DateFormat { } } - private String getKey() { - StringBuilder sb = new StringBuilder(); - sb.append(getCalendarName()).append('.'); - sb.append(locale.getLanguage()).append('_').append(locale.getCountry()).append('_').append(locale.getVariant()); - return sb.toString(); - } - /** * Returns the compiled form of the given pattern. The syntax of * the compiled pattern is: diff --git a/jdk/src/share/classes/java/util/Formatter.java b/jdk/src/share/classes/java/util/Formatter.java index 797b9e2f8aa..6dcf8788052 100644 --- a/jdk/src/share/classes/java/util/Formatter.java +++ b/jdk/src/share/classes/java/util/Formatter.java @@ -1401,10 +1401,9 @@ import sun.misc.FormattedFloatingDecimal; *

    The number of digits in the result for the fractional part of * m or a is equal to the precision. If the precision is not * specified then the default value is {@code 6}. If the precision is - * less than the number of digits which would appear after the decimal - * point in the string returned by {@link Float#toString(float)} or {@link - * Double#toString(double)} respectively, then the value will be rounded - * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up + * less than the number of digits to the right of the decimal point then + * the value will be rounded using the + * {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up * algorithm}. Otherwise, zeros may be appended to reach the precision. * For a canonical representation of the value, use {@link * BigDecimal#toString()}. @@ -1463,12 +1462,11 @@ import sun.misc.FormattedFloatingDecimal; * more decimal digits representing the fractional part of m. * *

    The number of digits in the result for the fractional part of - * m or a is equal to the precision. If the precision is not + * m or a is equal to the precision. If the precision is not * specified then the default value is {@code 6}. If the precision is - * less than the number of digits which would appear after the decimal - * point in the string returned by {@link Float#toString(float)} or {@link - * Double#toString(double)} respectively, then the value will be rounded - * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up + * less than the number of digits to the right of the decimal point + * then the value will be rounded using the + * {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up * algorithm}. Otherwise, zeros may be appended to reach the precision. * For a canonical representation of the value, use {@link * BigDecimal#toString()}. @@ -3585,7 +3583,7 @@ public final class Formatter implements Closeable, Flushable { int scale = value.scale(); if (scale > prec) { - // more "scale" digits than the requested "precision + // more "scale" digits than the requested "precision" int compPrec = value.precision(); if (compPrec <= scale) { // case of 0.xxxxxx diff --git a/jdk/src/share/classes/java/util/JumboEnumSet.java b/jdk/src/share/classes/java/util/JumboEnumSet.java index e3255963e56..398836a1c3b 100644 --- a/jdk/src/share/classes/java/util/JumboEnumSet.java +++ b/jdk/src/share/classes/java/util/JumboEnumSet.java @@ -34,6 +34,8 @@ package java.util; * @serial exclude */ class JumboEnumSet> extends EnumSet { + private static final long serialVersionUID = 334349849919042784L; + /** * Bit vector representation of this set. The ith bit of the jth * element of this array represents the presence of universe[64*j +i] @@ -138,8 +140,11 @@ class JumboEnumSet> extends EnumSet { public void remove() { if (lastReturned == 0) throw new IllegalStateException(); - elements[lastReturnedIndex] -= lastReturned; - size--; + final long oldElements = elements[lastReturnedIndex]; + elements[lastReturnedIndex] &= ~lastReturned; + if (oldElements != elements[lastReturnedIndex]) { + size--; + } lastReturned = 0; } } diff --git a/jdk/src/share/classes/java/util/Locale.java b/jdk/src/share/classes/java/util/Locale.java index efe200ed0db..63c8b03c4d3 100644 --- a/jdk/src/share/classes/java/util/Locale.java +++ b/jdk/src/share/classes/java/util/Locale.java @@ -1168,7 +1168,7 @@ public final class Locale implements Cloneable, Serializable { boolean e = (_extensions.getID().length() != 0); StringBuilder result = new StringBuilder(_baseLocale.getLanguage()); - if (r || (l && v)) { + if (r || (l && (v || s || e))) { result.append('_') .append(_baseLocale.getRegion()); // This may just append '_' } diff --git a/jdk/src/share/classes/java/util/RegularEnumSet.java b/jdk/src/share/classes/java/util/RegularEnumSet.java index c4f6215461b..a549fae2de1 100644 --- a/jdk/src/share/classes/java/util/RegularEnumSet.java +++ b/jdk/src/share/classes/java/util/RegularEnumSet.java @@ -34,6 +34,7 @@ package java.util; * @serial exclude */ class RegularEnumSet> extends EnumSet { + private static final long serialVersionUID = 3411599620347842686L; /** * Bit vector representation of this set. The 2^k bit indicates the * presence of universe[k] in this set. @@ -106,7 +107,7 @@ class RegularEnumSet> extends EnumSet { public void remove() { if (lastReturned == 0) throw new IllegalStateException(); - elements -= lastReturned; + elements &= ~lastReturned; lastReturned = 0; } } diff --git a/jdk/src/share/classes/java/util/TreeMap.java b/jdk/src/share/classes/java/util/TreeMap.java index e256240f306..d14ee9f4b66 100644 --- a/jdk/src/share/classes/java/util/TreeMap.java +++ b/jdk/src/share/classes/java/util/TreeMap.java @@ -528,11 +528,8 @@ public class TreeMap public V put(K key, V value) { Entry t = root; if (t == null) { - // TBD: - // 5045147: (coll) Adding null to an empty TreeSet should - // throw NullPointerException - // - // compare(key, key); // type check + compare(key, key); // type (and possibly null) check + root = new Entry<>(key, value, null); size = 1; modCount++; diff --git a/jdk/src/share/classes/java/util/UUID.java b/jdk/src/share/classes/java/util/UUID.java index c2d3a3184d6..348c8686e0a 100644 --- a/jdk/src/share/classes/java/util/UUID.java +++ b/jdk/src/share/classes/java/util/UUID.java @@ -26,8 +26,6 @@ package java.util; import java.security.*; -import java.io.IOException; -import java.io.UnsupportedEncodingException; /** * A class that represents an immutable universally unique identifier (UUID). @@ -90,36 +88,6 @@ public final class UUID implements java.io.Serializable, Comparable { */ private final long leastSigBits; - /* - * The version number associated with this UUID. Computed on demand. - */ - private transient int version = -1; - - /* - * The variant number associated with this UUID. Computed on demand. - */ - private transient int variant = -1; - - /* - * The timestamp associated with this UUID. Computed on demand. - */ - private transient volatile long timestamp = -1; - - /* - * The clock sequence associated with this UUID. Computed on demand. - */ - private transient int sequence = -1; - - /* - * The node number associated with this UUID. Computed on demand. - */ - private transient long node = -1; - - /* - * The hashcode of this UUID. Computed on demand. - */ - private transient int hashCode = -1; - /* * The random number generator used by this class to create random * based UUIDs. @@ -134,7 +102,7 @@ public final class UUID implements java.io.Serializable, Comparable { private UUID(byte[] data) { long msb = 0; long lsb = 0; - assert data.length == 16; + assert data.length == 16 : "data must be 16 bytes in length"; for (int i=0; i<8; i++) msb = (msb << 8) | (data[i] & 0xff); for (int i=8; i<16; i++) @@ -276,11 +244,8 @@ public final class UUID implements java.io.Serializable, Comparable { * @return The version number of this {@code UUID} */ public int version() { - if (version < 0) { - // Version is bits masked by 0x000000000000F000 in MS long - version = (int)((mostSigBits >> 12) & 0x0f); - } - return version; + // Version is bits masked by 0x000000000000F000 in MS long + return (int)((mostSigBits >> 12) & 0x0f); } /** @@ -298,17 +263,13 @@ public final class UUID implements java.io.Serializable, Comparable { * @return The variant number of this {@code UUID} */ public int variant() { - if (variant < 0) { - // This field is composed of a varying number of bits - if ((leastSigBits >>> 63) == 0) { - variant = 0; - } else if ((leastSigBits >>> 62) == 2) { - variant = 2; - } else { - variant = (int)(leastSigBits >>> 61); - } - } - return variant; + // This field is composed of a varying number of bits. + // 0 - - Reserved for NCS backward compatibility + // 1 0 - The Leach-Salz variant (used by this class) + // 1 1 0 Reserved, Microsoft backward compatibility + // 1 1 1 Reserved for future definition. + return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) + & (leastSigBits >> 63)); } /** @@ -330,14 +291,10 @@ public final class UUID implements java.io.Serializable, Comparable { if (version() != 1) { throw new UnsupportedOperationException("Not a time-based UUID"); } - long result = timestamp; - if (result < 0) { - result = (mostSigBits & 0x0000000000000FFFL) << 48; - result |= ((mostSigBits >> 16) & 0xFFFFL) << 32; - result |= mostSigBits >>> 32; - timestamp = result; - } - return result; + + return (mostSigBits & 0x0FFFL) << 48 + | ((mostSigBits >> 16) & 0x0FFFFL) << 32 + | mostSigBits >>> 32; } /** @@ -360,10 +317,8 @@ public final class UUID implements java.io.Serializable, Comparable { if (version() != 1) { throw new UnsupportedOperationException("Not a time-based UUID"); } - if (sequence < 0) { - sequence = (int)((leastSigBits & 0x3FFF000000000000L) >>> 48); - } - return sequence; + + return (int)((leastSigBits & 0x3FFF000000000000L) >>> 48); } /** @@ -386,10 +341,8 @@ public final class UUID implements java.io.Serializable, Comparable { if (version() != 1) { throw new UnsupportedOperationException("Not a time-based UUID"); } - if (node < 0) { - node = leastSigBits & 0x0000FFFFFFFFFFFFL; - } - return node; + + return leastSigBits & 0x0000FFFFFFFFFFFFL; } // Object Inherited Methods @@ -438,13 +391,8 @@ public final class UUID implements java.io.Serializable, Comparable { * @return A hash code value for this {@code UUID} */ public int hashCode() { - if (hashCode == -1) { - hashCode = (int)((mostSigBits >> 32) ^ - mostSigBits ^ - (leastSigBits >> 32) ^ - leastSigBits); - } - return hashCode; + long hilo = mostSigBits ^ leastSigBits; + return ((int)(hilo >> 32)) ^ (int) hilo; } /** @@ -460,9 +408,7 @@ public final class UUID implements java.io.Serializable, Comparable { * otherwise */ public boolean equals(Object obj) { - if (!(obj instanceof UUID)) - return false; - if (((UUID)obj).variant() != this.variant()) + if ((null == obj) || (obj.getClass() != UUID.class)) return false; UUID id = (UUID)obj; return (mostSigBits == id.mostSigBits && @@ -494,23 +440,4 @@ public final class UUID implements java.io.Serializable, Comparable { (this.leastSigBits > val.leastSigBits ? 1 : 0)))); } - - /** - * Reconstitute the {@code UUID} instance from a stream (that is, - * deserialize it). This is necessary to set the transient fields to their - * correct uninitialized value so they will be recomputed on demand. - */ - private void readObject(java.io.ObjectInputStream in) - throws java.io.IOException, ClassNotFoundException { - - in.defaultReadObject(); - - // Set "cached computation" fields to their initial values - version = -1; - variant = -1; - timestamp = -1; - sequence = -1; - node = -1; - hashCode = -1; - } } diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index f1b11140291..37d218f6775 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -44,8 +44,8 @@ import java.util.concurrent.atomic.*; * creation time, depending on which constructor is used. * *

    This class implements a concurrent variant of SkipLists providing - * expected average log(n) time cost for the + * href="http://en.wikipedia.org/wiki/Skip_list" target="_top">SkipLists + * providing expected average log(n) time cost for the * containsKey, get, put and * remove operations and their variants. Insertion, removal, * update, and access operations safely execute concurrently by diff --git a/jdk/src/share/classes/java/util/concurrent/Exchanger.java b/jdk/src/share/classes/java/util/concurrent/Exchanger.java index 8648278b755..e23f797c289 100644 --- a/jdk/src/share/classes/java/util/concurrent/Exchanger.java +++ b/jdk/src/share/classes/java/util/concurrent/Exchanger.java @@ -164,8 +164,8 @@ public class Exchanger { * races between two threads or thread pre-emptions occurring * between reading and CASing. Also, very transient peak * contention can be much higher than the average sustainable - * levels. The max limit is decreased on average 50% of the times - * that a non-slot-zero wait elapses without being fulfilled. + * levels. An attempt to decrease the max limit is usually made + * when a non-slot-zero wait elapses without being fulfilled. * Threads experiencing elapsed waits move closer to zero, so * eventually find existing (or future) threads even if the table * has been shrunk due to inactivity. The chosen mechanics and diff --git a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java index 22938fe4ba9..e298d151c1b 100644 --- a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java @@ -40,6 +40,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Random; import java.util.concurrent.AbstractExecutorService; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -51,6 +52,7 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.Condition; /** * An {@link ExecutorService} for running {@link ForkJoinTask}s. @@ -158,239 +160,208 @@ public class ForkJoinPool extends AbstractExecutorService { * set of worker threads: Submissions from non-FJ threads enter * into a submission queue. Workers take these tasks and typically * split them into subtasks that may be stolen by other workers. - * The main work-stealing mechanics implemented in class - * ForkJoinWorkerThread give first priority to processing tasks - * from their own queues (LIFO or FIFO, depending on mode), then - * to randomized FIFO steals of tasks in other worker queues, and - * lastly to new submissions. These mechanics do not consider - * affinities, loads, cache localities, etc, so rarely provide the - * best possible performance on a given machine, but portably - * provide good throughput by averaging over these factors. - * (Further, even if we did try to use such information, we do not - * usually have a basis for exploiting it. For example, some sets - * of tasks profit from cache affinities, but others are harmed by - * cache pollution effects.) + * Preference rules give first priority to processing tasks from + * their own queues (LIFO or FIFO, depending on mode), then to + * randomized FIFO steals of tasks in other worker queues, and + * lastly to new submissions. * - * Beyond work-stealing support and essential bookkeeping, the - * main responsibility of this framework is to take actions when - * one worker is waiting to join a task stolen (or always held by) - * another. Because we are multiplexing many tasks on to a pool - * of workers, we can't just let them block (as in Thread.join). - * We also cannot just reassign the joiner's run-time stack with - * another and replace it later, which would be a form of - * "continuation", that even if possible is not necessarily a good - * idea. Given that the creation costs of most threads on most - * systems mainly surrounds setting up runtime stacks, thread - * creation and switching is usually not much more expensive than - * stack creation and switching, and is more flexible). Instead we + * The main throughput advantages of work-stealing stem from + * decentralized control -- workers mostly take tasks from + * themselves or each other. We cannot negate this in the + * implementation of other management responsibilities. The main + * tactic for avoiding bottlenecks is packing nearly all + * essentially atomic control state into a single 64bit volatile + * variable ("ctl"). This variable is read on the order of 10-100 + * times as often as it is modified (always via CAS). (There is + * some additional control state, for example variable "shutdown" + * for which we can cope with uncoordinated updates.) This + * streamlines synchronization and control at the expense of messy + * constructions needed to repack status bits upon updates. + * Updates tend not to contend with each other except during + * bursts while submitted tasks begin or end. In some cases when + * they do contend, threads can instead do something else + * (usually, scan for tasks) until contention subsides. + * + * To enable packing, we restrict maximum parallelism to (1<<15)-1 + * (which is far in excess of normal operating range) to allow + * ids, counts, and their negations (used for thresholding) to fit + * into 16bit fields. + * + * Recording Workers. Workers are recorded in the "workers" array + * that is created upon pool construction and expanded if (rarely) + * necessary. This is an array as opposed to some other data + * structure to support index-based random steals by workers. + * Updates to the array recording new workers and unrecording + * terminated ones are protected from each other by a seqLock + * (scanGuard) but the array is otherwise concurrently readable, + * and accessed directly by workers. To simplify index-based + * operations, the array size is always a power of two, and all + * readers must tolerate null slots. To avoid flailing during + * start-up, the array is presized to hold twice #parallelism + * workers (which is unlikely to need further resizing during + * execution). But to avoid dealing with so many null slots, + * variable scanGuard includes a mask for the nearest power of two + * that contains all current workers. All worker thread creation + * is on-demand, triggered by task submissions, replacement of + * terminated workers, and/or compensation for blocked + * workers. However, all other support code is set up to work with + * other policies. To ensure that we do not hold on to worker + * references that would prevent GC, ALL accesses to workers are + * via indices into the workers array (which is one source of some + * of the messy code constructions here). In essence, the workers + * array serves as a weak reference mechanism. Thus for example + * the wait queue field of ctl stores worker indices, not worker + * references. Access to the workers in associated methods (for + * example signalWork) must both index-check and null-check the + * IDs. All such accesses ignore bad IDs by returning out early + * from what they are doing, since this can only be associated + * with termination, in which case it is OK to give up. + * + * All uses of the workers array, as well as queue arrays, check + * that the array is non-null (even if previously non-null). This + * allows nulling during termination, which is currently not + * necessary, but remains an option for resource-revocation-based + * shutdown schemes. + * + * Wait Queuing. Unlike HPC work-stealing frameworks, we cannot + * let workers spin indefinitely scanning for tasks when none can + * be found immediately, and we cannot start/resume workers unless + * there appear to be tasks available. On the other hand, we must + * quickly prod them into action when new tasks are submitted or + * generated. We park/unpark workers after placing in an event + * wait queue when they cannot find work. This "queue" is actually + * a simple Treiber stack, headed by the "id" field of ctl, plus a + * 15bit counter value to both wake up waiters (by advancing their + * count) and avoid ABA effects. Successors are held in worker + * field "nextWait". Queuing deals with several intrinsic races, + * mainly that a task-producing thread can miss seeing (and + * signalling) another thread that gave up looking for work but + * has not yet entered the wait queue. We solve this by requiring + * a full sweep of all workers both before (in scan()) and after + * (in tryAwaitWork()) a newly waiting worker is added to the wait + * queue. During a rescan, the worker might release some other + * queued worker rather than itself, which has the same net + * effect. Because enqueued workers may actually be rescanning + * rather than waiting, we set and clear the "parked" field of + * ForkJoinWorkerThread to reduce unnecessary calls to unpark. + * (Use of the parked field requires a secondary recheck to avoid + * missed signals.) + * + * Signalling. We create or wake up workers only when there + * appears to be at least one task they might be able to find and + * execute. When a submission is added or another worker adds a + * task to a queue that previously had two or fewer tasks, they + * signal waiting workers (or trigger creation of new ones if + * fewer than the given parallelism level -- see signalWork). + * These primary signals are buttressed by signals during rescans + * as well as those performed when a worker steals a task and + * notices that there are more tasks too; together these cover the + * signals needed in cases when more than two tasks are pushed + * but untaken. + * + * Trimming workers. To release resources after periods of lack of + * use, a worker starting to wait when the pool is quiescent will + * time out and terminate if the pool has remained quiescent for + * SHRINK_RATE nanosecs. This will slowly propagate, eventually + * terminating all workers after long periods of non-use. + * + * Submissions. External submissions are maintained in an + * array-based queue that is structured identically to + * ForkJoinWorkerThread queues except for the use of + * submissionLock in method addSubmission. Unlike the case for + * worker queues, multiple external threads can add new + * submissions, so adding requires a lock. + * + * Compensation. Beyond work-stealing support and lifecycle + * control, the main responsibility of this framework is to take + * actions when one worker is waiting to join a task stolen (or + * always held by) another. Because we are multiplexing many + * tasks on to a pool of workers, we can't just let them block (as + * in Thread.join). We also cannot just reassign the joiner's + * run-time stack with another and replace it later, which would + * be a form of "continuation", that even if possible is not + * necessarily a good idea since we sometimes need both an + * unblocked task and its continuation to progress. Instead we * combine two tactics: * * Helping: Arranging for the joiner to execute some task that it * would be running if the steal had not occurred. Method - * ForkJoinWorkerThread.helpJoinTask tracks joining->stealing + * ForkJoinWorkerThread.joinTask tracks joining->stealing * links to try to find such a task. * * Compensating: Unless there are already enough live threads, - * method helpMaintainParallelism() may create or - * re-activate a spare thread to compensate for blocked - * joiners until they unblock. - * - * It is impossible to keep exactly the target (parallelism) - * number of threads running at any given time. Determining - * existence of conservatively safe helping targets, the - * availability of already-created spares, and the apparent need - * to create new spares are all racy and require heuristic - * guidance, so we rely on multiple retries of each. Compensation - * occurs in slow-motion. It is triggered only upon timeouts of - * Object.wait used for joins. This reduces poor decisions that - * would otherwise be made when threads are waiting for others - * that are stalled because of unrelated activities such as - * garbage collection. + * method tryPreBlock() may create or re-activate a spare + * thread to compensate for blocked joiners until they + * unblock. * * The ManagedBlocker extension API can't use helping so relies * only on compensation in method awaitBlocker. * - * The main throughput advantages of work-stealing stem from - * decentralized control -- workers mostly steal tasks from each - * other. We do not want to negate this by creating bottlenecks - * implementing other management responsibilities. So we use a - * collection of techniques that avoid, reduce, or cope well with - * contention. These entail several instances of bit-packing into - * CASable fields to maintain only the minimally required - * atomicity. To enable such packing, we restrict maximum - * parallelism to (1<<15)-1 (enabling twice this (to accommodate - * unbalanced increments and decrements) to fit into a 16 bit - * field, which is far in excess of normal operating range. Even - * though updates to some of these bookkeeping fields do sometimes - * contend with each other, they don't normally cache-contend with - * updates to others enough to warrant memory padding or - * isolation. So they are all held as fields of ForkJoinPool - * objects. The main capabilities are as follows: + * It is impossible to keep exactly the target parallelism number + * of threads running at any given time. Determining the + * existence of conservatively safe helping targets, the + * availability of already-created spares, and the apparent need + * to create new spares are all racy and require heuristic + * guidance, so we rely on multiple retries of each. Currently, + * in keeping with on-demand signalling policy, we compensate only + * if blocking would leave less than one active (non-waiting, + * non-blocked) worker. Additionally, to avoid some false alarms + * due to GC, lagging counters, system activity, etc, compensated + * blocking for joins is only attempted after rechecks stabilize + * (retries are interspersed with Thread.yield, for good + * citizenship). The variable blockedCount, incremented before + * blocking and decremented after, is sometimes needed to + * distinguish cases of waiting for work vs blocking on joins or + * other managed sync. Both cases are equivalent for most pool + * control, so we can update non-atomically. (Additionally, + * contention on blockedCount alleviates some contention on ctl). * - * 1. Creating and removing workers. Workers are recorded in the - * "workers" array. This is an array as opposed to some other data - * structure to support index-based random steals by workers. - * Updates to the array recording new workers and unrecording - * terminated ones are protected from each other by a lock - * (workerLock) but the array is otherwise concurrently readable, - * and accessed directly by workers. To simplify index-based - * operations, the array size is always a power of two, and all - * readers must tolerate null slots. Currently, all worker thread - * creation is on-demand, triggered by task submissions, - * replacement of terminated workers, and/or compensation for - * blocked workers. However, all other support code is set up to - * work with other policies. + * Shutdown and Termination. A call to shutdownNow atomically sets + * the ctl stop bit and then (non-atomically) sets each workers + * "terminate" status, cancels all unprocessed tasks, and wakes up + * all waiting workers. Detecting whether termination should + * commence after a non-abrupt shutdown() call requires more work + * and bookkeeping. We need consensus about quiesence (i.e., that + * there is no more work) which is reflected in active counts so + * long as there are no current blockers, as well as possible + * re-evaluations during independent changes in blocking or + * quiescing workers. * - * To ensure that we do not hold on to worker references that - * would prevent GC, ALL accesses to workers are via indices into - * the workers array (which is one source of some of the unusual - * code constructions here). In essence, the workers array serves - * as a WeakReference mechanism. Thus for example the event queue - * stores worker indices, not worker references. Access to the - * workers in associated methods (for example releaseEventWaiters) - * must both index-check and null-check the IDs. All such accesses - * ignore bad IDs by returning out early from what they are doing, - * since this can only be associated with shutdown, in which case - * it is OK to give up. On termination, we just clobber these - * data structures without trying to use them. - * - * 2. Bookkeeping for dynamically adding and removing workers. We - * aim to approximately maintain the given level of parallelism. - * When some workers are known to be blocked (on joins or via - * ManagedBlocker), we may create or resume others to take their - * place until they unblock (see below). Implementing this - * requires counts of the number of "running" threads (i.e., those - * that are neither blocked nor artificially suspended) as well as - * the total number. These two values are packed into one field, - * "workerCounts" because we need accurate snapshots when deciding - * to create, resume or suspend. Note however that the - * correspondence of these counts to reality is not guaranteed. In - * particular updates for unblocked threads may lag until they - * actually wake up. - * - * 3. Maintaining global run state. The run state of the pool - * consists of a runLevel (SHUTDOWN, TERMINATING, etc) similar to - * those in other Executor implementations, as well as a count of - * "active" workers -- those that are, or soon will be, or - * recently were executing tasks. The runLevel and active count - * are packed together in order to correctly trigger shutdown and - * termination. Without care, active counts can be subject to very - * high contention. We substantially reduce this contention by - * relaxing update rules. A worker must claim active status - * prospectively, by activating if it sees that a submitted or - * stealable task exists (it may find after activating that the - * task no longer exists). It stays active while processing this - * task (if it exists) and any other local subtasks it produces, - * until it cannot find any other tasks. It then tries - * inactivating (see method preStep), but upon update contention - * instead scans for more tasks, later retrying inactivation if it - * doesn't find any. - * - * 4. Managing idle workers waiting for tasks. We cannot let - * workers spin indefinitely scanning for tasks when none are - * available. On the other hand, we must quickly prod them into - * action when new tasks are submitted or generated. We - * park/unpark these idle workers using an event-count scheme. - * Field eventCount is incremented upon events that may enable - * workers that previously could not find a task to now find one: - * Submission of a new task to the pool, or another worker pushing - * a task onto a previously empty queue. (We also use this - * mechanism for configuration and termination actions that - * require wakeups of idle workers). Each worker maintains its - * last known event count, and blocks when a scan for work did not - * find a task AND its lastEventCount matches the current - * eventCount. Waiting idle workers are recorded in a variant of - * Treiber stack headed by field eventWaiters which, when nonzero, - * encodes the thread index and count awaited for by the worker - * thread most recently calling eventSync. This thread in turn has - * a record (field nextEventWaiter) for the next waiting worker. - * In addition to allowing simpler decisions about need for - * wakeup, the event count bits in eventWaiters serve the role of - * tags to avoid ABA errors in Treiber stacks. Upon any wakeup, - * released threads also try to release at most two others. The - * net effect is a tree-like diffusion of signals, where released - * threads (and possibly others) help with unparks. To further - * reduce contention effects a bit, failed CASes to increment - * field eventCount are tolerated without retries in signalWork. - * Conceptually they are merged into the same event, which is OK - * when their only purpose is to enable workers to scan for work. - * - * 5. Managing suspension of extra workers. When a worker notices - * (usually upon timeout of a wait()) that there are too few - * running threads, we may create a new thread to maintain - * parallelism level, or at least avoid starvation. Usually, extra - * threads are needed for only very short periods, yet join - * dependencies are such that we sometimes need them in - * bursts. Rather than create new threads each time this happens, - * we suspend no-longer-needed extra ones as "spares". For most - * purposes, we don't distinguish "extra" spare threads from - * normal "core" threads: On each call to preStep (the only point - * at which we can do this) a worker checks to see if there are - * now too many running workers, and if so, suspends itself. - * Method helpMaintainParallelism looks for suspended threads to - * resume before considering creating a new replacement. The - * spares themselves are encoded on another variant of a Treiber - * Stack, headed at field "spareWaiters". Note that the use of - * spares is intrinsically racy. One thread may become a spare at - * about the same time as another is needlessly being created. We - * counteract this and related slop in part by requiring resumed - * spares to immediately recheck (in preStep) to see whether they - * should re-suspend. - * - * 6. Killing off unneeded workers. A timeout mechanism is used to - * shed unused workers: The oldest (first) event queue waiter uses - * a timed rather than hard wait. When this wait times out without - * a normal wakeup, it tries to shutdown any one (for convenience - * the newest) other spare or event waiter via - * tryShutdownUnusedWorker. This eventually reduces the number of - * worker threads to a minimum of one after a long enough period - * without use. - * - * 7. Deciding when to create new workers. The main dynamic - * control in this class is deciding when to create extra threads - * in method helpMaintainParallelism. We would like to keep - * exactly #parallelism threads running, which is an impossible - * task. We always need to create one when the number of running - * threads would become zero and all workers are busy. Beyond - * this, we must rely on heuristics that work well in the - * presence of transient phenomena such as GC stalls, dynamic - * compilation, and wake-up lags. These transients are extremely - * common -- we are normally trying to fully saturate the CPUs on - * a machine, so almost any activity other than running tasks - * impedes accuracy. Our main defense is to allow parallelism to - * lapse for a while during joins, and use a timeout to see if, - * after the resulting settling, there is still a need for - * additional workers. This also better copes with the fact that - * some of the methods in this class tend to never become compiled - * (but are interpreted), so some components of the entire set of - * controls might execute 100 times faster than others. And - * similarly for cases where the apparent lack of work is just due - * to GC stalls and other transient system activity. - * - * Beware that there is a lot of representation-level coupling + * Style notes: There is a lot of representation-level coupling * among classes ForkJoinPool, ForkJoinWorkerThread, and - * ForkJoinTask. For example, direct access to "workers" array by + * ForkJoinTask. Most fields of ForkJoinWorkerThread maintain + * data structures managed by ForkJoinPool, so are directly + * accessed. Conversely we allow access to "workers" array by * workers, and direct access to ForkJoinTask.status by both * ForkJoinPool and ForkJoinWorkerThread. There is little point * trying to reduce this, since any associated future changes in * representations will need to be accompanied by algorithmic - * changes anyway. + * changes anyway. All together, these low-level implementation + * choices produce as much as a factor of 4 performance + * improvement compared to naive implementations, and enable the + * processing of billions of tasks per second, at the expense of + * some ugliness. * - * Style notes: There are lots of inline assignments (of form - * "while ((local = field) != 0)") which are usually the simplest - * way to ensure the required read orderings (which are sometimes - * critical). Also several occurrences of the unusual "do {} - * while (!cas...)" which is the simplest way to force an update of - * a CAS'ed variable. There are also other coding oddities that - * help some methods perform reasonably even when interpreted (not - * compiled), at the expense of some messy constructions that - * reduce byte code counts. + * Methods signalWork() and scan() are the main bottlenecks so are + * especially heavily micro-optimized/mangled. There are lots of + * inline assignments (of form "while ((local = field) != 0)") + * which are usually the simplest way to ensure the required read + * orderings (which are sometimes critical). This leads to a + * "C"-like style of listing declarations of these locals at the + * heads of methods or blocks. There are several occurrences of + * the unusual "do {} while (!cas...)" which is the simplest way + * to force an update of a CAS'ed variable. There are also other + * coding oddities that help some methods perform reasonably even + * when interpreted (not compiled). * - * The order of declarations in this file is: (1) statics (2) - * fields (along with constants used when unpacking some of them) - * (3) internal control methods (4) callbacks and other support - * for ForkJoinTask and ForkJoinWorkerThread classes, (5) exported - * methods (plus a few little helpers). + * The order of declarations in this file is: (1) declarations of + * statics (2) fields (along with constants used when unpacking + * some of them), listed in an order that tends to reduce + * contention among them a bit under most JVMs. (3) internal + * control methods (4) callbacks and other support for + * ForkJoinTask and ForkJoinWorkerThread classes, (5) exported + * methods (plus a few little helpers). (6) static block + * initializing all statics in a minimally dependent order. */ /** @@ -425,15 +396,13 @@ public class ForkJoinPool extends AbstractExecutorService { * overridden in ForkJoinPool constructors. */ public static final ForkJoinWorkerThreadFactory - defaultForkJoinWorkerThreadFactory = - new DefaultForkJoinWorkerThreadFactory(); + defaultForkJoinWorkerThreadFactory; /** * Permission required for callers of methods that may start or * kill threads. */ - private static final RuntimePermission modifyThreadPermission = - new RuntimePermission("modifyThread"); + private static final RuntimePermission modifyThreadPermission; /** * If there is a security manager, makes sure caller has @@ -448,69 +417,76 @@ public class ForkJoinPool extends AbstractExecutorService { /** * Generator for assigning sequence numbers as pool names. */ - private static final AtomicInteger poolNumberGenerator = - new AtomicInteger(); + private static final AtomicInteger poolNumberGenerator; /** - * The time to block in a join (see awaitJoin) before checking if - * a new worker should be (re)started to maintain parallelism - * level. The value should be short enough to maintain global - * responsiveness and progress but long enough to avoid - * counterproductive firings during GC stalls or unrelated system - * activity, and to not bog down systems with continual re-firings - * on GCs or legitimately long waits. + * Generator for initial random seeds for worker victim + * selection. This is used only to create initial seeds. Random + * steals use a cheaper xorshift generator per steal attempt. We + * don't expect much contention on seedGenerator, so just use a + * plain Random. */ - private static final long JOIN_TIMEOUT_MILLIS = 250L; // 4 per second + static final Random workerSeedGenerator; /** - * The wakeup interval (in nanoseconds) for the oldest worker - * waiting for an event to invoke tryShutdownUnusedWorker to - * shrink the number of workers. The exact value does not matter - * too much. It must be short enough to release resources during - * sustained periods of idleness, but not so short that threads - * are continually re-created. + * Array holding all worker threads in the pool. Initialized upon + * construction. Array size must be a power of two. Updates and + * replacements are protected by scanGuard, but the array is + * always kept in a consistent enough state to be randomly + * accessed without locking by workers performing work-stealing, + * as well as other traversal-based methods in this class, so long + * as reads memory-acquire by first reading ctl. All readers must + * tolerate that some array slots may be null. */ - private static final long SHRINK_RATE_NANOS = - 30L * 1000L * 1000L * 1000L; // 2 per minute + ForkJoinWorkerThread[] workers; /** - * Absolute bound for parallelism level. Twice this number plus - * one (i.e., 0xfff) must fit into a 16bit field to enable - * word-packing for some counts and indices. + * Initial size for submission queue array. Must be a power of + * two. In many applications, these always stay small so we use a + * small initial cap. */ - private static final int MAX_WORKERS = 0x7fff; + private static final int INITIAL_QUEUE_CAPACITY = 8; /** - * Array holding all worker threads in the pool. Array size must - * be a power of two. Updates and replacements are protected by - * workerLock, but the array is always kept in a consistent enough - * state to be randomly accessed without locking by workers - * performing work-stealing, as well as other traversal-based - * methods in this class. All readers must tolerate that some - * array slots may be null. + * Maximum size for submission queue array. Must be a power of two + * less than or equal to 1 << (31 - width of array entry) to + * ensure lack of index wraparound, but is capped at a lower + * value to help users trap runaway computations. */ - volatile ForkJoinWorkerThread[] workers; + private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 24; // 16M /** - * Queue for external submissions. + * Array serving as submission queue. Initialized upon construction. */ - private final LinkedTransferQueue> submissionQueue; + private ForkJoinTask[] submissionQueue; /** - * Lock protecting updates to workers array. + * Lock protecting submissions array for addSubmission */ - private final ReentrantLock workerLock; + private final ReentrantLock submissionLock; /** - * Latch released upon termination. + * Condition for awaitTermination, using submissionLock for + * convenience. */ - private final Phaser termination; + private final Condition termination; /** * Creation factory for worker threads. */ private final ForkJoinWorkerThreadFactory factory; + /** + * The uncaught exception handler used when any worker abruptly + * terminates. + */ + final Thread.UncaughtExceptionHandler ueh; + + /** + * Prefix for assigning names to worker threads + */ + private final String workerNamePrefix; + /** * Sum of per-thread steal counts, updated only when threads are * idle or terminating. @@ -518,82 +494,87 @@ public class ForkJoinPool extends AbstractExecutorService { private volatile long stealCount; /** - * Encoded record of top of Treiber stack of threads waiting for - * events. The top 32 bits contain the count being waited for. The - * bottom 16 bits contains one plus the pool index of waiting - * worker thread. (Bits 16-31 are unused.) - */ - private volatile long eventWaiters; - - private static final int EVENT_COUNT_SHIFT = 32; - private static final int WAITER_ID_MASK = (1 << 16) - 1; - - /** - * A counter for events that may wake up worker threads: - * - Submission of a new task to the pool - * - A worker pushing a task on an empty queue - * - termination - */ - private volatile int eventCount; - - /** - * Encoded record of top of Treiber stack of spare threads waiting - * for resumption. The top 16 bits contain an arbitrary count to - * avoid ABA effects. The bottom 16bits contains one plus the pool - * index of waiting worker thread. - */ - private volatile int spareWaiters; - - private static final int SPARE_COUNT_SHIFT = 16; - private static final int SPARE_ID_MASK = (1 << 16) - 1; - - /** - * Lifecycle control. The low word contains the number of workers - * that are (probably) executing tasks. This value is atomically - * incremented before a worker gets a task to run, and decremented - * when a worker has no tasks and cannot find any. Bits 16-18 - * contain runLevel value. When all are zero, the pool is - * running. Level transitions are monotonic (running -> shutdown - * -> terminating -> terminated) so each transition adds a bit. - * These are bundled together to ensure consistent read for - * termination checks (i.e., that runLevel is at least SHUTDOWN - * and active threads is zero). + * Main pool control -- a long packed with: + * AC: Number of active running workers minus target parallelism (16 bits) + * TC: Number of total workers minus target parallelism (16bits) + * ST: true if pool is terminating (1 bit) + * EC: the wait count of top waiting thread (15 bits) + * ID: ~poolIndex of top of Treiber stack of waiting threads (16 bits) * - * Notes: Most direct CASes are dependent on these bitfield - * positions. Also, this field is non-private to enable direct - * performance-sensitive CASes in ForkJoinWorkerThread. + * When convenient, we can extract the upper 32 bits of counts and + * the lower 32 bits of queue state, u = (int)(ctl >>> 32) and e = + * (int)ctl. The ec field is never accessed alone, but always + * together with id and st. The offsets of counts by the target + * parallelism and the positionings of fields makes it possible to + * perform the most common checks via sign tests of fields: When + * ac is negative, there are not enough active workers, when tc is + * negative, there are not enough total workers, when id is + * negative, there is at least one waiting worker, and when e is + * negative, the pool is terminating. To deal with these possibly + * negative fields, we use casts in and out of "short" and/or + * signed shifts to maintain signedness. */ - volatile int runState; + volatile long ctl; - // Note: The order among run level values matters. - private static final int RUNLEVEL_SHIFT = 16; - private static final int SHUTDOWN = 1 << RUNLEVEL_SHIFT; - private static final int TERMINATING = 1 << (RUNLEVEL_SHIFT + 1); - private static final int TERMINATED = 1 << (RUNLEVEL_SHIFT + 2); - private static final int ACTIVE_COUNT_MASK = (1 << RUNLEVEL_SHIFT) - 1; + // bit positions/shifts for fields + private static final int AC_SHIFT = 48; + private static final int TC_SHIFT = 32; + private static final int ST_SHIFT = 31; + private static final int EC_SHIFT = 16; - /** - * Holds number of total (i.e., created and not yet terminated) - * and running (i.e., not blocked on joins or other managed sync) - * threads, packed together to ensure consistent snapshot when - * making decisions about creating and suspending spare - * threads. Updated only by CAS. Note that adding a new worker - * requires incrementing both counts, since workers start off in - * running state. - */ - private volatile int workerCounts; + // bounds + private static final int MAX_ID = 0x7fff; // max poolIndex + private static final int SMASK = 0xffff; // mask short bits + private static final int SHORT_SIGN = 1 << 15; + private static final int INT_SIGN = 1 << 31; - private static final int TOTAL_COUNT_SHIFT = 16; - private static final int RUNNING_COUNT_MASK = (1 << TOTAL_COUNT_SHIFT) - 1; - private static final int ONE_RUNNING = 1; - private static final int ONE_TOTAL = 1 << TOTAL_COUNT_SHIFT; + // masks + private static final long STOP_BIT = 0x0001L << ST_SHIFT; + private static final long AC_MASK = ((long)SMASK) << AC_SHIFT; + private static final long TC_MASK = ((long)SMASK) << TC_SHIFT; + + // units for incrementing and decrementing + private static final long TC_UNIT = 1L << TC_SHIFT; + private static final long AC_UNIT = 1L << AC_SHIFT; + + // masks and units for dealing with u = (int)(ctl >>> 32) + private static final int UAC_SHIFT = AC_SHIFT - 32; + private static final int UTC_SHIFT = TC_SHIFT - 32; + private static final int UAC_MASK = SMASK << UAC_SHIFT; + private static final int UTC_MASK = SMASK << UTC_SHIFT; + private static final int UAC_UNIT = 1 << UAC_SHIFT; + private static final int UTC_UNIT = 1 << UTC_SHIFT; + + // masks and units for dealing with e = (int)ctl + private static final int E_MASK = 0x7fffffff; // no STOP_BIT + private static final int EC_UNIT = 1 << EC_SHIFT; /** * The target parallelism level. - * Accessed directly by ForkJoinWorkerThreads. */ final int parallelism; + /** + * Index (mod submission queue length) of next element to take + * from submission queue. Usage is identical to that for + * per-worker queues -- see ForkJoinWorkerThread internal + * documentation. + */ + volatile int queueBase; + + /** + * Index (mod submission queue length) of next element to add + * in submission queue. Usage is identical to that for + * per-worker queues -- see ForkJoinWorkerThread internal + * documentation. + */ + int queueTop; + + /** + * True when shutdown() has been called. + */ + volatile boolean shutdown; + /** * True if use local fifo, not default lifo, for local polling * Read by, and replicated by ForkJoinWorkerThreads @@ -601,139 +582,615 @@ public class ForkJoinPool extends AbstractExecutorService { final boolean locallyFifo; /** - * The uncaught exception handler used when any worker abruptly - * terminates. + * The number of threads in ForkJoinWorkerThreads.helpQuiescePool. + * When non-zero, suppresses automatic shutdown when active + * counts become zero. */ - private final Thread.UncaughtExceptionHandler ueh; + volatile int quiescerCount; /** - * Pool number, just for assigning useful names to worker threads + * The number of threads blocked in join. */ - private final int poolNumber; - - // Utilities for CASing fields. Note that most of these - // are usually manually inlined by callers + volatile int blockedCount; /** - * Increments running count part of workerCounts. + * Counter for worker Thread names (unrelated to their poolIndex) */ - final void incrementRunningCount() { - int c; - do {} while (!UNSAFE.compareAndSwapInt(this, workerCountsOffset, - c = workerCounts, - c + ONE_RUNNING)); - } + private volatile int nextWorkerNumber; /** - * Tries to increment running count part of workerCounts. + * The index for the next created worker. Accessed under scanGuard. */ - final boolean tryIncrementRunningCount() { - int c; - return UNSAFE.compareAndSwapInt(this, workerCountsOffset, - c = workerCounts, - c + ONE_RUNNING); - } + private int nextWorkerIndex; /** - * Tries to decrement running count unless already zero. + * SeqLock and index masking for updates to workers array. Locked + * when SG_UNIT is set. Unlocking clears bit by adding + * SG_UNIT. Staleness of read-only operations can be checked by + * comparing scanGuard to value before the reads. The low 16 bits + * (i.e, anding with SMASK) hold (the smallest power of two + * covering all worker indices, minus one, and is used to avoid + * dealing with large numbers of null slots when the workers array + * is overallocated. */ - final boolean tryDecrementRunningCount() { - int wc = workerCounts; - if ((wc & RUNNING_COUNT_MASK) == 0) - return false; - return UNSAFE.compareAndSwapInt(this, workerCountsOffset, - wc, wc - ONE_RUNNING); - } + volatile int scanGuard; + + private static final int SG_UNIT = 1 << 16; /** - * Forces decrement of encoded workerCounts, awaiting nonzero if - * (rarely) necessary when other count updates lag. + * The wakeup interval (in nanoseconds) for a worker waiting for a + * task when the pool is quiescent to instead try to shrink the + * number of workers. The exact value does not matter too + * much. It must be short enough to release resources during + * sustained periods of idleness, but not so short that threads + * are continually re-created. + */ + private static final long SHRINK_RATE = + 4L * 1000L * 1000L * 1000L; // 4 seconds + + /** + * Top-level loop for worker threads: On each step: if the + * previous step swept through all queues and found no tasks, or + * there are excess threads, then possibly blocks. Otherwise, + * scans for and, if found, executes a task. Returns when pool + * and/or worker terminate. * - * @param dr -- either zero or ONE_RUNNING - * @param dt -- either zero or ONE_TOTAL + * @param w the worker */ - private void decrementWorkerCounts(int dr, int dt) { - for (;;) { - int wc = workerCounts; - if ((wc & RUNNING_COUNT_MASK) - dr < 0 || - (wc >>> TOTAL_COUNT_SHIFT) - dt < 0) { - if ((runState & TERMINATED) != 0) - return; // lagging termination on a backout - Thread.yield(); + final void work(ForkJoinWorkerThread w) { + boolean swept = false; // true on empty scans + long c; + while (!w.terminate && (int)(c = ctl) >= 0) { + int a; // active count + if (!swept && (a = (int)(c >> AC_SHIFT)) <= 0) + swept = scan(w, a); + else if (tryAwaitWork(w, c)) + swept = false; + } + } + + // Signalling + + /** + * Wakes up or creates a worker. + */ + final void signalWork() { + /* + * The while condition is true if: (there is are too few total + * workers OR there is at least one waiter) AND (there are too + * few active workers OR the pool is terminating). The value + * of e distinguishes the remaining cases: zero (no waiters) + * for create, negative if terminating (in which case do + * nothing), else release a waiter. The secondary checks for + * release (non-null array etc) can fail if the pool begins + * terminating after the test, and don't impose any added cost + * because JVMs must perform null and bounds checks anyway. + */ + long c; int e, u; + while ((((e = (int)(c = ctl)) | (u = (int)(c >>> 32))) & + (INT_SIGN|SHORT_SIGN)) == (INT_SIGN|SHORT_SIGN) && e >= 0) { + if (e > 0) { // release a waiting worker + int i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws; + if ((ws = workers) == null || + (i = ~e & SMASK) >= ws.length || + (w = ws[i]) == null) + break; + long nc = (((long)(w.nextWait & E_MASK)) | + ((long)(u + UAC_UNIT) << 32)); + if (w.eventCount == e && + UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) { + w.eventCount = (e + EC_UNIT) & E_MASK; + if (w.parked) + UNSAFE.unpark(w); + break; + } + } + else if (UNSAFE.compareAndSwapLong + (this, ctlOffset, c, + (long)(((u + UTC_UNIT) & UTC_MASK) | + ((u + UAC_UNIT) & UAC_MASK)) << 32)) { + addWorker(); + break; } - if (UNSAFE.compareAndSwapInt(this, workerCountsOffset, - wc, wc - (dr + dt))) - return; } } /** - * Tries decrementing active count; fails on contention. - * Called when workers cannot find tasks to run. + * Variant of signalWork to help release waiters on rescans. + * Tries once to release a waiter if active count < 0. + * + * @return false if failed due to contention, else true */ - final boolean tryDecrementActiveCount() { - int c; - return UNSAFE.compareAndSwapInt(this, runStateOffset, - c = runState, c - 1); - } - - /** - * Advances to at least the given level. Returns true if not - * already in at least the given level. - */ - private boolean advanceRunLevel(int level) { - for (;;) { - int s = runState; - if ((s & level) != 0) + private boolean tryReleaseWaiter() { + long c; int e, i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws; + if ((e = (int)(c = ctl)) > 0 && + (int)(c >> AC_SHIFT) < 0 && + (ws = workers) != null && + (i = ~e & SMASK) < ws.length && + (w = ws[i]) != null) { + long nc = ((long)(w.nextWait & E_MASK) | + ((c + AC_UNIT) & (AC_MASK|TC_MASK))); + if (w.eventCount != e || + !UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) return false; - if (UNSAFE.compareAndSwapInt(this, runStateOffset, s, s | level)) - return true; + w.eventCount = (e + EC_UNIT) & E_MASK; + if (w.parked) + UNSAFE.unpark(w); } + return true; } - // workers array maintenance + // Scanning for tasks /** - * Records and returns a workers array index for new worker. + * Scans for and, if found, executes one task. Scans start at a + * random index of workers array, and randomly select the first + * (2*#workers)-1 probes, and then, if all empty, resort to 2 + * circular sweeps, which is necessary to check quiescence. and + * taking a submission only if no stealable tasks were found. The + * steal code inside the loop is a specialized form of + * ForkJoinWorkerThread.deqTask, followed bookkeeping to support + * helpJoinTask and signal propagation. The code for submission + * queues is almost identical. On each steal, the worker completes + * not only the task, but also all local tasks that this task may + * have generated. On detecting staleness or contention when + * trying to take a task, this method returns without finishing + * sweep, which allows global state rechecks before retry. + * + * @param w the worker + * @param a the number of active workers + * @return true if swept all queues without finding a task */ - private int recordWorker(ForkJoinWorkerThread w) { - // Try using slot totalCount-1. If not available, scan and/or resize - int k = (workerCounts >>> TOTAL_COUNT_SHIFT) - 1; - final ReentrantLock lock = this.workerLock; - lock.lock(); - try { - ForkJoinWorkerThread[] ws = workers; - int n = ws.length; - if (k < 0 || k >= n || ws[k] != null) { - for (k = 0; k < n && ws[k] != null; ++k) - ; - if (k == n) - ws = workers = Arrays.copyOf(ws, n << 1); + private boolean scan(ForkJoinWorkerThread w, int a) { + int g = scanGuard; // mask 0 avoids useless scans if only one active + int m = (parallelism == 1 - a && blockedCount == 0) ? 0 : g & SMASK; + ForkJoinWorkerThread[] ws = workers; + if (ws == null || ws.length <= m) // staleness check + return false; + for (int r = w.seed, k = r, j = -(m + m); j <= m + m; ++j) { + ForkJoinTask t; ForkJoinTask[] q; int b, i; + ForkJoinWorkerThread v = ws[k & m]; + if (v != null && (b = v.queueBase) != v.queueTop && + (q = v.queue) != null && (i = (q.length - 1) & b) >= 0) { + long u = (i << ASHIFT) + ABASE; + if ((t = q[i]) != null && v.queueBase == b && + UNSAFE.compareAndSwapObject(q, u, t, null)) { + int d = (v.queueBase = b + 1) - v.queueTop; + v.stealHint = w.poolIndex; + if (d != 0) + signalWork(); // propagate if nonempty + w.execTask(t); + } + r ^= r << 13; r ^= r >>> 17; w.seed = r ^ (r << 5); + return false; // store next seed } - ws[k] = w; - int c = eventCount; // advance event count to ensure visibility - UNSAFE.compareAndSwapInt(this, eventCountOffset, c, c+1); - } finally { - lock.unlock(); + else if (j < 0) { // xorshift + r ^= r << 13; r ^= r >>> 17; k = r ^= r << 5; + } + else + ++k; + } + if (scanGuard != g) // staleness check + return false; + else { // try to take submission + ForkJoinTask t; ForkJoinTask[] q; int b, i; + if ((b = queueBase) != queueTop && + (q = submissionQueue) != null && + (i = (q.length - 1) & b) >= 0) { + long u = (i << ASHIFT) + ABASE; + if ((t = q[i]) != null && queueBase == b && + UNSAFE.compareAndSwapObject(q, u, t, null)) { + queueBase = b + 1; + w.execTask(t); + } + return false; + } + return true; // all queues empty } - return k; } /** - * Nulls out record of worker in workers array. + * Tries to enqueue worker w in wait queue and await change in + * worker's eventCount. If the pool is quiescent, possibly + * terminates worker upon exit. Otherwise, before blocking, + * rescans queues to avoid missed signals. Upon finding work, + * releases at least one worker (which may be the current + * worker). Rescans restart upon detected staleness or failure to + * release due to contention. Note the unusual conventions about + * Thread.interrupt here and elsewhere: Because interrupts are + * used solely to alert threads to check termination, which is + * checked here anyway, we clear status (using Thread.interrupted) + * before any call to park, so that park does not immediately + * return due to status being set via some other unrelated call to + * interrupt in user code. + * + * @param w the calling worker + * @param c the ctl value on entry + * @return true if waited or another thread was released upon enq */ - private void forgetWorker(ForkJoinWorkerThread w) { - int idx = w.poolIndex; - // Locking helps method recordWorker avoid unnecessary expansion - final ReentrantLock lock = this.workerLock; + private boolean tryAwaitWork(ForkJoinWorkerThread w, long c) { + int v = w.eventCount; + w.nextWait = (int)c; // w's successor record + long nc = (long)(v & E_MASK) | ((c - AC_UNIT) & (AC_MASK|TC_MASK)); + if (ctl != c || !UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) { + long d = ctl; // return true if lost to a deq, to force scan + return (int)d != (int)c && ((d - c) & AC_MASK) >= 0L; + } + for (int sc = w.stealCount; sc != 0;) { // accumulate stealCount + long s = stealCount; + if (UNSAFE.compareAndSwapLong(this, stealCountOffset, s, s + sc)) + sc = w.stealCount = 0; + else if (w.eventCount != v) + return true; // update next time + } + if (parallelism + (int)(nc >> AC_SHIFT) == 0 && + blockedCount == 0 && quiescerCount == 0) + idleAwaitWork(w, nc, c, v); // quiescent + for (boolean rescanned = false;;) { + if (w.eventCount != v) + return true; + if (!rescanned) { + int g = scanGuard, m = g & SMASK; + ForkJoinWorkerThread[] ws = workers; + if (ws != null && m < ws.length) { + rescanned = true; + for (int i = 0; i <= m; ++i) { + ForkJoinWorkerThread u = ws[i]; + if (u != null) { + if (u.queueBase != u.queueTop && + !tryReleaseWaiter()) + rescanned = false; // contended + if (w.eventCount != v) + return true; + } + } + } + if (scanGuard != g || // stale + (queueBase != queueTop && !tryReleaseWaiter())) + rescanned = false; + if (!rescanned) + Thread.yield(); // reduce contention + else + Thread.interrupted(); // clear before park + } + else { + w.parked = true; // must recheck + if (w.eventCount != v) { + w.parked = false; + return true; + } + LockSupport.park(this); + rescanned = w.parked = false; + } + } + } + + /** + * If inactivating worker w has caused pool to become + * quiescent, check for pool termination, and wait for event + * for up to SHRINK_RATE nanosecs (rescans are unnecessary in + * this case because quiescence reflects consensus about lack + * of work). On timeout, if ctl has not changed, terminate the + * worker. Upon its termination (see deregisterWorker), it may + * wake up another worker to possibly repeat this process. + * + * @param w the calling worker + * @param currentCtl the ctl value after enqueuing w + * @param prevCtl the ctl value if w terminated + * @param v the eventCount w awaits change + */ + private void idleAwaitWork(ForkJoinWorkerThread w, long currentCtl, + long prevCtl, int v) { + if (w.eventCount == v) { + if (shutdown) + tryTerminate(false); + ForkJoinTask.helpExpungeStaleExceptions(); // help clean weak refs + while (ctl == currentCtl) { + long startTime = System.nanoTime(); + w.parked = true; + if (w.eventCount == v) // must recheck + LockSupport.parkNanos(this, SHRINK_RATE); + w.parked = false; + if (w.eventCount != v) + break; + else if (System.nanoTime() - startTime < SHRINK_RATE) + Thread.interrupted(); // spurious wakeup + else if (UNSAFE.compareAndSwapLong(this, ctlOffset, + currentCtl, prevCtl)) { + w.terminate = true; // restore previous + w.eventCount = ((int)currentCtl + EC_UNIT) & E_MASK; + break; + } + } + } + } + + // Submissions + + /** + * Enqueues the given task in the submissionQueue. Same idea as + * ForkJoinWorkerThread.pushTask except for use of submissionLock. + * + * @param t the task + */ + private void addSubmission(ForkJoinTask t) { + final ReentrantLock lock = this.submissionLock; lock.lock(); try { - ForkJoinWorkerThread[] ws = workers; - if (idx >= 0 && idx < ws.length && ws[idx] == w) // verify - ws[idx] = null; + ForkJoinTask[] q; int s, m; + if ((q = submissionQueue) != null) { // ignore if queue removed + long u = (((s = queueTop) & (m = q.length-1)) << ASHIFT)+ABASE; + UNSAFE.putOrderedObject(q, u, t); + queueTop = s + 1; + if (s - queueBase == m) + growSubmissionQueue(); + } } finally { lock.unlock(); } + signalWork(); + } + + // (pollSubmission is defined below with exported methods) + + /** + * Creates or doubles submissionQueue array. + * Basically identical to ForkJoinWorkerThread version. + */ + private void growSubmissionQueue() { + ForkJoinTask[] oldQ = submissionQueue; + int size = oldQ != null ? oldQ.length << 1 : INITIAL_QUEUE_CAPACITY; + if (size > MAXIMUM_QUEUE_CAPACITY) + throw new RejectedExecutionException("Queue capacity exceeded"); + if (size < INITIAL_QUEUE_CAPACITY) + size = INITIAL_QUEUE_CAPACITY; + ForkJoinTask[] q = submissionQueue = new ForkJoinTask[size]; + int mask = size - 1; + int top = queueTop; + int oldMask; + if (oldQ != null && (oldMask = oldQ.length - 1) >= 0) { + for (int b = queueBase; b != top; ++b) { + long u = ((b & oldMask) << ASHIFT) + ABASE; + Object x = UNSAFE.getObjectVolatile(oldQ, u); + if (x != null && UNSAFE.compareAndSwapObject(oldQ, u, x, null)) + UNSAFE.putObjectVolatile + (q, ((b & mask) << ASHIFT) + ABASE, x); + } + } + } + + // Blocking support + + /** + * Tries to increment blockedCount, decrement active count + * (sometimes implicitly) and possibly release or create a + * compensating worker in preparation for blocking. Fails + * on contention or termination. + * + * @return true if the caller can block, else should recheck and retry + */ + private boolean tryPreBlock() { + int b = blockedCount; + if (UNSAFE.compareAndSwapInt(this, blockedCountOffset, b, b + 1)) { + int pc = parallelism; + do { + ForkJoinWorkerThread[] ws; ForkJoinWorkerThread w; + int e, ac, tc, rc, i; + long c = ctl; + int u = (int)(c >>> 32); + if ((e = (int)c) < 0) { + // skip -- terminating + } + else if ((ac = (u >> UAC_SHIFT)) <= 0 && e != 0 && + (ws = workers) != null && + (i = ~e & SMASK) < ws.length && + (w = ws[i]) != null) { + long nc = ((long)(w.nextWait & E_MASK) | + (c & (AC_MASK|TC_MASK))); + if (w.eventCount == e && + UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) { + w.eventCount = (e + EC_UNIT) & E_MASK; + if (w.parked) + UNSAFE.unpark(w); + return true; // release an idle worker + } + } + else if ((tc = (short)(u >>> UTC_SHIFT)) >= 0 && ac + pc > 1) { + long nc = ((c - AC_UNIT) & AC_MASK) | (c & ~AC_MASK); + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) + return true; // no compensation needed + } + else if (tc + pc < MAX_ID) { + long nc = ((c + TC_UNIT) & TC_MASK) | (c & ~TC_MASK); + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) { + addWorker(); + return true; // create a replacement + } + } + // try to back out on any failure and let caller retry + } while (!UNSAFE.compareAndSwapInt(this, blockedCountOffset, + b = blockedCount, b - 1)); + } + return false; + } + + /** + * Decrements blockedCount and increments active count + */ + private void postBlock() { + long c; + do {} while (!UNSAFE.compareAndSwapLong(this, ctlOffset, // no mask + c = ctl, c + AC_UNIT)); + int b; + do {} while(!UNSAFE.compareAndSwapInt(this, blockedCountOffset, + b = blockedCount, b - 1)); + } + + /** + * Possibly blocks waiting for the given task to complete, or + * cancels the task if terminating. Fails to wait if contended. + * + * @param joinMe the task + */ + final void tryAwaitJoin(ForkJoinTask joinMe) { + int s; + Thread.interrupted(); // clear interrupts before checking termination + if (joinMe.status >= 0) { + if (tryPreBlock()) { + joinMe.tryAwaitDone(0L); + postBlock(); + } + else if ((ctl & STOP_BIT) != 0L) + joinMe.cancelIgnoringExceptions(); + } + } + + /** + * Possibly blocks the given worker waiting for joinMe to + * complete or timeout + * + * @param joinMe the task + * @param millis the wait time for underlying Object.wait + */ + final void timedAwaitJoin(ForkJoinTask joinMe, long nanos) { + while (joinMe.status >= 0) { + Thread.interrupted(); + if ((ctl & STOP_BIT) != 0L) { + joinMe.cancelIgnoringExceptions(); + break; + } + if (tryPreBlock()) { + long last = System.nanoTime(); + while (joinMe.status >= 0) { + long millis = TimeUnit.NANOSECONDS.toMillis(nanos); + if (millis <= 0) + break; + joinMe.tryAwaitDone(millis); + if (joinMe.status < 0) + break; + if ((ctl & STOP_BIT) != 0L) { + joinMe.cancelIgnoringExceptions(); + break; + } + long now = System.nanoTime(); + nanos -= now - last; + last = now; + } + postBlock(); + break; + } + } + } + + /** + * If necessary, compensates for blocker, and blocks + */ + private void awaitBlocker(ManagedBlocker blocker) + throws InterruptedException { + while (!blocker.isReleasable()) { + if (tryPreBlock()) { + try { + do {} while (!blocker.isReleasable() && !blocker.block()); + } finally { + postBlock(); + } + break; + } + } + } + + // Creating, registering and deregistring workers + + /** + * Tries to create and start a worker; minimally rolls back counts + * on failure. + */ + private void addWorker() { + Throwable ex = null; + ForkJoinWorkerThread t = null; + try { + t = factory.newThread(this); + } catch (Throwable e) { + ex = e; + } + if (t == null) { // null or exceptional factory return + long c; // adjust counts + do {} while (!UNSAFE.compareAndSwapLong + (this, ctlOffset, c = ctl, + (((c - AC_UNIT) & AC_MASK) | + ((c - TC_UNIT) & TC_MASK) | + (c & ~(AC_MASK|TC_MASK))))); + // Propagate exception if originating from an external caller + if (!tryTerminate(false) && ex != null && + !(Thread.currentThread() instanceof ForkJoinWorkerThread)) + UNSAFE.throwException(ex); + } + else + t.start(); + } + + /** + * Callback from ForkJoinWorkerThread constructor to assign a + * public name + */ + final String nextWorkerName() { + for (int n;;) { + if (UNSAFE.compareAndSwapInt(this, nextWorkerNumberOffset, + n = nextWorkerNumber, ++n)) + return workerNamePrefix + n; + } + } + + /** + * Callback from ForkJoinWorkerThread constructor to + * determine its poolIndex and record in workers array. + * + * @param w the worker + * @return the worker's pool index + */ + final int registerWorker(ForkJoinWorkerThread w) { + /* + * In the typical case, a new worker acquires the lock, uses + * next available index and returns quickly. Since we should + * not block callers (ultimately from signalWork or + * tryPreBlock) waiting for the lock needed to do this, we + * instead help release other workers while waiting for the + * lock. + */ + for (int g;;) { + ForkJoinWorkerThread[] ws; + if (((g = scanGuard) & SG_UNIT) == 0 && + UNSAFE.compareAndSwapInt(this, scanGuardOffset, + g, g | SG_UNIT)) { + int k = nextWorkerIndex; + try { + if ((ws = workers) != null) { // ignore on shutdown + int n = ws.length; + if (k < 0 || k >= n || ws[k] != null) { + for (k = 0; k < n && ws[k] != null; ++k) + ; + if (k == n) + ws = workers = Arrays.copyOf(ws, n << 1); + } + ws[k] = w; + nextWorkerIndex = k + 1; + int m = g & SMASK; + g = k >= m? ((m << 1) + 1) & SMASK : g + (SG_UNIT<<1); + } + } finally { + scanGuard = g; + } + return k; + } + else if ((ws = workers) != null) { // help release others + for (ForkJoinWorkerThread u : ws) { + if (u != null && u.queueBase != u.queueTop) { + if (tryReleaseWaiter()) + break; + } + } + } + } } /** @@ -743,415 +1200,46 @@ public class ForkJoinPool extends AbstractExecutorService { * * @param w the worker */ - final void workerTerminated(ForkJoinWorkerThread w) { - forgetWorker(w); - decrementWorkerCounts(w.isTrimmed() ? 0 : ONE_RUNNING, ONE_TOTAL); - while (w.stealCount != 0) // collect final count - tryAccumulateStealCount(w); - tryTerminate(false); - } - - // Waiting for and signalling events - - /** - * Releases workers blocked on a count not equal to current count. - * Normally called after precheck that eventWaiters isn't zero to - * avoid wasted array checks. Gives up upon a change in count or - * upon releasing four workers, letting others take over. - */ - private void releaseEventWaiters() { - ForkJoinWorkerThread[] ws = workers; - int n = ws.length; - long h = eventWaiters; - int ec = eventCount; - int releases = 4; - ForkJoinWorkerThread w; int id; - while ((id = (((int)h) & WAITER_ID_MASK) - 1) >= 0 && - (int)(h >>> EVENT_COUNT_SHIFT) != ec && - id < n && (w = ws[id]) != null) { - if (UNSAFE.compareAndSwapLong(this, eventWaitersOffset, - h, w.nextWaiter)) { - LockSupport.unpark(w); - if (--releases == 0) - break; + final void deregisterWorker(ForkJoinWorkerThread w, Throwable ex) { + int idx = w.poolIndex; + int sc = w.stealCount; + int steps = 0; + // Remove from array, adjust worker counts and collect steal count. + // We can intermix failed removes or adjusts with steal updates + do { + long s, c; + int g; + if (steps == 0 && ((g = scanGuard) & SG_UNIT) == 0 && + UNSAFE.compareAndSwapInt(this, scanGuardOffset, + g, g |= SG_UNIT)) { + ForkJoinWorkerThread[] ws = workers; + if (ws != null && idx >= 0 && + idx < ws.length && ws[idx] == w) + ws[idx] = null; // verify + nextWorkerIndex = idx; + scanGuard = g + SG_UNIT; + steps = 1; } - if (eventCount != ec) - break; - h = eventWaiters; + if (steps == 1 && + UNSAFE.compareAndSwapLong(this, ctlOffset, c = ctl, + (((c - AC_UNIT) & AC_MASK) | + ((c - TC_UNIT) & TC_MASK) | + (c & ~(AC_MASK|TC_MASK))))) + steps = 2; + if (sc != 0 && + UNSAFE.compareAndSwapLong(this, stealCountOffset, + s = stealCount, s + sc)) + sc = 0; + } while (steps != 2 || sc != 0); + if (!tryTerminate(false)) { + if (ex != null) // possibly replace if died abnormally + signalWork(); + else + tryReleaseWaiter(); } } - /** - * Tries to advance eventCount and releases waiters. Called only - * from workers. - */ - final void signalWork() { - int c; // try to increment event count -- CAS failure OK - UNSAFE.compareAndSwapInt(this, eventCountOffset, c = eventCount, c+1); - if (eventWaiters != 0L) - releaseEventWaiters(); - } - - /** - * Adds the given worker to event queue and blocks until - * terminating or event count advances from the given value - * - * @param w the calling worker thread - * @param ec the count - */ - private void eventSync(ForkJoinWorkerThread w, int ec) { - long nh = (((long)ec) << EVENT_COUNT_SHIFT) | ((long)(w.poolIndex+1)); - long h; - while ((runState < SHUTDOWN || !tryTerminate(false)) && - (((int)(h = eventWaiters) & WAITER_ID_MASK) == 0 || - (int)(h >>> EVENT_COUNT_SHIFT) == ec) && - eventCount == ec) { - if (UNSAFE.compareAndSwapLong(this, eventWaitersOffset, - w.nextWaiter = h, nh)) { - awaitEvent(w, ec); - break; - } - } - } - - /** - * Blocks the given worker (that has already been entered as an - * event waiter) until terminating or event count advances from - * the given value. The oldest (first) waiter uses a timed wait to - * occasionally one-by-one shrink the number of workers (to a - * minimum of one) if the pool has not been used for extended - * periods. - * - * @param w the calling worker thread - * @param ec the count - */ - private void awaitEvent(ForkJoinWorkerThread w, int ec) { - while (eventCount == ec) { - if (tryAccumulateStealCount(w)) { // transfer while idle - boolean untimed = (w.nextWaiter != 0L || - (workerCounts & RUNNING_COUNT_MASK) <= 1); - long startTime = untimed ? 0 : System.nanoTime(); - Thread.interrupted(); // clear/ignore interrupt - if (w.isTerminating() || eventCount != ec) - break; // recheck after clear - if (untimed) - LockSupport.park(w); - else { - LockSupport.parkNanos(w, SHRINK_RATE_NANOS); - if (eventCount != ec || w.isTerminating()) - break; - if (System.nanoTime() - startTime >= SHRINK_RATE_NANOS) - tryShutdownUnusedWorker(ec); - } - } - } - } - - // Maintaining parallelism - - /** - * Pushes worker onto the spare stack. - */ - final void pushSpare(ForkJoinWorkerThread w) { - int ns = (++w.spareCount << SPARE_COUNT_SHIFT) | (w.poolIndex + 1); - do {} while (!UNSAFE.compareAndSwapInt(this, spareWaitersOffset, - w.nextSpare = spareWaiters,ns)); - } - - /** - * Tries (once) to resume a spare if the number of running - * threads is less than target. - */ - private void tryResumeSpare() { - int sw, id; - ForkJoinWorkerThread[] ws = workers; - int n = ws.length; - ForkJoinWorkerThread w; - if ((sw = spareWaiters) != 0 && - (id = (sw & SPARE_ID_MASK) - 1) >= 0 && - id < n && (w = ws[id]) != null && - (runState >= TERMINATING || - (workerCounts & RUNNING_COUNT_MASK) < parallelism) && - spareWaiters == sw && - UNSAFE.compareAndSwapInt(this, spareWaitersOffset, - sw, w.nextSpare)) { - int c; // increment running count before resume - do {} while (!UNSAFE.compareAndSwapInt - (this, workerCountsOffset, - c = workerCounts, c + ONE_RUNNING)); - if (w.tryUnsuspend()) - LockSupport.unpark(w); - else // back out if w was shutdown - decrementWorkerCounts(ONE_RUNNING, 0); - } - } - - /** - * Tries to increase the number of running workers if below target - * parallelism: If a spare exists tries to resume it via - * tryResumeSpare. Otherwise, if not enough total workers or all - * existing workers are busy, adds a new worker. In all cases also - * helps wake up releasable workers waiting for work. - */ - private void helpMaintainParallelism() { - int pc = parallelism; - int wc, rs, tc; - while (((wc = workerCounts) & RUNNING_COUNT_MASK) < pc && - (rs = runState) < TERMINATING) { - if (spareWaiters != 0) - tryResumeSpare(); - else if ((tc = wc >>> TOTAL_COUNT_SHIFT) >= MAX_WORKERS || - (tc >= pc && (rs & ACTIVE_COUNT_MASK) != tc)) - break; // enough total - else if (runState == rs && workerCounts == wc && - UNSAFE.compareAndSwapInt(this, workerCountsOffset, wc, - wc + (ONE_RUNNING|ONE_TOTAL))) { - ForkJoinWorkerThread w = null; - Throwable fail = null; - try { - w = factory.newThread(this); - } catch (Throwable ex) { - fail = ex; - } - if (w == null) { // null or exceptional factory return - decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL); - tryTerminate(false); // handle failure during shutdown - // If originating from an external caller, - // propagate exception, else ignore - if (fail != null && runState < TERMINATING && - !(Thread.currentThread() instanceof - ForkJoinWorkerThread)) - UNSAFE.throwException(fail); - break; - } - w.start(recordWorker(w), ueh); - if ((workerCounts >>> TOTAL_COUNT_SHIFT) >= pc) - break; // add at most one unless total below target - } - } - if (eventWaiters != 0L) - releaseEventWaiters(); - } - - /** - * Callback from the oldest waiter in awaitEvent waking up after a - * period of non-use. If all workers are idle, tries (once) to - * shutdown an event waiter or a spare, if one exists. Note that - * we don't need CAS or locks here because the method is called - * only from one thread occasionally waking (and even misfires are - * OK). Note that until the shutdown worker fully terminates, - * workerCounts will overestimate total count, which is tolerable. - * - * @param ec the event count waited on by caller (to abort - * attempt if count has since changed). - */ - private void tryShutdownUnusedWorker(int ec) { - if (runState == 0 && eventCount == ec) { // only trigger if all idle - ForkJoinWorkerThread[] ws = workers; - int n = ws.length; - ForkJoinWorkerThread w = null; - boolean shutdown = false; - int sw; - long h; - if ((sw = spareWaiters) != 0) { // prefer killing spares - int id = (sw & SPARE_ID_MASK) - 1; - if (id >= 0 && id < n && (w = ws[id]) != null && - UNSAFE.compareAndSwapInt(this, spareWaitersOffset, - sw, w.nextSpare)) - shutdown = true; - } - else if ((h = eventWaiters) != 0L) { - long nh; - int id = (((int)h) & WAITER_ID_MASK) - 1; - if (id >= 0 && id < n && (w = ws[id]) != null && - (nh = w.nextWaiter) != 0L && // keep at least one worker - UNSAFE.compareAndSwapLong(this, eventWaitersOffset, h, nh)) - shutdown = true; - } - if (w != null && shutdown) { - w.shutdown(); - LockSupport.unpark(w); - } - } - releaseEventWaiters(); // in case of interference - } - - /** - * Callback from workers invoked upon each top-level action (i.e., - * stealing a task or taking a submission and running it). - * Performs one or more of the following: - * - * 1. If the worker is active and either did not run a task - * or there are too many workers, try to set its active status - * to inactive and update activeCount. On contention, we may - * try again in this or a subsequent call. - * - * 2. If not enough total workers, help create some. - * - * 3. If there are too many running workers, suspend this worker - * (first forcing inactive if necessary). If it is not needed, - * it may be shutdown while suspended (via - * tryShutdownUnusedWorker). Otherwise, upon resume it - * rechecks running thread count and need for event sync. - * - * 4. If worker did not run a task, await the next task event via - * eventSync if necessary (first forcing inactivation), upon - * which the worker may be shutdown via - * tryShutdownUnusedWorker. Otherwise, help release any - * existing event waiters that are now releasable, - * - * @param w the worker - * @param ran true if worker ran a task since last call to this method - */ - final void preStep(ForkJoinWorkerThread w, boolean ran) { - int wec = w.lastEventCount; - boolean active = w.active; - boolean inactivate = false; - int pc = parallelism; - while (w.runState == 0) { - int rs = runState; - if (rs >= TERMINATING) { // propagate shutdown - w.shutdown(); - break; - } - if ((inactivate || (active && (rs & ACTIVE_COUNT_MASK) >= pc)) && - UNSAFE.compareAndSwapInt(this, runStateOffset, rs, --rs)) { - inactivate = active = w.active = false; - if (rs == SHUTDOWN) { // all inactive and shut down - tryTerminate(false); - continue; - } - } - int wc = workerCounts; // try to suspend as spare - if ((wc & RUNNING_COUNT_MASK) > pc) { - if (!(inactivate |= active) && // must inactivate to suspend - workerCounts == wc && - UNSAFE.compareAndSwapInt(this, workerCountsOffset, - wc, wc - ONE_RUNNING)) - w.suspendAsSpare(); - } - else if ((wc >>> TOTAL_COUNT_SHIFT) < pc) - helpMaintainParallelism(); // not enough workers - else if (ran) - break; - else { - long h = eventWaiters; - int ec = eventCount; - if (h != 0L && (int)(h >>> EVENT_COUNT_SHIFT) != ec) - releaseEventWaiters(); // release others before waiting - else if (ec != wec) { - w.lastEventCount = ec; // no need to wait - break; - } - else if (!(inactivate |= active)) - eventSync(w, wec); // must inactivate before sync - } - } - } - - /** - * Helps and/or blocks awaiting join of the given task. - * See above for explanation. - * - * @param joinMe the task to join - * @param worker the current worker thread - * @param timed true if wait should time out - * @param nanos timeout value if timed - */ - final void awaitJoin(ForkJoinTask joinMe, ForkJoinWorkerThread worker, - boolean timed, long nanos) { - long startTime = timed ? System.nanoTime() : 0L; - int retries = 2 + (parallelism >> 2); // #helpJoins before blocking - boolean running = true; // false when count decremented - while (joinMe.status >= 0) { - if (runState >= TERMINATING) { - joinMe.cancelIgnoringExceptions(); - break; - } - running = worker.helpJoinTask(joinMe, running); - if (joinMe.status < 0) - break; - if (retries > 0) { - --retries; - continue; - } - int wc = workerCounts; - if ((wc & RUNNING_COUNT_MASK) != 0) { - if (running) { - if (!UNSAFE.compareAndSwapInt(this, workerCountsOffset, - wc, wc - ONE_RUNNING)) - continue; - running = false; - } - long h = eventWaiters; - if (h != 0L && (int)(h >>> EVENT_COUNT_SHIFT) != eventCount) - releaseEventWaiters(); - if ((workerCounts & RUNNING_COUNT_MASK) != 0) { - long ms; int ns; - if (!timed) { - ms = JOIN_TIMEOUT_MILLIS; - ns = 0; - } - else { // at most JOIN_TIMEOUT_MILLIS per wait - long nt = nanos - (System.nanoTime() - startTime); - if (nt <= 0L) - break; - ms = nt / 1000000; - if (ms > JOIN_TIMEOUT_MILLIS) { - ms = JOIN_TIMEOUT_MILLIS; - ns = 0; - } - else - ns = (int) (nt % 1000000); - } - joinMe.internalAwaitDone(ms, ns); - } - if (joinMe.status < 0) - break; - } - helpMaintainParallelism(); - } - if (!running) { - int c; - do {} while (!UNSAFE.compareAndSwapInt - (this, workerCountsOffset, - c = workerCounts, c + ONE_RUNNING)); - } - } - - /** - * Same idea as awaitJoin, but no helping, retries, or timeouts. - */ - final void awaitBlocker(ManagedBlocker blocker) - throws InterruptedException { - while (!blocker.isReleasable()) { - int wc = workerCounts; - if ((wc & RUNNING_COUNT_MASK) == 0) - helpMaintainParallelism(); - else if (UNSAFE.compareAndSwapInt(this, workerCountsOffset, - wc, wc - ONE_RUNNING)) { - try { - while (!blocker.isReleasable()) { - long h = eventWaiters; - if (h != 0L && - (int)(h >>> EVENT_COUNT_SHIFT) != eventCount) - releaseEventWaiters(); - else if ((workerCounts & RUNNING_COUNT_MASK) == 0 && - runState < TERMINATING) - helpMaintainParallelism(); - else if (blocker.block()) - break; - } - } finally { - int c; - do {} while (!UNSAFE.compareAndSwapInt - (this, workerCountsOffset, - c = workerCounts, c + ONE_RUNNING)); - } - break; - } - } - } + // Shutdown and termination /** * Possibly initiates and/or completes termination. @@ -1161,97 +1249,132 @@ public class ForkJoinPool extends AbstractExecutorService { * @return true if now terminating or terminated */ private boolean tryTerminate(boolean now) { - if (now) - advanceRunLevel(SHUTDOWN); // ensure at least SHUTDOWN - else if (runState < SHUTDOWN || - !submissionQueue.isEmpty() || - (runState & ACTIVE_COUNT_MASK) != 0) - return false; - - if (advanceRunLevel(TERMINATING)) - startTerminating(); - - // Finish now if all threads terminated; else in some subsequent call - if ((workerCounts >>> TOTAL_COUNT_SHIFT) == 0) { - advanceRunLevel(TERMINATED); - termination.forceTermination(); + long c; + while (((c = ctl) & STOP_BIT) == 0) { + if (!now) { + if ((int)(c >> AC_SHIFT) != -parallelism) + return false; + if (!shutdown || blockedCount != 0 || quiescerCount != 0 || + queueBase != queueTop) { + if (ctl == c) // staleness check + return false; + continue; + } + } + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, c | STOP_BIT)) + startTerminating(); + } + if ((short)(c >>> TC_SHIFT) == -parallelism) { // signal when 0 workers + final ReentrantLock lock = this.submissionLock; + lock.lock(); + try { + termination.signalAll(); + } finally { + lock.unlock(); + } } return true; } /** - * Actions on transition to TERMINATING - * - * Runs up to four passes through workers: (0) shutting down each - * (without waking up if parked) to quickly spread notifications - * without unnecessary bouncing around event queues etc (1) wake - * up and help cancel tasks (2) interrupt (3) mop up races with - * interrupted workers + * Runs up to three passes through workers: (0) Setting + * termination status for each worker, followed by wakeups up to + * queued workers; (1) helping cancel tasks; (2) interrupting + * lagging threads (likely in external tasks, but possibly also + * blocked in joins). Each pass repeats previous steps because of + * potential lagging thread creation. */ private void startTerminating() { cancelSubmissions(); - for (int passes = 0; passes < 4 && workerCounts != 0; ++passes) { - int c; // advance event count - UNSAFE.compareAndSwapInt(this, eventCountOffset, - c = eventCount, c+1); - eventWaiters = 0L; // clobber lists - spareWaiters = 0; - for (ForkJoinWorkerThread w : workers) { - if (w != null) { - w.shutdown(); - if (passes > 0 && !w.isTerminated()) { - w.cancelTasks(); - LockSupport.unpark(w); - if (passes > 1 && !w.isInterrupted()) { - try { - w.interrupt(); - } catch (SecurityException ignore) { + for (int pass = 0; pass < 3; ++pass) { + ForkJoinWorkerThread[] ws = workers; + if (ws != null) { + for (ForkJoinWorkerThread w : ws) { + if (w != null) { + w.terminate = true; + if (pass > 0) { + w.cancelTasks(); + if (pass > 1 && !w.isInterrupted()) { + try { + w.interrupt(); + } catch (SecurityException ignore) { + } } } } } + terminateWaiters(); + } + } + } + + /** + * Polls and cancels all submissions. Called only during termination. + */ + private void cancelSubmissions() { + while (queueBase != queueTop) { + ForkJoinTask task = pollSubmission(); + if (task != null) { + try { + task.cancel(false); + } catch (Throwable ignore) { + } } } } /** - * Clears out and cancels submissions, ignoring exceptions. + * Tries to set the termination status of waiting workers, and + * then wakes them up (after which they will terminate). */ - private void cancelSubmissions() { - ForkJoinTask task; - while ((task = submissionQueue.poll()) != null) { - try { - task.cancel(false); - } catch (Throwable ignore) { + private void terminateWaiters() { + ForkJoinWorkerThread[] ws = workers; + if (ws != null) { + ForkJoinWorkerThread w; long c; int i, e; + int n = ws.length; + while ((i = ~(e = (int)(c = ctl)) & SMASK) < n && + (w = ws[i]) != null && w.eventCount == (e & E_MASK)) { + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, + (long)(w.nextWait & E_MASK) | + ((c + AC_UNIT) & AC_MASK) | + (c & (TC_MASK|STOP_BIT)))) { + w.terminate = true; + w.eventCount = e + EC_UNIT; + if (w.parked) + UNSAFE.unpark(w); + } } } } - // misc support for ForkJoinWorkerThread + // misc ForkJoinWorkerThread support /** - * Returns pool number. + * Increment or decrement quiescerCount. Needed only to prevent + * triggering shutdown if a worker is transiently inactive while + * checking quiescence. + * + * @param delta 1 for increment, -1 for decrement */ - final int getPoolNumber() { - return poolNumber; + final void addQuiescerCount(int delta) { + int c; + do {} while(!UNSAFE.compareAndSwapInt(this, quiescerCountOffset, + c = quiescerCount, c + delta)); } /** - * Tries to accumulate steal count from a worker, clearing - * the worker's value if successful. + * Directly increment or decrement active count without + * queuing. This method is used to transiently assert inactivation + * while checking quiescence. * - * @return true if worker steal count now zero + * @param delta 1 for increment, -1 for decrement */ - final boolean tryAccumulateStealCount(ForkJoinWorkerThread w) { - int sc = w.stealCount; - long c = stealCount; - // CAS even if zero, for fence effects - if (UNSAFE.compareAndSwapLong(this, stealCountOffset, c, c + sc)) { - if (sc != 0) - w.stealCount = 0; - return true; - } - return sc == 0; + final void addActiveCount(int delta) { + long d = delta < 0 ? -AC_UNIT : AC_UNIT; + long c; + do {} while (!UNSAFE.compareAndSwapLong(this, ctlOffset, c = ctl, + ((c + d) & AC_MASK) | + (c & ~AC_MASK))); } /** @@ -1259,16 +1382,17 @@ public class ForkJoinPool extends AbstractExecutorService { * active thread. */ final int idlePerActive() { - int pc = parallelism; // use parallelism, not rc - int ac = runState; // no mask -- artificially boosts during shutdown - // Use exact results for small values, saturate past 4 - return ((pc <= ac) ? 0 : - (pc >>> 1 <= ac) ? 1 : - (pc >>> 2 <= ac) ? 3 : - pc >>> 3); + // Approximate at powers of two for small values, saturate past 4 + int p = parallelism; + int a = p + (int)(ctl >> AC_SHIFT); + return (a > (p >>>= 1) ? 0 : + a > (p >>>= 1) ? 1 : + a > (p >>>= 1) ? 2 : + a > (p >>>= 1) ? 4 : + 8); } - // Public and protected methods + // Exported methods // Constructors @@ -1337,49 +1461,42 @@ public class ForkJoinPool extends AbstractExecutorService { checkPermission(); if (factory == null) throw new NullPointerException(); - if (parallelism <= 0 || parallelism > MAX_WORKERS) + if (parallelism <= 0 || parallelism > MAX_ID) throw new IllegalArgumentException(); this.parallelism = parallelism; this.factory = factory; this.ueh = handler; this.locallyFifo = asyncMode; - int arraySize = initialArraySizeFor(parallelism); - this.workers = new ForkJoinWorkerThread[arraySize]; - this.submissionQueue = new LinkedTransferQueue>(); - this.workerLock = new ReentrantLock(); - this.termination = new Phaser(1); - this.poolNumber = poolNumberGenerator.incrementAndGet(); - } - - /** - * Returns initial power of two size for workers array. - * @param pc the initial parallelism level - */ - private static int initialArraySizeFor(int pc) { - // If possible, initially allocate enough space for one spare - int size = pc < MAX_WORKERS ? pc + 1 : MAX_WORKERS; - // See Hackers Delight, sec 3.2. We know MAX_WORKERS < (1 >>> 16) - size |= size >>> 1; - size |= size >>> 2; - size |= size >>> 4; - size |= size >>> 8; - return size + 1; + long np = (long)(-parallelism); // offset ctl counts + this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK); + this.submissionQueue = new ForkJoinTask[INITIAL_QUEUE_CAPACITY]; + // initialize workers array with room for 2*parallelism if possible + int n = parallelism << 1; + if (n >= MAX_ID) + n = MAX_ID; + else { // See Hackers Delight, sec 3.2, where n < (1 << 16) + n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; + } + workers = new ForkJoinWorkerThread[n + 1]; + this.submissionLock = new ReentrantLock(); + this.termination = submissionLock.newCondition(); + StringBuilder sb = new StringBuilder("ForkJoinPool-"); + sb.append(poolNumberGenerator.incrementAndGet()); + sb.append("-worker-"); + this.workerNamePrefix = sb.toString(); } // Execution methods - /** - * Submits task and creates, starts, or resumes some workers if necessary - */ - private void doSubmit(ForkJoinTask task) { - submissionQueue.offer(task); - int c; // try to increment event count -- CAS failure OK - UNSAFE.compareAndSwapInt(this, eventCountOffset, c = eventCount, c+1); - helpMaintainParallelism(); - } - /** * Performs the given task, returning its result upon completion. + * If the computation encounters an unchecked Exception or Error, + * it is rethrown as the outcome of this invocation. Rethrown + * exceptions behave in the same way as regular exceptions, but, + * when possible, contain stack traces (as displayed for example + * using {@code ex.printStackTrace()}) of both the current thread + * as well as the thread actually encountering the exception; + * minimally only the latter. * * @param task the task * @return the task's result @@ -1388,16 +1505,16 @@ public class ForkJoinPool extends AbstractExecutorService { * scheduled for execution */ public T invoke(ForkJoinTask task) { + Thread t = Thread.currentThread(); if (task == null) throw new NullPointerException(); - if (runState >= SHUTDOWN) + if (shutdown) throw new RejectedExecutionException(); - Thread t = Thread.currentThread(); if ((t instanceof ForkJoinWorkerThread) && ((ForkJoinWorkerThread)t).pool == this) return task.invoke(); // bypass submit if in same pool else { - doSubmit(task); + addSubmission(task); return task.join(); } } @@ -1407,14 +1524,15 @@ public class ForkJoinPool extends AbstractExecutorService { * computation in the current pool, else submits as external task. */ private void forkOrSubmit(ForkJoinTask task) { - if (runState >= SHUTDOWN) - throw new RejectedExecutionException(); + ForkJoinWorkerThread w; Thread t = Thread.currentThread(); + if (shutdown) + throw new RejectedExecutionException(); if ((t instanceof ForkJoinWorkerThread) && - ((ForkJoinWorkerThread)t).pool == this) - task.fork(); + (w = (ForkJoinWorkerThread)t).pool == this) + w.pushTask(task); else - doSubmit(task); + addSubmission(task); } /** @@ -1571,7 +1689,7 @@ public class ForkJoinPool extends AbstractExecutorService { * @return the number of worker threads */ public int getPoolSize() { - return workerCounts >>> TOTAL_COUNT_SHIFT; + return parallelism + (short)(ctl >>> TC_SHIFT); } /** @@ -1593,7 +1711,8 @@ public class ForkJoinPool extends AbstractExecutorService { * @return the number of worker threads */ public int getRunningThreadCount() { - return workerCounts & RUNNING_COUNT_MASK; + int r = parallelism + (int)(ctl >> AC_SHIFT); + return r <= 0? 0 : r; // suppress momentarily negative values } /** @@ -1604,7 +1723,8 @@ public class ForkJoinPool extends AbstractExecutorService { * @return the number of active threads */ public int getActiveThreadCount() { - return runState & ACTIVE_COUNT_MASK; + int r = parallelism + (int)(ctl >> AC_SHIFT) + blockedCount; + return r <= 0? 0 : r; // suppress momentarily negative values } /** @@ -1619,7 +1739,7 @@ public class ForkJoinPool extends AbstractExecutorService { * @return {@code true} if all threads are currently idle */ public boolean isQuiescent() { - return (runState & ACTIVE_COUNT_MASK) == 0; + return parallelism + (int)(ctl >> AC_SHIFT) + blockedCount == 0; } /** @@ -1649,21 +1769,25 @@ public class ForkJoinPool extends AbstractExecutorService { */ public long getQueuedTaskCount() { long count = 0; - for (ForkJoinWorkerThread w : workers) - if (w != null) - count += w.getQueueSize(); + ForkJoinWorkerThread[] ws; + if ((short)(ctl >>> TC_SHIFT) > -parallelism && + (ws = workers) != null) { + for (ForkJoinWorkerThread w : ws) + if (w != null) + count -= w.queueBase - w.queueTop; // must read base first + } return count; } /** * Returns an estimate of the number of tasks submitted to this - * pool that have not yet begun executing. This method takes time - * proportional to the number of submissions. + * pool that have not yet begun executing. This method may take + * time proportional to the number of submissions. * * @return the number of queued submissions */ public int getQueuedSubmissionCount() { - return submissionQueue.size(); + return -queueBase + queueTop; } /** @@ -1673,7 +1797,7 @@ public class ForkJoinPool extends AbstractExecutorService { * @return {@code true} if there are any queued submissions */ public boolean hasQueuedSubmissions() { - return !submissionQueue.isEmpty(); + return queueBase != queueTop; } /** @@ -1684,7 +1808,19 @@ public class ForkJoinPool extends AbstractExecutorService { * @return the next submission, or {@code null} if none */ protected ForkJoinTask pollSubmission() { - return submissionQueue.poll(); + ForkJoinTask t; ForkJoinTask[] q; int b, i; + while ((b = queueBase) != queueTop && + (q = submissionQueue) != null && + (i = (q.length - 1) & b) >= 0) { + long u = (i << ASHIFT) + ABASE; + if ((t = q[i]) != null && + queueBase == b && + UNSAFE.compareAndSwapObject(q, u, t, null)) { + queueBase = b + 1; + return t; + } + } + return null; } /** @@ -1705,10 +1841,21 @@ public class ForkJoinPool extends AbstractExecutorService { * @return the number of elements transferred */ protected int drainTasksTo(Collection> c) { - int count = submissionQueue.drainTo(c); - for (ForkJoinWorkerThread w : workers) - if (w != null) - count += w.drainTasksTo(c); + int count = 0; + while (queueBase != queueTop) { + ForkJoinTask t = pollSubmission(); + if (t != null) { + c.add(t); + ++count; + } + } + ForkJoinWorkerThread[] ws; + if ((short)(ctl >>> TC_SHIFT) > -parallelism && + (ws = workers) != null) { + for (ForkJoinWorkerThread w : ws) + if (w != null) + count += w.drainTasksTo(c); + } return count; } @@ -1723,14 +1870,20 @@ public class ForkJoinPool extends AbstractExecutorService { long st = getStealCount(); long qt = getQueuedTaskCount(); long qs = getQueuedSubmissionCount(); - int wc = workerCounts; - int tc = wc >>> TOTAL_COUNT_SHIFT; - int rc = wc & RUNNING_COUNT_MASK; int pc = parallelism; - int rs = runState; - int ac = rs & ACTIVE_COUNT_MASK; + long c = ctl; + int tc = pc + (short)(c >>> TC_SHIFT); + int rc = pc + (int)(c >> AC_SHIFT); + if (rc < 0) // ignore transient negative + rc = 0; + int ac = rc + blockedCount; + String level; + if ((c & STOP_BIT) != 0) + level = (tc == 0)? "Terminated" : "Terminating"; + else + level = shutdown? "Shutting down" : "Running"; return super.toString() + - "[" + runLevelToString(rs) + + "[" + level + ", parallelism = " + pc + ", size = " + tc + ", active = " + ac + @@ -1741,13 +1894,6 @@ public class ForkJoinPool extends AbstractExecutorService { "]"; } - private static String runLevelToString(int s) { - return ((s & TERMINATED) != 0 ? "Terminated" : - ((s & TERMINATING) != 0 ? "Terminating" : - ((s & SHUTDOWN) != 0 ? "Shutting down" : - "Running"))); - } - /** * Initiates an orderly shutdown in which previously submitted * tasks are executed, but no new tasks will be accepted. @@ -1762,7 +1908,7 @@ public class ForkJoinPool extends AbstractExecutorService { */ public void shutdown() { checkPermission(); - advanceRunLevel(SHUTDOWN); + shutdown = true; tryTerminate(false); } @@ -1784,6 +1930,7 @@ public class ForkJoinPool extends AbstractExecutorService { */ public List shutdownNow() { checkPermission(); + shutdown = true; tryTerminate(true); return Collections.emptyList(); } @@ -1794,7 +1941,9 @@ public class ForkJoinPool extends AbstractExecutorService { * @return {@code true} if all tasks have completed following shut down */ public boolean isTerminated() { - return runState >= TERMINATED; + long c = ctl; + return ((c & STOP_BIT) != 0L && + (short)(c >>> TC_SHIFT) == -parallelism); } /** @@ -1811,14 +1960,16 @@ public class ForkJoinPool extends AbstractExecutorService { * @return {@code true} if terminating but not yet terminated */ public boolean isTerminating() { - return (runState & (TERMINATING|TERMINATED)) == TERMINATING; + long c = ctl; + return ((c & STOP_BIT) != 0L && + (short)(c >>> TC_SHIFT) != -parallelism); } /** * Returns true if terminating or terminated. Used by ForkJoinWorkerThread. */ final boolean isAtLeastTerminating() { - return runState >= TERMINATING; + return (ctl & STOP_BIT) != 0L; } /** @@ -1827,7 +1978,7 @@ public class ForkJoinPool extends AbstractExecutorService { * @return {@code true} if this pool has been shut down */ public boolean isShutdown() { - return runState >= SHUTDOWN; + return shutdown; } /** @@ -1843,12 +1994,20 @@ public class ForkJoinPool extends AbstractExecutorService { */ public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.submissionLock; + lock.lock(); try { - termination.awaitAdvanceInterruptibly(0, timeout, unit); - } catch (TimeoutException ex) { - return false; + for (;;) { + if (isTerminated()) + return true; + if (nanos <= 0) + return false; + nanos = termination.awaitNanos(nanos); + } + } finally { + lock.unlock(); } - return true; } /** @@ -1859,13 +2018,15 @@ public class ForkJoinPool extends AbstractExecutorService { * {@code isReleasable} must return {@code true} if blocking is * not necessary. Method {@code block} blocks the current thread * if necessary (perhaps internally invoking {@code isReleasable} - * before actually blocking). The unusual methods in this API - * accommodate synchronizers that may, but don't usually, block - * for long periods. Similarly, they allow more efficient internal - * handling of cases in which additional workers may be, but - * usually are not, needed to ensure sufficient parallelism. - * Toward this end, implementations of method {@code isReleasable} - * must be amenable to repeated invocation. + * before actually blocking). These actions are performed by any + * thread invoking {@link ForkJoinPool#managedBlock}. The + * unusual methods in this API accommodate synchronizers that may, + * but don't usually, block for long periods. Similarly, they + * allow more efficient internal handling of cases in which + * additional workers may be, but usually are not, needed to + * ensure sufficient parallelism. Toward this end, + * implementations of method {@code isReleasable} must be amenable + * to repeated invocation. * *

    For example, here is a ManagedBlocker based on a * ReentrantLock: @@ -1967,29 +2128,47 @@ public class ForkJoinPool extends AbstractExecutorService { } // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE; + private static final long ctlOffset; + private static final long stealCountOffset; + private static final long blockedCountOffset; + private static final long quiescerCountOffset; + private static final long scanGuardOffset; + private static final long nextWorkerNumberOffset; + private static final long ABASE; + private static final int ASHIFT; - private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe(); - private static final long workerCountsOffset = - objectFieldOffset("workerCounts", ForkJoinPool.class); - private static final long runStateOffset = - objectFieldOffset("runState", ForkJoinPool.class); - private static final long eventCountOffset = - objectFieldOffset("eventCount", ForkJoinPool.class); - private static final long eventWaitersOffset = - objectFieldOffset("eventWaiters", ForkJoinPool.class); - private static final long stealCountOffset = - objectFieldOffset("stealCount", ForkJoinPool.class); - private static final long spareWaitersOffset = - objectFieldOffset("spareWaiters", ForkJoinPool.class); - - private static long objectFieldOffset(String field, Class klazz) { + static { + poolNumberGenerator = new AtomicInteger(); + workerSeedGenerator = new Random(); + modifyThreadPermission = new RuntimePermission("modifyThread"); + defaultForkJoinWorkerThreadFactory = + new DefaultForkJoinWorkerThreadFactory(); + int s; try { - return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field)); - } catch (NoSuchFieldException e) { - // Convert Exception to corresponding Error - NoSuchFieldError error = new NoSuchFieldError(field); - error.initCause(e); - throw error; + UNSAFE = sun.misc.Unsafe.getUnsafe(); + Class k = ForkJoinPool.class; + ctlOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("ctl")); + stealCountOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("stealCount")); + blockedCountOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("blockedCount")); + quiescerCountOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("quiescerCount")); + scanGuardOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("scanGuard")); + nextWorkerNumberOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("nextWorkerNumber")); + Class a = ForkJoinTask[].class; + ABASE = UNSAFE.arrayBaseOffset(a); + s = UNSAFE.arrayIndexScale(a); + } catch (Exception e) { + throw new Error(e); } + if ((s & (s-1)) != 0) + throw new Error("data type scale not a power of two"); + ASHIFT = 31 - Integer.numberOfLeadingZeros(s); } + } diff --git a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java index b02323ffd6d..ee8ba8fcfab 100644 --- a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java @@ -41,7 +41,8 @@ import java.util.Collections; import java.util.List; import java.util.RandomAccess; import java.util.Map; -import java.util.WeakHashMap; +import java.lang.ref.WeakReference; +import java.lang.ref.ReferenceQueue; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; @@ -52,6 +53,8 @@ import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RunnableFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.ReentrantLock; +import java.lang.reflect.Constructor; /** * Abstract base class for tasks that run within a {@link ForkJoinPool}. @@ -95,7 +98,11 @@ import java.util.concurrent.TimeoutException; * rethrown to callers attempting to join them. These exceptions may * additionally include {@link RejectedExecutionException} stemming * from internal resource exhaustion, such as failure to allocate - * internal task queues. + * internal task queues. Rethrown exceptions behave in the same way as + * regular exceptions, but, when possible, contain stack traces (as + * displayed for example using {@code ex.printStackTrace()}) of both + * the thread that initiated the computation as well as the thread + * actually encountering the exception; minimally only the latter. * *

    The primary method for awaiting completion and extracting * results of a task is {@link #join}, but there are several variants: @@ -192,8 +199,7 @@ public abstract class ForkJoinTask implements Future, Serializable { * status maintenance (2) execution and awaiting completion (3) * user-level methods that additionally report results. This is * sometimes hard to see because this file orders exported methods - * in a way that flows well in javadocs. In particular, most - * join mechanics are in method quietlyJoin, below. + * in a way that flows well in javadocs. */ /* @@ -215,91 +221,67 @@ public abstract class ForkJoinTask implements Future, Serializable { /** The run status of this task */ volatile int status; // accessed directly by pool and workers - private static final int NORMAL = -1; private static final int CANCELLED = -2; private static final int EXCEPTIONAL = -3; private static final int SIGNAL = 1; - /** - * Table of exceptions thrown by tasks, to enable reporting by - * callers. Because exceptions are rare, we don't directly keep - * them with task objects, but instead use a weak ref table. Note - * that cancellation exceptions don't appear in the table, but are - * instead recorded as status values. - * TODO: Use ConcurrentReferenceHashMap - */ - static final Map, Throwable> exceptionMap = - Collections.synchronizedMap - (new WeakHashMap, Throwable>()); - - // Maintaining completion status - /** * Marks completion and wakes up threads waiting to join this task, * also clearing signal request bits. * * @param completion one of NORMAL, CANCELLED, EXCEPTIONAL + * @return completion status on exit */ - private void setCompletion(int completion) { - int s; - while ((s = status) >= 0) { + private int setCompletion(int completion) { + for (int s;;) { + if ((s = status) < 0) + return s; if (UNSAFE.compareAndSwapInt(this, statusOffset, s, completion)) { if (s != 0) synchronized (this) { notifyAll(); } - break; + return completion; } } } /** - * Records exception and sets exceptional completion. + * Tries to block a worker thread until completed or timed out. + * Uses Object.wait time argument conventions. + * May fail on contention or interrupt. * - * @return status on exit + * @param millis if > 0, wait time. */ - private void setExceptionalCompletion(Throwable rex) { - exceptionMap.put(this, rex); - setCompletion(EXCEPTIONAL); - } - - /** - * Blocks a worker thread until completed or timed out. Called - * only by pool. - */ - final void internalAwaitDone(long millis, int nanos) { - int s = status; - if ((s == 0 && - UNSAFE.compareAndSwapInt(this, statusOffset, 0, SIGNAL)) || - s > 0) { - try { // the odd construction reduces lock bias effects + final void tryAwaitDone(long millis) { + int s; + try { + if (((s = status) > 0 || + (s == 0 && + UNSAFE.compareAndSwapInt(this, statusOffset, 0, SIGNAL))) && + status > 0) { synchronized (this) { if (status > 0) - wait(millis, nanos); - else - notifyAll(); + wait(millis); } - } catch (InterruptedException ie) { - cancelIfTerminating(); } + } catch (InterruptedException ie) { + // caller must check termination } } /** * Blocks a non-worker-thread until completion. + * @return status upon completion */ - private void externalAwaitDone() { - if (status >= 0) { + private int externalAwaitDone() { + int s; + if ((s = status) >= 0) { boolean interrupted = false; synchronized (this) { - for (;;) { - int s = status; + while ((s = status) >= 0) { if (s == 0) UNSAFE.compareAndSwapInt(this, statusOffset, 0, SIGNAL); - else if (s < 0) { - notifyAll(); - break; - } else { try { wait(); @@ -312,53 +294,308 @@ public abstract class ForkJoinTask implements Future, Serializable { if (interrupted) Thread.currentThread().interrupt(); } + return s; } /** * Blocks a non-worker-thread until completion or interruption or timeout. */ - private void externalInterruptibleAwaitDone(boolean timed, long nanos) + private int externalInterruptibleAwaitDone(long millis) throws InterruptedException { + int s; if (Thread.interrupted()) throw new InterruptedException(); - if (status >= 0) { - long startTime = timed ? System.nanoTime() : 0L; + if ((s = status) >= 0) { synchronized (this) { - for (;;) { - long nt; - int s = status; + while ((s = status) >= 0) { if (s == 0) UNSAFE.compareAndSwapInt(this, statusOffset, 0, SIGNAL); - else if (s < 0) { - notifyAll(); + else { + wait(millis); + if (millis > 0L) + break; + } + } + } + } + return s; + } + + /** + * Primary execution method for stolen tasks. Unless done, calls + * exec and records status if completed, but doesn't wait for + * completion otherwise. + */ + final void doExec() { + if (status >= 0) { + boolean completed; + try { + completed = exec(); + } catch (Throwable rex) { + setExceptionalCompletion(rex); + return; + } + if (completed) + setCompletion(NORMAL); // must be outside try block + } + } + + /** + * Primary mechanics for join, get, quietlyJoin. + * @return status upon completion + */ + private int doJoin() { + Thread t; ForkJoinWorkerThread w; int s; boolean completed; + if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) { + if ((s = status) < 0) + return s; + if ((w = (ForkJoinWorkerThread)t).unpushTask(this)) { + try { + completed = exec(); + } catch (Throwable rex) { + return setExceptionalCompletion(rex); + } + if (completed) + return setCompletion(NORMAL); + } + return w.joinTask(this); + } + else + return externalAwaitDone(); + } + + /** + * Primary mechanics for invoke, quietlyInvoke. + * @return status upon completion + */ + private int doInvoke() { + int s; boolean completed; + if ((s = status) < 0) + return s; + try { + completed = exec(); + } catch (Throwable rex) { + return setExceptionalCompletion(rex); + } + if (completed) + return setCompletion(NORMAL); + else + return doJoin(); + } + + // Exception table support + + /** + * Table of exceptions thrown by tasks, to enable reporting by + * callers. Because exceptions are rare, we don't directly keep + * them with task objects, but instead use a weak ref table. Note + * that cancellation exceptions don't appear in the table, but are + * instead recorded as status values. + * + * Note: These statics are initialized below in static block. + */ + private static final ExceptionNode[] exceptionTable; + private static final ReentrantLock exceptionTableLock; + private static final ReferenceQueue exceptionTableRefQueue; + + /** + * Fixed capacity for exceptionTable. + */ + private static final int EXCEPTION_MAP_CAPACITY = 32; + + /** + * Key-value nodes for exception table. The chained hash table + * uses identity comparisons, full locking, and weak references + * for keys. The table has a fixed capacity because it only + * maintains task exceptions long enough for joiners to access + * them, so should never become very large for sustained + * periods. However, since we do not know when the last joiner + * completes, we must use weak references and expunge them. We do + * so on each operation (hence full locking). Also, some thread in + * any ForkJoinPool will call helpExpungeStaleExceptions when its + * pool becomes isQuiescent. + */ + static final class ExceptionNode extends WeakReference>{ + final Throwable ex; + ExceptionNode next; + final long thrower; // use id not ref to avoid weak cycles + ExceptionNode(ForkJoinTask task, Throwable ex, ExceptionNode next) { + super(task, exceptionTableRefQueue); + this.ex = ex; + this.next = next; + this.thrower = Thread.currentThread().getId(); + } + } + + /** + * Records exception and sets exceptional completion. + * + * @return status on exit + */ + private int setExceptionalCompletion(Throwable ex) { + int h = System.identityHashCode(this); + final ReentrantLock lock = exceptionTableLock; + lock.lock(); + try { + expungeStaleExceptions(); + ExceptionNode[] t = exceptionTable; + int i = h & (t.length - 1); + for (ExceptionNode e = t[i]; ; e = e.next) { + if (e == null) { + t[i] = new ExceptionNode(this, ex, t[i]); + break; + } + if (e.get() == this) // already present + break; + } + } finally { + lock.unlock(); + } + return setCompletion(EXCEPTIONAL); + } + + /** + * Removes exception node and clears status + */ + private void clearExceptionalCompletion() { + int h = System.identityHashCode(this); + final ReentrantLock lock = exceptionTableLock; + lock.lock(); + try { + ExceptionNode[] t = exceptionTable; + int i = h & (t.length - 1); + ExceptionNode e = t[i]; + ExceptionNode pred = null; + while (e != null) { + ExceptionNode next = e.next; + if (e.get() == this) { + if (pred == null) + t[i] = next; + else + pred.next = next; + break; + } + pred = e; + e = next; + } + expungeStaleExceptions(); + status = 0; + } finally { + lock.unlock(); + } + } + + /** + * Returns a rethrowable exception for the given task, if + * available. To provide accurate stack traces, if the exception + * was not thrown by the current thread, we try to create a new + * exception of the same type as the one thrown, but with the + * recorded exception as its cause. If there is no such + * constructor, we instead try to use a no-arg constructor, + * followed by initCause, to the same effect. If none of these + * apply, or any fail due to other exceptions, we return the + * recorded exception, which is still correct, although it may + * contain a misleading stack trace. + * + * @return the exception, or null if none + */ + private Throwable getThrowableException() { + if (status != EXCEPTIONAL) + return null; + int h = System.identityHashCode(this); + ExceptionNode e; + final ReentrantLock lock = exceptionTableLock; + lock.lock(); + try { + expungeStaleExceptions(); + ExceptionNode[] t = exceptionTable; + e = t[h & (t.length - 1)]; + while (e != null && e.get() != this) + e = e.next; + } finally { + lock.unlock(); + } + Throwable ex; + if (e == null || (ex = e.ex) == null) + return null; + if (e.thrower != Thread.currentThread().getId()) { + Class ec = ex.getClass(); + try { + Constructor noArgCtor = null; + Constructor[] cs = ec.getConstructors();// public ctors only + for (int i = 0; i < cs.length; ++i) { + Constructor c = cs[i]; + Class[] ps = c.getParameterTypes(); + if (ps.length == 0) + noArgCtor = c; + else if (ps.length == 1 && ps[0] == Throwable.class) + return (Throwable)(c.newInstance(ex)); + } + if (noArgCtor != null) { + Throwable wx = (Throwable)(noArgCtor.newInstance()); + wx.initCause(ex); + return wx; + } + } catch (Exception ignore) { + } + } + return ex; + } + + /** + * Poll stale refs and remove them. Call only while holding lock. + */ + private static void expungeStaleExceptions() { + for (Object x; (x = exceptionTableRefQueue.poll()) != null;) { + if (x instanceof ExceptionNode) { + ForkJoinTask key = ((ExceptionNode)x).get(); + ExceptionNode[] t = exceptionTable; + int i = System.identityHashCode(key) & (t.length - 1); + ExceptionNode e = t[i]; + ExceptionNode pred = null; + while (e != null) { + ExceptionNode next = e.next; + if (e == x) { + if (pred == null) + t[i] = next; + else + pred.next = next; break; } - else if (!timed) - wait(); - else if ((nt = nanos - (System.nanoTime()-startTime)) > 0L) - wait(nt / 1000000, (int)(nt % 1000000)); - else - break; + pred = e; + e = next; } } } } /** - * Unless done, calls exec and records status if completed, but - * doesn't wait for completion otherwise. Primary execution method - * for ForkJoinWorkerThread. + * If lock is available, poll stale refs and remove them. + * Called from ForkJoinPool when pools become quiescent. */ - final void quietlyExec() { - try { - if (status < 0 || !exec()) - return; - } catch (Throwable rex) { - setExceptionalCompletion(rex); - return; + static final void helpExpungeStaleExceptions() { + final ReentrantLock lock = exceptionTableLock; + if (lock.tryLock()) { + try { + expungeStaleExceptions(); + } finally { + lock.unlock(); + } } - setCompletion(NORMAL); // must be outside try block + } + + /** + * Report the result of invoke or join; called only upon + * non-normal return of internal versions. + */ + private V reportResult() { + int s; Throwable ex; + if ((s = status) == CANCELLED) + throw new CancellationException(); + if (s == EXCEPTIONAL && (ex = getThrowableException()) != null) + UNSAFE.throwException(ex); + return getRawResult(); } // public methods @@ -399,11 +636,10 @@ public abstract class ForkJoinTask implements Future, Serializable { * @return the computed result */ public final V join() { - quietlyJoin(); - Throwable ex; - if (status < NORMAL && (ex = getException()) != null) - UNSAFE.throwException(ex); - return getRawResult(); + if (doJoin() != NORMAL) + return reportResult(); + else + return getRawResult(); } /** @@ -415,11 +651,10 @@ public abstract class ForkJoinTask implements Future, Serializable { * @return the computed result */ public final V invoke() { - quietlyInvoke(); - Throwable ex; - if (status < NORMAL && (ex = getException()) != null) - UNSAFE.throwException(ex); - return getRawResult(); + if (doInvoke() != NORMAL) + return reportResult(); + else + return getRawResult(); } /** @@ -483,22 +718,16 @@ public abstract class ForkJoinTask implements Future, Serializable { } else if (i != 0) t.fork(); - else { - t.quietlyInvoke(); - if (ex == null && t.status < NORMAL) - ex = t.getException(); - } + else if (t.doInvoke() < NORMAL && ex == null) + ex = t.getException(); } for (int i = 1; i <= last; ++i) { ForkJoinTask t = tasks[i]; if (t != null) { if (ex != null) t.cancel(false); - else { - t.quietlyJoin(); - if (ex == null && t.status < NORMAL) - ex = t.getException(); - } + else if (t.doJoin() < NORMAL && ex == null) + ex = t.getException(); } } if (ex != null) @@ -546,22 +775,16 @@ public abstract class ForkJoinTask implements Future, Serializable { } else if (i != 0) t.fork(); - else { - t.quietlyInvoke(); - if (ex == null && t.status < NORMAL) - ex = t.getException(); - } + else if (t.doInvoke() < NORMAL && ex == null) + ex = t.getException(); } for (int i = 1; i <= last; ++i) { ForkJoinTask t = ts.get(i); if (t != null) { if (ex != null) t.cancel(false); - else { - t.quietlyJoin(); - if (ex == null && t.status < NORMAL) - ex = t.getException(); - } + else if (t.doJoin() < NORMAL && ex == null) + ex = t.getException(); } } if (ex != null) @@ -597,8 +820,7 @@ public abstract class ForkJoinTask implements Future, Serializable { * @return {@code true} if this task is now cancelled */ public boolean cancel(boolean mayInterruptIfRunning) { - setCompletion(CANCELLED); - return status == CANCELLED; + return setCompletion(CANCELLED) == CANCELLED; } /** @@ -614,21 +836,6 @@ public abstract class ForkJoinTask implements Future, Serializable { } } - /** - * Cancels if current thread is a terminating worker thread, - * ignoring any exceptions thrown by cancel. - */ - final void cancelIfTerminating() { - Thread t = Thread.currentThread(); - if ((t instanceof ForkJoinWorkerThread) && - ((ForkJoinWorkerThread) t).isTerminating()) { - try { - cancel(false); - } catch (Throwable ignore) { - } - } - } - public final boolean isDone() { return status < 0; } @@ -668,7 +875,7 @@ public abstract class ForkJoinTask implements Future, Serializable { int s = status; return ((s >= NORMAL) ? null : (s == CANCELLED) ? new CancellationException() : - exceptionMap.get(this)); + getThrowableException()); } /** @@ -726,19 +933,13 @@ public abstract class ForkJoinTask implements Future, Serializable { * member of a ForkJoinPool and was interrupted while waiting */ public final V get() throws InterruptedException, ExecutionException { - Thread t = Thread.currentThread(); - if (t instanceof ForkJoinWorkerThread) - quietlyJoin(); - else - externalInterruptibleAwaitDone(false, 0L); - int s = status; - if (s != NORMAL) { - Throwable ex; - if (s == CANCELLED) - throw new CancellationException(); - if (s == EXCEPTIONAL && (ex = exceptionMap.get(this)) != null) - throw new ExecutionException(ex); - } + int s = (Thread.currentThread() instanceof ForkJoinWorkerThread) ? + doJoin() : externalInterruptibleAwaitDone(0L); + Throwable ex; + if (s == CANCELLED) + throw new CancellationException(); + if (s == EXCEPTIONAL && (ex = getThrowableException()) != null) + throw new ExecutionException(ex); return getRawResult(); } @@ -758,20 +959,39 @@ public abstract class ForkJoinTask implements Future, Serializable { */ public final V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - long nanos = unit.toNanos(timeout); Thread t = Thread.currentThread(); - if (t instanceof ForkJoinWorkerThread) - ((ForkJoinWorkerThread)t).joinTask(this, true, nanos); - else - externalInterruptibleAwaitDone(true, nanos); + if (t instanceof ForkJoinWorkerThread) { + ForkJoinWorkerThread w = (ForkJoinWorkerThread) t; + long nanos = unit.toNanos(timeout); + if (status >= 0) { + boolean completed = false; + if (w.unpushTask(this)) { + try { + completed = exec(); + } catch (Throwable rex) { + setExceptionalCompletion(rex); + } + } + if (completed) + setCompletion(NORMAL); + else if (status >= 0 && nanos > 0) + w.pool.timedAwaitJoin(this, nanos); + } + } + else { + long millis = unit.toMillis(timeout); + if (millis > 0) + externalInterruptibleAwaitDone(millis); + } int s = status; if (s != NORMAL) { Throwable ex; if (s == CANCELLED) throw new CancellationException(); - if (s == EXCEPTIONAL && (ex = exceptionMap.get(this)) != null) + if (s != EXCEPTIONAL) + throw new TimeoutException(); + if ((ex = getThrowableException()) != null) throw new ExecutionException(ex); - throw new TimeoutException(); } return getRawResult(); } @@ -783,28 +1003,7 @@ public abstract class ForkJoinTask implements Future, Serializable { * known to have aborted. */ public final void quietlyJoin() { - Thread t; - if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) { - ForkJoinWorkerThread w = (ForkJoinWorkerThread) t; - if (status >= 0) { - if (w.unpushTask(this)) { - boolean completed; - try { - completed = exec(); - } catch (Throwable rex) { - setExceptionalCompletion(rex); - return; - } - if (completed) { - setCompletion(NORMAL); - return; - } - } - w.joinTask(this, false, 0L); - } - } - else - externalAwaitDone(); + doJoin(); } /** @@ -813,19 +1012,7 @@ public abstract class ForkJoinTask implements Future, Serializable { * exception. */ public final void quietlyInvoke() { - if (status >= 0) { - boolean completed; - try { - completed = exec(); - } catch (Throwable rex) { - setExceptionalCompletion(rex); - return; - } - if (completed) - setCompletion(NORMAL); - else - quietlyJoin(); - } + doInvoke(); } /** @@ -864,8 +1051,9 @@ public abstract class ForkJoinTask implements Future, Serializable { */ public void reinitialize() { if (status == EXCEPTIONAL) - exceptionMap.remove(this); - status = 0; + clearExceptionalCompletion(); + else + status = 0; } /** @@ -1176,23 +1364,23 @@ public abstract class ForkJoinTask implements Future, Serializable { s.defaultReadObject(); Object ex = s.readObject(); if (ex != null) - setExceptionalCompletion((Throwable) ex); + setExceptionalCompletion((Throwable)ex); } // Unsafe mechanics - - private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe(); - private static final long statusOffset = - objectFieldOffset("status", ForkJoinTask.class); - - private static long objectFieldOffset(String field, Class klazz) { + private static final sun.misc.Unsafe UNSAFE; + private static final long statusOffset; + static { + exceptionTableLock = new ReentrantLock(); + exceptionTableRefQueue = new ReferenceQueue(); + exceptionTable = new ExceptionNode[EXCEPTION_MAP_CAPACITY]; try { - return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field)); - } catch (NoSuchFieldException e) { - // Convert Exception to corresponding Error - NoSuchFieldError error = new NoSuchFieldError(field); - error.initCause(e); - throw error; + UNSAFE = sun.misc.Unsafe.getUnsafe(); + statusOffset = UNSAFE.objectFieldOffset + (ForkJoinTask.class.getDeclaredField("status")); + } catch (Exception e) { + throw new Error(e); } } + } diff --git a/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java b/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java index 7d79c5190e2..2f48080a664 100644 --- a/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java @@ -35,9 +35,7 @@ package java.util.concurrent; -import java.util.Random; import java.util.Collection; -import java.util.concurrent.locks.LockSupport; import java.util.concurrent.RejectedExecutionException; /** @@ -84,33 +82,38 @@ public class ForkJoinWorkerThread extends Thread { * a footprint as possible even in programs generating huge * numbers of tasks. To accomplish this, we shift the CAS * arbitrating pop vs deq (steal) from being on the indices - * ("base" and "sp") to the slots themselves (mainly via method - * "casSlotNull()"). So, both a successful pop and deq mainly - * entail a CAS of a slot from non-null to null. Because we rely - * on CASes of references, we do not need tag bits on base or sp. - * They are simple ints as used in any circular array-based queue - * (see for example ArrayDeque). Updates to the indices must - * still be ordered in a way that guarantees that sp == base means - * the queue is empty, but otherwise may err on the side of - * possibly making the queue appear nonempty when a push, pop, or - * deq have not fully committed. Note that this means that the deq - * operation, considered individually, is not wait-free. One thief - * cannot successfully continue until another in-progress one (or, - * if previously empty, a push) completes. However, in the + * ("queueBase" and "queueTop") to the slots themselves (mainly + * via method "casSlotNull()"). So, both a successful pop and deq + * mainly entail a CAS of a slot from non-null to null. Because + * we rely on CASes of references, we do not need tag bits on + * queueBase or queueTop. They are simple ints as used in any + * circular array-based queue (see for example ArrayDeque). + * Updates to the indices must still be ordered in a way that + * guarantees that queueTop == queueBase means the queue is empty, + * but otherwise may err on the side of possibly making the queue + * appear nonempty when a push, pop, or deq have not fully + * committed. Note that this means that the deq operation, + * considered individually, is not wait-free. One thief cannot + * successfully continue until another in-progress one (or, if + * previously empty, a push) completes. However, in the * aggregate, we ensure at least probabilistic non-blockingness. * If an attempted steal fails, a thief always chooses a different * random victim target to try next. So, in order for one thief to * progress, it suffices for any in-progress deq or new push on - * any empty queue to complete. One reason this works well here is - * that apparently-nonempty often means soon-to-be-stealable, - * which gives threads a chance to set activation status if - * necessary before stealing. + * any empty queue to complete. * * This approach also enables support for "async mode" where local * task processing is in FIFO, not LIFO order; simply by using a * version of deq rather than pop when locallyFifo is true (as set * by the ForkJoinPool). This allows use in message-passing - * frameworks in which tasks are never joined. + * frameworks in which tasks are never joined. However neither + * mode considers affinities, loads, cache localities, etc, so + * rarely provide the best possible performance on a given + * machine, but portably provide good throughput by averaging over + * these factors. (Further, even if we did try to use such + * information, we do not usually have a basis for exploiting + * it. For example, some sets of tasks profit from cache + * affinities, but others are harmed by cache pollution effects.) * * When a worker would otherwise be blocked waiting to join a * task, it first tries a form of linear helping: Each worker @@ -137,29 +140,26 @@ public class ForkJoinWorkerThread extends Thread { * miss links in the chain during long-lived tasks, GC stalls etc * (which is OK since blocking in such cases is usually a good * idea). (4) We bound the number of attempts to find work (see - * MAX_HELP_DEPTH) and fall back to suspending the worker and if - * necessary replacing it with a spare (see - * ForkJoinPool.awaitJoin). + * MAX_HELP) and fall back to suspending the worker and if + * necessary replacing it with another. * * Efficient implementation of these algorithms currently relies * on an uncomfortable amount of "Unsafe" mechanics. To maintain - * correct orderings, reads and writes of variable base require - * volatile ordering. Variable sp does not require volatile - * writes but still needs store-ordering, which we accomplish by - * pre-incrementing sp before filling the slot with an ordered - * store. (Pre-incrementing also enables backouts used in - * joinTask.) Because they are protected by volatile base reads, - * reads of the queue array and its slots by other threads do not - * need volatile load semantics, but writes (in push) require - * store order and CASes (in pop and deq) require (volatile) CAS - * semantics. (Michael, Saraswat, and Vechev's algorithm has - * similar properties, but without support for nulling slots.) - * Since these combinations aren't supported using ordinary - * volatiles, the only way to accomplish these efficiently is to - * use direct Unsafe calls. (Using external AtomicIntegers and - * AtomicReferenceArrays for the indices and array is - * significantly slower because of memory locality and indirection - * effects.) + * correct orderings, reads and writes of variable queueBase + * require volatile ordering. Variable queueTop need not be + * volatile because non-local reads always follow those of + * queueBase. Similarly, because they are protected by volatile + * queueBase reads, reads of the queue array and its slots by + * other threads do not need volatile load semantics, but writes + * (in push) require store order and CASes (in pop and deq) + * require (volatile) CAS semantics. (Michael, Saraswat, and + * Vechev's algorithm has similar properties, but without support + * for nulling slots.) Since these combinations aren't supported + * using ordinary volatiles, the only way to accomplish these + * efficiently is to use direct Unsafe calls. (Using external + * AtomicIntegers and AtomicReferenceArrays for the indices and + * array is significantly slower because of memory locality and + * indirection effects.) * * Further, performance on most platforms is very sensitive to * placement and sizing of the (resizable) queue array. Even @@ -167,30 +167,13 @@ public class ForkJoinWorkerThread extends Thread { * initial size must be large enough to counteract cache * contention effects across multiple queues (especially in the * presence of GC cardmarking). Also, to improve thread-locality, - * queues are initialized after starting. All together, these - * low-level implementation choices produce as much as a factor of - * 4 performance improvement compared to naive implementations, - * and enable the processing of billions of tasks per second, - * sometimes at the expense of ugliness. + * queues are initialized after starting. */ /** - * Generator for initial random seeds for random victim - * selection. This is used only to create initial seeds. Random - * steals use a cheaper xorshift generator per steal attempt. We - * expect only rare contention on seedGenerator, so just use a - * plain Random. + * Mask for pool indices encoded as shorts */ - private static final Random seedGenerator = new Random(); - - /** - * The maximum stolen->joining link depth allowed in helpJoinTask. - * Depths for legitimate chains are unbounded, but we use a fixed - * constant to avoid (otherwise unchecked) cycles and bound - * staleness of traversal parameters at the expense of sometimes - * blocking when we could be helping. - */ - private static final int MAX_HELP_DEPTH = 8; + private static final int SMASK = 0xffff; /** * Capacity of work-stealing queue array upon initialization. @@ -200,12 +183,19 @@ public class ForkJoinWorkerThread extends Thread { private static final int INITIAL_QUEUE_CAPACITY = 1 << 13; /** - * Maximum work-stealing queue array size. Must be less than or - * equal to 1 << (31 - width of array entry) to ensure lack of - * index wraparound. The value is set in the static block - * at the end of this file after obtaining width. + * Maximum size for queue array. Must be a power of two + * less than or equal to 1 << (31 - width of array entry) to + * ensure lack of index wraparound, but is capped at a lower + * value to help users trap runaway computations. */ - private static final int MAXIMUM_QUEUE_CAPACITY; + private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 24; // 16M + + /** + * The work-stealing queue array. Size must be a power of two. + * Initialized when started (as oposed to when constructed), to + * improve memory locality. + */ + ForkJoinTask[] queue; /** * The pool this thread works in. Accessed directly by ForkJoinTask. @@ -213,25 +203,19 @@ public class ForkJoinWorkerThread extends Thread { final ForkJoinPool pool; /** - * The work-stealing queue array. Size must be a power of two. - * Initialized in onStart, to improve memory locality. + * Index (mod queue.length) of next queue slot to push to or pop + * from. It is written only by owner thread, and accessed by other + * threads only after reading (volatile) queueBase. Both queueTop + * and queueBase are allowed to wrap around on overflow, but + * (queueTop - queueBase) still estimates size. */ - private ForkJoinTask[] queue; + int queueTop; /** * Index (mod queue.length) of least valid queue slot, which is * always the next position to steal from if nonempty. */ - private volatile int base; - - /** - * Index (mod queue.length) of next queue slot to push to or pop - * from. It is written only by owner thread, and accessed by other - * threads only after reading (volatile) base. Both sp and base - * are allowed to wrap around on overflow, but (sp - base) still - * estimates size. - */ - private int sp; + volatile int queueBase; /** * The index of most recent stealer, used as a hint to avoid @@ -240,92 +224,68 @@ public class ForkJoinWorkerThread extends Thread { * of them (usually the most current). Declared non-volatile, * relying on other prevailing sync to keep reasonably current. */ - private int stealHint; - - /** - * Run state of this worker. In addition to the usual run levels, - * tracks if this worker is suspended as a spare, and if it was - * killed (trimmed) while suspended. However, "active" status is - * maintained separately and modified only in conjunction with - * CASes of the pool's runState (which are currently sadly - * manually inlined for performance.) Accessed directly by pool - * to simplify checks for normal (zero) status. - */ - volatile int runState; - - private static final int TERMINATING = 0x01; - private static final int TERMINATED = 0x02; - private static final int SUSPENDED = 0x04; // inactive spare - private static final int TRIMMED = 0x08; // killed while suspended - - /** - * Number of steals. Directly accessed (and reset) by - * pool.tryAccumulateStealCount when idle. - */ - int stealCount; - - /** - * Seed for random number generator for choosing steal victims. - * Uses Marsaglia xorshift. Must be initialized as nonzero. - */ - private int seed; - - /** - * Activity status. When true, this worker is considered active. - * Accessed directly by pool. Must be false upon construction. - */ - boolean active; - - /** - * True if use local fifo, not default lifo, for local polling. - * Shadows value from ForkJoinPool. - */ - private final boolean locallyFifo; + int stealHint; /** * Index of this worker in pool array. Set once by pool before * running, and accessed directly by pool to locate this worker in * its workers array. */ - int poolIndex; + final int poolIndex; /** - * The last pool event waited for. Accessed only by pool in - * callback methods invoked within this thread. + * Encoded record for pool task waits. Usages are always + * surrounded by volatile reads/writes */ - int lastEventCount; + int nextWait; /** - * Encoded index and event count of next event waiter. Accessed - * only by ForkJoinPool for managing event waiters. + * Complement of poolIndex, offset by count of entries of task + * waits. Accessed by ForkJoinPool to manage event waiters. */ - volatile long nextWaiter; + volatile int eventCount; /** - * Number of times this thread suspended as spare. Accessed only - * by pool. + * Seed for random number generator for choosing steal victims. + * Uses Marsaglia xorshift. Must be initialized as nonzero. */ - int spareCount; + int seed; /** - * Encoded index and count of next spare waiter. Accessed only - * by ForkJoinPool for managing spares. + * Number of steals. Directly accessed (and reset) by pool when + * idle. */ - volatile int nextSpare; + int stealCount; /** - * The task currently being joined, set only when actively trying - * to help other stealers in helpJoinTask. Written only by this - * thread, but read by others. + * True if this worker should or did terminate */ - private volatile ForkJoinTask currentJoin; + volatile boolean terminate; + + /** + * Set to true before LockSupport.park; false on return + */ + volatile boolean parked; + + /** + * True if use local fifo, not default lifo, for local polling. + * Shadows value from ForkJoinPool. + */ + final boolean locallyFifo; /** * The task most recently stolen from another worker (or - * submission queue). Written only by this thread, but read by - * others. + * submission queue). All uses are surrounded by enough volatile + * reads/writes to maintain as non-volatile. */ - private volatile ForkJoinTask currentSteal; + ForkJoinTask currentSteal; + + /** + * The task currently being joined, set only when actively trying + * to help other stealers in helpJoinTask. All uses are surrounded + * by enough volatile reads/writes to maintain as non-volatile. + */ + ForkJoinTask currentJoin; /** * Creates a ForkJoinWorkerThread operating in the given pool. @@ -334,24 +294,19 @@ public class ForkJoinWorkerThread extends Thread { * @throws NullPointerException if pool is null */ protected ForkJoinWorkerThread(ForkJoinPool pool) { + super(pool.nextWorkerName()); this.pool = pool; - this.locallyFifo = pool.locallyFifo; - setDaemon(true); - // To avoid exposing construction details to subclasses, - // remaining initialization is in start() and onStart() - } - - /** - * Performs additional initialization and starts this thread. - */ - final void start(int poolIndex, UncaughtExceptionHandler ueh) { - this.poolIndex = poolIndex; + int k = pool.registerWorker(this); + poolIndex = k; + eventCount = ~k & SMASK; // clear wait count + locallyFifo = pool.locallyFifo; + Thread.UncaughtExceptionHandler ueh = pool.ueh; if (ueh != null) setUncaughtExceptionHandler(ueh); - start(); + setDaemon(true); } - // Public/protected methods + // Public methods /** * Returns the pool hosting this thread. @@ -375,6 +330,25 @@ public class ForkJoinWorkerThread extends Thread { return poolIndex; } + // Randomization + + /** + * Computes next value for random victim probes and backoffs. + * Scans don't require a very high quality generator, but also not + * a crummy one. Marsaglia xor-shift is cheap and works well + * enough. Note: This is manually inlined in FJP.scan() to avoid + * writes inside busy loops. + */ + private int nextSeed() { + int r = seed; + r ^= r << 13; + r ^= r >>> 17; + r ^= r << 5; + return seed = r; + } + + // Run State management + /** * Initializes internal state after construction but before * processing any tasks. If you override this method, you must @@ -385,15 +359,9 @@ public class ForkJoinWorkerThread extends Thread { * processing tasks. */ protected void onStart() { - int rs = seedGenerator.nextInt(); - seed = (rs == 0) ? 1 : rs; // seed must be nonzero - - // Allocate name string and arrays in this thread - String pid = Integer.toString(pool.getPoolNumber()); - String wid = Integer.toString(poolIndex); - setName("ForkJoinPool-" + pid + "-worker-" + wid); - queue = new ForkJoinTask[INITIAL_QUEUE_CAPACITY]; + int r = pool.workerSeedGenerator.nextInt(); + seed = (r == 0)? 1 : r; // must be nonzero } /** @@ -406,16 +374,9 @@ public class ForkJoinWorkerThread extends Thread { */ protected void onTermination(Throwable exception) { try { - ForkJoinPool p = pool; - if (active) { - int a; // inline p.tryDecrementActiveCount - active = false; - do {} while (!UNSAFE.compareAndSwapInt - (p, poolRunStateOffset, a = p.runState, a - 1)); - } + terminate = true; cancelTasks(); - setTerminated(); - p.workerTerminated(this); + pool.deregisterWorker(this, exception); } catch (Throwable ex) { // Shouldn't ever happen if (exception == null) // but if so, at least rethrown exception = ex; @@ -434,7 +395,7 @@ public class ForkJoinWorkerThread extends Thread { Throwable exception = null; try { onStart(); - mainLoop(); + pool.work(this); } catch (Throwable ex) { exception = ex; } finally { @@ -442,81 +403,6 @@ public class ForkJoinWorkerThread extends Thread { } } - // helpers for run() - - /** - * Finds and executes tasks, and checks status while running. - */ - private void mainLoop() { - boolean ran = false; // true if ran a task on last step - ForkJoinPool p = pool; - for (;;) { - p.preStep(this, ran); - if (runState != 0) - break; - ran = tryExecSteal() || tryExecSubmission(); - } - } - - /** - * Tries to steal a task and execute it. - * - * @return true if ran a task - */ - private boolean tryExecSteal() { - ForkJoinTask t; - if ((t = scan()) != null) { - t.quietlyExec(); - UNSAFE.putOrderedObject(this, currentStealOffset, null); - if (sp != base) - execLocalTasks(); - return true; - } - return false; - } - - /** - * If a submission exists, try to activate and run it. - * - * @return true if ran a task - */ - private boolean tryExecSubmission() { - ForkJoinPool p = pool; - // This loop is needed in case attempt to activate fails, in - // which case we only retry if there still appears to be a - // submission. - while (p.hasQueuedSubmissions()) { - ForkJoinTask t; int a; - if (active || // inline p.tryIncrementActiveCount - (active = UNSAFE.compareAndSwapInt(p, poolRunStateOffset, - a = p.runState, a + 1))) { - if ((t = p.pollSubmission()) != null) { - UNSAFE.putOrderedObject(this, currentStealOffset, t); - t.quietlyExec(); - UNSAFE.putOrderedObject(this, currentStealOffset, null); - if (sp != base) - execLocalTasks(); - return true; - } - } - } - return false; - } - - /** - * Runs local tasks until queue is empty or shut down. Call only - * while active. - */ - private void execLocalTasks() { - while (runState == 0) { - ForkJoinTask t = locallyFifo ? locallyDeqTask() : popTask(); - if (t != null) - t.quietlyExec(); - else if (sp == base) - break; - } - } - /* * Intrinsics-based atomic writes for queue slots. These are * basically the same as methods in AtomicReferenceArray, but @@ -528,10 +414,20 @@ public class ForkJoinWorkerThread extends Thread { * because they are protected by other volatile reads and are * confirmed by CASes. * - * Most uses don't actually call these methods, but instead contain - * inlined forms that enable more predictable optimization. We - * don't define the version of write used in pushTask at all, but - * instead inline there a store-fenced array slot write. + * Most uses don't actually call these methods, but instead + * contain inlined forms that enable more predictable + * optimization. We don't define the version of write used in + * pushTask at all, but instead inline there a store-fenced array + * slot write. + * + * Also in most methods, as a performance (not correctness) issue, + * we'd like to encourage compilers not to arbitrarily postpone + * setting queueTop after writing slot. Currently there is no + * intrinsic for arranging this, but using Unsafe putOrderedInt + * may be a preferable strategy on some compilers even though its + * main effect is a pre-, not post- fence. To simplify possible + * changes, the option is left in comments next to the associated + * assignments. */ /** @@ -540,7 +436,7 @@ public class ForkJoinWorkerThread extends Thread { */ private static final boolean casSlotNull(ForkJoinTask[] q, int i, ForkJoinTask t) { - return UNSAFE.compareAndSwapObject(q, (i << qShift) + qBase, t, null); + return UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, t, null); } /** @@ -550,7 +446,7 @@ public class ForkJoinWorkerThread extends Thread { */ private static final void writeSlot(ForkJoinTask[] q, int i, ForkJoinTask t) { - UNSAFE.putObjectVolatile(q, (i << qShift) + qBase, t); + UNSAFE.putObjectVolatile(q, (i << ASHIFT) + ABASE, t); } // queue methods @@ -561,14 +457,43 @@ public class ForkJoinWorkerThread extends Thread { * @param t the task. Caller must ensure non-null. */ final void pushTask(ForkJoinTask t) { - ForkJoinTask[] q = queue; - int mask = q.length - 1; // implicit assert q != null - int s = sp++; // ok to increment sp before slot write - UNSAFE.putOrderedObject(q, ((s & mask) << qShift) + qBase, t); - if ((s -= base) == 0) - pool.signalWork(); // was empty - else if (s == mask) - growQueue(); // is full + ForkJoinTask[] q; int s, m; + if ((q = queue) != null) { // ignore if queue removed + long u = (((s = queueTop) & (m = q.length - 1)) << ASHIFT) + ABASE; + UNSAFE.putOrderedObject(q, u, t); + queueTop = s + 1; // or use putOrderedInt + if ((s -= queueBase) <= 2) + pool.signalWork(); + else if (s == m) + growQueue(); + } + } + + /** + * Creates or doubles queue array. Transfers elements by + * emulating steals (deqs) from old array and placing, oldest + * first, into new array. + */ + private void growQueue() { + ForkJoinTask[] oldQ = queue; + int size = oldQ != null ? oldQ.length << 1 : INITIAL_QUEUE_CAPACITY; + if (size > MAXIMUM_QUEUE_CAPACITY) + throw new RejectedExecutionException("Queue capacity exceeded"); + if (size < INITIAL_QUEUE_CAPACITY) + size = INITIAL_QUEUE_CAPACITY; + ForkJoinTask[] q = queue = new ForkJoinTask[size]; + int mask = size - 1; + int top = queueTop; + int oldMask; + if (oldQ != null && (oldMask = oldQ.length - 1) >= 0) { + for (int b = queueBase; b != top; ++b) { + long u = ((b & oldMask) << ASHIFT) + ABASE; + Object x = UNSAFE.getObjectVolatile(oldQ, u); + if (x != null && UNSAFE.compareAndSwapObject(oldQ, u, x, null)) + UNSAFE.putObjectVolatile + (q, ((b & mask) << ASHIFT) + ABASE, x); + } + } } /** @@ -579,35 +504,34 @@ public class ForkJoinWorkerThread extends Thread { * @return a task, or null if none or contended */ final ForkJoinTask deqTask() { - ForkJoinTask t; - ForkJoinTask[] q; - int b, i; - if (sp != (b = base) && + ForkJoinTask t; ForkJoinTask[] q; int b, i; + if (queueTop != (b = queueBase) && (q = queue) != null && // must read q after b - (t = q[i = (q.length - 1) & b]) != null && base == b && - UNSAFE.compareAndSwapObject(q, (i << qShift) + qBase, t, null)) { - base = b + 1; + (i = (q.length - 1) & b) >= 0 && + (t = q[i]) != null && queueBase == b && + UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, t, null)) { + queueBase = b + 1; return t; } return null; } /** - * Tries to take a task from the base of own queue. Assumes active - * status. Called only by this thread. + * Tries to take a task from the base of own queue. Called only + * by this thread. * * @return a task, or null if none */ final ForkJoinTask locallyDeqTask() { + ForkJoinTask t; int m, b, i; ForkJoinTask[] q = queue; - if (q != null) { - ForkJoinTask t; - int b, i; - while (sp != (b = base)) { - if ((t = q[i = (q.length - 1) & b]) != null && base == b && - UNSAFE.compareAndSwapObject(q, (i << qShift) + qBase, + if (q != null && (m = q.length - 1) >= 0) { + while (queueTop != (b = queueBase)) { + if ((t = q[i = m & b]) != null && + queueBase == b && + UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, t, null)) { - base = b + 1; + queueBase = b + 1; return t; } } @@ -616,35 +540,21 @@ public class ForkJoinWorkerThread extends Thread { } /** - * Returns a popped task, or null if empty. Assumes active status. + * Returns a popped task, or null if empty. * Called only by this thread. */ private ForkJoinTask popTask() { + int m; ForkJoinTask[] q = queue; - if (q != null) { - int s; - while ((s = sp) != base) { - int i = (q.length - 1) & --s; - long u = (i << qShift) + qBase; // raw offset + if (q != null && (m = q.length - 1) >= 0) { + for (int s; (s = queueTop) != queueBase;) { + int i = m & --s; + long u = (i << ASHIFT) + ABASE; // raw offset ForkJoinTask t = q[i]; if (t == null) // lost to stealer break; if (UNSAFE.compareAndSwapObject(q, u, t, null)) { - /* - * Note: here and in related methods, as a - * performance (not correctness) issue, we'd like - * to encourage compiler not to arbitrarily - * postpone setting sp after successful CAS. - * Currently there is no intrinsic for arranging - * this, but using Unsafe putOrderedInt may be a - * preferable strategy on some compilers even - * though its main effect is a pre-, not post- - * fence. To simplify possible changes, the option - * is left in comments next to the associated - * assignments. - */ - sp = s; // putOrderedInt may encourage more timely write - // UNSAFE.putOrderedInt(this, spOffset, s); + queueTop = s; // or putOrderedInt return t; } } @@ -654,18 +564,17 @@ public class ForkJoinWorkerThread extends Thread { /** * Specialized version of popTask to pop only if topmost element - * is the given task. Called only by this thread while active. + * is the given task. Called only by this thread. * * @param t the task. Caller must ensure non-null. */ final boolean unpushTask(ForkJoinTask t) { + ForkJoinTask[] q; int s; - ForkJoinTask[] q = queue; - if ((s = sp) != base && q != null && + if ((q = queue) != null && (s = queueTop) != queueBase && UNSAFE.compareAndSwapObject - (q, (((q.length - 1) & --s) << qShift) + qBase, t, null)) { - sp = s; // putOrderedInt may encourage more timely write - // UNSAFE.putOrderedInt(this, spOffset, s); + (q, (((q.length - 1) & --s) << ASHIFT) + ABASE, t, null)) { + queueTop = s; // or putOrderedInt return true; } return false; @@ -675,222 +584,30 @@ public class ForkJoinWorkerThread extends Thread { * Returns next task, or null if empty or contended. */ final ForkJoinTask peekTask() { + int m; ForkJoinTask[] q = queue; - if (q == null) + if (q == null || (m = q.length - 1) < 0) return null; - int mask = q.length - 1; - int i = locallyFifo ? base : (sp - 1); - return q[i & mask]; + int i = locallyFifo ? queueBase : (queueTop - 1); + return q[i & m]; } + // Support methods for ForkJoinPool + /** - * Doubles queue array size. Transfers elements by emulating - * steals (deqs) from old array and placing, oldest first, into - * new array. + * Runs the given task, plus any local tasks until queue is empty */ - private void growQueue() { - ForkJoinTask[] oldQ = queue; - int oldSize = oldQ.length; - int newSize = oldSize << 1; - if (newSize > MAXIMUM_QUEUE_CAPACITY) - throw new RejectedExecutionException("Queue capacity exceeded"); - ForkJoinTask[] newQ = queue = new ForkJoinTask[newSize]; - - int b = base; - int bf = b + oldSize; - int oldMask = oldSize - 1; - int newMask = newSize - 1; - do { - int oldIndex = b & oldMask; - ForkJoinTask t = oldQ[oldIndex]; - if (t != null && !casSlotNull(oldQ, oldIndex, t)) - t = null; - writeSlot(newQ, b & newMask, t); - } while (++b != bf); - pool.signalWork(); - } - - /** - * Computes next value for random victim probe in scan(). Scans - * don't require a very high quality generator, but also not a - * crummy one. Marsaglia xor-shift is cheap and works well enough. - * Note: This is manually inlined in scan(). - */ - private static final int xorShift(int r) { - r ^= r << 13; - r ^= r >>> 17; - return r ^ (r << 5); - } - - /** - * Tries to steal a task from another worker. Starts at a random - * index of workers array, and probes workers until finding one - * with non-empty queue or finding that all are empty. It - * randomly selects the first n probes. If these are empty, it - * resorts to a circular sweep, which is necessary to accurately - * set active status. (The circular sweep uses steps of - * approximately half the array size plus 1, to avoid bias - * stemming from leftmost packing of the array in ForkJoinPool.) - * - * This method must be both fast and quiet -- usually avoiding - * memory accesses that could disrupt cache sharing etc other than - * those needed to check for and take tasks (or to activate if not - * already active). This accounts for, among other things, - * updating random seed in place without storing it until exit. - * - * @return a task, or null if none found - */ - private ForkJoinTask scan() { - ForkJoinPool p = pool; - ForkJoinWorkerThread[] ws; // worker array - int n; // upper bound of #workers - if ((ws = p.workers) != null && (n = ws.length) > 1) { - boolean canSteal = active; // shadow active status - int r = seed; // extract seed once - int mask = n - 1; - int j = -n; // loop counter - int k = r; // worker index, random if j < 0 - for (;;) { - ForkJoinWorkerThread v = ws[k & mask]; - r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // inline xorshift - ForkJoinTask[] q; ForkJoinTask t; int b, a; - if (v != null && (b = v.base) != v.sp && - (q = v.queue) != null) { - int i = (q.length - 1) & b; - long u = (i << qShift) + qBase; // raw offset - int pid = poolIndex; - if ((t = q[i]) != null) { - if (!canSteal && // inline p.tryIncrementActiveCount - UNSAFE.compareAndSwapInt(p, poolRunStateOffset, - a = p.runState, a + 1)) - canSteal = active = true; - if (canSteal && v.base == b++ && - UNSAFE.compareAndSwapObject(q, u, t, null)) { - v.base = b; - v.stealHint = pid; - UNSAFE.putOrderedObject(this, - currentStealOffset, t); - seed = r; - ++stealCount; - return t; - } - } - j = -n; - k = r; // restart on contention - } - else if (++j <= 0) - k = r; - else if (j <= n) - k += (n >>> 1) | 1; - else - break; - } - } - return null; - } - - // Run State management - - // status check methods used mainly by ForkJoinPool - final boolean isRunning() { return runState == 0; } - final boolean isTerminated() { return (runState & TERMINATED) != 0; } - final boolean isSuspended() { return (runState & SUSPENDED) != 0; } - final boolean isTrimmed() { return (runState & TRIMMED) != 0; } - - final boolean isTerminating() { - if ((runState & TERMINATING) != 0) - return true; - if (pool.isAtLeastTerminating()) { // propagate pool state - shutdown(); - return true; - } - return false; - } - - /** - * Sets state to TERMINATING. Does NOT unpark or interrupt - * to wake up if currently blocked. Callers must do so if desired. - */ - final void shutdown() { + final void execTask(ForkJoinTask t) { + currentSteal = t; for (;;) { - int s = runState; - if ((s & (TERMINATING|TERMINATED)) != 0) - break; - if ((s & SUSPENDED) != 0) { // kill and wakeup if suspended - if (UNSAFE.compareAndSwapInt(this, runStateOffset, s, - (s & ~SUSPENDED) | - (TRIMMED|TERMINATING))) - break; - } - else if (UNSAFE.compareAndSwapInt(this, runStateOffset, s, - s | TERMINATING)) + if (t != null) + t.doExec(); + if (queueTop == queueBase) break; + t = locallyFifo ? locallyDeqTask() : popTask(); } - } - - /** - * Sets state to TERMINATED. Called only by onTermination(). - */ - private void setTerminated() { - int s; - do {} while (!UNSAFE.compareAndSwapInt(this, runStateOffset, - s = runState, - s | (TERMINATING|TERMINATED))); - } - - /** - * If suspended, tries to set status to unsuspended. - * Does NOT wake up if blocked. - * - * @return true if successful - */ - final boolean tryUnsuspend() { - int s; - while (((s = runState) & SUSPENDED) != 0) { - if (UNSAFE.compareAndSwapInt(this, runStateOffset, s, - s & ~SUSPENDED)) - return true; - } - return false; - } - - /** - * Sets suspended status and blocks as spare until resumed - * or shutdown. - */ - final void suspendAsSpare() { - for (;;) { // set suspended unless terminating - int s = runState; - if ((s & TERMINATING) != 0) { // must kill - if (UNSAFE.compareAndSwapInt(this, runStateOffset, s, - s | (TRIMMED | TERMINATING))) - return; - } - else if (UNSAFE.compareAndSwapInt(this, runStateOffset, s, - s | SUSPENDED)) - break; - } - ForkJoinPool p = pool; - p.pushSpare(this); - while ((runState & SUSPENDED) != 0) { - if (p.tryAccumulateStealCount(this)) { - interrupted(); // clear/ignore interrupts - if ((runState & SUSPENDED) == 0) - break; - LockSupport.park(this); - } - } - } - - // Misc support methods for ForkJoinPool - - /** - * Returns an estimate of the number of tasks in the queue. Also - * used by ForkJoinTask. - */ - final int getQueueSize() { - int n; // external calls must read base first - return (n = -base + sp) <= 0 ? 0 : n; + ++stealCount; + currentSteal = null; } /** @@ -899,17 +616,12 @@ public class ForkJoinWorkerThread extends Thread { */ final void cancelTasks() { ForkJoinTask cj = currentJoin; // try to cancel ongoing tasks - if (cj != null && cj.status >= 0) { + if (cj != null && cj.status >= 0) cj.cancelIgnoringExceptions(); - try { - this.interrupt(); // awaken wait - } catch (SecurityException ignore) { - } - } ForkJoinTask cs = currentSteal; if (cs != null && cs.status >= 0) cs.cancelIgnoringExceptions(); - while (base != sp) { + while (queueBase != queueTop) { ForkJoinTask t = deqTask(); if (t != null) t.cancelIgnoringExceptions(); @@ -923,7 +635,7 @@ public class ForkJoinWorkerThread extends Thread { */ final int drainTasksTo(Collection> c) { int n = 0; - while (base != sp) { + while (queueBase != queueTop) { ForkJoinTask t = deqTask(); if (t != null) { c.add(t); @@ -935,21 +647,20 @@ public class ForkJoinWorkerThread extends Thread { // Support methods for ForkJoinTask + /** + * Returns an estimate of the number of tasks in the queue. + */ + final int getQueueSize() { + return queueTop - queueBase; + } + /** * Gets and removes a local task. * * @return a task, if available */ final ForkJoinTask pollLocalTask() { - ForkJoinPool p = pool; - while (sp != base) { - int a; // inline p.tryIncrementActiveCount - if (active || - (active = UNSAFE.compareAndSwapInt(p, poolRunStateOffset, - a = p.runState, a + 1))) - return locallyFifo ? locallyDeqTask() : popTask(); - } - return null; + return locallyFifo ? locallyDeqTask() : popTask(); } /** @@ -958,172 +669,205 @@ public class ForkJoinWorkerThread extends Thread { * @return a task, if available */ final ForkJoinTask pollTask() { + ForkJoinWorkerThread[] ws; ForkJoinTask t = pollLocalTask(); - if (t == null) { - t = scan(); - // cannot retain/track/help steal - UNSAFE.putOrderedObject(this, currentStealOffset, null); + if (t != null || (ws = pool.workers) == null) + return t; + int n = ws.length; // cheap version of FJP.scan + int steps = n << 1; + int r = nextSeed(); + int i = 0; + while (i < steps) { + ForkJoinWorkerThread w = ws[(i++ + r) & (n - 1)]; + if (w != null && w.queueBase != w.queueTop && w.queue != null) { + if ((t = w.deqTask()) != null) + return t; + i = 0; + } } - return t; + return null; } /** - * Possibly runs some tasks and/or blocks, until task is done. + * The maximum stolen->joining link depth allowed in helpJoinTask, + * as well as the maximum number of retries (allowing on average + * one staleness retry per level) per attempt to instead try + * compensation. Depths for legitimate chains are unbounded, but + * we use a fixed constant to avoid (otherwise unchecked) cycles + * and bound staleness of traversal parameters at the expense of + * sometimes blocking when we could be helping. + */ + private static final int MAX_HELP = 16; + + /** + * Possibly runs some tasks and/or blocks, until joinMe is done. * * @param joinMe the task to join - * @param timed true if use timed wait - * @param nanos wait time if timed + * @return completion status on exit */ - final void joinTask(ForkJoinTask joinMe, boolean timed, long nanos) { - // currentJoin only written by this thread; only need ordered store + final int joinTask(ForkJoinTask joinMe) { ForkJoinTask prevJoin = currentJoin; - UNSAFE.putOrderedObject(this, currentJoinOffset, joinMe); - pool.awaitJoin(joinMe, this, timed, nanos); - UNSAFE.putOrderedObject(this, currentJoinOffset, prevJoin); + currentJoin = joinMe; + for (int s, retries = MAX_HELP;;) { + if ((s = joinMe.status) < 0) { + currentJoin = prevJoin; + return s; + } + if (retries > 0) { + if (queueTop != queueBase) { + if (!localHelpJoinTask(joinMe)) + retries = 0; // cannot help + } + else if (retries == MAX_HELP >>> 1) { + --retries; // check uncommon case + if (tryDeqAndExec(joinMe) >= 0) + Thread.yield(); // for politeness + } + else + retries = helpJoinTask(joinMe)? MAX_HELP : retries - 1; + } + else { + retries = MAX_HELP; // restart if not done + pool.tryAwaitJoin(joinMe); + } + } } /** - * Tries to locate and help perform tasks for a stealer of the - * given task, or in turn one of its stealers. Traces + * If present, pops and executes the given task, or any other + * cancelled task + * + * @return false if any other non-cancelled task exists in local queue + */ + private boolean localHelpJoinTask(ForkJoinTask joinMe) { + int s, i; ForkJoinTask[] q; ForkJoinTask t; + if ((s = queueTop) != queueBase && (q = queue) != null && + (i = (q.length - 1) & --s) >= 0 && + (t = q[i]) != null) { + if (t != joinMe && t.status >= 0) + return false; + if (UNSAFE.compareAndSwapObject + (q, (i << ASHIFT) + ABASE, t, null)) { + queueTop = s; // or putOrderedInt + t.doExec(); + } + } + return true; + } + + /** + * Tries to locate and execute tasks for a stealer of the given + * task, or in turn one of its stealers, Traces * currentSteal->currentJoin links looking for a thread working on * a descendant of the given task and with a non-empty queue to - * steal back and execute tasks from. - * - * The implementation is very branchy to cope with potential - * inconsistencies or loops encountering chains that are stale, - * unknown, or of length greater than MAX_HELP_DEPTH links. All - * of these cases are dealt with by just returning back to the - * caller, who is expected to retry if other join mechanisms also - * don't work out. + * steal back and execute tasks from. The implementation is very + * branchy to cope with potential inconsistencies or loops + * encountering chains that are stale, unknown, or of length + * greater than MAX_HELP links. All of these cases are dealt with + * by just retrying by caller. * * @param joinMe the task to join - * @param running if false, then must update pool count upon - * running a task - * @return value of running on exit + * @param canSteal true if local queue is empty + * @return true if ran a task */ - final boolean helpJoinTask(ForkJoinTask joinMe, boolean running) { - /* - * Initial checks to (1) abort if terminating; (2) clean out - * old cancelled tasks from local queue; (3) if joinMe is next - * task, run it; (4) omit scan if local queue nonempty (since - * it may contain non-descendents of joinMe). - */ - ForkJoinPool p = pool; - for (;;) { - ForkJoinTask[] q; - int s; - if (joinMe.status < 0) - return running; - else if ((runState & TERMINATING) != 0) { - joinMe.cancelIgnoringExceptions(); - return running; - } - else if ((s = sp) == base || (q = queue) == null) - break; // queue empty - else { - int i = (q.length - 1) & --s; - long u = (i << qShift) + qBase; // raw offset - ForkJoinTask t = q[i]; - if (t == null) - break; // lost to a stealer - else if (t != joinMe && t.status >= 0) - return running; // cannot safely help - else if ((running || - (running = p.tryIncrementRunningCount())) && - UNSAFE.compareAndSwapObject(q, u, t, null)) { - sp = s; // putOrderedInt may encourage more timely write - // UNSAFE.putOrderedInt(this, spOffset, s); - t.quietlyExec(); - } - } - } - - int n; // worker array size - ForkJoinWorkerThread[] ws = p.workers; - if (ws != null && (n = ws.length) > 1) { // need at least 2 workers - ForkJoinTask task = joinMe; // base of chain - ForkJoinWorkerThread thread = this; // thread with stolen task - - outer:for (int d = 0; d < MAX_HELP_DEPTH; ++d) { // chain length + private boolean helpJoinTask(ForkJoinTask joinMe) { + boolean helped = false; + int m = pool.scanGuard & SMASK; + ForkJoinWorkerThread[] ws = pool.workers; + if (ws != null && ws.length > m && joinMe.status >= 0) { + int levels = MAX_HELP; // remaining chain length + ForkJoinTask task = joinMe; // base of chain + outer:for (ForkJoinWorkerThread thread = this;;) { // Try to find v, the stealer of task, by first using hint - ForkJoinWorkerThread v = ws[thread.stealHint & (n - 1)]; + ForkJoinWorkerThread v = ws[thread.stealHint & m]; if (v == null || v.currentSteal != task) { - for (int j = 0; ; ++j) { // search array - if (j < n) { - ForkJoinTask vs; - if ((v = ws[j]) != null && - (vs = v.currentSteal) != null) { - if (joinMe.status < 0) - break outer; - if (vs == task) { - if (task.status < 0) - break outer; // stale - thread.stealHint = j; - break; // save hint for next time - } - } + for (int j = 0; ;) { // search array + if ((v = ws[j]) != null && v.currentSteal == task) { + thread.stealHint = j; + break; // save hint for next time } - else - break outer; // no stealer + if (++j > m) + break outer; // can't find stealer } } - // Try to help v, using specialized form of deqTask for (;;) { + ForkJoinTask[] q; int b, i; if (joinMe.status < 0) break outer; - int b = v.base; - ForkJoinTask[] q = v.queue; - if (b == v.sp || q == null) - break; // empty - int i = (q.length - 1) & b; - long u = (i << qShift) + qBase; + if ((b = v.queueBase) == v.queueTop || + (q = v.queue) == null || + (i = (q.length-1) & b) < 0) + break; // empty + long u = (i << ASHIFT) + ABASE; ForkJoinTask t = q[i]; if (task.status < 0) - break outer; // stale - if (t != null && - (running || - (running = p.tryIncrementRunningCount())) && - v.base == b++ && + break outer; // stale + if (t != null && v.queueBase == b && UNSAFE.compareAndSwapObject(q, u, t, null)) { - if (t != joinMe && joinMe.status < 0) { - UNSAFE.putObjectVolatile(q, u, t); - break outer; // joinMe cancelled; back out - } - v.base = b; - if (t.status >= 0) { - ForkJoinTask ps = currentSteal; - int pid = poolIndex; - v.stealHint = pid; - UNSAFE.putOrderedObject(this, - currentStealOffset, t); - t.quietlyExec(); - UNSAFE.putOrderedObject(this, - currentStealOffset, ps); - } - } - else if ((runState & TERMINATING) != 0) { - joinMe.cancelIgnoringExceptions(); - break outer; + v.queueBase = b + 1; + v.stealHint = poolIndex; + ForkJoinTask ps = currentSteal; + currentSteal = t; + t.doExec(); + currentSteal = ps; + helped = true; } } - // Try to descend to find v's stealer ForkJoinTask next = v.currentJoin; - if (task.status < 0 || next == null || next == task || - joinMe.status < 0) - break; // done, stale, dead-end, or cyclic - task = next; - thread = v; + if (--levels > 0 && task.status >= 0 && + next != null && next != task) { + task = next; + thread = v; + } + else + break; // max levels, stale, dead-end, or cyclic } } - return running; + return helped; } /** - * Implements ForkJoinTask.getSurplusQueuedTaskCount(). - * Returns an estimate of the number of tasks, offset by a - * function of number of idle workers. + * Performs an uncommon case for joinTask: If task t is at base of + * some workers queue, steals and executes it. + * + * @param t the task + * @return t's status + */ + private int tryDeqAndExec(ForkJoinTask t) { + int m = pool.scanGuard & SMASK; + ForkJoinWorkerThread[] ws = pool.workers; + if (ws != null && ws.length > m && t.status >= 0) { + for (int j = 0; j <= m; ++j) { + ForkJoinTask[] q; int b, i; + ForkJoinWorkerThread v = ws[j]; + if (v != null && + (b = v.queueBase) != v.queueTop && + (q = v.queue) != null && + (i = (q.length - 1) & b) >= 0 && + q[i] == t) { + long u = (i << ASHIFT) + ABASE; + if (v.queueBase == b && + UNSAFE.compareAndSwapObject(q, u, t, null)) { + v.queueBase = b + 1; + v.stealHint = poolIndex; + ForkJoinTask ps = currentSteal; + currentSteal = t; + t.doExec(); + currentSteal = ps; + } + break; + } + } + } + return t.status; + } + + /** + * Implements ForkJoinTask.getSurplusQueuedTaskCount(). Returns + * an estimate of the number of tasks, offset by a function of + * number of idle workers. * * This method provides a cheap heuristic guide for task * partitioning when programmers, frameworks, tools, or languages @@ -1159,82 +903,96 @@ public class ForkJoinWorkerThread extends Thread { * When all threads are active, it is on average OK to estimate * surplus strictly locally. In steady-state, if one thread is * maintaining say 2 surplus tasks, then so are others. So we can - * just use estimated queue length (although note that (sp - base) - * can be an overestimate because of stealers lagging increments - * of base). However, this strategy alone leads to serious - * mis-estimates in some non-steady-state conditions (ramp-up, - * ramp-down, other stalls). We can detect many of these by - * further considering the number of "idle" threads, that are + * just use estimated queue length (although note that (queueTop - + * queueBase) can be an overestimate because of stealers lagging + * increments of queueBase). However, this strategy alone leads + * to serious mis-estimates in some non-steady-state conditions + * (ramp-up, ramp-down, other stalls). We can detect many of these + * by further considering the number of "idle" threads, that are * known to have zero queued tasks, so compensate by a factor of * (#idle/#active) threads. */ final int getEstimatedSurplusTaskCount() { - return sp - base - pool.idlePerActive(); + return queueTop - queueBase - pool.idlePerActive(); } /** - * Runs tasks until {@code pool.isQuiescent()}. + * Runs tasks until {@code pool.isQuiescent()}. We piggyback on + * pool's active count ctl maintenance, but rather than blocking + * when tasks cannot be found, we rescan until all others cannot + * find tasks either. The bracketing by pool quiescerCounts + * updates suppresses pool auto-shutdown mechanics that could + * otherwise prematurely terminate the pool because all threads + * appear to be inactive. */ final void helpQuiescePool() { + boolean active = true; ForkJoinTask ps = currentSteal; // to restore below + ForkJoinPool p = pool; + p.addQuiescerCount(1); for (;;) { - ForkJoinTask t = pollLocalTask(); - if (t != null || (t = scan()) != null) - t.quietlyExec(); + ForkJoinWorkerThread[] ws = p.workers; + ForkJoinWorkerThread v = null; + int n; + if (queueTop != queueBase) + v = this; + else if (ws != null && (n = ws.length) > 1) { + ForkJoinWorkerThread w; + int r = nextSeed(); // cheap version of FJP.scan + int steps = n << 1; + for (int i = 0; i < steps; ++i) { + if ((w = ws[(i + r) & (n - 1)]) != null && + w.queueBase != w.queueTop) { + v = w; + break; + } + } + } + if (v != null) { + ForkJoinTask t; + if (!active) { + active = true; + p.addActiveCount(1); + } + if ((t = (v != this) ? v.deqTask() : + locallyFifo? locallyDeqTask() : popTask()) != null) { + currentSteal = t; + t.doExec(); + currentSteal = ps; + } + } else { - ForkJoinPool p = pool; - int a; // to inline CASes if (active) { - if (!UNSAFE.compareAndSwapInt - (p, poolRunStateOffset, a = p.runState, a - 1)) - continue; // retry later - active = false; // inactivate - UNSAFE.putOrderedObject(this, currentStealOffset, ps); + active = false; + p.addActiveCount(-1); } if (p.isQuiescent()) { - active = true; // re-activate - do {} while (!UNSAFE.compareAndSwapInt - (p, poolRunStateOffset, a = p.runState, a+1)); - return; + p.addActiveCount(1); + p.addQuiescerCount(-1); + break; } } } } // Unsafe mechanics - - private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe(); - private static final long spOffset = - objectFieldOffset("sp", ForkJoinWorkerThread.class); - private static final long runStateOffset = - objectFieldOffset("runState", ForkJoinWorkerThread.class); - private static final long currentJoinOffset = - objectFieldOffset("currentJoin", ForkJoinWorkerThread.class); - private static final long currentStealOffset = - objectFieldOffset("currentSteal", ForkJoinWorkerThread.class); - private static final long qBase = - UNSAFE.arrayBaseOffset(ForkJoinTask[].class); - private static final long poolRunStateOffset = // to inline CAS - objectFieldOffset("runState", ForkJoinPool.class); - - private static final int qShift; + private static final sun.misc.Unsafe UNSAFE; + private static final long ABASE; + private static final int ASHIFT; static { - int s = UNSAFE.arrayIndexScale(ForkJoinTask[].class); + int s; + try { + UNSAFE = sun.misc.Unsafe.getUnsafe(); + Class a = ForkJoinTask[].class; + ABASE = UNSAFE.arrayBaseOffset(a); + s = UNSAFE.arrayIndexScale(a); + } catch (Exception e) { + throw new Error(e); + } if ((s & (s-1)) != 0) throw new Error("data type scale not a power of two"); - qShift = 31 - Integer.numberOfLeadingZeros(s); - MAXIMUM_QUEUE_CAPACITY = 1 << (31 - qShift); + ASHIFT = 31 - Integer.numberOfLeadingZeros(s); } - private static long objectFieldOffset(String field, Class klazz) { - try { - return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field)); - } catch (NoSuchFieldException e) { - // Convert Exception to corresponding Error - NoSuchFieldError error = new NoSuchFieldError(field); - error.initCause(e); - throw error; - } - } } diff --git a/jdk/src/share/classes/javax/swing/JOptionPane.java b/jdk/src/share/classes/javax/swing/JOptionPane.java index 66154cf39b5..307d834b4e6 100644 --- a/jdk/src/share/classes/javax/swing/JOptionPane.java +++ b/jdk/src/share/classes/javax/swing/JOptionPane.java @@ -987,11 +987,33 @@ public class JOptionPane extends JComponent implements Accessible } dialog.pack(); dialog.setLocationRelativeTo(parentComponent); + + final PropertyChangeListener listener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + // Let the defaultCloseOperation handle the closing + // if the user closed the window without selecting a button + // (newValue = null in that case). Otherwise, close the dialog. + if (dialog.isVisible() && event.getSource() == JOptionPane.this && + (event.getPropertyName().equals(VALUE_PROPERTY) || + event.getPropertyName().equals(INPUT_VALUE_PROPERTY)) && + event.getNewValue() != null && + event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) { + dialog.setVisible(false); + } + } + }; + WindowAdapter adapter = new WindowAdapter() { private boolean gotFocus = false; public void windowClosing(WindowEvent we) { setValue(null); } + + public void windowClosed(WindowEvent e) { + removePropertyChangeListener(listener); + dialog.getContentPane().removeAll(); + } + public void windowGainedFocus(WindowEvent we) { // Once window gets focus, set initial focus if (!gotFocus) { @@ -1008,20 +1030,8 @@ public class JOptionPane extends JComponent implements Accessible setValue(JOptionPane.UNINITIALIZED_VALUE); } }); - addPropertyChangeListener(new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent event) { - // Let the defaultCloseOperation handle the closing - // if the user closed the window without selecting a button - // (newValue = null in that case). Otherwise, close the dialog. - if (dialog.isVisible() && event.getSource() == JOptionPane.this && - (event.getPropertyName().equals(VALUE_PROPERTY) || - event.getPropertyName().equals(INPUT_VALUE_PROPERTY)) && - event.getNewValue() != null && - event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) { - dialog.setVisible(false); - } - } - }); + + addPropertyChangeListener(listener); } diff --git a/jdk/src/share/classes/javax/swing/Timer.java b/jdk/src/share/classes/javax/swing/Timer.java index 9e98d5f920e..c6c80baeda9 100644 --- a/jdk/src/share/classes/javax/swing/Timer.java +++ b/jdk/src/share/classes/javax/swing/Timer.java @@ -35,6 +35,10 @@ import java.util.concurrent.locks.*; import java.awt.*; import java.awt.event.*; import java.io.Serializable; +import java.io.*; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.PrivilegedAction; import javax.swing.event.EventListenerList; @@ -208,6 +212,22 @@ public class Timer implements Serializable } } + /* + * The timer's AccessControlContext. + */ + private transient volatile AccessControlContext acc = + AccessController.getContext(); + + /** + * Returns the acc this timer was constructed with. + */ + final AccessControlContext getAccessControlContext() { + if (acc == null) { + throw new SecurityException( + "Timer is missing AccessControlContext"); + } + return acc; + } /** * DoPostEvent is a runnable class that fires actionEvents to @@ -587,8 +607,13 @@ public class Timer implements Serializable void post() { - if (notify.compareAndSet(false, true) || !coalesce) { - SwingUtilities.invokeLater(doPostEvent); + if (notify.compareAndSet(false, true) || !coalesce) { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + SwingUtilities.invokeLater(doPostEvent); + return null; + } + }, getAccessControlContext()); } } @@ -596,6 +621,13 @@ public class Timer implements Serializable return lock; } + private void readObject(ObjectInputStream in) + throws ClassNotFoundException, IOException + { + this.acc = AccessController.getContext(); + in.defaultReadObject(); + } + /* * We have to use readResolve because we can not initialize final * fields for deserialized object otherwise diff --git a/jdk/src/share/classes/javax/swing/TransferHandler.java b/jdk/src/share/classes/javax/swing/TransferHandler.java index eb7f8d1a644..dd54b259eef 100644 --- a/jdk/src/share/classes/javax/swing/TransferHandler.java +++ b/jdk/src/share/classes/javax/swing/TransferHandler.java @@ -42,6 +42,16 @@ import sun.awt.AppContext; import sun.swing.*; import sun.awt.SunToolkit; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import java.security.AccessControlContext; +import java.security.ProtectionDomain; +import sun.misc.SharedSecrets; +import sun.misc.JavaSecurityAccess; + +import sun.awt.AWTAccessor; + /** * This class is used to handle the transfer of a Transferable * to and from Swing components. The Transferable is used to @@ -1686,7 +1696,37 @@ public class TransferHandler implements Serializable { return true; } - public void actionPerformed(ActionEvent e) { + private static final JavaSecurityAccess javaSecurityAccess = + SharedSecrets.getJavaSecurityAccess(); + + public void actionPerformed(final ActionEvent e) { + final Object src = e.getSource(); + + final PrivilegedAction action = new PrivilegedAction() { + public Void run() { + actionPerformedImpl(e); + return null; + } + }; + + final AccessControlContext stack = AccessController.getContext(); + final AccessControlContext srcAcc = AWTAccessor.getComponentAccessor().getAccessControlContext((Component)src); + final AccessControlContext eventAcc = AWTAccessor.getAWTEventAccessor().getAccessControlContext(e); + + if (srcAcc == null) { + javaSecurityAccess.doIntersectionPrivilege(action, stack, eventAcc); + } else { + javaSecurityAccess.doIntersectionPrivilege( + new PrivilegedAction() { + public Void run() { + javaSecurityAccess.doIntersectionPrivilege(action, eventAcc); + return null; + } + }, stack, srcAcc); + } + } + + private void actionPerformedImpl(ActionEvent e) { Object src = e.getSource(); if (src instanceof JComponent) { JComponent c = (JComponent) src; diff --git a/jdk/src/share/classes/org/relaxng/datatype/Datatype.java b/jdk/src/share/classes/org/relaxng/datatype/Datatype.java deleted file mode 100644 index f1b4d8df244..00000000000 --- a/jdk/src/share/classes/org/relaxng/datatype/Datatype.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * 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 org.relaxng.datatype; - -/** - * Datatype object. - * - * This object has the following functionality: - * - *
      - *
    1. functionality to identify a class of character sequences. This is - * done through the isValid method. - * - *
    2. functionality to produce a "value object" from a character sequence and - * context information. - * - *
    3. functionality to test the equality of two value objects. - *
    - * - * This interface also defines the createStreamingValidator method, - * which is intended to efficiently support the validation of - * large character sequences. - * - * @author James Clark - * @author Kohsuke KAWAGUCHI - */ -public interface Datatype { - - /** - * Checks if the specified 'literal' matches this Datatype - * with respect to the current context. - * - * @param literal - * the lexical representation to be checked. - * @param context - * If this datatype is context-dependent - * (i.e. the {@link #isContextDependent} method returns true), - * then the caller must provide a non-null valid context object. - * Otherwise, the caller can pass null. - * - * @return - * true if the 'literal' is a member of this Datatype; - * false if it's not a member of this Datatype. - */ - boolean isValid( String literal, ValidationContext context ); - - /** - * Similar to the isValid method but throws an exception with diagnosis - * in case of errors. - * - *

    - * If the specified 'literal' is a valid lexical representation for this - * datatype, then this method must return without throwing any exception. - * If not, the callee must throw an exception (with diagnosis message, - * if possible.) - * - *

    - * The application can use this method to provide detailed error message - * to users. This method is kept separate from the isValid method to - * achieve higher performance during normal validation. - * - * @exception DatatypeException - * If the given literal is invalid, then this exception is thrown. - * If the callee supports error diagnosis, then the exception should - * contain a diagnosis message. - */ - void checkValid( String literal, ValidationContext context ) - throws DatatypeException; - - /** - * Creates an instance of a streaming validator for this type. - * - *

    - * By using streaming validators instead of the isValid method, - * the caller can avoid keeping the entire string, which is - * sometimes quite big, in memory. - * - * @param context - * If this datatype is context-dependent - * (i.e. the {@link #isContextDependent} method returns true), - * then the caller must provide a non-null valid context object. - * Otherwise, the caller can pass null. - * The callee may keep a reference to this context object - * only while the returned streaming validator is being used. - */ - DatatypeStreamingValidator createStreamingValidator( ValidationContext context ); - - /** - * Converts lexcial value and the current context to the corresponding - * value object. - * - *

    - * The caller cannot generally assume that the value object is - * a meaningful Java object. For example, the caller cannot expect - * this method to return java.lang.Number type for - * the "integer" type of XML Schema Part 2. - * - *

    - * Also, the caller cannot assume that the equals method and - * the hashCode method of the value object are consistent with - * the semantics of the datatype. For that purpose, the sameValue - * method and the valueHashCode method have to be used. Note that - * this means you cannot use classes like - * java.util.Hashtable to store the value objects. - * - *

    - * The returned value object should be used solely for the sameValue - * and valueHashCode methods. - * - * @param context - * If this datatype is context-dependent - * (when the {@link #isContextDependent} method returns true), - * then the caller must provide a non-null valid context object. - * Otherwise, the caller can pass null. - * - * @return null - * when the given lexical value is not a valid lexical - * value for this type. - */ - Object createValue( String literal, ValidationContext context ); - - /** - * Tests the equality of two value objects which were originally - * created by the createValue method of this object. - * - * The behavior is undefined if objects not created by this type - * are passed. It is the caller's responsibility to ensure that - * value objects belong to this type. - * - * @return - * true if two value objects are considered equal according to - * the definition of this datatype; false if otherwise. - */ - boolean sameValue( Object value1, Object value2 ); - - - /** - * Computes the hash code for a value object, - * which is consistent with the sameValue method. - * - * @return - * hash code for the specified value object. - */ - int valueHashCode( Object value ); - - - - - /** - * Indicates that the datatype doesn't have ID/IDREF semantics. - * - * This value is one of the possible return values of the - * {@link #getIdType} method. - */ - public static final int ID_TYPE_NULL = 0; - - /** - * Indicates that RELAX NG compatibility processors should - * treat this datatype as having ID semantics. - * - * This value is one of the possible return values of the - * {@link #getIdType} method. - */ - public static final int ID_TYPE_ID = 1; - - /** - * Indicates that RELAX NG compatibility processors should - * treat this datatype as having IDREF semantics. - * - * This value is one of the possible return values of the - * {@link #getIdType} method. - */ - public static final int ID_TYPE_IDREF = 2; - - /** - * Indicates that RELAX NG compatibility processors should - * treat this datatype as having IDREFS semantics. - * - * This value is one of the possible return values of the - * {@link #getIdType} method. - */ - public static final int ID_TYPE_IDREFS = 3; - - /** - * Checks if the ID/IDREF semantics is associated with this - * datatype. - * - *

    - * This method is introduced to support the RELAX NG DTD - * compatibility spec. (Of course it's always free to use - * this method for other purposes.) - * - *

    - * If you are implementing a datatype library and have no idea about - * the "RELAX NG DTD compatibility" thing, just return - * ID_TYPE_NULL is fine. - * - * @return - * If this datatype doesn't have any ID/IDREF semantics, - * it returns {@link #ID_TYPE_NULL}. If it has such a semantics - * (for example, XSD:ID, XSD:IDREF and comp:ID type), then - * it returns {@link #ID_TYPE_ID}, {@link #ID_TYPE_IDREF} or - * {@link #ID_TYPE_IDREFS}. - */ - public int getIdType(); - - - /** - * Checks if this datatype may need a context object for - * the validation. - * - *

    - * The callee must return true even when the context - * is not always necessary. (For example, the "QName" type - * doesn't need a context object when validating unprefixed - * string. But nonetheless QName must return true.) - * - *

    - * XSD's string and short types - * are examples of context-independent datatypes. - * Its QName and ENTITY types - * are examples of context-dependent datatypes. - * - *

    - * When a datatype is context-independent, then - * the {@link #isValid} method, the {@link #checkValid} method, - * the {@link #createStreamingValidator} method and - * the {@link #createValue} method can be called without - * providing a context object. - * - * @return - * true if this datatype is context-dependent - * (it needs a context object sometimes); - * - * false if this datatype is context-independent - * (it never needs a context object). - */ - public boolean isContextDependent(); -} diff --git a/jdk/src/share/classes/org/relaxng/datatype/DatatypeBuilder.java b/jdk/src/share/classes/org/relaxng/datatype/DatatypeBuilder.java deleted file mode 100644 index ea15f33cea2..00000000000 --- a/jdk/src/share/classes/org/relaxng/datatype/DatatypeBuilder.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 org.relaxng.datatype; - -/** - * Creates a user-defined type by adding parameters to - * the pre-defined type. - * - * @author James Clark - * @author Kohsuke KAWAGUCHI - */ -public interface DatatypeBuilder { - - /** - * Adds a new parameter. - * - * @param name - * The name of the parameter to be added. - * @param strValue - * The raw value of the parameter. Caller may not normalize - * this value because any white space is potentially significant. - * @param context - * The context information which can be used by the callee to - * acquire additional information. This context object is - * valid only during this method call. The callee may not - * keep a reference to this object. - * @exception DatatypeException - * When the given parameter is inappropriate for some reason. - * The callee is responsible to recover from this error. - * That is, the object should behave as if no such error - * was occured. - */ - void addParameter( String name, String strValue, ValidationContext context ) - throws DatatypeException; - - /** - * Derives a new Datatype from a Datatype by parameters that - * were already set through the addParameter method. - * - * @exception DatatypeException - * DatatypeException must be thrown if the derivation is - * somehow invalid. For example, a required parameter is missing, - * etc. The exception should contain a diagnosis message - * if possible. - */ - Datatype createDatatype() throws DatatypeException; -} diff --git a/jdk/src/share/classes/org/relaxng/datatype/DatatypeLibrary.java b/jdk/src/share/classes/org/relaxng/datatype/DatatypeLibrary.java deleted file mode 100644 index f3f790d91e2..00000000000 --- a/jdk/src/share/classes/org/relaxng/datatype/DatatypeLibrary.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 org.relaxng.datatype; - -/** - * A Datatype library - * - * @author James Clark - * @author Kohsuke KAWAGUCHI - */ -public interface DatatypeLibrary { - - /** - * Creates a new instance of DatatypeBuilder. - * - * The callee should throw a DatatypeException in case of an error. - * - * @param baseTypeLocalName - * The local name of the base type. - * - * @return - * A non-null valid datatype object. - */ - DatatypeBuilder createDatatypeBuilder( String baseTypeLocalName ) - throws DatatypeException; - - /** - * Gets or creates a pre-defined type. - * - * This is just a short-cut of - * createDatatypeBuilder(typeLocalName).createDatatype(); - * - * The callee should throw a DatatypeException in case of an error. - * - * @return - * A non-null valid datatype object. - */ - Datatype createDatatype( String typeLocalName ) throws DatatypeException; -} diff --git a/jdk/src/share/classes/org/relaxng/datatype/DatatypeLibraryFactory.java b/jdk/src/share/classes/org/relaxng/datatype/DatatypeLibraryFactory.java deleted file mode 100644 index e406c078894..00000000000 --- a/jdk/src/share/classes/org/relaxng/datatype/DatatypeLibraryFactory.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 org.relaxng.datatype; - -/** - * Factory class for the DatatypeLibrary class. - * - *

    - * The datatype library should provide the implementation of - * this interface if it wants to be found by the schema processors. - * The implementor also have to place a file in your jar file. - * See the reference datatype library implementation for detail. - * - * @author James Clark - * @author Kohsuke KAWAGUCHI - */ -public interface DatatypeLibraryFactory -{ - /** - * Creates a new instance of a DatatypeLibrary that supports - * the specified namespace URI. - * - * @return - * null if the specified namespace URI is not - * supported. - */ - DatatypeLibrary createDatatypeLibrary( String namespaceURI ); -} diff --git a/jdk/src/share/classes/org/relaxng/datatype/DatatypeStreamingValidator.java b/jdk/src/share/classes/org/relaxng/datatype/DatatypeStreamingValidator.java deleted file mode 100644 index 56663923278..00000000000 --- a/jdk/src/share/classes/org/relaxng/datatype/DatatypeStreamingValidator.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 org.relaxng.datatype; - -/** - * Datatype streaming validator. - * - *

    - * The streaming validator is an optional feature that is useful for - * certain Datatypes. It allows the caller to incrementally provide - * the literal. - * - * @author James Clark - * @author Kohsuke KAWAGUCHI - */ -public interface DatatypeStreamingValidator { - - /** - * Passes an additional fragment of the literal. - * - *

    - * The application can call this method several times, then call - * the isValid method (or the checkValid method) to check the validity - * of the accumulated characters. - */ - void addCharacters( char[] buf, int start, int len ); - - /** - * Tells if the accumulated literal is valid with respect to - * the underlying Datatype. - * - * @return - * True if it is valid. False if otherwise. - */ - boolean isValid(); - - /** - * Similar to the isValid method, but this method throws - * Exception (with possibly diagnostic information), instead of - * returning false. - * - * @exception DatatypeException - * If the callee supports the diagnosis and the accumulated - * literal is invalid, then this exception that possibly - * contains diagnosis information is thrown. - */ - void checkValid() throws DatatypeException; -} diff --git a/jdk/src/share/classes/org/relaxng/datatype/ValidationContext.java b/jdk/src/share/classes/org/relaxng/datatype/ValidationContext.java deleted file mode 100644 index 8e37b0ee6a5..00000000000 --- a/jdk/src/share/classes/org/relaxng/datatype/ValidationContext.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 org.relaxng.datatype; - -/** - * An interface that must be implemented by caller to - * provide context information that is necessary to - * perform validation of some Datatypes. - * - * @author James Clark - * @author Kohsuke KAWAGUCHI - */ -public interface ValidationContext { - - /** - * Resolves a namespace prefix to the corresponding namespace URI. - * - * This method is used for validating the QName type, for example. - * - *

    - * If the prefix is "" (empty string), it indicates - * an unprefixed value. The callee - * should resolve it as for an unprefixed - * element, rather than for an unprefixed attribute. - * - *

    - * If the prefix is "xml", then the callee must resolve - * this prefix into "http://www.w3.org/XML/1998/namespace", - * as defined in the XML Namespaces Recommendation. - * - * @return - * namespace URI of this prefix. - * If the specified prefix is not declared, - * the implementation must return null. - */ - String resolveNamespacePrefix( String prefix ); - - /** - * Returns the base URI of the context. The null string may be returned - * if no base URI is known. - */ - String getBaseUri(); - - /** - * Checks if an unparsed entity is declared with the - * specified name. - * - * @return - * true - * if the DTD has an unparsed entity declaration for - * the specified name. - * false - * otherwise. - */ - boolean isUnparsedEntity( String entityName ); - - /** - * Checks if a notation is declared with the - * specified name. - * - * @return - * true - * if the DTD has a notation declaration for the specified name. - * false - * otherwise. - */ - boolean isNotation( String notationName ); -} diff --git a/jdk/src/share/classes/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java b/jdk/src/share/classes/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java deleted file mode 100644 index a3091b08780..00000000000 --- a/jdk/src/share/classes/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java +++ /dev/null @@ -1,262 +0,0 @@ -/** - * Copyright (c) 2001, Thai Open Source Software Center Ltd - * 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 the Thai Open Source Software Center Ltd 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 REGENTS 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 org.relaxng.datatype.helpers; - -import org.relaxng.datatype.DatatypeLibraryFactory; -import org.relaxng.datatype.DatatypeLibrary; -import java.util.Enumeration; -import java.util.NoSuchElementException; -import java.util.Vector; -import java.io.Reader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URL; - -/** - * Discovers the datatype library implementation from the classpath. - * - *

    - * The call of the createDatatypeLibrary method finds an implementation - * from a given datatype library URI at run-time. - */ -public class DatatypeLibraryLoader implements DatatypeLibraryFactory { - private final Service service = new Service(DatatypeLibraryFactory.class); - - public DatatypeLibrary createDatatypeLibrary(String uri) { - for (Enumeration e = service.getProviders(); - e.hasMoreElements();) { - DatatypeLibraryFactory factory - = (DatatypeLibraryFactory)e.nextElement(); - DatatypeLibrary library = factory.createDatatypeLibrary(uri); - if (library != null) - return library; - } - return null; - } - - private static class Service { - private final Class serviceClass; - private final Enumeration configFiles; - private Enumeration classNames = null; - private final Vector providers = new Vector(); - private Loader loader; - - private class ProviderEnumeration implements Enumeration { - private int nextIndex = 0; - - public boolean hasMoreElements() { - return nextIndex < providers.size() || moreProviders(); - } - - public Object nextElement() { - try { - return providers.elementAt(nextIndex++); - } - catch (ArrayIndexOutOfBoundsException e) { - throw new NoSuchElementException(); - } - } - } - - private static class Singleton implements Enumeration { - private Object obj; - private Singleton(Object obj) { - this.obj = obj; - } - - public boolean hasMoreElements() { - return obj != null; - } - - public Object nextElement() { - if (obj == null) - throw new NoSuchElementException(); - Object tem = obj; - obj = null; - return tem; - } - } - - // JDK 1.1 - private static class Loader { - Enumeration getResources(String resName) { - ClassLoader cl = Loader.class.getClassLoader(); - URL url; - if (cl == null) - url = ClassLoader.getSystemResource(resName); - else - url = cl.getResource(resName); - return new Singleton(url); - } - - Class loadClass(String name) throws ClassNotFoundException { - return Class.forName(name); - } - } - - // JDK 1.2+ - private static class Loader2 extends Loader { - private ClassLoader cl; - - Loader2() { - cl = Loader2.class.getClassLoader(); - // If the thread context class loader has the class loader - // of this class as an ancestor, use the thread context class - // loader. Otherwise, the thread context class loader - // probably hasn't been set up properly, so don't use it. - ClassLoader clt = Thread.currentThread().getContextClassLoader(); - for (ClassLoader tem = clt; tem != null; tem = tem.getParent()) - if (tem == cl) { - cl = clt; - break; - } - } - - Enumeration getResources(String resName) { - try { - return cl.getResources(resName); - - } - catch (IOException e) { - return new Singleton(null); - } - } - - Class loadClass(String name) throws ClassNotFoundException { - return Class.forName(name, true, cl); - } - } - - public Service(Class cls) { - try { - loader = new Loader2(); - } - catch (NoSuchMethodError e) { - loader = new Loader(); - } - serviceClass = cls; - String resName = "META-INF/services/" + serviceClass.getName(); - configFiles = loader.getResources(resName); - } - - public Enumeration getProviders() { - return new ProviderEnumeration(); - } - - synchronized private boolean moreProviders() { - for (;;) { - while (classNames == null) { - if (!configFiles.hasMoreElements()) - return false; - classNames = parseConfigFile((URL)configFiles.nextElement()); - } - while (classNames.hasMoreElements()) { - String className = (String)classNames.nextElement(); - try { - Class cls = loader.loadClass(className); - Object obj = cls.newInstance(); - if (serviceClass.isInstance(obj)) { - providers.addElement(obj); - return true; - } - } - catch (ClassNotFoundException e) { } - catch (InstantiationException e) { } - catch (IllegalAccessException e) { } - catch (LinkageError e) { } - } - classNames = null; - } - } - - private static final int START = 0; - private static final int IN_NAME = 1; - private static final int IN_COMMENT = 2; - - private static Enumeration parseConfigFile(URL url) { - try { - InputStream in = url.openStream(); - Reader r; - try { - r = new InputStreamReader(in, "UTF-8"); - } - catch (UnsupportedEncodingException e) { - r = new InputStreamReader(in, "UTF8"); - } - r = new BufferedReader(r); - Vector tokens = new Vector(); - StringBuffer tokenBuf = new StringBuffer(); - int state = START; - for (;;) { - int n = r.read(); - if (n < 0) - break; - char c = (char)n; - switch (c) { - case '\r': - case '\n': - state = START; - break; - case ' ': - case '\t': - break; - case '#': - state = IN_COMMENT; - break; - default: - if (state != IN_COMMENT) { - state = IN_NAME; - tokenBuf.append(c); - } - break; - } - if (tokenBuf.length() != 0 && state != IN_NAME) { - tokens.addElement(tokenBuf.toString()); - tokenBuf.setLength(0); - } - } - if (tokenBuf.length() != 0) - tokens.addElement(tokenBuf.toString()); - return tokens.elements(); - } - catch (IOException e) { - return null; - } - } - } - -} diff --git a/jdk/src/share/classes/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java b/jdk/src/share/classes/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java deleted file mode 100644 index 8a5efb8b2dd..00000000000 --- a/jdk/src/share/classes/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 org.relaxng.datatype.helpers; - -import org.relaxng.datatype.*; - -/** - * Dummy implementation of {@link DatatypeBuilder}. - * - * This implementation can be used for Datatypes which have no parameters. - * Any attempt to add parameters will be rejected. - * - *

    - * Typical usage would be: - *

    
    - * class MyDatatypeLibrary implements DatatypeLibrary {
    - *     ....
    - *     DatatypeBuilder createDatatypeBuilder( String typeName ) {
    - *         return new ParameterleessDatatypeBuilder(createDatatype(typeName));
    - *     }
    - *     ....
    - * }
    - * 
    - * - * @author Kohsuke KAWAGUCHI - */ -public final class ParameterlessDatatypeBuilder implements DatatypeBuilder { - - /** This type object is returned for the derive method. */ - private final Datatype baseType; - - public ParameterlessDatatypeBuilder( Datatype baseType ) { - this.baseType = baseType; - } - - public void addParameter( String name, String strValue, ValidationContext context ) - throws DatatypeException { - throw new DatatypeException(); - } - - public Datatype createDatatype() throws DatatypeException { - return baseType; - } -} diff --git a/jdk/src/share/classes/org/relaxng/datatype/helpers/StreamingValidatorImpl.java b/jdk/src/share/classes/org/relaxng/datatype/helpers/StreamingValidatorImpl.java deleted file mode 100644 index 5f7cc79e967..00000000000 --- a/jdk/src/share/classes/org/relaxng/datatype/helpers/StreamingValidatorImpl.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 org.relaxng.datatype.helpers; - -import org.relaxng.datatype.*; - -/** - * Dummy implementation of {@link DatatypeStreamingValidator}. - * - *

    - * This implementation can be used as a quick hack when the performance - * of streaming validation is not important. And this implementation - * also shows you how to implement the DatatypeStreamingValidator interface. - * - *

    - * Typical usage would be: - *

    
    - * class MyDatatype implements Datatype {
    - *     ....
    - *     public DatatypeStreamingValidator createStreamingValidator( ValidationContext context ) {
    - *         return new StreamingValidatorImpl(this,context);
    - *     }
    - *     ....
    - * }
    - * 
    - * - * @author Kohsuke KAWAGUCHI - */ -public final class StreamingValidatorImpl implements DatatypeStreamingValidator { - - /** This buffer accumulates characters. */ - private final StringBuffer buffer = new StringBuffer(); - - /** Datatype obejct that creates this streaming validator. */ - private final Datatype baseType; - - /** The current context. */ - private final ValidationContext context; - - public void addCharacters( char[] buf, int start, int len ) { - // append characters to the current buffer. - buffer.append(buf,start,len); - } - - public boolean isValid() { - return baseType.isValid(buffer.toString(),context); - } - - public void checkValid() throws DatatypeException { - baseType.checkValid(buffer.toString(),context); - } - - public StreamingValidatorImpl( Datatype baseType, ValidationContext context ) { - this.baseType = baseType; - this.context = context; - } -} diff --git a/jdk/src/share/classes/overview-core.html b/jdk/src/share/classes/overview-core.html index 86f33fe6ce9..c4b518c57b8 100644 --- a/jdk/src/share/classes/overview-core.html +++ b/jdk/src/share/classes/overview-core.html @@ -33,7 +33,7 @@ questions. -This document is the API specification for version 6 of the Java™ +This document is the API specification for the Java™ Platform, Standard Edition. diff --git a/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer.java b/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer.java index 015bcd3f442..af1f3d5a609 100644 --- a/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer.java +++ b/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -103,7 +103,6 @@ public class MsgAppletViewer extends ListResourceBundle { {"appletclassloader.fileexception", "{0} exception when loading: {1}"}, {"appletclassloader.filedeath", "{0} killed when loading: {1}"}, {"appletclassloader.fileerror", "{0} error when loading: {1}"}, - {"appletclassloader.findclass.verbose.findclass", "{0} find class {1}"}, {"appletclassloader.findclass.verbose.openstream", "Opening stream to: {0} to get {1}"}, {"appletclassloader.getresource.verbose.forname", "AppletClassLoader.getResource for name: {0}"}, {"appletclassloader.getresource.verbose.found", "Found resource: {0} as a system resource"}, diff --git a/jdk/src/share/classes/sun/awt/AWTAccessor.java b/jdk/src/share/classes/sun/awt/AWTAccessor.java index 0e38de6df6f..b88531dfcd2 100644 --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java @@ -33,6 +33,9 @@ import java.awt.image.BufferedImage; import sun.misc.Unsafe; import java.awt.peer.ComponentPeer; +import java.security.AccessController; +import java.security.AccessControlContext; + /** * The AWTAccessor utility class. * The main purpose of this class is to enable accessing @@ -221,6 +224,13 @@ public final class AWTAccessor { * Processes events occurring on this component. */ void processEvent(Component comp, AWTEvent e); + + + /* + * Returns the acc this component was constructed with. + */ + AccessControlContext getAccessControlContext(Component comp); + } /* @@ -323,6 +333,13 @@ public final class AWTAccessor { * Indicates whether this AWTEvent was generated by the system. */ boolean isSystemGenerated(AWTEvent ev); + + + /* + * Returns the acc this event was constructed with. + */ + AccessControlContext getAccessControlContext(AWTEvent ev); + } public interface InputEventAccessor { diff --git a/jdk/src/share/classes/sun/dyn/Access.java b/jdk/src/share/classes/sun/dyn/Access.java deleted file mode 100644 index 931303b03b6..00000000000 --- a/jdk/src/share/classes/sun/dyn/Access.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute 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.dyn; - -import sun.reflect.Reflection; - -/** - * Access control to this package. - * Classes in other packages can attempt to acquire the access token, - * but will fail if they are not recognized as friends. - * Certain methods in this package, although public, require a non-null - * access token in order to proceed; they act like package-private methods. - * @author jrose - */ - -public class Access { - - private Access() { } - - /** - * The heart of this pattern: The list of classes which are - * permitted to acquire the access token, and become honorary - * members of this package. - */ - private static final String[] FRIENDS = { - "java.dyn.", "sun.dyn." - }; - - /** - * The following object is NOT public. That's the point of the pattern. - * It is package-private, so that any member of this package - * can acquire the access token, and give it away to trusted friends. - */ - static final Access TOKEN = new Access(); - - /** - * @return Access.TOKEN, if the caller is a friend of this package - */ - public static Access getToken() { - Class callc = Reflection.getCallerClass(2); - if (isFriend(callc)) - return TOKEN; - else - throw new IllegalAccessError("bad caller: " + callc); - } - - /** Is the given name the name of a class which could be our friend? */ - public static boolean isFriendName(String name) { - for (String friend : FRIENDS) { - if (name.startsWith(friend)) - return true; - } - return false; - } - - /** Is the given class a friend? True if {@link #isFriendName}, - * and the given class also shares a class loader with us. - */ - public static boolean isFriend(Class c) { - return isFriendName(c.getName()) && c.getClassLoader() == CLASS_LOADER; - } - - private static final ClassLoader CLASS_LOADER = Access.class.getClassLoader(); - - /** - * Throw an IllegalAccessError if the caller does not possess - * the Access.TOKEN. - * @param must be Access.TOKEN - */ - public static void check(Access token) { - if (token == null) - fail(); - // else it must be the unique Access.TOKEN - assert(token == Access.TOKEN); - } - private static void fail() { - final int CALLER_DEPTH = 3; - // 0: Reflection.getCC, 1: this.fail, 2: Access.*, 3: caller - Class callc = Reflection.getCallerClass(CALLER_DEPTH); - throw new IllegalAccessError("bad caller: " + callc); - } - - static { - //sun.reflect.Reflection.registerMethodsToFilter(MH.class, "getToken"); - } -} diff --git a/jdk/src/share/classes/sun/dyn/CallSiteImpl.java b/jdk/src/share/classes/sun/dyn/CallSiteImpl.java deleted file mode 100644 index 703788ff484..00000000000 --- a/jdk/src/share/classes/sun/dyn/CallSiteImpl.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2008, 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. 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.dyn; - -import java.dyn.*; -import static sun.dyn.MemberName.uncaughtException; - -/** - * Parts of CallSite known to the JVM. - * @author jrose - */ -public class CallSiteImpl { - // this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite: - static CallSite makeSite(MethodHandle bootstrapMethod, - // Callee information: - String name, MethodType type, - // Extra arguments for BSM, if any: - Object info, - // Caller information: - MemberName callerMethod, int callerBCI) { - Class callerClass = callerMethod.getDeclaringClass(); - Object caller; - if (bootstrapMethod.type().parameterType(0) == Class.class && TRANSITIONAL_BEFORE_PFD) - caller = callerClass; // remove for PFD - else - caller = MethodHandleImpl.IMPL_LOOKUP.in(callerClass); - if (bootstrapMethod == null && TRANSITIONAL_BEFORE_PFD) { - // If there is no bootstrap method, throw IncompatibleClassChangeError. - // This is a valid generic error type for resolution (JLS 12.3.3). - throw new IncompatibleClassChangeError - ("Class "+callerClass.getName()+" has not declared a bootstrap method for invokedynamic"); - } - CallSite site; - try { - Object binding; - info = maybeReBox(info); - if (info == null) { - binding = bootstrapMethod.invokeGeneric(caller, name, type); - } else if (!info.getClass().isArray()) { - binding = bootstrapMethod.invokeGeneric(caller, name, type, info); - } else { - Object[] argv = (Object[]) info; - if (3 + argv.length > 255) - new InvokeDynamicBootstrapError("too many bootstrap method arguments"); - MethodType bsmType = bootstrapMethod.type(); - if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class) - binding = bootstrapMethod.invokeGeneric(caller, name, type, argv); - else - binding = MethodHandles.spreadInvoker(bsmType, 3) - .invokeGeneric(bootstrapMethod, caller, name, type, argv); - } - //System.out.println("BSM for "+name+type+" => "+binding); - if (binding instanceof CallSite) { - site = (CallSite) binding; - } else if (binding instanceof MethodHandle && TRANSITIONAL_BEFORE_PFD) { - // Transitional! - MethodHandle target = (MethodHandle) binding; - site = new ConstantCallSite(target); - } else { - throw new ClassCastException("bootstrap method failed to produce a CallSite"); - } - if (TRANSITIONAL_BEFORE_PFD) - PRIVATE_INITIALIZE_CALL_SITE.invokeExact(site, name, type, - callerMethod, callerBCI); - assert(site.getTarget() != null); - assert(site.getTarget().type().equals(type)); - } catch (Throwable ex) { - InvokeDynamicBootstrapError bex; - if (ex instanceof InvokeDynamicBootstrapError) - bex = (InvokeDynamicBootstrapError) ex; - else - bex = new InvokeDynamicBootstrapError("call site initialization exception", ex); - throw bex; - } - return site; - } - - private static boolean TRANSITIONAL_BEFORE_PFD = true; // FIXME: remove for PFD - - private static Object maybeReBox(Object x) { - if (x instanceof Integer) { - int xi = (int) x; - if (xi == (byte) xi) - x = xi; // must rebox; see JLS 5.1.7 - return x; - } else if (x instanceof Object[]) { - Object[] xa = (Object[]) x; - for (int i = 0; i < xa.length; i++) { - if (xa[i] instanceof Integer) - xa[i] = maybeReBox(xa[i]); - } - return xa; - } else { - return x; - } - } - - // This method is private in CallSite because it touches private fields in CallSite. - // These private fields (vmmethod, vmindex) are specific to the JVM. - private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE; - static { - try { - PRIVATE_INITIALIZE_CALL_SITE = - !TRANSITIONAL_BEFORE_PFD ? null : - MethodHandleImpl.IMPL_LOOKUP.findVirtual(CallSite.class, "initializeFromJVM", - MethodType.methodType(void.class, - String.class, MethodType.class, - MemberName.class, int.class)); - } catch (ReflectiveOperationException ex) { - throw uncaughtException(ex); - } - } - - public static void setCallSiteTarget(Access token, CallSite site, MethodHandle target) { - Access.check(token); - MethodHandleNatives.setCallSiteTarget(site, target); - } -} diff --git a/jdk/src/share/classes/sun/font/FileFont.java b/jdk/src/share/classes/sun/font/FileFont.java index 22096dda2eb..1c63e9f1159 100644 --- a/jdk/src/share/classes/sun/font/FileFont.java +++ b/jdk/src/share/classes/sun/font/FileFont.java @@ -32,22 +32,13 @@ import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.io.File; import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; import sun.java2d.Disposer; import sun.java2d.DisposerRecord; -import java.lang.ref.WeakReference; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.RandomAccessFile; -import java.io.UnsupportedEncodingException; -import java.nio.ByteOrder; -import java.nio.MappedByteBuffer; -import java.nio.BufferUnderflowException; -import java.nio.channels.ClosedChannelException; -import java.util.HashSet; -import java.util.HashMap; -import java.awt.Font; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; public abstract class FileFont extends PhysicalFont { @@ -286,4 +277,49 @@ public abstract class FileFont extends PhysicalFont { }); } } + + protected String getPublicFileName() { + SecurityManager sm = System.getSecurityManager(); + if (sm == null) { + return platName; + } + boolean canReadProperty = true; + + try { + sm.checkPropertyAccess("java.io.tmpdir"); + } catch (SecurityException e) { + canReadProperty = false; + } + + if (canReadProperty) { + return platName; + } + + final File f = new File(platName); + + Boolean isTmpFile = Boolean.FALSE; + try { + isTmpFile = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Boolean run() { + File tmp = new File(System.getProperty("java.io.tmpdir")); + try { + String tpath = tmp.getCanonicalPath(); + String fpath = f.getCanonicalPath(); + + return (fpath == null) || fpath.startsWith(tpath); + } catch (IOException e) { + return Boolean.TRUE; + } + } + } + ); + } catch (PrivilegedActionException e) { + // unable to verify whether value of java.io.tempdir will be + // exposed, so return only a name of the font file. + isTmpFile = Boolean.TRUE; + } + + return isTmpFile ? "temp file" : platName; + } } diff --git a/jdk/src/share/classes/sun/font/TrueTypeFont.java b/jdk/src/share/classes/sun/font/TrueTypeFont.java index e448338a3f3..84cbd2c9a34 100644 --- a/jdk/src/share/classes/sun/font/TrueTypeFont.java +++ b/jdk/src/share/classes/sun/font/TrueTypeFont.java @@ -519,7 +519,8 @@ public class TrueTypeFont extends FileFont { break; default: - throw new FontFormatException("Unsupported sfnt " + platName); + throw new FontFormatException("Unsupported sfnt " + + getPublicFileName()); } /* Now have the offset of this TT font (possibly within a TTC) @@ -1680,7 +1681,6 @@ public class TrueTypeFont extends FileFont { @Override public String toString() { return "** TrueType Font: Family="+familyName+ " Name="+fullName+ - " style="+style+" fileName="+platName; + " style="+style+" fileName="+getPublicFileName(); } - } diff --git a/jdk/src/share/classes/sun/font/Type1Font.java b/jdk/src/share/classes/sun/font/Type1Font.java index 48821dd94e5..5fa49bd132d 100644 --- a/jdk/src/share/classes/sun/font/Type1Font.java +++ b/jdk/src/share/classes/sun/font/Type1Font.java @@ -677,6 +677,6 @@ public class Type1Font extends FileFont { public String toString() { return "** Type1 Font: Family="+familyName+ " Name="+fullName+ - " style="+style+" fileName="+platName; + " style="+style+" fileName="+getPublicFileName(); } } diff --git a/jdk/src/share/classes/sun/dyn/WrapperInstance.java b/jdk/src/share/classes/sun/invoke/WrapperInstance.java similarity index 90% rename from jdk/src/share/classes/sun/dyn/WrapperInstance.java rename to jdk/src/share/classes/sun/invoke/WrapperInstance.java index d6e91fd0d03..ba918b4d9d2 100644 --- a/jdk/src/share/classes/sun/dyn/WrapperInstance.java +++ b/jdk/src/share/classes/sun/invoke/WrapperInstance.java @@ -23,14 +23,14 @@ * questions. */ -package sun.dyn; +package sun.invoke; -import java.dyn.MethodHandle; +import java.lang.invoke.MethodHandle; /** - * Private API used inside of java.dyn.MethodHandles. + * Private API used inside of java.lang.invoke.MethodHandles. * Interface implemented by every object which is produced by - * {@link java.dyn.MethodHandles#asInstance MethodHandles.asInstance}. + * {@link java.lang.invoke.MethodHandles#asInstance MethodHandles.asInstance}. * The methods of this interface allow a caller to recover the parameters * to {@code asInstance}. * This allows applications to repeatedly convert between method handles diff --git a/jdk/src/share/classes/sun/dyn/anon/AnonymousClassLoader.java b/jdk/src/share/classes/sun/invoke/anon/AnonymousClassLoader.java similarity index 99% rename from jdk/src/share/classes/sun/dyn/anon/AnonymousClassLoader.java rename to jdk/src/share/classes/sun/invoke/anon/AnonymousClassLoader.java index bd7c5cb59dd..3005a452f71 100644 --- a/jdk/src/share/classes/sun/dyn/anon/AnonymousClassLoader.java +++ b/jdk/src/share/classes/sun/invoke/anon/AnonymousClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -23,7 +23,7 @@ * questions. */ -package sun.dyn.anon; +package sun.invoke.anon; import java.io.IOException; import java.lang.reflect.InvocationTargetException; diff --git a/jdk/src/share/classes/sun/dyn/anon/ConstantPoolParser.java b/jdk/src/share/classes/sun/invoke/anon/ConstantPoolParser.java similarity index 99% rename from jdk/src/share/classes/sun/dyn/anon/ConstantPoolParser.java rename to jdk/src/share/classes/sun/invoke/anon/ConstantPoolParser.java index b68b3f650c9..441ba957336 100644 --- a/jdk/src/share/classes/sun/dyn/anon/ConstantPoolParser.java +++ b/jdk/src/share/classes/sun/invoke/anon/ConstantPoolParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -23,14 +23,14 @@ * questions. */ -package sun.dyn.anon; +package sun.invoke.anon; import java.io.IOException; import java.io.OutputStream; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; -import static sun.dyn.anon.ConstantPoolVisitor.*; +import static sun.invoke.anon.ConstantPoolVisitor.*; /** A constant pool parser. */ diff --git a/jdk/src/share/classes/sun/dyn/anon/ConstantPoolPatch.java b/jdk/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java similarity index 99% rename from jdk/src/share/classes/sun/dyn/anon/ConstantPoolPatch.java rename to jdk/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java index 87dc97f6025..259d4b2336e 100644 --- a/jdk/src/share/classes/sun/dyn/anon/ConstantPoolPatch.java +++ b/jdk/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -23,7 +23,7 @@ * questions. */ -package sun.dyn.anon; +package sun.invoke.anon; import java.io.IOException; import java.io.OutputStream; @@ -32,7 +32,7 @@ import java.util.HashSet; import java.util.IdentityHashMap; import java.util.Map; -import static sun.dyn.anon.ConstantPoolVisitor.*; +import static sun.invoke.anon.ConstantPoolVisitor.*; /** A class and its patched constant pool. * diff --git a/jdk/src/share/classes/sun/dyn/anon/ConstantPoolVisitor.java b/jdk/src/share/classes/sun/invoke/anon/ConstantPoolVisitor.java similarity index 98% rename from jdk/src/share/classes/sun/dyn/anon/ConstantPoolVisitor.java rename to jdk/src/share/classes/sun/invoke/anon/ConstantPoolVisitor.java index e882b7d6724..dfec8b41151 100644 --- a/jdk/src/share/classes/sun/dyn/anon/ConstantPoolVisitor.java +++ b/jdk/src/share/classes/sun/invoke/anon/ConstantPoolVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -23,7 +23,7 @@ * questions. */ -package sun.dyn.anon; +package sun.invoke.anon; /** * A visitor called by {@link ConstantPoolParser#parse(ConstantPoolVisitor)} diff --git a/jdk/src/share/classes/sun/dyn/anon/InvalidConstantPoolFormatException.java b/jdk/src/share/classes/sun/invoke/anon/InvalidConstantPoolFormatException.java similarity index 94% rename from jdk/src/share/classes/sun/dyn/anon/InvalidConstantPoolFormatException.java rename to jdk/src/share/classes/sun/invoke/anon/InvalidConstantPoolFormatException.java index 555bb428f3f..d420d34b0d6 100644 --- a/jdk/src/share/classes/sun/dyn/anon/InvalidConstantPoolFormatException.java +++ b/jdk/src/share/classes/sun/invoke/anon/InvalidConstantPoolFormatException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -23,7 +23,7 @@ * questions. */ -package sun.dyn.anon; +package sun.invoke.anon; /** Exception used when there is an error in the constant pool * format. diff --git a/jdk/src/share/classes/sun/dyn/empty/Empty.java b/jdk/src/share/classes/sun/invoke/empty/Empty.java similarity index 90% rename from jdk/src/share/classes/sun/dyn/empty/Empty.java rename to jdk/src/share/classes/sun/invoke/empty/Empty.java index 416a6f128e8..f75d2b3d016 100644 --- a/jdk/src/share/classes/sun/dyn/empty/Empty.java +++ b/jdk/src/share/classes/sun/invoke/empty/Empty.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -23,14 +23,14 @@ * questions. */ -package sun.dyn.empty; +package sun.invoke.empty; /** * An empty class in an empty package. * Used as a proxy for unprivileged code, since making access checks * against it will only succeed against public methods in public types. *

    - * This class also stands (internally to sun.dyn) for the type of a + * This class also stands (internally to sun.invoke) for the type of a * value that cannot be produced, because the expression of this type * always returns abnormally. (Cf. Nothing in the closures proposal.) * @author jrose diff --git a/jdk/src/share/classes/sun/dyn/package-info.java b/jdk/src/share/classes/sun/invoke/package-info.java similarity index 93% rename from jdk/src/share/classes/sun/dyn/package-info.java rename to jdk/src/share/classes/sun/invoke/package-info.java index d129b0f5a27..74999fe6c7e 100644 --- a/jdk/src/share/classes/sun/dyn/package-info.java +++ b/jdk/src/share/classes/sun/invoke/package-info.java @@ -24,8 +24,8 @@ */ /** - * Implementation details for JSR 292 RI, package java.dyn. + * Implementation details for JSR 292 RI, package java.lang.invoke. * @author jrose */ -package sun.dyn; +package sun.invoke; diff --git a/jdk/src/share/classes/sun/dyn/util/BytecodeDescriptor.java b/jdk/src/share/classes/sun/invoke/util/BytecodeDescriptor.java similarity index 97% rename from jdk/src/share/classes/sun/dyn/util/BytecodeDescriptor.java rename to jdk/src/share/classes/sun/invoke/util/BytecodeDescriptor.java index 2c59b918338..ccc313cd41b 100644 --- a/jdk/src/share/classes/sun/dyn/util/BytecodeDescriptor.java +++ b/jdk/src/share/classes/sun/invoke/util/BytecodeDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -23,9 +23,9 @@ * questions. */ -package sun.dyn.util; +package sun.invoke.util; -import java.dyn.MethodType; +import java.lang.invoke.MethodType; import java.util.ArrayList; import java.util.List; diff --git a/jdk/src/share/classes/sun/dyn/util/BytecodeName.java b/jdk/src/share/classes/sun/invoke/util/BytecodeName.java similarity index 99% rename from jdk/src/share/classes/sun/dyn/util/BytecodeName.java rename to jdk/src/share/classes/sun/invoke/util/BytecodeName.java index 73be3fb1361..9b8fa35cb70 100644 --- a/jdk/src/share/classes/sun/dyn/util/BytecodeName.java +++ b/jdk/src/share/classes/sun/invoke/util/BytecodeName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -23,7 +23,7 @@ * questions. */ -package sun.dyn.util; +package sun.invoke.util; /** * Utility routines for dealing with bytecode-level names. diff --git a/jdk/src/share/classes/sun/dyn/util/ValueConversions.java b/jdk/src/share/classes/sun/invoke/util/ValueConversions.java similarity index 94% rename from jdk/src/share/classes/sun/dyn/util/ValueConversions.java rename to jdk/src/share/classes/sun/invoke/util/ValueConversions.java index 374bd245058..c6a56abf665 100644 --- a/jdk/src/share/classes/sun/dyn/util/ValueConversions.java +++ b/jdk/src/share/classes/sun/invoke/util/ValueConversions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -23,22 +23,19 @@ * questions. */ -package sun.dyn.util; +package sun.invoke.util; -import java.dyn.*; -import java.dyn.MethodHandles.Lookup; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.MethodType; import java.util.ArrayList; import java.util.Arrays; import java.util.EnumMap; import java.util.List; -import sun.dyn.Access; -import sun.dyn.AdapterMethodHandle; -import sun.dyn.MethodHandleImpl; -import static sun.dyn.MemberName.uncaughtException; public class ValueConversions { - private static final Access IMPL_TOKEN = Access.getToken(); - private static final Lookup IMPL_LOOKUP = MethodHandleImpl.getLookup(IMPL_TOKEN); + private static final Lookup IMPL_LOOKUP = MethodHandles.lookup(); private static EnumMap[] newWrapperCaches(int n) { @SuppressWarnings("unchecked") @@ -157,7 +154,7 @@ public class ValueConversions { mh = null; } } else { - mh = retype(type, unbox(wrap, !exact, raw)); + mh = unbox(wrap, !exact, raw).asType(type); } if (mh != null) { cache.put(wrap, mh); @@ -293,7 +290,7 @@ public class ValueConversions { mh = null; } } else { - mh = retype(type.erase(), box(wrap, !exact, raw)); + mh = box(wrap, !exact, raw).asType(type.erase()); } if (mh != null) { cache.put(wrap, mh); @@ -412,7 +409,7 @@ public class ValueConversions { mh = null; } } else { - mh = retype(IDENTITY.type(), rebox(wrap, !exact)); + mh = rebox(wrap, !exact).asType(IDENTITY.type()); } if (mh != null) { cache.put(wrap, mh); @@ -504,8 +501,8 @@ public class ValueConversions { // use the raw method Wrapper rawWrap = wrap.rawPrimitive(); - if (rawWrap != wrap) { - mh = retype(type, zeroConstantFunction(rawWrap)); + if (mh == null && rawWrap != wrap) { + mh = MethodHandles.explicitCastArguments(zeroConstantFunction(rawWrap), type); } if (mh != null) { cache.put(wrap, mh); @@ -552,6 +549,22 @@ public class ValueConversions { return x; } + static byte identity(byte x) { + return x; + } + + static short identity(short x) { + return x; + } + + static boolean identity(boolean x) { + return x; + } + + static char identity(char x) { + return x; + } + /** * Identity function on longs. * @param x an arbitrary long value @@ -561,6 +574,14 @@ public class ValueConversions { return x; } + static float identity(float x) { + return x; + } + + static double identity(double x) { + return x; + } + /** * Identity function, with reference cast. * @param t an arbitrary reference type @@ -590,7 +611,9 @@ public class ValueConversions { IGNORE = IMPL_LOOKUP.findStatic(ValueConversions.class, "ignore", ignoreType); EMPTY = IMPL_LOOKUP.findStatic(ValueConversions.class, "empty", ignoreType.dropParameterTypes(0, 1)); } catch (Exception ex) { - throw uncaughtException(ex); + Error err = new InternalError("uncaught exception"); + err.initCause(ex); + throw err; } } @@ -622,7 +645,8 @@ public class ValueConversions { mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type); if (exact) { MethodType xmt = MethodType.methodType(type, Object.class); - mh = AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, xmt, mh); + mh = MethodHandles.explicitCastArguments(mh, xmt); + //mh = AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, xmt, mh); } if (cache != null) cache.put(wrap, mh); @@ -634,15 +658,11 @@ public class ValueConversions { } public static MethodHandle identity(Class type) { - if (type == Object.class) - return IDENTITY; - else if (!type.isPrimitive()) - return retype(MethodType.methodType(type, type), IDENTITY); - else - return identity(Wrapper.forPrimitiveType(type)); + // This stuff has been moved into MethodHandles: + return MethodHandles.identity(type); } - static MethodHandle identity(Wrapper wrap) { + public static MethodHandle identity(Wrapper wrap) { EnumMap cache = CONSTANT_FUNCTIONS[1]; MethodHandle mh = cache.get(wrap); if (mh != null) { @@ -665,12 +685,6 @@ public class ValueConversions { return mh; } - // use a raw conversion - if (wrap.isSingleWord() && wrap != Wrapper.INT) { - mh = retype(type, identity(Wrapper.INT)); - } else if (wrap.isDoubleWord() && wrap != Wrapper.LONG) { - mh = retype(type, identity(Wrapper.LONG)); - } if (mh != null) { cache.put(wrap, mh); return mh; @@ -678,10 +692,6 @@ public class ValueConversions { throw new IllegalArgumentException("cannot find identity for " + wrap); } - private static MethodHandle retype(MethodType type, MethodHandle mh) { - return AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, type, mh); - } - private static final Object[] NO_ARGS_ARRAY = {}; private static Object[] makeArray(Object... args) { return args; } private static Object[] array() { return NO_ARGS_ARRAY; } diff --git a/jdk/src/share/classes/sun/dyn/util/VerifyAccess.java b/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java similarity index 98% rename from jdk/src/share/classes/sun/dyn/util/VerifyAccess.java rename to jdk/src/share/classes/sun/invoke/util/VerifyAccess.java index 1114bad2695..657aeec23d8 100644 --- a/jdk/src/share/classes/sun/dyn/util/VerifyAccess.java +++ b/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -23,12 +23,9 @@ * questions. */ -package sun.dyn.util; +package sun.invoke.util; import java.lang.reflect.Modifier; -import sun.dyn.MemberName; -import sun.dyn.MethodHandleImpl; -import sun.dyn.empty.Empty; import static java.lang.reflect.Modifier.*; /** diff --git a/jdk/src/share/classes/sun/dyn/util/VerifyType.java b/jdk/src/share/classes/sun/invoke/util/VerifyType.java similarity index 98% rename from jdk/src/share/classes/sun/dyn/util/VerifyType.java rename to jdk/src/share/classes/sun/invoke/util/VerifyType.java index b6277e4a8a9..39286d09ca4 100644 --- a/jdk/src/share/classes/sun/dyn/util/VerifyType.java +++ b/jdk/src/share/classes/sun/invoke/util/VerifyType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -23,10 +23,10 @@ * questions. */ -package sun.dyn.util; +package sun.invoke.util; -import java.dyn.MethodType; -import sun.dyn.empty.Empty; +import java.lang.invoke.MethodType; +import sun.invoke.empty.Empty; /** * This class centralizes information about the JVM verifier diff --git a/jdk/src/share/classes/sun/dyn/util/Wrapper.java b/jdk/src/share/classes/sun/invoke/util/Wrapper.java similarity index 99% rename from jdk/src/share/classes/sun/dyn/util/Wrapper.java rename to jdk/src/share/classes/sun/invoke/util/Wrapper.java index 91b599e8c64..8e2ce578386 100644 --- a/jdk/src/share/classes/sun/dyn/util/Wrapper.java +++ b/jdk/src/share/classes/sun/invoke/util/Wrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -23,7 +23,7 @@ * questions. */ -package sun.dyn.util; +package sun.invoke.util; public enum Wrapper { BOOLEAN(Boolean.class, boolean.class, 'Z', (Boolean)false, Format.unsigned(1)), @@ -267,7 +267,7 @@ public enum Wrapper { FROM_WRAP[wi] = w; FROM_CHAR[ci] = w; } - //assert(jdk.sun.dyn.util.WrapperTest.test(false)); + //assert(jdk.sun.invoke.util.WrapperTest.test(false)); } /** What is the primitive type wrapped by this wrapper? */ diff --git a/jdk/src/share/classes/sun/dyn/util/package-info.java b/jdk/src/share/classes/sun/invoke/util/package-info.java similarity index 88% rename from jdk/src/share/classes/sun/dyn/util/package-info.java rename to jdk/src/share/classes/sun/invoke/util/package-info.java index 0977b22ef94..785ca804302 100644 --- a/jdk/src/share/classes/sun/dyn/util/package-info.java +++ b/jdk/src/share/classes/sun/invoke/util/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -24,8 +24,8 @@ */ /** - * Extra support for using JSR 292 RI, package java.dyn. + * Extra support for using JSR 292 RI, package java.lang.invoke. * @author jrose */ -package sun.dyn.util; +package sun.invoke.util; diff --git a/jdk/src/share/classes/sun/java2d/pisces/Helpers.java b/jdk/src/share/classes/sun/java2d/pisces/Helpers.java index b91bc6a400a..42c7f2654d3 100644 --- a/jdk/src/share/classes/sun/java2d/pisces/Helpers.java +++ b/jdk/src/share/classes/sun/java2d/pisces/Helpers.java @@ -154,9 +154,6 @@ final class Helpers { // These use a hardcoded factor of 2 for increasing sizes. Perhaps this // should be provided as an argument. static float[] widenArray(float[] in, final int cursize, final int numToAdd) { - if (in == null) { - return new float[5 * numToAdd]; - } if (in.length >= cursize + numToAdd) { return in; } diff --git a/jdk/src/share/classes/sun/java2d/pisces/PiscesTileGenerator.java b/jdk/src/share/classes/sun/java2d/pisces/PiscesTileGenerator.java index ba91edb9819..3d6046bed69 100644 --- a/jdk/src/share/classes/sun/java2d/pisces/PiscesTileGenerator.java +++ b/jdk/src/share/classes/sun/java2d/pisces/PiscesTileGenerator.java @@ -191,8 +191,7 @@ final class PiscesTileGenerator implements AATileGenerator { System.out.println("len = "+runLen); System.out.print(cache.toString()); e0.printStackTrace(); - System.exit(1); - return; + throw e0; } int rx0 = cx; @@ -215,8 +214,7 @@ final class PiscesTileGenerator implements AATileGenerator { System.out.println("len = "+runLen); System.out.print(cache.toString()); e.printStackTrace(); - System.exit(1); - return; + throw e; } } pos += 2; @@ -250,4 +248,5 @@ final class PiscesTileGenerator implements AATileGenerator { * No further calls will be made on this instance. */ public void dispose() {} -} \ No newline at end of file +} + diff --git a/jdk/src/share/classes/sun/java2d/pisces/Renderer.java b/jdk/src/share/classes/sun/java2d/pisces/Renderer.java index cbfa2897d94..6d07b532e08 100644 --- a/jdk/src/share/classes/sun/java2d/pisces/Renderer.java +++ b/jdk/src/share/classes/sun/java2d/pisces/Renderer.java @@ -47,16 +47,16 @@ final class Renderer implements PathConsumer2D { private static final int INIT_CROSSINGS_SIZE = 10; - private ScanlineIterator() { + // Preconditions: Only subpixel scanlines in the range + // (start <= subpixel_y <= end) will be evaluated. No + // edge may have a valid (i.e. inside the supplied clip) + // crossing that would be generated outside that range. + private ScanlineIterator(int start, int end) { crossings = new int[INIT_CROSSINGS_SIZE]; edgePtrs = new int[INIT_CROSSINGS_SIZE]; - // We don't care if we clip some of the line off with ceil, since - // no scan line crossings will be eliminated (in fact, the ceil is - // the y of the first scan line crossing). - final int minY = getFirstScanLineCrossing(); - nextY = minY; - maxY = getScanLineCrossingEnd()-1; + nextY = start; + maxY = end; edgeCount = 0; } @@ -148,6 +148,7 @@ final class Renderer implements PathConsumer2D { // don't just set NULL to -1, because we want NULL+NEXT to be negative. private static final int NULL = -SIZEOF_EDGE; private float[] edges = null; + private static final int INIT_NUM_EDGES = 8; private int[] edgeBuckets = null; private int[] edgeBucketCounts = null; // 2*newedges + (1 if pruning needed) private int numEdges; @@ -156,7 +157,7 @@ final class Renderer implements PathConsumer2D { private static final float INC_BND = 8f; // each bucket is a linked list. this method adds eptr to the - // start "bucket"th linked list. + // start of the "bucket"th linked list. private void addEdgeToBucket(final int eptr, final int bucket) { edges[eptr+NEXT] = edgeBuckets[bucket]; edgeBuckets[bucket] = eptr; @@ -168,7 +169,8 @@ final class Renderer implements PathConsumer2D { // X0, Y0, D*[X|Y], COUNT; not variables used for computing scanline crossings). private void quadBreakIntoLinesAndAdd(float x0, float y0, final Curve c, - final float x2, final float y2) { + final float x2, final float y2) + { final float QUAD_DEC_BND = 32; final int countlg = 4; int count = 1 << countlg; @@ -204,7 +206,8 @@ final class Renderer implements PathConsumer2D { // here, but then too many numbers are passed around. private void curveBreakIntoLinesAndAdd(float x0, float y0, final Curve c, - final float x3, final float y3) { + final float x3, final float y3) + { final int countlg = 3; int count = 1 << countlg; @@ -259,8 +262,6 @@ final class Renderer implements PathConsumer2D { } } - // Preconditions: y2 > y1 and the curve must cross some scanline - // i.e.: y1 <= y < y2 for some y such that boundsMinY <= y < boundsMaxY private void addLine(float x1, float y1, float x2, float y2) { float or = 1; // orientation of the line. 1 if y increases, 0 otherwise. if (y2 < y1) { @@ -272,12 +273,11 @@ final class Renderer implements PathConsumer2D { x1 = or; or = 0; } - final int firstCrossing = Math.max((int) Math.ceil(y1), boundsMinY); + final int firstCrossing = Math.max((int)Math.ceil(y1), boundsMinY); final int lastCrossing = Math.min((int)Math.ceil(y2), boundsMaxY); if (firstCrossing >= lastCrossing) { return; } - if (y1 < edgeMinY) { edgeMinY = y1; } if (y2 > edgeMaxY) { edgeMaxY = y2; } @@ -297,22 +297,10 @@ final class Renderer implements PathConsumer2D { edges[ptr+OR] = or; edges[ptr+CURX] = x1 + (firstCrossing - y1) * slope; edges[ptr+SLOPE] = slope; - edges[ptr+YMAX] = y2; + edges[ptr+YMAX] = lastCrossing; final int bucketIdx = firstCrossing - boundsMinY; addEdgeToBucket(ptr, bucketIdx); - if (lastCrossing < boundsMaxY) { - edgeBucketCounts[lastCrossing - boundsMinY] |= 1; - } - } - - // preconditions: should not be called before the last line has been added - // to the edge list (even though it will return a correct answer at that - // point in time, it's not meant to be used that way). - private int getFirstScanLineCrossing() { - return Math.max(boundsMinY, (int)Math.ceil(edgeMinY)); - } - private int getScanLineCrossingEnd() { - return Math.min(boundsMaxY, (int)Math.ceil(edgeMaxY)); + edgeBucketCounts[lastCrossing - boundsMinY] |= 1; } // END EDGE LIST @@ -366,9 +354,11 @@ final class Renderer implements PathConsumer2D { this.boundsMaxX = (pix_boundsX + pix_boundsWidth) * SUBPIXEL_POSITIONS_X; this.boundsMaxY = (pix_boundsY + pix_boundsHeight) * SUBPIXEL_POSITIONS_Y; + edges = new float[INIT_NUM_EDGES * SIZEOF_EDGE]; + numEdges = 0; edgeBuckets = new int[boundsMaxY - boundsMinY]; java.util.Arrays.fill(edgeBuckets, NULL); - edgeBucketCounts = new int[edgeBuckets.length]; + edgeBucketCounts = new int[edgeBuckets.length + 1]; } private float tosubpixx(float pix_x) { @@ -394,7 +384,7 @@ final class Renderer implements PathConsumer2D { y0 = y1; } - Curve c = new Curve(); + private Curve c = new Curve(); @Override public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) @@ -431,8 +421,8 @@ final class Renderer implements PathConsumer2D { throw new InternalError("Renderer does not use a native consumer."); } - private void _endRendering(final int pix_bboxx0, final int pix_bboxy0, - final int pix_bboxx1, final int pix_bboxy1) + private void _endRendering(final int pix_bboxx0, final int pix_bboxx1, + int ymin, int ymax) { // Mask to determine the relevant bit of the crossing sum // 0x1 if EVEN_ODD, all bits if NON_ZERO @@ -455,7 +445,7 @@ final class Renderer implements PathConsumer2D { int pix_minX = Integer.MAX_VALUE; int y = boundsMinY; // needs to be declared here so we emit the last row properly. - ScanlineIterator it = this.new ScanlineIterator(); + ScanlineIterator it = this.new ScanlineIterator(ymin, ymax); for ( ; it.hasNext(); ) { int numCrossings = it.next(); int[] crossings = it.crossings; @@ -477,7 +467,7 @@ final class Renderer implements PathConsumer2D { int curxo = crossings[i]; int curx = curxo >> 1; // to turn {0, 1} into {-1, 1}, multiply by 2 and subtract 1. - int crorientation = ((curxo & 0x1) << 1) -1; + int crorientation = ((curxo & 0x1) << 1) - 1; if ((sum & mask) != 0) { int x0 = Math.max(prev, bboxx0); int x1 = Math.min(curx, bboxx1); @@ -541,7 +531,7 @@ final class Renderer implements PathConsumer2D { } this.cache = new PiscesCache(pminX, pminY, pmaxX, pmaxY); - _endRendering(pminX, pminY, pmaxX, pmaxY); + _endRendering(pminX, pmaxX, spminY, spmaxY); } public PiscesCache getCache() { diff --git a/jdk/src/share/classes/sun/java2d/pisces/Stroker.java b/jdk/src/share/classes/sun/java2d/pisces/Stroker.java index b898febc4c2..f7323f95adb 100644 --- a/jdk/src/share/classes/sun/java2d/pisces/Stroker.java +++ b/jdk/src/share/classes/sun/java2d/pisces/Stroker.java @@ -764,6 +764,11 @@ final class Stroker implements PathConsumer2D { private static final int MAX_N_CURVES = 11; private float[] subdivTs = new float[MAX_N_CURVES - 1]; + // If this class is compiled with ecj, then Hotspot crashes when OSR + // compiling this function. See bugs 7004570 and 6675699 + // TODO: until those are fixed, we should work around that by + // manually inlining this into curveTo and quadTo. +/******************************* WORKAROUND ********************************** private void somethingTo(final int type) { // need these so we can update the state at the end of this method final float xf = middle[type-2], yf = middle[type-1]; @@ -866,6 +871,7 @@ final class Stroker implements PathConsumer2D { this.cy0 = yf; this.prev = DRAWING_OP_TO; } +****************************** END WORKAROUND *******************************/ // finds values of t where the curve in pts should be subdivided in order // to get good offset curves a distance of w away from the middle curve. @@ -932,18 +938,168 @@ final class Stroker implements PathConsumer2D { middle[2] = x1; middle[3] = y1; middle[4] = x2; middle[5] = y2; middle[6] = x3; middle[7] = y3; - somethingTo(8); - } - @Override public long getNativeConsumer() { - throw new InternalError("Stroker doesn't use a native consumer"); + // inlined version of somethingTo(8); + // See the TODO on somethingTo + + // need these so we can update the state at the end of this method + final float xf = middle[6], yf = middle[7]; + float dxs = middle[2] - middle[0]; + float dys = middle[3] - middle[1]; + float dxf = middle[6] - middle[4]; + float dyf = middle[7] - middle[5]; + + boolean p1eqp2 = (dxs == 0f && dys == 0f); + boolean p3eqp4 = (dxf == 0f && dyf == 0f); + if (p1eqp2) { + dxs = middle[4] - middle[0]; + dys = middle[5] - middle[1]; + if (dxs == 0f && dys == 0f) { + dxs = middle[6] - middle[0]; + dys = middle[7] - middle[1]; + } + } + if (p3eqp4) { + dxf = middle[6] - middle[2]; + dyf = middle[7] - middle[3]; + if (dxf == 0f && dyf == 0f) { + dxf = middle[6] - middle[0]; + dyf = middle[7] - middle[1]; + } + } + if (dxs == 0f && dys == 0f) { + // this happens iff the "curve" is just a point + lineTo(middle[0], middle[1]); + return; + } + + // if these vectors are too small, normalize them, to avoid future + // precision problems. + if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) { + float len = (float)Math.sqrt(dxs*dxs + dys*dys); + dxs /= len; + dys /= len; + } + if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) { + float len = (float)Math.sqrt(dxf*dxf + dyf*dyf); + dxf /= len; + dyf /= len; + } + + computeOffset(dxs, dys, lineWidth2, offset[0]); + final float mx = offset[0][0]; + final float my = offset[0][1]; + drawJoin(cdx, cdy, cx0, cy0, dxs, dys, cmx, cmy, mx, my); + + int nSplits = findSubdivPoints(middle, subdivTs, 8, lineWidth2); + + int kind = 0; + Iterator it = Curve.breakPtsAtTs(middle, 8, subdivTs, nSplits); + while(it.hasNext()) { + int curCurveOff = it.next(); + + kind = computeOffsetCubic(middle, curCurveOff, lp, rp); + if (kind != 0) { + emitLineTo(lp[0], lp[1]); + switch(kind) { + case 8: + emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false); + emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true); + break; + case 4: + emitLineTo(lp[2], lp[3]); + emitLineTo(rp[0], rp[1], true); + break; + } + emitLineTo(rp[kind - 2], rp[kind - 1], true); + } + } + + this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2; + this.cmy = (lp[kind - 1] - rp[kind - 1]) / 2; + this.cdx = dxf; + this.cdy = dyf; + this.cx0 = xf; + this.cy0 = yf; + this.prev = DRAWING_OP_TO; } @Override public void quadTo(float x1, float y1, float x2, float y2) { middle[0] = cx0; middle[1] = cy0; middle[2] = x1; middle[3] = y1; middle[4] = x2; middle[5] = y2; - somethingTo(6); + + // inlined version of somethingTo(8); + // See the TODO on somethingTo + + // need these so we can update the state at the end of this method + final float xf = middle[4], yf = middle[5]; + float dxs = middle[2] - middle[0]; + float dys = middle[3] - middle[1]; + float dxf = middle[4] - middle[2]; + float dyf = middle[5] - middle[3]; + if ((dxs == 0f && dys == 0f) || (dxf == 0f && dyf == 0f)) { + dxs = dxf = middle[4] - middle[0]; + dys = dyf = middle[5] - middle[1]; + } + if (dxs == 0f && dys == 0f) { + // this happens iff the "curve" is just a point + lineTo(middle[0], middle[1]); + return; + } + // if these vectors are too small, normalize them, to avoid future + // precision problems. + if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) { + float len = (float)Math.sqrt(dxs*dxs + dys*dys); + dxs /= len; + dys /= len; + } + if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) { + float len = (float)Math.sqrt(dxf*dxf + dyf*dyf); + dxf /= len; + dyf /= len; + } + + computeOffset(dxs, dys, lineWidth2, offset[0]); + final float mx = offset[0][0]; + final float my = offset[0][1]; + drawJoin(cdx, cdy, cx0, cy0, dxs, dys, cmx, cmy, mx, my); + + int nSplits = findSubdivPoints(middle, subdivTs, 6, lineWidth2); + + int kind = 0; + Iterator it = Curve.breakPtsAtTs(middle, 6, subdivTs, nSplits); + while(it.hasNext()) { + int curCurveOff = it.next(); + + kind = computeOffsetQuad(middle, curCurveOff, lp, rp); + if (kind != 0) { + emitLineTo(lp[0], lp[1]); + switch(kind) { + case 6: + emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false); + emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true); + break; + case 4: + emitLineTo(lp[2], lp[3]); + emitLineTo(rp[0], rp[1], true); + break; + } + emitLineTo(rp[kind - 2], rp[kind - 1], true); + } + } + + this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2; + this.cmy = (lp[kind - 1] - rp[kind - 1]) / 2; + this.cdx = dxf; + this.cdy = dyf; + this.cx0 = xf; + this.cy0 = yf; + this.prev = DRAWING_OP_TO; + } + + @Override public long getNativeConsumer() { + throw new InternalError("Stroker doesn't use a native consumer"); } // a stack of polynomial curves where each curve shares endpoints with diff --git a/jdk/src/share/classes/sun/launcher/LauncherHelper.java b/jdk/src/share/classes/sun/launcher/LauncherHelper.java index ff71e8908b1..bd0b72e47ab 100644 --- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java +++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java @@ -42,10 +42,12 @@ package sun.launcher; import java.io.File; import java.io.IOException; import java.io.PrintStream; +import java.io.UnsupportedEncodingException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.RoundingMode; +import java.nio.charset.Charset; import java.util.ResourceBundle; import java.text.MessageFormat; import java.util.ArrayList; @@ -471,11 +473,11 @@ public enum LauncherHelper { } catch (ClassNotFoundException cnfe) { abort(ostream, cnfe, "java.launcher.cls.error1", cn); } - signatureDiagnostic(ostream, c); + getMainMethod(ostream, c); return c; } - static void signatureDiagnostic(PrintStream ostream, Class clazz) { + static Method getMainMethod(PrintStream ostream, Class clazz) { String classname = clazz.getName(); Method method = null; try { @@ -495,6 +497,31 @@ public enum LauncherHelper { if (method.getReturnType() != java.lang.Void.TYPE) { abort(ostream, null, "java.launcher.cls.error3", classname); } - return; + return method; + } + + private static final String encprop = "sun.jnu.encoding"; + private static String encoding = null; + private static boolean isCharsetSupported = false; + + /* + * converts a c or a byte array to a platform specific string, + * previously implemented as a native method in the launcher. + */ + static String makePlatformString(boolean printToStderr, byte[] inArray) { + final PrintStream ostream = (printToStderr) ? System.err : System.out; + if (encoding == null) { + encoding = System.getProperty(encprop); + isCharsetSupported = Charset.isSupported(encoding); + } + try { + String out = isCharsetSupported + ? new String(inArray, encoding) + : new String(inArray); + return out; + } catch (UnsupportedEncodingException uee) { + abort(ostream, uee, null); + } + return null; // keep the compiler happy } } diff --git a/jdk/src/share/classes/java/dyn/MethodTypeForm.java b/jdk/src/share/classes/sun/misc/JavaSecurityAccess.java similarity index 68% rename from jdk/src/share/classes/java/dyn/MethodTypeForm.java rename to jdk/src/share/classes/sun/misc/JavaSecurityAccess.java index 35c59a45c0c..5a3aa513fb8 100644 --- a/jdk/src/share/classes/java/dyn/MethodTypeForm.java +++ b/jdk/src/share/classes/sun/misc/JavaSecurityAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,17 +23,18 @@ * questions. */ -package java.dyn; +package sun.misc; -/** - * TO DO: Temporary shim; remove after refactoring effects are complete in JVM. - * @author John Rose - */ -import sun.dyn.MethodTypeImpl; +import java.security.AccessControlContext; +import java.security.PrivilegedAction; -class MethodTypeForm extends MethodTypeImpl { +public interface JavaSecurityAccess { + + T doIntersectionPrivilege(PrivilegedAction action, + AccessControlContext stack, + AccessControlContext context); + + T doIntersectionPrivilege(PrivilegedAction action, + AccessControlContext context); - MethodTypeForm(MethodType erasedType) { - super(erasedType); - } } diff --git a/jdk/src/share/classes/sun/misc/SharedSecrets.java b/jdk/src/share/classes/sun/misc/SharedSecrets.java index 2335b2d68b5..0bd39b4a5d4 100644 --- a/jdk/src/share/classes/sun/misc/SharedSecrets.java +++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java @@ -30,6 +30,8 @@ import java.io.Console; import java.io.FileDescriptor; import java.security.ProtectionDomain; +import java.security.AccessController; + /** A repository of "shared secrets", which are a mechanism for calling implementation-private methods in another package without using reflection. A package-private class implements a public @@ -48,6 +50,7 @@ public class SharedSecrets { private static JavaNioAccess javaNioAccess; private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess; private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess; + private static JavaSecurityAccess javaSecurityAccess; public static JavaUtilJarAccess javaUtilJarAccess() { if (javaUtilJarAccess == null) { @@ -125,4 +128,15 @@ public class SharedSecrets { unsafe.ensureClassInitialized(ProtectionDomain.class); return javaSecurityProtectionDomainAccess; } + + public static void setJavaSecurityAccess(JavaSecurityAccess jsa) { + javaSecurityAccess = jsa; + } + + public static JavaSecurityAccess getJavaSecurityAccess() { + if (javaSecurityAccess == null) { + unsafe.ensureClassInitialized(AccessController.class); + } + return javaSecurityAccess; + } } diff --git a/jdk/src/share/classes/sun/net/ResourceManager.java b/jdk/src/share/classes/sun/net/ResourceManager.java new file mode 100644 index 00000000000..11bfc464819 --- /dev/null +++ b/jdk/src/share/classes/sun/net/ResourceManager.java @@ -0,0 +1,82 @@ +/* + * 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.net; + +import java.net.SocketException; +import java.util.concurrent.atomic.AtomicInteger; +import sun.security.action.GetPropertyAction; + +/** + * Manages count of total number of UDP sockets and ensures + * that exception is thrown if we try to create more than the + * configured limit. + * + * This functionality could be put in NetHooks some time in future. + */ + +public class ResourceManager { + + /* default maximum number of udp sockets per VM + * when a security manager is enabled. + * The default is 1024 which is high enough to be useful + * but low enough to be well below the maximum number + * of port numbers actually available on all OSes for + * such sockets (5000 on some versions of windows) + */ + + private static final int DEFAULT_MAX_SOCKETS = 1024; + private static final int maxSockets; + private static final AtomicInteger numSockets; + + static { + String prop = java.security.AccessController.doPrivileged( + new GetPropertyAction("sun.net.maxDatagramSockets") + ); + int defmax = DEFAULT_MAX_SOCKETS; + try { + if (prop != null) { + defmax = Integer.parseInt(prop); + } + } catch (NumberFormatException e) {} + maxSockets = defmax; + numSockets = new AtomicInteger(0); + } + + public static void beforeUdpCreate() throws SocketException { + if (System.getSecurityManager() != null) { + if (numSockets.incrementAndGet() > maxSockets) { + numSockets.decrementAndGet(); + throw new SocketException("maximum number of DatagramSockets reached"); + } + } + } + + public static void afterUdpClose() { + if (System.getSecurityManager() != null) { + numSockets.decrementAndGet(); + } + } +} diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index 69f12a5c601..afc8cea0308 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -2173,6 +2173,13 @@ public class HttpURLConnection extends java.net.HttpURLConnection { if (tryTransparentNTLMServer) { tryTransparentNTLMServer = NTLMAuthenticationProxy.proxy.supportsTransparentAuth; + /* If the platform supports transparent authentication + * then check if we are in a secure environment + * whether, or not, we should try transparent authentication.*/ + if (tryTransparentNTLMServer) { + tryTransparentNTLMServer = + NTLMAuthenticationProxy.proxy.isTrustedSite(url); + } } a = null; if (tryTransparentNTLMServer) { diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/NTLMAuthenticationProxy.java b/jdk/src/share/classes/sun/net/www/protocol/http/NTLMAuthenticationProxy.java index a998d2b1226..b235a0bed17 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/NTLMAuthenticationProxy.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/NTLMAuthenticationProxy.java @@ -36,12 +36,14 @@ import sun.util.logging.PlatformLogger; */ class NTLMAuthenticationProxy { private static Method supportsTA; + private static Method isTrustedSite; private static final String clazzStr = "sun.net.www.protocol.http.ntlm.NTLMAuthentication"; private static final String supportsTAStr = "supportsTransparentAuth"; + private static final String isTrustedSiteStr = "isTrustedSite"; static final NTLMAuthenticationProxy proxy = tryLoadNTLMAuthentication(); static final boolean supported = proxy != null ? true : false; - static final boolean supportsTransparentAuth = supported ? supportsTransparentAuth(supportsTA) : false; + static final boolean supportsTransparentAuth = supported ? supportsTransparentAuth() : false; private final Constructor threeArgCtr; private final Constructor fiveArgCtr; @@ -82,9 +84,22 @@ class NTLMAuthenticationProxy { * authentication (try with the current users credentials before * prompting for username and password, etc). */ - private static boolean supportsTransparentAuth(Method method) { + private static boolean supportsTransparentAuth() { try { - return (Boolean)method.invoke(null); + return (Boolean)supportsTA.invoke(null); + } catch (ReflectiveOperationException roe) { + finest(roe); + } + + return false; + } + + /* Transparent authentication should only be tried with a trusted + * site ( when running in a secure environment ). + */ + public static boolean isTrustedSite(URL url) { + try { + return (Boolean)isTrustedSite.invoke(null, url); } catch (ReflectiveOperationException roe) { finest(roe); } @@ -112,6 +127,7 @@ class NTLMAuthenticationProxy { int.class, PasswordAuthentication.class); supportsTA = cl.getDeclaredMethod(supportsTAStr); + isTrustedSite = cl.getDeclaredMethod(isTrustedSiteStr, java.net.URL.class); return new NTLMAuthenticationProxy(threeArg, fiveArg); } diff --git a/jdk/src/share/classes/org/relaxng/datatype/DatatypeException.java b/jdk/src/share/classes/sun/net/www/protocol/http/ntlm/NTLMAuthenticationCallback.java similarity index 50% rename from jdk/src/share/classes/org/relaxng/datatype/DatatypeException.java rename to jdk/src/share/classes/sun/net/www/protocol/http/ntlm/NTLMAuthenticationCallback.java index aae00d0aa0b..92886311e09 100644 --- a/jdk/src/share/classes/org/relaxng/datatype/DatatypeException.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/ntlm/NTLMAuthenticationCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,42 +23,37 @@ * questions. */ -package org.relaxng.datatype; +package sun.net.www.protocol.http.ntlm; + +import java.net.URL; /** - * Signals Datatype related exceptions. - * - * @author James Clark - * @author Kohsuke KAWAGUCHI + * This class is used to call back to deployment to determine if a given + * URL is trusted. Transparent authentication (try with logged in users + * credentials without prompting) should only be tried with trusted sites. */ -public class DatatypeException extends Exception { +public abstract class NTLMAuthenticationCallback { + private static volatile NTLMAuthenticationCallback callback = + new DefaultNTLMAuthenticationCallback(); - public DatatypeException( int index, String msg ) { - super(msg); - this.index = index; - } - public DatatypeException( String msg ) { - this(UNKNOWN,msg); - } - /** - * A constructor for those datatype libraries which don't support any - * diagnostic information at all. - */ - public DatatypeException() { - this(UNKNOWN,null); - } + public static void setNTLMAuthenticationCallback( + NTLMAuthenticationCallback callback) { + NTLMAuthenticationCallback.callback = callback; + } + public static NTLMAuthenticationCallback getNTLMAuthenticationCallback() { + return callback; + } - private final int index; + /** + * Returns true if the given site is trusted, i.e. we can try + * transparent Authentication. + */ + public abstract boolean isTrustedSite(URL url); - public static final int UNKNOWN = -1; - - /** - * Gets the index of the content where the error occured. - * UNKNOWN can be returned to indicate that no index information - * is available. - */ - public int getIndex() { - return index; - } + static class DefaultNTLMAuthenticationCallback extends NTLMAuthenticationCallback { + @Override + public boolean isTrustedSite(URL url) { return true; } + } } + diff --git a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java index 8d2e31bf74c..de712d6b64f 100644 --- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -32,6 +32,7 @@ import java.nio.ByteBuffer; import java.nio.channels.*; import java.nio.channels.spi.*; import java.util.*; +import sun.net.ResourceManager; /** @@ -101,14 +102,22 @@ class DatagramChannelImpl throws IOException { super(sp); - this.family = Net.isIPv6Available() ? - StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; - this.fd = Net.socket(family, false); - this.fdVal = IOUtil.fdVal(fd); - this.state = ST_UNCONNECTED; + ResourceManager.beforeUdpCreate(); + try { + this.family = Net.isIPv6Available() ? + StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; + this.fd = Net.socket(family, false); + this.fdVal = IOUtil.fdVal(fd); + this.state = ST_UNCONNECTED; + } catch (IOException ioe) { + ResourceManager.afterUdpClose(); + throw ioe; + } } - public DatagramChannelImpl(SelectorProvider sp, ProtocolFamily family) { + public DatagramChannelImpl(SelectorProvider sp, ProtocolFamily family) + throws IOException + { super(sp); if ((family != StandardProtocolFamily.INET) && (family != StandardProtocolFamily.INET6)) @@ -755,11 +764,14 @@ class DatagramChannelImpl throw new IllegalArgumentException("Group not a multicast address"); // check multicast address is compatible with this socket - if (!(group instanceof Inet4Address)) { - if (family == StandardProtocolFamily.INET) - throw new IllegalArgumentException("Group is not IPv4 address"); - if (!(group instanceof Inet6Address)) - throw new IllegalArgumentException("Address type not supported"); + if (group instanceof Inet4Address) { + if (family == StandardProtocolFamily.INET6 && !Net.canIPv6SocketJoinIPv4Group()) + throw new IllegalArgumentException("Group is not IPv4 multicast address"); + } else if (group instanceof Inet6Address) { + if (family != StandardProtocolFamily.INET6) + throw new IllegalArgumentException("Group is not IPv6 multicast address"); + } else { + throw new IllegalArgumentException("Address type not supported"); } // check source address @@ -791,7 +803,9 @@ class DatagramChannelImpl } MembershipKeyImpl key; - if (family == StandardProtocolFamily.INET6) { + if ((family == StandardProtocolFamily.INET6) && + ((group instanceof Inet6Address) || Net.canJoin6WithIPv4Group())) + { int index = interf.getIndex(); if (index == -1) throw new IOException("Network interface cannot be identified"); @@ -861,7 +875,7 @@ class DatagramChannelImpl return; try { - if (family == StandardProtocolFamily.INET6) { + if (key instanceof MembershipKeyImpl.Type6) { MembershipKeyImpl.Type6 key6 = (MembershipKeyImpl.Type6)key; Net.drop6(fd, key6.groupAddress(), key6.index(), key6.source()); @@ -901,7 +915,7 @@ class DatagramChannelImpl throw new IllegalArgumentException("Source address is different type to group"); int n; - if (family == StandardProtocolFamily.INET6) { + if (key instanceof MembershipKeyImpl.Type6) { MembershipKeyImpl.Type6 key6 = (MembershipKeyImpl.Type6)key; n = Net.block6(fd, key6.groupAddress(), key6.index(), @@ -931,7 +945,7 @@ class DatagramChannelImpl throw new IllegalStateException("key is no longer valid"); try { - if (family == StandardProtocolFamily.INET6) { + if (key instanceof MembershipKeyImpl.Type6) { MembershipKeyImpl.Type6 key6 = (MembershipKeyImpl.Type6)key; Net.unblock6(fd, key6.groupAddress(), key6.index(), @@ -952,6 +966,7 @@ class DatagramChannelImpl protected void implCloseSelectableChannel() throws IOException { synchronized (stateLock) { nd.preClose(fd); + ResourceManager.afterUdpClose(); // if member of mulitcast group then invalidate all keys if (registry != null) diff --git a/jdk/src/share/classes/sun/nio/ch/Net.java b/jdk/src/share/classes/sun/nio/ch/Net.java index b1b893a5cb2..58cfe3b1a5b 100644 --- a/jdk/src/share/classes/sun/nio/ch/Net.java +++ b/jdk/src/share/classes/sun/nio/ch/Net.java @@ -60,6 +60,21 @@ class Net { // package-private return isIPv6Available; } + /** + * Tells whether IPv6 sockets can join IPv4 multicast groups + */ + static boolean canIPv6SocketJoinIPv4Group() { + return canIPv6SocketJoinIPv4Group0(); + } + + /** + * Tells whether {@link #join6} can be used to join an IPv4 + * multicast group (IPv4 group as IPv4-mapped IPv6 address) + */ + static boolean canJoin6WithIPv4Group() { + return canJoin6WithIPv4Group0(); + } + static InetSocketAddress checkAddress(SocketAddress sa) { if (sa == null) throw new NullPointerException(); @@ -291,13 +306,18 @@ class Net { // package-private // -- Socket operations -- - static native boolean isIPv6Available0(); + private static native boolean isIPv6Available0(); - static FileDescriptor socket(boolean stream) { + private static native boolean canIPv6SocketJoinIPv4Group0(); + + private static native boolean canJoin6WithIPv4Group0(); + + static FileDescriptor socket(boolean stream) throws IOException { return socket(UNSPEC, stream); } - static FileDescriptor socket(ProtocolFamily family, boolean stream) { + static FileDescriptor socket(ProtocolFamily family, boolean stream) + throws IOException { boolean preferIPv6 = isIPv6Available() && (family != StandardProtocolFamily.INET); return IOUtil.newFD(socket0(preferIPv6, stream, false)); diff --git a/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java b/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java index 4011291d009..07f931c995c 100644 --- a/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java +++ b/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java @@ -679,6 +679,14 @@ public class ExtendedCharsets "1124" }); + charset("x-IBM1364", "IBM1364", + new String[] { + "cp1364", + "ibm1364", + "ibm-1364", + "1364" + }); + charset("IBM273", "IBM273", new String[] { "cp273", // JDK historical diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java b/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java index cd1e6c26b8d..33eeb315f43 100644 --- a/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java +++ b/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java @@ -57,8 +57,8 @@ abstract class AbstractAclFileAttributeView setAcl((List)value); return; } - throw new UnsupportedOperationException("'" + name() + ":" + - attribute + "' not supported"); + throw new IllegalArgumentException("'" + name() + ":" + + attribute + "' not recognized"); } @Override @@ -81,6 +81,8 @@ abstract class AbstractAclFileAttributeView owner = true; continue; } + throw new IllegalArgumentException("'" + name() + ":" + + attribute + "' not recognized"); } Map result = new HashMap<>(2); if (acl) diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java b/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java index 6383c08edf1..9fa04ee7f8e 100644 --- a/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java +++ b/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java @@ -46,6 +46,18 @@ abstract class AbstractBasicFileAttributeView private static final String IS_SYMBOLIC_LINK_NAME = "isSymbolicLink"; private static final String IS_OTHER_NAME = "isOther"; + // the names of the basic attributes + static final Set basicAttributeNames = + Util.newSet(SIZE_NAME, + CREATION_TIME_NAME, + LAST_ACCESS_TIME_NAME, + LAST_MODIFIED_TIME_NAME, + FILE_KEY_NAME, + IS_DIRECTORY_NAME, + IS_REGULAR_FILE_NAME, + IS_SYMBOLIC_LINK_NAME, + IS_OTHER_NAME); + protected AbstractBasicFileAttributeView() { } @Override @@ -69,24 +81,26 @@ abstract class AbstractBasicFileAttributeView setTimes(null, null, (FileTime)value); return; } - throw new UnsupportedOperationException("'" + attribute + - "' is unknown or read-only attribute"); + throw new IllegalArgumentException("'" + name() + ":" + + attribute + "' not recognized"); } /** * Used to build a map of attribute name/values. */ static class AttributesBuilder { - private Set set = new HashSet<>(); + private Set names = new HashSet<>(); private Map map = new HashMap<>(); private boolean copyAll; - private AttributesBuilder(String[] attributes) { - for (String attribute: attributes) { - if (attribute.equals("*")) { + private AttributesBuilder(Set allowed, String[] requested) { + for (String name: requested) { + if (name.equals("*")) { copyAll = true; } else { - set.add(attribute); + if (!allowed.contains(name)) + throw new IllegalArgumentException("'" + name + "' not recognized"); + names.add(name); } } } @@ -94,21 +108,19 @@ abstract class AbstractBasicFileAttributeView /** * Creates builder to build up a map of the matching attributes */ - static AttributesBuilder create(String[] attributes) { - return new AttributesBuilder(attributes); + static AttributesBuilder create(Set allowed, String[] requested) { + return new AttributesBuilder(allowed, requested); } /** * Returns true if the attribute should be returned in the map */ - boolean match(String attribute) { - if (copyAll) - return true; - return set.contains(attribute); + boolean match(String name) { + return copyAll || names.contains(name); } - void add(String attribute, Object value) { - map.put(attribute, value); + void add(String name, Object value) { + map.put(name, value); } /** @@ -124,7 +136,7 @@ abstract class AbstractBasicFileAttributeView * Invoked by readAttributes or sub-classes to add all matching basic * attributes to the builder */ - final void addBasicAttributesToBuilder(BasicFileAttributes attrs, + final void addRequestedBasicAttributes(BasicFileAttributes attrs, AttributesBuilder builder) { if (builder.match(SIZE_NAME)) @@ -148,9 +160,12 @@ abstract class AbstractBasicFileAttributeView } @Override - public Map readAttributes(String[] attributes) throws IOException { - AttributesBuilder builder = AttributesBuilder.create(attributes); - addBasicAttributesToBuilder(readAttributes(), builder); + public Map readAttributes(String[] requested) + throws IOException + { + AttributesBuilder builder = + AttributesBuilder.create(basicAttributeNames, requested); + addRequestedBasicAttributes(readAttributes(), builder); return builder.unmodifiableMap(); } } diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractFileSystemProvider.java b/jdk/src/share/classes/sun/nio/fs/AbstractFileSystemProvider.java index 95d1cb30931..9e1dc6133ac 100644 --- a/jdk/src/share/classes/sun/nio/fs/AbstractFileSystemProvider.java +++ b/jdk/src/share/classes/sun/nio/fs/AbstractFileSystemProvider.java @@ -29,7 +29,6 @@ import java.nio.file.*; import java.nio.file.spi.FileSystemProvider; import java.io.IOException; import java.util.Map; -import java.util.Collections; /** * Base implementation class of FileSystemProvider @@ -72,6 +71,8 @@ abstract class AbstractFileSystemProvider extends FileSystemProvider { throws IOException { String[] s = split(attribute); + if (s[0].length() == 0) + throw new IllegalArgumentException(attribute); DynamicFileAttributeView view = getFileAttributeView(file, s[0], options); if (view == null) throw new UnsupportedOperationException("View '" + s[0] + "' not available"); @@ -83,9 +84,11 @@ abstract class AbstractFileSystemProvider extends FileSystemProvider { throws IOException { String[] s = split(attributes); + if (s[0].length() == 0) + throw new IllegalArgumentException(attributes); DynamicFileAttributeView view = getFileAttributeView(file, s[0], options); if (view == null) - return Collections.emptyMap(); + throw new UnsupportedOperationException("View '" + s[0] + "' not available"); return view.readAttributes(s[1].split(",")); } diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java b/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java index cf36a09ff0a..8a4f975c4f4 100644 --- a/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java +++ b/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java @@ -59,22 +59,6 @@ abstract class AbstractUserDefinedFileAttributeView return "user"; } - private Object getAttribute(String attribute) throws IOException { - int size; - try { - size = size(attribute); - } catch (IOException e) { - // not found or some other I/O error - if (list().contains(attribute)) - throw e; - return null; - } - - byte[] buf = new byte[size]; - int n = read(attribute, ByteBuffer.wrap(buf)); - return (n == size) ? buf : Arrays.copyOf(buf, n); - } - @Override public final void setAttribute(String attribute, Object value) throws IOException @@ -94,12 +78,13 @@ abstract class AbstractUserDefinedFileAttributeView { // names of attributes to return List names = new ArrayList<>(); - for (String name: attributes) { if (name.equals("*")) { names = list(); break; } else { + if (name.length() == 0) + throw new IllegalArgumentException(); names.add(name); } } @@ -107,11 +92,12 @@ abstract class AbstractUserDefinedFileAttributeView // read each value and return in map Map result = new HashMap<>(); for (String name: names) { - Object value = getAttribute(name); - if (value != null) - result.put(name, value); + int size = size(name); + byte[] buf = new byte[size]; + int n = read(name, ByteBuffer.wrap(buf)); + byte[] value = (n == size) ? buf : Arrays.copyOf(buf, n); + result.put(name, value); } - return result; } } diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java b/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java index 55234ba6528..f083f46313a 100644 --- a/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java +++ b/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java @@ -81,7 +81,8 @@ abstract class AbstractWatchKey implements WatchKey { /** * Return the original watchable (Path) */ - Path watchable() { + @Override + public Path watchable() { return dir; } diff --git a/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java b/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java index aae9bd318c1..5fcb21e264a 100644 --- a/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java +++ b/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java @@ -63,10 +63,10 @@ final class FileOwnerAttributeViewImpl { if (attribute.equals(OWNER_NAME)) { setOwner((UserPrincipal)value); - return; + } else { + throw new IllegalArgumentException("'" + name() + ":" + + attribute + "' not recognized"); } - throw new UnsupportedOperationException("'" + name() + ":" + - attribute + "' not supported"); } @Override @@ -75,6 +75,9 @@ final class FileOwnerAttributeViewImpl for (String attribute: attributes) { if (attribute.equals("*") || attribute.equals(OWNER_NAME)) { result.put(OWNER_NAME, getOwner()); + } else { + throw new IllegalArgumentException("'" + name() + ":" + + attribute + "' not recognized"); } } return result; diff --git a/jdk/src/share/classes/sun/nio/fs/Util.java b/jdk/src/share/classes/sun/nio/fs/Util.java index 6a289058e4b..76287011169 100644 --- a/jdk/src/share/classes/sun/nio/fs/Util.java +++ b/jdk/src/share/classes/sun/nio/fs/Util.java @@ -25,6 +25,8 @@ package sun.nio.fs; +import java.util.*; + /** * Utility methods */ @@ -54,6 +56,28 @@ class Util { } result[n] = s.substring(last, s.length()); return result; + } + /** + * Returns a Set containing the given elements. + */ + static Set newSet(E... elements) { + HashSet set = new HashSet<>(); + for (E e: elements) { + set.add(e); + } + return set; + } + + /** + * Returns a Set containing all the elements of the given Set plus + * the given elements. + */ + static Set newSet(Set other, E... elements) { + HashSet set = new HashSet<>(other); + for (E e: elements) { + set.add(e); + } + return set; } } diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11Key.java b/jdk/src/share/classes/sun/security/pkcs11/P11Key.java index b54d0d3c190..56c40a97586 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/P11Key.java +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Key.java @@ -999,18 +999,34 @@ abstract class P11Key implements Key { new CK_ATTRIBUTE(CKA_EC_PARAMS), }; fetchAttributes(attributes); + try { params = P11ECKeyFactory.decodeParameters (attributes[1].getByteArray()); - DerValue wECPoint = new DerValue(attributes[0].getByteArray()); - if (wECPoint.getTag() != DerValue.tag_OctetString) - throw new IOException("Unexpected tag: " + - wECPoint.getTag()); - params = P11ECKeyFactory.decodeParameters - (attributes[1].getByteArray()); - w = P11ECKeyFactory.decodePoint - (wECPoint.getDataBytes(), params.getCurve()); + /* + * An uncompressed EC point may be in either of two formats. + * First try the OCTET STRING encoding: + * 04 04 + * + * Otherwise try the raw encoding: + * 04 + */ + byte[] ecKey = attributes[0].getByteArray(); + + try { + DerValue wECPoint = new DerValue(ecKey); + if (wECPoint.getTag() != DerValue.tag_OctetString) + throw new IOException("Unexpected tag: " + + wECPoint.getTag()); + + w = P11ECKeyFactory.decodePoint + (wECPoint.getDataBytes(), params.getCurve()); + + } catch (IOException e) { + // Failover + w = P11ECKeyFactory.decodePoint(ecKey, params.getCurve()); + } } catch (Exception e) { throw new RuntimeException("Could not parse key values", e); diff --git a/jdk/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java b/jdk/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java index 1b14bf8fa66..959ac59d12c 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java @@ -46,10 +46,16 @@ import sun.security.x509.AuthorityKeyIdentifierExtension; */ class AdaptableX509CertSelector extends X509CertSelector { // The start date of a validity period. - private Date startDate = null; + private Date startDate; // The end date of a validity period. - private Date endDate = null; + private Date endDate; + + // Is subject key identifier sensitive? + private boolean isSKIDSensitive = false; + + // Is serial number sensitive? + private boolean isSNSensitive = false; AdaptableX509CertSelector() { super(); @@ -97,15 +103,24 @@ class AdaptableX509CertSelector extends X509CertSelector { if (akidext != null) { KeyIdentifier akid = (KeyIdentifier)akidext.get(akidext.KEY_ID); if (akid != null) { - DerOutputStream derout = new DerOutputStream(); - derout.putOctetString(akid.getIdentifier()); - super.setSubjectKeyIdentifier(derout.toByteArray()); + // Do not override the previous setting for initial selection. + if (isSKIDSensitive || getSubjectKeyIdentifier() == null) { + DerOutputStream derout = new DerOutputStream(); + derout.putOctetString(akid.getIdentifier()); + super.setSubjectKeyIdentifier(derout.toByteArray()); + + isSKIDSensitive = true; + } } SerialNumber asn = (SerialNumber)akidext.get(akidext.SERIAL_NUMBER); if (asn != null) { - super.setSerialNumber(asn.getNumber()); + // Do not override the previous setting for initial selection. + if (isSNSensitive || getSerialNumber() == null) { + super.setSerialNumber(asn.getNumber()); + isSNSensitive = true; + } } // the subject criterion should be set by the caller. @@ -148,11 +163,25 @@ class AdaptableX509CertSelector extends X509CertSelector { } } - if (version < 3 || xcert.getExtensionValue("2.5.29.14") == null) { - // If no SubjectKeyIdentifier extension, don't bother to check it. + // If no SubjectKeyIdentifier extension, don't bother to check it. + if (isSKIDSensitive && + (version < 3 || xcert.getExtensionValue("2.5.29.14") == null)) { setSubjectKeyIdentifier(null); } + // In practice, a CA may replace its root certificate and require that + // the existing certificate is still valid, even if the AKID extension + // does not match the replacement root certificate fields. + // + // Conservatively, we only support the replacement for version 1 and + // version 2 certificate. As for version 2, the certificate extension + // may contain sensitive information (for example, policies), the + // AKID need to be respected to seek the exact certificate in case + // of key or certificate abuse. + if (isSNSensitive && version < 3) { + setSerialNumber(null); + } + return super.match(cert); } diff --git a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java index e9c0ca77879..e2666a6771b 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java @@ -243,12 +243,6 @@ class ForwardBuilder extends Builder { caTargetSelector.setPolicy(getMatchingPolicies()); } - /* - * Require CA certs with a pathLenConstraint that allows - * at least as many CA certs that have already been traversed - */ - caTargetSelector.setBasicConstraints(currentState.traversedCACerts); - sel = caTargetSelector; } else { @@ -282,12 +276,6 @@ class ForwardBuilder extends Builder { CertPathHelper.setPathToNames (caSelector, currentState.subjectNamesTraversed); - /* - * Require CA certs with a pathLenConstraint that allows - * at least as many CA certs that have already been traversed - */ - caSelector.setBasicConstraints(currentState.traversedCACerts); - /* * Facilitate certification path construction with authority * key identifier and subject key identifier. @@ -305,6 +293,14 @@ class ForwardBuilder extends Builder { sel = caSelector; } + /* + * For compatibility, conservatively, we don't check the path + * length constraint of trusted anchors. Please don't set the + * basic constraints criterion unless the trusted certificate + * matching is completed. + */ + sel.setBasicConstraints(-1); + for (X509Certificate trustedCert : trustedCerts) { if (sel.match(trustedCert)) { if (debug != null) { @@ -323,6 +319,12 @@ class ForwardBuilder extends Builder { */ sel.setCertificateValid(date); + /* + * Require CA certs with a pathLenConstraint that allows + * at least as many CA certs that have already been traversed + */ + sel.setBasicConstraints(currentState.traversedCACerts); + /* * If we have already traversed as many CA certs as the maxPathLength * will allow us to, then we don't bother looking through these diff --git a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java index 3920b35c37a..fbf23196aba 100644 --- a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java +++ b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -377,8 +377,9 @@ final class ClientHandshaker extends Handshaker { ProtocolVersion mesgVersion = mesg.protocolVersion; if (!isNegotiable(mesgVersion)) { throw new SSLHandshakeException( - "Server chose unsupported or disabled protocol: " + - mesgVersion); + "Server chose " + mesgVersion + + ", but that protocol version is not enabled or not supported " + + "by the client."); } handshakeHash.protocolDetermined(mesgVersion); diff --git a/jdk/src/share/classes/sun/security/ssl/SunJSSE.java b/jdk/src/share/classes/sun/security/ssl/SunJSSE.java index 1668e6ff79d..bba258670d8 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, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -195,6 +195,8 @@ public abstract class SunJSSE extends java.security.Provider { "sun.security.ssl.KeyManagerFactoryImpl$SunX509"); put("KeyManagerFactory.NewSunX509", "sun.security.ssl.KeyManagerFactoryImpl$X509"); + put("Alg.Alias.KeyManagerFactory.PKIX", "NewSunX509"); + put("TrustManagerFactory.SunX509", "sun.security.ssl.TrustManagerFactoryImpl$SimpleFactory"); put("TrustManagerFactory.PKIX", diff --git a/jdk/src/share/classes/sun/text/resources/CollationData_sr_Latn.java b/jdk/src/share/classes/sun/text/resources/CollationData_sr_Latn.java new file mode 100644 index 00000000000..1c7c5e1e949 --- /dev/null +++ b/jdk/src/share/classes/sun/text/resources/CollationData_sr_Latn.java @@ -0,0 +1,76 @@ +/* + * 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. + */ + +/* + */ + +/* + * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved + * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved + * + * The original version of this source code and documentation + * is copyrighted and owned by Taligent, Inc., a wholly-owned + * subsidiary of IBM. These materials are provided under terms + * of a License Agreement between Taligent and Sun. This technology + * is protected by multiple US and International patents. + * + * This notice and attribution to Taligent may not be removed. + * Taligent is a registered trademark of Taligent, Inc. + * + */ + +package sun.text.resources; + +import java.util.ListResourceBundle; + +public class CollationData_sr_Latn extends ListResourceBundle { + + protected final Object[][] getContents() { + return new Object[][] { + { "Rule", + /* for sr-Latin, default sorting except for the following: */ + + /* add dz "ligature" between d and d. */ + /* add d between d and e. */ + /* add lj "ligature" between l and l. */ + /* add l between l and m. */ + /* add nj "ligature" between n and o. */ + /* add z after z. */ + "& \u200f = \u030c " + + "& \u0306 = \u030d " + + "& C < c\u030c , C\u030c " // C < c-caron + + "< c\u0301 , C\u0301 " // c-acute + + "& D < \u01f3 , \u01f2 , \u01f1 " // dz + + "< dz , dZ , Dz , DZ " // dz ligature + + "< \u01c6 , \u01c5 , \u01c4 " // dz-caron + + "< \u0111 , \u0110 " // d-stroke + + "& L < lj , lJ , Lj , LJ " // l < lj ligature + + "& N < nj , nJ , Nj , NJ " // n < nj ligature + + "& S < s\u030c , S\u030c " // s < s-caron + + "& Z < z\u030c , Z\u030c " // z < z-caron + } + }; + } +} diff --git a/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn.java b/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn.java new file mode 100644 index 00000000000..aa9bca860b6 --- /dev/null +++ b/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 1997, 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. + */ + +/* + * COPYRIGHT AND PERMISSION NOTICE + * + * Copyright (C) 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 of the Unicode data files and any associated documentation (the + * "Data Files") or Unicode software and any associated documentation + * (the "Software") to deal in the Data Files or Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, and/or sell copies of the Data + * Files or Software, and to permit persons to whom the Data Files or + * Software are furnished to do so, provided that (a) the above copyright + * notice(s) and this permission notice appear with all copies of the + * Data Files or Software, (b) both the above copyright notice(s) and + * this permission notice appear in associated documentation, and (c) + * there is clear notice in each modified Data File or in the Software as + * well as in the documentation associated with the Data File(s) or + * Software that the data or software has been modified. + * + * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF + * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR + * ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR + * SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in these Data Files or Software without prior + * written authorization of the copyright holder. + */ + +// Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +package sun.text.resources; + +import java.util.ListResourceBundle; + +public class FormatData_sr_Latn extends ListResourceBundle { + protected final Object[][] getContents() { + return new Object[][] { + { "MonthNames", + new String[] { + "januar", + "februar", + "mart", + "april", + "maj", + "jun", + "jul", + "avgust", + "septembar", + "oktobar", + "novembar", + "decembar", + "", + } + }, + { "MonthAbbreviations", + new String[] { + "jan", + "feb", + "mar", + "apr", + "maj", + "jun", + "jul", + "avg", + "sep", + "okt", + "nov", + "dec", + "", + } + }, + { "DayNames", + new String[] { + "nedelja", + "ponedeljak", + "utorak", + "sreda", + "\u010detvrtak", + "petak", + "subota", + } + }, + { "DayAbbreviations", + new String[] { + "ned", + "pon", + "uto", + "sre", + "\u010det", + "pet", + "sub", + } + }, + { "Eras", + new String[] { + "p. n. e.", + "n. e", + } + }, + { "NumberPatterns", + new String[] { + "#,##0.###", + "\u00a4\u00a0#,##0.00", + "#,##0%", + } + }, + { "NumberElements", + new String[] { + ".", + ",", + ";", + "%", + "0", + "#", + "-", + "E", + "\u2030", + "\u221e", + "NaN", + } + }, + { "DateTimePatterns", + new String[] { + "HH.mm.ss zzzz", + "HH.mm.ss z", + "HH.mm.ss", + "HH.mm", + "EEEE, dd. MMMM y.", + "dd. MMMM y.", + "dd.MM.y.", + "d.M.yy.", + "{1} {0}", + } + }, + }; + } +} diff --git a/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn_BA.java b/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn_BA.java new file mode 100644 index 00000000000..0bdc0061cf9 --- /dev/null +++ b/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn_BA.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1997, 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. + */ + +/* + * COPYRIGHT AND PERMISSION NOTICE + * + * Copyright (C) 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 of the Unicode data files and any associated documentation (the + * "Data Files") or Unicode software and any associated documentation + * (the "Software") to deal in the Data Files or Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, and/or sell copies of the Data + * Files or Software, and to permit persons to whom the Data Files or + * Software are furnished to do so, provided that (a) the above copyright + * notice(s) and this permission notice appear with all copies of the + * Data Files or Software, (b) both the above copyright notice(s) and + * this permission notice appear in associated documentation, and (c) + * there is clear notice in each modified Data File or in the Software as + * well as in the documentation associated with the Data File(s) or + * Software that the data or software has been modified. + * + * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF + * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR + * ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR + * SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in these Data Files or Software without prior + * written authorization of the copyright holder. + */ + +// Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +package sun.text.resources; + +import sun.util.EmptyListResourceBundle; + +public class FormatData_sr_Latn_BA extends EmptyListResourceBundle { +} diff --git a/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn_ME.java b/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn_ME.java new file mode 100644 index 00000000000..dcd50585f0a --- /dev/null +++ b/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn_ME.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1997, 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. + */ + +/* + * COPYRIGHT AND PERMISSION NOTICE + * + * Copyright (C) 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 of the Unicode data files and any associated documentation (the + * "Data Files") or Unicode software and any associated documentation + * (the "Software") to deal in the Data Files or Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, and/or sell copies of the Data + * Files or Software, and to permit persons to whom the Data Files or + * Software are furnished to do so, provided that (a) the above copyright + * notice(s) and this permission notice appear with all copies of the + * Data Files or Software, (b) both the above copyright notice(s) and + * this permission notice appear in associated documentation, and (c) + * there is clear notice in each modified Data File or in the Software as + * well as in the documentation associated with the Data File(s) or + * Software that the data or software has been modified. + * + * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF + * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR + * ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR + * SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in these Data Files or Software without prior + * written authorization of the copyright holder. + */ + +// Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +package sun.text.resources; + +import java.util.ListResourceBundle; + +public class FormatData_sr_Latn_ME extends ListResourceBundle { + protected final Object[][] getContents() { + return new Object[][] { + { "DateTimePatterns", + new String[] { + "HH.mm.ss zzzz", + "HH.mm.ss z", + "HH.mm.ss", + "HH.mm", + "EEEE, dd. MMMM y.", + "d.MM.yyyy.", + "dd.MM.y.", + "d.M.yy.", + "{1} {0}", + } + } + }; + } +} diff --git a/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn_RS.java b/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn_RS.java new file mode 100644 index 00000000000..80fba9f0960 --- /dev/null +++ b/jdk/src/share/classes/sun/text/resources/FormatData_sr_Latn_RS.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1997, 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. + */ + +/* + * COPYRIGHT AND PERMISSION NOTICE + * + * Copyright (C) 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 of the Unicode data files and any associated documentation (the + * "Data Files") or Unicode software and any associated documentation + * (the "Software") to deal in the Data Files or Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, and/or sell copies of the Data + * Files or Software, and to permit persons to whom the Data Files or + * Software are furnished to do so, provided that (a) the above copyright + * notice(s) and this permission notice appear with all copies of the + * Data Files or Software, (b) both the above copyright notice(s) and + * this permission notice appear in associated documentation, and (c) + * there is clear notice in each modified Data File or in the Software as + * well as in the documentation associated with the Data File(s) or + * Software that the data or software has been modified. + * + * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF + * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR + * ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR + * SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in these Data Files or Software without prior + * written authorization of the copyright holder. + */ + +// Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +package sun.text.resources; + +import sun.util.EmptyListResourceBundle; + +public class FormatData_sr_Latn_RS extends EmptyListResourceBundle { +} diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/JConsoleResources_ja.java b/jdk/src/share/classes/sun/tools/jconsole/resources/JConsoleResources_ja.java index 35e7286db22..452e620d7f3 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/JConsoleResources_ja.java +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/JConsoleResources_ja.java @@ -44,7 +44,7 @@ import static java.awt.event.KeyEvent.*; * or if the keys ends with ".mnemonic", an element * representing a mnemomic keycode int or char. */ -public class JConsoleResources_ja extends ListResourceBundle { +public class JConsoleResources_ja extends JConsoleResources { /** * Returns the contents of this ResourceBundle. diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/JConsoleResources_zh_CN.java b/jdk/src/share/classes/sun/tools/jconsole/resources/JConsoleResources_zh_CN.java index a29aaaf4032..b101429d83c 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/JConsoleResources_zh_CN.java +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/JConsoleResources_zh_CN.java @@ -44,7 +44,7 @@ import static java.awt.event.KeyEvent.*; * or if the keys ends with ".mnemonic", an element * representing a mnemomic keycode int or char. */ -public class JConsoleResources_zh_CN extends ListResourceBundle { +public class JConsoleResources_zh_CN extends JConsoleResources { /** * Returns the contents of this ResourceBundle. 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 2cd2bf53ae7..2595b5e1b03 100644 --- a/jdk/src/share/classes/sun/util/logging/resources/logging.properties +++ b/jdk/src/share/classes/sun/util/logging/resources/logging.properties @@ -25,13 +25,22 @@ # Localizations for Level names. For the US locale # these are the same as the non-localized level name. -ALL=ALL -SEVERE=SEVERE -WARNING=WARNING -INFO=INFO -CONFIG= CONFIG -FINE=FINE -FINER=FINER -FINEST=FINEST -OFF=OFF +# The following ALL CAPS words should be translated. +ALL=ALL +# The following ALL CAPS words should be translated. +SEVERE=SEVERE +# The following ALL CAPS words should be translated. +WARNING=WARNING +# The following ALL CAPS words should be translated. +INFO=INFO +# The following ALL CAPS words should be translated. +CONFIG= CONFIG +# The following ALL CAPS words should be translated. +FINE=FINE +# The following ALL CAPS words should be translated. +FINER=FINER +# The following ALL CAPS words should be translated. +FINEST=FINEST +# The following ALL CAPS words should be translated. +OFF=OFF diff --git a/jdk/src/share/classes/sun/util/resources/CalendarData_sr_Latn_BA.properties b/jdk/src/share/classes/sun/util/resources/CalendarData_sr_Latn_BA.properties new file mode 100644 index 00000000000..7d29a94e698 --- /dev/null +++ b/jdk/src/share/classes/sun/util/resources/CalendarData_sr_Latn_BA.properties @@ -0,0 +1,66 @@ +# +# Copyright (c) 2005, 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. +# + +# +# COPYRIGHT AND PERMISSION NOTICE +# +# Copyright (C) 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 of the Unicode data files and any associated documentation (the +# "Data Files") or Unicode software and any associated documentation +# (the "Software") to deal in the Data Files or Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, and/or sell copies of the Data +# Files or Software, and to permit persons to whom the Data Files or +# Software are furnished to do so, provided that (a) the above copyright +# notice(s) and this permission notice appear with all copies of the +# Data Files or Software, (b) both the above copyright notice(s) and +# this permission notice appear in associated documentation, and (c) +# there is clear notice in each modified Data File or in the Software as +# well as in the documentation associated with the Data File(s) or +# Software that the data or software has been modified. +# +# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR +# ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +# SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in these Data Files or Software without prior +# written authorization of the copyright holder. + +# +# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# +minimalDaysInFirstWeek=4 diff --git a/jdk/src/share/classes/sun/util/resources/CalendarData_sr_Latn_ME.properties b/jdk/src/share/classes/sun/util/resources/CalendarData_sr_Latn_ME.properties new file mode 100644 index 00000000000..7d29a94e698 --- /dev/null +++ b/jdk/src/share/classes/sun/util/resources/CalendarData_sr_Latn_ME.properties @@ -0,0 +1,66 @@ +# +# Copyright (c) 2005, 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. +# + +# +# COPYRIGHT AND PERMISSION NOTICE +# +# Copyright (C) 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 of the Unicode data files and any associated documentation (the +# "Data Files") or Unicode software and any associated documentation +# (the "Software") to deal in the Data Files or Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, and/or sell copies of the Data +# Files or Software, and to permit persons to whom the Data Files or +# Software are furnished to do so, provided that (a) the above copyright +# notice(s) and this permission notice appear with all copies of the +# Data Files or Software, (b) both the above copyright notice(s) and +# this permission notice appear in associated documentation, and (c) +# there is clear notice in each modified Data File or in the Software as +# well as in the documentation associated with the Data File(s) or +# Software that the data or software has been modified. +# +# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR +# ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +# SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in these Data Files or Software without prior +# written authorization of the copyright holder. + +# +# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# +minimalDaysInFirstWeek=4 diff --git a/jdk/src/share/classes/sun/util/resources/CalendarData_sr_Latn_RS.properties b/jdk/src/share/classes/sun/util/resources/CalendarData_sr_Latn_RS.properties new file mode 100644 index 00000000000..7d29a94e698 --- /dev/null +++ b/jdk/src/share/classes/sun/util/resources/CalendarData_sr_Latn_RS.properties @@ -0,0 +1,66 @@ +# +# Copyright (c) 2005, 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. +# + +# +# COPYRIGHT AND PERMISSION NOTICE +# +# Copyright (C) 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 of the Unicode data files and any associated documentation (the +# "Data Files") or Unicode software and any associated documentation +# (the "Software") to deal in the Data Files or Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, and/or sell copies of the Data +# Files or Software, and to permit persons to whom the Data Files or +# Software are furnished to do so, provided that (a) the above copyright +# notice(s) and this permission notice appear with all copies of the +# Data Files or Software, (b) both the above copyright notice(s) and +# this permission notice appear in associated documentation, and (c) +# there is clear notice in each modified Data File or in the Software as +# well as in the documentation associated with the Data File(s) or +# Software that the data or software has been modified. +# +# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR +# ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +# SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in these Data Files or Software without prior +# written authorization of the copyright holder. + +# +# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# +minimalDaysInFirstWeek=4 diff --git a/jdk/src/share/classes/sun/util/resources/CurrencyNames.properties b/jdk/src/share/classes/sun/util/resources/CurrencyNames.properties index e3eea6e1fa6..6fac2dd43aa 100644 --- a/jdk/src/share/classes/sun/util/resources/CurrencyNames.properties +++ b/jdk/src/share/classes/sun/util/resources/CurrencyNames.properties @@ -1,45 +1,68 @@ # -# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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. # # # COPYRIGHT AND PERMISSION NOTICE # -# Copyright (C) 1991-2007 Unicode, Inc. All rights reserved. +# Copyright (C) 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 -# of the Unicode data files and any associated documentation (the "Data -# Files") or Unicode software and any associated documentation (the -# "Software") to deal in the Data Files or Software without restriction, -# including without limitation the rights to use, copy, modify, merge, -# publish, distribute, and/or sell copies of the Data Files or Software, and -# to permit persons to whom the Data Files or Software are furnished to do -# so, provided that (a) the above copyright notice(s) and this permission -# notice appear with all copies of the Data Files or Software, (b) both the -# above copyright notice(s) and this permission notice appear in associated -# documentation, and (c) there is clear notice in each modified Data File or -# in the Software as well as in the documentation associated with the Data -# File(s) or Software that the data or software has been modified. +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of the Unicode data files and any associated documentation (the +# "Data Files") or Unicode software and any associated documentation +# (the "Software") to deal in the Data Files or Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, and/or sell copies of the Data +# Files or Software, and to permit persons to whom the Data Files or +# Software are furnished to do so, provided that (a) the above copyright +# notice(s) and this permission notice appear with all copies of the +# Data Files or Software, (b) both the above copyright notice(s) and +# this permission notice appear in associated documentation, and (c) +# there is clear notice in each modified Data File or in the Software as +# well as in the documentation associated with the Data File(s) or +# Software that the data or software has been modified. # -# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF -# THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS -# INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR -# CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF -# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THE DATA FILES OR SOFTWARE. +# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR +# ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +# SOFTWARE. # -# Except as contained in this notice, the name of a copyright holder shall not -# be used in advertising or otherwise to promote the sale, use or other -# dealings in these Data Files or Software without prior written -# authorization of the copyright holder. -# - -# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in these Data Files or Software without prior +# written authorization of the copyright holder. +# +# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# ADP=ADP AED=AED AFA=AFA @@ -254,52 +277,52 @@ ZWD=ZWD ZWN=ZWN adp=Andorran Peseta aed=United Arab Emirates Dirham -afa=Afghani (1927-2002) -afn=Afghani +afa=Afghan Afghani (1927-2002) +afn=Afghan Afghani all=Albanian Lek amd=Armenian Dram -ang=Netherlands Antillan Guilder +ang=Netherlands Antillean Guilder aoa=Angolan Kwanza ars=Argentine Peso ats=Austrian Schilling aud=Australian Dollar -awg=Aruban Guilder -azm=Azerbaijanian Manat (1993-2006) -azn=Azerbaijanian Manat +awg=Aruban Florin +azm=Azerbaijani Manat (1993-2006) +azn=Azerbaijani Manat bam=Bosnia-Herzegovina Convertible Mark -bbd=Barbados Dollar -bdt=Bangladesh Taka +bbd=Barbadian Dollar +bdt=Bangladeshi Taka bef=Belgian Franc bgl=Bulgarian Hard Lev -bgn=Bulgarian New Lev +bgn=Bulgarian Lev bhd=Bahraini Dinar -bif=Burundi Franc +bif=Burundian Franc bmd=Bermudan Dollar bnd=Brunei Dollar -bob=Boliviano +bob=Bolivian Boliviano bov=Bolivian Mvdol brl=Brazilian Real bsd=Bahamian Dollar -btn=Bhutan Ngultrum +btn=Bhutanese Ngultrum bwp=Botswanan Pula -byb=Belarussian New Ruble (1994-1999) -byr=Belarussian Ruble +byb=Belarusian New Ruble (1994-1999) +byr=Belarusian Ruble bzd=Belize Dollar cad=Canadian Dollar -cdf=Congolese Franc Congolais +cdf=Congolese Franc chf=Swiss Franc -clf=Chilean Unidades de Fomento +clf=Chilean Unit of Account (UF) clp=Chilean Peso -cny=Chinese Yuan Renminbi +cny=Chinese Yuan cop=Colombian Peso -crc=Costa Rican Colon -csd=Serbian Dinar +crc=Costa Rican Col\u00f3n +csd=Serbian Dinar (2002-2006) cup=Cuban Peso -cve=Cape Verde Escudo -cyp=Cyprus Pound +cve=Cape Verdean Escudo +cyp=Cypriot Pound czk=Czech Republic Koruna -dem=Deutsche Mark -djf=Djibouti Franc +dem=German Mark +djf=Djiboutian Franc dkk=Danish Krone dop=Dominican Peso dzd=Algerian Dinar @@ -310,22 +333,22 @@ esp=Spanish Peseta etb=Ethiopian Birr eur=Euro fim=Finnish Markka -fjd=Fiji Dollar +fjd=Fijian Dollar fkp=Falkland Islands Pound frf=French Franc gbp=British Pound Sterling gel=Georgian Lari -ghc=Ghana Cedi -ghs=Ghana Cedi +ghc=Ghanaian Cedi (1979-2007) +ghs=Ghanaian Cedi gip=Gibraltar Pound -gmd=Gambia Dalasi -gnf=Guinea Franc +gmd=Gambian Dalasi +gnf=Guinean Franc grd=Greek Drachma -gtq=Guatemala Quetzal +gtq=Guatemalan Quetzal gwp=Guinea-Bissau Peso -gyd=Guyana Dollar +gyd=Guyanaese Dollar hkd=Hong Kong Dollar -hnl=Hoduras Lempira +hnl=Honduran Lempira hrk=Croatian Kuna htg=Haitian Gourde huf=Hungarian Forint @@ -335,110 +358,111 @@ ils=Israeli New Sheqel inr=Indian Rupee iqd=Iraqi Dinar irr=Iranian Rial -isk=Icelandic Krona +isk=Icelandic Kr\u00f3na itl=Italian Lira jmd=Jamaican Dollar jod=Jordanian Dinar jpy=Japanese Yen kes=Kenyan Shilling -kgs=Kyrgystan Som +kgs=Kyrgystani Som khr=Cambodian Riel -kmf=Comoro Franc +kmf=Comorian Franc kpw=North Korean Won krw=South Korean Won kwd=Kuwaiti Dinar kyd=Cayman Islands Dollar -kzt=Kazakhstan Tenge +kzt=Kazakhstani Tenge lak=Laotian Kip lbp=Lebanese Pound -lkr=Sri Lanka Rupee +lkr=Sri Lankan Rupee lrd=Liberian Dollar lsl=Lesotho Loti -ltl=Lithuanian Lita -luf=Luxembourg Franc +ltl=Lithuanian Litas +luf=Luxembourgian Franc lvl=Latvian Lats lyd=Libyan Dinar mad=Moroccan Dirham mdl=Moldovan Leu -mga=Madagascar Ariary -mgf=Madagascar Franc +mga=Malagasy Ariary +mgf=Malagasy Franc mkd=Macedonian Denar -mmk=Myanmar Kyat +mmk=Myanma Kyat mnt=Mongolian Tugrik -mop=Macao Pataca -mro=Mauritania Ouguiya +mop=Macanese Pataca +mro=Mauritanian Ouguiya mtl=Maltese Lira -mur=Mauritius Rupee -mvr=Maldive Islands Rufiyaa -mwk=Malawi Kwacha +mur=Mauritian Rupee +mvr=Maldivian Rufiyaa +mwk=Malawian Kwacha mxn=Mexican Peso -mxv=Mexican Unidad de Inversion (UDI) +mxv=Mexican Investment Unit myr=Malaysian Ringgit -mzm=Old Mozambique Metical -mzn=Mozambique Metical -nad=Namibia Dollar +mzm=Mozambican Metical (1980-2006) +mzn=Mozambican Metical +nad=Namibian Dollar ngn=Nigerian Naira -nio=Nicaraguan Cordoba Oro -nlg=Netherlands Guilder +nio=Nicaraguan C\u00f3rdoba +nlg=Dutch Guilder nok=Norwegian Krone npr=Nepalese Rupee nzd=New Zealand Dollar -omr=Oman Rial +omr=Omani Rial pab=Panamanian Balboa -pen=Peruvian Sol Nuevo -pgk=Papua New Guinea Kina +pen=Peruvian Nuevo Sol +pgk=Papua New Guinean Kina php=Philippine Peso -pkr=Pakistan Rupee +pkr=Pakistani Rupee pln=Polish Zloty pte=Portuguese Escudo -pyg=Paraguay Guarani +pyg=Paraguayan Guarani qar=Qatari Rial -rol=Old Romanian Leu +rol=Romanian Leu (1952-2006) ron=Romanian Leu +rsd=Serbian Dinar rub=Russian Ruble rur=Russian Ruble (1991-1998) rwf=Rwandan Franc sar=Saudi Riyal sbd=Solomon Islands Dollar -scr=Seychelles Rupee -sdd=Sudanese Dinar +scr=Seychellois Rupee +sdd=Sudanese Dinar (1992-2007) sdg=Sudanese Pound sek=Swedish Krona sgd=Singapore Dollar shp=Saint Helena Pound -sit=Slovenia Tolar +sit=Slovenian Tolar skk=Slovak Koruna -sll=Sierra Leone Leone +sll=Sierra Leonean Leone sos=Somali Shilling -srd=Surinam Dollar -srg=Suriname Guilder -std=Sao Tome and Principe Dobra -svc=El Salvador Colon +srd=Surinamese Dollar +srg=Surinamese Guilder +std=S\u00e3o Tom\u00e9 and Pr\u00edncipe Dobra +svc=Salvadoran Col\u00f3n syp=Syrian Pound -szl=Swaziland Lilangeni +szl=Swazi Lilangeni thb=Thai Baht -tjs=Tajikistan Somoni -tmm=Turkmenistan Manat +tjs=Tajikistani Somoni +tmm=Turkmenistani Manat (1993-2009) tnd=Tunisian Dinar -top=Tonga Pa\u02bbanga -tpe=Timor Escudo -trl=Turkish Lira -try=New Turkish Lira +top=Tongan Pa\u02bbanga +tpe=Timorese Escudo +trl=Turkish Lira (1922-2005) +try=Turkish Lira ttd=Trinidad and Tobago Dollar -twd=Taiwan New Dollar +twd=New Taiwan Dollar tzs=Tanzanian Shilling uah=Ukrainian Hryvnia ugx=Ugandan Shilling usd=US Dollar usn=US Dollar (Next day) uss=US Dollar (Same day) -uyu=Uruguay Peso Uruguayo -uzs=Uzbekistan Sum -veb=Venezuelan Bolivar -vef=Venezuelan Bolivar Fuerte +uyu=Uruguayan Peso +uzs=Uzbekistan Som +veb=Venezuelan Bol\u00edvar (1871-2008) +vef=Venezuelan Bol\u00edvar vnd=Vietnamese Dong vuv=Vanuatu Vatu -wst=Western Samoa Tala +wst=Samoan Tala xaf=CFA Franc BEAC xag=Silver xau=Gold @@ -455,9 +479,9 @@ xpd=Palladium xpf=CFP Franc xpt=Platinum xts=Testing Currency Code -xxx=No Currency +xxx=Unknown Currency yer=Yemeni Rial -yum=Yugoslavian Noviy Dinar +yum=Yugoslavian New Dinar (1994-2002) zar=South African Rand zmk=Zambian Kwacha -zwd=Zimbabwe Dollar +zwd=Zimbabwean Dollar (1980-2008) diff --git a/jdk/src/share/classes/sun/util/resources/CurrencyNames_pt.properties b/jdk/src/share/classes/sun/util/resources/CurrencyNames_pt.properties new file mode 100644 index 00000000000..d033ea7e676 --- /dev/null +++ b/jdk/src/share/classes/sun/util/resources/CurrencyNames_pt.properties @@ -0,0 +1,273 @@ +# +# Copyright (c) 2005, 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. +# + +# +# COPYRIGHT AND PERMISSION NOTICE +# +# Copyright (C) 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 of the Unicode data files and any associated documentation (the +# "Data Files") or Unicode software and any associated documentation +# (the "Software") to deal in the Data Files or Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, and/or sell copies of the Data +# Files or Software, and to permit persons to whom the Data Files or +# Software are furnished to do so, provided that (a) the above copyright +# notice(s) and this permission notice appear with all copies of the +# Data Files or Software, (b) both the above copyright notice(s) and +# this permission notice appear in associated documentation, and (c) +# there is clear notice in each modified Data File or in the Software as +# well as in the documentation associated with the Data File(s) or +# Software that the data or software has been modified. +# +# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR +# ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +# SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in these Data Files or Software without prior +# written authorization of the copyright holder. + +# +# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# +adp=Peseta de Andorra +aed=Dir\u00e9m dos Emirados \u00c1rabes Unidos +afa=Afegane (1927-2002) +afn=Afegane +all=Lek Alban\u00eas +amd=Dram arm\u00eanio +ang=Guilder das Antilhas Holandesas +aoa=Cuanza angolano +ars=Peso argentino +ats=Xelim austr\u00edaco +aud=D\u00f3lar australiano +awg=Guilder de Aruba +azm=Manat azerbaijano +azn=Manat do Azerbaij\u00e3o +bam=Marco b\u00f3snio-herzegovino convers\u00edvel +bbd=D\u00f3lar de Barbados +bdt=Taka de Bangladesh +bef=Franco belga +bgl=Lev forte b\u00falgaro +bgn=Lev novo b\u00falgaro +bhd=Dinar bareinita +bif=Franco do Burundi +bmd=D\u00f3lar das Bermudas +bnd=D\u00f3lar do Brunei +bov=Mvdol boliviano +brl=Real brasileiro +bsd=D\u00f3lar das Bahamas +btn=Ngultrum do But\u00e3o +bwp=Pula botsuanesa +byb=Rublo novo bielo-russo (1994-1999) +byr=Rublo bielo-russo +bzd=D\u00f3lar do Belize +cad=D\u00f3lar canadense +cdf=Franco congol\u00eas +chf=Franco su\u00ed\u00e7o +clf=Unidades de Fomento chilenas +clp=Peso chileno +cny=Yuan Renminbi chin\u00eas +cop=Peso colombiano +crc=Colon da Costa Rica +csd=Dinar s\u00e9rvio antigo +cup=Peso cubano +cve=Escudo cabo-verdiano +cyp=Libra cipriota +czk=Coroa checa +dem=Marco alem\u00e3o +djf=Franco do Djibuti +dkk=Coroa dinamarquesa +dop=Peso dominicano +dzd=Dinar argelino +eek=Coroa estoniana +egp=Libra eg\u00edpcia +ern=Nakfa da Eritreia +esp=Peseta espanhola +etb=Birr et\u00edope +fim=Marca finlandesa +fjd=D\u00f3lar de Fiji +fkp=Libra das Malvinas +frf=Franco franc\u00eas +gbp=Libra esterlina brit\u00e2nica +gel=Lari georgiano +ghc=Cedi de Gana (1979-2007) +ghs=Cedi gan\u00eas +gip=Libra de Gibraltar +gmd=Dalasi de G\u00e2mbia +gnf=Franco de Guin\u00e9 +grd=Dracma grego +gtq=Quet\u00e7al da Guatemala +gwp=Peso da Guin\u00e9-Bissau +gyd=D\u00f3lar da Guiana +hkd=D\u00f3lar de Hong Kong +hnl=Lempira de Honduras +hrk=Kuna croata +htg=Gurde do Haiti +huf=Forinte h\u00fangaro +idr=Rupia indon\u00e9sia +iep=Libra irlandesa +ils=Sheqel Novo israelita +inr=R\u00fapia indiana +iqd=Dinar iraquiano +irr=Rial iraniano +isk=Coroa islandesa +itl=Lira italiana +jmd=D\u00f3lar jamaicano +jod=Dinar jordaniano +jpy=Iene japon\u00eas +kes=Xelim queniano +kgs=Som quirguiz +khr=Riel cambojano +kmf=Franco de Comores +kpw=Won norte-coreano +krw=Won sul-coreano +kwd=Dinar coveitiano +kyd=D\u00f3lar das Ilhas Caiman +kzt=Tenge do Cazaquist\u00e3o +lak=Kip de Laos +lbp=Libra libanesa +lkr=Rupia do Sri Lanka +lrd=D\u00f3lar liberiano +lsl=Loti do Lesoto +ltl=Lita lituano +luf=Franco luxemburgu\u00eas +lvl=Lats let\u00e3o +lyd=Dinar l\u00edbio +mad=Dir\u00e9m marroquino +mdl=Leu mold\u00e1vio +mga=Ariary de Madagascar +mgf=Franco de Madagascar +mkd=Dinar maced\u00f4nio +mmk=Kyat de Mianmar +mnt=Tugrik mongol +mop=Pataca macaense +mro=Ouguiya da Maurit\u00e2nia +mtl=Lira maltesa +mur=Rupia de Maur\u00edcio +mvr=Rupias das Ilhas Maldivas +mwk=Cuacha do Mal\u00e1ui +mxn=Peso mexicano +mxv=Unidade Mexicana de Investimento (UDI) +myr=Ringgit malaio +mzm=Metical antigo de Mo\u00e7ambique +mzn=Metical do Mo\u00e7ambique +nad=D\u00f3lar da Nam\u00edbia +ngn=Naira nigeriana +nio=C\u00f3rdoba Ouro nicaraguense +nlg=Florim holand\u00eas +nok=Coroa norueguesa +npr=Rupia nepalesa +nzd=D\u00f3lar da Nova Zel\u00e2ndia +omr=Rial de Om\u00e3 +pab=Balboa panamenho +pen=Sol Novo peruano +pgk=Kina da Papua-Nova Guin\u00e9 +php=Peso filipino +pkr=Rupia paquistanesa +pln=Zloti polon\u00eas +pte=Escudo portugu\u00eas +pyg=Guarani paraguaio +qar=Rial catariano +rol=Leu romeno antigo +ron=Leu romeno +rsd=Dinar s\u00e9rvio +rub=Rublo russo +rur=Rublo russo (1991-1998) +rwf=Franco ruand\u00eas +sar=Rial saudita +sbd=D\u00f3lar das Ilhas Salom\u00e3o +scr=Rupia das Seychelles +sdd=Dinar sudan\u00eas +sdg=Libra sudanesa +sek=Coroa sueca +sgd=D\u00f3lar de Cingapura +shp=Libra de Santa Helena +sit=Tolar Bons esloveno +skk=Coroa eslovaca +sll=Leone de Serra Leoa +sos=Xelim somali +srd=D\u00f3lar do Suriname +srg=Florim do Suriname +std=Dobra de S\u00e3o Tom\u00e9 e Pr\u00edncipe +svc=Colom salvadorenho +syp=Libra s\u00edria +szl=Lilangeni da Suazil\u00e2ndia +thb=Baht tailand\u00eas +tjs=Somoni tadjique +tmm=Manat do Turcomenist\u00e3o +tnd=Dinar tunisiano +top=Pa\u02bbanga de Tonga +tpe=Escudo timorense +trl=Lira turca antiga +try=Lira turca +ttd=D\u00f3lar de Trinidad e Tobago +twd=D\u00f3lar Novo de Taiwan +tzs=Xelim da Tanz\u00e2nia +uah=Hryvnia ucraniano +ugx=Xelim ugandense +usd=D\u00f3lar norte-americano +usn=D\u00f3lar norte-americano (Dia seguinte) +uss=D\u00f3lar norte-americano (Mesmo dia) +uyu=Peso uruguaio +uzs=Sum do Usbequist\u00e3o +veb=Bol\u00edvar venezuelano +vef=Bol\u00edvar v enezuelano forte +vnd=Dong vietnamita +vuv=Vatu de Vanuatu +wst=Tala samoano +xaf=Franco CFA BEAC +xag=Prata +xau=Ouro +xba=Unidade Composta Europeia +xbb=Unidade Monet\u00e1ria Europeia +xbc=Unidade de Conta Europeia (XBC) +xbd=Unidade de Conta Europeia (XBD) +xcd=D\u00f3lar do Caribe Oriental +xdr=Direitos Especiais de Giro +xfo=Franco-ouro franc\u00eas +xfu=Franco UIC franc\u00eas +xof=Franco CFA BCEAO +xpd=Pal\u00e1dio +xpf=Franco CFP +xpt=Platina +xts=C\u00f3digo de Moeda de Teste +xxx=Moeda Desconhecida ou Inv\u00e1lida +yer=Rial iemenita +yum=Dinar noviy iugoslavo +zar=Rand sul-africano +zmk=Cuacha zambiano +zwd=D\u00f3lar do Zimb\u00e1bue diff --git a/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_Latn_BA.properties b/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_Latn_BA.properties new file mode 100644 index 00000000000..7dc0375ecbf --- /dev/null +++ b/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_Latn_BA.properties @@ -0,0 +1,69 @@ +# +# Copyright (c) 2005, 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. +# + +# +# COPYRIGHT AND PERMISSION NOTICE +# +# Copyright (C) 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 of the Unicode data files and any associated documentation (the +# "Data Files") or Unicode software and any associated documentation +# (the "Software") to deal in the Data Files or Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, and/or sell copies of the Data +# Files or Software, and to permit persons to whom the Data Files or +# Software are furnished to do so, provided that (a) the above copyright +# notice(s) and this permission notice appear with all copies of the +# Data Files or Software, (b) both the above copyright notice(s) and +# this permission notice appear in associated documentation, and (c) +# there is clear notice in each modified Data File or in the Software as +# well as in the documentation associated with the Data File(s) or +# Software that the data or software has been modified. +# +# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR +# ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +# SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in these Data Files or Software without prior +# written authorization of the copyright holder. + +# +# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# +BAM=KM +bam=Bosansko-Hercegova\u010dka konvertibilna marka +EUR=\u20ac +eur=Evro diff --git a/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_Latn_ME.properties b/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_Latn_ME.properties new file mode 100644 index 00000000000..0983b6a2ecc --- /dev/null +++ b/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_Latn_ME.properties @@ -0,0 +1,67 @@ +# +# Copyright (c) 2005, 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. +# + +# +# COPYRIGHT AND PERMISSION NOTICE +# +# Copyright (C) 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 of the Unicode data files and any associated documentation (the +# "Data Files") or Unicode software and any associated documentation +# (the "Software") to deal in the Data Files or Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, and/or sell copies of the Data +# Files or Software, and to permit persons to whom the Data Files or +# Software are furnished to do so, provided that (a) the above copyright +# notice(s) and this permission notice appear with all copies of the +# Data Files or Software, (b) both the above copyright notice(s) and +# this permission notice appear in associated documentation, and (c) +# there is clear notice in each modified Data File or in the Software as +# well as in the documentation associated with the Data File(s) or +# Software that the data or software has been modified. +# +# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR +# ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +# SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in these Data Files or Software without prior +# written authorization of the copyright holder. + +# +# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# +EUR=\u20ac +eur=Evro diff --git a/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_Latn_RS.properties b/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_Latn_RS.properties new file mode 100644 index 00000000000..3a299f40642 --- /dev/null +++ b/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_Latn_RS.properties @@ -0,0 +1,67 @@ +# +# Copyright (c) 2005, 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. +# + +# +# COPYRIGHT AND PERMISSION NOTICE +# +# Copyright (C) 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 of the Unicode data files and any associated documentation (the +# "Data Files") or Unicode software and any associated documentation +# (the "Software") to deal in the Data Files or Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, and/or sell copies of the Data +# Files or Software, and to permit persons to whom the Data Files or +# Software are furnished to do so, provided that (a) the above copyright +# notice(s) and this permission notice appear with all copies of the +# Data Files or Software, (b) both the above copyright notice(s) and +# this permission notice appear in associated documentation, and (c) +# there is clear notice in each modified Data File or in the Software as +# well as in the documentation associated with the Data File(s) or +# Software that the data or software has been modified. +# +# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR +# ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +# SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in these Data Files or Software without prior +# written authorization of the copyright holder. + +# +# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# +RSD=din. +rsd=Srpski dinar diff --git a/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_RS.properties b/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_RS.properties new file mode 100644 index 00000000000..83555220774 --- /dev/null +++ b/jdk/src/share/classes/sun/util/resources/CurrencyNames_sr_RS.properties @@ -0,0 +1,66 @@ +# +# Copyright (c) 2005, 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. +# + +# +# COPYRIGHT AND PERMISSION NOTICE +# +# Copyright (C) 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 of the Unicode data files and any associated documentation (the +# "Data Files") or Unicode software and any associated documentation +# (the "Software") to deal in the Data Files or Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, and/or sell copies of the Data +# Files or Software, and to permit persons to whom the Data Files or +# Software are furnished to do so, provided that (a) the above copyright +# notice(s) and this permission notice appear with all copies of the +# Data Files or Software, (b) both the above copyright notice(s) and +# this permission notice appear in associated documentation, and (c) +# there is clear notice in each modified Data File or in the Software as +# well as in the documentation associated with the Data File(s) or +# Software that the data or software has been modified. +# +# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR +# ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +# SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in these Data Files or Software without prior +# written authorization of the copyright holder. + +# +# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# +RSD=\u0434\u0438\u043d. diff --git a/jdk/src/share/classes/sun/util/resources/LocaleData.java b/jdk/src/share/classes/sun/util/resources/LocaleData.java index 9686abc8e2f..86d6e92d8bf 100644 --- a/jdk/src/share/classes/sun/util/resources/LocaleData.java +++ b/jdk/src/share/classes/sun/util/resources/LocaleData.java @@ -171,16 +171,21 @@ public class LocaleData { /* Get the locale string list from LocaleDataMetaInfo class. */ String localeString = LocaleDataMetaInfo.getSupportedLocaleString(baseName); - if (localeString.length() == 0) { + if (localeString.length() == 0) { return candidates; } for (Iterator l = candidates.iterator(); l.hasNext(); ) { - String lstr = l.next().toString(); - /* truncate extra segment introduced by Java 7 for script and extesions */ - int idx = lstr.indexOf("_#"); - if (idx >= 0) { - lstr = lstr.substring(0, idx); + Locale loc = l.next(); + String lstr = null; + if (loc.getScript().length() > 0) { + lstr = loc.toLanguageTag().replace('-', '_'); + } else { + lstr = loc.toString(); + int idx = lstr.indexOf("_#"); + if (idx >= 0) { + lstr = lstr.substring(0, idx); + } } /* Every locale string in the locale string list returned from the above getSupportedLocaleString is enclosed @@ -265,28 +270,15 @@ public class LocaleData { Locale[] locales = new Locale[localeStringTokenizer.countTokens()]; for (int i = 0; i < locales.length; i++) { - String currentToken = localeStringTokenizer.nextToken(); - int p2 = 0; - int p1 = currentToken.indexOf('_'); - String language = ""; - String country = ""; - String variant = ""; - - if (p1 == -1) { - language = currentToken; - } else { - language = currentToken.substring(0, p1); - p2 = currentToken.indexOf('_', p1 + 1); - if (p2 == -1) { - country = currentToken.substring(p1 + 1); - } else { - country = currentToken.substring(p1 + 1, p2); - if (p2 < currentToken.length()) { - variant = currentToken.substring(p2 + 1); - } - } + String currentToken = localeStringTokenizer.nextToken().replace('_','-'); + if (currentToken.equals("ja-JP-JP")) { + currentToken = "ja-JP-u-ca-japanese-x-lvariant-JP"; + } else if (currentToken.equals("th-TH-TH")) { + currentToken = "th-TH-u-nu-thai-x-lvariant-TH"; + } else if (currentToken.equals("no-NO-NY")) { + currentToken = "no-NO-x-lvariant-NY"; } - locales[i] = new Locale(language, country, variant); + locales[i] = Locale.forLanguageTag(currentToken); } return locales; } diff --git a/jdk/src/share/classes/sun/util/resources/LocaleNames_sr_Latn.properties b/jdk/src/share/classes/sun/util/resources/LocaleNames_sr_Latn.properties new file mode 100644 index 00000000000..7cc1c2477c7 --- /dev/null +++ b/jdk/src/share/classes/sun/util/resources/LocaleNames_sr_Latn.properties @@ -0,0 +1,471 @@ +# +# Copyright (c) 2005, 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. +# + +# +# COPYRIGHT AND PERMISSION NOTICE +# +# Copyright (C) 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 of the Unicode data files and any associated documentation (the +# "Data Files") or Unicode software and any associated documentation +# (the "Software") to deal in the Data Files or Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, and/or sell copies of the Data +# Files or Software, and to permit persons to whom the Data Files or +# Software are furnished to do so, provided that (a) the above copyright +# notice(s) and this permission notice appear with all copies of the +# Data Files or Software, (b) both the above copyright notice(s) and +# this permission notice appear in associated documentation, and (c) +# there is clear notice in each modified Data File or in the Software as +# well as in the documentation associated with the Data File(s) or +# Software that the data or software has been modified. +# +# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR +# ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +# SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in these Data Files or Software without prior +# written authorization of the copyright holder. + +# +# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# +aa=Afarski +ab=Abkazijski +ae=Avestanski +af=Afrikanerski +am=Amharski +an=Aragone\u017eanski +ar=Arapski +as=Asemijski +av=Avarski +ay=Ajmara +az=Azerbejd\u017eanski +ba=Ba\u0161kir +be=Beloruski +bg=Bugarski +bh=Biharski +bn=Bengalski +bo=Tibetanski +br=Bretonski +bs=Bosanski +ca=Katalonski +ce=\u010ce\u010denski +ch=\u010camoro +co=Korzikanski +cr=Kri +cs=\u010ce\u0161ki +cu=Staroslovenski +cv=\u010cuva\u0161ki +cy=Vel\u0161ki +da=Danski +de=Nema\u010dki +dv=Divehijski +dz=D\u017eonga +ee=Eve +el=Gr\u010dki +en=Engleski +eo=Esperanto +es=\u0160panski +et=Estonski +eu=Baskijski +fa=Persijski +fi=Finski +fj=Fid\u017eijski +fo=Farski +fr=Francuski +fy=Frizijski +ga=Irski +gd=\u0160kotski Galski +gl=Galski +gn=Gvarani +gu=Gud\u017earati +gv=Manks +he=Hebrejski +hi=Hindi +hr=Hrvatski +ht=Hai\u0107anski +hu=Ma\u0111arski +hy=Jermenski +ia=Interlingva +id=Indonezijski +ie=Interlingve +ii=Si\u010duan ji +ik=Inupiak +in=Indonezijski +is=Islandski +it=Italijanski +iw=Hebrejski +ja=Japanski +ji=Jidi\u0161 +jv=Javanski +ka=Gruzijski +ki=Kikuju +kj=Kuanjama +kk=Koza\u010dki +kl=Kalalisutski +km=Kmerski +kn=Kanada +ko=Korejski +ks=Ka\u0161miri +ku=Kurdski +kw=Korni\u0161ki +ky=Kirgiski +la=Latinski +lb=Luksembur\u0161ki +li=Limburgi\u0161 +lo=Lao\u0161ki +lt=Litvanski +lu=Luba-katanga +lv=Letonski +mg=Malagazijski +mh=Mar\u0161alski +mi=Maorski +mk=Makedonski +ml=Malajalam +mn=Mongolski +mo=Moldavski +mr=Marati +ms=Malajski +mt=Melte\u0161ki +my=Burmanski +nb=Norve\u0161ki bokm\u00e5l +nd=Severni ndebele +ne=Nepalski +nl=Holandski +nn=Norve\u0161ki njorsk +no=Norve\u0161ki +nr=Ju\u017eni ndebele +nv=Navaho +ny=Njanja +oc=Provansalski +oj=Ojibva +or=Orijski +os=Osetski +pa=Pand\u017eabski +pl=Poljski +ps=Pa\u0161tunski +pt=Portugalski +qu=Kven\u010da +rm=Reto-Romanski +ro=Rumunski +ru=Ruski +rw=Kinjarvanda +sa=Sanskrit +sc=Sardinijski +sd=Sindi +se=Severni sami +si=Singaleski +sk=Slova\u010dki +sl=Slovena\u010dki +sm=Samoanski +sn=\u0160ona +so=Somalski +sq=Albanski +sr=Srpski +ss=Svati +st=Sesoto +su=Sudanski +sv=\u0160vedski +sw=Svahili +ta=Tamilski +tg=Ta\u0111ik +th=Tajlandski +ti=Tigrinja +tk=Turkmenski +tl=Tagalski +tn=Tsvana +tr=Turski +tt=Tatarski +tw=Tvi +ty=Tahi\u0107anski +ug=Ujgurski +uk=Ukrajinski +uz=Uzbe\u010dki +vi=Vijetnamski +wa=Valun +wo=Volof +xh=Khosa +yi=Jidi\u0161 +yo=Jorubanski +za=Zuang +zh=Kineski +AD=Andora +AE=Ujedinjeni Arapski Emirati +AF=Avganistan +AG=Antigva i Barbuda +AI=Angvila +AL=Albanija +AM=Armenija +AN=Holandski Antili +AO=Angola +AQ=Antarktika +AR=Argentina +AS=Ameri\u010dka Samoa +AT=Austrija +AU=Australija +AW=Aruba +AX=Alandska ostrva +AZ=Azerbejd\u017ean +BA=Bosna i Hercegovina +BB=Barbados +BD=Banglade\u0161 +BE=Belgija +BF=Burkina Faso +BG=Bugarska +BH=Bahrein +BI=Burundi +BJ=Benin +BL=Sv. Bartolomej +BM=Bermuda +BN=Brunej +BO=Bolivija +BR=Brazil +BS=Bahami +BT=Butan +BV=Buve Ostrva +BW=Bocvana +BY=Belorusija +BZ=Belise +CA=Kanada +CC=Kokos (Keling) Ostrva +CD=Demokratska Republika Kongo +CF=Centralno Afri\u010dka Republika +CG=Kongo +CH=\u0160vajcarska +CI=Obala Slonova\u010de +CK=Kukova Ostrva +CL=\u010cile +CM=Kamerun +CN=Kina +CO=Kolumbija +CR=Kostarika +CU=Kuba +CV=Kape Verde +CX=Bo\u017ei\u0107na Ostrva +CY=Kipar +CZ=\u010ce\u0161ka +DE=Nema\u010dka +DJ=D\u017eibuti +DK=Danska +DM=Dominika +DO=Dominikanska Republika +DZ=Al\u017eir +EC=Ekvador +EE=Estonija +EG=Egipat +EH=Zapadna Sahara +ER=Eritreja +ES=\u0160panija +ET=Etiopija +FI=Finska +FJ=Fid\u017ei +FK=Folklandska Ostrva +FM=Mikronezija +FO=Farska Ostrva +FR=Francuska +GA=Gabon +GB=Velika Britanija +GD=Grenada +GE=Gruzija +GF=Francuska Gvajana +GG=Gurnsi +GH=Gana +GI=Gibraltar +GL=Grenland +GM=Gambija +GN=Gvineja +GP=Gvadelupe +GQ=Ekvatorijalna Gvineja +GR=Gr\u010dka +GS=Ju\u017ena D\u017eord\u017eija i Ju\u017ena Sendvi\u010d Ostrva +GT=Gvatemala +GU=Guam +GW=Gvineja-Bisao +GY=Gvajana +HK=Hong Kong (S. A. R. Kina) +HM=Herd i Mekdonald Ostrva +HN=Honduras +HR=Hrvatska +HT=Haiti +HU=Ma\u0111arska +ID=Indonezija +IE=Irska +IL=Izrael +IM=Ostrvo Man +IN=Indija +IO=Britansko Indijska Okeanska Teritorija +IQ=Irak +IR=Iran +IS=Island +IT=Italija +JE=D\u017eersi +JM=Jamajka +JO=Jordan +JP=Japan +KE=Kenija +KG=Kirgizstan +KH=Kambod\u017ea +KI=Kiribati +KM=Komorska Ostrva +KN=Sent Kits i Nevis +KP=Severna Koreja +KR=Ju\u017ena Koreja +KW=Kuvajt +KY=Kajmanska Ostrva +KZ=Kazahstan +LA=Laos +LB=Liban +LC=Sent Lucija +LI=Lihten\u0161tajn +LK=\u0160ri Lanka +LR=Liberija +LS=Lesoto +LT=Litvanija +LU=Luksemburg +LV=Letonija +LY=Libija +MA=Maroko +MC=Monako +MD=Moldavija +ME=Crna Gora +MF=Sv. Martin +MG=Madagaskar +MH=Mar\u0161alska Ostrva +MK=Makedonija +ML=Mali +MM=Mijanmar +MN=Mongolija +MO=Makao (S. A. R. Kina) +MP=Severna Marijanska Ostrva +MQ=Martinik +MR=Mauritanija +MS=Monserat +MT=Malta +MU=Mauricius +MV=Maldivi +MW=Malavi +MX=Meksiko +MY=Malezija +MZ=Mozambik +NA=Namibija +NC=Nova Kaledonija +NE=Niger +NF=Norfolk Ostrvo +NG=Nigerija +NI=Nikaragva +NL=Holandija +NO=Norve\u0161ka +NP=Nepal +NR=Nauru +NU=Niue +NZ=Novi Zeland +OM=Oman +PA=Panama +PE=Peru +PF=Francuska Polinezija +PG=Papua Nova Gvineja +PH=Filipini +PK=Pakistan +PL=Poljska +PM=Sen Pjer i Mikelon +PN=Pitcairn +PR=Porto Riko +PS=Palestinska Teritorija +PT=Portugal +PW=Palau +PY=Paragvaj +QA=Katar +RE=Rejunion +RO=Rumunija +RS=Srbija +RU=Rusija +RW=Ruanda +SA=Saudijska Arabija +SB=Solomonska Ostrva +SC=Sej\u0161eli +SD=Sudan +SE=\u0160vedska +SG=Singapur +SH=Sveta Jelena +SI=Slovenija +SJ=Svalbard i Janmajen Ostrva +SK=Slova\u010dka +SL=Sijera Leone +SM=San Marino +SN=Senegal +SO=Somalija +SR=Surinam +ST=Sao Tome i Principe +SV=Salvador +SY=Sirija +SZ=Svazilend +TC=Turks i Kajkos Ostrva +TD=\u010cad +TF=Francuske Ju\u017ene Teritorije +TG=Togo +TH=Tajland +TJ=Tad\u017eikistan +TK=Tokelau +TL=Isto\u010dni Timor +TM=Turkmenistan +TN=Tunis +TO=Tonga +TR=Turska +TT=Trinidad i Tobago +TV=Tuvalu +TW=Tajvan +TZ=Tanzanija +UA=Ukrajina +UG=Uganda +UM=Manja Udaljena Ostrva SAD +US=Sjedinjene Ameri\u010dke Dr\u017eave +UY=Urugvaj +UZ=Uzbekistan +VA=Vatikan +VC=Sent Vinsent i Grenadini +VE=Venecuela +VG=Britanska Devi\u010danska Ostrva +VI=S.A.D. Devi\u010danska Ostrva +VN=Vijetnam +VU=Vanuatu +WF=Valis i Futuna Ostrva +WS=Samoa +YE=Jemen +YT=Majote +ZA=Ju\u017enoafri\u010dka Republika +ZM=Zambija +ZW=Zimbabve diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java index a5c73549809..0016ae24d20 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java @@ -216,6 +216,7 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { {"America/Anchorage", AKST}, {"AST", AKST}, {"America/Halifax", AST}, + {"America/Sitka", AKST}, {"America/St_Johns", NST}, {"CNT", NST}, {"Europe/Paris", CET}, @@ -392,6 +393,8 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { {"America/Mendoza", AGT}, {"America/Menominee", CST}, {"America/Merida", CST}, + {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", + "Metlakatla Daylight Time", "MeDT"}}, {"America/Mexico_City", CST}, {"America/Miquelon", new String[] {"Pierre & Miquelon Standard Time", "PMST", "Pierre & Miquelon Daylight Time", "PMDT"}}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java index b3cb23224fa..0e4d91d94f7 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java @@ -216,6 +216,7 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { {"America/Anchorage", AKST}, {"AST", AKST}, {"America/Halifax", AST}, + {"America/Sitka", AKST}, {"America/St_Johns", NST}, {"CNT", NST}, {"Europe/Paris", CET}, @@ -392,6 +393,8 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { {"America/Mendoza", AGT}, {"America/Menominee", CST}, {"America/Merida", CST}, + {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", + "Metlakatla Daylight Time", "MeDT"}}, {"America/Mexico_City", CST}, {"America/Miquelon", new String[] {"Pierre & Miquelon Normalzeit", "PMST", "Pierre & Miquelon Sommerzeit", "PMDT"}}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java index 613cc6419fb..711afc45563 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java @@ -216,6 +216,7 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { {"America/Anchorage", AKST}, {"AST", AKST}, {"America/Halifax", AST}, + {"America/Sitka", AKST}, {"America/St_Johns", NST}, {"CNT", NST}, {"Europe/Paris", CET}, @@ -392,6 +393,8 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { {"America/Mendoza", AGT}, {"America/Menominee", CST}, {"America/Merida", CST}, + {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", + "Metlakatla Daylight Time", "MeDT"}}, {"America/Mexico_City", CST}, {"America/Miquelon", new String[] {"Hora est\u00e1ndar de Pierre & Miquelon", "PMST", "Hora de verano de Pierre & Miquelon", "PMDT"}}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java index f1dc5300c25..090820b6742 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java @@ -216,6 +216,7 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { {"America/Anchorage", AKST}, {"AST", AKST}, {"America/Halifax", AST}, + {"America/Sitka", AKST}, {"America/St_Johns", NST}, {"CNT", NST}, {"Europe/Paris", CET}, @@ -392,6 +393,8 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { {"America/Mendoza", AGT}, {"America/Menominee", CST}, {"America/Merida", CST}, + {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", + "Metlakatla Daylight Time", "MeDT"}}, {"America/Mexico_City", CST}, {"America/Miquelon", new String[] {"Heure normale de Saint-Pierre et Miquelon", "PMST", "Heure avanc\u00e9e de Saint-Pierre et Miquelon", "PMDT"}}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java index e983872e7a1..6413104ba74 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java @@ -216,6 +216,7 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { {"America/Anchorage", AKST}, {"AST", AKST}, {"America/Halifax", AST}, + {"America/Sitka", AKST}, {"America/St_Johns", NST}, {"CNT", NST}, {"Europe/Paris", CET}, @@ -392,6 +393,8 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { {"America/Mendoza", AGT}, {"America/Menominee", CST}, {"America/Merida", CST}, + {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", + "Metlakatla Daylight Time", "MeDT"}}, {"America/Mexico_City", CST}, {"America/Miquelon", new String[] {"Ora solare di Saint-Pierre e Miquelon", "PMST", "Ora legale di Saint-Pierre e Miquelon", "PMDT"}}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java index 56330acf91d..4c1226666c8 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java @@ -216,6 +216,7 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { {"America/Anchorage", AKST}, {"AST", AKST}, {"America/Halifax", AST}, + {"America/Sitka", AKST}, {"America/St_Johns", NST}, {"CNT", NST}, {"Europe/Paris", CET}, @@ -392,6 +393,8 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { {"America/Mendoza", AGT}, {"America/Menominee", CST}, {"America/Merida", CST}, + {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", + "Metlakatla Daylight Time", "MeDT"}}, {"America/Mexico_City", CST}, {"America/Miquelon", new String[] {"\u30b5\u30f3\u30d4\u30a8\u30fc\u30eb\u30fb\u30df\u30af\u30ed\u30f3\u8af8\u5cf6\u6a19\u6e96\u6642", "PMST", "\u30b5\u30f3\u30d4\u30a8\u30fc\u30eb\u30fb\u30df\u30af\u30ed\u30f3\u8af8\u5cf6\u590f\u6642\u9593", "PMDT"}}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java index 82edcce1ec5..486e1bdd9a5 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java @@ -216,6 +216,7 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { {"America/Anchorage", AKST}, {"AST", AKST}, {"America/Halifax", AST}, + {"America/Sitka", AKST}, {"America/St_Johns", NST}, {"CNT", NST}, {"Europe/Paris", CET}, @@ -392,6 +393,8 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { {"America/Mendoza", AGT}, {"America/Menominee", CST}, {"America/Merida", CST}, + {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", + "Metlakatla Daylight Time", "MeDT"}}, {"America/Mexico_City", CST}, {"America/Miquelon", new String[] {"\ud53c\uc5d0\ub974 \ubbf8\ud06c\ub860 \ud45c\uc900\uc2dc", "PMST", "\ud53c\uc5d0\ub974 \ubbf8\ud06c\ub860 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PMDT"}}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_pt_BR.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_pt_BR.java index d9b83fe0491..7eab4bb48b4 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_pt_BR.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_pt_BR.java @@ -217,6 +217,7 @@ public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle { {"America/Anchorage", AKST}, {"AST", AKST}, {"America/Halifax", AST}, + {"America/Sitka", AKST}, {"America/St_Johns", NST}, {"CNT", NST}, {"Europe/Paris", CET}, @@ -392,6 +393,8 @@ public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle { {"America/Mendoza", AGT}, {"America/Menominee", CST}, {"America/Merida", CST}, + {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", + "Metlakatla Daylight Time", "MeDT"}}, {"America/Mexico_City", CST}, {"America/Miquelon", new String[] {"Fuso hor\u00e1rio padr\u00e3o de S\u00e3o Pedro e Miquelon", "PMST", "Hor\u00e1rio de luz natural de S\u00e3o Pedro e Miquelon", "PMDT"}}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java index 14108065241..63b5e084523 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java @@ -216,6 +216,7 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { {"America/Anchorage", AKST}, {"AST", AKST}, {"America/Halifax", AST}, + {"America/Sitka", AKST}, {"America/St_Johns", NST}, {"CNT", NST}, {"Europe/Paris", CET}, @@ -392,6 +393,8 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { {"America/Mendoza", AGT}, {"America/Menominee", CST}, {"America/Merida", CST}, + {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", + "Metlakatla Daylight Time", "MeDT"}}, {"America/Mexico_City", CST}, {"America/Miquelon", new String[] {"Saint-Pierre-et-Miquelon, normaltid", "PMST", "Saint-Pierre-et-Miquelon, sommartid", "PMDT"}}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java index 4f80a1b739c..b215a186e9a 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java @@ -216,6 +216,7 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { {"America/Anchorage", AKST}, {"AST", AKST}, {"America/Halifax", AST}, + {"America/Sitka", AKST}, {"America/St_Johns", NST}, {"CNT", NST}, {"Europe/Paris", CET}, @@ -392,6 +393,8 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { {"America/Mendoza", AGT}, {"America/Menominee", CST}, {"America/Merida", CST}, + {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", + "Metlakatla Daylight Time", "MeDT"}}, {"America/Mexico_City", CST}, {"America/Miquelon", new String[] {"\u76ae\u57c3\u5c14\u5c9b\u53ca\u5bc6\u514b\u9686\u5c9b\u6807\u51c6\u65f6\u95f4", "PMST", "\u76ae\u57c3\u5c14\u5c9b\u53ca\u5bc6\u514b\u9686\u5c9b\u590f\u4ee4\u65f6", "PMDT"}}, diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java index 5218bed7ed6..7a638641e89 100644 --- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java +++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java @@ -216,6 +216,7 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { {"America/Anchorage", AKST}, {"AST", AKST}, {"America/Halifax", AST}, + {"America/Sitka", AKST}, {"America/St_Johns", NST}, {"CNT", NST}, {"Europe/Paris", CET}, @@ -392,6 +393,8 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { {"America/Mendoza", AGT}, {"America/Menominee", CST}, {"America/Merida", CST}, + {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", + "Metlakatla Daylight Time", "MeDT"}}, {"America/Mexico_City", CST}, {"America/Miquelon", new String[] {"\u76ae\u57c3\u723e\u5cf6\u53ca\u5bc6\u514b\u9686\u5cf6\u6a19\u6e96\u6642\u9593", "PMST", "\u76ae\u57c3\u723e\u5cf6\u53ca\u5bc6\u514b\u9686\u5cf6\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "PMDT"}}, diff --git a/jdk/src/share/demo/jfc/Font2DTest/README.txt b/jdk/src/share/demo/jfc/Font2DTest/README.txt index dec4895b55e..c5f03af0cb8 100644 --- a/jdk/src/share/demo/jfc/Font2DTest/README.txt +++ b/jdk/src/share/demo/jfc/Font2DTest/README.txt @@ -7,7 +7,7 @@ To run Font2DTest: or % appletviewer Font2DTest.html -These instructions assume that the 1.5 versions of the java +These instructions assume that the 1.7 versions of the java and appletviewer commands are in your path. If they aren't, then you should either specify the complete path to the commands or update your PATH environment variable as described in the diff --git a/jdk/src/share/demo/jfc/Font2DTest/RangeMenu.java b/jdk/src/share/demo/jfc/Font2DTest/RangeMenu.java index 1f4c582f2df..20a3113df44 100644 --- a/jdk/src/share/demo/jfc/Font2DTest/RangeMenu.java +++ b/jdk/src/share/demo/jfc/Font2DTest/RangeMenu.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,6 +41,9 @@ import java.awt.event.ItemListener; import javax.swing.*; +import java.util.*; +import java.util.regex.*; + /** * RangeMenu.java * @@ -52,358 +55,8 @@ import javax.swing.*; public final class RangeMenu extends JComboBox implements ActionListener { - /// Painfully extracted from java.lang.Character.UnicodeBlock. Arrrgh! - /// Unicode 5.1.0 data. - - private final int[][] UNICODE_RANGES = { - { 0x000000, 0x00007f }, /// BASIC_LATIN - { 0x000080, 0x0000ff }, /// LATIN_1_SUPPLEMENT - { 0x000100, 0x00017f }, /// LATIN_EXTENDED_A - { 0x000180, 0x00024f }, /// LATIN_EXTENDED_B - { 0x000250, 0x0002af }, /// IPA_EXTENSIONS - { 0x0002b0, 0x0002ff }, /// SPACING_MODIFIER_LETTERS - { 0x000300, 0x00036f }, /// COMBINING_DIACRITICAL_MARKS - { 0x000370, 0x0003ff }, /// GREEK_AND_COPTIC - { 0x000400, 0x0004ff }, /// CYRILLIC - { 0x000500, 0x00052f }, /// CYRILLIC_SUPPLEMENTARY - { 0x000530, 0x00058f }, /// ARMENIAN - { 0x000590, 0x0005ff }, /// HEBREW - { 0x000600, 0x0006ff }, /// ARABIC - { 0x000700, 0x00074f }, /// SYRIAC - { 0x000750, 0x00077f }, /// ARABIC_SUPPLEMENT - { 0x000780, 0x0007bf }, /// THAANA - { 0x0007c0, 0x0007ff }, /// NKO - { 0x000900, 0x00097f }, /// DEVANAGARI - { 0x000980, 0x0009ff }, /// BENGALI - { 0x000a00, 0x000a7f }, /// GURMUKHI - { 0x000a80, 0x000aff }, /// GUJARATI - { 0x000b00, 0x000b7f }, /// ORIYA - { 0x000b80, 0x000bff }, /// TAMIL - { 0x000c00, 0x000c7f }, /// TELUGU - { 0x000c80, 0x000cff }, /// KANNADA - { 0x000d00, 0x000d7f }, /// MALAYALAM - { 0x000d80, 0x000dff }, /// SINHALA - { 0x000e00, 0x000e7f }, /// THAI - { 0x000e80, 0x000eff }, /// LAO - { 0x000f00, 0x000fff }, /// TIBETAN - { 0x001000, 0x00109f }, /// MYANMAR - { 0x0010a0, 0x0010ff }, /// GEORGIAN - { 0x001100, 0x0011ff }, /// HANGUL_JAMO - { 0x001200, 0x00137f }, /// ETHIOPIC - { 0x001380, 0x00139f }, /// ETHIOPIC_SUPPLEMENT - { 0x0013a0, 0x0013ff }, /// CHEROKEE - { 0x001400, 0x00167f }, /// UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS - { 0x001680, 0x00169f }, /// OGHAM - { 0x0016a0, 0x0016ff }, /// RUNIC - { 0x001700, 0x00171f }, /// TAGALOG - { 0x001720, 0x00173f }, /// HANUNOO - { 0x001740, 0x00175f }, /// BUHID - { 0x001760, 0x00177f }, /// TAGBANWA - { 0x001780, 0x0017ff }, /// KHMER - { 0x001800, 0x0018af }, /// MONGOLIAN - { 0x001900, 0x00194f }, /// LIMBU - { 0x001950, 0x00197f }, /// TAI_LE - { 0x001980, 0x0019df }, /// NEW_TAI_LE - { 0x0019e0, 0x0019ff }, /// KHMER_SYMBOLS - { 0x001a00, 0x001a1f }, /// BUGINESE - { 0x001b00, 0x001b7f }, /// BALINESE - { 0x001b80, 0x001bbf }, /// SUNDANESE - { 0x001c00, 0x001c4f }, /// LEPCHA - { 0x001c50, 0x001c7f }, /// OL_CHIKI - { 0x001d00, 0x001d7f }, /// PHONETIC_EXTENSIONS - { 0x001d80, 0x001dbf }, /// PHONEITC EXTENSIONS SUPPLEMENT - { 0x001dc0, 0x001dff }, /// COMBINING_DIACRITICAL_MAKRS_SUPPLEMENT - { 0x001e00, 0x001eff }, /// LATIN_EXTENDED_ADDITIONAL - { 0x001f00, 0x001fff }, /// GREEK_EXTENDED - { 0x002000, 0x00206f }, /// GENERAL_PUNCTUATION - { 0x002070, 0x00209f }, /// SUPERSCRIPTS_AND_SUBSCRIPTS - { 0x0020a0, 0x0020cf }, /// CURRENCY_SYMBOLS - { 0x0020d0, 0x0020ff }, /// COMBINING_MARKS_FOR_SYMBOLS - { 0x002100, 0x00214f }, /// LETTERLIKE_SYMBOLS - { 0x002150, 0x00218f }, /// NUMBER_FORMS - { 0x002190, 0x0021ff }, /// ARROWS - { 0x002200, 0x0022ff }, /// MATHEMATICAL_OPERATORS - { 0x002300, 0x0023ff }, /// MISCELLANEOUS_TECHNICAL - { 0x002400, 0x00243f }, /// CONTROL_PICTURES - { 0x002440, 0x00245f }, /// OPTICAL_CHARACTER_RECOGNITION - { 0x002460, 0x0024ff }, /// ENCLOSED_ALPHANUMERICS - { 0x002500, 0x00257f }, /// BOX_DRAWING - { 0x002580, 0x00259f }, /// BLOCK_ELEMENTS - { 0x0025a0, 0x0025ff }, /// GEOMETRIC_SHAPES - { 0x002600, 0x0026ff }, /// MISCELLANEOUS_SYMBOLS - { 0x002700, 0x0027bf }, /// DINGBATS - { 0x0027c0, 0x0027ef }, /// MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A - { 0x0027f0, 0x0027ff }, /// SUPPLEMENTAL_ARROWS_A - { 0x002800, 0x0028ff }, /// BRAILLE_PATTERNS - { 0x002900, 0x00297f }, /// SUPPLEMENTAL_ARROWS_B - { 0x002980, 0x0029ff }, /// MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B - { 0x002a00, 0x002aff }, /// SUPPLEMENTAL_MATHEMATICAL_OPERATORS - { 0x002b00, 0x002bff }, /// MISCELLANEOUS_SYMBOLS_AND_ARROWS - { 0x002c00, 0x002c5f }, /// GLAGOLITIC - { 0x002c60, 0x002c7f }, /// LATIN_EXTENDED-C - { 0x002c80, 0x002cff }, /// COPTIC - { 0x002d00, 0x002d2f }, /// GEORGIAN_SUPPLEMENT - { 0x002d30, 0x002d7f }, /// TIFINAGH - { 0x002d80, 0x002ddf }, /// ETHIOPIC_EXTENDED - { 0x002de0, 0x002dff }, /// CYRILLIC_EXTENDED-A - { 0x002e00, 0x002e7f }, /// SUPPLEMENTAL_PUNCTUATION - { 0x002e80, 0x002eff }, /// CJK_RADICALS_SUPPLEMENT - { 0x002f00, 0x002fdf }, /// KANGXI_RADICALS - { 0x002ff0, 0x002fff }, /// IDEOGRAPHIC_DESCRIPTION_CHARACTERS - { 0x003000, 0x00303f }, /// CJK_SYMBOLS_AND_PUNCTUATION - { 0x003040, 0x00309f }, /// HIRAGANA - { 0x0030a0, 0x0030ff }, /// KATAKANA - { 0x003100, 0x00312f }, /// BOPOMOFO - { 0x003130, 0x00318f }, /// HANGUL_COMPATIBILITY_JAMO - { 0x003190, 0x00319f }, /// KANBUN - { 0x0031a0, 0x0031bf }, /// BOPOMOFO_EXTENDED - { 0x0031c0, 0x0031ef }, /// CJK_STROKES - { 0x0031f0, 0x0031ff }, /// KATAKANA_PHONETIC_EXTENSIONS - { 0x003200, 0x0032ff }, /// ENCLOSED_CJK_LETTERS_AND_MONTHS - { 0x003300, 0x0033ff }, /// CJK_COMPATIBILITY - { 0x003400, 0x004dbf }, /// CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A - { 0x004dc0, 0x004dff }, /// YIJING_HEXAGRAM_SYMBOLS - { 0x004e00, 0x009fff }, /// CJK_UNIFIED_IDEOGRAPHS - { 0x00a000, 0x00a48f }, /// YI_SYLLABLES - { 0x00a490, 0x00a4cf }, /// YI_RADICALS - { 0x00a500, 0x00a63f }, /// YAI - { 0x00a640, 0x00a69f }, /// CYRILLIC_EXTENDED-B - { 0x00a700, 0x00a71f }, /// MODIFIER_TONE_LETTERS - { 0x00a720, 0x00a7ff }, /// LATIN_EXTENDED-D - { 0x00a800, 0x00a82f }, /// SYLOTI_NAGRI - { 0x00a840, 0x00a87f }, /// PHAGS-PA - { 0x00a880, 0x00a8df }, /// SAURASHTRA - { 0x00a900, 0x00a92f }, /// KAYAH_LI - { 0x00a930, 0x00a95f }, /// REJANG - { 0x00aa00, 0x00aa5f }, /// CHAM - { 0x00ac00, 0x00d7af }, /// HANGUL_SYLLABLES - { 0x00d800, 0x00db7f }, /// HIGH_SURROGATES_AREA - { 0x00db80, 0x00dbff }, /// HIGH_PRIVATE_USE_SURROGATES_AREA - { 0x00dc00, 0x00dfff }, /// LOW_SURROGATES_AREA - { 0x00e000, 0x00f8ff }, /// PRIVATE_USE_AREA - { 0x00f900, 0x00faff }, /// CJK_COMPATIBILITY_IDEOGRAPHS - { 0x00fb00, 0x00fb4f }, /// ALPHABETIC_PRESENTATION_FORMS - { 0x00fb50, 0x00fdff }, /// ARABIC_PRESENTATION_FORMS_A - { 0x00fe00, 0x00fe0f }, /// VARIATION_SELECTORS - { 0x00fe10, 0x00fe1f }, /// VERTICAL_FORMS - { 0x00fe20, 0x00fe2f }, /// COMBINING_HALF_MARKS - { 0x00fe30, 0x00fe4f }, /// CJK_COMPATIBILITY_FORMS - { 0x00fe50, 0x00fe6f }, /// SMALL_FORM_VARIANTS - { 0x00fe70, 0x00feff }, /// ARABIC_PRESENTATION_FORMS_B - { 0x00ff00, 0x00ffef }, /// HALFWIDTH_AND_FULLWIDTH_FORMS - { 0x00fff0, 0x00ffff }, /// SPECIALS - { 0x010000, 0x01007f }, /// LINEAR_B_SYLLABARY - { 0x010080, 0x0100ff }, /// LINEAR_B_IDEOGRAMS - { 0x010100, 0x01013f }, /// AEGEAN_NUMBERS - { 0x010140, 0x01018f }, /// ANCIENT_GREEK_NUMBERS - { 0x010190, 0x0101cf }, /// ANCIENT_SYMBOLS - { 0x0101d0, 0x0101ff }, /// PHAISTOS_DISC - { 0x010280, 0x01029f }, /// LYCIAN - { 0x0102a0, 0x0102df }, /// CARIAN - { 0x010300, 0x01032f }, /// OLD_ITALIC - { 0x010330, 0x01034f }, /// GOTHIC - { 0x010380, 0x01039f }, /// UGARITIC - { 0x0103a0, 0x0103df }, /// OLD_PERSIAN - { 0x010400, 0x01044f }, /// DESERET - { 0x010450, 0x01047f }, /// SHAVIAN - { 0x010480, 0x0104af }, /// OSMANYA - { 0x010800, 0x01083f }, /// CYPRIOT_SYLLABARY - { 0x010900, 0x01091f }, /// PHOENICIAN - { 0x010920, 0x01093f }, /// LYDIAN - { 0x010a00, 0x010a5f }, /// KHAROSHTHI - { 0x012000, 0x0123ff }, /// CUNEIFORM - { 0x012400, 0x01247f }, /// CUNEIFORM_NUMBERS_AND_PUNCTUATION - { 0x01d000, 0x01d0ff }, /// BYZANTINE_MUSICAL_SYMBOLS - { 0x01d100, 0x01d1ff }, /// MUSICAL_SYMBOLS - { 0x01d200, 0x01d24f }, /// ANCIENT_GREEK_MUSICAL_NOTATION - { 0x01d300, 0x01d35f }, /// TAI_XUAN_JING_SYMBOLS - { 0x01d360, 0x01d37f }, /// COUNTING_ROD_NUMERALS - { 0x01d400, 0x01d7ff }, /// MATHEMATICAL_ALPHANUMERIC_SYMBOLS - { 0x01f000, 0x01f02f }, /// MAHJONG_TILES - { 0x01f030, 0x01f09f }, /// DOMINO_TILES - { 0x020000, 0x02a6df }, /// CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B - { 0x02f800, 0x02fa1f }, /// CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT - { 0x0e0000, 0x0e007f }, /// TAGS - { 0x0e0100, 0x0e01ef }, /// VARIATION_SELECTORS_SUPPLEMENT - { 0x0f0000, 0x0fffff }, /// SUPPLEMENTARY_PRIVATE_USE_AREA_A - { 0x100000, 0x10ffff }, /// SUPPLEMENTARY_PRIVATE_USE_AREA_B - { 0x000000, 0x00007f }, /// OTHER [USER DEFINED RANGE] - }; - - private final String[] UNICODE_RANGE_NAMES = { - "Basic Latin", - "Latin-1 Supplement", - "Latin Extended-A", - "Latin Extended-B", - "IPA Extensions", - "Spacing Modifier Letters", - "Combining Diacritical Marks", - "Greek and Coptic", - "Cyrillic", - "Cyrillic Supplement", - "Armenian", - "Hebrew", - "Arabic", - "Syriac", - "Arabic Supplement", - "Thaana", - "NKo", - "Devanagari", - "Bengali", - "Gurmukhi", - "Gujarati", - "Oriya", - "Tamil", - "Telugu", - "Kannada", - "Malayalam", - "Sinhala", - "Thai", - "Lao", - "Tibetan", - "Myanmar", - "Georgian", - "Hangul Jamo", - "Ethiopic", - "Ethiopic Supplement", - "Cherokee", - "Unified Canadian Aboriginal Syllabics", - "Ogham", - "Runic", - "Tagalog", - "Hanunoo", - "Buhid", - "Tagbanwa", - "Khmer", - "Mongolian", - "Limbu", - "Tai Le", - "New Tai Lue", - "Khmer Symbols", - "Buginese", - "Balinese", - "Sundanese", - "Lepcha", - "Ol Chiki", - "Phonetic Extensions", - "Phonetic Extensions Supplement", - "Combining Diacritical Marks Supplement", - "Latin Extended Additional", - "Greek Extended", - "General Punctuation", - "Superscripts and Subscripts", - "Currency Symbols", - "Combining Diacritical Marks for Symbols", - "Letterlike Symbols", - "Number Forms", - "Arrows", - "Mathematical Operators", - "Miscellaneous Technical", - "Control Pictures", - "Optical Character Recognition", - "Enclosed Alphanumerics", - "Box Drawing", - "Block Elements", - "Geometric Shapes", - "Miscellaneous Symbols", - "Dingbats", - "Miscellaneous Mathematical Symbols-A", - "Supplemental Arrows-A", - "Braille Patterns", - "Supplemental Arrows-B", - "Miscellaneous Mathematical Symbols-B", - "Supplemental Mathematical Operators", - "Miscellaneous Symbols and Arrows", - "Glagolitic", - "Latin Extended-C", - "Coptic", - "Georgian Supplement", - "Tifinagh", - "Ethiopic Extended", - "Cyrillic Extended-A", - "Supplemental Punctuation", - "CJK Radicals Supplement", - "Kangxi Radicals", - "Ideographic Description Characters", - "CJK Symbols and Punctuation", - "Hiragana", - "Katakana", - "Bopomofo", - "Hangul Compatibility Jamo", - "Kanbun", - "Bopomofo Extended", - "CJK Strokes", - "Katakana Phonetic Extensions", - "Enclosed CJK Letters and Months", - "CJK Compatibility", - "CJK Unified Ideographs Extension A", - "Yijing Hexagram Symbols", - "CJK Unified Ideographs", - "Yi Syllables", - "Yi Radicals", - "Vai", - "Cyrillic Extended-B", - "Modifier Tone Letters", - "Latin Extended-D", - "Syloti Nagri", - "Phags-pa", - "Saurashtra", - "Kayah Li", - "Rejang", - "Cham", - "Hangul Syllables", - "High Surrogates", - "High Private Use Surrogates", - "Low Surrogates", - "Private Use Area", - "CJK Compatibility Ideographs", - "Alphabetic Presentation Forms", - "Arabic Presentation Forms-A", - "Variation Selectors", - "Vertical Forms", - "Combining Half Marks", - "CJK Compatibility Forms", - "Small Form Variants", - "Arabic Presentation Forms-B", - "Halfwidth and Fullwidth Forms", - "Specials", - "Linear B Syllabary", - "Linear B Ideograms", - "Aegean Numbers", - "Ancient Greek Numbers", - "Ancient Symbols", - "Phaistos Disc", - "Lycian", - "Carian", - "Old Italic", - "Gothic", - "Ugaritic", - "Old Persian", - "Deseret", - "Shavian", - "Osmanya", - "Cypriot Syllabary", - "Phoenician", - "Lydian", - "Kharoshthi", - "Cuneiform", - "Cuneiform Numbers and Punctuation", - "Byzantine Musical Symbols", - "Musical Symbols", - "Ancient Greek Musical Notation", - "Tai Xuan Jing Symbols", - "Counting Rod Numerals", - "Mathematical Alphanumeric Symbols", - "Mahjong Tiles", - "Domino Tiles", - "CJK Unified Ideographs Extension B", - "CJK Compatibility Ideographs Supplement", - "Tags", - "Variation Selectors Supplement", - "Supplementary Private Use Area-A", - "Supplementary Private Use Area-B", - "Custom...", - }; + private static final int[][] UNICODE_RANGES = getUnicodeRanges(); + private static final String[] UNICODE_RANGE_NAMES = getUnicodeRangeNames(); private boolean useCustomRange = false; private int[] customRange = { 0x0000, 0x007f }; @@ -536,4 +189,61 @@ public final class RangeMenu extends JComboBox implements ActionListener { customRangeDialog.hide(); } } + + private static int[][] getUnicodeRanges() { + List ranges = new ArrayList<>(); + ranges.add(0); + Character.UnicodeBlock currentBlock = Character.UnicodeBlock.of(0); + for (int cp = 0x000001; cp < 0x110000; cp++ ) { + Character.UnicodeBlock ub = Character.UnicodeBlock.of(cp); + if (currentBlock == null) { + if (ub != null) { + ranges.add(cp); + currentBlock = ub; + } + } else { // being in some unicode range + if (ub == null) { + ranges.add(cp - 1); + currentBlock = null; + } else if (cp == 0x10ffff) { // end of last block + ranges.add(cp); + } else if (! ub.equals(currentBlock)) { + ranges.add(cp - 1); + ranges.add(cp); + currentBlock = ub; + } + } + } + ranges.add(0x00); // for user defined range. + ranges.add(0x7f); // for user defined range. + + int[][] returnval = new int[ranges.size() / 2][2]; + for (int i = 0 ; i < ranges.size() / 2 ; i++ ) { + returnval[i][0] = ranges.get(2*i); + returnval[i][1] = ranges.get(2*i + 1); + } + return returnval; + } + + private static String[] getUnicodeRangeNames() { + String[] names = new String[UNICODE_RANGES.length]; + for (int i = 0 ; i < names.length ; i++ ) { + names[i] = titleCase( + Character.UnicodeBlock.of(UNICODE_RANGES[i][0]).toString()); + } + names[names.length - 1] = "Custom..."; + return names; + } + + private static String titleCase(String str) { + str = str.replaceAll("_", " "); + Pattern p = Pattern.compile("(^|\\W)([a-z])"); + Matcher m = p.matcher(str.toLowerCase(Locale.ROOT)); + StringBuffer sb = new StringBuffer(); + while (m.find()) { + m.appendReplacement(sb, m.group(1) + m.group(2).toUpperCase(Locale.ROOT)); + } + m.appendTail(sb); + return sb.toString().replace("Cjk", "CJK").replace("Nko", "NKo"); + } } diff --git a/jdk/src/share/demo/jfc/Notepad/resources/Notepad.properties b/jdk/src/share/demo/jfc/Notepad/resources/Notepad.properties index fdd5c5a2246..ef61d6fd3c4 100644 --- a/jdk/src/share/demo/jfc/Notepad/resources/Notepad.properties +++ b/jdk/src/share/demo/jfc/Notepad/resources/Notepad.properties @@ -3,12 +3,15 @@ Title=Notepad ElementTreeFrameTitle=Elements +# The following string should NOT be translated: ViewportBackingStore ViewportBackingStore=false # menubar definition # # Each of the strings that follow form a key to be # used to the actual menu definition. + +# The following string should NOT be translated: menubar menubar=file edit debug # file Menu definition @@ -20,6 +23,8 @@ menubar=file edit debug # new -> Notepad.newAction # save -> Notepad.saveAction # exit -> Notepad.exitAction + +# The following string should NOT be translated: file file=new open save - exit fileLabel=File openLabel=Open @@ -36,28 +41,38 @@ exitLabel=Exit # cut -> JTextComponent.cutAction # copy -> JTextComponent.copyAction # paste -> JTextComponent.pasteAction + +# The following string should NOT be translated: edit edit=cut copy paste - undo redo editLabel=Edit cutLabel=Cut +# The following string should NOT be translated: cutAction cutAction=cut-to-clipboard cutImage=resources/cut.gif copyLabel=Copy +# The following string should NOT be translated: copyAction copyAction=copy-to-clipboard copyImage=resources/copy.gif pasteLabel=Paste +# The following string should NOT be translated: pasteAction pasteAction=paste-from-clipboard pasteImage=resources/paste.gif undoLabel=Undo +# The following string should NOT be translated: undoAction undoAction=Undo redoLabel=Redo +# The following string should NOT be translated: redoAction redoAction=Redo # # debug Menu definition # + +# The following string should NOT be translated: debug debug=dump showElementTree debugLabel=Debug dumpLabel=Dump model to System.err +# The following string should NOT be translated: dumpAction dumpAction=dump-model showElementTreeLabel=Show Elements @@ -67,6 +82,8 @@ showElementTreeLabel=Show Elements # used as the basis of the tool definition. Actions # are of course sharable, and in this case are shared # with the menu items. + +# The following string should NOT be translated: toolbar toolbar=new open save - cut copy paste newTooltip=Create a new file openTooltip=Open a file diff --git a/jdk/src/share/demo/jfc/Notepad/resources/Notepad_ja.properties b/jdk/src/share/demo/jfc/Notepad/resources/Notepad_ja.properties index 8a40242b9ec..777e1cf72f9 100644 --- a/jdk/src/share/demo/jfc/Notepad/resources/Notepad_ja.properties +++ b/jdk/src/share/demo/jfc/Notepad/resources/Notepad_ja.properties @@ -9,7 +9,7 @@ ViewportBackingStore=false # # Each of the strings that follow form a key to be # used to the actual menu definition. -menubar=\u30D5\u30A1\u30A4\u30EB \u7DE8\u96C6 \u30C7\u30D0\u30C3\u30B0 +menubar=file edit debug # file Menu definition # @@ -20,7 +20,7 @@ menubar=\u30D5\u30A1\u30A4\u30EB \u7DE8\u96C6 \u30C7\u30D0\u30C3\u30B0 # new -> Notepad.newAction # save -> Notepad.saveAction # exit -> Notepad.exitAction -file=\u65B0\u898F \u958B\u304F \u4FDD\u5B58 - \u7D42\u4E86 +file=new open save - exit fileLabel=\u30D5\u30A1\u30A4\u30EB openLabel=\u958B\u304F openImage=resources/open.gif @@ -36,7 +36,7 @@ exitLabel=\u7D42\u4E86 # cut -> JTextComponent.cutAction # copy -> JTextComponent.copyAction # paste -> JTextComponent.pasteAction -edit=\u5207\u53D6\u308A \u30B3\u30D4\u30FC \u8CBC\u4ED8\u3051 - \u5143\u306B\u623B\u3059 \u518D\u5B9F\u884C +edit=cut copy paste - undo redo editLabel=\u7DE8\u96C6 cutLabel=\u5207\u53D6\u308A cutAction=cut-to-clipboard @@ -48,14 +48,14 @@ pasteLabel=\u8CBC\u4ED8\u3051 pasteAction=paste-from-clipboard pasteImage=resources/paste.gif undoLabel=\u5143\u306B\u623B\u3059 -undoAction=\u5143\u306B\u623B\u3059 +undoAction=Undo redoLabel=\u518D\u5B9F\u884C -redoAction=\u518D\u5B9F\u884C +redoAction=Redo # # debug Menu definition # -debug=showElementTree\u306E\u30C0\u30F3\u30D7 +debug=dump showElementTree debugLabel=\u30C7\u30D0\u30C3\u30B0 dumpLabel=\u30E2\u30C7\u30EB\u3092System.err\u306B\u30C0\u30F3\u30D7 dumpAction=dump-model @@ -67,7 +67,7 @@ showElementTreeLabel=\u8981\u7D20\u306E\u8868\u793A # used as the basis of the tool definition. Actions # are of course sharable, and in this case are shared # with the menu items. -toolbar=\u65B0\u898F \u958B\u304F \u4FDD\u5B58 - \u5207\u53D6\u308A \u30B3\u30D4\u30FC \u8CBC\u4ED8\u3051 +toolbar=new open save - cut copy paste newTooltip=\u30D5\u30A1\u30A4\u30EB\u3092\u65B0\u898F\u4F5C\u6210\u3059\u308B openTooltip=\u30D5\u30A1\u30A4\u30EB\u3092\u958B\u304F saveTooltip=\u30D5\u30A1\u30A4\u30EB\u306B\u4FDD\u5B58 diff --git a/jdk/src/share/demo/jfc/Notepad/resources/Notepad_zh_CN.properties b/jdk/src/share/demo/jfc/Notepad/resources/Notepad_zh_CN.properties index 9706f903dad..be6ec0692c1 100644 --- a/jdk/src/share/demo/jfc/Notepad/resources/Notepad_zh_CN.properties +++ b/jdk/src/share/demo/jfc/Notepad/resources/Notepad_zh_CN.properties @@ -48,9 +48,9 @@ pasteLabel=\u7C98\u8D34 pasteAction=paste-from-clipboard pasteImage=resources/paste.gif undoLabel=\u64A4\u6D88 -undoAction=\u64A4\u6D88 +undoAction=Undo redoLabel=\u91CD\u505A -redoAction=\u91CD\u505A +redoAction=Redo # # debug Menu definition diff --git a/jdk/src/share/lib/security/java.security b/jdk/src/share/lib/security/java.security index 5a0726de0a7..a89d40e194b 100644 --- a/jdk/src/share/lib/security/java.security +++ b/jdk/src/share/lib/security/java.security @@ -123,7 +123,7 @@ keystore.type=jks # passed to checkPackageAccess unless the # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. -package.access=sun.,com.sun.imageio. +package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio. # # List of comma-separated packages that start with or equal this string diff --git a/jdk/src/share/lib/security/java.security-solaris b/jdk/src/share/lib/security/java.security-solaris index 8e9b1ffd791..1a19f44d231 100644 --- a/jdk/src/share/lib/security/java.security-solaris +++ b/jdk/src/share/lib/security/java.security-solaris @@ -124,7 +124,7 @@ keystore.type=jks # passed to checkPackageAccess unless the # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. -package.access=sun.,com.sun.imageio. +package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio. # # List of comma-separated packages that start with or equal this string diff --git a/jdk/src/share/lib/security/java.security-windows b/jdk/src/share/lib/security/java.security-windows index 99eda51b910..3db627a4f32 100644 --- a/jdk/src/share/lib/security/java.security-windows +++ b/jdk/src/share/lib/security/java.security-windows @@ -124,7 +124,7 @@ keystore.type=jks # passed to checkPackageAccess unless the # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. -package.access=sun.,com.sun.imageio. +package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio. # # List of comma-separated packages that start with or equal this string diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp index b53b14ed87b..40067b1df0f 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp @@ -489,7 +489,6 @@ enum { CHUNK = (1 << 14), SMALL = (1 << 9) }; // Call malloc. Try to combine small blocks and free much later. void* unpacker::alloc_heap(size_t size, bool smallOK, bool temp) { - CHECK_0; if (!smallOK || size > SMALL) { void* res = must_malloc((int)size); (temp ? &tmallocs : &mallocs)->add(res); @@ -2560,6 +2559,10 @@ void unpacker::putlayout(band** body) { int i; int prevBII = -1; int prevBCI = -1; + if (body == NULL) { + abort("putlayout: unexpected NULL for body"); + return; + } for (i = 0; body[i] != null; i++) { band& b = *body[i]; byte le_kind = b.le_kind; @@ -4767,7 +4770,9 @@ void unpacker::redirect_stdio() { } char *tname = tempnam(tmpdir,"#upkg"); + if (tname == NULL) return; sprintf(log_file_name, "%s", tname); + ::free(tname); if ((errstrm = fopen(log_file_name, "a+")) != NULL) { log_file = errstrm_name = saveStr(log_file_name); return ; diff --git a/jdk/src/share/native/com/sun/media/sound/SoundDefs.h b/jdk/src/share/native/com/sun/media/sound/SoundDefs.h index 5ac73451681..f141ea62ac2 100644 --- a/jdk/src/share/native/com/sun/media/sound/SoundDefs.h +++ b/jdk/src/share/native/com/sun/media/sound/SoundDefs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -39,6 +39,8 @@ #define X_IA64 4 #define X_AMD64 5 #define X_ZERO 6 +#define X_ARM 7 +#define X_PPC 8 // ********************************** // Make sure you set X_PLATFORM and X_ARCH defines correctly. diff --git a/jdk/src/share/native/common/check_code.c b/jdk/src/share/native/common/check_code.c index 00dcdf163b3..dcdaeda58bf 100644 --- a/jdk/src/share/native/common/check_code.c +++ b/jdk/src/share/native/common/check_code.c @@ -2685,11 +2685,11 @@ push_stack(context_type *context, unsigned int inumber, stack_info_type *new_sta switch (type_table[operand]) { case JVM_CONSTANT_MethodType: full_info = make_class_info_from_name(context, - "java/dyn/MethodType"); + "java/lang/invoke/MethodType"); break; default: //JVM_CONSTANT_MethodHandle full_info = make_class_info_from_name(context, - "java/dyn/MethodHandle"); + "java/lang/invoke/MethodHandle"); break; } break; diff --git a/jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h b/jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h index 2b3592dc143..196bb0d8e02 100644 --- a/jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h +++ b/jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -28,8 +28,8 @@ #ifdef __NEWVALID /* special setup for Sun test regime */ #if defined(i386) || defined(i486) || \ - defined(intel) || defined(x86) || \ - defined(i86pc) || defined(_M_IA64) || defined(ia64) + defined(intel) || defined(x86) || defined(arm) || \ + defined(i86pc) || defined(_M_IA64) || defined(ia64) #define _LITTLE_ENDIAN #endif #endif 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 04a87fd1cac..84b91889725 100644 --- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c +++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c @@ -40,7 +40,7 @@ #include #include #include - +#include /* java native interface headers */ #include "jni.h" @@ -2657,7 +2657,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage (destWidth < 0) || (destWidth > srcWidth) || (destHeight < 0) || (stepX < 0) || (stepY < 0) || - ((scanLineSize / numBands) < destWidth)) /* destWidth causes an integer overflow */ + ((INT_MAX / numBands) < destWidth)) /* destWidth causes an integer overflow */ { JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid argument to native writeImage"); diff --git a/jdk/src/share/native/sun/font/layout/KernTable.cpp b/jdk/src/share/native/sun/font/layout/KernTable.cpp index 8d368211309..3a9987eb6b9 100644 --- a/jdk/src/share/native/sun/font/layout/KernTable.cpp +++ b/jdk/src/share/native/sun/font/layout/KernTable.cpp @@ -210,7 +210,7 @@ void KernTable::process(LEGlyphStorage& storage) // all the elements ahead of time and store them in the font const PairInfo* p = pairs; - const PairInfo* tp = (const PairInfo*)(p + rangeShift); + const PairInfo* tp = (const PairInfo*)(p + (rangeShift/KERN_PAIRINFO_SIZE)); /* rangeshift is in original table bytes */ if (key > tp->key) { p = tp; } @@ -222,7 +222,7 @@ void KernTable::process(LEGlyphStorage& storage) le_uint32 probe = searchRange; while (probe > 1) { probe >>= 1; - tp = (const PairInfo*)(p + probe); + tp = (const PairInfo*)(p + (probe/KERN_PAIRINFO_SIZE)); le_uint32 tkey = tp->key; #if DEBUG fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairs), tkey); diff --git a/jdk/src/share/native/sun/font/layout/LayoutEngine.cpp b/jdk/src/share/native/sun/font/layout/LayoutEngine.cpp index 6b0aa1baa58..90aafde2a80 100644 --- a/jdk/src/share/native/sun/font/layout/LayoutEngine.cpp +++ b/jdk/src/share/native/sun/font/layout/LayoutEngine.cpp @@ -251,6 +251,10 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off return 0; } + if ((fTypoFlags & 0x4) == 0) { // no canonical processing + return count; + } + const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable; LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode); LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode); diff --git a/jdk/src/share/native/sun/java2d/loops/ProcessPath.c b/jdk/src/share/native/sun/java2d/loops/ProcessPath.c index b4f724752dc..5131a3e22c7 100644 --- a/jdk/src/share/native/sun/java2d/loops/ProcessPath.c +++ b/jdk/src/share/native/sun/java2d/loops/ProcessPath.c @@ -118,19 +118,25 @@ jint Y1 = (fY1) >> MDP_PREC; \ jint res; \ \ - /* Checking bounds and clipping if necessary */ \ + /* Checking bounds and clipping if necessary. \ + * REMIND: It's temporary solution to avoid OOB in rendering code. \ + * Current approach uses float equations which are unreliable for \ + * clipping and makes assumptions about the line biases of the \ + * rendering algorithm. Also, clipping code should be moved down \ + * into only those output renderers that need it. \ + */ \ if (checkBounds) { \ - TESTANDCLIP(hnd->dhnd->yMin, hnd->dhnd->yMax, Y0, X0, Y1, X1, \ - jint, res); \ + jfloat xMinf = hnd->dhnd->xMinf + 0.5f; \ + jfloat yMinf = hnd->dhnd->yMinf + 0.5f; \ + jfloat xMaxf = hnd->dhnd->xMaxf + 0.5f; \ + jfloat yMaxf = hnd->dhnd->yMaxf + 0.5f; \ + TESTANDCLIP(yMinf, yMaxf, Y0, X0, Y1, X1, jint, res); \ if (res == CRES_INVISIBLE) break; \ - TESTANDCLIP(hnd->dhnd->yMin, hnd->dhnd->yMax, Y1, X1, Y0, X0, \ - jint, res); \ + TESTANDCLIP(yMinf, yMaxf, Y1, X1, Y0, X0, jint, res); \ if (res == CRES_INVISIBLE) break; \ - TESTANDCLIP(hnd->dhnd->xMin, hnd->dhnd->xMax, X0, Y0, X1, Y1, \ - jint, res); \ + TESTANDCLIP(xMinf, xMaxf, X0, Y0, X1, Y1, jint, res); \ if (res == CRES_INVISIBLE) break; \ - TESTANDCLIP(hnd->dhnd->xMin, hnd->dhnd->xMax, X1, Y1, X0, Y0, \ - jint, res); \ + TESTANDCLIP(xMinf, xMaxf, X1, Y1, X0, Y0, jint, res); \ if (res == CRES_INVISIBLE) break; \ } \ \ diff --git a/jdk/src/share/sample/nio/file/WatchDir.java b/jdk/src/share/sample/nio/file/WatchDir.java index 33c15dd0c04..796b728206b 100644 --- a/jdk/src/share/sample/nio/file/WatchDir.java +++ b/jdk/src/share/sample/nio/file/WatchDir.java @@ -33,8 +33,7 @@ import java.nio.file.*; import static java.nio.file.StandardWatchEventKind.*; import static java.nio.file.LinkOption.*; import java.nio.file.attribute.*; -import java.io.*; -import java.util.*; +import java.io.IOException; /** * Example to watch a directory (or tree) for changes to files. @@ -43,9 +42,9 @@ import java.util.*; public class WatchDir { private final WatchService watcher; - private final Map keys; private final boolean recursive; private boolean trace = false; + private int count; @SuppressWarnings("unchecked") static WatchEvent cast(WatchEvent event) { @@ -57,17 +56,9 @@ public class WatchDir { */ private void register(Path dir) throws IOException { WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); - if (trace) { - Path prev = keys.get(key); - if (prev == null) { - System.out.format("register: %s\n", dir); - } else { - if (!dir.equals(prev)) { - System.out.format("update: %s -> %s\n", prev, dir); - } - } - } - keys.put(key, dir); + count++; + if (trace) + System.out.format("register: %s\n", dir); } /** @@ -92,7 +83,6 @@ public class WatchDir { */ WatchDir(Path dir, boolean recursive) throws IOException { this.watcher = FileSystems.getDefault().newWatchService(); - this.keys = new HashMap(); this.recursive = recursive; if (recursive) { @@ -121,12 +111,6 @@ public class WatchDir { return; } - Path dir = keys.get(key); - if (dir == null) { - System.err.println("WatchKey not recognized!!"); - continue; - } - for (WatchEvent event: key.pollEvents()) { WatchEvent.Kind kind = event.kind(); @@ -138,7 +122,7 @@ public class WatchDir { // Context for directory entry event is the file name of entry WatchEvent ev = cast(event); Path name = ev.context(); - Path child = dir.resolve(name); + Path child = ((Path)key.watchable()).resolve(name); // print out event System.out.format("%s: %s\n", event.kind().name(), child); @@ -156,15 +140,13 @@ public class WatchDir { } } - // reset key and remove from set if directory no longer accessible + // reset key boolean valid = key.reset(); if (!valid) { - keys.remove(key); - - // all directories are inaccessible - if (keys.isEmpty()) { + // directory no longer accessible + count--; + if (count == 0) break; - } } } } diff --git a/jdk/src/solaris/bin/ergo.c b/jdk/src/solaris/bin/ergo.c index e9e863e9ce5..2047087e7c5 100644 --- a/jdk/src/solaris/bin/ergo.c +++ b/jdk/src/solaris/bin/ergo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -67,6 +67,35 @@ ServerClassMachine(void) { } } +#ifdef USE_GENERIC_ERGO +/* Ask the OS how many processors there are. */ +static unsigned long +physical_processors(void) { + const unsigned long sys_processors = sysconf(_SC_NPROCESSORS_CONF); + JLI_TraceLauncher("sysconf(_SC_NPROCESSORS_CONF): %lu\n", sys_processors); + return sys_processors; +} + +jboolean +ServerClassMachineImpl(void) { + jboolean result = JNI_FALSE; + /* How big is a server class machine? */ + const unsigned long server_processors = 2UL; + const uint64_t server_memory = 2UL * GB; + const uint64_t actual_memory = physical_memory(); + + /* Is this a server class machine? */ + if (actual_memory >= server_memory) { + const unsigned long actual_processors = physical_processors(); + if (actual_processors >= server_processors) { + result = JNI_TRUE; + } + } + JLI_TraceLauncher("unix_" LIBARCHNAME "_ServerClassMachine: %s\n", + (result == JNI_TRUE ? "JNI_TRUE" : "JNI_FALSE")); + return result; +} +#endif /* Compute physical memory by asking the OS */ uint64_t diff --git a/jdk/src/solaris/bin/ergo_sparc.c b/jdk/src/solaris/bin/ergo_sparc.c deleted file mode 100644 index 9261a423de6..00000000000 --- a/jdk/src/solaris/bin/ergo_sparc.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1998, 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. 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. - */ -#include "ergo.h" - - -/* Methods for solaris-sparc and linux-sparc: these are easy. */ - -/* Ask the OS how many processors there are. */ -static unsigned long -physical_processors(void) { - const unsigned long sys_processors = sysconf(_SC_NPROCESSORS_CONF); - - JLI_TraceLauncher("sysconf(_SC_NPROCESSORS_CONF): %lu\n", sys_processors); - return sys_processors; -} - -/* The sparc version of the "server-class" predicate. */ -jboolean -ServerClassMachineImpl(void) { - jboolean result = JNI_FALSE; - /* How big is a server class machine? */ - const unsigned long server_processors = 2UL; - const uint64_t server_memory = 2UL * GB; - const uint64_t actual_memory = physical_memory(); - - /* Is this a server class machine? */ - if (actual_memory >= server_memory) { - const unsigned long actual_processors = physical_processors(); - if (actual_processors >= server_processors) { - result = JNI_TRUE; - } - } - JLI_TraceLauncher("unix_" LIBARCHNAME "_ServerClassMachine: %s\n", - (result == JNI_TRUE ? "JNI_TRUE" : "JNI_FALSE")); - return result; -} diff --git a/jdk/src/solaris/bin/ergo_zero.c b/jdk/src/solaris/bin/ergo_zero.c deleted file mode 100644 index 9261a423de6..00000000000 --- a/jdk/src/solaris/bin/ergo_zero.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1998, 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. 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. - */ -#include "ergo.h" - - -/* Methods for solaris-sparc and linux-sparc: these are easy. */ - -/* Ask the OS how many processors there are. */ -static unsigned long -physical_processors(void) { - const unsigned long sys_processors = sysconf(_SC_NPROCESSORS_CONF); - - JLI_TraceLauncher("sysconf(_SC_NPROCESSORS_CONF): %lu\n", sys_processors); - return sys_processors; -} - -/* The sparc version of the "server-class" predicate. */ -jboolean -ServerClassMachineImpl(void) { - jboolean result = JNI_FALSE; - /* How big is a server class machine? */ - const unsigned long server_processors = 2UL; - const uint64_t server_memory = 2UL * GB; - const uint64_t actual_memory = physical_memory(); - - /* Is this a server class machine? */ - if (actual_memory >= server_memory) { - const unsigned long actual_processors = physical_processors(); - if (actual_processors >= server_processors) { - result = JNI_TRUE; - } - } - JLI_TraceLauncher("unix_" LIBARCHNAME "_ServerClassMachine: %s\n", - (result == JNI_TRUE ? "JNI_TRUE" : "JNI_FALSE")); - return result; -} diff --git a/jdk/src/solaris/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java b/jdk/src/solaris/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java index 5ad8b8d54d8..be2426d7f72 100644 --- a/jdk/src/solaris/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java +++ b/jdk/src/solaris/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java @@ -68,6 +68,9 @@ import sun.net.www.protocol.http.HttpURLConnection; public class NTLMAuthentication extends AuthenticationInfo { private static final long serialVersionUID = 170L; + private static final NTLMAuthenticationCallback NTLMAuthCallback = + NTLMAuthenticationCallback.getNTLMAuthenticationCallback(); + private String hostname; private static String defaultDomain; /* Domain to use if not specified by user */ @@ -81,6 +84,14 @@ public class NTLMAuthentication extends AuthenticationInfo { return false; } + /** + * Returns true if the given site is trusted, i.e. we can try + * transparent Authentication. + */ + public static boolean isTrustedSite(URL url) { + return NTLMAuthCallback.isTrustedSite(url); + } + private void init0() { hostname = java.security.AccessController.doPrivileged( diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java index 4499a08924c..af0dc1036bd 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java +++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java @@ -27,6 +27,7 @@ package sun.nio.fs; import java.nio.file.attribute.*; import java.util.Map; +import java.util.Set; import java.io.IOException; import sun.misc.Unsafe; @@ -57,6 +58,10 @@ class LinuxDosFileAttributeView private static final int DOS_XATTR_SYSTEM = 0x04; private static final int DOS_XATTR_ARCHIVE = 0x20; + // the names of the DOS attributes (includes basic) + private static final Set dosAttributeNames = + Util.newSet(basicAttributeNames, READONLY_NAME, ARCHIVE_NAME, SYSTEM_NAME, HIDDEN_NAME); + LinuxDosFileAttributeView(UnixPath file, boolean followLinks) { super(file, followLinks); } @@ -93,9 +98,10 @@ class LinuxDosFileAttributeView public Map readAttributes(String[] attributes) throws IOException { - AttributesBuilder builder = AttributesBuilder.create(attributes); + AttributesBuilder builder = + AttributesBuilder.create(dosAttributeNames, attributes); DosFileAttributes attrs = readAttributes(); - addBasicAttributesToBuilder(attrs, builder); + addRequestedBasicAttributes(attrs, builder); if (builder.match(READONLY_NAME)) builder.add(READONLY_NAME, attrs.isReadOnly()); if (builder.match(ARCHIVE_NAME)) diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java index b8b8c30f936..18309cb4450 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java +++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java @@ -28,8 +28,6 @@ package sun.nio.fs; import java.nio.file.*; import java.io.IOException; import java.util.*; -import java.security.AccessController; -import sun.security.action.GetPropertyAction; import static sun.nio.fs.LinuxNativeDispatcher.*; /** @@ -37,42 +35,16 @@ import static sun.nio.fs.LinuxNativeDispatcher.*; */ class LinuxFileSystem extends UnixFileSystem { - private final boolean hasInotify; - LinuxFileSystem(UnixFileSystemProvider provider, String dir) { super(provider, dir); - - // assume X.Y[-Z] format - String osversion = AccessController - .doPrivileged(new GetPropertyAction("os.version")); - String[] vers = Util.split(osversion, '.'); - assert vers.length >= 2; - - int majorVersion = Integer.parseInt(vers[0]); - int minorVersion = Integer.parseInt(vers[1]); - int microVersion = 0; - if (vers.length > 2) { - String[] microVers = Util.split(vers[2], '-'); - microVersion = (microVers.length > 0) ? - Integer.parseInt(microVers[0]) : 0; - } - - // inotify available since 2.6.13 - this.hasInotify = ((majorVersion > 2) || - (majorVersion == 2 && minorVersion > 6) || - ((majorVersion == 2) && (minorVersion == 6) && (microVersion >= 13))); } @Override public WatchService newWatchService() throws IOException { - if (hasInotify) { - return new LinuxWatchService(this); - } else { - // use polling implementation on older kernels - return new PollingWatchService(); - } + // assume 2.6.13 or newer + return new LinuxWatchService(this); } diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java index c21a17707a8..ad0a2a00d12 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java +++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java @@ -123,6 +123,10 @@ class UnixFileAttributeViews { private static final String OWNER_NAME = "owner"; private static final String GROUP_NAME = "group"; + // the names of the posix attributes (incudes basic) + static final Set posixAttributeNames = + Util.newSet(basicAttributeNames, PERMISSIONS_NAME, OWNER_NAME, GROUP_NAME); + Posix(UnixPath file, boolean followLinks) { super(file, followLinks); } @@ -172,9 +176,10 @@ class UnixFileAttributeViews { * Invoked by readAttributes or sub-classes to add all matching posix * attributes to the builder */ - final void addPosixAttributesToBuilder(PosixFileAttributes attrs, + final void addRequestedPosixAttributes(PosixFileAttributes attrs, AttributesBuilder builder) { + addRequestedBasicAttributes(attrs, builder); if (builder.match(PERMISSIONS_NAME)) builder.add(PERMISSIONS_NAME, attrs.permissions()); if (builder.match(OWNER_NAME)) @@ -184,13 +189,13 @@ class UnixFileAttributeViews { } @Override - public Map readAttributes(String[] attributes) + public Map readAttributes(String[] requested) throws IOException { - AttributesBuilder builder = AttributesBuilder.create(attributes); + AttributesBuilder builder = + AttributesBuilder.create(posixAttributeNames, requested); PosixFileAttributes attrs = readAttributes(); - addBasicAttributesToBuilder(attrs, builder); - addPosixAttributesToBuilder(attrs, builder); + addRequestedPosixAttributes(attrs, builder); return builder.unmodifiableMap(); } @@ -287,6 +292,12 @@ class UnixFileAttributeViews { private static final String GID_NAME = "gid"; private static final String CTIME_NAME = "ctime"; + // the names of the unix attributes (including posix) + static final Set unixAttributeNames = + Util.newSet(posixAttributeNames, + MODE_NAME, INO_NAME, DEV_NAME, RDEV_NAME, + NLINK_NAME, UID_NAME, GID_NAME, CTIME_NAME); + Unix(UnixPath file, boolean followLinks) { super(file, followLinks); } @@ -316,13 +327,13 @@ class UnixFileAttributeViews { } @Override - public Map readAttributes(String[] attributes) + public Map readAttributes(String[] requested) throws IOException { - AttributesBuilder builder = AttributesBuilder.create(attributes); + AttributesBuilder builder = + AttributesBuilder.create(unixAttributeNames, requested); UnixFileAttributes attrs = readAttributes(); - addBasicAttributesToBuilder(attrs, builder); - addPosixAttributesToBuilder(attrs, builder); + addRequestedPosixAttributes(attrs, builder); if (builder.match(MODE_NAME)) builder.add(MODE_NAME, attrs.mode()); if (builder.match(INO_NAME)) diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java index 9ec49b8d37a..b392b56b7e9 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java +++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java @@ -606,7 +606,9 @@ class UnixPath @Override public boolean startsWith(Path other) { - UnixPath that = toUnixPath(other); + if (!(Objects.requireNonNull(other) instanceof UnixPath)) + return false; + UnixPath that = (UnixPath)other; // other path is longer if (that.path.length > path.length) @@ -655,7 +657,9 @@ class UnixPath @Override public boolean endsWith(Path other) { - UnixPath that = toUnixPath(other); + if (!(Objects.requireNonNull(other) instanceof UnixPath)) + return false; + UnixPath that = (UnixPath)other; int thisLen = path.length; int thatLen = that.path.length; diff --git a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c index e6eaa0aa2f5..9a5b78e7723 100644 --- a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c +++ b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c @@ -60,7 +60,7 @@ Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) { char hostname[MAXHOSTNAMELEN+1]; hostname[0] = '\0'; - if (JVM_GetHostName(hostname, MAXHOSTNAMELEN)) { + if (JVM_GetHostName(hostname, sizeof(hostname))) { /* Something went wrong, maybe networking is not setup? */ strcpy(hostname, "localhost"); } else { @@ -83,6 +83,9 @@ Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) { char *buf2[HENT_BUF_SIZE/(sizeof (char *))]; int h_error=0; + // ensure null-terminated + hostname[MAXHOSTNAMELEN] = '\0'; + #ifdef __GLIBC__ gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &hp, &h_error); #else diff --git a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c index 5db03bf36fa..835969d7761 100644 --- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c +++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c @@ -64,10 +64,12 @@ Java_java_net_Inet6AddressImpl_getLocalHostName(JNIEnv *env, jobject this) { char hostname[NI_MAXHOST+1]; hostname[0] = '\0'; - if (JVM_GetHostName(hostname, MAXHOSTNAMELEN)) { + if (JVM_GetHostName(hostname, sizeof(hostname))) { /* Something went wrong, maybe networking is not setup? */ strcpy(hostname, "localhost"); } else { + // ensure null-terminated + hostname[NI_MAXHOST] = '\0'; #ifdef __linux__ /* On Linux gethostname() says "host.domain.sun.com". On * Solaris gethostname() says "host", so extra work is needed. diff --git a/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c b/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c index 0c1275b3bc2..f84c08edf66 100644 --- a/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c +++ b/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c @@ -302,6 +302,7 @@ awt_DrawingSurface_FreeDrawingSurfaceInfo(JAWT_DrawingSurfaceInfo* dsi) #ifdef DEBUG fprintf(stderr, "Drawing Surface Info is NULL\n"); #endif + return; } free(dsi->platformInfo); free(dsi); diff --git a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c index 45184950931..b548df4bf5d 100644 --- a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c +++ b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c @@ -240,7 +240,7 @@ makeDefaultConfig(JNIEnv *env, int screen) { AwtGraphicsConfigDataPtr defaultConfig; int xinawareScreen = 0; - VisualID forcedVisualID, defaultVisualID; + VisualID forcedVisualID = 0, defaultVisualID; char *forcedVisualStr; XVisualInfo vinfo; long mask; @@ -254,7 +254,7 @@ makeDefaultConfig(JNIEnv *env, int screen) { if ((forcedVisualStr = getenv("FORCEDEFVIS"))) { mask = VisualIDMask | VisualScreenMask; - if (sscanf(forcedVisualStr, "%x", &forcedVisualID) > 0 && + if (sscanf(forcedVisualStr, "%lx", &forcedVisualID) > 0 && forcedVisualID > 0) { vinfo.visualid = forcedVisualID; diff --git a/jdk/src/solaris/native/sun/nio/ch/Net.c b/jdk/src/solaris/native/sun/nio/ch/Net.c index c43664c5000..9f9b4669a8e 100644 --- a/jdk/src/solaris/native/sun/nio/ch/Net.c +++ b/jdk/src/solaris/native/sun/nio/ch/Net.c @@ -154,6 +154,22 @@ Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl) return (ipv6_available()) ? JNI_TRUE : JNI_FALSE; } +JNIEXPORT jboolean JNICALL +Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl) +{ + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL +Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl) +{ +#ifdef __solaris__ + return JNI_TRUE; +#else + return JNI_FALSE; +#endif +} + JNIEXPORT int JNICALL Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6, jboolean stream, jboolean reuse) diff --git a/jdk/src/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java b/jdk/src/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java index 65969a877d5..5590523b6ae 100644 --- a/jdk/src/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java +++ b/jdk/src/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java @@ -26,6 +26,7 @@ package java.net; import java.io.IOException; import java.io.FileDescriptor; +import sun.net.ResourceManager; /** * This class defines the plain DatagramSocketImpl that is used for all @@ -108,6 +109,7 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl protected void close() { if (fd != null || fd1 != null) { datagramSocketClose(); + ResourceManager.afterUdpClose(); fd = null; fd1 = null; } diff --git a/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java b/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java index c9c26517d9b..c4b20db6495 100644 --- a/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java +++ b/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java @@ -45,6 +45,9 @@ public class NTLMAuthentication extends AuthenticationInfo { private static final long serialVersionUID = 100L; + private static final NTLMAuthenticationCallback NTLMAuthCallback = + NTLMAuthenticationCallback.getNTLMAuthenticationCallback(); + private String hostname; private static String defaultDomain; /* Domain to use if not specified by user */ @@ -142,6 +145,14 @@ public class NTLMAuthentication extends AuthenticationInfo { return true; } + /** + * Returns true if the given site is trusted, i.e. we can try + * transparent Authentication. + */ + public static boolean isTrustedSite(URL url) { + return NTLMAuthCallback.isTrustedSite(url); + } + /** * Not supported. Must use the setHeaders() method */ diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java index 8a81b87a0ab..67e5be670e0 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java @@ -157,6 +157,11 @@ class WindowsFileAttributeViews { private static final String HIDDEN_NAME = "hidden"; private static final String ATTRIBUTES_NAME = "attributes"; + // the names of the DOS attribtues (includes basic) + static final Set dosAttributeNames = + Util.newSet(basicAttributeNames, + READONLY_NAME, ARCHIVE_NAME, SYSTEM_NAME, HIDDEN_NAME, ATTRIBUTES_NAME); + Dos(WindowsPath file, boolean followLinks) { super(file, followLinks); } @@ -193,9 +198,10 @@ class WindowsFileAttributeViews { public Map readAttributes(String[] attributes) throws IOException { - AttributesBuilder builder = AttributesBuilder.create(attributes); + AttributesBuilder builder = + AttributesBuilder.create(dosAttributeNames, attributes); WindowsFileAttributes attrs = readAttributes(); - addBasicAttributesToBuilder(attrs, builder); + addRequestedBasicAttributes(attrs, builder); if (builder.match(READONLY_NAME)) builder.add(READONLY_NAME, attrs.isReadOnly()); if (builder.match(ARCHIVE_NAME)) diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java index 26c2b26ce8e..eb35de8167e 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java @@ -646,7 +646,9 @@ class WindowsPath extends AbstractPath { @Override public boolean startsWith(Path obj) { - WindowsPath other = toWindowsPath(obj); + if (!(Objects.requireNonNull(obj) instanceof WindowsPath)) + return false; + WindowsPath other = (WindowsPath)obj; // if this path has a root component the given path's root must match if (!this.root.equalsIgnoreCase(other.root)) { @@ -675,7 +677,9 @@ class WindowsPath extends AbstractPath { @Override public boolean endsWith(Path obj) { - WindowsPath other = toWindowsPath(obj); + if (!(Objects.requireNonNull(obj) instanceof WindowsPath)) + return false; + WindowsPath other = (WindowsPath)obj; // other path is longer if (other.path.length() > this.path.length()) { diff --git a/jdk/src/windows/native/sun/nio/ch/Net.c b/jdk/src/windows/native/sun/nio/ch/Net.c index b415cdfc3e2..75c9ba4ce66 100644 --- a/jdk/src/windows/native/sun/nio/ch/Net.c +++ b/jdk/src/windows/native/sun/nio/ch/Net.c @@ -100,6 +100,18 @@ Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl) return JNI_FALSE; } +JNIEXPORT jboolean JNICALL +Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl) +{ + return JNI_FALSE; +} + +JNIEXPORT jboolean JNICALL +Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl) +{ + return JNI_FALSE; +} + JNIEXPORT jint JNICALL Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6, jboolean stream, jboolean reuse) diff --git a/jdk/src/windows/native/sun/security/krb5/NativeCreds.c b/jdk/src/windows/native/sun/security/krb5/NativeCreds.c index 7533cc12811..91ed2cb84bb 100644 --- a/jdk/src/windows/native/sun/security/krb5/NativeCreds.c +++ b/jdk/src/windows/native/sun/security/krb5/NativeCreds.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -1032,12 +1032,12 @@ jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime) { // XXX Cannot use %02.2ld, because the leading 0 is ignored for integers. // So, print them to strings, and then print them to the master string with a // format pattern that makes it two digits and prefix with a 0 if necessary. - swprintf( (wchar_t *)month, L"%2.2d", systemTime.wMonth); - swprintf( (wchar_t *)day, L"%2.2d", systemTime.wDay); - swprintf( (wchar_t *)hour, L"%2.2d", systemTime.wHour); - swprintf( (wchar_t *)minute, L"%2.2d", systemTime.wMinute); - swprintf( (wchar_t *)second, L"%2.2d", systemTime.wSecond); - swprintf( (wchar_t *)timeString, + swprintf( (wchar_t *)month, 3, L"%2.2d", systemTime.wMonth); + swprintf( (wchar_t *)day, 3, L"%2.2d", systemTime.wDay); + swprintf( (wchar_t *)hour, 3, L"%2.2d", systemTime.wHour); + swprintf( (wchar_t *)minute, 3, L"%2.2d", systemTime.wMinute); + swprintf( (wchar_t *)second, 3, L"%2.2d", systemTime.wSecond); + swprintf( (wchar_t *)timeString, 16, L"%ld%02.2s%02.2s%02.2s%02.2s%02.2sZ", systemTime.wYear, month, diff --git a/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c b/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c index 07b136aba2d..6086ddf30f0 100644 --- a/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c +++ b/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -173,24 +173,45 @@ JNIEXPORT jbyteArray JNICALL Java_sun_tools_attach_WindowsVirtualMachine_generat JNIEXPORT jlong JNICALL Java_sun_tools_attach_WindowsVirtualMachine_openProcess (JNIEnv *env, jclass cls, jint pid) { - HANDLE hProcess; + HANDLE hProcess = NULL; - /* - * Attempt to open process. If it fails then we try to enable the - * SE_DEBUG_NAME privilege and retry. - */ - hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); - if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) { - hProcess = doPrivilegedOpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); + if (pid == (jint) GetCurrentProcessId()) { + /* process is attaching to itself; get a pseudo handle instead */ + hProcess = GetCurrentProcess(); + /* duplicate the pseudo handle so it can be used in more contexts */ + if (DuplicateHandle(hProcess, hProcess, hProcess, &hProcess, + PROCESS_ALL_ACCESS, FALSE, 0) == 0) { + /* + * Could not duplicate the handle which isn't a good sign, + * but we'll try again with OpenProcess() below. + */ + hProcess = NULL; + } } if (hProcess == NULL) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - JNU_ThrowIOException(env, "no such process"); - } else { - JNU_ThrowIOExceptionWithLastError(env, "OpenProcess failed"); + /* + * Attempt to open process. If it fails then we try to enable the + * SE_DEBUG_NAME privilege and retry. + */ + hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); + if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) { + hProcess = doPrivilegedOpenProcess(PROCESS_ALL_ACCESS, FALSE, + (DWORD)pid); + } + + if (hProcess == NULL) { + if (GetLastError() == ERROR_INVALID_PARAMETER) { + JNU_ThrowIOException(env, "no such process"); + } else { + char err_mesg[255]; + /* include the last error in the default detail message */ + sprintf(err_mesg, "OpenProcess(pid=%d) failed; LastError=0x%x", + (int)pid, (int)GetLastError()); + JNU_ThrowIOExceptionWithLastError(env, err_mesg); + } + return (jlong)0; } - return (jlong)0; } /* diff --git a/jdk/src/windows/native/sun/windows/awt_PrintJob.cpp b/jdk/src/windows/native/sun/windows/awt_PrintJob.cpp index df0f263ddfc..1deff60252a 100644 --- a/jdk/src/windows/native/sun/windows/awt_PrintJob.cpp +++ b/jdk/src/windows/native/sun/windows/awt_PrintJob.cpp @@ -3699,7 +3699,9 @@ static void matchPaperSize(HDC printDC, HGLOBAL hDevMode, HGLOBAL hDevNames, double* newWid, double *newHgt, WORD* paperSize) { - const double epsilon = 0.50; + // Tolerated differences in comparing page dimensions between passed in + // "orig" media with that of Windows' device. + const double epsilon = 3.6; // (1/72) of an inch const double tolerance = (1.0 * 72.0); // # inches * 72 *newWid = origWid; diff --git a/jdk/test/Makefile b/jdk/test/Makefile index d26d19c544a..d1171b96027 100644 --- a/jdk/test/Makefile +++ b/jdk/test/Makefile @@ -399,12 +399,12 @@ $(foreach i,$1,$(wildcard ${i})) $(foreach i,$1,$(wildcard closed/${i})) endef # Running batches of tests with or without samevm define RunSamevmBatch -$(ECHO) "Running tests in samevm mode: $(call TestDirs, $?)" -$(MAKE) TESTDIRS="$(call TestDirs, $?)" USE_JTREG_SAMEVM=true UNIQUE_DIR=$@ jtreg_tests +$(ECHO) "Running tests in samevm mode: $?" +$(MAKE) TESTDIRS="$?" USE_JTREG_SAMEVM=true UNIQUE_DIR=$@ jtreg_tests endef define RunOthervmBatch -$(ECHO) "Running tests in othervm mode: $(call TestDirs, $?)" -$(MAKE) TESTDIRS="$(call TestDirs, $?)" USE_JTREG_SAMEVM=false UNIQUE_DIR=$@ jtreg_tests +$(ECHO) "Running tests in othervm mode: $?" +$(MAKE) TESTDIRS="$?" USE_JTREG_SAMEVM=false UNIQUE_DIR=$@ jtreg_tests endef define SummaryInfo $(ECHO) "########################################################" @@ -420,27 +420,29 @@ JDK_ALL_TARGETS = # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has problems, and doesn't help performance as much as others. JDK_ALL_TARGETS += jdk_awt -jdk_awt: com/sun/awt java/awt sun/awt +jdk_awt: $(call TestDirs, com/sun/awt java/awt sun/awt) $(call RunOthervmBatch) # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_beans1 -jdk_beans1: java/beans/beancontext java/beans/PropertyChangeSupport \ +jdk_beans1: $(call TestDirs, \ + java/beans/beancontext java/beans/PropertyChangeSupport \ java/beans/Introspector java/beans/Performance \ - java/beans/VetoableChangeSupport java/beans/Statement + java/beans/VetoableChangeSupport java/beans/Statement) $(call RunSamevmBatch) # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_beans2 -jdk_beans2: java/beans/Beans java/beans/EventHandler java/beans/XMLDecoder \ - java/beans/PropertyEditor +jdk_beans2: $(call TestDirs, \ + java/beans/Beans java/beans/EventHandler java/beans/XMLDecoder \ + java/beans/PropertyEditor) $(call RunOthervmBatch) # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_beans3 -jdk_beans3: java/beans/XMLEncoder +jdk_beans3: $(call TestDirs, java/beans/XMLEncoder) $(call RunOthervmBatch) # All beans tests @@ -449,24 +451,24 @@ jdk_beans: jdk_beans1 jdk_beans2 jdk_beans3 # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_io -jdk_io: java/io +jdk_io: $(call TestDirs, java/io) $(call RunSamevmBatch) # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_lang -jdk_lang: java/lang +jdk_lang: $(call TestDirs, java/lang) $(call RunSamevmBatch) # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_management1 -jdk_management1: javax/management +jdk_management1: $(call TestDirs, javax/management) $(call RunOthervmBatch) # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_management2 -jdk_management2: com/sun/jmx com/sun/management sun/management +jdk_management2: $(call TestDirs, com/sun/jmx com/sun/management sun/management) $(call RunOthervmBatch) # All management tests @@ -475,36 +477,37 @@ jdk_management: jdk_management1 jdk_management2 # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_math -jdk_math: java/math +jdk_math: $(call TestDirs, java/math) $(call RunSamevmBatch) # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_misc -jdk_misc: demo javax/imageio javax/naming javax/print javax/script \ +jdk_misc: $(call TestDirs, \ + demo javax/imageio javax/naming javax/print javax/script \ javax/smartcardio javax/sound com/sun/java com/sun/jndi \ - com/sun/org sun/misc sun/pisces + com/sun/org com/sun/xml sun/misc sun/pisces) $(call RunSamevmBatch) # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_net -jdk_net: com/sun/net java/net sun/net +jdk_net: $(call TestDirs, com/sun/net java/net sun/net) $(call RunSamevmBatch) # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_nio1 -jdk_nio1: java/nio/file +jdk_nio1: $(call TestDirs, java/nio/file) $(call RunSamevmBatch) # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_nio2 -jdk_nio2: java/nio/Buffer java/nio/ByteOrder \ - java/nio/channels java/nio/BufferPoolMXBean java/nio/MappedByteBuffer +jdk_nio2: $(call TestDirs, java/nio/Buffer java/nio/ByteOrder \ + java/nio/channels java/nio/BufferPoolMXBean java/nio/MappedByteBuffer) $(call SharedLibraryPermissions,java/nio/channels) $(call RunSamevmBatch) # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_nio3 -jdk_nio3: com/sun/nio sun/nio +jdk_nio3: $(call TestDirs, com/sun/nio sun/nio) $(call RunSamevmBatch) # All nio tests @@ -514,24 +517,25 @@ jdk_nio: jdk_nio1 jdk_nio2 jdk_nio3 # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_rmi -jdk_rmi: java/rmi javax/rmi sun/rmi +jdk_rmi: $(call TestDirs, java/rmi javax/rmi sun/rmi) $(call RunOthervmBatch) # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_security1 -jdk_security1: java/security +jdk_security1: $(call TestDirs, java/security) $(call RunSamevmBatch) # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_security2 -jdk_security2: javax/crypto com/sun/crypto +jdk_security2: $(call TestDirs, javax/crypto com/sun/crypto) $(call RunOthervmBatch) # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_security3 -jdk_security3: com/sun/security lib/security javax/security sun/security +jdk_security3: $(call TestDirs, com/sun/security lib/security \ + javax/security sun/security) $(call SharedLibraryPermissions,sun/security) $(call RunOthervmBatch) @@ -542,23 +546,25 @@ jdk_security: jdk_security1 jdk_security2 jdk_security3 # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has problems, and doesn't help performance as much as others. JDK_ALL_TARGETS += jdk_swing -jdk_swing: javax/swing sun/java2d +jdk_swing: $(call TestDirs, javax/swing sun/java2d) $(call RunOthervmBatch) # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_text -jdk_text: java/text sun/text +jdk_text: $(call TestDirs, java/text sun/text) $(call RunSamevmBatch) # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_tools1 -jdk_tools1: com/sun/jdi +jdk_tools1: $(call TestDirs, com/sun/jdi) $(call RunSamevmBatch) # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_tools2 -jdk_tools2: com/sun/tools sun/jvmstat sun/tools tools vm com/sun/servicetag com/sun/tracing +jdk_tools2: $(call TestDirs, \ + com/sun/tools sun/jvmstat sun/tools tools vm \ + com/sun/servicetag com/sun/tracing) $(call SharedLibraryPermissions,tools/launcher) $(call RunSamevmBatch) @@ -568,7 +574,7 @@ jdk_tools: jdk_tools1 jdk_tools2 # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_util -jdk_util: java/util sun/util +jdk_util: $(call TestDirs, java/util sun/util) $(call RunSamevmBatch) # ------------------------------------------------------------------ diff --git a/jdk/test/java/awt/font/TextLayout/CombiningPerf.java b/jdk/test/java/awt/font/TextLayout/CombiningPerf.java new file mode 100644 index 00000000000..d51e586e507 --- /dev/null +++ b/jdk/test/java/awt/font/TextLayout/CombiningPerf.java @@ -0,0 +1,85 @@ +/* + * 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 6328154 6962082 + * @summary ensure that ascii, and latin-1 text without combining marks, both layout faster + * than latin-1 text with combining marks. The presumption is then that the canonical + * GSUB table is being run only on the latter and not on either of the former. + */ + +import java.awt.Font; +import java.awt.GraphicsEnvironment; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; + +import static java.awt.Font.*; + +public class CombiningPerf { + private static Font font; + private static FontRenderContext frc; + + public static void main(String[] args) throws Exception { + System.err.println("start"); + + GraphicsEnvironment.getLocalGraphicsEnvironment(); + + font = new Font("Lucida Sans Regular", PLAIN, 12); + frc = new FontRenderContext(null, false, false); + + String ascii = "the characters are critical noodles?"; + String french = "l'aper\u00e7u caract\u00e8re one \u00e9t\u00e9 cr\u00e9\u00e9s"; + String frenchX = "l'aper\u00e7u caracte\u0300re one e\u0301te\u0301 ere\u0301e\u0301s"; + + // warmup + for (int i = 0; i < 100; ++i) { + TextLayout tl = new TextLayout(french, font, frc); + tl = new TextLayout(ascii, font, frc); + tl = new TextLayout(frenchX, font, frc); + } + /**/ + long atime = test(ascii); + System.err.println("atime: " + (atime/1000000.0) + " length: " + ascii.length()); + + long ftime = test(french); + System.err.println("ftime: " + (ftime/1000000.0) + " length: " + french.length()); + + long xtime = test(frenchX); + System.err.println("xtime: " + (xtime/1000000.0) + " length: " + frenchX.length()); + + long limit = xtime * 2 / 3; + if (atime > limit || ftime > limit) { + throw new Exception("took too long"); + } + /**/ + } + + private static long test(String text) { + long start = System.nanoTime(); + for (int i = 0; i < 2000; ++i) { + TextLayout tl = new TextLayout(text, font, frc); + } + return System.nanoTime() - start; + } +} diff --git a/jdk/test/java/awt/font/TextLayout/KernCrash.java b/jdk/test/java/awt/font/TextLayout/KernCrash.java new file mode 100644 index 00000000000..50e44d4c30d --- /dev/null +++ b/jdk/test/java/awt/font/TextLayout/KernCrash.java @@ -0,0 +1,67 @@ +/* + * 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.io.*; +import java.awt.*; +import java.awt.font.*; +import java.util.*; + +/** + * Shows (top) with kerning, (middle) without, (bottom) also without. + * + * @bug 7017324 + */ +public class KernCrash extends Frame { + private static Font font0; + private static Font font1; + private static Font font2; + + public static void main(String[] args) throws Exception { + HashMap attrs = new HashMap(); + font0 = Font.createFont(Font.TRUETYPE_FONT, new File("Vera.ttf")); + System.out.println("using " + font0); + attrs.put(TextAttribute.SIZE, new Float(58f)); + font1 = font0.deriveFont(attrs); + attrs.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); + font2 = font0.deriveFont(attrs); + + KernCrash f = new KernCrash(); + f.setTitle("Kerning Crash"); + f.setSize(600, 300); + f.setForeground(Color.black); + f.show(); + } + + public void paint(Graphics g) { + Graphics2D g2 = (Graphics2D)g; + FontRenderContext frc = g2.getFontRenderContext(); + TextLayout layout = new TextLayout("text", font2, frc); + layout.draw(g2, 10, 150); + + String s = "WAVATastic"; + TextLayout layout2 = new TextLayout(s, font1, frc); + layout2.draw(g2, 10, 200); + TextLayout layout3 = new TextLayout(s, font2, frc); + layout3.draw(g2, 10, 100); + } +} diff --git a/hotspot/test/compiler/6987555/Test6987555.java b/jdk/test/java/lang/invoke/6987555/Test6987555.java similarity index 99% rename from hotspot/test/compiler/6987555/Test6987555.java rename to jdk/test/java/lang/invoke/6987555/Test6987555.java index a438fee8dd1..465da236d7c 100644 --- a/hotspot/test/compiler/6987555/Test6987555.java +++ b/jdk/test/java/lang/invoke/6987555/Test6987555.java @@ -30,7 +30,7 @@ * @run main/othervm -Xint -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -XX:+UnlockDiagnosticVMOptions -XX:+VerifyMethodHandles Test6987555 */ -import java.dyn.*; +import java.lang.invoke.*; public class Test6987555 { private static final Class CLASS = Test6987555.class; diff --git a/hotspot/test/compiler/6991596/Test6991596.java b/jdk/test/java/lang/invoke/6991596/Test6991596.java similarity index 98% rename from hotspot/test/compiler/6991596/Test6991596.java rename to jdk/test/java/lang/invoke/6991596/Test6991596.java index aff08c88641..e02bcfc819e 100644 --- a/hotspot/test/compiler/6991596/Test6991596.java +++ b/jdk/test/java/lang/invoke/6991596/Test6991596.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -30,7 +30,7 @@ * @run main/othervm -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -XX:+UnlockDiagnosticVMOptions -XX:+VerifyMethodHandles Test6991596 */ -import java.dyn.*; +import java.lang.invoke.*; public class Test6991596 { private static final Class CLASS = Test6991596.class; @@ -47,7 +47,7 @@ public class Test6991596 { } // Helpers to get various methods. - static MethodHandle getmh1(Class ret, Class arg) throws NoAccessException { + static MethodHandle getmh1(Class ret, Class arg) throws ReflectiveOperationException { return MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(ret, arg)); } static MethodHandle getmh2(MethodHandle mh1, Class ret, Class arg) { diff --git a/jdk/test/java/dyn/ClassValueTest.java b/jdk/test/java/lang/invoke/ClassValueTest.java similarity index 94% rename from jdk/test/java/dyn/ClassValueTest.java rename to jdk/test/java/lang/invoke/ClassValueTest.java index f917e9581da..59c5a658c7e 100644 --- a/jdk/test/java/dyn/ClassValueTest.java +++ b/jdk/test/java/lang/invoke/ClassValueTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -26,21 +26,21 @@ /* @test * @summary tests for class-specific values * @compile ClassValueTest.java - * @run junit/othervm test.java.dyn.ClassValueTest + * @run junit/othervm test.java.lang.invoke.ClassValueTest */ /* Manually: - $ $JAVA7X_HOME/bin/javac -d foo -cp $JUNIT4_JAR test/java/dyn/ClassValueTest.java - $ $JAVA7X_HOME/bin/java -cp foo:$JUNIT4_JAR org.junit.runner.JUnitCore test.java.dyn.ClassValueTest + $ $JAVA7X_HOME/bin/javac -d foo -cp $JUNIT4_JAR test/java/lang/invoke/ClassValueTest.java + $ $JAVA7X_HOME/bin/java -cp foo:$JUNIT4_JAR org.junit.runner.JUnitCore test.java.lang.invoke.ClassValueTest Output: .testAdd => 1000 : Integer */ -package test.java.dyn; +package test.java.lang.invoke; import java.util.*; -import java.dyn.*; +import java.lang.invoke.*; import org.junit.*; import static org.junit.Assert.*; diff --git a/jdk/test/java/dyn/InvokeDynamicPrintArgs.java b/jdk/test/java/lang/invoke/InvokeDynamicPrintArgs.java similarity index 89% rename from jdk/test/java/dyn/InvokeDynamicPrintArgs.java rename to jdk/test/java/lang/invoke/InvokeDynamicPrintArgs.java index 233c4fc316c..7089e959223 100644 --- a/jdk/test/java/dyn/InvokeDynamicPrintArgs.java +++ b/jdk/test/java/lang/invoke/InvokeDynamicPrintArgs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -29,19 +29,19 @@ * indify.Indify * --verify-specifier-count=3 --transitionalJSR292=false * --expand-properties --classpath ${test.classes} - * --java test.java.dyn.InvokeDynamicPrintArgs --check-output + * --java test.java.lang.invoke.InvokeDynamicPrintArgs --check-output */ -package test.java.dyn; +package test.java.lang.invoke; import org.junit.Test; import java.util.*; import java.io.*; -import java.dyn.*; -import static java.dyn.MethodHandles.*; -import static java.dyn.MethodType.*; +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; public class InvokeDynamicPrintArgs { public static void main(String... av) throws Throwable { @@ -65,7 +65,7 @@ public class InvokeDynamicPrintArgs { String[] args = new String[]{ "--verify-specifier-count=3", "--transitionalJSR292=false", "--expand-properties", "--classpath", testClassPath, - "--java", "test.java.dyn.InvokeDynamicPrintArgs", "--check-output" + "--java", "test.java.lang.invoke.InvokeDynamicPrintArgs", "--check-output" }; System.err.println("Indify: "+Arrays.toString(args)); indify.Indify.main(args); @@ -97,11 +97,11 @@ public class InvokeDynamicPrintArgs { } private static final String[] EXPECT_OUTPUT = { "Printing some argument lists, starting with a empty one:", - "[test.java.dyn.InvokeDynamicPrintArgs, nothing, ()void][]", - "[test.java.dyn.InvokeDynamicPrintArgs, bar, (String,int)void, class java.lang.Void, void type!, 1, 234.5, 67.5, 89][bar arg, 1]", - "[test.java.dyn.InvokeDynamicPrintArgs, bar2, (String,int)void, class java.lang.Void, void type!, 1, 234.5, 67.5, 89][bar2 arg, 222]", - "[test.java.dyn.InvokeDynamicPrintArgs, baz, (String,int,double)void, 1234.5][baz arg, 2, 3.14]", - "[test.java.dyn.InvokeDynamicPrintArgs, foo, (String)void][foo arg]", + "[test.java.lang.invoke.InvokeDynamicPrintArgs, nothing, ()void][]", + "[test.java.lang.invoke.InvokeDynamicPrintArgs, bar, (String,int)void, class java.lang.Void, void type!, 1, 234.5, 67.5, 89][bar arg, 1]", + "[test.java.lang.invoke.InvokeDynamicPrintArgs, bar2, (String,int)void, class java.lang.Void, void type!, 1, 234.5, 67.5, 89][bar2 arg, 222]", + "[test.java.lang.invoke.InvokeDynamicPrintArgs, baz, (String,int,double)void, 1234.5][baz arg, 2, 3.14]", + "[test.java.lang.invoke.InvokeDynamicPrintArgs, foo, (String)void][foo arg]", "Done printing argument lists." }; diff --git a/jdk/test/java/dyn/InvokeGenericTest.java b/jdk/test/java/lang/invoke/InvokeGenericTest.java similarity index 97% rename from jdk/test/java/dyn/InvokeGenericTest.java rename to jdk/test/java/lang/invoke/InvokeGenericTest.java index bae888060a0..f1aaf9eaa71 100644 --- a/jdk/test/java/dyn/InvokeGenericTest.java +++ b/jdk/test/java/lang/invoke/InvokeGenericTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -24,16 +24,16 @@ */ /* @test - * @summary unit tests for java.dyn.MethodHandle.invokeGeneric + * @summary unit tests for java.lang.invoke.MethodHandle.invokeGeneric * @compile -XDallowTransitionalJSR292=no -target 7 InvokeGenericTest.java - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles test.java.dyn.InvokeGenericTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles test.java.lang.invoke.InvokeGenericTest */ -package test.java.dyn; +package test.java.lang.invoke; -import java.dyn.*; -import static java.dyn.MethodHandles.*; -import static java.dyn.MethodType.*; +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; import java.lang.reflect.*; import java.util.*; import org.junit.*; @@ -49,7 +49,7 @@ public class InvokeGenericTest { // How much output? static int verbosity = 0; static { - String vstr = System.getProperty("test.java.dyn.InvokeGenericTest.verbosity"); + String vstr = System.getProperty("test.java.lang.invoke.InvokeGenericTest.verbosity"); if (vstr != null) verbosity = Integer.parseInt(vstr); } @@ -216,7 +216,7 @@ public class InvokeGenericTest { if (wrap != null) { return wrap; } -// import sun.dyn.util.Wrapper; +// import sun.invoke.util.Wrapper; // Wrapper wrap = Wrapper.forBasicType(dst); // if (wrap == Wrapper.OBJECT && Wrapper.isWrapperType(dst)) // wrap = Wrapper.forWrapperType(dst); diff --git a/jdk/test/java/dyn/JavaDocExamplesTest.java b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java similarity index 88% rename from jdk/test/java/dyn/JavaDocExamplesTest.java rename to jdk/test/java/lang/invoke/JavaDocExamplesTest.java index 72a62851f82..7093ea2005a 100644 --- a/jdk/test/java/dyn/JavaDocExamplesTest.java +++ b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java @@ -24,27 +24,27 @@ */ /* @test - * @summary example code used in javadoc for java.dyn API + * @summary example code used in javadoc for java.lang.invoke API * @compile -XDallowTransitionalJSR292=no JavaDocExamplesTest.java - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles test.java.dyn.JavaDocExamplesTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles test.java.lang.invoke.JavaDocExamplesTest */ /* ---- To run outside jtreg: $ $JAVA7X_HOME/bin/javac -cp $JUNIT4_JAR -d /tmp/Classes \ - $DAVINCI/sources/jdk/test/java/dyn/JavaDocExamplesTest.java + $DAVINCI/sources/jdk/test/java/lang/invoke/JavaDocExamplesTest.java $ $JAVA7X_HOME/bin/java -cp $JUNIT4_JAR:/tmp/Classes \ -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles \ - -Dtest.java.dyn.JavaDocExamplesTest.verbosity=1 \ - test.java.dyn.JavaDocExamplesTest + -Dtest.java.lang.invoke.JavaDocExamplesTest.verbosity=1 \ + test.java.lang.invoke.JavaDocExamplesTest ---- */ -package test.java.dyn; +package test.java.lang.invoke; -import java.dyn.*; -import static java.dyn.MethodHandles.*; -import static java.dyn.MethodType.*; +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; import java.lang.reflect.*; import java.util.*; @@ -65,7 +65,7 @@ public class JavaDocExamplesTest { org.junit.runner.JUnitCore.runClasses(JavaDocExamplesTest.class); } // How much output? - static int verbosity = Integer.getInteger("test.java.dyn.JavaDocExamplesTest.verbosity", 0); + static int verbosity = Integer.getInteger("test.java.lang.invoke.JavaDocExamplesTest.verbosity", 0); {} static final private Lookup LOOKUP = lookup(); @@ -108,6 +108,16 @@ assertEquals("xy".hashCode(), (int) HASHCODE_3.invokeExact((Object)"xy")); MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); assertEquals("xy", (String) cat.invokeExact("x", "y")); +MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class); +MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2)); +assertEquals(bigType, d0.type()); +assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z")); + }} + {{ +{} /// JAVADOC +MethodHandle cat = lookup().findVirtual(String.class, + "concat", methodType(String.class, String.class)); +assertEquals("xy", (String) cat.invokeExact("x", "y")); MethodHandle d0 = dropArguments(cat, 0, String.class); assertEquals("yz", (String) d0.invokeExact("x", "y", "z")); MethodHandle d1 = dropArguments(cat, 1, String.class); diff --git a/jdk/test/java/dyn/MethodHandlesTest.java b/jdk/test/java/lang/invoke/MethodHandlesTest.java similarity index 99% rename from jdk/test/java/dyn/MethodHandlesTest.java rename to jdk/test/java/lang/invoke/MethodHandlesTest.java index b44f262fa02..bae38f766bc 100644 --- a/jdk/test/java/dyn/MethodHandlesTest.java +++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java @@ -24,15 +24,15 @@ */ /* @test - * @summary unit tests for java.dyn.MethodHandles + * @summary unit tests for java.lang.invoke.MethodHandles * @compile -source 7 -target 7 -XDallowTransitionalJSR292=no MethodHandlesTest.java - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles test.java.dyn.MethodHandlesTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles test.java.lang.invoke.MethodHandlesTest */ -package test.java.dyn; +package test.java.lang.invoke; -import java.dyn.*; -import java.dyn.MethodHandles.Lookup; +import java.lang.invoke.*; +import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.*; import java.util.*; import org.junit.*; @@ -48,7 +48,7 @@ public class MethodHandlesTest { // How much output? static int verbosity = 0; static { - String vstr = System.getProperty("test.java.dyn.MethodHandlesTest.verbosity"); + String vstr = System.getProperty("test.java.lang.invoke.MethodHandlesTest.verbosity"); if (vstr != null) verbosity = Integer.parseInt(vstr); } @@ -258,7 +258,7 @@ public class MethodHandlesTest { if (wrap != null) { return wrap; } -// import sun.dyn.util.Wrapper; +// import sun.invoke.util.Wrapper; // Wrapper wrap = Wrapper.forBasicType(dst); // if (wrap == Wrapper.OBJECT && Wrapper.isWrapperType(dst)) // wrap = Wrapper.forWrapperType(dst); @@ -2264,7 +2264,7 @@ public class MethodHandlesTest { } } } -// Local abbreviated copy of sun.dyn.util.ValueConversions +// Local abbreviated copy of sun.invoke.util.ValueConversions class ValueConversions { private static final Lookup IMPL_LOOKUP = MethodHandles.lookup(); private static final Object[] NO_ARGS_ARRAY = {}; diff --git a/jdk/test/java/dyn/MethodTypeTest.java b/jdk/test/java/lang/invoke/MethodTypeTest.java similarity index 82% rename from jdk/test/java/dyn/MethodTypeTest.java rename to jdk/test/java/lang/invoke/MethodTypeTest.java index caadaa04a33..5cc32771624 100644 --- a/jdk/test/java/dyn/MethodTypeTest.java +++ b/jdk/test/java/lang/invoke/MethodTypeTest.java @@ -24,15 +24,14 @@ */ /* @test - * @summary unit tests for java.dyn.MethodType + * @summary unit tests for java.lang.invoke.MethodType * @compile MethodTypeTest.java - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles test.java.dyn.MethodTypeTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles test.java.lang.invoke.MethodTypeTest */ -package test.java.dyn; +package test.java.lang.invoke; -import sun.dyn.MemberName; -import java.dyn.MethodType; +import java.lang.invoke.MethodType; import java.lang.reflect.Method; import java.util.*; @@ -163,18 +162,6 @@ public class MethodTypeTest { assertSame(expResult, result); } - /** - * Test of make method, of class MethodType. - */ - @Test - public void testMake_Method() { - System.out.println("make (via MemberName.getMethodType)"); - MethodType expResult = MethodType.methodType(int.class, String.class); - MemberName name = new MemberName(compareTo); - MethodType result = name.getMethodType(); - assertSame(expResult, result); - } - /** * Test of make method, of class MethodType. */ @@ -476,10 +463,13 @@ public class MethodTypeTest { @Test public void testPortableSerialFormat() throws Throwable { System.out.println("portable serial format"); + boolean generateData = false; + //generateData = true; // set this true to generate the following input data: Object[][] cases = { { mt_vv, new byte[] { // ()void - (byte)0xac, (byte)0xed, (byte)0x00, (byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x13, - (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x64, (byte)0x79, (byte)0x6e, + (byte)0xac, (byte)0xed, (byte)0x00, (byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x1b, + (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, + (byte)0x67, (byte)0x2e, (byte)0x69, (byte)0x6e, (byte)0x76, (byte)0x6f, (byte)0x6b, (byte)0x65, (byte)0x2e, (byte)0x4d, (byte)0x65, (byte)0x74, (byte)0x68, (byte)0x6f, (byte)0x64, (byte)0x54, (byte)0x79, (byte)0x70, (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x24, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, @@ -493,8 +483,9 @@ public class MethodTypeTest { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78, } }, { mt_OO, new byte[] { // (Object)Object - (byte)0xac, (byte)0xed, (byte)0x00, (byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x13, - (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x64, (byte)0x79, (byte)0x6e, + (byte)0xac, (byte)0xed, (byte)0x00, (byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x1b, + (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, + (byte)0x67, (byte)0x2e, (byte)0x69, (byte)0x6e, (byte)0x76, (byte)0x6f, (byte)0x6b, (byte)0x65, (byte)0x2e, (byte)0x4d, (byte)0x65, (byte)0x74, (byte)0x68, (byte)0x6f, (byte)0x64, (byte)0x54, (byte)0x79, (byte)0x70, (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x24, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, @@ -509,14 +500,47 @@ public class MethodTypeTest { (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x71, (byte)0x00, (byte)0x7e, (byte)0x00, (byte)0x03, (byte)0x78, } }, + { mt_vOiSzA, new byte[] { // (Object,int,String,boolean,Object[])void + (byte)0xac, (byte)0xed, (byte)0x00, (byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x1b, + (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, + (byte)0x67, (byte)0x2e, (byte)0x69, (byte)0x6e, (byte)0x76, (byte)0x6f, (byte)0x6b, (byte)0x65, + (byte)0x2e, (byte)0x4d, (byte)0x65, (byte)0x74, (byte)0x68, (byte)0x6f, (byte)0x64, (byte)0x54, + (byte)0x79, (byte)0x70, (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x01, (byte)0x24, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, + (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x04, (byte)0x76, (byte)0x6f, (byte)0x69, (byte)0x64, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, (byte)0x75, (byte)0x72, (byte)0x00, + (byte)0x12, (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, + (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2e, (byte)0x43, (byte)0x6c, (byte)0x61, + (byte)0x73, (byte)0x73, (byte)0x3b, (byte)0xab, (byte)0x16, (byte)0xd7, (byte)0xae, (byte)0xcb, + (byte)0xcd, (byte)0x5a, (byte)0x99, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x10, + (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, + (byte)0x67, (byte)0x2e, (byte)0x4f, (byte)0x62, (byte)0x6a, (byte)0x65, (byte)0x63, (byte)0x74, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, (byte)0x76, (byte)0x72, (byte)0x00, + (byte)0x03, (byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78, + (byte)0x70, (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x10, (byte)0x6a, (byte)0x61, (byte)0x76, + (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2e, (byte)0x53, + (byte)0x74, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67, (byte)0xa0, (byte)0xf0, (byte)0xa4, + (byte)0x38, (byte)0x7a, (byte)0x3b, (byte)0xb3, (byte)0x42, (byte)0x02, (byte)0x00, (byte)0x00, + (byte)0x78, (byte)0x70, (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x07, (byte)0x62, (byte)0x6f, + (byte)0x6f, (byte)0x6c, (byte)0x65, (byte)0x61, (byte)0x6e, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x78, (byte)0x70, (byte)0x76, (byte)0x72, (byte)0x00, (byte)0x13, (byte)0x5b, (byte)0x4c, + (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, + (byte)0x67, (byte)0x2e, (byte)0x4f, (byte)0x62, (byte)0x6a, (byte)0x65, (byte)0x63, (byte)0x74, + (byte)0x3b, (byte)0x90, (byte)0xce, (byte)0x58, (byte)0x9f, (byte)0x10, (byte)0x73, (byte)0x29, + (byte)0x6c, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70, (byte)0x78, + } }, }; - boolean generateData = false; - //generateData = true; for (Object[] c : cases) { MethodType mt = (MethodType) c[0]; System.out.println("deserialize "+mt); byte[] wire = (byte[]) c[1]; if (generateData) { + System.out.println(""); wire = writeSerial(mt); final String INDENT = " "; System.out.print("{ // "+mt); @@ -528,6 +552,7 @@ public class MethodTypeTest { } System.out.println(); System.out.println(INDENT+"}"); + System.out.println(""); System.out.flush(); } Object decode; diff --git a/jdk/test/java/dyn/indify/Indify.java b/jdk/test/java/lang/invoke/indify/Indify.java similarity index 98% rename from jdk/test/java/dyn/indify/Indify.java rename to jdk/test/java/lang/invoke/indify/Indify.java index ba24b79a9d9..ac0485a5ebc 100644 --- a/jdk/test/java/dyn/indify/Indify.java +++ b/jdk/test/java/lang/invoke/indify/Indify.java @@ -47,9 +47,9 @@ import java.util.regex.*; * and {@code CONSTANT_MethodType} "ldc" instructions. * The stereotyped code must create method types by calls to {@code methodType} or * {@code fromMethodDescriptorString}. The "lookup" argument must be created - * by calls to {@code java.dyn.MethodHandles#lookup MethodHandles.lookup}. + * by calls to {@code java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}. * The class and string arguments must be constant. - * The following methods of {@code java.dyn.MethodHandle.Lookup Lookup} are + * The following methods of {@code java.lang.invoke.MethodHandle.Lookup Lookup} are * allowed for method handle creation: {@code findStatic}, {@code findVirtual}, * {@code findConstructor}, {@code findSpecial}, * {@code findGetter}, {@code findSetter}, @@ -350,10 +350,15 @@ public class Indify { } protected Class findClass(String name) throws ClassNotFoundException { try { - return transformAndLoadClass(findClassInPath(name)); + File f = findClassInPath(name); + if (f != null) { + Class c = transformAndLoadClass(f); + if (c != null) return c; + } } catch (IOException ex) { throw new ClassNotFoundException("IO error", ex); } + throw new ClassNotFoundException(); } private Class transformAndLoadClass(File f) throws ClassNotFoundException, IOException { if (verbose) System.err.println("Loading class from "+f); @@ -592,7 +597,9 @@ public class Indify { if (s.startsWith("MT_")) return 'T'; else if (s.startsWith("MH_")) return 'H'; else if (s.startsWith("INDY_")) return 'I'; - else if (s.startsWith("java/dyn/")) return 'D'; + else if (transitionalJSR292 && + s.startsWith("java/dyn/")) return 'D'; + else if (s.startsWith("java/lang/invoke/")) return 'D'; else if (s.startsWith("java/lang/")) return 'J'; return 0; } @@ -605,15 +612,24 @@ public class Indify { String descr = cf.pool.getString(CONSTANT_Utf8, n2); String requiredType; switch (poolMarks[(char)n1]) { - case 'H': requiredType = "()Ljava/dyn/MethodHandle;"; break; - case 'T': requiredType = "()Ljava/dyn/MethodType;"; break; - case 'I': requiredType = "()Ljava/dyn/MethodHandle;"; break; + case 'H': requiredType = "()Ljava/lang/invoke/MethodHandle;"; break; + case 'T': requiredType = "()Ljava/lang/invoke/MethodType;"; break; + case 'I': requiredType = "()Ljava/lang/invoke/MethodHandle;"; break; default: return 0; } - if (descr.equals(requiredType)) return mark; + if (matchType(descr, requiredType)) return mark; return 0; } + boolean matchType(String descr, String requiredType) { + if (descr.equals(requiredType)) return true; + if (transitionalJSR292) { + String oldType = requiredType.replace("Ljava/lang/invoke/", "Ljava/dyn/"); + if (descr.equals(oldType)) return true; + } + return false; + } + private class JVMState { final List stack = new ArrayList<>(); int sp() { return stack.size(); } diff --git a/jdk/test/java/net/URI/Test.java b/jdk/test/java/net/URI/Test.java index f0bb8da821a..3f157ea7561 100644 --- a/jdk/test/java/net/URI/Test.java +++ b/jdk/test/java/net/URI/Test.java @@ -23,7 +23,7 @@ /* @test * @summary Unit test for java.net.URI - * @bug 4464135 4505046 4503239 4438319 4991359 4866303 + * @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 * @author Mark Reinhold */ @@ -1050,6 +1050,13 @@ public class Test { test("http://1.2.3.4.5").psa().x().z(); test("http://[1.2.3.4:5]").x().z(); test("http://1:2:3:4:5:6:7:8").psa().x().z(); + test("http://[1.2.3.4]/").x().z(); + test("http://[1.2.3.4/").x().z(); + test("http://[foo]/").x().z(); + test("http://[foo/").x().z(); + test("s", "[foo]", "/", null, null).x().z(); + test("s", "[foo", "/", null, null).x().z(); + test("s", "[::foo", "/", null, null).x().z(); // Test hostnames that might initially look like IPv4 addresses diff --git a/jdk/test/java/net/URLConnection/GetXmlContentType.java b/jdk/test/java/net/URLConnection/GetXmlContentType.java index 5c3282d63ec..e89043a9781 100644 --- a/jdk/test/java/net/URLConnection/GetXmlContentType.java +++ b/jdk/test/java/net/URLConnection/GetXmlContentType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -23,8 +23,8 @@ /* * @test - * @bug 4160195 - * @summary Check for correct detection of XML content type + * @bug 4160195 7026346 + * @summary Check for correct detection of XML content type, including BOM streams */ import java.io.*; @@ -34,6 +34,8 @@ import java.net.*; public class GetXmlContentType { static final String XML_MIME_TYPE = "application/xml"; + static final String XML_HEADER = " 0) + throw new RuntimeException ( + "Test failed; passed = " + passed + ", failed = " + failed); + } + + static void contentTypeFromFile() throws Exception { // POSITIVE tests: good data --> good result - // - for (int i = 0; i < goodFiles.length; i++) { - String result = getUrlContentType (goodFiles [i]); - if (!XML_MIME_TYPE.equals (result)) { - System.out.println ("Wrong MIME type: " - + goodFiles [i] - + " --> " + result - ); - sawError = true; + for (String goodFile : goodFiles) { + String result = getUrlContentType(goodFile); + + if (!XML_MIME_TYPE.equals(result)) { + System.out.println("Wrong MIME type: " + goodFile + " --> " + result); + failed++; + } else { + passed++; } } - // // NEGATIVE tests: bad data --> correct diagnostic - // - for (int i = 0; i < badFiles.length; i++) { - String result = getUrlContentType (badFiles [i]); + for (String badFile : badFiles) { + String result = getUrlContentType(badFile); - if (XML_MIME_TYPE.equals (result)) { - System.out.println ("Wrong MIME type: " - + badFiles [i] - + " --> " + result - ); - sawError = true; + if (XML_MIME_TYPE.equals(result)) { + System.out.println("Wrong MIME type: " + badFile + " --> " + result); + failed++; + } else { + passed++; } } - - if (sawError) - throw new Exception ( - "GetXmlContentType Test failed; see diagnostics."); } - static String getUrlContentType (String name) throws IOException { - File file = new File(System.getProperty("test.src", "."), "xml"); - URL u = new URL ("file:" - + file.getCanonicalPath() - + file.separator - + name); - URLConnection conn = u.openConnection (); + static String getUrlContentType(String name) throws IOException { + File file = new File(System.getProperty("test.src", "."), "xml"); + URL u = new URL("file:" + + file.getCanonicalPath() + + file.separator + + name); + URLConnection conn = u.openConnection(); - return conn.getContentType (); + return conn.getContentType(); } + static void contentTypeFromBOMStream() throws Exception { + final String[] encodings = new String[] + {"UTF-8", "UTF-16BE", "UTF-16LE", "UTF-32BE", "UTF-32LE"}; + for (String encoding : encodings) { + try (InputStream is = new ByteArrayInputStream(toBOMBytes(encoding))) { + String mime = URLConnection.guessContentTypeFromStream(is); + if ( !XML_MIME_TYPE.equals(mime) ) { + System.out.println("Wrong MIME type: " + encoding + " --> " + mime); + failed++; + } else { + passed++; + } + } + } + } + + static byte[] toBOMBytes(String encoding) throws Exception { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + switch (encoding) { + case "UTF-8" : + bos.write(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF }); + break; + case "UTF-16BE" : + bos.write(new byte[] { (byte) 0xFE, (byte) 0xFF }); + break; + case "UTF-16LE" : + bos.write(new byte[] { (byte) 0xFF, (byte) 0xFE }); + break; + case "UTF-32BE" : + bos.write(new byte[] { (byte) 0x00, (byte) 0x00, + (byte) 0xFE, (byte) 0xFF }); + break; + case "UTF-32LE" : + bos.write(new byte[] { (byte) 0xFF, (byte) 0xFE, + (byte) 0x00, (byte) 0x00 }); + } + + bos.write(XML_HEADER.getBytes(encoding)); + return bos.toByteArray(); + } } diff --git a/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java b/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java index aa79e2214df..f4445bb946f 100644 --- a/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java +++ b/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4527345 + * @bug 4527345 7026376 * @summary Unit test for DatagramChannel's multicast support * @build MulticastSendReceiveTests NetworkConfiguration * @run main MulticastSendReceiveTests @@ -31,12 +31,19 @@ import java.nio.ByteBuffer; import java.nio.channels.*; import java.net.*; +import static java.net.StandardProtocolFamily.*; import java.util.*; import java.io.IOException; public class MulticastSendReceiveTests { - static Random rand = new Random(); + static final Random rand = new Random(); + + static final ProtocolFamily UNSPEC = new ProtocolFamily() { + public String name() { + return "UNSPEC"; + } + }; /** * Send datagram from given local address to given multicast @@ -130,75 +137,84 @@ public class MulticastSendReceiveTests { /** * Exercise multicast send/receive on given group/interface */ - static void test(NetworkInterface nif, InetAddress group, InetAddress source) + static void test(ProtocolFamily family, + NetworkInterface nif, + InetAddress group, + InetAddress source) throws IOException { - ProtocolFamily family = (group instanceof Inet6Address) ? - StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; - System.out.format("create channel to %s socket\n", family.name()); - DatagramChannel dc = DatagramChannel.open(family) - .setOption(StandardSocketOption.SO_REUSEADDR, true) - .bind(new InetSocketAddress(0)); + System.out.format("\nTest DatagramChannel to %s socket\n", family.name()); + try (DatagramChannel dc = (family == UNSPEC) ? + DatagramChannel.open() : DatagramChannel.open(family)) { + dc.setOption(StandardSocketOption.SO_REUSEADDR, true) + .bind(new InetSocketAddress(0)); - // join group - System.out.format("join %s @ %s\n", group.getHostAddress(), - nif.getName()); - MembershipKey key = dc.join(group, nif); + // join group + System.out.format("join %s @ %s\n", group.getHostAddress(), + nif.getName()); + MembershipKey key; + try { + key = dc.join(group, nif); + } catch (IllegalArgumentException iae) { + if (family == UNSPEC) { + System.out.println("Not supported"); + return; + } + throw iae; + } - // send message to group - int port = ((InetSocketAddress)dc.getLocalAddress()).getPort(); - int id = sendDatagram(source, nif, group, port); + // send message to group + int port = ((InetSocketAddress)dc.getLocalAddress()).getPort(); + int id = sendDatagram(source, nif, group, port); - // receive message and check id matches - receiveDatagram(dc, source, id); - - // exclude-mode filtering - - try { - System.out.format("block %s\n", source.getHostAddress()); - - // may throw UOE - key.block(source); - id = sendDatagram(source, nif, group, port); - receiveDatagram(dc, null, id); - - // unblock source, send message, message should be received - System.out.format("unblock %s\n", source.getHostAddress()); - key.unblock(source); - id = sendDatagram(source, nif, group, port); + // receive message and check id matches receiveDatagram(dc, source, id); - } catch (UnsupportedOperationException x) { - System.out.println("Exclude-mode filtering not supported!"); - } - key.drop(); + // exclude-mode filtering - // include-mode filtering + try { + System.out.format("block %s\n", source.getHostAddress()); - InetAddress bogus = (group instanceof Inet6Address) ? - InetAddress.getByName("fe80::1234") : - InetAddress.getByName("1.2.3.4"); - System.out.format("join %s @ %s only-source %s\n", group.getHostAddress(), - nif.getName(), bogus.getHostAddress()); - try { - // may throw UOE - key = dc.join(group, nif, bogus); + // may throw UOE + key.block(source); + id = sendDatagram(source, nif, group, port); + receiveDatagram(dc, null, id); - id = sendDatagram(source, nif, group, port); - receiveDatagram(dc, null, id); + // unblock source, send message, message should be received + System.out.format("unblock %s\n", source.getHostAddress()); + key.unblock(source); + id = sendDatagram(source, nif, group, port); + receiveDatagram(dc, source, id); + } catch (UnsupportedOperationException x) { + System.out.println("Exclude-mode filtering not supported!"); + } + key.drop(); + + // include-mode filtering + + InetAddress bogus = (group instanceof Inet6Address) ? + InetAddress.getByName("fe80::1234") : + InetAddress.getByName("1.2.3.4"); System.out.format("join %s @ %s only-source %s\n", group.getHostAddress(), - nif.getName(), source.getHostAddress()); - key = dc.join(group, nif, source); + nif.getName(), bogus.getHostAddress()); + try { + // may throw UOE + key = dc.join(group, nif, bogus); - id = sendDatagram(source, nif, group, port); - receiveDatagram(dc, source, id); - } catch (UnsupportedOperationException x) { - System.out.println("Include-mode filtering not supported!"); + id = sendDatagram(source, nif, group, port); + receiveDatagram(dc, null, id); + + System.out.format("join %s @ %s only-source %s\n", group.getHostAddress(), + nif.getName(), source.getHostAddress()); + key = dc.join(group, nif, source); + + id = sendDatagram(source, nif, group, port); + receiveDatagram(dc, source, id); + } catch (UnsupportedOperationException x) { + System.out.println("Include-mode filtering not supported!"); + } } - - // done - dc.close(); } public static void main(String[] args) throws IOException { @@ -210,12 +226,14 @@ public class MulticastSendReceiveTests { for (NetworkInterface nif: config.ip4Interfaces()) { InetAddress source = config.ip4Addresses(nif).iterator().next(); - test(nif, ip4Group, source); + test(INET, nif, ip4Group, source); + test(UNSPEC, nif, ip4Group, source); } for (NetworkInterface nif: config.ip6Interfaces()) { InetAddress source = config.ip6Addresses(nif).iterator().next(); - test(nif, ip6Group, source); + test(INET6, nif, ip6Group, source); + test(UNSPEC, nif, ip6Group, source); } } } diff --git a/jdk/test/java/nio/file/Files/FileAttributes.java b/jdk/test/java/nio/file/Files/FileAttributes.java index bd799dc6b1e..d8aea7fe3ba 100644 --- a/jdk/test/java/nio/file/Files/FileAttributes.java +++ b/jdk/test/java/nio/file/Files/FileAttributes.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6838333 + * @bug 4313887 6838333 7017446 * @summary Unit test for java.nio.file.Files * @library .. */ @@ -94,12 +94,6 @@ public class FileAttributes { assertTrue(map.size() == 2); checkEqual(attrs.size(), map.get("size")); checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime")); - - map = Files.readAttributes(file, - "basic:lastModifiedTime,lastAccessTime,ShouldNotExist"); - assertTrue(map.size() == 2); - checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime")); - checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime")); } // Exercise getAttribute/setAttribute/readAttributes on posix attributes @@ -132,7 +126,7 @@ public class FileAttributes { assertTrue(map.size() >= 12); checkEqual(attrs.permissions(), map.get("permissions")); // check one - map = Files.readAttributes(file, "posix:size,owner,ShouldNotExist"); + map = Files.readAttributes(file, "posix:size,owner"); assertTrue(map.size() == 2); checkEqual(attrs.size(), map.get("size")); checkEqual(attrs.owner(), map.get("owner")); @@ -155,7 +149,7 @@ public class FileAttributes { map = Files.readAttributes(file, "unix:*"); assertTrue(map.size() >= 20); - map = Files.readAttributes(file, "unix:size,uid,gid,ShouldNotExist"); + map = Files.readAttributes(file, "unix:size,uid,gid"); assertTrue(map.size() == 3); checkEqual(map.get("size"), Files.readAttributes(file, BasicFileAttributes.class).size()); @@ -206,14 +200,65 @@ public class FileAttributes { assertTrue(map.size() >= 13); checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one - map = Files.readAttributes(file, "dos:size,hidden,ShouldNotExist"); + map = Files.readAttributes(file, "dos:size,hidden"); assertTrue(map.size() == 2); checkEqual(attrs.size(), map.get("size")); checkEqual(attrs.isHidden(), map.get("hidden")); } + static void checkBadSet(Path file, String attribute, Object value) + throws IOException + { + try { + Files.setAttribute(file, attribute, 0); + throw new RuntimeException("IllegalArgumentException expected"); + } catch (IllegalArgumentException ignore) { } + } + + static void checkBadGet(Path file, String attribute) throws IOException { + try { + Files.getAttribute(file, attribute); + throw new RuntimeException("IllegalArgumentException expected"); + } catch (IllegalArgumentException ignore) { } + } + + static void checkBadRead(Path file, String attribute) throws IOException { + try { + Files.readAttributes(file, attribute); + throw new RuntimeException("IllegalArgumentException expected"); + } catch (IllegalArgumentException ignore) { } + } + static void miscTests(Path file) throws IOException { - // NPE tests + // unsupported views + try { + Files.setAttribute(file, "foo:bar", 0); + throw new RuntimeException("UnsupportedOperationException expected"); + } catch (UnsupportedOperationException ignore) { } + try { + Files.getAttribute(file, "foo:bar"); + throw new RuntimeException("UnsupportedOperationException expected"); + } catch (UnsupportedOperationException ignore) { } + try { + Files.readAttributes(file, "foo:*"); + throw new RuntimeException("UnsupportedOperationException expected"); + } catch (UnsupportedOperationException ignore) { } + + // bad args + checkBadSet(file, "", 0); + checkBadSet(file, "basic:", 0); + checkBadSet(file, "basic:foobar", 0); + checkBadGet(file, ""); + checkBadGet(file, "basic:"); + checkBadGet(file, "basic:foobar"); + checkBadGet(file, "basic:size,lastModifiedTime"); + checkBadGet(file, "basic:*"); + checkBadRead(file, ""); + checkBadRead(file, "basic:"); + checkBadRead(file, "basic:foobar"); + checkBadRead(file, "basic:size,foobar"); + + // nulls try { Files.getAttribute(file, null); throw new RuntimeException("NullPointerException expected"); diff --git a/jdk/test/java/nio/file/WatchService/Basic.java b/jdk/test/java/nio/file/WatchService/Basic.java index 2869a519f37..1b4c526dbd8 100644 --- a/jdk/test/java/nio/file/WatchService/Basic.java +++ b/jdk/test/java/nio/file/WatchService/Basic.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6838333 + * @bug 4313887 6838333 7017446 * @summary Unit test for java.nio.file.WatchService * @library .. * @run main/timeout=120 Basic @@ -44,6 +44,8 @@ public class Basic { static void checkKey(WatchKey key, Path dir) { if (!key.isValid()) throw new RuntimeException("Key is not valid"); + if (key.watchable() != dir) + throw new RuntimeException("Unexpected watchable"); } static void takeExpectedKey(WatchService watcher, WatchKey expected) { diff --git a/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java b/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java index a6af4192234..c8c07b4d8e4 100644 --- a/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java +++ b/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java @@ -141,9 +141,6 @@ public class Basic { map = Files.readAttributes(file, "user:*"); if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME))) throw new RuntimeException("Unexpected attribute value"); - map = Files.readAttributes(file, "user:DoesNotExist"); - if (!map.isEmpty()) - throw new RuntimeException("Map expected to be empty"); } static void miscTests(final Path file) throws IOException { diff --git a/jdk/test/java/util/EnumSet/LargeEnumIteratorRemoveResilience.java b/jdk/test/java/util/EnumSet/LargeEnumIteratorRemoveResilience.java new file mode 100644 index 00000000000..7113ba24647 --- /dev/null +++ b/jdk/test/java/util/EnumSet/LargeEnumIteratorRemoveResilience.java @@ -0,0 +1,96 @@ +/* + * 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. + */ + +/* + * Portions Copyright (c) 2011 IBM Corporation + */ + +/* + * @test + * @bug 7014637 + * @summary EnumSet's iterator.remove() can be resilient to set's modification. + * @author Neil Richards , + */ + +import java.util.EnumSet; +import java.util.Iterator; +import java.util.Set; + +public class LargeEnumIteratorRemoveResilience { + // enum with more than 64 values + private static enum LargeEnum { + e00, e01, e02, e03, e04, e05, e06, e07, + e08, e09, e0A, e0B, e0C, e0D, e0E, e0F, + e10, e11, e12, e13, e14, e15, e16, e17, + e18, e19, e1A, e1B, e1C, e1D, e1E, e1F, + e20, e21, e22, e23, e24, e25, e26, e27, + e28, e29, e2A, e2B, e2C, e2D, e2E, e2F, + e30, e31, e32, e33, e34, e35, e36, e37, + e38, e39, e3A, e3B, e3C, e3D, e3E, e3F, + e40, e41, e42, e43, e44, e45, e46, e47, + e48, e49, e4A, e4B, e4C, e4D, e4E, e4F, + } + + public static void main(final String[] args) throws Exception { + final Set set = EnumSet.noneOf(LargeEnum.class); + + set.add(LargeEnum.e2D); + set.add(LargeEnum.e42); + + final Iterator iterator = set.iterator(); + + int size = set.size(); + LargeEnum element = iterator.next(); + + iterator.remove(); + checkSetAfterRemoval(set, size, element); + + size = set.size(); + element = iterator.next(); + + set.remove(element); + checkSetAfterRemoval(set, size, element); + + // The Java API declares that the behaviour here - to call + // iterator.remove() after the underlying collection has been + // modified - is "unspecified". + // However, in the case of iterators for EnumSet, it is easy to + // implement their remove() operation such that the set is + // unmodified if it is called for an element that has already been + // removed from the set - this being the naturally "resilient" + // behaviour. + iterator.remove(); + checkSetAfterRemoval(set, size, element); + } + + private static void checkSetAfterRemoval(final Set set, + final int origSize, final LargeEnum removedElement) + throws Exception { + if (set.size() != (origSize - 1)) { + throw new Exception("Test FAILED: Unexpected set size after removal; expected '" + (origSize - 1) + "' but found '" + set.size() + "'"); + } + if (set.contains(removedElement)) { + throw new Exception("Test FAILED: Element returned from iterator unexpectedly still in set after removal."); + } + } +} diff --git a/jdk/test/java/util/EnumSet/SmallEnumIteratorRemoveResilience.java b/jdk/test/java/util/EnumSet/SmallEnumIteratorRemoveResilience.java new file mode 100644 index 00000000000..e813a5cad3f --- /dev/null +++ b/jdk/test/java/util/EnumSet/SmallEnumIteratorRemoveResilience.java @@ -0,0 +1,85 @@ +/* + * 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. + */ + +/* + * Portions Copyright (c) 2011 IBM Corporation + */ + +/* + * @test + * @bug 7014637 + * @summary EnumSet's iterator.remove() can be resilient to set's modification. + * @author Neil Richards , + */ + +import java.util.EnumSet; +import java.util.Iterator; +import java.util.Set; + +public class SmallEnumIteratorRemoveResilience { + // enum with less than 64 values + private static enum SmallEnum { e0, e1, e2 } + + public static void main(final String[] args) throws Exception { + final Set set = EnumSet.noneOf(SmallEnum.class); + + set.add(SmallEnum.e0); + set.add(SmallEnum.e1); + + final Iterator iterator = set.iterator(); + + int size = set.size(); + SmallEnum element = iterator.next(); + + iterator.remove(); + checkSetAfterRemoval(set, size, element); + + size = set.size(); + element = iterator.next(); + + set.remove(element); + checkSetAfterRemoval(set, size, element); + + // The Java API declares that the behaviour here - to call + // iterator.remove() after the underlying collection has been + // modified - is "unspecified". + // However, in the case of iterators for EnumSet, it is easy to + // implement their remove() operation such that the set is + // unmodified if it is called for an element that has already been + // removed from the set - this being the naturally "resilient" + // behaviour. + iterator.remove(); + checkSetAfterRemoval(set, size, element); + } + + private static void checkSetAfterRemoval(final Set set, + final int origSize, final SmallEnum removedElement) + throws Exception { + if (set.size() != (origSize - 1)) { + throw new Exception("Test FAILED: Unexpected set size after removal; expected '" + (origSize - 1) + "' but found '" + set.size() + "'"); + } + if (set.contains(removedElement)) { + throw new Exception("Test FAILED: Element returned from iterator unexpectedly still in set after removal."); + } + } +} diff --git a/jdk/test/java/util/Locale/LocaleEnhanceTest.java b/jdk/test/java/util/Locale/LocaleEnhanceTest.java index 0ee6ed24dca..23445d5afc0 100644 --- a/jdk/test/java/util/Locale/LocaleEnhanceTest.java +++ b/jdk/test/java/util/Locale/LocaleEnhanceTest.java @@ -43,7 +43,7 @@ import java.util.Set; /** * @test - * @bug 6875847 + * @bug 6875847 6992272 7002320 7015500 7023613 * @summary test API changes to Locale */ public class LocaleEnhanceTest extends LocaleTestFmwk { @@ -83,7 +83,7 @@ public class LocaleEnhanceTest extends LocaleTestFmwk { "en-Latn-US-NewYork", "en_US_NewYork_#Latn", "en-Latn-US", "en_US_#Latn", "en-Latn-NewYork", "en__NewYork_#Latn", // double underscore - "en-Latn", "en_#Latn", + "en-Latn", "en__#Latn", // double underscore "en-US-NewYork", "en_US_NewYork", "en-US", "en_US", "en-NewYork", "en__NewYork", // double underscore @@ -1259,6 +1259,22 @@ public class LocaleEnhanceTest extends LocaleTestFmwk { } } + public void testBug7023613() { + String[][] testdata = { + {"en-Latn", "en__#Latn"}, + {"en-u-ca-japanese", "en__#u-ca-japanese"}, + }; + + for (String[] data : testdata) { + String in = data[0]; + String expected = (data.length == 1) ? data[0] : data[1]; + + Locale loc = Locale.forLanguageTag(in); + String out = loc.toString(); + assertEquals("Empty country field with non-empty script/extension with input: " + in, expected, out); + } + } + /// /// utility asserts /// diff --git a/jdk/test/java/util/TreeMap/EmptyMapAndNulls.java b/jdk/test/java/util/TreeMap/EmptyMapAndNulls.java new file mode 100644 index 00000000000..1642f74f1bc --- /dev/null +++ b/jdk/test/java/util/TreeMap/EmptyMapAndNulls.java @@ -0,0 +1,120 @@ +/* + * 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 5045147 + * @summary Test handling of null with empty Map + * @author Mike Duigou + */ + +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; +import java.lang.reflect.*; + +public class EmptyMapAndNulls { + + @SuppressWarnings("rawtypes") + static void realMain(String[] args) throws Throwable { + // No comparator + Map comparable = new TreeMap<>(); + + // insert null into empty map (5045147 failure) + try { + comparable.put(null, "anything"); + fail("null shouldn't be accepted"); + } catch (NullPointerException failed) { + pass(); + } + + // insert non-null into empty map + try { + comparable.put("test", "anything"); + pass(); + } catch (NullPointerException failed) { + fail(); + } + + // insert null into non-empty map + try { + comparable.put(null, "anything"); + fail("null shouldn't be accepted"); + } catch (NullPointerException failed) { + pass(); + } + + // Comparator (String.CASE_INSENSITIVE_ORDER). Intentionally a raw type. + Map comparator = new TreeMap(String.CASE_INSENSITIVE_ORDER); + + // insert null into empty map (5045147 failure) + try { + comparator.put(null, "anything"); + fail("null shouldn't be accepted"); + } catch (NullPointerException failed) { + pass(); + } + + // insert non-null into empty map + try { + comparator.put("test", "anything"); + pass(); + } catch (NullPointerException failed) { + fail(); + } + + // insert null into non-empty map + try { + comparator.put(null, "anything"); + fail("null shouldn't be accepted"); + } catch (NullPointerException failed) { + pass(); + } + + comparator.clear(); + + // insert non-String into empty map (5045147 failure) + try { + comparator.put(new Object(), "anything"); + fail("Object shouldn't be accepted"); + } catch (ClassCastException failed) { + pass(); + } + + } + + //--------------------- Infrastructure --------------------------- + static volatile int passed = 0, failed = 0; + static void pass() {passed++;} + static void fail() {failed++; Thread.dumpStack();} + static void fail(String msg) {System.out.println(msg); fail();} + static void unexpected(Throwable t) {failed++; t.printStackTrace();} + static void check(boolean cond) {if (cond) pass(); else fail();} + static void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + try {realMain(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} diff --git a/jdk/test/javax/script/GetInterfaceTest.java b/jdk/test/javax/script/GetInterfaceTest.java new file mode 100644 index 00000000000..d780a6db08b --- /dev/null +++ b/jdk/test/javax/script/GetInterfaceTest.java @@ -0,0 +1,77 @@ +/* + * 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 6960211 + * @summary JavaScript engine allows creation of interface although methods not available. + */ + +import javax.script.*; + +public class GetInterfaceTest { + public static void main(String[] args) throws Exception { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("js"); + + if (engine == null) { + System.out.println("Warning: No engine engine found; test vacuously passes."); + return; + } + + // don't define any function. + engine.eval(""); + + Runnable runnable = ((Invocable)engine).getInterface(Runnable.class); + if (runnable != null) { + throw new RuntimeException("runnable is not null!"); + } + + // now define "run" + engine.eval("function run() { println('this is run function'); }"); + runnable = ((Invocable)engine).getInterface(Runnable.class); + // should not return null now! + runnable.run(); + + // define only one method of "Foo2" + engine.eval("function bar() { println('bar function'); }"); + Foo2 foo2 = ((Invocable)engine).getInterface(Foo2.class); + if (foo2 != null) { + throw new RuntimeException("foo2 is not null!"); + } + + // now define other method of "Foo2" + engine.eval("function bar2() { println('bar2 function'); }"); + foo2 = ((Invocable)engine).getInterface(Foo2.class); + foo2.bar(); + foo2.bar2(); + } + + interface Foo { + public void bar(); + } + + interface Foo2 extends Foo { + public void bar2(); + } +} diff --git a/jdk/test/javax/swing/JOptionPane/6464022/bug6464022.java b/jdk/test/javax/swing/JOptionPane/6464022/bug6464022.java new file mode 100644 index 00000000000..9554ae9828e --- /dev/null +++ b/jdk/test/javax/swing/JOptionPane/6464022/bug6464022.java @@ -0,0 +1,83 @@ +/* + * 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 6464022 + * @summary Memory leak in JOptionPane.createDialog + * @author Pavel Porvatov + * @library ../../regtesthelpers + * @build Util + * @run main bug6464022 + */ + +import javax.swing.*; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +public class bug6464022 { + private static JOptionPane pane; + + public static void main(String[] args) throws Exception { + final List> references = new ArrayList>(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + pane = new JOptionPane(null, JOptionPane.UNDEFINED_CONDITION); + + for (int i = 0; i < 10; i++) { + JDialog dialog = pane.createDialog(null, "Test " + i); + + references.add(new WeakReference(dialog)); + + dialog.dispose(); + + System.out.println("Disposing Dialog:" + dialog.hashCode()); + } + } + }); + + Util.generateOOME(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + int allocatedCount = 0; + + for (WeakReference ref : references) { + if (ref.get() != null) { + allocatedCount++; + + System.out.println(ref.get().hashCode() + " is still allocated"); + } + } + + if (allocatedCount > 0) { + throw new RuntimeException("Some dialogs still exist in memory. Test failed"); + } else { + System.out.println("All dialogs were GCed. Test passed."); + } + } + }); + } +} diff --git a/jdk/test/javax/swing/UIDefaults/6795356/bug6795356.java b/jdk/test/javax/swing/UIDefaults/6795356/bug6795356.java index 781f57d3872..698dc00e22f 100644 --- a/jdk/test/javax/swing/UIDefaults/6795356/bug6795356.java +++ b/jdk/test/javax/swing/UIDefaults/6795356/bug6795356.java @@ -26,6 +26,8 @@ * @bug 6795356 * @summary Leak caused by javax.swing.UIDefaults.ProxyLazyValue.acc * @author Alexander Potochkin + * @library ../../regtesthelpers + * @build Util * @run main bug6795356 */ @@ -58,43 +60,11 @@ public class bug6795356 { weakRef = new WeakReference(domain); domain = null; - // Generate OutOfMemory and check the weak ref - generateOOME(); + Util.generateOOME(); if (weakRef.get() != null) { throw new RuntimeException("Memory leak found!"); } System.out.println("Test passed"); } - - static void generateOOME() { - List bigLeak = new LinkedList(); - boolean oome = false; - System.out.print("Filling the heap"); - try { - for(int i = 0; true ; i++) { - // Now, use up all RAM - bigLeak.add(new byte[1024 * 1024]); - System.out.print("."); - - // Give the GC a change at that weakref - if (i % 10 == 0) { - System.gc(); - try { - Thread.sleep(100); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - } catch (OutOfMemoryError e) { - bigLeak = null; - oome = true; - } - System.out.println(""); - if (!oome) { - throw new RuntimeException("Problem with test case - never got OOME"); - } - System.out.println("Got OOME"); - } } diff --git a/jdk/test/javax/swing/regtesthelpers/Util.java b/jdk/test/javax/swing/regtesthelpers/Util.java index 5da14b9396a..76217ae8687 100644 --- a/jdk/test/javax/swing/regtesthelpers/Util.java +++ b/jdk/test/javax/swing/regtesthelpers/Util.java @@ -24,6 +24,8 @@ import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; +import java.util.LinkedList; +import java.util.List; /** *

    This class contains utilities useful for regression testing. @@ -72,4 +74,46 @@ public class Util { return true; } + + /** + * Fills the heap until OutOfMemoryError occurs. This method is useful for + * WeakReferences removing. + */ + public static void generateOOME() { + List bigLeak = new LinkedList(); + + boolean oome = false; + + System.out.print("Filling the heap"); + + try { + for(int i = 0; true ; i++) { + // Now, use up all RAM + bigLeak.add(new byte[1024 * 1024]); + + System.out.print("."); + + // Give the GC a change at that weakref + if (i % 10 == 0) { + System.gc(); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } catch (OutOfMemoryError e) { + bigLeak = null; + oome = true; + } + + System.out.println(""); + + if (!oome) { + throw new RuntimeException("Problem with test case - never got OOME"); + } + + System.out.println("Got OOME"); + } } diff --git a/jdk/test/sun/java2d/pipe/Test7027667.java b/jdk/test/sun/java2d/pipe/Test7027667.java new file mode 100644 index 00000000000..08f478f60b1 --- /dev/null +++ b/jdk/test/sun/java2d/pipe/Test7027667.java @@ -0,0 +1,49 @@ +/* + * 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 7027667, 7023591 + * + * @summary Verifies that aa clipped rectangles are drawn, not filled. + * + * @run main Test7027667 + */ + +import java.awt.*; +import java.awt.geom.*; +import java.awt.image.*; +import static java.awt.RenderingHints.*; + +public class Test7027667 { + public static void main(String[] args) throws Exception { + BufferedImage bImg = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = (Graphics2D) bImg.getGraphics(); + g2d.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON); + g2d.setClip(new Ellipse2D.Double(0, 0, 100, 100)); + g2d.drawRect(10, 10, 100, 100); + if (new Color(bImg.getRGB(50, 50)).equals(Color.white)) { + throw new Exception("Rectangle should be drawn, not filled"); + } + } +} diff --git a/jdk/test/sun/java2d/pisces/Renderer/Test7019861.java b/jdk/test/sun/java2d/pisces/Renderer/Test7019861.java new file mode 100644 index 00000000000..7c262b961cf --- /dev/null +++ b/jdk/test/sun/java2d/pisces/Renderer/Test7019861.java @@ -0,0 +1,76 @@ +/* + * 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 7019861 + * + * @summary Verifies that the last scanline isn't skipped when doing + * antialiased rendering. + * + * @run main Test7019861 + */ + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Path2D; +import java.awt.image.BufferedImage; +import java.util.Arrays; + +import static java.awt.RenderingHints.*; + +public class Test7019861 { + + public static void main(String[] argv) throws Exception { + BufferedImage im = getWhiteImage(30, 30); + Graphics2D g2 = (Graphics2D)im.getGraphics(); + g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON); + g2.setRenderingHint(KEY_STROKE_CONTROL, VALUE_STROKE_PURE); + g2.setStroke(new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + g2.setBackground(Color.white); + g2.setColor(Color.black); + + Path2D p = getPath(0, 0, 20); + g2.draw(p); + + if (!(new Color(im.getRGB(20, 19))).equals(Color.black)) { + throw new Exception("This pixel should be black"); + } + } + + private static Path2D getPath(int x, int y, int len) { + Path2D p = new Path2D.Double(); + p.moveTo(x, y); + p.quadTo(x + len, y, x + len, y + len); + return p; + } + + private static BufferedImage getWhiteImage(int w, int h) { + BufferedImage ret = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + final int[] white = new int[w * h]; + Arrays.fill(white, 0xffffff); + ret.setRGB(0, 0, w, h, white, 0, w); + return ret; + } +} diff --git a/jdk/test/sun/nio/cs/TestIBM1364.java b/jdk/test/sun/nio/cs/TestIBM1364.java new file mode 100644 index 00000000000..78912bdf519 --- /dev/null +++ b/jdk/test/sun/nio/cs/TestIBM1364.java @@ -0,0 +1,209 @@ +/* + * 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 6803681 + @summary Test IBM1364 + */ + +import java.util.Arrays; +import java.nio.*; +import java.nio.charset.*; + +public class TestIBM1364 { + private static String c2bNRStr = "\u00AD\u00B7\u2015\u223C\u2299\uFF5E"; + private static byte[] c2bNRBytes = new byte[] { + (byte)0x0e, + (byte)0x41, (byte)0x48, + (byte)0x41, (byte)0x43, + (byte)0x41, (byte)0x49, + (byte)0x42, (byte)0xa1, + (byte)0x49, (byte)0x6f, + (byte)0x49, (byte)0x54, + (byte)0x0f }; + + // end at SO + private static String mixedStr = "\u008d\u008e\u0020\u3000\u3001\u71ba\u3164\u0088\ue757"; + private static byte[] mixedBytes = new byte[] { + (byte)0x09, + (byte)0x0a, + (byte)0x40, + (byte)0x0e, + (byte)0x40, (byte)0x40, + (byte)0x41, (byte)0x41, + (byte)0x6c, (byte)0x45, + (byte)0x84, (byte)0x41, + (byte)0x0f, + (byte)0x28, + (byte)0x0e, + (byte)0xdd, (byte)0xfd, + (byte)0x0f }; + + // end at SI + private static String mixedStr2 = "\u008d\u008e\u0020\u3000\u3001\u71ba\u3164\u0088"; + private static byte[] mixedBytes2 = new byte[] { + (byte)0x09, + (byte)0x0a, + (byte)0x40, + (byte)0x0e, + (byte)0x40, (byte)0x40, + (byte)0x41, (byte)0x41, + (byte)0x6c, (byte)0x45, + (byte)0x84, (byte)0x41, + (byte)0x0f, + (byte)0x28 }; + + private static byte[][] malformedBytes = { + { (byte)0x0e, + (byte)0x039, (byte)0x40, + (byte)0x0f + }, + { (byte)0x0e, + (byte)0x039, (byte)0x42, + (byte)0x0f + }, + { (byte)0x0e, + (byte)0x040, (byte)0x41, + (byte)0x0f + }, + { (byte)0x0e, + (byte)0x040, (byte)0xee, + (byte)0x0f + }, + { (byte)0x0e, + (byte)0x0ef, (byte)0x30, + (byte)0x0f + }, + { (byte)0x0e, + (byte)0x0ff, (byte)0x41, + (byte)0x0f + } + }; + + private static byte[][] unmappedBytes = { + { (byte)0x0e, + (byte)0x06c, (byte)0x46, + (byte)0x0f, + }, + { (byte)0x0e, + (byte)0x078, (byte)0x46, + (byte)0x0f, + }, + { (byte)0x0e, + (byte)0x083, (byte)0xfe, + (byte)0x0f, + }, + { (byte)0xfa }, + { (byte)0xfe }, + }; + + public static void main(String[] args) throws Exception { + if (!(Arrays.equals(mixedStr.getBytes("cp1364"), mixedBytes)) || + !mixedStr.equals(new String(mixedBytes, "cp1364"))) + throw new RuntimeException("cp1364 failed on mixed!"); + + if (!(Arrays.equals(mixedStr2.getBytes("cp1364"), mixedBytes2)) || + !mixedStr2.equals(new String(mixedBytes2, "cp1364"))) + throw new RuntimeException("cp1364 failed on mixed!"); + + if (!(Arrays.equals(c2bNRStr.getBytes("cp1364"), c2bNRBytes)) || + c2bNRStr.equals(new String(c2bNRBytes, "cp1364"))) + throw new RuntimeException("cp1364 failed on c2bNR!"); + + ByteBuffer bb = ByteBuffer.allocateDirect(mixedBytes.length); + bb.put(mixedBytes).flip(); + CharBuffer cb = Charset.forName("ibm1364").decode(bb); + if (!mixedStr.equals(new String(cb.toString()))) + throw new RuntimeException("cp1364 failed on direct decod()!"); + + bb = ByteBuffer.allocateDirect(mixedBytes2.length); + bb.put(mixedBytes2).flip(); + cb = Charset.forName("ibm1364").decode(bb); + if (!mixedStr2.equals(new String(cb.toString()))) + throw new RuntimeException("cp1364 failed on direct decod()!"); + + cb = ByteBuffer.allocateDirect(mixedStr.length() * 2).asCharBuffer(); + cb.put(mixedStr.toCharArray()).flip(); + bb = Charset.forName("x-ibm1364").encode(cb); + if (!(Arrays.equals(Arrays.copyOf(bb.array(), bb.limit()), mixedBytes))) + throw new RuntimeException("cp1364 failed on direct encode()!"); + + cb = ByteBuffer.allocateDirect(mixedStr2.length() * 2).asCharBuffer(); + cb.put(mixedStr2.toCharArray()).flip(); + bb = Charset.forName("x-ibm1364").encode(cb); + if (!(Arrays.equals(Arrays.copyOf(bb.array(), bb.limit()), mixedBytes2))) + throw new RuntimeException("cp1364 failed on direct encode()!"); + + // malformed + cb = CharBuffer.allocate(1024); + CharBuffer cbd = ByteBuffer.allocateDirect(1024).asCharBuffer(); + CharsetDecoder dec = Charset.forName("x-ibm1364").newDecoder(); + for (byte[] ba:malformedBytes) { + cb.clear(); + dec.reset(); + if (!dec.reset().decode(ByteBuffer.wrap(ba), cb, true).isMalformed() || + !dec.reset().decode(ByteBuffer.wrap(ba), cbd, true).isMalformed()) + throw new RuntimeException("cp1364 failed on decode()/malformed!"); + } + + //unmappable + for (byte[] ba:unmappedBytes) { + cb.clear(); + dec.reset(); + if (!dec.reset().decode(ByteBuffer.wrap(ba), cb, true).isUnmappable() || + !dec.reset().decode(ByteBuffer.wrap(ba), cbd, true).isUnmappable()) + throw new RuntimeException("cp1364 failed on decode()/unmappable!"); + } + + //overflow + cb.limit(mixedStr.length() - 1); + cbd.limit(mixedStr.length() - 1); + if (!dec.reset().decode(ByteBuffer.wrap(mixedBytes), cb, true).isOverflow() || + !dec.reset().decode(ByteBuffer.wrap(mixedBytes), cbd, true).isOverflow()) + throw new RuntimeException("cp1364 failed on decode()/overflow!"); + + CharsetEncoder enc = Charset.forName("x-ibm1364").newEncoder(); + // last "0x0f" is from flush() + bb = ByteBuffer.allocate(mixedBytes.length - 2); + ByteBuffer bbd = ByteBuffer.allocateDirect(mixedBytes.length - 2); + if (!enc.reset() + .encode(CharBuffer.wrap(mixedStr.toCharArray()), bb, true) + .isOverflow() || + !enc.reset() + .encode(CharBuffer.wrap(mixedStr.toCharArray()), bbd, true) + .isOverflow()) + throw new RuntimeException("cp1364 failed on encode()/overflow!"); + + // flush() overflow + bb = ByteBuffer.allocate(mixedBytes.length - 1); + bbd = ByteBuffer.allocateDirect(mixedBytes.length - 1); + + enc.reset().encode(CharBuffer.wrap(mixedStr.toCharArray()), bb, true); + enc.reset().encode(CharBuffer.wrap(mixedStr.toCharArray()), bbd, true); + + if (!enc.flush(bb).isOverflow() || + !enc.flush(bbd).isOverflow()) + throw new RuntimeException("cp1364 failed on encode()/flush()/overflow!"); + } +} diff --git a/jdk/test/sun/security/mscapi/access.policy b/jdk/test/sun/security/mscapi/access.policy index 27e6692027c..22bf290bd8f 100644 --- a/jdk/test/sun/security/mscapi/access.policy +++ b/jdk/test/sun/security/mscapi/access.policy @@ -3,7 +3,7 @@ grant { permission java.lang.RuntimePermission "accessClassInPackage.sun.*"; - permission java.lang.RuntimePermission "loadLibrary.sunmscapi"; + permission java.lang.RuntimePermission "loadLibrary.*"; permission java.util.PropertyPermission "os.arch", "read"; diff --git a/jdk/test/sun/security/mscapi/noaccess.policy b/jdk/test/sun/security/mscapi/noaccess.policy index 8cda681cfed..e4260cf5070 100644 --- a/jdk/test/sun/security/mscapi/noaccess.policy +++ b/jdk/test/sun/security/mscapi/noaccess.policy @@ -3,7 +3,7 @@ grant { permission java.lang.RuntimePermission "accessClassInPackage.sun.*"; - permission java.lang.RuntimePermission "loadLibrary.sunmscapi"; + permission java.lang.RuntimePermission "loadLibrary.*"; permission java.util.PropertyPermission "os.arch", "read"; diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/GetInstance.java b/jdk/test/sun/security/ssl/javax/net/ssl/GetInstance.java index dcfb98b48c4..2ffdad9ac02 100644 --- a/jdk/test/sun/security/ssl/javax/net/ssl/GetInstance.java +++ b/jdk/test/sun/security/ssl/javax/net/ssl/GetInstance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -23,8 +23,9 @@ /* * @test - * @bug 4898428 + * @bug 4898428 7022855 * @summary verify getInstance() works using Provider.getService() + * Export "PKIX" as the standard algorithm name of KeyManagerFactory * @author Andreas Sterbenz */ @@ -61,6 +62,20 @@ public class GetInstance { kmf = KeyManagerFactory.getInstance("SunX509", p); same(p, kmf.getProvider()); + kmf = KeyManagerFactory.getInstance("NewSunX509"); + same(p, kmf.getProvider()); + kmf = KeyManagerFactory.getInstance("NewSunX509", "SunJSSE"); + same(p, kmf.getProvider()); + kmf = KeyManagerFactory.getInstance("NewSunX509", p); + same(p, kmf.getProvider()); + + kmf = KeyManagerFactory.getInstance("PKIX"); + same(p, kmf.getProvider()); + kmf = KeyManagerFactory.getInstance("PKIX", "SunJSSE"); + same(p, kmf.getProvider()); + kmf = KeyManagerFactory.getInstance("PKIX", p); + same(p, kmf.getProvider()); + TrustManagerFactory tmf; tmf = TrustManagerFactory.getInstance("SunX509"); same(p, tmf.getProvider()); @@ -69,6 +84,34 @@ public class GetInstance { tmf = TrustManagerFactory.getInstance("SunX509", p); same(p, tmf.getProvider()); + tmf = TrustManagerFactory.getInstance("PKIX"); + same(p, tmf.getProvider()); + tmf = TrustManagerFactory.getInstance("PKIX", "SunJSSE"); + same(p, tmf.getProvider()); + tmf = TrustManagerFactory.getInstance("PKIX", p); + same(p, tmf.getProvider()); + + tmf = TrustManagerFactory.getInstance("SunPKIX"); + same(p, tmf.getProvider()); + tmf = TrustManagerFactory.getInstance("SunPKIX", "SunJSSE"); + same(p, tmf.getProvider()); + tmf = TrustManagerFactory.getInstance("SunPKIX", p); + same(p, tmf.getProvider()); + + tmf = TrustManagerFactory.getInstance("X509"); + same(p, tmf.getProvider()); + tmf = TrustManagerFactory.getInstance("X509", "SunJSSE"); + same(p, tmf.getProvider()); + tmf = TrustManagerFactory.getInstance("X509", p); + same(p, tmf.getProvider()); + + tmf = TrustManagerFactory.getInstance("X.509"); + same(p, tmf.getProvider()); + tmf = TrustManagerFactory.getInstance("X.509", "SunJSSE"); + same(p, tmf.getProvider()); + tmf = TrustManagerFactory.getInstance("X.509", p); + same(p, tmf.getProvider()); + testComSun(); long stop = System.currentTimeMillis(); diff --git a/jdk/test/sun/text/resources/LocaleData b/jdk/test/sun/text/resources/LocaleData index 090b73c8d12..0f538113beb 100644 --- a/jdk/test/sun/text/resources/LocaleData +++ b/jdk/test/sun/text/resources/LocaleData @@ -6101,3 +6101,348 @@ LocaleNames/nl/ZM=Zambia # bug 6919624 CalendarData/hu/minimalDaysInFirstWeek=4 + +# bug 6998391 +CalendarData/sr-Latn/firstDayOfWeek=2 +CalendarData/sr-Latn-BA/firstDayOfWeek=2 +CalendarData/sr-Latn-ME/firstDayOfWeek=2 +CalendarData/sr-Latn-RS/firstDayOfWeek=2 +# +CalendarData/sr-Latn/minimalDaysInFirstWeek=1 +CalendarData/sr-Latn-BA/minimalDaysInFirstWeek=4 +CalendarData/sr-Latn-ME/minimalDaysInFirstWeek=4 +CalendarData/sr-Latn-RS/minimalDaysInFirstWeek=4 +# +LocaleNames/sr-Latn/SR=Surinam +LocaleNames/sr-Latn-BA/SR=Surinam +LocaleNames/sr-Latn-ME/SR=Surinam +LocaleNames/sr-Latn-RS/SR=Surinam +# +FormatData/sr-Latn/MonthNames/2=mart +FormatData/sr-Latn-BA/MonthNames/4=maj +FormatData/sr-Latn-ME/MonthNames/7=avgust +FormatData/sr-Latn-RS/MonthNames/8=septembar +# +FormatData/sr-Latn/DayNames/1=ponedeljak +FormatData/sr-Latn-BA/DayNames/2=utorak +FormatData/sr-Latn-ME/DayNames/3=sreda +FormatData/sr-Latn-RS/DayNames/4=\u010detvrtak +# +FormatData/sr-Latn/DayAbbreviations/1=pon +FormatData/sr-Latn-BA/DayAbbreviations/2=uto +FormatData/sr-Latn-ME/DayAbbreviations/3=sre +FormatData/sr-Latn-RS/DayAbbreviations/4=\u010det +# +CurrencyNames/sr-Latn/EUR=EUR +CurrencyNames/sr-Latn-BA/EUR=\u20ac +CurrencyNames/sr-Latn-BA/BAM=KM +CurrencyNames/sr-Latn-ME/EUR=\u20ac +CurrencyNames/sr-Latn-RS/EUR=EUR +# +FormatData/sr-Latn/DateTimePatterns/1=HH.mm.ss z +FormatData/sr-Latn-BA/DateTimePatterns/2=HH.mm.ss +FormatData/sr-Latn-ME/DateTimePatterns/5=d.MM.yyyy. +FormatData/sr-Latn-RS/DateTimePatterns/5=dd. MMMM y. + +# bug 7019267 +CurrencyNames/pt/adp=Peseta de Andorra +CurrencyNames/pt/aed=Dir\u00e9m dos Emirados \u00c1rabes Unidos +CurrencyNames/pt/afa=Afegane (1927-2002) +CurrencyNames/pt/afn=Afegane +CurrencyNames/pt/all=Lek Alban\u00eas +CurrencyNames/pt/amd=Dram arm\u00eanio +CurrencyNames/pt/ang=Guilder das Antilhas Holandesas +CurrencyNames/pt/aoa=Cuanza angolano +CurrencyNames/pt/ars=Peso argentino +CurrencyNames/pt/ats=Xelim austr\u00edaco +CurrencyNames/pt/aud=D\u00f3lar australiano +CurrencyNames/pt/awg=Guilder de Aruba +CurrencyNames/pt/azm=Manat azerbaijano +CurrencyNames/pt/azn=Manat do Azerbaij\u00e3o +CurrencyNames/pt/bam=Marco b\u00f3snio-herzegovino convers\u00edvel +CurrencyNames/pt/bbd=D\u00f3lar de Barbados +CurrencyNames/pt/bdt=Taka de Bangladesh +CurrencyNames/pt/bef=Franco belga +CurrencyNames/pt/bgl=Lev forte b\u00falgaro +CurrencyNames/pt/bgn=Lev novo b\u00falgaro +CurrencyNames/pt/bhd=Dinar bareinita +CurrencyNames/pt/bif=Franco do Burundi +CurrencyNames/pt/bmd=D\u00f3lar das Bermudas +CurrencyNames/pt/bnd=D\u00f3lar do Brunei +CurrencyNames/pt/bov=Mvdol boliviano +CurrencyNames/pt/brl=Real brasileiro +CurrencyNames/pt/bsd=D\u00f3lar das Bahamas +CurrencyNames/pt/btn=Ngultrum do But\u00e3o +CurrencyNames/pt/bwp=Pula botsuanesa +CurrencyNames/pt/byb=Rublo novo bielo-russo (1994-1999) +CurrencyNames/pt/byr=Rublo bielo-russo +CurrencyNames/pt/bzd=D\u00f3lar do Belize +CurrencyNames/pt/cad=D\u00f3lar canadense +CurrencyNames/pt/cdf=Franco congol\u00eas +CurrencyNames/pt/chf=Franco su\u00ed\u00e7o +CurrencyNames/pt/clf=Unidades de Fomento chilenas +CurrencyNames/pt/clp=Peso chileno +CurrencyNames/pt/cny=Yuan Renminbi chin\u00eas +CurrencyNames/pt/cop=Peso colombiano +CurrencyNames/pt/crc=Colon da Costa Rica +CurrencyNames/pt/csd=Dinar s\u00e9rvio antigo +CurrencyNames/pt/cup=Peso cubano +CurrencyNames/pt/cve=Escudo cabo-verdiano +CurrencyNames/pt/cyp=Libra cipriota +CurrencyNames/pt/czk=Coroa checa +CurrencyNames/pt/dem=Marco alem\u00e3o +CurrencyNames/pt/djf=Franco do Djibuti +CurrencyNames/pt/dkk=Coroa dinamarquesa +CurrencyNames/pt/dop=Peso dominicano +CurrencyNames/pt/dzd=Dinar argelino +CurrencyNames/pt/eek=Coroa estoniana +CurrencyNames/pt/egp=Libra eg\u00edpcia +CurrencyNames/pt/ern=Nakfa da Eritreia +CurrencyNames/pt/esp=Peseta espanhola +CurrencyNames/pt/etb=Birr et\u00edope +CurrencyNames/pt/fim=Marca finlandesa +CurrencyNames/pt/fjd=D\u00f3lar de Fiji +CurrencyNames/pt/fkp=Libra das Malvinas +CurrencyNames/pt/frf=Franco franc\u00eas +CurrencyNames/pt/gbp=Libra esterlina brit\u00e2nica +CurrencyNames/pt/gel=Lari georgiano +CurrencyNames/pt/ghc=Cedi de Gana (1979-2007) +CurrencyNames/pt/ghs=Cedi gan\u00eas +CurrencyNames/pt/gip=Libra de Gibraltar +CurrencyNames/pt/gmd=Dalasi de G\u00e2mbia +CurrencyNames/pt/gnf=Franco de Guin\u00e9 +CurrencyNames/pt/grd=Dracma grego +CurrencyNames/pt/gtq=Quet\u00e7al da Guatemala +CurrencyNames/pt/gwp=Peso da Guin\u00e9-Bissau +CurrencyNames/pt/gyd=D\u00f3lar da Guiana +CurrencyNames/pt/hkd=D\u00f3lar de Hong Kong +CurrencyNames/pt/hnl=Lempira de Honduras +CurrencyNames/pt/hrk=Kuna croata +CurrencyNames/pt/htg=Gurde do Haiti +CurrencyNames/pt/huf=Forinte h\u00fangaro +CurrencyNames/pt/idr=Rupia indon\u00e9sia +CurrencyNames/pt/iep=Libra irlandesa +CurrencyNames/pt/ils=Sheqel Novo israelita +CurrencyNames/pt/inr=R\u00fapia indiana +CurrencyNames/pt/iqd=Dinar iraquiano +CurrencyNames/pt/irr=Rial iraniano +CurrencyNames/pt/isk=Coroa islandesa +CurrencyNames/pt/itl=Lira italiana +CurrencyNames/pt/jmd=D\u00f3lar jamaicano +CurrencyNames/pt/jod=Dinar jordaniano +CurrencyNames/pt/jpy=Iene japon\u00eas +CurrencyNames/pt/kes=Xelim queniano +CurrencyNames/pt/kgs=Som quirguiz +CurrencyNames/pt/khr=Riel cambojano +CurrencyNames/pt/kmf=Franco de Comores +CurrencyNames/pt/kpw=Won norte-coreano +CurrencyNames/pt/krw=Won sul-coreano +CurrencyNames/pt/kwd=Dinar coveitiano +CurrencyNames/pt/kyd=D\u00f3lar das Ilhas Caiman +CurrencyNames/pt/kzt=Tenge do Cazaquist\u00e3o +CurrencyNames/pt/lak=Kip de Laos +CurrencyNames/pt/lbp=Libra libanesa +CurrencyNames/pt/lkr=Rupia do Sri Lanka +CurrencyNames/pt/lrd=D\u00f3lar liberiano +CurrencyNames/pt/lsl=Loti do Lesoto +CurrencyNames/pt/ltl=Lita lituano +CurrencyNames/pt/luf=Franco luxemburgu\u00eas +CurrencyNames/pt/lvl=Lats let\u00e3o +CurrencyNames/pt/lyd=Dinar l\u00edbio +CurrencyNames/pt/mad=Dir\u00e9m marroquino +CurrencyNames/pt/mdl=Leu mold\u00e1vio +CurrencyNames/pt/mga=Ariary de Madagascar +CurrencyNames/pt/mgf=Franco de Madagascar +CurrencyNames/pt/mkd=Dinar maced\u00f4nio +CurrencyNames/pt/mmk=Kyat de Mianmar +CurrencyNames/pt/mnt=Tugrik mongol +CurrencyNames/pt/mop=Pataca macaense +CurrencyNames/pt/mro=Ouguiya da Maurit\u00e2nia +CurrencyNames/pt/mtl=Lira maltesa +CurrencyNames/pt/mur=Rupia de Maur\u00edcio +CurrencyNames/pt/mvr=Rupias das Ilhas Maldivas +CurrencyNames/pt/mwk=Cuacha do Mal\u00e1ui +CurrencyNames/pt/mxn=Peso mexicano +CurrencyNames/pt/mxv=Unidade Mexicana de Investimento (UDI) +CurrencyNames/pt/myr=Ringgit malaio +CurrencyNames/pt/mzm=Metical antigo de Mo\u00e7ambique +CurrencyNames/pt/mzn=Metical do Mo\u00e7ambique +CurrencyNames/pt/nad=D\u00f3lar da Nam\u00edbia +CurrencyNames/pt/ngn=Naira nigeriana +CurrencyNames/pt/nio=C\u00f3rdoba Ouro nicaraguense +CurrencyNames/pt/nlg=Florim holand\u00eas +CurrencyNames/pt/nok=Coroa norueguesa +CurrencyNames/pt/npr=Rupia nepalesa +CurrencyNames/pt/nzd=D\u00f3lar da Nova Zel\u00e2ndia +CurrencyNames/pt/omr=Rial de Om\u00e3 +CurrencyNames/pt/pab=Balboa panamenho +CurrencyNames/pt/pen=Sol Novo peruano +CurrencyNames/pt/pgk=Kina da Papua-Nova Guin\u00e9 +CurrencyNames/pt/php=Peso filipino +CurrencyNames/pt/pkr=Rupia paquistanesa +CurrencyNames/pt/pln=Zloti polon\u00eas +CurrencyNames/pt/pte=Escudo portugu\u00eas +CurrencyNames/pt/pyg=Guarani paraguaio +CurrencyNames/pt/qar=Rial catariano +CurrencyNames/pt/rol=Leu romeno antigo +CurrencyNames/pt/ron=Leu romeno +CurrencyNames/pt/rsd=Dinar s\u00e9rvio +CurrencyNames/pt/rub=Rublo russo +CurrencyNames/pt/rur=Rublo russo (1991-1998) +CurrencyNames/pt/rwf=Franco ruand\u00eas +CurrencyNames/pt/sar=Rial saudita +CurrencyNames/pt/sbd=D\u00f3lar das Ilhas Salom\u00e3o +CurrencyNames/pt/scr=Rupia das Seychelles +CurrencyNames/pt/sdd=Dinar sudan\u00eas +CurrencyNames/pt/sdg=Libra sudanesa +CurrencyNames/pt/sek=Coroa sueca +CurrencyNames/pt/sgd=D\u00f3lar de Cingapura +CurrencyNames/pt/shp=Libra de Santa Helena +CurrencyNames/pt/sit=Tolar Bons esloveno +CurrencyNames/pt/skk=Coroa eslovaca +CurrencyNames/pt/sll=Leone de Serra Leoa +CurrencyNames/pt/sos=Xelim somali +CurrencyNames/pt/srd=D\u00f3lar do Suriname +CurrencyNames/pt/srg=Florim do Suriname +CurrencyNames/pt/std=Dobra de S\u00e3o Tom\u00e9 e Pr\u00edncipe +CurrencyNames/pt/svc=Colom salvadorenho +CurrencyNames/pt/syp=Libra s\u00edria +CurrencyNames/pt/szl=Lilangeni da Suazil\u00e2ndia +CurrencyNames/pt/thb=Baht tailand\u00eas +CurrencyNames/pt/tjs=Somoni tadjique +CurrencyNames/pt/tmm=Manat do Turcomenist\u00e3o +CurrencyNames/pt/tnd=Dinar tunisiano +CurrencyNames/pt/top=Pa\u02bbanga de Tonga +CurrencyNames/pt/tpe=Escudo timorense +CurrencyNames/pt/trl=Lira turca antiga +CurrencyNames/pt/try=Lira turca +CurrencyNames/pt/ttd=D\u00f3lar de Trinidad e Tobago +CurrencyNames/pt/twd=D\u00f3lar Novo de Taiwan +CurrencyNames/pt/tzs=Xelim da Tanz\u00e2nia +CurrencyNames/pt/uah=Hryvnia ucraniano +CurrencyNames/pt/ugx=Xelim ugandense +CurrencyNames/pt/usd=D\u00f3lar norte-americano +CurrencyNames/pt/usn=D\u00f3lar norte-americano (Dia seguinte) +CurrencyNames/pt/uss=D\u00f3lar norte-americano (Mesmo dia) +CurrencyNames/pt/uyu=Peso uruguaio +CurrencyNames/pt/uzs=Sum do Usbequist\u00e3o +CurrencyNames/pt/veb=Bol\u00edvar venezuelano +CurrencyNames/pt/vef=Bol\u00edvar v enezuelano forte +CurrencyNames/pt/vnd=Dong vietnamita +CurrencyNames/pt/vuv=Vatu de Vanuatu +CurrencyNames/pt/wst=Tala samoano +CurrencyNames/pt/xaf=Franco CFA BEAC +CurrencyNames/pt/xag=Prata +CurrencyNames/pt/xau=Ouro +CurrencyNames/pt/xba=Unidade Composta Europeia +CurrencyNames/pt/xbb=Unidade Monet\u00e1ria Europeia +CurrencyNames/pt/xbc=Unidade de Conta Europeia (XBC) +CurrencyNames/pt/xbd=Unidade de Conta Europeia (XBD) +CurrencyNames/pt/xcd=D\u00f3lar do Caribe Oriental +CurrencyNames/pt/xdr=Direitos Especiais de Giro +CurrencyNames/pt/xfo=Franco-ouro franc\u00eas +CurrencyNames/pt/xfu=Franco UIC franc\u00eas +CurrencyNames/pt/xof=Franco CFA BCEAO +CurrencyNames/pt/xpd=Pal\u00e1dio +CurrencyNames/pt/xpf=Franco CFP +CurrencyNames/pt/xpt=Platina +CurrencyNames/pt/xts=C\u00f3digo de Moeda de Teste +CurrencyNames/pt/xxx=Moeda Desconhecida ou Inv\u00e1lida +CurrencyNames/pt/yer=Rial iemenita +CurrencyNames/pt/yum=Dinar noviy iugoslavo +CurrencyNames/pt/zar=Rand sul-africano +CurrencyNames/pt/zmk=Cuacha zambiano +CurrencyNames/pt/zwd=D\u00f3lar do Zimb\u00e1bue + +# bug 7020960 +CurrencyNames/sr_RS/RSD=\u0434\u0438\u043d. + +# bug 7025837 +CurrencyNames/sr-Latn-BA/bam=Bosansko-Hercegova\u010dka konvertibilna marka +CurrencyNames/sr-Latn-BA/eur=Evro +CurrencyNames/sr-Latn-ME/eur=Evro +CurrencyNames/sr-Latn-RS/rsd=Srpski dinar + +CurrencyNames//afa=Afghan Afghani (1927-2002) +CurrencyNames//afn=Afghan Afghani +CurrencyNames//ang=Netherlands Antillean Guilder +CurrencyNames//awg=Aruban Florin +CurrencyNames//azm=Azerbaijani Manat (1993-2006) +CurrencyNames//azn=Azerbaijani Manat +CurrencyNames//bbd=Barbadian Dollar +CurrencyNames//bdt=Bangladeshi Taka +CurrencyNames//bgn=Bulgarian Lev +CurrencyNames//bif=Burundian Franc +CurrencyNames//bob=Bolivian Boliviano +CurrencyNames//btn=Bhutanese Ngultrum +CurrencyNames//byb=Belarusian New Ruble (1994-1999) +CurrencyNames//byr=Belarusian Ruble +CurrencyNames//cdf=Congolese Franc +CurrencyNames//clf=Chilean Unit of Account (UF) +CurrencyNames//cny=Chinese Yuan +CurrencyNames//crc=Costa Rican Col\u00f3n +CurrencyNames//csd=Serbian Dinar (2002-2006) +CurrencyNames//cve=Cape Verdean Escudo +CurrencyNames//cyp=Cypriot Pound +CurrencyNames//dem=German Mark +CurrencyNames//djf=Djiboutian Franc +CurrencyNames//fjd=Fijian Dollar +CurrencyNames//ghc=Ghanaian Cedi (1979-2007) +CurrencyNames//ghs=Ghanaian Cedi +CurrencyNames//gmd=Gambian Dalasi +CurrencyNames//gnf=Guinean Franc +CurrencyNames//gtq=Guatemalan Quetzal +CurrencyNames//gyd=Guyanaese Dollar +CurrencyNames//hnl=Honduran Lempira +CurrencyNames//isk=Icelandic Kr\u00f3na +CurrencyNames//kgs=Kyrgystani Som +CurrencyNames//kmf=Comorian Franc +CurrencyNames//kzt=Kazakhstani Tenge +CurrencyNames//lkr=Sri Lankan Rupee +CurrencyNames//ltl=Lithuanian Litas +CurrencyNames//luf=Luxembourgian Franc +CurrencyNames//mga=Malagasy Ariary +CurrencyNames//mgf=Malagasy Franc +CurrencyNames//mmk=Myanma Kyat +CurrencyNames//mop=Macanese Pataca +CurrencyNames//mro=Mauritanian Ouguiya +CurrencyNames//mur=Mauritian Rupee +CurrencyNames//mvr=Maldivian Rufiyaa +CurrencyNames//mwk=Malawian Kwacha +CurrencyNames//mxv=Mexican Investment Unit +CurrencyNames//mzm=Mozambican Metical (1980-2006) +CurrencyNames//mzn=Mozambican Metical +CurrencyNames//nad=Namibian Dollar +CurrencyNames//nio=Nicaraguan C\u00f3rdoba +CurrencyNames//nlg=Dutch Guilder +CurrencyNames//omr=Omani Rial +CurrencyNames//pen=Peruvian Nuevo Sol +CurrencyNames//pgk=Papua New Guinean Kina +CurrencyNames//pkr=Pakistani Rupee +CurrencyNames//pyg=Paraguayan Guarani +CurrencyNames//rol=Romanian Leu (1952-2006) +CurrencyNames//rsd=Serbian Dinar +CurrencyNames//scr=Seychellois Rupee +CurrencyNames//sdd=Sudanese Dinar (1992-2007) +CurrencyNames//sit=Slovenian Tolar +CurrencyNames//sll=Sierra Leonean Leone +CurrencyNames//srd=Surinamese Dollar +CurrencyNames//srg=Surinamese Guilder +CurrencyNames//std=S\u00e3o Tom\u00e9 and Pr\u00edncipe Dobra +CurrencyNames//svc=Salvadoran Col\u00f3n +CurrencyNames//szl=Swazi Lilangeni +CurrencyNames//tjs=Tajikistani Somoni +CurrencyNames//tmm=Turkmenistani Manat (1993-2009) +CurrencyNames//top=Tongan Pa\u02bbanga +CurrencyNames//tpe=Timorese Escudo +CurrencyNames//trl=Turkish Lira (1922-2005) +CurrencyNames//try=Turkish Lira +CurrencyNames//twd=New Taiwan Dollar +CurrencyNames//uyu=Uruguayan Peso +CurrencyNames//uzs=Uzbekistan Som +CurrencyNames//veb=Venezuelan Bol\u00edvar (1871-2008) +CurrencyNames//vef=Venezuelan Bol\u00edvar +CurrencyNames//wst=Samoan Tala +CurrencyNames//xxx=Unknown Currency +CurrencyNames//yum=Yugoslavian New Dinar (1994-2002) +CurrencyNames//zwd=Zimbabwean Dollar (1980-2008) diff --git a/jdk/test/sun/text/resources/LocaleDataTest.java b/jdk/test/sun/text/resources/LocaleDataTest.java index 2a04cd973db..311b08a9125 100644 --- a/jdk/test/sun/text/resources/LocaleDataTest.java +++ b/jdk/test/sun/text/resources/LocaleDataTest.java @@ -33,7 +33,7 @@ * 6379214 6485516 6486607 4225362 4494727 6533691 6531591 6531593 6570259 * 6509039 6609737 6610748 6645271 6507067 6873931 6450945 6645268 6646611 * 6645405 6650730 6910489 6573250 6870908 6585666 6716626 6914413 6916787 - * 6919624 + * 6919624 6998391 7019267 7020960 7025837 * @summary Verify locale data * */ @@ -91,6 +91,10 @@ * LocaleNames/fr_FR/US=\u00c9tats-Unis * LocaleNames/fr_FR/FR=France * + * You can use language tag with '-' in locale field like this:
    + *        LocaleNames/sr-Latn/SR=Surinam
    + *        FormatData/sr-Latn-BA/DayNames/2=utorak
    + * * The command-line syntax of this test is * java LocaleDataTest [-w] [{ -s | }] * @@ -242,7 +246,9 @@ public class LocaleDataTest if (index == -1 || index + 1 == key.length()) throw new Exception("Malformed input file: \"" + key + "\" is missing locale name"); localeName = key.substring(oldIndex, index); - if (localeName.length() > 0) { + boolean use_tag = localeName.indexOf("-") != -1; + + if (use_tag == false && localeName.length() > 0) { language = localeName.substring(0, 2); if (localeName.length() > 3) { country = localeName.substring(3, 5); @@ -283,8 +289,14 @@ public class LocaleDataTest } else { fullName = "sun.text.resources." + rbName; } + Locale locale; + if (use_tag) { + locale = Locale.forLanguageTag(localeName); + } else { + locale = new Locale(language, country, variant); + } ResourceBundle bundle = ResourceBundle.getBundle(fullName, - new Locale(language, country, variant), + locale, ResourceBundle.Control.getNoFallbackControl(Control.FORMAT_DEFAULT)); resource = bundle.getObject(resTag); } diff --git a/jdk/test/tools/launcher/MiscTests.java b/jdk/test/tools/launcher/MiscTests.java index 654a56a01f4..1d7fcf9514b 100644 --- a/jdk/test/tools/launcher/MiscTests.java +++ b/jdk/test/tools/launcher/MiscTests.java @@ -23,8 +23,8 @@ /* * @test - * @bug 6856415 6981001 - * @summary Miscellaneous tests, Exceptions, EnsureJRE etc. + * @bug 6856415 + * @summary Miscellaneous tests, Exceptions * @compile -XDignore.symbol.file MiscTests.java TestHelper.java * @run main MiscTests */ @@ -32,9 +32,6 @@ import java.io.File; import java.io.FileNotFoundException; -import java.util.HashMap; -import java.util.Map; - public class MiscTests { @@ -67,22 +64,9 @@ public class MiscTests { System.out.println(tr.status); } } - // 6981001 : Check EnsureJreInstallation is ok, note we cannot - // thoroughly test this function, we simply do our best. - static void test6981001() { - if (TestHelper.is64Bit || !TestHelper.isWindows) { - return; - } - Map env = new HashMap(); - env.put("_JAVA_LAUNCHER_DEBUG", "true"); - TestHelper.TestResult tr = TestHelper.doExec(env, TestHelper.javaCmd); - if (!tr.contains(TestHelper.JAVAHOME + "\\lib\\bundles")) { - System.out.println(tr.status); - } - } + public static void main(String... args) { test6856415(); - test6981001(); if (TestHelper.testExitValue != 0) { throw new Error(TestHelper.testExitValue + " tests failed"); } diff --git a/langtools/.hgtags b/langtools/.hgtags index 04cc0b5bcb3..aee1d2128e3 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -108,3 +108,6 @@ d7225b476a5d1aebffb8827e7c72ba2e1651f4e7 jdk7-b128 67221b8643b478c4fceacc89240db876455aae76 jdk7-b131 e3d011d59a33acef79eff7523bef069557e91002 jdk7-b132 e77e98f936e83d94c9b56cc7af218dc822a06122 jdk7-b133 +3d7acdbb72cab55deedfd35f60d4732abc9d6ac4 jdk7-b134 +9d0a61ac567b983da7cc8f4a7030f2245bb6dbab jdk7-b135 +ed0f7f1f9511db4f9615b1426d22f8b961629275 jdk7-b136 diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java index 9db6e97bb3d..bbac0b65cb1 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -305,11 +305,7 @@ public class ClassUseWriter extends SubWriterHolderWriter { tr.addContent(tdFirst); HtmlTree tdLast = new HtmlTree(HtmlTag.TD); tdLast.addStyle(HtmlStyle.colLast); - if (pkg != null) { - addSummaryComment(pkg, tdLast); - } else { - tdLast.addContent(getSpace()); - } + addSummaryComment(pkg, tdLast); tr.addContent(tdLast); tbody.addContent(tr); } @@ -355,10 +351,7 @@ public class ClassUseWriter extends SubWriterHolderWriter { contentTree.addContent(tdFirst); HtmlTree tdLast = new HtmlTree(HtmlTag.TD); tdLast.addStyle(HtmlStyle.colLast); - if (pkg != null) - addSummaryComment(pkg, tdLast); - else - tdLast.addContent(getSpace()); + addSummaryComment(pkg, tdLast); contentTree.addContent(tdLast); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java index e162075a636..ba6f921e61c 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java @@ -283,23 +283,32 @@ public class HelpWriter extends HtmlDocletWriter { Content framePara = HtmlTree.P(line26); liFrame.addContent(framePara); ul.addContent(liFrame); + Content allclassesHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, + getResource("doclet.All_Classes")); + Content liAllClasses = HtmlTree.LI(HtmlStyle.blockList, allclassesHead); + Content line27 = getResource("doclet.Help_line_27", + getHyperLinkString("allclasses-noframe.html", + configuration.getText("doclet.All_Classes"))); + Content allclassesPara = HtmlTree.P(line27); + liAllClasses.addContent(allclassesPara); + ul.addContent(liAllClasses); Content sHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, getResource("doclet.Serialized_Form")); Content liSerial = HtmlTree.LI(HtmlStyle.blockList, sHead); - Content line27 = getResource("doclet.Help_line_27"); - Content serialPara = HtmlTree.P(line27); + Content line28 = getResource("doclet.Help_line_28"); + Content serialPara = HtmlTree.P(line28); liSerial.addContent(serialPara); ul.addContent(liSerial); Content constHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, getResource("doclet.Constants_Summary")); Content liConst = HtmlTree.LI(HtmlStyle.blockList, constHead); - Content line28 = getResource("doclet.Help_line_28"); - Content constPara = HtmlTree.P(line28); + Content line29 = getResource("doclet.Help_line_29"); + Content constPara = HtmlTree.P(line29); liConst.addContent(constPara); ul.addContent(liConst); Content divContent = HtmlTree.DIV(HtmlStyle.contentContainer, ul); - Content line29 = HtmlTree.EM(getResource("doclet.Help_line_29")); - divContent.addContent(line29); + Content line30 = HtmlTree.EM(getResource("doclet.Help_line_30")); + divContent.addContent(line30); contentTree.addContent(divContent); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java index 5bea2d75204..4e9019a1d98 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -246,10 +246,7 @@ public class PackageUseWriter extends SubWriterHolderWriter { contentTree.addContent(tdFirst); HtmlTree tdLast = new HtmlTree(HtmlTag.TD); tdLast.addStyle(HtmlStyle.colLast); - if (pkg != null) - addSummaryComment(pkg, tdLast); - else - tdLast.addContent(getSpace()); + addSummaryComment(pkg, tdLast); contentTree.addContent(tdLast); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties index 16fdd9497de..b59771f2c42 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties @@ -167,7 +167,7 @@ doclet.Window_Help_title=API Help doclet.Help_line_1=How This API Document Is Organized doclet.Help_line_2=This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows. doclet.Help_line_3=The {0} page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages. -doclet.Help_line_4=Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories: +doclet.Help_line_4=Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories: doclet.Help_line_5=Class/Interface doclet.Help_line_6=Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions: doclet.Help_line_7=Class inheritance diagram @@ -190,9 +190,10 @@ doclet.Help_line_23=Prev/Next doclet.Help_line_24=These links take you to the next or previous class, interface, package, or related page. doclet.Help_line_25=Frames/No Frames doclet.Help_line_26=These links show and hide the HTML frames. All pages are available with or without frames. -doclet.Help_line_27=Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description. -doclet.Help_line_28=The Constant Field Values page lists the static final fields and their values. -doclet.Help_line_29=This help file applies to API documentation generated using the standard doclet. +doclet.Help_line_27=The {0} link shows all classes and interfaces except non-static nested types. +doclet.Help_line_28=Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description. +doclet.Help_line_29=The Constant Field Values page lists the static final fields and their values. +doclet.Help_line_30=This help file applies to API documentation generated using the standard doclet. doclet.Help_enum_line_1=Each enum has its own separate page with the following sections: doclet.Help_enum_line_2=Enum declaration doclet.Help_enum_line_3=Enum description 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 07e39a8c3bd..17f894a09a0 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -129,19 +129,11 @@ public class JavacTaskImpl extends JavacTask { public Boolean call() { if (!used.getAndSet(true)) { - beginContext(); + initContext(); notYetEntered = new HashMap(); - try { - compilerMain.setFatalErrors(true); - result = compilerMain.compile(args, context, fileObjects, processors); - } finally { - endContext(); - } - compilerMain = null; - args = null; - context = null; - fileObjects = null; - notYetEntered = null; + compilerMain.setFatalErrors(true); + result = compilerMain.compile(args, context, fileObjects, processors); + cleanup(); return result == 0; } else { throw new IllegalStateException("multiple calls to method 'call'"); @@ -163,8 +155,11 @@ public class JavacTaskImpl extends JavacTask { } private void prepareCompiler() throws IOException { - if (!used.getAndSet(true)) { - beginContext(); + if (used.getAndSet(true)) { + if (compiler == null) + throw new IllegalStateException(); + } else { + initContext(); compilerMain.setOptions(Options.instance(context)); compilerMain.filenames = new ListBuffer(); List filenames = compilerMain.processArgs(CommandLine.parse(args)); @@ -185,13 +180,12 @@ public class JavacTaskImpl extends JavacTask { } } - private void beginContext() { + private void initContext() { context.put(JavacTaskImpl.class, this); if (context.get(TaskListener.class) != null) context.put(TaskListener.class, (TaskListener)null); if (taskListener != null) context.put(TaskListener.class, wrap(taskListener)); - tool.beginContext(context); //initialize compiler's default locale JavacMessages.instance(context).setCurrentLocale(locale); } @@ -218,8 +212,15 @@ public class JavacTaskImpl extends JavacTask { }; } - private void endContext() { - tool.endContext(); + void cleanup() { + if (compiler != null) + compiler.close(); + compiler = null; + compilerMain = null; + args = null; + context = null; + fileObjects = null; + notYetEntered = null; } /** @@ -446,12 +447,12 @@ public class JavacTaskImpl extends JavacTask { } if (genList.isEmpty()) { compiler.reportDeferredDiagnostics(); - compiler.log.flush(); - endContext(); + cleanup(); } } finally { - compiler.log.flush(); + if (compiler != null) + compiler.log.flush(); } return results; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTool.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTool.java index 354f5fad5fd..23405f6e1d4 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTool.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTool.java @@ -152,36 +152,6 @@ public final class JavacTool implements JavaCompiler { return new JavacFileManager(context, true, charset); } - private boolean compilationInProgress = false; - - /** - * Register that a compilation is about to start. - */ - void beginContext(Context context) { - if (compilationInProgress) - throw new IllegalStateException("Compilation in progress"); - compilationInProgress = true; - final JavaFileManager givenFileManager = context.get(JavaFileManager.class); - context.put(JavaFileManager.class, (JavaFileManager)null); - context.put(JavaFileManager.class, new Context.Factory() { - public JavaFileManager make(Context c) { - if (givenFileManager != null) { - c.put(JavaFileManager.class, givenFileManager); - return givenFileManager; - } else { - return new JavacFileManager(c, true, null); - } - } - }); - } - - /** - * Register that a compilation is completed. - */ - void endContext() { - compilationInProgress = false; - } - public JavacTask getTask(Writer out, JavaFileManager fileManager, DiagnosticListener diagnosticListener, diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java index b4bb52cfbf9..3ecbf5a3b89 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java @@ -131,6 +131,12 @@ public enum Source { public boolean allowMulticatch() { return compareTo(JDK1_7) >= 0; } + public boolean allowImprovedRethrowAnalysis() { + return compareTo(JDK1_7) >= 0; + } + public boolean allowImprovedCatchAnalysis() { + return compareTo(JDK1_7) >= 0; + } public boolean allowEnums() { return compareTo(JDK1_5) >= 0; } 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 46c1982b40e..2f224ebd27b 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 @@ -3004,6 +3004,30 @@ public class Attr extends JCTree.Visitor { throw new AssertionError(); } + /** + * Attribute an env for either a top level tree or class declaration. + */ + public void attrib(Env env) { + if (env.tree.getTag() == JCTree.TOPLEVEL) + attribTopLevel(env); + else + attribClass(env.tree.pos(), env.enclClass.sym); + } + + /** + * Attribute a top level tree. These trees are encountered when the + * package declaration has annotations. + */ + public void attribTopLevel(Env env) { + JCCompilationUnit toplevel = env.toplevel; + try { + annotate.flush(); + chk.validateAnnotations(toplevel.packageAnnotations, toplevel.packge); + } catch (CompletionFailure ex) { + chk.completionError(toplevel.pos(), ex); + } + } + /** Main method: attribute class definition associated with given class symbol. * reporting completion failures at the given position. * @param pos The source position at which completion errors are to be 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 89191201de1..8b07d8e9040 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 @@ -190,7 +190,8 @@ public class Flow extends TreeScanner { private final Resolve rs; private Env attrEnv; private Lint lint; - private final boolean allowRethrowAnalysis; + private final boolean allowImprovedRethrowAnalysis; + private final boolean allowImprovedCatchAnalysis; public static Flow instance(Context context) { Flow instance = context.get(flowKey); @@ -209,7 +210,8 @@ public class Flow extends TreeScanner { lint = Lint.instance(context); rs = Resolve.instance(context); Source source = Source.instance(context); - allowRethrowAnalysis = source.allowMulticatch(); + allowImprovedRethrowAnalysis = source.allowImprovedRethrowAnalysis(); + allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis(); } /** A flag that indicates whether the last statement could @@ -1046,7 +1048,9 @@ public class Flow extends TreeScanner { } } scanStat(tree.body); - List thrownInTry = thrown; + List thrownInTry = allowImprovedCatchAnalysis ? + chk.union(thrown, List.of(syms.runtimeExceptionType, syms.errorType)) : + thrown; thrown = thrownPrev; caught = caughtPrev; boolean aliveEnd = alive; @@ -1081,16 +1085,7 @@ public class Flow extends TreeScanner { ctypes = ctypes.append(exc); if (types.isSameType(exc, syms.objectType)) continue; - if (chk.subset(exc, caughtInTry)) { - log.error(l.head.pos(), - "except.already.caught", exc); - } else if (!chk.isUnchecked(l.head.pos(), exc) && - exc.tsym != syms.throwableType.tsym && - exc.tsym != syms.exceptionType.tsym && - !chk.intersects(exc, thrownInTry)) { - log.error(l.head.pos(), - "except.never.thrown.in.try", exc); - } + checkCaughtType(l.head.pos(), exc, thrownInTry, caughtInTry); caughtInTry = chk.incl(exc, caughtInTry); } } @@ -1154,6 +1149,29 @@ public class Flow extends TreeScanner { uninitsTry.andSet(uninitsTryPrev).andSet(uninits); } + void checkCaughtType(DiagnosticPosition pos, Type exc, List thrownInTry, List caughtInTry) { + if (chk.subset(exc, caughtInTry)) { + log.error(pos, "except.already.caught", exc); + } else if (!chk.isUnchecked(pos, exc) && + exc.tsym != syms.throwableType.tsym && + exc.tsym != syms.exceptionType.tsym && + !chk.intersects(exc, thrownInTry)) { + log.error(pos, "except.never.thrown.in.try", exc); + } else if (allowImprovedCatchAnalysis) { + List catchableThrownTypes = chk.intersect(List.of(exc), thrownInTry); + // 'catchableThrownTypes' cannnot possibly be empty - if 'exc' was an + // unchecked exception, the result list would not be empty, as the augmented + // thrown set includes { RuntimeException, Error }; if 'exc' was a checked + // exception, that would have been covered in the branch above + if (chk.diff(catchableThrownTypes, caughtInTry).isEmpty()) { + String key = catchableThrownTypes.length() == 1 ? + "unreachable.catch" : + "unreachable.catch.1"; + log.warning(pos, key, catchableThrownTypes); + } + } + } + public void visitConditional(JCConditional tree) { scanCond(tree.cond); Bits initsBeforeElse = initsWhenFalse; @@ -1238,7 +1256,7 @@ public class Flow extends TreeScanner { sym.kind == VAR && (sym.flags() & (FINAL | EFFECTIVELY_FINAL)) != 0 && preciseRethrowTypes.get(sym) != null && - allowRethrowAnalysis) { + allowImprovedRethrowAnalysis) { for (Type t : preciseRethrowTypes.get(sym)) { markThrown(tree, t); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java index 8e89af024de..ff10fd3ed36 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -89,7 +89,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil private FSInfo fsInfo; - private boolean useZipFileIndex; + private boolean contextUseOptimizedZip; private ZipFileIndexCache zipFileIndexCache; private final File uninited = new File("U N I N I T E D"); @@ -164,8 +164,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil fsInfo = FSInfo.instance(context); - useZipFileIndex = options.isSet("useOptimizedZip"); - if (useZipFileIndex) + contextUseOptimizedZip = options.getBoolean("useOptimizedZip", true); + if (contextUseOptimizedZip) zipFileIndexCache = ZipFileIndexCache.getSharedInstance(); mmappedIO = options.isSet("mmappedIO"); @@ -471,9 +471,27 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil private static final RelativeDirectory symbolFilePrefix = new RelativeDirectory("META-INF/sym/rt.jar/"); + /* + * This method looks for a ZipFormatException and takes appropriate + * evasive action. If there is a failure in the fast mode then we + * fail over to the platform zip, and allow it to deal with a potentially + * non compliant zip file. + */ + protected Archive openArchive(File zipFilename) throws IOException { + try { + return openArchive(zipFilename, contextUseOptimizedZip); + } catch (IOException ioe) { + if (ioe instanceof ZipFileIndex.ZipFormatException) { + return openArchive(zipFilename, false); + } else { + throw ioe; + } + } + } + /** Open a new zip file directory, and cache it. */ - protected Archive openArchive(File zipFileName) throws IOException { + private Archive openArchive(File zipFileName, boolean useOptimizedZip) throws IOException { File origZipFileName = zipFileName; if (!ignoreSymbolFile && paths.isDefaultBootClassPathRtJar(zipFileName)) { File file = zipFileName.getParentFile().getParentFile(); // ${java.home} @@ -495,7 +513,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil boolean usePreindexedCache = false; String preindexCacheLocation = null; - if (!useZipFileIndex) { + if (!useOptimizedZip) { zdir = new ZipFile(zipFileName); } else { usePreindexedCache = options.isSet("usezipindex"); @@ -524,23 +542,22 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil } if (origZipFileName == zipFileName) { - if (!useZipFileIndex) { + if (!useOptimizedZip) { archive = new ZipArchive(this, zdir); } else { archive = new ZipFileIndexArchive(this, - zipFileIndexCache.getZipFileIndex(zipFileName, + zipFileIndexCache.getZipFileIndex(zipFileName, null, usePreindexedCache, preindexCacheLocation, options.isSet("writezipindexfiles"))); } } else { - if (!useZipFileIndex) { + if (!useOptimizedZip) { archive = new SymbolArchive(this, origZipFileName, zdir, symbolFilePrefix); - } - else { + } else { archive = new ZipFileIndexArchive(this, - zipFileIndexCache.getZipFileIndex(zipFileName, + zipFileIndexCache.getZipFileIndex(zipFileName, symbolFilePrefix, usePreindexedCache, preindexCacheLocation, @@ -549,6 +566,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil } } catch (FileNotFoundException ex) { archive = new MissingArchive(zipFileName); + } catch (ZipFileIndex.ZipFormatException zfe) { + throw zfe; } catch (IOException ex) { if (zipFileName.exists()) log.error("error.reading.file", zipFileName, getMessage(ex)); diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java index fc9d1b3789f..1bee909914f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java @@ -492,10 +492,32 @@ public class ZipFileIndex { public ZipDirectory(RandomAccessFile zipRandomFile, long start, long end, ZipFileIndex index) throws IOException { this.zipRandomFile = zipRandomFile; this.zipFileIndex = index; - + hasValidHeader(); findCENRecord(start, end); } + /* + * the zip entry signature should be at offset 0, otherwise allow the + * calling logic to take evasive action by throwing ZipFormatException. + */ + private boolean hasValidHeader() throws IOException { + final long pos = zipRandomFile.getFilePointer(); + try { + if (zipRandomFile.read() == 'P') { + if (zipRandomFile.read() == 'K') { + if (zipRandomFile.read() == 0x03) { + if (zipRandomFile.read() == 0x04) { + return true; + } + } + } + } + } finally { + zipRandomFile.seek(pos); + } + throw new ZipFormatException("invalid zip magic"); + } + /* * Reads zip file central directory. * For more details see readCEN in zip_util.c from the JDK sources. @@ -529,7 +551,13 @@ public class ZipFileIndex { zipDir = new byte[get4ByteLittleEndian(endbuf, i + 12) + 2]; zipDir[0] = endbuf[i + 10]; zipDir[1] = endbuf[i + 11]; - zipRandomFile.seek(start + get4ByteLittleEndian(endbuf, i + 16)); + int sz = get4ByteLittleEndian(endbuf, i + 16); + // a negative offset or the entries field indicates a + // potential zip64 archive + if (sz < 0 || get2ByteLittleEndian(zipDir, 0) == 0xffff) { + throw new ZipFormatException("detected a zip64 archive"); + } + zipRandomFile.seek(start + sz); zipRandomFile.readFully(zipDir, 2, zipDir.length - 2); return; } else { @@ -1127,4 +1155,18 @@ public class ZipFileIndex { } } + /* + * Exception primarily used to implement a failover, used exclusively here. + */ + + static final class ZipFormatException extends IOException { + private static final long serialVersionUID = 8000196834066748623L; + protected ZipFormatException(String message) { + super(message); + } + + protected ZipFormatException(String message, Throwable cause) { + super(message, cause); + } + } } 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 d7107ad5626..fe1cb42db0b 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 @@ -638,6 +638,19 @@ public class JavaCompiler implements ClassReader.SourceCompleter { } } + /** Resolve an identifier which may be the binary name of a class or + * the Java name of a class or package. + * @param name The name to resolve + */ + public Symbol resolveBinaryNameOrIdent(String name) { + try { + Name flatname = names.fromString(name.replace("/", ".")); + return reader.loadClass(flatname); + } catch (CompletionFailure ignore) { + return resolveIdent(name); + } + } + /** Resolve an identifier. * @param name The identifier to resolve */ @@ -1058,7 +1071,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { } else { boolean errors = false; for (String nameStr : classnames) { - Symbol sym = resolveIdent(nameStr); + Symbol sym = resolveBinaryNameOrIdent(nameStr); if (sym == null || (sym.kind == Kinds.PCK && !processPcks)) { log.error("proc.cant.find.class", nameStr); errors = true; @@ -1166,7 +1179,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { env.enclClass.sym.sourcefile : env.toplevel.sourcefile); try { - attr.attribClass(env.tree.pos(), env.enclClass.sym); + attr.attrib(env); if (errorCount() > 0 && !shouldStop(CompileState.ATTR)) { //if in fail-over mode, ensure that AST expression nodes //are correctly initialized (e.g. they have a type/symbol) 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 3af480c9385..5e34ee484fa 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -73,9 +73,14 @@ public class JavacTypes implements javax.lang.model.util.Types { public Element asElement(TypeMirror t) { Type type = cast(Type.class, t); - if (type.tag != TypeTags.CLASS && type.tag != TypeTags.TYPEVAR) - return null; - return type.asElement(); + switch (type.tag) { + case TypeTags.CLASS: + case TypeTags.ERROR: + case TypeTags.TYPEVAR: + return type.asElement(); + default: + return null; + } } public boolean isSameType(TypeMirror t1, TypeMirror t2) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index eee56d25725..e83c477b2af 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -820,13 +820,17 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea /** The set of package-info files to be processed this round. */ List packageInfoFiles; + /** The number of Messager errors generated in this round. */ + int nMessagerErrors; + /** Create a round (common code). */ - private Round(Context context, int number, int priorWarnings) { + private Round(Context context, int number, int priorErrors, int priorWarnings) { this.context = context; this.number = number; compiler = JavaCompiler.instance(context); log = Log.instance(context); + log.nerrors = priorErrors; log.nwarnings += priorWarnings; log.deferDiagnostics = true; @@ -840,7 +844,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea /** Create the first round. */ Round(Context context, List roots, List classSymbols) { - this(context, 1, 0); + this(context, 1, 0, 0); this.roots = roots; genClassFiles = new HashMap(); @@ -860,7 +864,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea /** Create a new round. */ private Round(Round prev, Set newSourceFiles, Map newClassFiles) { - this(prev.nextContext(), prev.number+1, prev.compiler.log.nwarnings); + this(prev.nextContext(), + prev.number+1, + prev.nMessagerErrors, + prev.compiler.log.nwarnings); this.genClassFiles = prev.genClassFiles; List parsedFiles = compiler.parseFiles(newSourceFiles); @@ -1014,6 +1021,8 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea if (taskListener != null) taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); } + + nMessagerErrors = messager.errorCount(); } void showDiagnostics(boolean showAll) { 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 4a3a5fa5bfb..889e2293bf3 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 @@ -1102,6 +1102,16 @@ compiler.warn.inexact.non-varargs.call=\ cast to {0} for a varargs call\n\ cast to {1} for a non-varargs call and to suppress this warning +# 0: list of type +compiler.warn.unreachable.catch=\ + unreachable catch clause\n\ + thrown type {0} has already been caught + +# 0: list of type +compiler.warn.unreachable.catch.1=\ + unreachable catch clause\n\ + thrown types {0} have already been caught + # 0: symbol compiler.warn.long.SVUID=\ serialVersionUID must be of type long in class {0} diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java index 033c385ef5d..cec4b954b4e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -26,6 +26,7 @@ package com.sun.tools.javac.util; import java.util.Collection; +import java.util.EnumMap; import java.util.EnumSet; import java.util.HashMap; import java.util.Locale; @@ -226,17 +227,14 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter { DiagnosticPart.SOURCE)); initFormat(); initIndentation(); + if (options.isSet("oldDiags")) + initOldFormat(); String fmt = options.get("diagsFormat"); if (fmt != null) { - String[] formats = fmt.split("\\|"); - switch (formats.length) { - case 3: - setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, formats[2]); - case 2: - setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, formats[1]); - default: - setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, formats[0]); - } + if (fmt.equals("OLD")) + initOldFormat(); + else + initFormats(fmt); } String srcPos = null; if ((((srcPos = options.get("sourcePosition")) != null)) && @@ -280,14 +278,35 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter { initFormat(); initIndentation(); } - //where + private void initFormat() { - availableFormats = new HashMap(); - setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, "%f:%l:%_%t%L%m"); - setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, "%p%L%m"); - setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, "%f:%_%t%L%m"); + initFormats("%f:%l:%_%p%L%m", "%p%L%m", "%f:%_%p%L%m"); } - //where + + private void initOldFormat() { + initFormats("%f:%l:%_%t%L%m", "%p%L%m", "%f:%_%t%L%m"); + } + + private void initFormats(String pos, String nopos, String clazz) { + availableFormats = new EnumMap(BasicFormatKind.class); + setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, pos); + setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, nopos); + setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, clazz); + } + + @SuppressWarnings("fallthrough") + private void initFormats(String fmt) { + String[] formats = fmt.split("\\|"); + switch (formats.length) { + case 3: + setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, formats[2]); + case 2: + setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, formats[1]); + default: + setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, formats[0]); + } + } + private void initIndentation() { indentationLevels = new HashMap(); setIndentation(DiagnosticPart.SUMMARY, 0); diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Options.java b/langtools/src/share/classes/com/sun/tools/javac/util/Options.java index c44cfa960a1..1f68ddb1a35 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Options.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Options.java @@ -75,6 +75,22 @@ public class Options { return values.get(name.optionName); } + /** + * Get the boolean value for an option, patterned after Boolean.getBoolean, + * essentially will return true, iff the value exists and is set to "true". + */ + public boolean getBoolean(String name) { + return getBoolean(name, false); + } + + /** + * Get the boolean with a default value if the option is not set. + */ + public boolean getBoolean(String name, boolean defaultValue) { + String value = get(name); + return (value == null) ? defaultValue : Boolean.parseBoolean(value); + } + /** * Check if the value for an undocumented option has been set. */ diff --git a/langtools/src/share/classes/javax/lang/model/element/Element.java b/langtools/src/share/classes/javax/lang/model/element/Element.java index 522faa6405b..f46c2cf26f5 100644 --- a/langtools/src/share/classes/javax/lang/model/element/Element.java +++ b/langtools/src/share/classes/javax/lang/model/element/Element.java @@ -197,11 +197,12 @@ public interface Element { *
  • If this is a {@linkplain * PackageElement#getEnclosingElement package}, {@code null} is * returned. - + * *
  • If this is a {@linkplain * TypeParameterElement#getEnclosingElement type parameter}, - * {@code null} is returned. - + * {@linkplain TypeParameterElement#getGenericElement the + * generic element} of the type parameter is returned. + * * * * @return the enclosing element, or {@code null} if there is none diff --git a/langtools/src/share/classes/javax/lang/model/element/TypeParameterElement.java b/langtools/src/share/classes/javax/lang/model/element/TypeParameterElement.java index e6a0536bc5a..f9b128e2490 100644 --- a/langtools/src/share/classes/javax/lang/model/element/TypeParameterElement.java +++ b/langtools/src/share/classes/javax/lang/model/element/TypeParameterElement.java @@ -64,9 +64,9 @@ public interface TypeParameterElement extends Element { List getBounds(); /** - * Returns {@code null}. + * Returns the {@linkplain TypeParameterElement#getGenericElement generic element} of this type parameter. * - * @return {@code null} + * @return the generic element of this type parameter */ @Override Element getEnclosingElement(); diff --git a/langtools/test/com/sun/javadoc/testUseOption/C.java b/langtools/test/com/sun/javadoc/testUseOption/C.java new file mode 100644 index 00000000000..419d36ba73c --- /dev/null +++ b/langtools/test/com/sun/javadoc/testUseOption/C.java @@ -0,0 +1,41 @@ +/* + * 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. + */ + +/** + * Class in an unnamed package. + */ + +public class C { + + /** + * Field in C. + */ + public UsedInC fieldInC; + + /** + * Method in C. + */ + public UsedInC methodInC(UsedInC p) { + return p; + } +} diff --git a/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java b/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java index f03f24002bc..58f56073a38 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, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 4496290 4985072 + * @bug 4496290 4985072 7006178 * @summary A simple test to determine if -use works. * @author jamieh * @library ../lib/ @@ -34,7 +34,7 @@ public class TestUseOption extends JavadocTester { - private static final String BUG_ID = "4496290-4985072"; + private static final String BUG_ID = "4496290-4985072-7006178"; //Input for string search tests. private static final String[] TEST2 = { @@ -54,6 +54,16 @@ public class TestUseOption extends JavadocTester { "Method in C8.", }; + private static final String[][] TEST3 = { + {BUG_ID + "-3" + FS + "class-use" + FS + "UsedInC.html", "Uses of " + + "UsedInC in <Unnamed>" + }, + {BUG_ID + "-3" + FS + "package-use.html", "" + + "UsedInC " + } + }; + private static final String[] ARGS = new String[] { "-d", BUG_ID, "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" }; @@ -62,6 +72,10 @@ public class TestUseOption extends JavadocTester { "-d", BUG_ID+"-2", "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" }; + private static final String[] ARGS3 = new String[] { + "-d", BUG_ID + "-3", "-sourcepath", SRC_DIR, "-use", SRC_DIR + FS + "C.java", SRC_DIR + FS + "UsedInC.java" + }; + /** * The entry point of the test. * @param args the array of command line arguments. @@ -93,6 +107,8 @@ public class TestUseOption extends JavadocTester { prevIndex = currentIndex; } tester.printSummary(); + run(tester, ARGS3, TEST3, NO_TEST); + tester.printSummary(); } /** diff --git a/langtools/test/com/sun/javadoc/testUseOption/UsedInC.java b/langtools/test/com/sun/javadoc/testUseOption/UsedInC.java new file mode 100644 index 00000000000..61b43eda51d --- /dev/null +++ b/langtools/test/com/sun/javadoc/testUseOption/UsedInC.java @@ -0,0 +1,26 @@ +/* + * 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. + */ + +public class UsedInC +{ +} diff --git a/langtools/test/tools/apt/Compile/golden.txt b/langtools/test/tools/apt/Compile/golden.txt index 42ee8bd867b..180efe276d2 100644 --- a/langtools/test/tools/apt/Compile/golden.txt +++ b/langtools/test/tools/apt/Compile/golden.txt @@ -1,6 +1,6 @@ error: It's a mad, mad, mad, mad world error: Something wicked this way comes -HelloWorld.java:2: Boring class name +HelloWorld.java:2: error: Boring class name public class HelloWorld { ^ 3 errors diff --git a/langtools/test/tools/javac/4846262/Test.out b/langtools/test/tools/javac/4846262/Test.out index 254d9d2f644..175101fa83a 100644 --- a/langtools/test/tools/javac/4846262/Test.out +++ b/langtools/test/tools/javac/4846262/Test.out @@ -1,7 +1,7 @@ -Test.java:4: not a statement +Test.java:4: error: not a statement abcdefg ^ -Test.java:4: ';' expected +Test.java:4: error: ';' expected abcdefg ^ 2 errors diff --git a/langtools/test/tools/javac/6508981/TestInferBinaryName.java b/langtools/test/tools/javac/6508981/TestInferBinaryName.java index aeb91cfebba..b14bdc01894 100644 --- a/langtools/test/tools/javac/6508981/TestInferBinaryName.java +++ b/langtools/test/tools/javac/6508981/TestInferBinaryName.java @@ -139,9 +139,8 @@ public class TestInferBinaryName { throws IOException { Context ctx = new Context(); Options options = Options.instance(ctx); - // uugh, ugly back door, should be cleaned up, someday - if (zipFileIndexKind == USE_ZIP_FILE_INDEX) - options.put("useOptimizedZip", "true"); + options.put("useOptimizedZip", + Boolean.toString(zipFileIndexKind == USE_ZIP_FILE_INDEX)); if (symFileKind == IGNORE_SYMBOL_FILE) options.put("ignore.symbol.file", "true"); diff --git a/langtools/test/tools/javac/6558548/T6558548.java b/langtools/test/tools/javac/6558548/T6558548.java new file mode 100644 index 00000000000..09bbda66237 --- /dev/null +++ b/langtools/test/tools/javac/6558548/T6558548.java @@ -0,0 +1,300 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6558548 + * @summary The compiler needs to be aligned with clarified specification of throws + * @compile/fail/ref=T6558548_latest.out -XDrawDiagnostics T6558548.java + * @compile/fail/ref=T6558548_6.out -source 6 -XDrawDiagnostics T6558548.java + */ + +class T6558548 { + + void nothing() {} + void checked() throws InterruptedException {} + void runtime() throws IllegalArgumentException {} + + void m1() { + try { + throw new java.io.FileNotFoundException(); + } + catch(java.io.FileNotFoundException exc) { } + catch(java.io.IOException exc) { } // 6: ok; latest: unreachable + } + + void m1a() { + try { + throw new java.io.IOException(); + } + catch(java.io.FileNotFoundException exc) { } + catch(java.io.IOException exc) { } //ok + } + + void m2() { + try { + nothing(); + } + catch(Exception exc) { } // ok + } + + void m3() { + try { + checked(); + } + catch(Exception exc) { } //ok + } + + void m4() { + try { + runtime(); + } + catch(Exception exc) { } //ok + } + + void m5() { + try { + nothing(); + } + catch(Throwable exc) { } //ok + } + + void m6() { + try { + checked(); + } + catch(Throwable exc) { } //ok + } + + void m7() { + try { + runtime(); + } + catch(Throwable exc) { } //ok + } + + void m9() { + try { + checked(); + } + catch(Error exc) { } + catch(Throwable exc) { } //ok + } + + void m10() { + try { + runtime(); + } + catch(Error exc) { } + catch(Throwable exc) { } //ok + } + + void m11() { + try { + nothing(); + } + catch(Error exc) { } + catch(Throwable exc) { } //ok + } + + void m12() { + try { + checked(); + } + catch(RuntimeException exc) { } + catch(Throwable exc) { } // ok + } + + void m13() { + try { + runtime(); + } + catch(RuntimeException exc) { } + catch(Throwable exc) { } // ok + } + + void m14() { + try { + nothing(); + } + catch(RuntimeException exc) { } + catch(Throwable exc) { } // ok + } + + void m15() { + try { + checked(); + } + catch(RuntimeException exc) { } + catch(Exception exc) { } //ok + } + + void m16() { + try { + runtime(); + } + catch(RuntimeException exc) { } + catch(Exception exc) { } //6: ok; latest: unreachable + } + + void m17() { + try { + nothing(); + } + catch(RuntimeException exc) { } + catch(Exception exc) { } //6: ok; latest: unreachable + } + + void m18() { + try { + checked(); + } + catch(RuntimeException exc) { } + catch(InterruptedException exc) { } + catch(Exception exc) { } //6: ok; latest: unreachable + } + + void m19() { + try { + runtime(); + } + catch(RuntimeException exc) { } + catch(InterruptedException exc) { } //never thrown in try + catch(Exception exc) { } //6: ok; latest: unreachable + } + + void m20() { + try { + nothing(); + } + catch(RuntimeException exc) { } + catch(InterruptedException exc) { } //never thrown in try + catch(Exception exc) { } //6: ok; latest: unreachable + } + + void m21() { + try { + checked(); + } + catch(RuntimeException exc) { } + catch(Exception exc) { } // ok + } + + void m22() { + try { + runtime(); + } + catch(RuntimeException exc) { } + catch(Exception exc) { } // 6: ok; latest: unreachable + } + + void m23() { + try { + nothing(); + } + catch(RuntimeException exc) { } + catch(Exception exc) { } // 6: ok; latest: unreachable + } + + void m24() { + try { + checked(); + } + catch(RuntimeException exc) { } + catch(Error exc) { } + catch(Throwable exc) { } //ok + } + + void m25() { + try { + runtime(); + } + catch(RuntimeException exc) { } + catch(Error exc) { } + catch(Throwable exc) { } //6: ok; latest: unreachable + } + + void m26() { + try { + nothing(); + } + catch(RuntimeException exc) { } + catch(Error exc) { } + catch(Throwable exc) { } //6: ok; latest: unreachable + } + + void m27() { + try { + checked(); + } + catch(RuntimeException exc) { } + catch(Error exc) { } + catch(InterruptedException exc) { } + catch(Throwable exc) { } //6: ok; latest: unreachable + } + + void m28() { + try { + runtime(); + } + catch(RuntimeException exc) { } + catch(Error exc) { } + catch(InterruptedException exc) { } //never thrown in try + catch(Throwable exc) { } //6: ok; latest: unreachable + } + + void m29() { + try { + nothing(); + } + catch(RuntimeException exc) { } + catch(Error exc) { } + catch(InterruptedException exc) { } //never thrown in try + catch(Throwable exc) { } //6: ok; latest: unreachable + } + + void m30() { + try { + checked(); + } + catch(RuntimeException exc) { } + catch(Error exc) { } + catch(Throwable exc) { } //ok + } + + void m31() { + try { + runtime(); + } + catch(RuntimeException exc) { } + catch(Error exc) { } + catch(Throwable exc) { } //6: ok; latest: unreachable + } + + void m32() { + try { + nothing(); + } + catch(RuntimeException exc) { } + catch(Error exc) { } + catch(Throwable exc) { } //6: ok; latest: unreachable + } + + void m33() { + try { + checked(); + } + catch(InterruptedException exc) { } //ok + } + + void m34() { + try { + runtime(); + } + catch(InterruptedException exc) { } //never thrown in try + } + + void m35() { + try { + nothing(); + } + catch(InterruptedException exc) { } //never thrown in try + } +} diff --git a/langtools/test/tools/javac/6558548/T6558548_6.out b/langtools/test/tools/javac/6558548/T6558548_6.out new file mode 100644 index 00000000000..551ed33e503 --- /dev/null +++ b/langtools/test/tools/javac/6558548/T6558548_6.out @@ -0,0 +1,9 @@ +- compiler.warn.source.no.bootclasspath: 1.6 +T6558548.java:159:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +T6558548.java:168:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +T6558548.java:239:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +T6558548.java:249:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +T6558548.java:291:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +T6558548.java:298:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +6 errors +1 warning diff --git a/langtools/test/tools/javac/6558548/T6558548_latest.out b/langtools/test/tools/javac/6558548/T6558548_latest.out new file mode 100644 index 00000000000..ee686cb4a6a --- /dev/null +++ b/langtools/test/tools/javac/6558548/T6558548_latest.out @@ -0,0 +1,23 @@ +T6558548.java:20:9: compiler.warn.unreachable.catch: java.io.FileNotFoundException +T6558548.java:134:9: compiler.warn.unreachable.catch: java.lang.RuntimeException +T6558548.java:142:9: compiler.warn.unreachable.catch: java.lang.RuntimeException +T6558548.java:151:9: compiler.warn.unreachable.catch.1: java.lang.InterruptedException,java.lang.RuntimeException +T6558548.java:159:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +T6558548.java:160:9: compiler.warn.unreachable.catch: java.lang.RuntimeException +T6558548.java:168:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +T6558548.java:169:9: compiler.warn.unreachable.catch: java.lang.RuntimeException +T6558548.java:185:9: compiler.warn.unreachable.catch: java.lang.RuntimeException +T6558548.java:193:9: compiler.warn.unreachable.catch: java.lang.RuntimeException +T6558548.java:211:9: compiler.warn.unreachable.catch.1: java.lang.RuntimeException,java.lang.Error +T6558548.java:220:9: compiler.warn.unreachable.catch.1: java.lang.RuntimeException,java.lang.Error +T6558548.java:230:9: compiler.warn.unreachable.catch.1: java.lang.InterruptedException,java.lang.RuntimeException,java.lang.Error +T6558548.java:239:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +T6558548.java:240:9: compiler.warn.unreachable.catch.1: java.lang.RuntimeException,java.lang.Error +T6558548.java:249:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +T6558548.java:250:9: compiler.warn.unreachable.catch.1: java.lang.RuntimeException,java.lang.Error +T6558548.java:268:9: compiler.warn.unreachable.catch.1: java.lang.RuntimeException,java.lang.Error +T6558548.java:277:9: compiler.warn.unreachable.catch.1: java.lang.RuntimeException,java.lang.Error +T6558548.java:291:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +T6558548.java:298:9: compiler.err.except.never.thrown.in.try: java.lang.InterruptedException +6 errors +15 warnings diff --git a/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java b/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java index 84d096a4ff1..922b00fcebd 100644 --- a/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java +++ b/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -261,7 +261,7 @@ public class T6769027 { enum PositionKind { NOPOS(Position.NOPOS, "- ", "error: "), - POS(5, "Test.java:1:6: ", "/Test.java:1: "); + POS(5, "Test.java:1:6: ", "/Test.java:1: error: "); int pos; String rawOutput; diff --git a/langtools/test/tools/javac/Diagnostics/7010608/Test.java b/langtools/test/tools/javac/Diagnostics/7010608/Test.java new file mode 100644 index 00000000000..d0b718ddebc --- /dev/null +++ b/langtools/test/tools/javac/Diagnostics/7010608/Test.java @@ -0,0 +1,92 @@ +/* + * 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 7010608 + * @summary the string 'error' should appear in error messages + */ + +import java.io.*; +import java.net.URI; +import java.util.*; +import javax.tools.*; +import javax.tools.JavaCompiler.CompilationTask; + +public class Test { + public static void main(String... args) throws Exception { + new Test().run(); + } + + void run() throws Exception { + Locale prev = Locale.getDefault(); + Locale.setDefault(Locale.ENGLISH); + try { + test(Arrays.asList(), + "myfo://test:1: error: cannot find symbol"); + test(Arrays.asList("-XDdiagsFormat=OLD"), + "myfo://test:1: cannot find symbol"); + test(Arrays.asList("-XDoldDiags"), + "myfo://test:1: cannot find symbol"); + } finally { + Locale.setDefault(prev); + } + } + + void test(List options, String expect) throws Exception { + System.err.println("test: " + options); + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + JavaFileObject f = new MyFileObject("myfo://test", "class Bad { Missing x; }"); + List files = Arrays.asList(f); + CompilationTask task = javac.getTask(pw, null, null, options, null, files); + boolean ok = task.call(); + pw.close(); + String out = sw.toString(); + if (!out.isEmpty()) + System.err.println(out); + if (ok) + throw new Exception("Compilation succeeded unexpectedly"); + if (!out.contains(expect)) + throw new Exception("expected text not found: " + expect); + } + + class MyFileObject extends SimpleJavaFileObject { + MyFileObject(String uri, String text) { + super(URI.create(uri), JavaFileObject.Kind.SOURCE); + this.text = text; + } + @Override + public String getName() { + return uri.toString(); + } + @Override + public String getCharContent(boolean ignoreEncodingErrors) { + return text; + } + final String text; + } +} + + diff --git a/langtools/test/tools/javac/annotations/TestAnnotationPackageInfo.java b/langtools/test/tools/javac/annotations/TestAnnotationPackageInfo.java new file mode 100644 index 00000000000..ac7593c3d49 --- /dev/null +++ b/langtools/test/tools/javac/annotations/TestAnnotationPackageInfo.java @@ -0,0 +1,87 @@ +/* + * 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 6993311 + * @summary annotations on packages are not validated + */ + +import java.io.*; +import java.net.*; +import java.util.*; +import javax.tools.*; +import com.sun.source.util.*; + +public class TestAnnotationPackageInfo { + public static void main(String... args) throws Exception { + new TestAnnotationPackageInfo().run(); + } + + static class MyFileObject extends SimpleJavaFileObject { + private String text; + public MyFileObject(String fileName, String text) { + super(URI.create("myfo:/" + fileName), JavaFileObject.Kind.SOURCE); + this.text = text; + } + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return text; + } + } + + public void run() throws Exception { + final String bootPath = System.getProperty("sun.boot.class.path"); + final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); + assert tool != null; + + JavaFileObject test_java = new MyFileObject("test/Test.java", + "package test; public @interface Test {\n" + + " public int mandatory();\n" + + "}\n"); + + JavaFileObject package_info_java = new MyFileObject("test/package-info.java", + "@Test package test;"); + + DiagnosticCollector coll = new DiagnosticCollector(); + + List options = Arrays.asList("-bootclasspath", bootPath); + List files = Arrays.asList(test_java, package_info_java); + JavacTask ct = (JavacTask)tool.getTask(null, null, coll, options, null, files); + ct.analyze(); + + String expectedCode = "compiler.err.annotation.missing.default.value"; + List> diags = coll.getDiagnostics(); + switch (diags.size()) { + case 0: + throw new Exception("no diagnostics reported"); + case 1: + String code = diags.get(0).getCode(); + if (code.equals(expectedCode)) + return; + throw new Exception("unexpected diag: " + diags.get(0)); + default: + throw new Exception("unexpected diags reported: " + diags); + } + } +} diff --git a/langtools/test/tools/javac/annotations/pos/package-info.java b/langtools/test/tools/javac/annotations/pos/package-info.java index dc18796ac39..460a0fcb7d9 100644 --- a/langtools/test/tools/javac/annotations/pos/package-info.java +++ b/langtools/test/tools/javac/annotations/pos/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -23,12 +23,12 @@ /* * @test - * @bug 4901290 + * @bug 4901290 6993311 * @summary Package annotations * @author gafter * * @compile package-info.java */ -@java.lang.annotation.Documented +@Deprecated package foo.bar; diff --git a/langtools/test/tools/javac/api/6411310/Test.java b/langtools/test/tools/javac/api/6411310/Test.java index b7702d705a6..aec6c7db615 100644 --- a/langtools/test/tools/javac/api/6411310/Test.java +++ b/langtools/test/tools/javac/api/6411310/Test.java @@ -153,14 +153,12 @@ public class Test { Context c = new Context(); Options options = Options.instance(c); - if (useOptimizedZip) { - options.put("useOptimizedZip", "true"); - } + options.put("useOptimizedZip", Boolean.toString(useOptimizedZip)); - if (!useSymbolFile) { - options.put("ignore.symbol.file", "true"); - } - return new JavacFileManager(c, false, null); + if (!useSymbolFile) { + options.put("ignore.symbol.file", "true"); + } + return new JavacFileManager(c, false, null); } File createDir(String name, String... entries) throws Exception { diff --git a/langtools/test/tools/javac/api/6557752/T6557752.java b/langtools/test/tools/javac/api/6557752/T6557752.java index c920a953e6e..fe748bee53e 100644 --- a/langtools/test/tools/javac/api/6557752/T6557752.java +++ b/langtools/test/tools/javac/api/6557752/T6557752.java @@ -118,7 +118,8 @@ public class T6557752 { Types types = task.getTypes(); - if (types.asElement(trees.getOriginalType((ErrorType)typeMirror)) != null) { + str1 = types.asElement(trees.getOriginalType((ErrorType)typeMirror)).toString(); + if (!str1.equals("FooBar")) { throw new AssertionError("Types.asElement() error!"); } foundError = true; diff --git a/langtools/test/tools/javac/api/T6838467.java b/langtools/test/tools/javac/api/T6838467.java index daa5a654a76..b08412d6f79 100644 --- a/langtools/test/tools/javac/api/T6838467.java +++ b/langtools/test/tools/javac/api/T6838467.java @@ -178,12 +178,10 @@ public class T6838467 { return fm; } - JavacFileManager createFileManager(boolean useOptimedZipIndex) { + JavacFileManager createFileManager(boolean useOptimizedZip) { Context ctx = new Context(); - if (useOptimedZipIndex) { - Options options = Options.instance(ctx); - options.put("useOptimizedZip", "true"); - } + Options options = Options.instance(ctx); + options.put("useOptimizedZip", Boolean.toString(useOptimizedZip)); return new JavacFileManager(ctx, false, null); } diff --git a/langtools/test/tools/javac/api/T6877206.java b/langtools/test/tools/javac/api/T6877206.java index 5a8442ad22a..3c82bb3e500 100644 --- a/langtools/test/tools/javac/api/T6877206.java +++ b/langtools/test/tools/javac/api/T6877206.java @@ -168,9 +168,7 @@ public class T6877206 { JavacFileManager createFileManager(boolean useOptimizedZip, boolean useSymbolFile) { Context ctx = new Context(); Options options = Options.instance(ctx); - if (useOptimizedZip) { - options.put("useOptimizedZip", "true"); - } + options.put("useOptimizedZip", Boolean.toString(useOptimizedZip)); if (!useSymbolFile) { options.put("ignore.symbol.file", "true"); } diff --git a/langtools/test/tools/javac/api/TestJavacTask_Lock.java b/langtools/test/tools/javac/api/TestJavacTask_Lock.java new file mode 100644 index 00000000000..cc27c11765b --- /dev/null +++ b/langtools/test/tools/javac/api/TestJavacTask_Lock.java @@ -0,0 +1,111 @@ +/* + * 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 7026509 + * @summary Cannot use JavaCompiler to create multiple CompilationTasks for partial compilations + */ + +import java.io.*; +import java.util.*; +import javax.tools.*; +import javax.tools.JavaCompiler.CompilationTask; +import com.sun.source.util.*; + +public class TestJavacTask_Lock { + public static void main(String... args) throws Exception { + new TestJavacTask_Lock().run(); + } + + enum MethodKind { + CALL { + int test(CompilationTask t) { + boolean ok = t.call(); + if (!ok) + throw new Error("compilation failed"); + return 1; + } + }, + PARSE { + int test(CompilationTask t) { + try { + ((JavacTask) t).parse(); + return 1; + } catch (IOException ex) { + throw new Error(ex); + } + } + + }; + abstract int test(CompilationTask t); + } + + JavaCompiler comp; + StandardJavaFileManager fm; + + void run() throws Exception { + comp = ToolProvider.getSystemJavaCompiler(); + fm = comp.getStandardFileManager(null, null, null); + + for (MethodKind first: MethodKind.values()) { + for (MethodKind second: MethodKind.values()) { + test(first, second); + } + } + + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + void test(MethodKind first, MethodKind second) { + System.err.println("test: " + first + ", " + second); + File testSrc = new File(System.getProperty("test.src")); + String thisClassName = TestJavacTask_Lock.class.getName(); + Iterable files = + fm.getJavaFileObjects(new File(testSrc, thisClassName + ".java")); + File tmpDir = new File(first + "_" + second); + tmpDir.mkdirs(); + List options = Arrays.asList( "-d", tmpDir.getPath() ); + CompilationTask t = comp.getTask(null, fm, null, options, null, files); + + try { + first.test(t); + second.test(t); + error("No exception thrown"); + } catch (IllegalStateException e) { + System.err.println("Expected exception caught: " + e); + } catch (Exception e) { + error("Unexpected exception caught: " + e); + e.printStackTrace(System.err); + } + + } + + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; +} diff --git a/langtools/test/tools/javac/api/TestJavacTask_Multiple.java b/langtools/test/tools/javac/api/TestJavacTask_Multiple.java new file mode 100644 index 00000000000..c80cc6e00cf --- /dev/null +++ b/langtools/test/tools/javac/api/TestJavacTask_Multiple.java @@ -0,0 +1,118 @@ +/* + * 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 7026509 + * @summary Cannot use JavaCompiler to create multiple CompilationTasks for partial compilations + */ + +import java.io.*; +import java.util.*; +import javax.tools.*; +import javax.tools.JavaCompiler.CompilationTask; +import com.sun.source.util.*; + +public class TestJavacTask_Multiple { + public static void main(String... args) throws Exception { + new TestJavacTask_Multiple().run(); + } + + final int MAX_TASKS = 3; + + enum TestKind { + CALL { + int test(CompilationTask t) { + boolean ok = t.call(); + if (!ok) + throw new Error("compilation failed"); + return 1; + } + }, + PARSE { + int test(CompilationTask t) { + try { + ((JavacTask) t).parse(); + return 1; + } catch (IOException ex) { + throw new Error(ex); + } + } + + }; + abstract int test(CompilationTask t); + } + + int count; + + void run() throws Exception { + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + for (TestKind tk: TestKind.values()) { + test(comp, fm, tk); + } + + int expect = TestKind.values().length * MAX_TASKS; + if (count != expect) { + throw new Exception("Unexpected number of tests completed: " + count + + ", expected: " + expect); + } + + } + + void test(JavaCompiler comp, StandardJavaFileManager fm, TestKind tk) { + System.err.println("test " + tk); + File testSrc = new File(System.getProperty("test.src")); + String thisClassName = TestJavacTask_Multiple.class.getName(); + Iterable files = + fm.getJavaFileObjects(new File(testSrc, thisClassName + ".java")); + + List tasks = new ArrayList(); + for (int i = 1; i <= MAX_TASKS; i++) { + File tmpDir = new File(tk + "_" + i); + tmpDir.mkdirs(); + List options = Arrays.asList( "-d", tmpDir.getPath() ); + CompilationTask t = comp.getTask(null, fm, null, options, null, files); + ((JavacTask) t).setTaskListener(createTaskListener(tk, i)); + tasks.add(t); + } + + for (CompilationTask t: tasks) + count += tk.test(t); + + System.err.println(); + } + + TaskListener createTaskListener(final TestKind tk, final int i) { + return new TaskListener() { + + public void started(TaskEvent e) { + System.err.println(tk + "." + i + ": " + e + " started"); + } + + public void finished(TaskEvent e) { + System.err.println(tk + "." + i + ": " + e + " finished"); + } + }; + } +} diff --git a/langtools/test/tools/javac/api/TestJavacTask_ParseAttrGen.java b/langtools/test/tools/javac/api/TestJavacTask_ParseAttrGen.java new file mode 100644 index 00000000000..e318b3e0a58 --- /dev/null +++ b/langtools/test/tools/javac/api/TestJavacTask_ParseAttrGen.java @@ -0,0 +1,127 @@ +/* + * 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 7026509 + * @summary Cannot use JavaCompiler to create multiple CompilationTasks for partial compilations + */ + +import java.io.*; +import java.util.*; +import javax.lang.model.element.*; +import javax.tools.*; +import com.sun.source.tree.*; +import com.sun.source.util.*; + +public class TestJavacTask_ParseAttrGen { + public static void main(String... args) throws Exception { + new TestJavacTask_ParseAttrGen().run(); + } + + JavaCompiler comp; + StandardJavaFileManager fm; + + void run() throws Exception { + comp = ToolProvider.getSystemJavaCompiler(); + fm = comp.getStandardFileManager(null, null, null); + + final boolean[] booleanValues = { false, true }; + for (boolean pk: booleanValues) { + for (boolean ak: booleanValues) { + for (boolean gk: booleanValues) { + test(pk, ak, gk); + } + } + } + } + + void test(boolean pk, boolean ak, boolean gk) throws Exception { + if (!pk && !ak && !gk) // nothing to do + return; + + System.err.println("test: pk:" + pk + ", ak:" + ak + ", gk: " + gk); + File testSrc = new File(System.getProperty("test.src")); + String thisClassName = TestJavacTask_ParseAttrGen.class.getName(); + Iterable files = + fm.getJavaFileObjects(new File(testSrc, thisClassName + ".java")); + File tmpDir = new File((pk ? "p" : "") + (ak ? "a" : "") + (gk ? "g" : "")); + tmpDir.mkdirs(); + fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(tmpDir)); + JavacTask t = (JavacTask) comp.getTask(null, fm, null, null, null, files); + //t.setTaskListener(createTaskListener()); + + try { + if (pk) { + Iterable trees = t.parse(); + System.err.println(count(trees) + " trees parsed"); + } + + if (ak) { + Iterable elems = t.analyze(); + System.err.println(count(elems) + " elements analyzed"); + } + + if (gk) { + Iterable classfiles = t.generate(); + System.err.println(count(classfiles) + " class files generated"); + } + } catch (IOException e) { + error("unexpected exception caught: " + e); + } + + File[] genFiles = tmpDir.listFiles(); + int expect = (gk ? 2 : 0); // main class and anon class for TaskListener + if (genFiles.length != expect) + error("unexpected number of files generated: " + genFiles.length + + ", expected: " + expect); + + System.err.println(); + } + + TaskListener createTaskListener() { + return new TaskListener() { + public void started(TaskEvent e) { + System.err.println(e + " started"); + } + + public void finished(TaskEvent e) { + System.err.println(e + " finished"); + } + }; + } + + int count(Iterable items) { + int count = 0; + for (T item: items) + count++; + return count; + } + + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; +} diff --git a/langtools/test/tools/javac/diags/examples/CountError.java b/langtools/test/tools/javac/diags/examples/CountError.java index 782d45d9241..2d09842c12a 100644 --- a/langtools/test/tools/javac/diags/examples/CountError.java +++ b/langtools/test/tools/javac/diags/examples/CountError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -23,6 +23,7 @@ // key: compiler.misc.count.error // key: compiler.err.unreported.exception.need.to.catch.or.throw +// key: compiler.err.error // run: backdoor class CountError { diff --git a/langtools/test/tools/javac/diags/examples/CountErrorPlural.java b/langtools/test/tools/javac/diags/examples/CountErrorPlural.java index efd8dc4255b..9d5ecb98c80 100644 --- a/langtools/test/tools/javac/diags/examples/CountErrorPlural.java +++ b/langtools/test/tools/javac/diags/examples/CountErrorPlural.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -23,6 +23,7 @@ // key: compiler.misc.count.error.plural // key: compiler.err.unreported.exception.need.to.catch.or.throw +// key: compiler.err.error // run: backdoor class CountErrorPlural { diff --git a/langtools/test/tools/javac/diags/examples/IdentifierExpected.java b/langtools/test/tools/javac/diags/examples/IdentifierExpected.java index 440b2688dd8..f36b8ad2161 100644 --- a/langtools/test/tools/javac/diags/examples/IdentifierExpected.java +++ b/langtools/test/tools/javac/diags/examples/IdentifierExpected.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -25,6 +25,7 @@ // key: compiler.err.expected // key: compiler.err.invalid.binary.number // key: compiler.misc.count.error.plural +// key: compiler.err.error // run: backdoor class IdentifierExpected { diff --git a/langtools/test/tools/javac/diags/examples/KindnameClass.java b/langtools/test/tools/javac/diags/examples/KindnameClass.java index 245e75332c3..4f856607cc4 100644 --- a/langtools/test/tools/javac/diags/examples/KindnameClass.java +++ b/langtools/test/tools/javac/diags/examples/KindnameClass.java @@ -25,6 +25,7 @@ // key: compiler.err.cant.resolve.location // key: compiler.misc.location // key: compiler.misc.count.error +// key: compiler.err.error // run: backdoor class KindnameClass { diff --git a/langtools/test/tools/javac/diags/examples/KindnameConstructor.java b/langtools/test/tools/javac/diags/examples/KindnameConstructor.java index c451c3a3ad9..21396b58b98 100644 --- a/langtools/test/tools/javac/diags/examples/KindnameConstructor.java +++ b/langtools/test/tools/javac/diags/examples/KindnameConstructor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -28,6 +28,7 @@ // key: compiler.misc.arg.length.mismatch // key: compiler.misc.no.conforming.assignment.exists // key: compiler.misc.count.error.plural +// key: compiler.err.error // run: backdoor class KindnameConstructor { diff --git a/langtools/test/tools/javac/diags/examples/KindnameMethod.java b/langtools/test/tools/javac/diags/examples/KindnameMethod.java index 3bcb7605585..7dd283fe4ca 100644 --- a/langtools/test/tools/javac/diags/examples/KindnameMethod.java +++ b/langtools/test/tools/javac/diags/examples/KindnameMethod.java @@ -26,6 +26,7 @@ // key: compiler.err.cant.resolve.location.args // key: compiler.misc.location // key: compiler.misc.count.error +// key: compiler.err.error // run: backdoor class KindnameMethod { diff --git a/langtools/test/tools/javac/diags/examples/KindnameVariable.java b/langtools/test/tools/javac/diags/examples/KindnameVariable.java index 894322b1a48..e88f30f7aa0 100644 --- a/langtools/test/tools/javac/diags/examples/KindnameVariable.java +++ b/langtools/test/tools/javac/diags/examples/KindnameVariable.java @@ -26,6 +26,7 @@ // key: compiler.err.cant.resolve.location // key: compiler.misc.location // key: compiler.misc.count.error +// key: compiler.err.error // run: backdoor class KindnameVariable { diff --git a/langtools/test/tools/javac/diags/examples/UnreachableCatch.java b/langtools/test/tools/javac/diags/examples/UnreachableCatch.java new file mode 100644 index 00000000000..5189e7a2757 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/UnreachableCatch.java @@ -0,0 +1,35 @@ +/* + * 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. + */ + +// key: compiler.warn.unreachable.catch + +class UnreachableCatch { + + void test() { + try { + throw new java.io.FileNotFoundException(); + } + catch(java.io.FileNotFoundException exc) { } + catch(java.io.IOException exc) { } //unreachable + } +} diff --git a/langtools/test/tools/javac/diags/examples/UnreachableCatch1.java b/langtools/test/tools/javac/diags/examples/UnreachableCatch1.java new file mode 100644 index 00000000000..3cf6ac32c7b --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/UnreachableCatch1.java @@ -0,0 +1,36 @@ +/* + * 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. + */ + +// key: compiler.warn.unreachable.catch.1 + +class UnreachableCatch1 { + + void test() { + try { + throw new IllegalArgumentException(); + } + catch(Error err) { } + catch(RuntimeException rex) { } + catch(Throwable t) { } //unreachable + } +} diff --git a/langtools/test/tools/javac/file/zip/T6836682.java b/langtools/test/tools/javac/file/zip/T6836682.java new file mode 100644 index 00000000000..c25779b6112 --- /dev/null +++ b/langtools/test/tools/javac/file/zip/T6836682.java @@ -0,0 +1,241 @@ +/* + * 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 6836682 7025988 + * @summary JavacFileManager handling of zip64 archives (Scenario A and B) + * @compile -XDignore.symbol.file T6836682.java Utils.java + * @run main T6836682 + */ +/* + * This test consists of two scenarios: + * + * Scenario A: create a jar with entries exceeding 64K, and see if the javac + * can handle this large jar on the classpath. Generally this test completes + * within a minute + * + * Scenario B: create a jar with a large enough file exceeding 4GB, and + * similarly test javac. This test is known to be slow and problematic on + * certain operating systems, thus this test can be selected by passing a + * property through jtreg as follows: + * -javaoptions=-DT6836682.testScenarioB=true. + * Note this test will only run iff all the disk requirements are met at runtime. + */ +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.zip.CRC32; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class T6836682 { + + private static final long GIGA = 1024 * 1024 * 1024; + private static final int BUFFER_LEN = Short.MAX_VALUE * 2; + + static long getCount(long minlength) { + return (minlength / BUFFER_LEN) + 1; + } + + static long computeCRC(long minlength) { + CRC32 crc = new CRC32(); + byte[] buffer = new byte[BUFFER_LEN]; + long count = getCount(minlength); + for (long i = 0; i < count; i++) { + crc.update(buffer); + } + return crc.getValue(); + } + + static long computeCRC(File inFile) throws IOException { + byte[] buffer = new byte[8192]; + CRC32 crc = new CRC32(); + FileInputStream fis = null; + BufferedInputStream bis = null; + try { + fis = new FileInputStream(inFile); + bis = new BufferedInputStream(fis); + int n = bis.read(buffer); + while (n > 0) { + crc.update(buffer, 0, n); + n = bis.read(buffer); + } + } finally { + Utils.close(bis); + Utils.close(fis); + } + return crc.getValue(); + } + + static void createLargeFile(OutputStream os, long minlength) throws IOException { + byte[] buffer = new byte[BUFFER_LEN]; + long count = getCount(minlength); + for (long i = 0; i < count; i++) { + os.write(buffer); + } + os.flush(); + } + + static void createJarWithLargeFile(File jarFile, File javaFile, + long minlength) throws IOException { + Utils.createClassFile(javaFile, null, true); + File classFile = new File(Utils.getClassFileName(javaFile)); + ZipOutputStream zos = null; + BufferedOutputStream bos = null; + FileInputStream fis = null; + try { + zos = new ZipOutputStream(new FileOutputStream(jarFile)); + zos.setLevel(ZipOutputStream.STORED); + zos.setMethod(0); + bos = new BufferedOutputStream(zos); + + ZipEntry ze = new ZipEntry("large.data"); + ze.setCompressedSize(getCount(minlength) * BUFFER_LEN); + ze.setSize(getCount(minlength) * BUFFER_LEN); + ze.setCrc(computeCRC(minlength)); + ze.setMethod(ZipEntry.STORED); + zos.putNextEntry(ze); + createLargeFile(bos, minlength); + + ze = new ZipEntry(classFile.getName()); + ze.setCompressedSize(classFile.length()); + ze.setSize(classFile.length()); + ze.setCrc(computeCRC(classFile)); + ze.setMethod(ZipEntry.STORED); + zos.putNextEntry(ze); + fis = new FileInputStream(classFile); + Utils.copyStream(fis, bos); + bos.flush(); + zos.closeEntry(); + } finally { + Utils.close(bos); + Utils.close(zos); + Utils.close(fis); + } + // deleted to prevent accidental linkage + new File(Utils.getClassFileName(javaFile)).delete(); + } + + static void createLargeJar(File jarFile, File javaFile) throws IOException { + File classFile = new File(Utils.getClassFileName(javaFile)); + Utils.createClassFile(javaFile, null, true); + ZipOutputStream zos = null; + FileInputStream fis = null; + final int MAX = Short.MAX_VALUE * 2 + 10; + ZipEntry ze = null; + try { + zos = new ZipOutputStream(new FileOutputStream(jarFile)); + zos.setLevel(ZipOutputStream.STORED); + zos.setMethod(ZipOutputStream.STORED); + for (int i = 0; i < MAX ; i++) { + ze = new ZipEntry("X" + i + ".txt"); + ze.setSize(0); + ze.setCompressedSize(0); + ze.setCrc(0); + zos.putNextEntry(ze); + } + + // add a class file + ze = new ZipEntry(classFile.getName()); + ze.setCompressedSize(classFile.length()); + ze.setSize(classFile.length()); + ze.setCrc(computeCRC(classFile)); + zos.putNextEntry(ze); + fis = new FileInputStream(classFile); + Utils.copyStream(fis, zos); + } finally { + Utils.close(zos); + Utils.close(fis); + // deleted to prevent accidental linkage + new File(Utils.getClassFileName(javaFile)).delete(); + } + } + + // a jar with entries exceeding 64k + a class file for the existential test + public static void testScenarioA(String... args) throws IOException { + File largeJar = new File("large.jar"); + File javaFile = new File("Foo.java"); + createLargeJar(largeJar, javaFile); + + File testFile = new File("Bar.java"); + try { + Utils.createJavaFile(testFile, javaFile); + if (!Utils.compile("-doe", "-verbose", "-cp", + largeJar.getAbsolutePath(), testFile.getAbsolutePath())) { + throw new IOException("test failed"); + } + } finally { + Utils.deleteFile(largeJar); + } + } + + // a jar with an enormous file + a class file for the existential test + public static void testScenarioB(String... args) throws IOException { + final File largeJar = new File("huge.jar"); + final File javaFile = new File("Foo.java"); + + final Path path = largeJar.getAbsoluteFile().getParentFile().toPath(); + final long available = Files.getFileStore(path).getUsableSpace(); + final long MAX_VALUE = 0xFFFF_FFFFL; + + final long absolute = MAX_VALUE + 1L; + final long required = (long)(absolute * 1.1); // pad for sundries + System.out.println("\tavailable: " + available / GIGA + " GB"); + System.out.println("\trequired: " + required / GIGA + " GB"); + + if (available > required) { + createJarWithLargeFile(largeJar, javaFile, absolute); + File testFile = new File("Bar.java"); + Utils.createJavaFile(testFile, javaFile); + try { + if (!Utils.compile("-doe", "-verbose", "-cp", + largeJar.getAbsolutePath(), testFile.getAbsolutePath())) { + throw new IOException("test failed"); + } + } finally { + Utils.deleteFile(largeJar); + } + } else { + System.out.println("Warning: testScenarioB passes vacuously," + + " requirements exceeds available space"); + } + } + + public static void main(String... args) throws IOException { + testScenarioA(); + System.out.println("testScenarioA: PASS"); + if (Boolean.getBoolean("T6836682.testScenarioB")) { + testScenarioB(); + System.out.println("testScenarioB: PASS"); + } else { + System.out.println("Warning: testScenarioB, large file test skipped"); + } + } +} diff --git a/langtools/test/tools/javac/file/zip/T6865530.java b/langtools/test/tools/javac/file/zip/T6865530.java new file mode 100644 index 00000000000..62d410429a6 --- /dev/null +++ b/langtools/test/tools/javac/file/zip/T6865530.java @@ -0,0 +1,66 @@ +/* + * 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 6865530 + * @summary ensure JavacFileManager handles non-standard zipfiles. + * @compile -XDignore.symbol.file T6865530.java + * @run main T6865530 + */ + + +import java.io.File; + + +public class T6865530 { + + public static void main(String... args) throws Exception { + File badFile = new File("bad.exe"); + File testJar = new File("test.jar"); + File fooJava = new File("Foo.java"); + File barJava = new File("Bar.java"); + + // create a jar by compiling a file, and append the jar to some + // arbitrary data to offset the start of the zip/jar archive + Utils.createJavaFile(fooJava); + Utils.compile("-doe", "-verbose", fooJava.getName()); + String[] jarArgs = { + "cvf", testJar.getAbsolutePath(), "Foo.class" + }; + Utils.jarTool.run(jarArgs); + Utils.cat(badFile, fooJava, testJar); + + // create test file and use the above file as a classpath + Utils.createJavaFile(barJava); + try { + if (!Utils.compile("-doe", "-verbose", "-cp", badFile.getAbsolutePath(), "Bar.java")) { + throw new RuntimeException("test fails javac did not compile"); + } + } finally { + Utils.deleteFile(badFile); + Utils.deleteFile(testJar); + } + } +} + diff --git a/langtools/test/tools/javac/file/zip/Utils.java b/langtools/test/tools/javac/file/zip/Utils.java new file mode 100644 index 00000000000..2f5f31b329b --- /dev/null +++ b/langtools/test/tools/javac/file/zip/Utils.java @@ -0,0 +1,131 @@ +/* + * 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.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; + +public class Utils { + + static final sun.tools.jar.Main jarTool = + new sun.tools.jar.Main(System.out, System.err, "jar-tool"); + + static final com.sun.tools.javac.Main javac = + new com.sun.tools.javac.Main(); + + private Utils(){} + + public static boolean compile(String... args) { + return javac.compile(args) == 0; + } + + public static void createClassFile(File javaFile, File superClass, + boolean delete) throws IOException { + createJavaFile(javaFile, superClass); + if (!compile(javaFile.getName())) { + throw new RuntimeException("compile failed unexpectedly"); + } + if (delete) javaFile.delete(); + } + + public static void createJavaFile(File outFile) throws IOException { + createJavaFile(outFile, null); + } + + public static void createJavaFile(File outFile, File superClass) throws IOException { + PrintStream ps = null; + String srcStr = "public class " + getSimpleName(outFile) + " "; + if (superClass != null) { + srcStr = srcStr.concat("extends " + getSimpleName(superClass) + " "); + } + srcStr = srcStr.concat("{}"); + try { + FileOutputStream fos = new FileOutputStream(outFile); + ps = new PrintStream(fos); + ps.println(srcStr); + } finally { + close(ps); + } + } + + static String getClassFileName(File javaFile) { + return javaFile.getName().endsWith(".java") + ? javaFile.getName().replace(".java", ".class") + : null; + } + + static String getSimpleName(File inFile) { + String fname = inFile.getName(); + return fname.substring(0, fname.indexOf(".")); + } + + public static void copyStream(InputStream in, OutputStream out) throws IOException { + byte[] buf = new byte[8192]; + int n = in.read(buf); + while (n > 0) { + out.write(buf, 0, n); + n = in.read(buf); + } + } + + public static void close(Closeable c) { + if (c != null) { + try { + c.close(); + } catch (IOException ignore) {} + } + } + + public static void deleteFile(File f) { + if (!f.delete()) { + throw new RuntimeException("could not delete file: " + f.getAbsolutePath()); + } + } + + public static void cat(File output, File... files) throws IOException { + BufferedInputStream bis = null; + BufferedOutputStream bos = null; + FileOutputStream fos = null; + try { + fos = new FileOutputStream(output); + bos = new BufferedOutputStream(fos); + for (File x : files) { + FileInputStream fis = new FileInputStream(x); + bis = new BufferedInputStream(fis); + copyStream(bis, bos); + Utils.close(bis); + } + } finally { + Utils.close(bis); + Utils.close(bos); + Utils.close(fos); + } + } +} diff --git a/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java b/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java index 2706782b10d..4960cacde5e 100644 --- a/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java +++ b/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -24,8 +24,6 @@ import java.util.*; import javax.annotation.processing.*; import javax.lang.model.SourceVersion; -import static javax.lang.model.SourceVersion.*; -import javax.lang.model.element.*; import javax.lang.model.util.*; /** diff --git a/langtools/test/tools/javac/processing/6430209/b6341534.java b/langtools/test/tools/javac/processing/6430209/b6341534.java index 5dfad046c90..567a02484be 100644 --- a/langtools/test/tools/javac/processing/6430209/b6341534.java +++ b/langtools/test/tools/javac/processing/6430209/b6341534.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -56,7 +56,9 @@ public class b6341534 extends JavacTestingAbstractProcessor { // on round 1, expect errorRaised == false && processingOver == false // on round 2, expect errorRaised == true && processingOver == true if( renv.errorRaised() != renv.processingOver()) { - messager.printMessage(ERROR, "FAILED"); + messager.printMessage(ERROR, "FAILED: round:" + r + + ", errorRaised:" + renv.errorRaised() + + ", processingOver:" + renv.processingOver()); } return true; } diff --git a/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out b/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out index 6a48a0e137b..37632783d8f 100644 --- a/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out +++ b/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out @@ -1,4 +1,4 @@ SemanticErrorTest.java:11:46: compiler.err.repeated.interface - compiler.err.proc.messager: Deliberate Error SemanticErrorTest.java:11:46: compiler.err.repeated.interface -1 error +2 errors diff --git a/langtools/test/tools/javac/processing/environment/round/TestContext.java b/langtools/test/tools/javac/processing/environment/round/TestContext.java index ddcba25fe80..deed69202bc 100644 --- a/langtools/test/tools/javac/processing/environment/round/TestContext.java +++ b/langtools/test/tools/javac/processing/environment/round/TestContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -34,7 +34,6 @@ import java.io.*; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.element.*; -import javax.tools.*; import static javax.tools.Diagnostic.Kind.*; import com.sun.source.util.Trees; diff --git a/langtools/test/tools/javac/processing/errors/TestErrorCount.java b/langtools/test/tools/javac/processing/errors/TestErrorCount.java new file mode 100644 index 00000000000..1f40ae8ad58 --- /dev/null +++ b/langtools/test/tools/javac/processing/errors/TestErrorCount.java @@ -0,0 +1,46 @@ +/* + * 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 6988079 + * @summary Errors reported via Messager.printMessage(ERROR,"error message") are not tallied correctly + * @library ../../lib + * @build JavacTestingAbstractProcessor TestErrorCount + * @compile/fail/ref=TestErrorCount.out -XDrawDiagnostics -processor TestErrorCount TestErrorCount.java + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.element.*; +import javax.tools.*; + +public class TestErrorCount extends JavacTestingAbstractProcessor { + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + messager.printMessage(Diagnostic.Kind.ERROR, "intentional error"); + return true; + } +} + diff --git a/langtools/test/tools/javac/processing/errors/TestErrorCount.out b/langtools/test/tools/javac/processing/errors/TestErrorCount.out new file mode 100644 index 00000000000..ccd4db7e5b2 --- /dev/null +++ b/langtools/test/tools/javac/processing/errors/TestErrorCount.out @@ -0,0 +1,3 @@ +- compiler.err.proc.messager: intentional error +- compiler.err.proc.messager: intentional error +2 errors diff --git a/langtools/test/tools/javac/processing/filer/TestPackageInfo.java b/langtools/test/tools/javac/processing/filer/TestPackageInfo.java index 7a905467370..651f9b7ba45 100644 --- a/langtools/test/tools/javac/processing/filer/TestPackageInfo.java +++ b/langtools/test/tools/javac/processing/filer/TestPackageInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 6380018 6392177 + * @bug 6380018 6392177 6993311 * @summary Test the ability to create and process package-info.java files * @author Joseph D. Darcy * @library ../../lib @@ -60,7 +60,7 @@ public class TestPackageInfo extends JavacTestingAbstractProcessor { // Verify annotations are as expected Set expectedAnnotations = new HashSet(); - expectedAnnotations.add(eltUtils.getTypeElement("java.lang.SuppressWarnings")); + expectedAnnotations.add(eltUtils.getTypeElement("java.lang.Deprecated")); if (!roundEnv.processingOver()) { System.out.println("\nRound " + round); @@ -90,7 +90,7 @@ public class TestPackageInfo extends JavacTestingAbstractProcessor { } catch(FilerException fe) {} PrintWriter pw = new PrintWriter(filer.createSourceFile("foo.package-info").openWriter()); - pw.println("@SuppressWarnings(\"\")"); + pw.println("@Deprecated"); pw.println("package foo;"); pw.close(); diff --git a/langtools/test/tools/javac/processing/filer/foo/bar/package-info.java b/langtools/test/tools/javac/processing/filer/foo/bar/package-info.java index eb666f4a02e..b4cbbe5803a 100644 --- a/langtools/test/tools/javac/processing/filer/foo/bar/package-info.java +++ b/langtools/test/tools/javac/processing/filer/foo/bar/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -24,5 +24,5 @@ /** * Javadoc for the foo.bar package! */ -@SuppressWarnings("deprecation") +@Deprecated package foo.bar; diff --git a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java index d602bc08ead..df7e6d08c9b 100644 --- a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java +++ b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 6449781 + * @bug 6449781 6930508 * @summary Test that reported names of anonymous classes are non-null. * @author Joseph D. Darcy * @library ../../../lib @@ -93,6 +93,7 @@ public class TestAnonClassNames { TestAnonClassNames.class, }; + List names = new ArrayList(); for(Class clazz : classes) { String name = clazz.getName(); Nesting anno = clazz.getAnnotation(Nesting.class); @@ -100,7 +101,14 @@ public class TestAnonClassNames { clazz.getName(), anno == null ? "(unset/ANONYMOUS)" : anno.value()); testClassName(name); + names.add(name); } + + // test all names together + testClassNames(names); + + if (errors > 0) + throw new RuntimeException(errors + " errors occurred"); } /** @@ -109,15 +117,23 @@ public class TestAnonClassNames { * input classes are modeled as elements. */ static void testClassName(String className) { - JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); - List classNames = new ArrayList(); - classNames.add(className); + testClassNames(Arrays.asList(className)); + } + + /** + * Perform annotation processing on a list of class file names and verify + * the existence of different flavors of class names when the + * input classes are modeled as elements. + */ + static void testClassNames(List classNames) { + System.out.println("test: " + classNames); List options = new ArrayList(); options.add("-proc:only"); options.add("-classpath"); options.add(System.getProperty("test.classes")); + JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); JavaCompiler.CompilationTask compileTask = javaCompiler.getTask(null, // Output null, // File manager @@ -130,9 +146,16 @@ public class TestAnonClassNames { compileTask.setProcessors(processors); Boolean goodResult = compileTask.call(); if (!goodResult) { - throw new RuntimeException("Errors found during compile."); + error("Errors found during compile."); } } + + static int errors = 0; + + static void error(String msg) { + System.out.println("Error: " + msg); + errors++; + } } @Retention(RUNTIME) 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 0bbff60766b..ec1fe05015e 100644 --- a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java +++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java @@ -24,7 +24,7 @@ /* * @test - * @bug 6639645 + * @bug 6639645 7026414 * @summary Modeling type implementing missing interfaces * @library ../../../../lib * @build JavacTestingAbstractProcessor TestMissingElement @@ -112,6 +112,7 @@ public class TestMissingElement extends JavacTestingAbstractProcessor { @Override public String visitDeclared(DeclaredType t, Void ignore) { + checkEqual(t.asElement(), types.asElement(t)); String s = asString(t.asElement()); List args = t.getTypeArguments(); if (!args.isEmpty()) @@ -179,6 +180,13 @@ public class TestMissingElement extends JavacTestingAbstractProcessor { return (e != null && e.getKind() == ElementKind.PACKAGE && ((PackageElement) e).isUnnamed()); } + + void checkEqual(Element e1, Element e2) { + if (e1 != e2) { + throw new AssertionError("elements not equal as expected: " + + e1 + ", " + e2); + } + } } diff --git a/langtools/test/tools/javac/processing/options/testCommandLineClasses/Test.java b/langtools/test/tools/javac/processing/options/testCommandLineClasses/Test.java new file mode 100644 index 00000000000..f9287e695d8 --- /dev/null +++ b/langtools/test/tools/javac/processing/options/testCommandLineClasses/Test.java @@ -0,0 +1,106 @@ +/* + * 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 6930508 + * @summary Passing nested class names on javac command line interfere with subsequent name -> class lookup + * @library ../../../lib + * @build JavacTestingAbstractProcessor p.NestedExamples Test + * @run main Test + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; +import javax.tools.*; + +import p.NestedExamples; + +public class Test extends JavacTestingAbstractProcessor { + public static void main(String... args) throws Exception { + new Test().run(); + } + + void run() throws Exception { + NestedExamples e = new NestedExamples(); + List names = getNames(e.getClasses()); + test(names); + test(reverse(names)); + names = Arrays.asList(e.getClassNames()); + test(names); + test(reverse(names)); + + if (errors > 0) + throw new RuntimeException(errors + " errors occurred"); + } + + List getNames(Class[] classes) { + List names = new ArrayList(); + for (Class c: classes) + names.add(c.getName()); + return names; + } + + void test(List names) throws Exception { + System.err.println("test: " + names); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); + File testClasses = new File(System.getProperty("test.classes")); + fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(testClasses)); + JavaCompiler.CompilationTask task = compiler.getTask( + null, null, null, Arrays.asList("-proc:only"), names, null); + task.setProcessors(Arrays.asList(new Test())); + boolean ok = task.call(); + if (!ok) + error("compilation failed"); + System.err.println(); + } + + List reverse(List list) { + List newList = new ArrayList(list); + Collections.reverse(newList); + return newList; + } + + int errors = 0; + + void error(String msg) { + System.out.println("Error: " + msg); + errors++; + } + + //---------- + + public boolean process(Set annotations, + RoundEnvironment roundEnv) { + if (!roundEnv.processingOver()) { + for (TypeElement typeElt : ElementFilter.typesIn(roundEnv.getRootElements())) { + messager.printMessage(Diagnostic.Kind.NOTE, "processing " + typeElt); + } + } + return true; + } +} diff --git a/langtools/test/tools/javac/processing/options/testCommandLineClasses/p/NestedExamples.java b/langtools/test/tools/javac/processing/options/testCommandLineClasses/p/NestedExamples.java new file mode 100644 index 00000000000..80a344c1b5f --- /dev/null +++ b/langtools/test/tools/javac/processing/options/testCommandLineClasses/p/NestedExamples.java @@ -0,0 +1,63 @@ +/* + * 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. + */ + +package p; + +public class NestedExamples { + static class MemberClass1 { } + + class MemberClass2 { } + + class Win$$AtVegas { } // Class with funny name. + + public Class[] getClasses() { + class LocalClass { } + + Object o = new Object() { // An anonymous class + @Override + public String toString() { + return "I have no name!"; + } + }; + + return new Class[] { + NestedExamples.class, + MemberClass1.class, + MemberClass2.class, + Win$$AtVegas.class, + LocalClass.class, + o.getClass() + }; + } + + public String[] getClassNames() { + return new String[] { + "p.NestedExamples", + "p.NestedExamples.MemberClass1", + "p.NestedExamples.MemberClass2", + "p.NestedExamples.Win$$AtVegas" + }; + } +} + + diff --git a/langtools/test/tools/javac/processing/options/testPrintProcessorInfo/Test.java b/langtools/test/tools/javac/processing/options/testPrintProcessorInfo/Test.java new file mode 100644 index 00000000000..c16ccc6606c --- /dev/null +++ b/langtools/test/tools/javac/processing/options/testPrintProcessorInfo/Test.java @@ -0,0 +1,74 @@ +/* + * 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 6987384 + * @summary -XprintProcessorRoundsInfo message printed with different timing than previous + * @library ../../../lib + * @build JavacTestingAbstractProcessor Test + * @compile/fail/ref=Test.out -XDrawDiagnostics -XprintProcessorInfo -Werror -proc:only -processor Test Test.java + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.lang.model.util.*; +import javax.tools.*; + +public class Test extends JavacTestingAbstractProcessor { + final int MAX_ROUNDS = 3; + int round = 0; + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + round++; + messager.printMessage(Diagnostic.Kind.NOTE, "round " + round); + if (round <= MAX_ROUNDS) + generateSource("Gen" + round); + if (roundEnv.processingOver()) + messager.printMessage(Diagnostic.Kind.WARNING, "last round"); + return true; + } + + void generateSource(String name) { + String text = "class " + name + " { }\n"; + + // avoid try-with-resources so test can be run on older builds + try { + Writer out = filer.createSourceFile(name).openWriter(); + try { + out.write(text); + } finally { + out.close(); + } + } catch (IOException e) { + throw new Error(e); + } + } +} + + + diff --git a/langtools/test/tools/javac/processing/options/testPrintProcessorInfo/Test.out b/langtools/test/tools/javac/processing/options/testPrintProcessorInfo/Test.out new file mode 100644 index 00000000000..0e22a7f5240 --- /dev/null +++ b/langtools/test/tools/javac/processing/options/testPrintProcessorInfo/Test.out @@ -0,0 +1,13 @@ +Processor Test matches [java.lang.Override] and returns true. +- compiler.note.proc.messager: round 1 +Processor Test matches [] and returns true. +- compiler.note.proc.messager: round 2 +Processor Test matches [] and returns true. +- compiler.note.proc.messager: round 3 +Processor Test matches [] and returns true. +- compiler.note.proc.messager: round 4 +- compiler.note.proc.messager: round 5 +- compiler.warn.proc.messager: last round +- compiler.err.warnings.and.werror +1 error +1 warning