From b0fc35dfc04539e65dd3bb5814bc9d34f228174c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Wed, 8 Feb 2017 11:57:41 +0100 Subject: [PATCH 01/59] 8171539: Better script accessibility for JavaScript Reviewed-by: jlaskey, sundar --- .../jdk/nashorn/internal/objects/Global.java | 33 +++++++--- .../runtime/test/ClassFilterTest.java | 60 +++++++++++++++++++ 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java index dc172a88683..9a6b5eae76d 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java @@ -90,9 +90,9 @@ import jdk.nashorn.tools.ShellFunctions; @ScriptClass("Global") public final class Global extends Scope { // This special value is used to flag a lazily initialized global property. - // This also serves as placeholder value used in place of a location property - // (__FILE__, __DIR__, __LINE__) private static final Object LAZY_SENTINEL = new Object(); + // This serves as placeholder value used in place of a location property (__FILE__, __DIR__, __LINE__) + private static final Object LOCATION_PLACEHOLDER = new Object(); private static final String PACKAGE_PREFIX = "jdk.nashorn.internal.objects."; @@ -916,7 +916,7 @@ public final class Global extends Scope { public volatile Object org; /** - * Getter for the Nashorn extension: Java access - global.javaImporter. + * Getter for the Nashorn extension: Java access - global.JavaImporter. * * @param self self reference * @return the value of the JavaImporter property @@ -931,7 +931,7 @@ public final class Global extends Scope { } /** - * Setter for the Nashorn extension: Java access - global.javaImporter. + * Setter for the Nashorn extension: Java access - global.JavaImporter. * * @param self self reference * @param value value of the JavaImporter property @@ -975,15 +975,15 @@ public final class Global extends Scope { /** Nashorn extension: current script's file name */ @Property(name = "__FILE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT) - public static final Object __FILE__ = LAZY_SENTINEL; + public static final Object __FILE__ = LOCATION_PLACEHOLDER; /** Nashorn extension: current script's directory */ @Property(name = "__DIR__", attributes = Attribute.NON_ENUMERABLE_CONSTANT) - public static final Object __DIR__ = LAZY_SENTINEL; + public static final Object __DIR__ = LOCATION_PLACEHOLDER; /** Nashorn extension: current source line number being executed */ @Property(name = "__LINE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT) - public static final Object __LINE__ = LAZY_SENTINEL; + public static final Object __LINE__ = LOCATION_PLACEHOLDER; private volatile NativeDate DEFAULT_DATE; @@ -2093,6 +2093,9 @@ public final class Global extends Scope { } private synchronized ScriptFunction getBuiltinJavaImporter() { + if (getContext().getEnv()._no_java) { + throw new IllegalStateException(); + } if (this.builtinJavaImporter == null) { this.builtinJavaImporter = initConstructor("JavaImporter", ScriptFunction.class); } @@ -2100,6 +2103,9 @@ public final class Global extends Scope { } private synchronized ScriptObject getBuiltinJavaApi() { + if (getContext().getEnv()._no_java) { + throw new IllegalStateException(); + } if (this.builtinJavaApi == null) { this.builtinJavaApi = initConstructor("Java", ScriptObject.class); this.builtInJavaExtend = (ScriptFunction)builtinJavaApi.get("extend"); @@ -2325,7 +2331,7 @@ public final class Global extends Scope { * @return true if the value is a placeholder, false otherwise. */ public static boolean isLocationPropertyPlaceholder(final Object placeholder) { - return placeholder == LAZY_SENTINEL; + return placeholder == LOCATION_PLACEHOLDER; } /** @@ -2628,6 +2634,17 @@ public final class Global extends Scope { this.javaApi = LAZY_SENTINEL; this.javaImporter = LAZY_SENTINEL; initJavaAccess(); + } else { + // delete nasgen-created global properties related to java access + this.delete("Java", false); + this.delete("JavaImporter", false); + this.delete("Packages", false); + this.delete("com", false); + this.delete("edu", false); + this.delete("java", false); + this.delete("javafx", false); + this.delete("javax", false); + this.delete("org", false); } if (! env._no_typed_arrays) { diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/test/ClassFilterTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/test/ClassFilterTest.java index 7f535405663..a01e223d5ae 100644 --- a/nashorn/test/src/jdk/nashorn/internal/runtime/test/ClassFilterTest.java +++ b/nashorn/test/src/jdk/nashorn/internal/runtime/test/ClassFilterTest.java @@ -25,6 +25,7 @@ package jdk.nashorn.internal.runtime.test; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; import java.io.File; import javax.script.ScriptEngine; @@ -77,6 +78,65 @@ public class ClassFilterTest { } catch (final ScriptException e) { //emtpy } + try { + engine.eval("Java"); + fail("TypeError should have been thrown"); + } catch (final ScriptException e) { + //emtpy + } + try { + engine.eval("JavaImporter"); + fail("TypeError should have been thrown"); + } catch (final ScriptException e) { + //emtpy + } + try { + engine.eval("Packages"); + fail("TypeError should have been thrown"); + } catch (final ScriptException e) { + //emtpy + } + try { + engine.eval("com"); + fail("TypeError should have been thrown"); + } catch (final ScriptException e) { + //emtpy + } + try { + engine.eval("edu"); + fail("TypeError should have been thrown"); + } catch (final ScriptException e) { + //emtpy + } + try { + engine.eval("java"); + fail("TypeError should have been thrown"); + } catch (final ScriptException e) { + //emtpy + } + try { + engine.eval("javafx"); + fail("TypeError should have been thrown"); + } catch (final ScriptException e) { + //emtpy + } + try { + engine.eval("javax"); + fail("TypeError should have been thrown"); + } catch (final ScriptException e) { + //emtpy + } + try { + engine.eval("org"); + fail("TypeError should have been thrown"); + } catch (final ScriptException e) { + //emtpy + } + try { + assertEquals(engine.eval("Java = this[\"__LINE__\"]; Java === this[\"__LINE__\"]"), Boolean.TRUE); + } catch (final ScriptException e) { + fail("Unexpected exception", e); + } } @Test From 2098d07f0f963c7f797b5c344a6aab1928e09f1c Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Tue, 14 Feb 2017 10:14:06 -0800 Subject: [PATCH 02/59] 8172469: Transform Transformer Exceptions Reviewed-by: dfuchs, lancea, rriggs --- .../dtm/DTMConfigurationException.java | 100 ------- .../apache/xml/internal/dtm/DTMException.java | 273 +----------------- .../apache/xml/internal/dtm/DTMManager.java | 68 +---- .../xml/transform/TransformerException.java | 135 +++++---- 4 files changed, 73 insertions(+), 503 deletions(-) delete mode 100644 jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMConfigurationException.java diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMConfigurationException.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMConfigurationException.java deleted file mode 100644 index dffbc9891a0..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMConfigurationException.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.xml.internal.dtm; - -import javax.xml.transform.SourceLocator; - -/** - * Indicates a serious configuration error. - */ -public class DTMConfigurationException extends DTMException { - static final long serialVersionUID = -4607874078818418046L; - - /** - * Create a new DTMConfigurationException with no - * detail message. - */ - public DTMConfigurationException() { - super("Configuration Error"); - } - - /** - * Create a new DTMConfigurationException with - * the String specified as an error message. - * - * @param msg The error message for the exception. - */ - public DTMConfigurationException(String msg) { - super(msg); - } - - /** - * Create a new DTMConfigurationException with a - * given Exception base cause of the error. - * - * @param e The exception to be encapsulated in a - * DTMConfigurationException. - */ - public DTMConfigurationException(Throwable e) { - super(e); - } - - /** - * Create a new DTMConfigurationException with the - * given Exception base cause and detail message. - * - * @param msg The detail message. - * @param e The exception to be wrapped in a DTMConfigurationException - */ - public DTMConfigurationException(String msg, Throwable e) { - super(msg, e); - } - - /** - * Create a new DTMConfigurationException from a message and a Locator. - * - *

This constructor is especially useful when an application is - * creating its own exception from within a DocumentHandler - * callback.

- * - * @param message The error or warning message. - * @param locator The locator object for the error or warning. - */ - public DTMConfigurationException(String message, - SourceLocator locator) { - super(message, locator); - } - - /** - * Wrap an existing exception in a DTMConfigurationException. - * - * @param message The error or warning message, or null to - * use the message from the embedded exception. - * @param locator The locator object for the error or warning. - * @param e Any exception. - */ - public DTMConfigurationException(String message, - SourceLocator locator, - Throwable e) { - super(message, locator, e); - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMException.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMException.java index 9e8f68ecb46..584827b795f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMException.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMException.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,124 +20,20 @@ package com.sun.org.apache.xml.internal.dtm; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import javax.xml.transform.SourceLocator; - -import com.sun.org.apache.xml.internal.res.XMLErrorResources; -import com.sun.org.apache.xml.internal.res.XMLMessages; - - /** - * This class specifies an exceptional condition that occured + * This class specifies an exceptional condition that occurred * in the DTM module. */ public class DTMException extends RuntimeException { static final long serialVersionUID = -775576419181334734L; - /** Field locator specifies where the error occured. - * @serial */ - SourceLocator locator; - - /** - * Method getLocator retrieves an instance of a SourceLocator - * object that specifies where an error occured. - * - * @return A SourceLocator object, or null if none was specified. - */ - public SourceLocator getLocator() { - return locator; - } - - /** - * Method setLocator sets an instance of a SourceLocator - * object that specifies where an error occured. - * - * @param location A SourceLocator object, or null to clear the location. - */ - public void setLocator(SourceLocator location) { - locator = location; - } - - /** Field containedException specifies a wrapped exception. May be null. - * @serial */ - Throwable containedException; - - /** - * This method retrieves an exception that this exception wraps. - * - * @return An Throwable object, or null. - * @see #getCause - */ - public Throwable getException() { - return containedException; - } - - /** - * Returns the cause of this throwable or null if the - * cause is nonexistent or unknown. (The cause is the throwable that - * caused this throwable to get thrown.) - */ - public Throwable getCause() { - - return ((containedException == this) - ? null - : containedException); - } - - /** - * Initializes the cause of this throwable to the specified value. - * (The cause is the throwable that caused this throwable to get thrown.) - * - *

This method can be called at most once. It is generally called from - * within the constructor, or immediately after creating the - * throwable. If this throwable was created - * with {@link #DTMException(Throwable)} or - * {@link #DTMException(String,Throwable)}, this method cannot be called - * even once. - * - * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method). (A null value is - * permitted, and indicates that the cause is nonexistent or - * unknown.) - * @return a reference to this Throwable instance. - * @throws IllegalArgumentException if cause is this - * throwable. (A throwable cannot - * be its own cause.) - * @throws IllegalStateException if this throwable was - * created with {@link #DTMException(Throwable)} or - * {@link #DTMException(String,Throwable)}, or this method has already - * been called on this throwable. - */ - public synchronized Throwable initCause(Throwable cause) { - - if ((this.containedException == null) && (cause != null)) { - throw new IllegalStateException(XMLMessages.createXMLMessage(XMLErrorResources.ER_CANNOT_OVERWRITE_CAUSE, null)); //"Can't overwrite cause"); - } - - if (cause == this) { - throw new IllegalArgumentException( - XMLMessages.createXMLMessage(XMLErrorResources.ER_SELF_CAUSATION_NOT_PERMITTED, null)); //"Self-causation not permitted"); - } - - this.containedException = cause; - - return this; - } - /** * Create a new DTMException. * * @param message The error or warning message. */ public DTMException(String message) { - super(message); - - this.containedException = null; - this.locator = null; } /** @@ -147,11 +42,7 @@ public class DTMException extends RuntimeException { * @param e The exception to be wrapped. */ public DTMException(Throwable e) { - - super(e.getMessage()); - - this.containedException = e; - this.locator = null; + super(e); } /** @@ -165,162 +56,6 @@ public class DTMException extends RuntimeException { * @param e Any exception */ public DTMException(String message, Throwable e) { - - super(((message == null) || (message.length() == 0)) - ? e.getMessage() - : message); - - this.containedException = e; - this.locator = null; + super(message, e); } - - /** - * Create a new DTMException from a message and a Locator. - * - *

This constructor is especially useful when an application is - * creating its own exception from within a DocumentHandler - * callback.

- * - * @param message The error or warning message. - * @param locator The locator object for the error or warning. - */ - public DTMException(String message, SourceLocator locator) { - - super(message); - - this.containedException = null; - this.locator = locator; } - - /** - * Wrap an existing exception in a DTMException. - * - * @param message The error or warning message, or null to - * use the message from the embedded exception. - * @param locator The locator object for the error or warning. - * @param e Any exception - */ - public DTMException(String message, SourceLocator locator, - Throwable e) { - - super(message); - - this.containedException = e; - this.locator = locator; - } - - /** - * Get the error message with location information - * appended. - */ - public String getMessageAndLocation() { - - StringBuffer sbuffer = new StringBuffer(); - String message = super.getMessage(); - - if (null != message) { - sbuffer.append(message); - } - - if (null != locator) { - String systemID = locator.getSystemId(); - int line = locator.getLineNumber(); - int column = locator.getColumnNumber(); - - if (null != systemID) { - sbuffer.append("; SystemID: "); - sbuffer.append(systemID); - } - - if (0 != line) { - sbuffer.append("; Line#: "); - sbuffer.append(line); - } - - if (0 != column) { - sbuffer.append("; Column#: "); - sbuffer.append(column); - } - } - - return sbuffer.toString(); - } - - /** - * Get the location information as a string. - * - * @return A string with location info, or null - * if there is no location information. - */ - public String getLocationAsString() { - - if (null != locator) { - StringBuffer sbuffer = new StringBuffer(); - String systemID = locator.getSystemId(); - int line = locator.getLineNumber(); - int column = locator.getColumnNumber(); - - if (null != systemID) { - sbuffer.append("; SystemID: "); - sbuffer.append(systemID); - } - - if (0 != line) { - sbuffer.append("; Line#: "); - sbuffer.append(line); - } - - if (0 != column) { - sbuffer.append("; Column#: "); - sbuffer.append(column); - } - - return sbuffer.toString(); - } else { - return null; - } - } - - /** - * Print the the trace of methods from where the error - * originated. This will trace all nested exception - * objects, as well as this object. - */ - public void printStackTrace() { - printStackTrace(new java.io.PrintWriter(System.err, true)); - } - - /** - * Print the the trace of methods from where the error - * originated. This will trace all nested exception - * objects, as well as this object. - * @param s The stream where the dump will be sent to. - */ - public void printStackTrace(java.io.PrintStream s) { - printStackTrace(new java.io.PrintWriter(s)); - } - - /** - * Print the the trace of methods from where the error - * originated. This will trace all nested exception - * objects, as well as this object. - * @param s The writer where the dump will be sent to. - */ - public void printStackTrace(java.io.PrintWriter s) { - - if (s == null) { - s = new java.io.PrintWriter(System.err, true); - } - - try { - String locInfo = getLocationAsString(); - - if (null != locInfo) { - s.println(locInfo); - } - - super.printStackTrace(s); - } catch (Throwable e) {} - - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMManager.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMManager.java index 052dea8cf97..e2719e8e487 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMManager.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMManager.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,12 +20,8 @@ package com.sun.org.apache.xml.internal.dtm; -import com.sun.org.apache.xml.internal.res.XMLErrorResources; -import com.sun.org.apache.xml.internal.res.XMLMessages; import com.sun.org.apache.xml.internal.utils.PrefixResolver; import com.sun.org.apache.xml.internal.utils.XMLStringFactory; -import com.sun.org.apache.xalan.internal.utils.ObjectFactory; -import com.sun.org.apache.xalan.internal.utils.SecuritySupport; /** * A DTMManager instance can be used to create DTM and @@ -99,11 +94,11 @@ public abstract class DTMManager * * @return new DTMManager instance, never null. * - * @throws DTMConfigurationException + * @throws DTMException * if the implementation is not available or cannot be instantiated. */ public static DTMManager newInstance(XMLStringFactory xsf) - throws DTMConfigurationException + throws DTMException { final DTMManager factoryImpl = new com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault(); factoryImpl.setXMLStringFactory(xsf); @@ -315,20 +310,6 @@ public abstract class DTMManager // -------------------- private methods -------------------- - /** - * Temp debug code - this will be removed after we test everything - */ - private static boolean debug; - - static - { - try - { - debug = SecuritySupport.getSystemProperty("dtm.debug") != null; - } - catch (SecurityException ex){} - } - /** This value, set at compile time, controls how many bits of the * DTM node identifier numbers are used to identify a node within a * document, and thus sets the maximum number of nodes per @@ -394,47 +375,4 @@ public abstract class DTMManager { return IDENT_NODE_DEFAULT; } - - // - // Classes - // - - /** - * A configuration error. - * Originally in ObjectFactory. This is the only portion used in this package - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = 5122054096615067992L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - } diff --git a/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerException.java b/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerException.java index 78a058c322d..b18ee414e64 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerException.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,36 +27,45 @@ package javax.xml.transform; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.CodeSigner; +import java.security.CodeSource; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.PrivilegedAction; +import java.security.ProtectionDomain; +import java.util.Objects; /** - * This class specifies an exceptional condition that occured + * This class specifies an exceptional condition that occurred * during the transformation process. * * @since 1.4 */ public class TransformerException extends Exception { - /** Field locator specifies where the error occured */ + /** Field locator specifies where the error occurred */ SourceLocator locator; /** * Method getLocator retrieves an instance of a SourceLocator - * object that specifies where an error occured. + * object that specifies where an error occurred. * * @return A SourceLocator object, or null if none was specified. */ public SourceLocator getLocator() { - return locator; + return this.locator; } /** * Method setLocator sets an instance of a SourceLocator - * object that specifies where an error occured. + * object that specifies where an error occurred. * * @param location A SourceLocator object, or null to clear the location. */ public void setLocator(SourceLocator location) { - locator = location; + this.locator = location; } /** Field containedException specifies a wrapped exception. May be null. */ @@ -76,7 +85,9 @@ public class TransformerException extends Exception { * Returns the cause of this throwable or null if the * cause is nonexistent or unknown. (The cause is the throwable that * caused this throwable to get thrown.) + * @return the cause, or null if unknown */ + @Override public Throwable getCause() { return ((containedException == this) @@ -108,6 +119,7 @@ public class TransformerException extends Exception { * {@link #TransformerException(String,Throwable)}, or this method has already * been called on this throwable. */ + @Override public synchronized Throwable initCause(Throwable cause) { // TransformerException doesn't set its cause (probably @@ -136,11 +148,7 @@ public class TransformerException extends Exception { * @param message The error or warning message. */ public TransformerException(String message) { - - super(message); - - this.containedException = null; - this.locator = null; + this(message, null, null); } /** @@ -149,11 +157,7 @@ public class TransformerException extends Exception { * @param e The exception to be wrapped. */ public TransformerException(Throwable e) { - - super(e.toString()); - - this.containedException = e; - this.locator = null; + this(null, null, e); } /** @@ -167,13 +171,7 @@ public class TransformerException extends Exception { * @param e Any exception */ public TransformerException(String message, Throwable e) { - - super(((message == null) || (message.length() == 0)) - ? e.toString() - : message); - - this.containedException = e; - this.locator = null; + this(message, null, e); } /** @@ -187,11 +185,7 @@ public class TransformerException extends Exception { * @param locator The locator object for the error or warning. */ public TransformerException(String message, SourceLocator locator) { - - super(message); - - this.containedException = null; - this.locator = locator; + this(message, locator, null); } /** @@ -204,8 +198,9 @@ public class TransformerException extends Exception { */ public TransformerException(String message, SourceLocator locator, Throwable e) { - - super(message); + super(((message == null) || (message.length() == 0)) + ? ((e == null) ? "" : e.toString()) + : message); this.containedException = e; this.locator = locator; @@ -219,34 +214,9 @@ public class TransformerException extends Exception { * location information appended. */ public String getMessageAndLocation() { - - StringBuffer sbuffer = new StringBuffer(); - String message = super.getMessage(); - - if (null != message) { - sbuffer.append(message); - } - - if (null != locator) { - String systemID = locator.getSystemId(); - int line = locator.getLineNumber(); - int column = locator.getColumnNumber(); - - if (null != systemID) { - sbuffer.append("; SystemID: "); - sbuffer.append(systemID); - } - - if (0 != line) { - sbuffer.append("; Line#: "); - sbuffer.append(line); - } - - if (0 != column) { - sbuffer.append("; Column#: "); - sbuffer.append(column); - } - } + StringBuilder sbuffer = new StringBuilder(); + sbuffer.append(Objects.toString(super.getMessage(), "")); + sbuffer.append(Objects.toString(getLocationAsString(), "")); return sbuffer.toString(); } @@ -258,9 +228,29 @@ public class TransformerException extends Exception { * if there is no location information. */ public String getLocationAsString() { + if (locator == null) { + return null; + } - if (null != locator) { - StringBuffer sbuffer = new StringBuffer(); + if (System.getSecurityManager() == null) { + return getLocationString(); + } else { + return AccessController.doPrivileged((PrivilegedAction) () -> + getLocationString(), + new AccessControlContext(new ProtectionDomain[] {getNonPrivDomain()})); + } + } + + /** + * Constructs the location string. + * @return the location string + */ + private String getLocationString() { + if (locator == null) { + return null; + } + + StringBuilder sbuffer = new StringBuilder(); String systemID = locator.getSystemId(); int line = locator.getLineNumber(); int column = locator.getColumnNumber(); @@ -281,9 +271,6 @@ public class TransformerException extends Exception { } return sbuffer.toString(); - } else { - return null; - } } /** @@ -291,6 +278,7 @@ public class TransformerException extends Exception { * originated. This will trace all nested exception * objects, as well as this object. */ + @Override public void printStackTrace() { printStackTrace(new java.io.PrintWriter(System.err, true)); } @@ -301,6 +289,7 @@ public class TransformerException extends Exception { * objects, as well as this object. * @param s The stream where the dump will be sent to. */ + @Override public void printStackTrace(java.io.PrintStream s) { printStackTrace(new java.io.PrintWriter(s)); } @@ -311,6 +300,7 @@ public class TransformerException extends Exception { * objects, as well as this object. * @param s The writer where the dump will be sent to. */ + @Override public void printStackTrace(java.io.PrintWriter s) { if (s == null) { @@ -358,11 +348,8 @@ public class TransformerException extends Exception { } else { exception = null; } - } catch (InvocationTargetException ite) { - exception = null; - } catch (IllegalAccessException iae) { - exception = null; - } catch (NoSuchMethodException nsme) { + } catch (InvocationTargetException | IllegalAccessException + | NoSuchMethodException e) { exception = null; } } @@ -371,4 +358,14 @@ public class TransformerException extends Exception { s.flush(); } } + + /** + * Creates a ProtectionDomain that has no permission. + * @return a ProtectionDomain + */ + private ProtectionDomain getNonPrivDomain() { + CodeSource nullSource = new CodeSource(null, (CodeSigner[]) null); + PermissionCollection noPermission = new Permissions(); + return new ProtectionDomain(nullSource, noPermission); +} } From b6c0d9ee2318f44878364f9c6528b421f1d43282 Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Thu, 23 Mar 2017 15:14:18 +0100 Subject: [PATCH 03/59] 8173770: Image conversion improvements Reviewed-by: kvn, vlivanov, dlong, rhalade, mschoene, iignatyev --- hotspot/src/cpu/arm/vm/arm.ad | 216 ++++++++++++++++++++ hotspot/src/cpu/sparc/vm/sparc.ad | 134 ++++++++++++ hotspot/src/cpu/x86/vm/x86_32.ad | 152 +++++++++++++- hotspot/src/cpu/x86/vm/x86_64.ad | 42 ++++ hotspot/src/share/vm/adlc/archDesc.cpp | 1 + hotspot/src/share/vm/opto/classes.hpp | 1 + hotspot/src/share/vm/opto/loopPredicate.cpp | 155 +++++++++++--- hotspot/src/share/vm/opto/loopnode.hpp | 4 +- hotspot/src/share/vm/opto/output.cpp | 1 + hotspot/src/share/vm/opto/subnode.cpp | 54 +++++ hotspot/src/share/vm/opto/subnode.hpp | 9 + hotspot/src/share/vm/runtime/vmStructs.cpp | 1 + 12 files changed, 739 insertions(+), 31 deletions(-) diff --git a/hotspot/src/cpu/arm/vm/arm.ad b/hotspot/src/cpu/arm/vm/arm.ad index ef84124ef43..f4e5bd324cd 100644 --- a/hotspot/src/cpu/arm/vm/arm.ad +++ b/hotspot/src/cpu/arm/vm/arm.ad @@ -2695,6 +2695,30 @@ operand flagsRegL_LEGT() %{ format %{ "apsr_L_LEGT" %} interface(REG_INTER); %} + +operand flagsRegUL_LTGE() %{ + constraint(ALLOC_IN_RC(int_flags)); + match(RegFlags); + + format %{ "apsr_UL_LTGE" %} + interface(REG_INTER); +%} + +operand flagsRegUL_EQNE() %{ + constraint(ALLOC_IN_RC(int_flags)); + match(RegFlags); + + format %{ "apsr_UL_EQNE" %} + interface(REG_INTER); +%} + +operand flagsRegUL_LEGT() %{ + constraint(ALLOC_IN_RC(int_flags)); + match(RegFlags); + + format %{ "apsr_UL_LEGT" %} + interface(REG_INTER); +%} #endif // Condition Code Register, floating comparisons, unordered same as "less". @@ -3249,6 +3273,39 @@ operand cmpOpL_commute() %{ %} %} +operand cmpOpUL() %{ + match(Bool); + + format %{ "UL" %} + interface(COND_INTER) %{ + equal(0x0); + not_equal(0x1); + less(0x3); + greater_equal(0x2); + less_equal(0x9); + greater(0x8); + overflow(0x0); // unsupported/unimplemented + no_overflow(0x0); // unsupported/unimplemented + %} +%} + +operand cmpOpUL_commute() %{ + match(Bool); + + format %{ "UL" %} + interface(COND_INTER) %{ + equal(0x0); + not_equal(0x1); + less(0x8); + greater_equal(0x9); + less_equal(0x2); + greater(0x3); + overflow(0x0); // unsupported/unimplemented + no_overflow(0x0); // unsupported/unimplemented + %} +%} + + //----------OPERAND CLASSES---------------------------------------------------- // Operand Classes are groups of operands that are used to simplify // instruction definitions by not requiring the AD writer to specify separate @@ -10467,6 +10524,17 @@ instruct compL_reg_reg(flagsReg xcc, iRegL op1, iRegL op2) %} ins_pipe(ialu_cconly_reg_reg); %} + +instruct compUL_iReg(flagsRegU xcc, iRegL op1, iRegL op2) %{ + match(Set xcc (CmpUL op1 op2)); + + size(4); + format %{ "CMP $op1,$op2\t! unsigned long" %} + ins_encode %{ + __ cmp($op1$$Register, $op2$$Register); + %} + ins_pipe(ialu_cconly_reg_reg); +%} #else instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{ match(Set xcc (CmpL op1 op2)); @@ -10481,6 +10549,20 @@ instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %} ins_pipe(ialu_cconly_reg_reg); %} + +instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{ + match(Set xcc (CmpUL op1 op2)); + effect(DEF xcc, USE op1, USE op2, TEMP tmp); + + size(8); + format %{ "SUBS $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t" + "SBCS $tmp,$op1.hi,$op2.hi" %} + ins_encode %{ + __ subs($tmp$$Register, $op1$$Register, $op2$$Register); + __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor()); + %} + ins_pipe(ialu_cconly_reg_reg); +%} #endif #ifdef AARCH64 @@ -10496,6 +10578,19 @@ instruct compL_reg_con(flagsReg xcc, iRegL op1, aimmL con) %{ ins_pipe(ialu_cconly_reg_imm); %} + +instruct compUL_reg_con(flagsRegU xcc, iRegL op1, aimmL con) %{ + match(Set xcc (CmpUL op1 con)); + effect(DEF xcc, USE op1, USE con); + + size(8); + format %{ "CMP $op1,$con\t\t! unsigned long" %} + ins_encode %{ + __ cmp($op1$$Register, $con$$constant); + %} + + ins_pipe(ialu_cconly_reg_imm); +%} #else instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{ match(Set xcc (CmpL op1 op2)); @@ -10575,6 +10670,85 @@ instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL ins_pipe(ialu_cconly_reg_reg); %} + +instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{ + match(Set xcc (CmpUL op1 op2)); + effect(DEF xcc, USE op1, USE op2); + + size(8); + format %{ "TEQ $op1.hi,$op2.hi\t\t! unsigned long\n\t" + "TEQ.eq $op1.lo,$op2.lo" %} + ins_encode %{ + __ teq($op1$$Register->successor(), $op2$$Register->successor()); + __ teq($op1$$Register, $op2$$Register, eq); + %} + ins_pipe(ialu_cconly_reg_reg); +%} + +instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{ + match(Set xcc (CmpUL op1 op2)); + effect(DEF xcc, USE op1, USE op2, TEMP tmp); + + size(8); + format %{ "SUBS $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t" + "SBCS $tmp,$op2.hi,$op1.hi" %} + ins_encode %{ + __ subs($tmp$$Register, $op2$$Register, $op1$$Register); + __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor()); + %} + ins_pipe(ialu_cconly_reg_reg); +%} + +// TODO: try immLRot2 instead, (0, $con$$constant) becomes +// (hi($con$$constant), lo($con$$constant)) becomes +instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{ + match(Set xcc (CmpUL op1 con)); + effect(DEF xcc, USE op1, USE con, TEMP tmp); + + size(8); + format %{ "SUBS $tmp,$op1.low,$con\t\t! unsigned long\n\t" + "SBCS $tmp,$op1.hi,0" %} + ins_encode %{ + __ subs($tmp$$Register, $op1$$Register, $con$$constant); + __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0); + %} + + ins_pipe(ialu_cconly_reg_reg); +%} + +// TODO: try immLRot2 instead, (0, $con$$constant) becomes +// (hi($con$$constant), lo($con$$constant)) becomes +instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{ + match(Set xcc (CmpUL op1 con)); + effect(DEF xcc, USE op1, USE con); + + size(8); + format %{ "TEQ $op1.hi,0\t\t! unsigned long\n\t" + "TEQ.eq $op1.lo,$con" %} + ins_encode %{ + __ teq($op1$$Register->successor(), 0); + __ teq($op1$$Register, $con$$constant, eq); + %} + + ins_pipe(ialu_cconly_reg_reg); +%} + +// TODO: try immLRot2 instead, (0, $con$$constant) becomes +// (hi($con$$constant), lo($con$$constant)) becomes +instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{ + match(Set xcc (CmpUL op1 con)); + effect(DEF xcc, USE op1, USE con, TEMP tmp); + + size(8); + format %{ "RSBS $tmp,$op1.low,$con\t\t! unsigned long\n\t" + "RSCS $tmp,$op1.hi,0" %} + ins_encode %{ + __ rsbs($tmp$$Register, $op1$$Register, $con$$constant); + __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0); + %} + + ins_pipe(ialu_cconly_reg_reg); +%} #endif /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */ @@ -11126,6 +11300,48 @@ instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{ %} ins_pipe(br_cc); %} + +instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{ + match(If cmp xcc); + effect(USE labl); + predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); + + size(4); + ins_cost(BRANCH_COST); + format %{ "B$cmp $xcc,$labl" %} + ins_encode %{ + __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(br_cc); +%} + +instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{ + match(If cmp xcc); + effect(USE labl); + predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); + + size(4); + ins_cost(BRANCH_COST); + format %{ "B$cmp $xcc,$labl" %} + ins_encode %{ + __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(br_cc); +%} + +instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{ + match(If cmp xcc); + effect(USE labl); + predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le); + + size(4); + ins_cost(BRANCH_COST); + format %{ "B$cmp $xcc,$labl" %} + ins_encode %{ + __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(br_cc); +%} #endif instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{ diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad index fa0bedae739..35e90204b68 100644 --- a/hotspot/src/cpu/sparc/vm/sparc.ad +++ b/hotspot/src/cpu/sparc/vm/sparc.ad @@ -3403,6 +3403,16 @@ operand immU12() %{ interface(CONST_INTER); %} +// Unsigned Long Immediate: 12-bit (non-negative that fits in simm13) +operand immUL12() %{ + predicate((0 <= n->get_long()) && (n->get_long() == (int)n->get_long()) && Assembler::is_simm13((int)n->get_long())); + match(ConL); + op_cost(0); + + format %{ %} + interface(CONST_INTER); +%} + // Integer Immediate non-negative operand immU31() %{ @@ -3936,6 +3946,15 @@ operand flagsRegL() %{ interface(REG_INTER); %} +// Condition Code Register, unsigned long comparisons. +operand flagsRegUL() %{ + constraint(ALLOC_IN_RC(int_flags)); + match(RegFlags); + + format %{ "xcc_UL" %} + interface(REG_INTER); +%} + // Condition Code Register, floating comparisons, unordered same as "less". operand flagsRegF() %{ constraint(ALLOC_IN_RC(float_flags)); @@ -8797,6 +8816,17 @@ instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{ ins_pipe(ialu_cconly_reg_reg); %} +instruct compUL_iReg(flagsRegUL xcc, iRegL op1, iRegL op2) %{ + match(Set xcc (CmpUL op1 op2)); + effect(DEF xcc, USE op1, USE op2); + + size(4); + format %{ "CMP $op1,$op2\t! unsigned long" %} + opcode(Assembler::subcc_op3, Assembler::arith_op); + ins_encode(form3_rs1_rs2_rd(op1, op2, R_G0)); + ins_pipe(ialu_cconly_reg_reg); +%} + instruct compI_iReg_imm13(flagsReg icc, iRegI op1, immI13 op2) %{ match(Set icc (CmpI op1 op2)); effect( DEF icc, USE op1 ); @@ -8883,6 +8913,17 @@ instruct compU_iReg_imm13(flagsRegU icc, iRegI op1, immU12 op2 ) %{ ins_pipe(ialu_cconly_reg_imm); %} +instruct compUL_iReg_imm13(flagsRegUL xcc, iRegL op1, immUL12 op2) %{ + match(Set xcc (CmpUL op1 op2)); + effect(DEF xcc, USE op1, USE op2); + + size(4); + format %{ "CMP $op1,$op2\t! unsigned long" %} + opcode(Assembler::subcc_op3, Assembler::arith_op); + ins_encode(form3_rs1_simm13_rd(op1, op2, R_G0)); + ins_pipe(ialu_cconly_reg_imm); +%} + // Compare Pointers instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{ match(Set pcc (CmpP op1 op2)); @@ -9256,6 +9297,44 @@ instruct cmpU_imm_branch(cmpOpU cmp, iRegI op1, immI5 op2, label labl, flagsRegU ins_pipe(cmp_br_reg_imm); %} +instruct cmpUL_reg_branch(cmpOpU cmp, iRegL op1, iRegL op2, label labl, flagsRegUL xcc) %{ + match(If cmp (CmpUL op1 op2)); + effect(USE labl, KILL xcc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! unsigned long\n\t" + "BP$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$Register); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_reg); +%} + +instruct cmpUL_imm_branch(cmpOpU cmp, iRegL op1, immL5 op2, label labl, flagsRegUL xcc) %{ + match(If cmp (CmpUL op1 op2)); + effect(USE labl, KILL xcc); + + size(12); + ins_cost(BRANCH_COST); + format %{ "CMP $op1,$op2\t! unsigned long\n\t" + "BP$cmp $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + __ cmp($op1$$Register, $op2$$constant); + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_pipe(cmp_br_reg_imm); +%} + instruct cmpL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{ match(If cmp (CmpL op1 op2)); effect(USE labl, KILL xcc); @@ -9484,6 +9563,42 @@ instruct cmpU_imm_branch_short(cmpOpU cmp, iRegI op1, immI5 op2, label labl, fla ins_pipe(cbcond_reg_imm); %} +instruct cmpUL_reg_branch_short(cmpOpU cmp, iRegL op1, iRegL op2, label labl, flagsRegUL xcc) %{ + match(If cmp (CmpUL op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL xcc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CXB$cmp $op1,$op2,$labl\t! unsigned long" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$Register, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); + ins_pipe(cbcond_reg_reg); +%} + +instruct cmpUL_imm_branch_short(cmpOpU cmp, iRegL op1, immL5 op2, label labl, flagsRegUL xcc) %{ + match(If cmp (CmpUL op1 op2)); + predicate(UseCBCond); + effect(USE labl, KILL xcc); + + size(4); + ins_cost(BRANCH_COST); + format %{ "CXB$cmp $op1,$op2,$labl\t! unsigned long" %} + ins_encode %{ + Label* L = $labl$$label; + assert(__ use_cbcond(*L), "back to back cbcond"); + __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$constant, *L); + %} + ins_short_branch(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); + ins_pipe(cbcond_reg_imm); +%} + instruct cmpL_reg_branch_short(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{ match(If cmp (CmpL op1 op2)); predicate(UseCBCond); @@ -9722,6 +9837,25 @@ instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{ ins_pipe(br_cc); %} +instruct branchConU_long(cmpOpU cmp, flagsRegUL xcc, label labl) %{ + match(If cmp xcc); + effect(USE labl); + + size(8); + ins_cost(BRANCH_COST); + format %{ "BP$cmp $xcc,$labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Predict predict_taken = + cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; + + __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L); + __ delayed()->nop(); + %} + ins_avoid_back_to_back(AVOID_BEFORE); + ins_pipe(br_cc); +%} + // Manifest a CmpL3 result in an integer register. Very painful. // This is the test to avoid. instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{ diff --git a/hotspot/src/cpu/x86/vm/x86_32.ad b/hotspot/src/cpu/x86/vm/x86_32.ad index e82361ba810..3f045554ba2 100644 --- a/hotspot/src/cpu/x86/vm/x86_32.ad +++ b/hotspot/src/cpu/x86/vm/x86_32.ad @@ -4030,6 +4030,26 @@ operand flagsReg_long_LEGT() %{ interface(REG_INTER); %} +// Condition Code Register used by unsigned long compare +operand flagsReg_ulong_LTGE() %{ + constraint(ALLOC_IN_RC(int_flags)); + match(RegFlags); + format %{ "FLAGS_U_LTGE" %} + interface(REG_INTER); +%} +operand flagsReg_ulong_EQNE() %{ + constraint(ALLOC_IN_RC(int_flags)); + match(RegFlags); + format %{ "FLAGS_U_EQNE" %} + interface(REG_INTER); +%} +operand flagsReg_ulong_LEGT() %{ + constraint(ALLOC_IN_RC(int_flags)); + match(RegFlags); + format %{ "FLAGS_U_LEGT" %} + interface(REG_INTER); +%} + // Float register operands operand regDPR() %{ predicate( UseSSE < 2 ); @@ -4588,7 +4608,7 @@ operand cmpOp_fcmov() %{ %} %} -// Comparision Code used in long compares +// Comparison Code used in long compares operand cmpOp_commute() %{ match(Bool); @@ -4605,6 +4625,23 @@ operand cmpOp_commute() %{ %} %} +// Comparison Code used in unsigned long compares +operand cmpOpU_commute() %{ + match(Bool); + + format %{ "" %} + interface(COND_INTER) %{ + equal(0x4, "e"); + not_equal(0x5, "ne"); + less(0x7, "nbe"); + greater_equal(0x6, "be"); + less_equal(0x3, "nb"); + greater(0x2, "b"); + overflow(0x0, "o"); + no_overflow(0x1, "no"); + %} +%} + //----------OPERAND CLASSES---------------------------------------------------- // Operand Classes are groups of operands that are used as to simplify // instruction definitions by not requiring the AD writer to specify separate @@ -12639,6 +12676,44 @@ instruct cmpL_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, label labl) %{ %} %} +//====== +// Manifest a CmpUL result in the normal flags. Only good for LT or GE +// compares. Can be used for LE or GT compares by reversing arguments. +// NOT GOOD FOR EQ/NE tests. +instruct cmpUL_zero_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src, immL0 zero) %{ + match(Set flags (CmpUL src zero)); + ins_cost(100); + format %{ "TEST $src.hi,$src.hi" %} + opcode(0x85); + ins_encode(OpcP, RegReg_Hi2(src, src)); + ins_pipe(ialu_cr_reg_reg); +%} + +// Manifest a CmpUL result in the normal flags. Only good for LT or GE +// compares. Can be used for LE or GT compares by reversing arguments. +// NOT GOOD FOR EQ/NE tests. +instruct cmpUL_reg_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src1, eRegL src2, rRegI tmp) %{ + match(Set flags (CmpUL src1 src2)); + effect(TEMP tmp); + ins_cost(300); + format %{ "CMP $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t" + "MOV $tmp,$src1.hi\n\t" + "SBB $tmp,$src2.hi\t! Compute flags for unsigned long compare" %} + ins_encode(long_cmp_flags2(src1, src2, tmp)); + ins_pipe(ialu_cr_reg_reg); +%} + +// Unsigned long compares reg < zero/req OR reg >= zero/req. +// Just a wrapper for a normal branch, plus the predicate test. +instruct cmpUL_LTGE(cmpOpU cmp, flagsReg_ulong_LTGE flags, label labl) %{ + match(If cmp flags); + effect(USE labl); + predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); + expand %{ + jmpCon(cmp, flags, labl); // JLT or JGE... + %} +%} + // Compare 2 longs and CMOVE longs. instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{ match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); @@ -12767,6 +12842,41 @@ instruct cmpL_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, label labl) %{ %} %} +//====== +// Manifest a CmpUL result in the normal flags. Only good for EQ/NE compares. +instruct cmpUL_zero_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src, immL0 zero, rRegI tmp) %{ + match(Set flags (CmpUL src zero)); + effect(TEMP tmp); + ins_cost(200); + format %{ "MOV $tmp,$src.lo\n\t" + "OR $tmp,$src.hi\t! Unsigned long is EQ/NE 0?" %} + ins_encode(long_cmp_flags0(src, tmp)); + ins_pipe(ialu_reg_reg_long); +%} + +// Manifest a CmpUL result in the normal flags. Only good for EQ/NE compares. +instruct cmpUL_reg_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src1, eRegL src2) %{ + match(Set flags (CmpUL src1 src2)); + ins_cost(200+300); + format %{ "CMP $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t" + "JNE,s skip\n\t" + "CMP $src1.hi,$src2.hi\n\t" + "skip:\t" %} + ins_encode(long_cmp_flags1(src1, src2)); + ins_pipe(ialu_cr_reg_reg); +%} + +// Unsigned long compare reg == zero/reg OR reg != zero/reg +// Just a wrapper for a normal branch, plus the predicate test. +instruct cmpUL_EQNE(cmpOpU cmp, flagsReg_ulong_EQNE flags, label labl) %{ + match(If cmp flags); + effect(USE labl); + predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); + expand %{ + jmpCon(cmp, flags, labl); // JEQ or JNE... + %} +%} + // Compare 2 longs and CMOVE longs. instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{ match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); @@ -12900,6 +13010,46 @@ instruct cmpL_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, label labl) %{ %} %} +//====== +// Manifest a CmpUL result in the normal flags. Only good for LE or GT compares. +// Same as cmpUL_reg_flags_LEGT except must negate src +instruct cmpUL_zero_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src, immL0 zero, rRegI tmp) %{ + match(Set flags (CmpUL src zero)); + effect(TEMP tmp); + ins_cost(300); + format %{ "XOR $tmp,$tmp\t# Unsigned long compare for -$src < 0, use commuted test\n\t" + "CMP $tmp,$src.lo\n\t" + "SBB $tmp,$src.hi\n\t" %} + ins_encode(long_cmp_flags3(src, tmp)); + ins_pipe(ialu_reg_reg_long); +%} + +// Manifest a CmpUL result in the normal flags. Only good for LE or GT compares. +// Same as cmpUL_reg_flags_LTGE except operands swapped. Swapping operands +// requires a commuted test to get the same result. +instruct cmpUL_reg_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src1, eRegL src2, rRegI tmp) %{ + match(Set flags (CmpUL src1 src2)); + effect(TEMP tmp); + ins_cost(300); + format %{ "CMP $src2.lo,$src1.lo\t! Unsigned long compare, swapped operands, use with commuted test\n\t" + "MOV $tmp,$src2.hi\n\t" + "SBB $tmp,$src1.hi\t! Compute flags for unsigned long compare" %} + ins_encode(long_cmp_flags2( src2, src1, tmp)); + ins_pipe(ialu_cr_reg_reg); +%} + +// Unsigned long compares reg < zero/req OR reg >= zero/req. +// Just a wrapper for a normal branch, plus the predicate test +instruct cmpUL_LEGT(cmpOpU_commute cmp, flagsReg_ulong_LEGT flags, label labl) %{ + match(If cmp flags); + effect(USE labl); + predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le); + ins_cost(300); + expand %{ + jmpCon(cmp, flags, labl); // JGT or JLE... + %} +%} + // Compare 2 longs and CMOVE longs. instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{ match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad index 99ae5f5f738..41e3ab1fb9f 100644 --- a/hotspot/src/cpu/x86/vm/x86_64.ad +++ b/hotspot/src/cpu/x86/vm/x86_64.ad @@ -11518,6 +11518,48 @@ instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) ins_pipe(pipe_slow); %} +// Unsigned long compare Instructions; really, same as signed long except they +// produce an rFlagsRegU instead of rFlagsReg. +instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) +%{ + match(Set cr (CmpUL op1 op2)); + + format %{ "cmpq $op1, $op2\t# unsigned" %} + opcode(0x3B); /* Opcode 3B /r */ + ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); + ins_pipe(ialu_cr_reg_reg); +%} + +instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) +%{ + match(Set cr (CmpUL op1 op2)); + + format %{ "cmpq $op1, $op2\t# unsigned" %} + opcode(0x81, 0x07); /* Opcode 81 /7 */ + ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); + ins_pipe(ialu_cr_reg_imm); +%} + +instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) +%{ + match(Set cr (CmpUL op1 (LoadL op2))); + + format %{ "cmpq $op1, $op2\t# unsigned" %} + opcode(0x3B); /* Opcode 3B /r */ + ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); + ins_pipe(ialu_cr_reg_mem); +%} + +instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) +%{ + match(Set cr (CmpUL src zero)); + + format %{ "testq $src, $src\t# unsigned" %} + opcode(0x85); + ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); + ins_pipe(ialu_cr_reg_imm); +%} + //----------Max and Min-------------------------------------------------------- // Min Instructions diff --git a/hotspot/src/share/vm/adlc/archDesc.cpp b/hotspot/src/share/vm/adlc/archDesc.cpp index 18cfeb43ccd..56a888224bb 100644 --- a/hotspot/src/share/vm/adlc/archDesc.cpp +++ b/hotspot/src/share/vm/adlc/archDesc.cpp @@ -1166,6 +1166,7 @@ void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) { || strcmp(idealName,"CmpP") == 0 || strcmp(idealName,"CmpN") == 0 || strcmp(idealName,"CmpL") == 0 + || strcmp(idealName,"CmpUL") == 0 || strcmp(idealName,"CmpD") == 0 || strcmp(idealName,"CmpF") == 0 || strcmp(idealName,"FastLock") == 0 diff --git a/hotspot/src/share/vm/opto/classes.hpp b/hotspot/src/share/vm/opto/classes.hpp index 06d754ffd78..06afc1f1e30 100644 --- a/hotspot/src/share/vm/opto/classes.hpp +++ b/hotspot/src/share/vm/opto/classes.hpp @@ -81,6 +81,7 @@ macro(CmpL3) macro(CmpLTMask) macro(CmpP) macro(CmpU) +macro(CmpUL) macro(CompareAndSwapB) macro(CompareAndSwapS) macro(CompareAndSwapI) diff --git a/hotspot/src/share/vm/opto/loopPredicate.cpp b/hotspot/src/share/vm/opto/loopPredicate.cpp index 7f10a7d980a..243b20d0173 100644 --- a/hotspot/src/share/vm/opto/loopPredicate.cpp +++ b/hotspot/src/share/vm/opto/loopPredicate.cpp @@ -29,6 +29,7 @@ #include "opto/connode.hpp" #include "opto/convertnode.hpp" #include "opto/loopnode.hpp" +#include "opto/matcher.hpp" #include "opto/mulnode.hpp" #include "opto/opaquenode.hpp" #include "opto/rootnode.hpp" @@ -629,45 +630,138 @@ bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invari // max(scale*i + offset) = scale*init + offset BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl, int scale, Node* offset, - Node* init, Node* limit, Node* stride, - Node* range, bool upper) { + Node* init, Node* limit, jint stride, + Node* range, bool upper, bool &overflow) { + jint con_limit = limit->is_Con() ? limit->get_int() : 0; + jint con_init = init->is_Con() ? init->get_int() : 0; + jint con_offset = offset->is_Con() ? offset->get_int() : 0; + stringStream* predString = NULL; if (TraceLoopPredicate) { predString = new stringStream(); predString->print("rc_predicate "); } - Node* max_idx_expr = init; - int stride_con = stride->get_int(); - if ((stride_con > 0) == (scale > 0) == upper) { - // Limit is not exact. - // Calculate exact limit here. - // Note, counted loop's test is '<' or '>'. - limit = exact_limit(loop); - max_idx_expr = new SubINode(limit, stride); + overflow = false; + Node* max_idx_expr = NULL; + const TypeInt* idx_type = TypeInt::INT; + if ((stride > 0) == (scale > 0) == upper) { + if (TraceLoopPredicate) { + predString->print(limit->is_Con() ? "(%d " : "(limit ", con_limit); + predString->print("- %d) ", stride); + } + // Check if (limit - stride) may overflow + const TypeInt* limit_type = _igvn.type(limit)->isa_int(); + jint limit_lo = limit_type->_lo; + jint limit_hi = limit_type->_hi; + if ((stride > 0 && (java_subtract(limit_lo, stride) < limit_lo)) || + (stride < 0 && (java_subtract(limit_hi, stride) > limit_hi))) { + // No overflow possible + ConINode* con_stride = _igvn.intcon(stride); + set_ctrl(con_stride, C->root()); + max_idx_expr = new SubINode(limit, con_stride); + idx_type = TypeInt::make(limit_lo - stride, limit_hi - stride, limit_type->_widen); + } else { + // May overflow + overflow = true; + limit = new ConvI2LNode(limit); + register_new_node(limit, ctrl); + ConLNode* con_stride = _igvn.longcon(stride); + set_ctrl(con_stride, C->root()); + max_idx_expr = new SubLNode(limit, con_stride); + } register_new_node(max_idx_expr, ctrl); - if (TraceLoopPredicate) predString->print("(limit - stride) "); } else { - if (TraceLoopPredicate) predString->print("init "); + if (TraceLoopPredicate) { + predString->print(init->is_Con() ? "%d " : "init ", con_init); + } + idx_type = _igvn.type(init)->isa_int(); + max_idx_expr = init; } if (scale != 1) { ConNode* con_scale = _igvn.intcon(scale); set_ctrl(con_scale, C->root()); - max_idx_expr = new MulINode(max_idx_expr, con_scale); + if (TraceLoopPredicate) { + predString->print("* %d ", scale); + } + // Check if (scale * max_idx_expr) may overflow + const TypeInt* scale_type = TypeInt::make(scale); + MulINode* mul = new MulINode(max_idx_expr, con_scale); + idx_type = (TypeInt*)mul->mul_ring(idx_type, scale_type); + if (overflow || TypeInt::INT->higher_equal(idx_type)) { + // May overflow + mul->destruct(); + if (!overflow) { + max_idx_expr = new ConvI2LNode(max_idx_expr); + register_new_node(max_idx_expr, ctrl); + } + overflow = true; + con_scale = _igvn.longcon(scale); + set_ctrl(con_scale, C->root()); + max_idx_expr = new MulLNode(max_idx_expr, con_scale); + } else { + // No overflow possible + max_idx_expr = mul; + } register_new_node(max_idx_expr, ctrl); - if (TraceLoopPredicate) predString->print("* %d ", scale); } - if (offset && (!offset->is_Con() || offset->get_int() != 0)){ - max_idx_expr = new AddINode(max_idx_expr, offset); + if (offset && (!offset->is_Con() || con_offset != 0)){ + if (TraceLoopPredicate) { + predString->print(offset->is_Con() ? "+ %d " : "+ offset", con_offset); + } + // Check if (max_idx_expr + offset) may overflow + const TypeInt* offset_type = _igvn.type(offset)->isa_int(); + jint lo = java_add(idx_type->_lo, offset_type->_lo); + jint hi = java_add(idx_type->_hi, offset_type->_hi); + if (overflow || (lo > hi) || + ((idx_type->_lo & offset_type->_lo) < 0 && lo >= 0) || + ((~(idx_type->_hi | offset_type->_hi)) < 0 && hi < 0)) { + // May overflow + if (!overflow) { + max_idx_expr = new ConvI2LNode(max_idx_expr); + register_new_node(max_idx_expr, ctrl); + } + overflow = true; + offset = new ConvI2LNode(offset); + register_new_node(offset, ctrl); + max_idx_expr = new AddLNode(max_idx_expr, offset); + } else { + // No overflow possible + max_idx_expr = new AddINode(max_idx_expr, offset); + } register_new_node(max_idx_expr, ctrl); - if (TraceLoopPredicate) - if (offset->is_Con()) predString->print("+ %d ", offset->get_int()); - else predString->print("+ offset "); } - CmpUNode* cmp = new CmpUNode(max_idx_expr, range); + CmpNode* cmp = NULL; + if (overflow) { + // Integer expressions may overflow, do long comparison + range = new ConvI2LNode(range); + register_new_node(range, ctrl); + if (!Matcher::has_match_rule(Op_CmpUL)) { + // We don't support unsigned long comparisons. Set 'max_idx_expr' + // to max_julong if < 0 to make the signed comparison fail. + ConINode* sign_pos = _igvn.intcon(BitsPerLong - 1); + set_ctrl(sign_pos, C->root()); + Node* sign_bit_mask = new RShiftLNode(max_idx_expr, sign_pos); + register_new_node(sign_bit_mask, ctrl); + // OR with sign bit to set all bits to 1 if negative (otherwise no change) + max_idx_expr = new OrLNode(max_idx_expr, sign_bit_mask); + register_new_node(max_idx_expr, ctrl); + // AND with 0x7ff... to unset the sign bit + ConLNode* remove_sign_mask = _igvn.longcon(max_jlong); + set_ctrl(remove_sign_mask, C->root()); + max_idx_expr = new AndLNode(max_idx_expr, remove_sign_mask); + register_new_node(max_idx_expr, ctrl); + + cmp = new CmpLNode(max_idx_expr, range); + } else { + cmp = new CmpULNode(max_idx_expr, range); + } + } else { + cmp = new CmpUNode(max_idx_expr, range); + } register_new_node(cmp, ctrl); BoolNode* bol = new BoolNode(cmp, BoolTest::lt); register_new_node(bol, ctrl); @@ -814,28 +908,30 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) { assert(ok, "must be index expression"); Node* init = cl->init_trip(); - Node* limit = cl->limit(); - Node* stride = cl->stride(); + // Limit is not exact. + // Calculate exact limit here. + // Note, counted loop's test is '<' or '>'. + Node* limit = exact_limit(loop); + int stride = cl->stride()->get_int(); // Build if's for the upper and lower bound tests. The // lower_bound test will dominate the upper bound test and all // cloned or created nodes will use the lower bound test as // their declared control. - ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, iff->Opcode()); - ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, iff->Opcode()); - assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate"); - Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0); // Perform cloning to keep Invariance state correct since the // late schedule will place invariant things in the loop. + Node *ctrl = predicate_proj->in(0)->as_If()->in(0); rng = invar.clone(rng, ctrl); if (offset && offset != zero) { assert(invar.is_invariant(offset), "offset must be loop invariant"); offset = invar.clone(offset, ctrl); } + // If predicate expressions may overflow in the integer range, longs are used. + bool overflow = false; // Test the lower bound - BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false); + BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false, overflow); // Negate test if necessary bool negated = false; if (proj->_con != predicate_proj->_con) { @@ -843,19 +939,22 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) { register_new_node(lower_bound_bol, ctrl); negated = true; } + ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, overflow ? Op_If : iff->Opcode()); IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If(); _igvn.hash_delete(lower_bound_iff); lower_bound_iff->set_req(1, lower_bound_bol); if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx); // Test the upper bound - BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true); + BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow); negated = false; if (proj->_con != predicate_proj->_con) { upper_bound_bol = new BoolNode(upper_bound_bol->in(1), upper_bound_bol->_test.negate()); register_new_node(upper_bound_bol, ctrl); negated = true; } + ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, overflow ? Op_If : iff->Opcode()); + assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate"); IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If(); _igvn.hash_delete(upper_bound_iff); upper_bound_iff->set_req(1, upper_bound_bol); diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp index 3419b786e03..70168186cca 100644 --- a/hotspot/src/share/vm/opto/loopnode.hpp +++ b/hotspot/src/share/vm/opto/loopnode.hpp @@ -983,8 +983,8 @@ public: // Construct a range check for a predicate if BoolNode* rc_predicate(IdealLoopTree *loop, Node* ctrl, int scale, Node* offset, - Node* init, Node* limit, Node* stride, - Node* range, bool upper); + Node* init, Node* limit, jint stride, + Node* range, bool upper, bool &overflow); // Implementation of the loop predication to promote checks outside the loop bool loop_predication_impl(IdealLoopTree *loop); diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index e0164274f2d..cf9e4cf7323 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -1982,6 +1982,7 @@ void Scheduling::AddNodeToAvailableList(Node *n) { if( last->is_MachIf() && last->in(1) == n && ( op == Op_CmpI || op == Op_CmpU || + op == Op_CmpUL || op == Op_CmpP || op == Op_CmpF || op == Op_CmpD || diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp index 2e2597f6076..694dda17367 100644 --- a/hotspot/src/share/vm/opto/subnode.cpp +++ b/hotspot/src/share/vm/opto/subnode.cpp @@ -738,6 +738,60 @@ const Type *CmpLNode::sub( const Type *t1, const Type *t2 ) const { return TypeInt::CC; // else use worst case results } + +// Simplify a CmpUL (compare 2 unsigned longs) node, based on local information. +// If both inputs are constants, compare them. +const Type* CmpULNode::sub(const Type* t1, const Type* t2) const { + assert(!t1->isa_ptr(), "obsolete usage of CmpUL"); + + // comparing two unsigned longs + const TypeLong* r0 = t1->is_long(); // Handy access + const TypeLong* r1 = t2->is_long(); + + // Current installed version + // Compare ranges for non-overlap + julong lo0 = r0->_lo; + julong hi0 = r0->_hi; + julong lo1 = r1->_lo; + julong hi1 = r1->_hi; + + // If either one has both negative and positive values, + // it therefore contains both 0 and -1, and since [0..-1] is the + // full unsigned range, the type must act as an unsigned bottom. + bool bot0 = ((jlong)(lo0 ^ hi0) < 0); + bool bot1 = ((jlong)(lo1 ^ hi1) < 0); + + if (bot0 || bot1) { + // All unsigned values are LE -1 and GE 0. + if (lo0 == 0 && hi0 == 0) { + return TypeInt::CC_LE; // 0 <= bot + } else if ((jlong)lo0 == -1 && (jlong)hi0 == -1) { + return TypeInt::CC_GE; // -1 >= bot + } else if (lo1 == 0 && hi1 == 0) { + return TypeInt::CC_GE; // bot >= 0 + } else if ((jlong)lo1 == -1 && (jlong)hi1 == -1) { + return TypeInt::CC_LE; // bot <= -1 + } + } else { + // We can use ranges of the form [lo..hi] if signs are the same. + assert(lo0 <= hi0 && lo1 <= hi1, "unsigned ranges are valid"); + // results are reversed, '-' > '+' for unsigned compare + if (hi0 < lo1) { + return TypeInt::CC_LT; // smaller + } else if (lo0 > hi1) { + return TypeInt::CC_GT; // greater + } else if (hi0 == lo1 && lo0 == hi1) { + return TypeInt::CC_EQ; // Equal results + } else if (lo0 >= hi1) { + return TypeInt::CC_GE; + } else if (hi0 <= lo1) { + return TypeInt::CC_LE; + } + } + + return TypeInt::CC; // else use worst case results +} + //============================================================================= //------------------------------sub-------------------------------------------- // Simplify an CmpP (compare 2 pointers) node, based on local information. diff --git a/hotspot/src/share/vm/opto/subnode.hpp b/hotspot/src/share/vm/opto/subnode.hpp index 63bcd3cc2b4..a4adbcf5a47 100644 --- a/hotspot/src/share/vm/opto/subnode.hpp +++ b/hotspot/src/share/vm/opto/subnode.hpp @@ -198,6 +198,15 @@ public: virtual const Type *sub( const Type *, const Type * ) const; }; +//------------------------------CmpULNode--------------------------------------- +// Compare 2 unsigned long values, returning condition codes (-1, 0 or 1). +class CmpULNode : public CmpNode { +public: + CmpULNode(Node* in1, Node* in2) : CmpNode(in1, in2) { } + virtual int Opcode() const; + virtual const Type* sub(const Type*, const Type*) const; +}; + //------------------------------CmpL3Node-------------------------------------- // Compare 2 long values, returning integer value (-1, 0 or 1). class CmpL3Node : public CmpLNode { diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 0d973ca5ee8..a945f4f4a0e 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -2008,6 +2008,7 @@ typedef CompactHashtable SymbolCompactHashTable; declare_c2_type(CmpPNode, CmpNode) \ declare_c2_type(CmpNNode, CmpNode) \ declare_c2_type(CmpLNode, CmpNode) \ + declare_c2_type(CmpULNode, CmpNode) \ declare_c2_type(CmpL3Node, CmpLNode) \ declare_c2_type(CmpFNode, CmpNode) \ declare_c2_type(CmpF3Node, CmpFNode) \ From 268c2d053f276b8bc0ba1a94be4a2b00801322f8 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov Date: Thu, 6 Apr 2017 20:14:33 +0300 Subject: [PATCH 04/59] 8176731: JCK tests in api/javax_xml/transform/ spec conformance started failing after 8172469 Reviewed-by: joehw, dfuchs --- .../javax/xml/transform/TransformerConfigurationException.java | 2 ++ .../share/classes/javax/xml/transform/TransformerException.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerConfigurationException.java b/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerConfigurationException.java index a81fde2989c..a90e29121a8 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerConfigurationException.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerConfigurationException.java @@ -32,6 +32,8 @@ package javax.xml.transform; */ public class TransformerConfigurationException extends TransformerException { + private static final long serialVersionUID = 1285547467942875745L; + /** * Create a new TransformerConfigurationException with no * detail message. diff --git a/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerException.java b/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerException.java index b18ee414e64..b5e7657dccf 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerException.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerException.java @@ -45,6 +45,8 @@ import java.util.Objects; */ public class TransformerException extends Exception { + private static final long serialVersionUID = 975798773772956428L; + /** Field locator specifies where the error occurred */ SourceLocator locator; From 4641bfb53baad110b3396f858c613a60d2b8f1f7 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Thu, 1 Jun 2017 12:20:37 +0200 Subject: [PATCH 05/59] 8181420: PPC: Image conversion improvements Reviewed-by: thartmann, simonis, mbaesken --- hotspot/src/cpu/ppc/vm/ppc.ad | 23 +++++++++++++++++++++++ hotspot/src/cpu/s390/vm/s390.ad | 18 ++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/hotspot/src/cpu/ppc/vm/ppc.ad b/hotspot/src/cpu/ppc/vm/ppc.ad index 6c3d9cf1fda..f9534b65bff 100644 --- a/hotspot/src/cpu/ppc/vm/ppc.ad +++ b/hotspot/src/cpu/ppc/vm/ppc.ad @@ -11048,6 +11048,29 @@ instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ ins_pipe(pipe_class_compare); %} +// Added CmpUL for LoopPredicate. +instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ + match(Set crx (CmpUL src1 src2)); + format %{ "CMPLD $crx, $src1, $src2" %} + size(4); + ins_encode %{ + // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); + __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); + %} + ins_pipe(pipe_class_compare); +%} + +instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ + match(Set crx (CmpUL src1 src2)); + format %{ "CMPLDI $crx, $src1, $src2" %} + size(4); + ins_encode %{ + // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); + __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); + %} + ins_pipe(pipe_class_compare); +%} + instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ match(Set cr0 (CmpL (AndL src1 src2) zero)); // r0 is killed diff --git a/hotspot/src/cpu/s390/vm/s390.ad b/hotspot/src/cpu/s390/vm/s390.ad index fd188525c46..7daf348c0af 100644 --- a/hotspot/src/cpu/s390/vm/s390.ad +++ b/hotspot/src/cpu/s390/vm/s390.ad @@ -8475,6 +8475,24 @@ instruct compL_reg_memI(iRegL dst, memory src, flagsReg cr)%{ %} // LONG unsigned +// Added CmpUL for LoopPredicate. +instruct compUL_reg_reg(flagsReg cr, iRegL op1, iRegL op2) %{ + match(Set cr (CmpUL op1 op2)); + size(4); + format %{ "CLGR $op1,$op2\t # long" %} + opcode(CLGR_ZOPC); + ins_encode(z_rreform(op1, op2)); + ins_pipe(pipe_class_dummy); +%} + +instruct compUL_reg_imm32(flagsReg cr, iRegL op1, uimmL32 con) %{ + match(Set cr (CmpUL op1 con)); + size(6); + format %{ "CLGFI $op1,$con" %} + opcode(CLGFI_ZOPC); + ins_encode(z_rilform_unsigned(op1, con)); + ins_pipe(pipe_class_dummy); +%} // PTR unsigned From 313f2419cb61ee4d90e7a22be66ba4b0ad35bd65 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov Date: Sat, 24 Jun 2017 22:10:40 +0100 Subject: [PATCH 06/59] 8182054: Improve wsdl support Also reviewed by Roman Grigoriadi Reviewed-by: joehw, lancea --- .../sun/xml/internal/ws/util/xml/XmlUtil.java | 43 +++++++++++++++++-- .../internal/ws/wsdl/parser/DOMForest.java | 26 +++-------- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java index 213b584b15a..8a63b73cee1 100644 --- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java +++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java @@ -84,6 +84,14 @@ public class XmlUtil { private final static String LEXICAL_HANDLER_PROPERTY = "http://xml.org/sax/properties/lexical-handler"; + private static final String DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl"; + + private static final String EXTERNAL_GE = "http://xml.org/sax/features/external-general-entities"; + + private static final String EXTERNAL_PE = "http://xml.org/sax/features/external-parameter-entities"; + + private static final String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; + private static final Logger LOGGER = Logger.getLogger(XmlUtil.class.getName()); private static final String DISABLE_XML_SECURITY = "com.sun.xml.internal.ws.disableXmlSecurity"; @@ -327,10 +335,24 @@ public class XmlUtil { public static DocumentBuilderFactory newDocumentBuilderFactory(boolean disableSecurity) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING; try { - factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, !xmlSecurityDisabled(disableSecurity)); + boolean securityOn = !xmlSecurityDisabled(disableSecurity); + factory.setFeature(featureToSet, securityOn); + factory.setNamespaceAware(true); + if (securityOn) { + factory.setExpandEntityReferences(false); + featureToSet = DISALLOW_DOCTYPE_DECL; + factory.setFeature(featureToSet, true); + featureToSet = EXTERNAL_GE; + factory.setFeature(featureToSet, false); + featureToSet = EXTERNAL_PE; + factory.setFeature(featureToSet, false); + featureToSet = LOAD_EXTERNAL_DTD; + factory.setFeature(featureToSet, false); + } } catch (ParserConfigurationException e) { - LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[] { factory.getClass().getName() } ); + LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[] {factory.getClass().getName()} ); } return factory; } @@ -347,10 +369,23 @@ public class XmlUtil { public static SAXParserFactory newSAXParserFactory(boolean disableSecurity) { SAXParserFactory factory = SAXParserFactory.newInstance(); + String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING; try { - factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, !xmlSecurityDisabled(disableSecurity)); + boolean securityOn = !xmlSecurityDisabled(disableSecurity); + factory.setFeature(featureToSet, securityOn); + factory.setNamespaceAware(true); + if (securityOn) { + featureToSet = DISALLOW_DOCTYPE_DECL; + factory.setFeature(featureToSet, true); + featureToSet = EXTERNAL_GE; + factory.setFeature(featureToSet, false); + featureToSet = EXTERNAL_PE; + factory.setFeature(featureToSet, false); + featureToSet = LOAD_EXTERNAL_DTD; + factory.setFeature(featureToSet, false); + } } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[]{factory.getClass().getName()}); + LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[]{factory.getClass().getName()}); } return factory; } diff --git a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMForest.java b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMForest.java index e105d2f386c..c7d9aeec1d7 100644 --- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMForest.java +++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMForest.java @@ -112,29 +112,13 @@ public class DOMForest { this.entityResolver = entityResolver; this.errorReceiver = errReceiver; this.logic = logic; + // secure xml processing can be switched off if input requires it + boolean disableXmlSecurity = options == null ? false : options.disableXmlSecurity; + + DocumentBuilderFactory dbf = XmlUtil.newDocumentBuilderFactory(disableXmlSecurity); + this.parserFactory = XmlUtil.newSAXParserFactory(disableXmlSecurity); try { - // secure xml processing can be switched off if input requires it - boolean secureProcessingEnabled = options == null || !options.disableXmlSecurity; - DocumentBuilderFactory dbf = XmlUtil.newDocumentBuilderFactory(!secureProcessingEnabled); - dbf.setNamespaceAware(true); this.documentBuilder = dbf.newDocumentBuilder(); - - this.parserFactory = XmlUtil.newSAXParserFactory(secureProcessingEnabled); - this.parserFactory.setNamespaceAware(true); - - if(secureProcessingEnabled){ - dbf.setExpandEntityReferences(false); - try { - parserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - parserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); - parserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - } catch (SAXNotRecognizedException e){ - throw new ParserConfigurationException(e.getMessage()); - } catch (SAXNotSupportedException e) { - throw new ParserConfigurationException(e.getMessage()); - } - } - } catch (ParserConfigurationException e) { throw new AssertionError(e); } From 4f700bfe11d93c99c892a63a9f1f33d5ba119093 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 13 Jul 2017 17:32:48 +0000 Subject: [PATCH 07/59] Added tag jdk-9+178 for changeset d9bf695aa380 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 2cec32fee92..5c9cabf45f0 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -420,3 +420,4 @@ b25838a28195f4b6dab34668411eedd2d366a16c jdk-9+169 8f7227c6012b0051ea4e0bcee040c627bf699b88 jdk-9+175 84777531d994ef70163d35078ec9c4127f2eadb5 jdk-9+176 a4371edb589c60db01142e45c317adb9ccbcb083 jdk-9+177 +ec4159ebe7050fcc5dcee8a2d150cf948ecc97db jdk-9+178 From c6e41cad4017b8f84d00e71ffd75d6c1c37ea0d6 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 13 Jul 2017 17:32:49 +0000 Subject: [PATCH 08/59] Added tag jdk-9+178 for changeset 36707109c109 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 4cef58700ee..a09db324464 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -580,3 +580,4 @@ e64b1cb48d6e7703928a9d1da106fc27f8cb65fd jdk-9+173 8f04d457168b9f1f4a1b2c37f49e0513ca9d33a7 jdk-9+175 2ab74e5dbdc2b6a962c865500cafd23cf387dc60 jdk-9+176 1ca8f038fceb88c640badf9bd18905205bc63b43 jdk-9+177 +9d032191f82fca5ba0aac98682f69c4ff0f1283d jdk-9+178 From 794843910708397a7c758e56541b0a2b03edacf7 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 13 Jul 2017 17:32:49 +0000 Subject: [PATCH 09/59] Added tag jdk-9+178 for changeset eb61690de048 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 6bb7df9a6e8..fbe26bf015a 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -420,3 +420,4 @@ c62e5964cfcf144d8f72e9ba69757897785349a9 jdk-9+171 dc78a3dd6b3a4f11cdae8a3e3d160e6a78bc7838 jdk-9+175 40fb9f229471ef357d493813d34b15afcce9f32b jdk-9+176 c72e9d3823f04cb3ef3166646dfea9e4c2769133 jdk-9+177 +9c1e9712648921ae389d623042d22561fad82d75 jdk-9+178 From b7c294d71f5667bb3761d4bfefdd0b681c887473 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 13 Jul 2017 17:32:50 +0000 Subject: [PATCH 10/59] Added tag jdk-9+178 for changeset df8265c4f940 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index f62d9a855b6..7e4ae9232b4 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -420,3 +420,4 @@ b9c0b105002272d7414c8b34af9aded151f9cad6 jdk-9+174 736412a8dccee9d439044e6b1af2e7470d0a3563 jdk-9+175 38cf34e2328070cc691c4f136e6dde1a44c04171 jdk-9+176 332ad9f92632f56f337b8c40edef9a95a42b26bc jdk-9+177 +0983b2dbe17ba4fed3af34e0512ca77a9845fe8a jdk-9+178 From 6e08d438f2a4dd26b25d3572460bc7ec63d4d36d Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 13 Jul 2017 17:32:50 +0000 Subject: [PATCH 11/59] Added tag jdk-9+178 for changeset a848d4a9fb60 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index a70a115ee06..cf60b722cdf 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -423,3 +423,4 @@ c2296642010f1b215ac35da89e92c3ce44104e32 jdk-9+174 a5d361b9d1f7f78a675f3baef0d1fd32deee9ea2 jdk-9+175 ea819b6009d33a72e6672bab6c101d51db0cfb4c jdk-9+176 b44a721aee3d3b2537754e559fe9ecccadea548b jdk-9+177 +d0190aaf1816081d9b2e0577b65b793804896d1e jdk-9+178 From cf59ac539c684ca1aae2fe2f27b2fe60b787d2c4 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 13 Jul 2017 17:32:52 +0000 Subject: [PATCH 12/59] Added tag jdk-9+178 for changeset a737ff10b290 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index bc0d5aa0566..38af67fac9f 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -411,3 +411,4 @@ fa8e4de50e821eed876388c84f7129a6739268be jdk-9+173 734b3209b6edeb57e482c97793ae9c066af72871 jdk-9+175 3c6fbdf6e785aaf18d35ce9c6684369952fd22ec jdk-9+176 aa7404e062b95f679018f25eaaf933dcf0cf3f2b jdk-9+177 +7497ad85759ff010f44344b553223d1647fb6eba jdk-9+178 From c66cb9267ab2a3c19a66a9e94e07037c199731d8 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 13 Jul 2017 17:32:52 +0000 Subject: [PATCH 13/59] Added tag jdk-9+178 for changeset e8d8b02716f5 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 894b3998f36..922d86d25ce 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -420,3 +420,4 @@ aae59039c1f5701ae933c5eed30e75d6e3afaeee jdk-9+171 83f6eb009d8f6e94fd348c7d23e4b00754d745db jdk-9+175 0d0ac75b0f6cbe218362e3fac4bb443496e7258f jdk-9+176 2f01728210c1405ef459e69d9c7247b5df6abb78 jdk-9+177 +849e366ef175012e6dedc3ca151da416716e0ea9 jdk-9+178 From 51a564a1bc9be06087d4e8077b7bf4d108e20470 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Thu, 20 Jul 2017 13:59:12 +0200 Subject: [PATCH 14/59] 8183551: Aarch64 platform specific code for 8173770 Reviewed-by: aph, kvn --- hotspot/src/cpu/aarch64/vm/aarch64.ad | 60 ++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/hotspot/src/cpu/aarch64/vm/aarch64.ad b/hotspot/src/cpu/aarch64/vm/aarch64.ad index 4360e8caac8..b8302d985ad 100644 --- a/hotspot/src/cpu/aarch64/vm/aarch64.ad +++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad @@ -14392,7 +14392,7 @@ instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) ins_pipe(icmp_reg_reg); %} -instruct compL_reg_immI0(rFlagsReg cr, iRegL op1, immI0 zero) +instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) %{ match(Set cr (CmpL op1 zero)); @@ -14434,6 +14434,62 @@ instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) ins_pipe(icmp_reg_imm); %} +instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) +%{ + match(Set cr (CmpUL op1 op2)); + + effect(DEF cr, USE op1, USE op2); + + ins_cost(INSN_COST); + format %{ "cmp $op1, $op2" %} + + ins_encode(aarch64_enc_cmp(op1, op2)); + + ins_pipe(icmp_reg_reg); +%} + +instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) +%{ + match(Set cr (CmpUL op1 zero)); + + effect(DEF cr, USE op1); + + ins_cost(INSN_COST); + format %{ "tst $op1" %} + + ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); + + ins_pipe(icmp_reg_imm); +%} + +instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) +%{ + match(Set cr (CmpUL op1 op2)); + + effect(DEF cr, USE op1); + + ins_cost(INSN_COST); + format %{ "cmp $op1, $op2" %} + + ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); + + ins_pipe(icmp_reg_imm); +%} + +instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) +%{ + match(Set cr (CmpUL op1 op2)); + + effect(DEF cr, USE op1); + + ins_cost(INSN_COST * 2); + format %{ "cmp $op1, $op2" %} + + ins_encode(aarch64_enc_cmp_imm(op1, op2)); + + ins_pipe(icmp_reg_imm); +%} + instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) %{ match(Set cr (CmpP op1 op2)); @@ -14918,7 +14974,7 @@ instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label %} instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ - match(If cmp (CmpU op1 op2)); + match(If cmp (CmpUL op1 op2)); effect(USE labl); ins_cost(BRANCH_COST); From abb24fe6e4e733c5d55ee158cf661b47016023c1 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 20 Jul 2017 21:12:20 +0000 Subject: [PATCH 15/59] Added tag jdk-9+179 for changeset ee148c113ae0 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index a09db324464..3afcce0f7c6 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -581,3 +581,4 @@ e64b1cb48d6e7703928a9d1da106fc27f8cb65fd jdk-9+173 2ab74e5dbdc2b6a962c865500cafd23cf387dc60 jdk-9+176 1ca8f038fceb88c640badf9bd18905205bc63b43 jdk-9+177 9d032191f82fca5ba0aac98682f69c4ff0f1283d jdk-9+178 +d2661aa42bff322badbe6c1337fc638d2e0f5730 jdk-9+179 From b61c05cb438ce473ed225d56bfaeafd049c86420 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 20 Jul 2017 21:12:20 +0000 Subject: [PATCH 16/59] Added tag jdk-9+179 for changeset 0af1b1a0e2ca --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 5c9cabf45f0..7de83411416 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -421,3 +421,4 @@ b25838a28195f4b6dab34668411eedd2d366a16c jdk-9+169 84777531d994ef70163d35078ec9c4127f2eadb5 jdk-9+176 a4371edb589c60db01142e45c317adb9ccbcb083 jdk-9+177 ec4159ebe7050fcc5dcee8a2d150cf948ecc97db jdk-9+178 +252475ccfd84cc249f8d6faf4b7806b5e2c384ce jdk-9+179 From 94741168aa118566a920c1a6052fab75597ca165 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 20 Jul 2017 21:12:20 +0000 Subject: [PATCH 17/59] Added tag jdk-9+179 for changeset 75521d21ec5b --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index fbe26bf015a..c70104da520 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -421,3 +421,4 @@ dc78a3dd6b3a4f11cdae8a3e3d160e6a78bc7838 jdk-9+175 40fb9f229471ef357d493813d34b15afcce9f32b jdk-9+176 c72e9d3823f04cb3ef3166646dfea9e4c2769133 jdk-9+177 9c1e9712648921ae389d623042d22561fad82d75 jdk-9+178 +24390da83c5ee9e23ceafbcaff4460a01e37bb3a jdk-9+179 From 30c77d4037b6dc1b91ec47b4d2e0663e94657060 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 20 Jul 2017 21:12:21 +0000 Subject: [PATCH 18/59] Added tag jdk-9+179 for changeset 9c2658f4a8c9 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 7e4ae9232b4..a15959a57fb 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -421,3 +421,4 @@ b9c0b105002272d7414c8b34af9aded151f9cad6 jdk-9+174 38cf34e2328070cc691c4f136e6dde1a44c04171 jdk-9+176 332ad9f92632f56f337b8c40edef9a95a42b26bc jdk-9+177 0983b2dbe17ba4fed3af34e0512ca77a9845fe8a jdk-9+178 +87243a3131f79e8b3903eaca6b629abc48f08ace jdk-9+179 From 12b068bb727dcfe0a084ce623eafb8555c4048e6 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 20 Jul 2017 21:12:22 +0000 Subject: [PATCH 19/59] Added tag jdk-9+179 for changeset 08e2a28966ff --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index cf60b722cdf..ef54246bbb3 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -424,3 +424,4 @@ a5d361b9d1f7f78a675f3baef0d1fd32deee9ea2 jdk-9+175 ea819b6009d33a72e6672bab6c101d51db0cfb4c jdk-9+176 b44a721aee3d3b2537754e559fe9ecccadea548b jdk-9+177 d0190aaf1816081d9b2e0577b65b793804896d1e jdk-9+178 +56ac1831ac5924b5092a53a85d6fc68749501fb8 jdk-9+179 From 34eef857364037e9c2e75e9cb681669a76061737 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 20 Jul 2017 21:12:23 +0000 Subject: [PATCH 20/59] Added tag jdk-9+179 for changeset e504e67e549a --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 922d86d25ce..09f8afdfbb2 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -421,3 +421,4 @@ aae59039c1f5701ae933c5eed30e75d6e3afaeee jdk-9+171 0d0ac75b0f6cbe218362e3fac4bb443496e7258f jdk-9+176 2f01728210c1405ef459e69d9c7247b5df6abb78 jdk-9+177 849e366ef175012e6dedc3ca151da416716e0ea9 jdk-9+178 +b653b1b2ea883593596bc18e9af73a9b369eeb0a jdk-9+179 From 017bca45d617fd979d8371359a8d7f28a163038f Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 20 Jul 2017 21:12:24 +0000 Subject: [PATCH 21/59] Added tag jdk-9+179 for changeset f0b8841af1c2 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 38af67fac9f..1d349ed7276 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -412,3 +412,4 @@ fa8e4de50e821eed876388c84f7129a6739268be jdk-9+173 3c6fbdf6e785aaf18d35ce9c6684369952fd22ec jdk-9+176 aa7404e062b95f679018f25eaaf933dcf0cf3f2b jdk-9+177 7497ad85759ff010f44344b553223d1647fb6eba jdk-9+178 +3adfb547e3e49e304ffc82d8c6489cb830b74d62 jdk-9+179 From d5769843a52d99d7d707fa7e4e8e5ccabe5b2b4b Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 27 Jul 2017 13:13:19 -0700 Subject: [PATCH 22/59] 8185092: Data race in FilterOutputStream.close Change boolean instance variable "closed" to an AtomicBoolean. Reviewed-by: martin, alanb, redestad --- .../share/classes/java/io/FilterOutputStream.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/io/FilterOutputStream.java b/jdk/src/java.base/share/classes/java/io/FilterOutputStream.java index 8030979cdaa..55abe739196 100644 --- a/jdk/src/java.base/share/classes/java/io/FilterOutputStream.java +++ b/jdk/src/java.base/share/classes/java/io/FilterOutputStream.java @@ -50,7 +50,12 @@ public class FilterOutputStream extends OutputStream { /** * Whether the stream is closed; implicitly initialized to false. */ - private boolean closed; + private volatile boolean closed; + + /** + * Object used to prevent a race on the 'closed' instance variable. + */ + private final Object closeLock = new Object(); /** * Creates an output stream filter built on top of the specified @@ -165,7 +170,12 @@ public class FilterOutputStream extends OutputStream { if (closed) { return; } - closed = true; + synchronized (closeLock) { + if (closed) { + return; + } + closed = true; + } Throwable flushException = null; try { From 5f174120d2d89cca82aeb436453bf06ca9ecbe59 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 27 Jul 2017 16:46:52 -0700 Subject: [PATCH 23/59] 8185464: Link issues in java.xml module Reviewed-by: lancea --- .../javax/xml/catalog/CatalogFeatures.java | 10 +++++----- .../javax/xml/datatype/DatatypeFactory.java | 2 +- .../javax/xml/datatype/package-info.java | 18 ++++-------------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java index 17961e79620..b84949d9ce3 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java @@ -34,7 +34,7 @@ import jdk.xml.internal.SecuritySupport; * The CatalogFeatures holds a collection of features and properties. * * - * + *
* * * @@ -55,7 +55,7 @@ import jdk.xml.internal.SecuritySupport; * * * - * + * * @@ -71,7 +71,7 @@ import jdk.xml.internal.SecuritySupport; * * * - * + * * * @@ -91,7 +91,7 @@ import jdk.xml.internal.SecuritySupport; * * * - * + * * @@ -111,7 +111,7 @@ import jdk.xml.internal.SecuritySupport; * * * - * + * * * diff --git a/jaxp/src/java.xml/share/classes/javax/xml/datatype/DatatypeFactory.java b/jaxp/src/java.xml/share/classes/javax/xml/datatype/DatatypeFactory.java index afa1d1809a9..21ed157f3bb 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/datatype/DatatypeFactory.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/datatype/DatatypeFactory.java @@ -34,7 +34,7 @@ import com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl; /** * Factory that creates new {@code javax.xml.datatype} {@code Object}s that map XML to/from Java {@code Object}s. - *

+ *

* A new instance of the {@code DatatypeFactory} is created through the {@link #newInstance()} method * that uses the following implementation resolution mechanisms to determine an implementation: *

    diff --git a/jaxp/src/java.xml/share/classes/javax/xml/datatype/package-info.java b/jaxp/src/java.xml/share/classes/javax/xml/datatype/package-info.java index 3a440a5eafb..15c427e67ee 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/datatype/package-info.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/datatype/package-info.java @@ -149,23 +149,13 @@ *
  1. xs:unsignedShort
  2. * * - *
    - * - * - * - *
    * @since 1.5 */ From 429ba8883ae70aefe89f157a880f6a9a62d5d62d Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Fri, 28 Jul 2017 02:34:33 +0000 Subject: [PATCH 24/59] Added tag jdk-10+17 for changeset ddc079e73172 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 7759ffe4dfa..8faa13d434f 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -439,3 +439,4 @@ a6c830ee8a6798b186730475e700027cdf4598aa jdk-10+15 2fe66ca1e2b3c361f949de9cb2894661dc0a3fa2 jdk-10+16 ec4159ebe7050fcc5dcee8a2d150cf948ecc97db jdk-9+178 252475ccfd84cc249f8d6faf4b7806b5e2c384ce jdk-9+179 +a133a7d1007b1456bc62824382fd8ac93b45d329 jdk-10+17 From 8fb81f3e3ab618b4b9c2d892b7e786487c00b219 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Fri, 28 Jul 2017 02:34:34 +0000 Subject: [PATCH 25/59] Added tag jdk-10+17 for changeset 886f599a54e6 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index e05452975b8..93330098b14 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -599,3 +599,4 @@ c1f3649a3a42f124b418a5a916dbad13d059b757 jdk-10+15 2fe2a593e8ebf3a9e4dcd9ba3333a7b43126589d jdk-10+16 9d032191f82fca5ba0aac98682f69c4ff0f1283d jdk-9+178 d2661aa42bff322badbe6c1337fc638d2e0f5730 jdk-9+179 +73e2cb8700bfa51304bd4b02f224620859a3f600 jdk-10+17 From 177c76c0eba563eb3530dafdd7026250adb97314 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Fri, 28 Jul 2017 02:34:37 +0000 Subject: [PATCH 26/59] Added tag jdk-10+17 for changeset 88f61b15df6c --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index c4304d05803..ae9a9aab2e5 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -439,3 +439,4 @@ c72e9d3823f04cb3ef3166646dfea9e4c2769133 jdk-9+177 b82b62ed5debda2d98dda597506ef29cf947fbae jdk-10+16 9c1e9712648921ae389d623042d22561fad82d75 jdk-9+178 24390da83c5ee9e23ceafbcaff4460a01e37bb3a jdk-9+179 +50ff1fd66362f212a8db6de76089d9d0ffa4df0f jdk-10+17 From f91ca3df7108975db1fffb03e5e1014f6b5e22a3 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Fri, 28 Jul 2017 02:34:39 +0000 Subject: [PATCH 27/59] Added tag jdk-10+17 for changeset e5fbaa96e81b --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 3152488def9..52f64b895d0 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -430,3 +430,4 @@ f8a0c4895b2abe64a8c55af6117ffda192e34d30 jdk-10+15 f456f59dad3f6b74bcc3c668a56d51f5955cfb28 jdk-10+16 7497ad85759ff010f44344b553223d1647fb6eba jdk-9+178 3adfb547e3e49e304ffc82d8c6489cb830b74d62 jdk-9+179 +6ac0ca441ccb9ccc49c5007248dc1f3af8076a71 jdk-10+17 From ec8ed521b74e06aa4e16a3016f15bc57fa332d69 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Fri, 28 Jul 2017 02:34:40 +0000 Subject: [PATCH 28/59] Added tag jdk-10+17 for changeset 882cea808912 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 2520b0ff926..38265bedcdc 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -439,3 +439,4 @@ e069834e2c518a7bc2ffadc8c7e3cd7ec69fa8a0 jdk-10+15 3281b964ab104002623d744e8b77a12269b70acd jdk-10+16 443025bee731eb2225371b92c1c74b519b7baf33 jdk-9+178 06df1ce4b9b887d05ce6a13f4def3547e434dd1a jdk-9+179 +d93f2fd542b7d7855c2cd49ae15ebcc3d441a83b jdk-10+17 From aebc535a09a9f3320af77564cb6af9f43cdc67da Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Fri, 28 Jul 2017 02:34:45 +0000 Subject: [PATCH 29/59] Added tag jdk-10+17 for changeset 7ee858174605 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index ae4e7d20120..dae0ab0140c 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -439,3 +439,4 @@ add6717b655efa3aa9350e917175f3965cfc0729 jdk-10+14 4070d214e88729006184a4abbe8f494fcec6afb6 jdk-10+16 849e366ef175012e6dedc3ca151da416716e0ea9 jdk-9+178 b653b1b2ea883593596bc18e9af73a9b369eeb0a jdk-9+179 +41028d8c0a71c6beaf1886ca095e703fbb1513ec jdk-10+17 From c4fd444e12d8fbf737107c177e97f9ad4b2de708 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Fri, 28 Jul 2017 02:34:46 +0000 Subject: [PATCH 30/59] Added tag jdk-10+17 for changeset 832f85797be8 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 43e2ddb5352..2ab93a9d847 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -442,3 +442,4 @@ b44a721aee3d3b2537754e559fe9ecccadea548b jdk-9+177 bc8289ce1ed3ed5fff62152ed46da3be0b60b7c3 jdk-10+16 d0190aaf1816081d9b2e0577b65b793804896d1e jdk-9+178 56ac1831ac5924b5092a53a85d6fc68749501fb8 jdk-9+179 +4c07d366c2e177edba7aa54c4b015e4dbf12bc83 jdk-10+17 From 33ec10050436393b1a36448c75cda249bd45f966 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Fri, 28 Jul 2017 02:34:48 +0000 Subject: [PATCH 31/59] Added tag jdk-10+17 for changeset a3c10d5df818 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 3fbef6f0092..f2420478bb0 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -439,3 +439,4 @@ ff293e39e83366c40a5687dacd1ccb2305ed2c1e jdk-10+12 d109d55cf642bf2b438624e81f94c18c168f9178 jdk-10+16 0983b2dbe17ba4fed3af34e0512ca77a9845fe8a jdk-9+178 87243a3131f79e8b3903eaca6b629abc48f08ace jdk-9+179 +97d6f14334cfd766f57c296a5a707c8a709aeff0 jdk-10+17 From 135d500fc845339fd08390f44886483959a3009e Mon Sep 17 00:00:00 2001 From: Amy Lu Date: Fri, 28 Jul 2017 19:54:26 +0800 Subject: [PATCH 32/59] 8184894: Mark ExternalEditorTest.java as intermittently failing, demote to tier 2 Reviewed-by: jlahoda --- langtools/test/TEST.groups | 2 ++ langtools/test/jdk/jshell/ExternalEditorTest.java | 1 + 2 files changed, 3 insertions(+) diff --git a/langtools/test/TEST.groups b/langtools/test/TEST.groups index 0499d1b7dd4..885ac5f79ca 100644 --- a/langtools/test/TEST.groups +++ b/langtools/test/TEST.groups @@ -27,11 +27,13 @@ tier1 = \ jdk \ lib \ tools \ + -jdk/jshell/ExternalEditorTest.java \ -jdk/jshell/ToolReloadTest.java \ -jdk/jshell/ToolLocaleMessageTest.java # (Almost) no langtools tests are tier 2. tier2 = \ + jdk/jshell/ExternalEditorTest.java \ jdk/jshell/ToolReloadTest.java \ jdk/jshell/ToolLocaleMessageTest.java diff --git a/langtools/test/jdk/jshell/ExternalEditorTest.java b/langtools/test/jdk/jshell/ExternalEditorTest.java index 1c421e268a7..009afd87815 100644 --- a/langtools/test/jdk/jshell/ExternalEditorTest.java +++ b/langtools/test/jdk/jshell/ExternalEditorTest.java @@ -28,6 +28,7 @@ * @modules jdk.jshell/jdk.internal.jshell.tool * @build ReplToolTesting CustomEditor EditorTestBase * @run testng ExternalEditorTest + * @key intermittent */ import java.io.BufferedWriter; From 2cb9e39fc912e2a4acceb32995778b09cd6d04eb Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Fri, 28 Jul 2017 13:22:33 -0700 Subject: [PATCH 33/59] 8161121: VM::isSystemDomainLoader should consider platform class loader Reviewed-by: alanb --- jdk/src/java.base/share/classes/java/lang/Class.java | 4 ++-- .../share/classes/java/lang/invoke/MethodHandles.java | 2 +- .../share/classes/java/lang/reflect/Proxy.java | 2 +- .../jdk/internal/logger/DefaultLoggerFinder.java | 10 +++------- .../java.base/share/classes/jdk/internal/misc/VM.java | 6 +++--- .../share/classes/jdk/internal/reflect/Reflection.java | 3 +-- .../java/lang/management/ManagementFactory.java | 4 ++-- 7 files changed, 13 insertions(+), 18 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/Class.java b/jdk/src/java.base/share/classes/java/lang/Class.java index 679c0fa1066..8a4e38514e2 100644 --- a/jdk/src/java.base/share/classes/java/lang/Class.java +++ b/jdk/src/java.base/share/classes/java/lang/Class.java @@ -364,9 +364,9 @@ public final class Class implements java.io.Serializable, // Reflective call to get caller class is only needed if a security manager // is present. Avoid the overhead of making this call otherwise. caller = Reflection.getCallerClass(); - if (VM.isSystemDomainLoader(loader)) { + if (loader == null) { ClassLoader ccl = ClassLoader.getClassLoader(caller); - if (!VM.isSystemDomainLoader(ccl)) { + if (ccl != null) { sm.checkPermission( SecurityConstants.GET_CLASSLOADER_PERMISSION); } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 2bd64edb0e5..45ccb909490 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -2476,7 +2476,7 @@ return mh1; return false; } ClassLoader loader = defc.getClassLoader(); - if (!jdk.internal.misc.VM.isSystemDomainLoader(loader)) { + if (loader != null) { ClassLoader sysl = ClassLoader.getSystemClassLoader(); boolean found = false; while (sysl != null) { diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java index e2a950ed1c1..ee3395b6080 100644 --- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java @@ -453,7 +453,7 @@ public class Proxy implements java.io.Serializable { SecurityManager sm = System.getSecurityManager(); if (sm != null) { ClassLoader ccl = caller.getClassLoader(); - if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) { + if (loader == null && ccl != null) { sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); } ReflectUtil.checkProxyPackageAccess(ccl, interfaces); diff --git a/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java b/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java index 5ffd8fd7af4..986eea2c994 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java +++ b/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java @@ -25,6 +25,8 @@ package jdk.internal.logger; +import jdk.internal.misc.VM; + import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.HashMap; @@ -140,15 +142,9 @@ public class DefaultLoggerFinder extends LoggerFinder { return AccessController.doPrivileged(new PrivilegedAction<>() { @Override public Boolean run() { - final ClassLoader moduleCL = m.getClassLoader(); - if (moduleCL == null) return true; - ClassLoader cl = ClassLoader.getPlatformClassLoader(); - while (cl != null && moduleCL != cl) { - cl = cl.getParent(); - } // returns true if moduleCL is the platform class loader // or one of its ancestors. - return moduleCL == cl; + return VM.isSystemDomainLoader(m.getClassLoader()); } }); } diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java b/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java index 95961c74584..46a2dbb5067 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java @@ -124,11 +124,11 @@ public class VM { } /** - * Returns true if the given class loader is in the system domain - * in which all permissions are granted. + * Returns true if the given class loader is the bootstrap class loader + * or the platform class loader. */ public static boolean isSystemDomainLoader(ClassLoader loader) { - return loader == null; + return loader == null || loader == ClassLoader.getPlatformClassLoader(); } /** diff --git a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java index f2670e55200..384b67734a3 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java +++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java @@ -316,8 +316,7 @@ public class Reflection { */ public static boolean isCallerSensitive(Method m) { final ClassLoader loader = m.getDeclaringClass().getClassLoader(); - if (VM.isSystemDomainLoader(loader) || - loader == ClassLoaders.platformClassLoader()) { + if (VM.isSystemDomainLoader(loader)) { return m.isAnnotationPresent(CallerSensitive.class); } return false; diff --git a/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java b/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java index 90018468ff9..53adeb7d812 100644 --- a/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java +++ b/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java @@ -588,8 +588,8 @@ public class ManagementFactory { Class mxbeanInterface) throws java.io.IOException { - // Only allow MXBean interfaces from rt.jar loaded by the - // bootstrap class loader + // Only allow MXBean interfaces from the platform modules loaded by the + // bootstrap or platform class loader final Class cls = mxbeanInterface; ClassLoader loader = AccessController.doPrivileged( From 0fdd008b62eb26562a7b791068ef2c1c3c1bfc58 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Fri, 28 Jul 2017 14:29:29 -0700 Subject: [PATCH 34/59] 8183026: minor cleanup for IndexUseComparator 8163990: Utils.ElementComparator does not need to be generic Reviewed-by: jjg --- .../internal/doclets/toolkit/util/Utils.java | 311 ++++++++++-------- 1 file changed, 170 insertions(+), 141 deletions(-) diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java index ac6e4ec8a7c..a9334d0effd 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java @@ -679,10 +679,11 @@ public class Utils { } } - /** + /** * Get the signature. It is the parameter list, type is qualified. * For instance, for a method {@code mymethod(String x, int y)}, * it will return {@code(java.lang.String,int)}. + * * @param e * @return String */ @@ -1674,19 +1675,24 @@ public class Utils { } } + private Comparator moduleComparator = null; /** * Comparator for ModuleElements, simply compares the fully qualified names * @return a Comparator */ public Comparator makeModuleComparator() { - return new Utils.ElementComparator() { - @Override - public int compare(Element mod1, Element mod2) { - return compareFullyQualifiedNames(mod1, mod2); - } - }; + if (moduleComparator == null) { + moduleComparator = new Utils.ElementComparator() { + @Override + public int compare(Element mod1, Element mod2) { + return compareFullyQualifiedNames(mod1, mod2); + } + }; + } + return moduleComparator; } + private Comparator allClassesComparator = null; /** * Returns a Comparator for all classes, compares the simple names of * TypeElement, if equal then the fully qualified names. @@ -1694,42 +1700,53 @@ public class Utils { * @return Comparator */ public Comparator makeAllClassesComparator() { - return new Utils.ElementComparator() { - @Override - public int compare(Element e1, Element e2) { - int result = compareNames(e1, e2); - if (result == 0) - result = compareFullyQualifiedNames(e1, e2); + if (allClassesComparator == null) { + allClassesComparator = new Utils.ElementComparator() { + @Override + public int compare(Element e1, Element e2) { + int result = compareNames(e1, e2); + if (result == 0) + result = compareFullyQualifiedNames(e1, e2); - return result; - } - }; + return result; + } + }; + } + return allClassesComparator; } + private Comparator packageComparator = null; /** * Returns a Comparator for packages, by comparing the fully qualified names. * * @return a Comparator */ public Comparator makePackageComparator() { - return new Utils.ElementComparator() { - @Override - public int compare(Element pkg1, Element pkg2) { - return compareFullyQualifiedNames(pkg1, pkg2); - } - }; + if (packageComparator == null) { + packageComparator = new Utils.ElementComparator() { + @Override + public int compare(Element pkg1, Element pkg2) { + return compareFullyQualifiedNames(pkg1, pkg2); + } + }; + } + return packageComparator; } + private Comparator serialFieldTreeComparator = null; /** * Returns a Comparator for SerialFieldTree. * @return a Comparator */ public Comparator makeSerialFieldTreeComparator() { - return (SerialFieldTree o1, SerialFieldTree o2) -> { - String s1 = o1.getName().toString(); - String s2 = o2.getName().toString(); - return s1.compareTo(s2); - }; + if (serialFieldTreeComparator == null) { + serialFieldTreeComparator = (SerialFieldTree o1, SerialFieldTree o2) -> { + String s1 = o1.getName().toString(); + String s2 = o2.getName().toString(); + return s1.compareTo(s2); + }; + } + return serialFieldTreeComparator; } /** @@ -1740,6 +1757,7 @@ public class Utils { return makeClassUseComparator(); } + private Comparator overrideUseComparator = null; /** * Returns a Comparator for overrides and implements, * used primarily on methods, compares the name first, @@ -1748,33 +1766,38 @@ public class Utils { * @return a Comparator */ public Comparator makeOverrideUseComparator() { - return new Utils.ElementComparator() { - @Override - public int compare(Element o1, Element o2) { - int result = compareStrings(getSimpleName(o1), getSimpleName(o2)); - if (result != 0) { - return result; - } - if (!isTypeElement(o1) && !isTypeElement(o2) && !isPackage(o1) && !isPackage(o2)) { - TypeElement t1 = getEnclosingTypeElement(o1); - TypeElement t2 = getEnclosingTypeElement(o2); - result = compareStrings(getSimpleName(t1), getSimpleName(t2)); + if (overrideUseComparator == null) { + overrideUseComparator = new Utils.ElementComparator() { + @Override + public int compare(Element o1, Element o2) { + int result = compareStrings(getSimpleName(o1), getSimpleName(o2)); + if (result != 0) { + return result; + } + if (!isTypeElement(o1) && !isTypeElement(o2) && !isPackage(o1) && !isPackage(o2)) { + TypeElement t1 = getEnclosingTypeElement(o1); + TypeElement t2 = getEnclosingTypeElement(o2); + result = compareStrings(getSimpleName(t1), getSimpleName(t2)); + if (result != 0) + return result; + } + result = compareStrings(getFullyQualifiedName(o1), getFullyQualifiedName(o2)); if (result != 0) return result; + return compareElementTypeKinds(o1, o2); } - result = compareStrings(getFullyQualifiedName(o1), getFullyQualifiedName(o2)); - if (result != 0) - return result; - return compareElementTypeKinds(o1, o2); - } - }; + }; + } + return overrideUseComparator; } + private Comparator indexUseComparator = null; /** - * Returns a Comparator for index file presentations, and are sorted as follows. - * If comparing modules and packages then simply compare the qualified names, if comparing a module - * or a package with a type/member then compare the FullyQualifiedName of the module or a package - * with the SimpleName of the entity, otherwise + * Returns a Comparator for index file presentations, and are sorted as follows. + * If comparing modules and/or packages then simply compare the qualified names, + * if comparing a module or a package with a type/member then compare the + * FullyQualifiedName of the module or a package with the SimpleName of the entity, + * otherwise: * 1. compare the ElementKind ex: Module, Package, Interface etc. * 2a. if equal and if the type is of ExecutableElement(Constructor, Methods), * a case insensitive comparison of parameter the type signatures @@ -1783,73 +1806,76 @@ public class Utils { * @return a comparator for index file use */ public Comparator makeIndexUseComparator() { - return new Utils.ElementComparator() { - /** - * Compare two given elements, if comparing two modules or two packages, return the - * comparison of FullyQualifiedName, if comparing a module or a package with a - * type/member then compare the FullyQualifiedName of the module or the package - * with the SimpleName of the entity, then sort on the kinds, then on - * the parameters only if the type is an ExecutableElement, - * the parameters are compared and finally the qualified names. - * - * @param e1 - an element. - * @param e2 - an element. - * @return a negative integer, zero, or a positive integer as the first - * argument is less than, equal to, or greater than the second. - */ - @Override - public int compare(Element e1, Element e2) { - int result = 0; - if ((isModule(e1) || isPackage(e1)) && (isModule(e2) || isPackage(e2))) { - result = compareFullyQualifiedNames(e1, e2); + if (indexUseComparator == null) { + indexUseComparator = new Utils.ElementComparator() { + /** + * Compares two elements. + * + * @param e1 - an element. + * @param e2 - an element. + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second. + */ + @Override + public int compare(Element e1, Element e2) { + int result; + // first, compare names as appropriate + if ((isModule(e1) || isPackage(e1)) && (isModule(e2) || isPackage(e2))) { + result = compareFullyQualifiedNames(e1, e2); + } else if (isModule(e1) || isPackage(e1)) { + result = compareStrings(getFullyQualifiedName(e1), getSimpleName(e2)); + } else if (isModule(e2) || isPackage(e2)) { + result = compareStrings(getSimpleName(e1), getFullyQualifiedName(e2)); + } else { + result = compareNames(e1, e2); + } if (result != 0) { return result; } - return compareElementTypeKinds(e1, e2); - } - if (isModule(e1) || isPackage(e1)) { - result = compareStrings(getFullyQualifiedName(e1), getSimpleName(e2)); - } else if (isModule(e2) || isPackage(e2)) { - result = compareStrings(getSimpleName(e1), getFullyQualifiedName(e2)); - } else { - result = compareNames(e1, e2); - } - if (result != 0) { - return result; - } - result = compareElementTypeKinds(e1, e2); - if (result != 0) { - return result; - } - if (hasParameters(e1)) { - List parameters1 = ((ExecutableElement)e1).getParameters(); - List parameters2 = ((ExecutableElement)e2).getParameters(); - result = compareParameters(false, parameters1, parameters2); + // if names are the same, compare element kinds + result = compareElementTypeKinds(e1, e2); if (result != 0) { return result; } - result = compareParameters(true, parameters1, parameters2); - if (result != 0) { - return result; + // if element kinds are the same, and are methods, + // compare the method parameters + if (hasParameters(e1)) { + List parameters1 = ((ExecutableElement)e1).getParameters(); + List parameters2 = ((ExecutableElement)e2).getParameters(); + result = compareParameters(false, parameters1, parameters2); + if (result != 0) { + return result; + } + result = compareParameters(true, parameters1, parameters2); + if (result != 0) { + return result; + } } + // else fall back on fully qualified names + return compareFullyQualifiedNames(e1, e2); } - return compareFullyQualifiedNames(e1, e2); - } - }; + }; + } + return indexUseComparator; } + private Comparator typeMirrorClassUseComparator = null; /** * Compares the FullyQualifiedNames of two TypeMirrors * @return */ public Comparator makeTypeMirrorClassUseComparator() { - return (TypeMirror type1, TypeMirror type2) -> { - String s1 = getQualifiedTypeName(type1); - String s2 = getQualifiedTypeName(type2); - return compareStrings(s1, s2); - }; + if (typeMirrorClassUseComparator == null) { + typeMirrorClassUseComparator = (TypeMirror type1, TypeMirror type2) -> { + String s1 = getQualifiedTypeName(type1); + String s2 = getQualifiedTypeName(type2); + return compareStrings(s1, s2); + }; + } + return typeMirrorClassUseComparator; } + private Comparator typeMirrorIndexUseComparator = null; /** * Compares the SimpleNames of TypeMirrors if equal then the * FullyQualifiedNames of TypeMirrors. @@ -1857,12 +1883,15 @@ public class Utils { * @return */ public Comparator makeTypeMirrorIndexUseComparator() { - return (TypeMirror t1, TypeMirror t2) -> { - int result = compareStrings(getTypeName(t1, false), getTypeName(t2, false)); - if (result != 0) - return result; - return compareStrings(getQualifiedTypeName(t1), getQualifiedTypeName(t2)); - }; + if (typeMirrorIndexUseComparator == null) { + typeMirrorIndexUseComparator = (TypeMirror t1, TypeMirror t2) -> { + int result = compareStrings(getTypeName(t1, false), getTypeName(t2, false)); + if (result != 0) + return result; + return compareStrings(getQualifiedTypeName(t1), getQualifiedTypeName(t2)); + }; + } + return typeMirrorIndexUseComparator; } /** @@ -1936,6 +1965,7 @@ public class Utils { }.visit(e); } + private Comparator classUseComparator = null; /** * Comparator for ClassUse presentations, and sorts as follows: * 1. member names @@ -1945,51 +1975,52 @@ public class Utils { * @return a comparator to sort classes and members for class use */ public Comparator makeClassUseComparator() { - return new Utils.ElementComparator() { - /** - * Compare two Elements, first sort on simple name, and if - * applicable on the fully qualified name, and finally if applicable - * on the parameter types. - * @param e1 - an element. - * @param e2 - an element. - * @return a negative integer, zero, or a positive integer as the first - * argument is less than, equal to, or greater than the second. - */ - @Override - public int compare(Element e1, Element e2) { - int result = compareNames(e1, e2); - if (result != 0) { - return result; - } - result = compareFullyQualifiedNames(e1, e2); - if (result != 0) { - return result; - } - if (hasParameters(e1) && hasParameters(e2)) { - @SuppressWarnings("unchecked") - List parameters1 = (List) ((ExecutableElement)e1).getParameters(); - @SuppressWarnings("unchecked") - List parameters2 = (List) ((ExecutableElement)e2).getParameters(); - result = compareParameters(false, parameters1, parameters2); + if (classUseComparator == null) { + classUseComparator = new Utils.ElementComparator() { + /** + * Compares two Elements. + * + * @param e1 - an element. + * @param e2 - an element. + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second. + */ + @Override + public int compare(Element e1, Element e2) { + int result = compareNames(e1, e2); if (result != 0) { return result; } - result = compareParameters(true, parameters1, parameters2); + result = compareFullyQualifiedNames(e1, e2); + if (result != 0) { + return result; + } + if (hasParameters(e1) && hasParameters(e2)) { + @SuppressWarnings("unchecked") + List parameters1 = (List)((ExecutableElement)e1).getParameters(); + @SuppressWarnings("unchecked") + List parameters2 = (List)((ExecutableElement)e2).getParameters(); + result = compareParameters(false, parameters1, parameters2); + if (result != 0) { + return result; + } + result = compareParameters(true, parameters1, parameters2); + } + if (result != 0) { + return result; + } + return compareElementTypeKinds(e1, e2); } - if (result != 0) { - return result; - } - return compareElementTypeKinds(e1, e2); - } - }; + }; + } + return classUseComparator; } /** * A general purpose comparator to sort Element entities, basically provides the building blocks * for creating specific comparators for an use-case. - * @param an Element */ - private abstract class ElementComparator implements Comparator { + private abstract class ElementComparator implements Comparator { /** * compares two parameter arrays by first comparing the length of the arrays, and * then each Type of the parameter in the array. @@ -2097,8 +2128,6 @@ public class Utils { /** * The fully qualified names of the entities, used solely by the comparator. * - * @param p1 the first Element. - * @param p2 the first Element. * @return a negative integer, zero, or a positive integer as the first argument is less * than, equal to, or greater than the second. */ From d8492f4fcd03a2bcddb16deb327d5d1b67b3a641 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Fri, 28 Jul 2017 15:00:53 -0700 Subject: [PATCH 35/59] 8184969: Cannot specify multiple -link to jdk9 javadoc Reviewed-by: jjg --- .../doclets/toolkit/BaseConfiguration.java | 513 +++++++++--------- .../internal/doclets/toolkit/util/Extern.java | 35 +- .../internal/doclets/toolkit/util/Utils.java | 15 + .../doclet/testLinkOption/TestLinkOption.java | 44 +- .../javadoc/doclet/testLinkOption/pkg3/A.java | 34 ++ 5 files changed, 377 insertions(+), 264 deletions(-) create mode 100644 langtools/test/jdk/javadoc/doclet/testLinkOption/pkg3/A.java diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java index e1ca4018e95..f5ce8f8d5b9 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java @@ -55,6 +55,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.MetaKeywords; import jdk.javadoc.internal.doclets.toolkit.util.SimpleDocletException; import jdk.javadoc.internal.doclets.toolkit.util.TypeElementCatalog; import jdk.javadoc.internal.doclets.toolkit.util.Utils; +import jdk.javadoc.internal.doclets.toolkit.util.Utils.Pair; import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap; import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap.GetterSetter; import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap.Kind; @@ -66,11 +67,11 @@ import static javax.tools.Diagnostic.Kind.*; * BaseConfiguration, to configure and add their own options. This class contains * all user options which are supported by the 1.1 doclet and the standard * doclet. - * - *

    This is NOT part of any supported API. - * If you write code that depends on this, you do so at your own risk. - * This code and its internal interfaces are subject to change or - * deletion without notice. + *

    + *

    This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. * * @author Robert Field. * @author Atul Dambalkar. @@ -240,7 +241,6 @@ public abstract class BaseConfiguration { /** * Sourcepath from where to read the source files. Default is classpath. - * */ public String sourcepath = ""; @@ -266,7 +266,7 @@ public abstract class BaseConfiguration { * True if user wants to suppress time stamp in output. * Default is false. */ - public boolean notimestamp= false; + public boolean notimestamp = false; /** * The package grouping instance. @@ -278,7 +278,7 @@ public abstract class BaseConfiguration { */ public final Extern extern = new Extern(this); - public Reporter reporter; + public Reporter reporter; public Locale locale; @@ -287,21 +287,21 @@ public abstract class BaseConfiguration { */ public boolean quiet = false; - private String urlForLink; + // A list containing urls + private final List linkList = new ArrayList<>(); - private String pkglistUrlForLink; + // A list of pairs containing urls and package list + private final List> linkOfflineList = new ArrayList<>(); - private String urlForLinkOffline; - - private String pkglistUrlForLinkOffline; public boolean dumpOnError = false; - private List groups; + private List> groupPairs; private final Map>> typeElementMemberCache; public abstract Messages getMessages(); + public abstract Resources getResources(); /** @@ -342,15 +342,17 @@ public abstract class BaseConfiguration { */ public SortedMap> modulePackages; - /** - * The list of known modules, that should be documented. - */ + /** + * The list of known modules, that should be documented. + */ public SortedSet modules; protected static final String sharedResourceBundleName = "jdk.javadoc.internal.doclets.toolkit.resources.doclets"; + /** * Constructs the configurations needed by the doclet. + * * @param doclet the doclet that created this configuration */ public BaseConfiguration(Doclet doclet) { @@ -359,7 +361,7 @@ public abstract class BaseConfiguration { excludedQualifiers = new HashSet<>(); setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH); metakeywords = new MetaKeywords(this); - groups = new ArrayList<>(0); + groupPairs = new ArrayList<>(0); typeElementMemberCache = new HashMap<>(); } @@ -400,31 +402,37 @@ public abstract class BaseConfiguration { } private Set specifiedModuleElements; + public Set getSpecifiedModuleElements() { return specifiedModuleElements; } private Set specifiedPackageElements; + public Set getSpecifiedPackageElements() { return specifiedPackageElements; } private Set specifiedTypeElements; + public Set getSpecifiedTypeElements() { return specifiedTypeElements; } private Set includedModuleElements; + public Set getIncludedModuleElements() { return includedModuleElements; } private Set includedPackageElements; + public Set getIncludedPackageElements() { return includedPackageElements; } private Set includedTypeElements; + public Set getIncludedTypeElements() { return includedTypeElements; } @@ -435,7 +443,7 @@ public abstract class BaseConfiguration { modules.addAll(getSpecifiedModuleElements()); modulePackages = new TreeMap<>(utils.makeModuleComparator()); - for (PackageElement p: packages) { + for (PackageElement p : packages) { ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p); if (mdle != null && !mdle.isUnnamed()) { Set s = modulePackages @@ -444,7 +452,7 @@ public abstract class BaseConfiguration { } } - for (PackageElement p: getIncludedPackageElements()) { + for (PackageElement p : getIncludedPackageElements()) { ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p); if (mdle != null && !mdle.isUnnamed()) { Set s = modulePackages @@ -474,207 +482,205 @@ public abstract class BaseConfiguration { public Set getSupportedOptions() { Resources resources = getResources(); Doclet.Option[] options = { - new Option(resources, "-author") { - @Override - public boolean process(String opt, List args) { - showauthor = true; - return true; - } - }, - new Option(resources, "-d", 1) { - @Override - public boolean process(String opt, List args) { - destDirName = addTrailingFileSep(args.get(0)); - return true; - } - }, - new Option(resources, "-docencoding", 1) { - @Override - public boolean process(String opt, List args) { - docencoding = args.get(0); - return true; - } - }, - new Option(resources, "-docfilessubdirs") { - @Override - public boolean process(String opt, List args) { - copydocfilesubdirs = true; - return true; - } - }, - new Hidden(resources, "-encoding", 1) { - @Override - public boolean process(String opt, List args) { - encoding = args.get(0); - return true; - } - }, - new Option(resources, "-excludedocfilessubdir", 1) { - @Override - public boolean process(String opt, List args) { - addToSet(excludedDocFileDirs, args.get(0)); - return true; - } - }, - new Option(resources, "-group", 2) { - @Override - public boolean process(String opt, List args) { - groups.add(new GroupContainer(args.get(0), args.get(1))); - return true; - } - }, - new Option(resources, "--javafx -javafx") { - @Override - public boolean process(String opt, List args) { - javafx = true; - return true; - } - }, - new Option(resources, "-keywords") { - @Override - public boolean process(String opt, List args) { - keywords = true; - return true; - } - }, - new Option(resources, "-link", 1) { - @Override - public boolean process(String opt, List args) { - urlForLink = args.get(0); - pkglistUrlForLink = urlForLink; - return true; - } - }, - new Option(resources, "-linksource") { - @Override - public boolean process(String opt, List args) { - linksource = true; - return true; - } - }, - new Option(resources, "-linkoffline", 2) { - @Override - public boolean process(String opt, List args) { - urlForLinkOffline = args.get(0); - pkglistUrlForLinkOffline = args.get(1); - return true; - } - }, - new Option(resources, "-nocomment") { - @Override - public boolean process(String opt, List args) { - nocomment = true; - return true; - } - }, - new Option(resources, "-nodeprecated") { - @Override - public boolean process(String opt, List args) { - nodeprecated = true; - return true; - } - }, - new Option(resources, "-nosince") { - @Override - public boolean process(String opt, List args) { - nosince = true; - return true; - } - }, - new Option(resources, "-notimestamp") { - @Override - public boolean process(String opt, List args) { - notimestamp = true; - return true; - } - }, - new Option(resources, "-noqualifier", 1) { - @Override - public boolean process(String opt, List args) { - addToSet(excludedQualifiers, args.get(0)); - return true; - } - }, - new Hidden(resources, "-quiet") { - @Override - public boolean process(String opt, List args) { - quiet = true; - return true; - } - }, - new Option(resources, "-serialwarn") { - @Override - public boolean process(String opt, List args) { - serialwarn = true; - return true; - } - }, - new Option(resources, "-sourcetab", 1) { - @Override - public boolean process(String opt, List args) { - linksource = true; - try { - setTabWidth(Integer.parseInt(args.get(0))); - } catch (NumberFormatException e) { - //Set to -1 so that warning will be printed - //to indicate what is valid argument. - sourcetab = -1; + new Option(resources, "-author") { + @Override + public boolean process(String opt, List args) { + showauthor = true; + return true; } - if (sourcetab <= 0) { - getMessages().warning("doclet.sourcetab_warning"); - setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH); + }, + new Option(resources, "-d", 1) { + @Override + public boolean process(String opt, List args) { + destDirName = addTrailingFileSep(args.get(0)); + return true; + } + }, + new Option(resources, "-docencoding", 1) { + @Override + public boolean process(String opt, List args) { + docencoding = args.get(0); + return true; + } + }, + new Option(resources, "-docfilessubdirs") { + @Override + public boolean process(String opt, List args) { + copydocfilesubdirs = true; + return true; + } + }, + new Hidden(resources, "-encoding", 1) { + @Override + public boolean process(String opt, List args) { + encoding = args.get(0); + return true; + } + }, + new Option(resources, "-excludedocfilessubdir", 1) { + @Override + public boolean process(String opt, List args) { + addToSet(excludedDocFileDirs, args.get(0)); + return true; + } + }, + new Option(resources, "-group", 2) { + @Override + public boolean process(String opt, List args) { + groupPairs.add(new Pair<>(args.get(0), args.get(1))); + return true; + } + }, + new Option(resources, "--javafx -javafx") { + @Override + public boolean process(String opt, List args) { + javafx = true; + return true; + } + }, + new Option(resources, "-keywords") { + @Override + public boolean process(String opt, List args) { + keywords = true; + return true; + } + }, + new Option(resources, "-link", 1) { + @Override + public boolean process(String opt, List args) { + linkList.add(args.get(0)); + return true; + } + }, + new Option(resources, "-linksource") { + @Override + public boolean process(String opt, List args) { + linksource = true; + return true; + } + }, + new Option(resources, "-linkoffline", 2) { + @Override + public boolean process(String opt, List args) { + linkOfflineList.add(new Pair(args.get(0), args.get(1))); + return true; + } + }, + new Option(resources, "-nocomment") { + @Override + public boolean process(String opt, List args) { + nocomment = true; + return true; + } + }, + new Option(resources, "-nodeprecated") { + @Override + public boolean process(String opt, List args) { + nodeprecated = true; + return true; + } + }, + new Option(resources, "-nosince") { + @Override + public boolean process(String opt, List args) { + nosince = true; + return true; + } + }, + new Option(resources, "-notimestamp") { + @Override + public boolean process(String opt, List args) { + notimestamp = true; + return true; + } + }, + new Option(resources, "-noqualifier", 1) { + @Override + public boolean process(String opt, List args) { + addToSet(excludedQualifiers, args.get(0)); + return true; + } + }, + new Hidden(resources, "-quiet") { + @Override + public boolean process(String opt, List args) { + quiet = true; + return true; + } + }, + new Option(resources, "-serialwarn") { + @Override + public boolean process(String opt, List args) { + serialwarn = true; + return true; + } + }, + new Option(resources, "-sourcetab", 1) { + @Override + public boolean process(String opt, List args) { + linksource = true; + try { + setTabWidth(Integer.parseInt(args.get(0))); + } catch (NumberFormatException e) { + //Set to -1 so that warning will be printed + //to indicate what is valid argument. + sourcetab = -1; + } + if (sourcetab <= 0) { + getMessages().warning("doclet.sourcetab_warning"); + setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH); + } + return true; + } + }, + new Option(resources, "-tag", 1) { + @Override + public boolean process(String opt, List args) { + ArrayList list = new ArrayList<>(); + list.add(opt); + list.add(args.get(0)); + customTagStrs.add(list); + return true; + } + }, + new Option(resources, "-taglet", 1) { + @Override + public boolean process(String opt, List args) { + ArrayList list = new ArrayList<>(); + list.add(opt); + list.add(args.get(0)); + customTagStrs.add(list); + return true; + } + }, + new Option(resources, "-tagletpath", 1) { + @Override + public boolean process(String opt, List args) { + tagletpath = args.get(0); + return true; + } + }, + new Option(resources, "-version") { + @Override + public boolean process(String opt, List args) { + showversion = true; + return true; + } + }, + new Hidden(resources, "--dump-on-error") { + @Override + public boolean process(String opt, List args) { + dumpOnError = true; + return true; + } + }, + new Option(resources, "--allow-script-in-comments") { + @Override + public boolean process(String opt, List args) { + allowScriptInComments = true; + return true; } - return true; } - }, - new Option(resources, "-tag", 1) { - @Override - public boolean process(String opt, List args) { - ArrayList list = new ArrayList<>(); - list.add(opt); - list.add(args.get(0)); - customTagStrs.add(list); - return true; - } - }, - new Option(resources, "-taglet", 1) { - @Override - public boolean process(String opt, List args) { - ArrayList list = new ArrayList<>(); - list.add(opt); - list.add(args.get(0)); - customTagStrs.add(list); - return true; - } - }, - new Option(resources, "-tagletpath", 1) { - @Override - public boolean process(String opt, List args) { - tagletpath = args.get(0); - return true; - } - }, - new Option(resources, "-version") { - @Override - public boolean process(String opt, List args) { - showversion = true; - return true; - } - }, - new Hidden(resources, "--dump-on-error") { - @Override - public boolean process(String opt, List args) { - dumpOnError = true; - return true; - } - }, - new Option(resources, "--allow-script-in-comments") { - @Override - public boolean process(String opt, List args) { - allowScriptInComments = true; - return true; - } - } }; Set set = new TreeSet<>(); set.addAll(Arrays.asList(options)); @@ -689,20 +695,22 @@ public abstract class BaseConfiguration { */ private void finishOptionSettings0() throws DocletException { initDestDirectory(); - if (urlForLink != null && pkglistUrlForLink != null) - extern.link(urlForLink, pkglistUrlForLink, reporter, false); - if (urlForLinkOffline != null && pkglistUrlForLinkOffline != null) - extern.link(urlForLinkOffline, pkglistUrlForLinkOffline, reporter, true); + for (String link : linkList) { + extern.link(link, reporter); + } + for (Pair linkOfflinePair : linkOfflineList) { + extern.link(linkOfflinePair.first, linkOfflinePair.second, reporter); + } if (docencoding == null) { docencoding = encoding; } typeElementCatalog = new TypeElementCatalog(includedTypeElements, this); initTagletManager(customTagStrs); - groups.stream().forEach((grp) -> { + groupPairs.stream().forEach((grp) -> { if (showModules) { - group.checkModuleGroups(grp.value1, grp.value2); + group.checkModuleGroups(grp.first, grp.second); } else { - group.checkPackageGroups(grp.value1, grp.value2); + group.checkPackageGroups(grp.first, grp.second); } }); } @@ -748,12 +756,12 @@ public abstract class BaseConfiguration { * be in the following format: "[tag name]:[location str]:[heading]". * * @param customTagStrs the set two dimensional arrays of strings. These arrays contain - * either -tag or -taglet arguments. + * either -tag or -taglet arguments. */ private void initTagletManager(Set> customTagStrs) { tagletManager = tagletManager == null ? - new TagletManager(nosince, showversion, showauthor, javafx, this) : - tagletManager; + new TagletManager(nosince, showversion, showauthor, javafx, this) : + tagletManager; for (List args : customTagStrs) { if (args.get(0).equals("-taglet")) { tagletManager.addCustomTag(args.get(1), getFileManager(), tagletpath); @@ -793,12 +801,11 @@ public abstract class BaseConfiguration { * @param maxTokens the maximum number of tokens returned. If the * max is reached, the remaining part of s is appended * to the end of the last token. - * * @return an array of tokens. */ private List tokenize(String s, char separator, int maxTokens) { List tokens = new ArrayList<>(); - StringBuilder token = new StringBuilder (); + StringBuilder token = new StringBuilder(); boolean prevIsEscapeChar = false; for (int i = 0; i < s.length(); i += Character.charCount(i)) { int currentChar = s.codePointAt(i); @@ -806,7 +813,7 @@ public abstract class BaseConfiguration { // Case 1: escaped character token.appendCodePoint(currentChar); prevIsEscapeChar = false; - } else if (currentChar == separator && tokens.size() < maxTokens-1) { + } else if (currentChar == separator && tokens.size() < maxTokens - 1) { // Case 2: separator tokens.add(token.toString()); token = new StringBuilder(); @@ -824,10 +831,10 @@ public abstract class BaseConfiguration { return tokens; } - private void addToSet(Set s, String str){ + private void addToSet(Set s, String str) { StringTokenizer st = new StringTokenizer(str, ":"); String current; - while(st.hasMoreTokens()){ + while (st.hasMoreTokens()) { current = st.nextToken(); s.add(current); } @@ -847,7 +854,7 @@ public abstract class BaseConfiguration { int indexDblfs; while ((indexDblfs = path.indexOf(dblfs, 1)) >= 0) { path = path.substring(0, indexDblfs) + - path.substring(indexDblfs + fs.length()); + path.substring(indexDblfs + fs.length()); } if (!path.endsWith(fs)) path += fs; @@ -855,7 +862,6 @@ public abstract class BaseConfiguration { } /** - * * This checks for the validity of the options used by the user. * As of this writing, this checks only docencoding. * @@ -883,7 +889,7 @@ public abstract class BaseConfiguration { * @param reporter used to report errors. */ private boolean checkOutputFileEncoding(String docencoding) { - OutputStream ost= new ByteArrayOutputStream(); + OutputStream ost = new ByteArrayOutputStream(); OutputStreamWriter osw = null; try { osw = new OutputStreamWriter(ost, docencoding); @@ -908,7 +914,7 @@ public abstract class BaseConfiguration { * @param docfilesubdir the doc-files subdirectory to check. * @return true if the directory is excluded. */ - public boolean shouldExcludeDocFileDir(String docfilesubdir){ + public boolean shouldExcludeDocFileDir(String docfilesubdir) { return excludedDocFileDirs.contains(docfilesubdir); } @@ -918,10 +924,10 @@ public abstract class BaseConfiguration { * @param qualifier the qualifier to check. * @return true if the qualifier should be excluded */ - public boolean shouldExcludeQualifier(String qualifier){ + public boolean shouldExcludeQualifier(String qualifier) { if (excludedQualifiers.contains("all") || - excludedQualifiers.contains(qualifier) || - excludedQualifiers.contains(qualifier + ".*")) { + excludedQualifiers.contains(qualifier) || + excludedQualifiers.contains(qualifier + ".*")) { return true; } else { int index = -1; @@ -956,7 +962,7 @@ public abstract class BaseConfiguration { * @param key the key for the desired string * @return the string for the given key * @throws MissingResourceException if the key is not found in either - * bundle. + * bundle. */ public abstract String getText(String key); @@ -965,11 +971,11 @@ public abstract class BaseConfiguration { * {@link Resources resources}. * Equivalent to getResources.getText(key, args);. * - * @param key the key for the desired string + * @param key the key for the desired string * @param args values to be substituted into the resulting string * @return the string for the given key * @throws MissingResourceException if the key is not found in either - * bundle. + * bundle. */ public abstract String getText(String key, String... args); @@ -997,8 +1003,8 @@ public abstract class BaseConfiguration { * {@link Resources resources} as a {@code Content} object. * * @param key the key for the desired string - * @param o1 resource argument - * @param o2 resource argument + * @param o1 resource argument + * @param o2 resource argument * @return a content tree for the text */ public abstract Content getContent(String key, Object o1, Object o2); @@ -1045,8 +1051,8 @@ public abstract class BaseConfiguration { */ public InputStream getBuilderXML() throws DocFileIOException { return builderXMLPath == null ? - BaseConfiguration.class.getResourceAsStream(DEFAULT_BUILDER_XML) : - DocFile.createFileForInput(this, builderXMLPath).openInputStream(); + BaseConfiguration.class.getResourceAsStream(DEFAULT_BUILDER_XML) : + DocFile.createFileForInput(this, builderXMLPath).openInputStream(); } /** @@ -1202,18 +1208,6 @@ public abstract class BaseConfiguration { } } - /* - * Stores a pair of Strings. - */ - protected static class GroupContainer { - final String value1; - final String value2; - public GroupContainer(String value1, String value2) { - this.value1 = value1; - this.value2 = value2; - } - } - /* * Splits the elements in a collection to its individual * collection. @@ -1267,6 +1261,7 @@ public abstract class BaseConfiguration { /** * Returns whether or not to allow JavaScript in comments. * Default is off; can be set true from a command line option. + * * @return the allowScriptInComments */ public boolean isAllowScriptInComments() { diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java index fae7e3e5f77..11c31cc3baa 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java @@ -170,6 +170,36 @@ public class Extern { } /** + * Build the extern package list from given URL or the directory path, + * as specified with the "-link" flag. + * Flag error if the "-link" or "-linkoffline" option is already used. + * + * @param url URL or Directory path. + * @param reporter The DocErrorReporter used to report errors. + * @return true if successful, false otherwise + * @throws DocFileIOException if there is a problem reading a package list file + */ + public boolean link(String url, Reporter reporter) throws DocFileIOException { + return link(url, url, reporter, false); + } + + /** + * Build the extern package list from given URL or the directory path, + * as specified with the "-linkoffline" flag. + * Flag error if the "-link" or "-linkoffline" option is already used. + * + * @param url URL or Directory path. + * @param pkglisturl This can be another URL for "package-list" or ordinary + * file. + * @param reporter The DocErrorReporter used to report errors. + * @return true if successful, false otherwise + * @throws DocFileIOException if there is a problem reading a package list file + */ + public boolean link(String url, String pkglisturl, Reporter reporter) throws DocFileIOException { + return link(url, pkglisturl, reporter, true); + } + + /* * Build the extern package list from given URL or the directory path. * Flag error if the "-link" or "-linkoffline" option is already used. * @@ -181,7 +211,7 @@ public class Extern { * @return true if successful, false otherwise * @throws DocFileIOException if there is a problem reading a package list file */ - public boolean link(String url, String pkglisturl, Reporter reporter, boolean linkoffline) + private boolean link(String url, String pkglisturl, Reporter reporter, boolean linkoffline) throws DocFileIOException { this.linkoffline = linkoffline; try { @@ -245,8 +275,7 @@ public class Extern { readPackageList(link.openStream(), urlpath, false); } catch (URISyntaxException | MalformedURLException exc) { throw new Fault(configuration.getText("doclet.MalformedURL", pkglisturlpath.toString()), exc); - } - catch (IOException exc) { + } catch (IOException exc) { throw new Fault(configuration.getText("doclet.URL_error", pkglisturlpath.toString()), exc); } } diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java index a9334d0effd..676bb3cc4d6 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java @@ -3328,4 +3328,19 @@ public class Utils { return out; } } + + /** + * A simple pair container. + * @param first a value + * @param second another value + */ + public static class Pair { + public final K first; + public final L second; + + public Pair(K first, L second) { + this.first = first; + this.second = second; + } + } } diff --git a/langtools/test/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java b/langtools/test/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java index a4378fc52dc..094218a4a4f 100644 --- a/langtools/test/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java +++ b/langtools/test/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. * 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 4720957 5020118 8026567 8038976 + * @bug 4720957 5020118 8026567 8038976 8184969 * @summary Test to make sure that -link and -linkoffline link to * right files, and URLs with and without trailing slash are accepted. * @author jamieh @@ -135,6 +135,46 @@ public class TestLinkOption extends JavadocTester { // this is the text that is given when there is a problem with a URL checkOutput(Output.OUT, false, "warning - Error fetching URL"); + + // check multiple link options + javadoc("-d", "out5", + "-sourcepath", testSrc, + "-link", "../" + "out1", + "-link", "../" + "out2", + "pkg3"); + checkExit(Exit.OK); + checkOutput("pkg3/A.html", true, + "

    public class A\n"
    +                + "extends java.lang.Object
    \n" + + "
    Test links.\n" + + "
    \n" + + " link to pkg2.C2\n" + + "
    \n" + + " " + + "link to mylib.lang.StringBuilderChild.
    \n" + ); + + // check multiple linkoffline options + javadoc("-d", "out6", + "-sourcepath", testSrc, + "-linkoffline", "../copy/out1", "out1", + "-linkoffline", "../copy/out2", "out2", + "pkg3"); + checkExit(Exit.OK); + checkOutput("pkg3/A.html", true, + "
    public class A\n"
    +                        + "extends java.lang.Object
    \n" + + "
    Test links.\n" + + "
    \n" + + " link to pkg2.C2\n" + + "
    \n" + + " " + + "link to mylib.lang.StringBuilderChild.
    \n" + ); } /* diff --git a/langtools/test/jdk/javadoc/doclet/testLinkOption/pkg3/A.java b/langtools/test/jdk/javadoc/doclet/testLinkOption/pkg3/A.java new file mode 100644 index 00000000000..afff357ed42 --- /dev/null +++ b/langtools/test/jdk/javadoc/doclet/testLinkOption/pkg3/A.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 pkg3; + +/** + * Test links. + *
    + * {@link pkg2.C2 link to pkg2.C2} + *
    + * {@link mylib.lang.StringBuilderChild link to mylib.lang.StringBuilderChild}. + */ + +public class A {} From 85c53bd5529e633a63e497aa0c85856988826415 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 31 Jul 2017 16:02:23 -0700 Subject: [PATCH 36/59] 8185588: jdk.attach API has accessibility issues Reviewed-by: alanb --- .../com/sun/tools/attach/AttachPermission.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/jdk/src/jdk.attach/share/classes/com/sun/tools/attach/AttachPermission.java b/jdk/src/jdk.attach/share/classes/com/sun/tools/attach/AttachPermission.java index 5c8caaeece7..48219bfc6bc 100644 --- a/jdk/src/jdk.attach/share/classes/com/sun/tools/attach/AttachPermission.java +++ b/jdk/src/jdk.attach/share/classes/com/sun/tools/attach/AttachPermission.java @@ -42,14 +42,16 @@ package com.sun.tools.attach; * *
Catalog Features
FILESFILESA semicolon-delimited list of URIs to locate the catalog files. * The URIs must be absolute and have a URL protocol handler for the URI scheme. *
PREFERPREFERIndicates the preference between the public and system * identifiers. The default value is public [3].javax.xml.catalog.prefer
DEFERDEFERIndicates that the alternative catalogs including those * specified in delegate entries or nextCatalog are not read until they are * needed. The default value is true.
RESOLVERESOLVEDetermines the action if there is no matching entry found after * all of the specified catalogs are exhausted. The default is strict.javax.xml.catalog.resolve [4]
+ * * - * - * - * + * + * + * * - * + * + * * - * + * * @@ -59,14 +61,14 @@ package com.sun.tools.attach; * * * - * + * * * * - + * * *
Table shows permission * target name, what the permission allows, and associated risks
Permission Target NameWhat the Permission AllowsRisks of Allowing this PermissionPermission Target NameWhat the Permission AllowsRisks of Allowing this Permission
attachVirtualMachineattachVirtualMachineAbility to attach to another Java virtual machine and load agents * into that VM. *
createAttachProvidercreateAttachProviderAbility to create an AttachProvider instance. * This allows an attacker to create an AttachProvider which can * potentially be used to attach to other Java virtual machines. *
From 2de62f2a743a76f19cbb28c9cb278de2192e3f82 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 31 Jul 2017 17:37:46 -0700 Subject: [PATCH 37/59] 8185589: jdk.management API has accessibility issues Reviewed-by: alanb --- .../management/DiagnosticCommandMBean.java | 42 +++++++++++-------- .../GarbageCollectionNotificationInfo.java | 16 ++++--- .../classes/com/sun/management/GcInfo.java | 18 ++++---- .../classes/com/sun/management/VMOption.java | 16 ++++--- 4 files changed, 56 insertions(+), 36 deletions(-) diff --git a/jdk/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java b/jdk/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java index 1424835ae2d..95e9f99e643 100644 --- a/jdk/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java @@ -107,35 +107,38 @@ import javax.management.DynamicMBean; * diagnostic command are described in the table below: * * + * * - * + * * + * + * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * + * *
description
NameTypeDescriptionNameTypeDescription
dcmd.nameStringdcmd.nameStringThe original diagnostic command name (not the operation name)
dcmd.descriptionStringdcmd.descriptionStringThe diagnostic command description
dcmd.helpStringdcmd.helpStringThe full help message for this diagnostic command (same output as * the one produced by the 'help' command)
dcmd.vmImpactStringdcmd.vmImpactStringThe impact of the diagnostic command, * this value is the same as the one printed in the 'impact' * section of the help message of the diagnostic command, and it * is different from the getImpact() of the MBeanOperationInfo
dcmd.enabledbooleandcmd.enabledbooleanTrue if the diagnostic command is enabled, false otherwise
dcmd.permissionClassStringdcmd.permissionClassStringSome diagnostic command might require a specific permission to be * executed, in addition to the MBeanPermission to invoke their * associated MBean operation. This field returns the fully qualified @@ -143,22 +146,23 @@ import javax.management.DynamicMBean; *
dcmd.permissionNameStringdcmd.permissionNameStringThe fist argument of the permission required to execute this * diagnostic command or null if no permission is required
dcmd.permissionActionStringdcmd.permissionActionStringThe second argument of the permission required to execute this * diagnostic command or null if the permission constructor has only * one argument (like the ManagementPermission) or if no permission * is required
dcmd.argumentsDescriptordcmd.argumentsDescriptorA Descriptor instance containing the descriptions of options and * arguments supported by the diagnostic command (see below)
* *

The description of parameters (options or arguments) of a diagnostic @@ -168,37 +172,41 @@ import javax.management.DynamicMBean; * instance are described in the table below: * * + * * - * + * * + * + * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * + * *
description
NameTypeDescriptionNameTypeDescription
dcmd.arg.nameStringdcmd.arg.nameStringThe name of the parameter
dcmd.arg.typeStringdcmd.arg.typeStringThe type of the parameter. The returned String is the name of a type * recognized by the diagnostic command parser. These types are not * Java types and are implementation dependent. *
dcmd.arg.descriptionStringdcmd.arg.descriptionStringThe parameter description
dcmd.arg.isMandatorybooleandcmd.arg.isMandatorybooleanTrue if the parameter is mandatory, false otherwise
dcmd.arg.isOptionbooleandcmd.arg.isOptionbooleanTrue if the parameter is an option, false if it is an argument
dcmd.arg.isMultiplebooleandcmd.arg.isMultiplebooleanTrue if the parameter can be specified several times, false * otherwise
* *

When the set of diagnostic commands currently supported by the Java diff --git a/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java b/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java index c2061987e22..9e4a9be6478 100644 --- a/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java @@ -182,26 +182,30 @@ public class GarbageCollectionNotificationInfo implements CompositeDataView { * the following attributes: *

* + * * - * - * + * + * * + * + * * - * + * * * * - * + * * * * - * + * * * * - * + * * * + * *
description
Attribute NameTypeAttribute NameType
gcNamegcName{@code java.lang.String}
gcActiongcAction{@code java.lang.String}
gcCausegcCause{@code java.lang.String}
gcInfogcInfo{@code javax.management.openmbean.CompositeData}
*
* diff --git a/jdk/src/jdk.management/share/classes/com/sun/management/GcInfo.java b/jdk/src/jdk.management/share/classes/com/sun/management/GcInfo.java index 5290a2999c1..6f729bffcbc 100644 --- a/jdk/src/jdk.management/share/classes/com/sun/management/GcInfo.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/GcInfo.java @@ -184,30 +184,34 @@ public class GcInfo implements CompositeData, CompositeDataView { * *
* + * * - * - * + * + * * + * + * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * + * *
description
Attribute NameTypeAttribute NameType
indexindex{@code java.lang.Long}
startTimestartTime{@code java.lang.Long}
endTimeendTime{@code java.lang.Long}
memoryUsageBeforeGcmemoryUsageBeforeGc{@code javax.management.openmbean.TabularData}
memoryUsageAfterGcmemoryUsageAfterGc{@code javax.management.openmbean.TabularData}
*
* diff --git a/jdk/src/jdk.management/share/classes/com/sun/management/VMOption.java b/jdk/src/jdk.management/share/classes/com/sun/management/VMOption.java index 7143acc7107..9694d9c31a9 100644 --- a/jdk/src/jdk.management/share/classes/com/sun/management/VMOption.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/VMOption.java @@ -191,26 +191,30 @@ public class VMOption { * *
* + * * - * - * + * + * * + * + * * - * + * * * * - * + * * * * - * + * * * * - * + * * * + * *
description
Attribute NameTypeAttribute NameType
namename{@code java.lang.String}
valuevalue{@code java.lang.String}
originorigin{@code java.lang.String}
writeablewriteable{@code java.lang.Boolean}
*
* From a3821dc595eb036b9ec83751b1f4fed17d87473e Mon Sep 17 00:00:00 2001 From: Ujwal Vangapally Date: Tue, 1 Aug 2017 10:33:47 +0530 Subject: [PATCH 38/59] 8181895: javax management docs contain links to technotes Edited links to point to Alternate paths Reviewed-by: rriggs --- .../management/remote/rmi/RMIConnection.java | 6 +++--- .../javax/management/remote/rmi/package.html | 17 +++-------------- .../javax/management/loading/package.html | 9 +++------ .../javax/management/modelmbean/package.html | 7 +++---- .../javax/management/monitor/package.html | 9 +++------ .../javax/management/openmbean/package.html | 7 ++----- .../share/classes/javax/management/package.html | 9 +++------ .../javax/management/relation/package.html | 7 ++----- .../javax/management/remote/package.html | 11 ++++------- 9 files changed, 26 insertions(+), 56 deletions(-) diff --git a/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnection.java b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnection.java index bc63fba83ad..0fe51563caa 100644 --- a/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnection.java +++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. * 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,8 +73,8 @@ import javax.security.auth.Subject; * must not be null; the behavior is unspecified if it is.

* *

Class loading aspects are detailed in the - * - * JMX Specification, version 1.4 PDF document.

+ * + * JMX Specification, version 1.4

* *

Most methods in this interface parallel methods in the {@link * MBeanServerConnection} interface. Where an aspect of the behavior diff --git a/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/package.html b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/package.html index fb58ff80547..be95841191d 100644 --- a/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/package.html +++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/package.html @@ -2,7 +2,7 @@ RMI connector \n" + + "\n" + "

This is the first line." + " Note the newlines before the <p> is relevant.

"); diff --git a/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java b/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java index b5ca0681671..0bfc7706a9f 100644 --- a/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java +++ b/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java @@ -161,7 +161,9 @@ public class TestHtmlVersion extends JavadocTester { + "", "
\n" + "
", - "
\n" + "
\n" + + "\n" + + "\n" + "
Test package.
", "