* Regular expression constructs, and what they match
@@ -378,7 +378,7 @@ import java.util.stream.StreamSupport;
*
*
*
- *
+ *
*
* The backslash character ({@code '\'}) serves to introduce escaped
* constructs, as defined in the table above, as well as to quote characters
@@ -406,7 +406,7 @@ import java.util.stream.StreamSupport;
* {@code (hello)} the string literal {@code "\\(hello\\)"}
* must be used.
*
- *
+ *
*
* Character classes may appear within other character classes, and
* may be composed by the union operator (implicit) and the intersection
@@ -449,7 +449,7 @@ import java.util.stream.StreamSupport;
* character class, while the expression {@code -} becomes a range
* forming metacharacter.
*
- *
+ *
*
* A line terminator is a one- or two-character sequence that marks
* the end of a line of the input character sequence. The following are
@@ -484,9 +484,9 @@ import java.util.stream.StreamSupport;
* except at the end of input. When in {@link #MULTILINE} mode {@code $}
* matches just before a line terminator or the end of the input sequence.
*
- *
+ *
*
- *
+ *
* Capturing groups are numbered by counting their opening parentheses from
* left to right. In the expression {@code ((A)(B(C)))}, for example, there
* are four such groups:
@@ -505,7 +505,7 @@ import java.util.stream.StreamSupport;
* subsequence may be used later in the expression, via a back reference, and
* may also be retrieved from the matcher once the match operation is complete.
*
- *
+ *
* A capturing group can also be assigned a "name", a {@code named-capturing group},
* and then be back-referenced later by the "name". Group names are composed of
* the following characters. The first character must be a {@code letter}.
@@ -534,7 +534,7 @@ import java.util.stream.StreamSupport;
* that do not capture text and do not count towards the group total, or
* named-capturing group.
*
- *
Unicode support
+ * Unicode support
*
* This class is in conformance with Level 1 of Unicode Technical
@@ -688,7 +688,7 @@ import java.util.stream.StreamSupport;
* available through the same \p{prop} syntax where
* the specified property has the name javamethodname.
*
- *
Comparison to Perl 5
+ * Comparison to Perl 5
*
* The {@code Pattern} engine performs traditional NFA-based matching
* with ordered alternation as occurs in Perl 5.
diff --git a/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java b/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java
index f064aa49505..901f2ce02f1 100644
--- a/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java
+++ b/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,7 @@ import java.util.Locale;
* interfaces to offer support for locales beyond the set of locales
* supported by the Java runtime environment itself.
*
- *
Packaging of Locale Sensitive Service Provider Implementations
+ * Packaging of Locale Sensitive Service Provider Implementations
* Implementations of these locale sensitive services can be made available
* by adding them to the application's class path. A provider identifies itself with a
* provider-configuration file in the resource directory META-INF/services,
@@ -75,7 +75,7 @@ import java.util.Locale;
*
* which is the fully qualified class name of the class implementing
* DateFormatProvider.
- * Invocation of Locale Sensitive Services
+ * Invocation of Locale Sensitive Services
*
* Locale sensitive factory methods and methods for name retrieval in the
* java.text and java.util packages invoke
diff --git a/src/java.base/share/classes/java/util/spi/ResourceBundleProvider.java b/src/java.base/share/classes/java/util/spi/ResourceBundleProvider.java
index 62fa501c538..08effa93d52 100644
--- a/src/java.base/share/classes/java/util/spi/ResourceBundleProvider.java
+++ b/src/java.base/share/classes/java/util/spi/ResourceBundleProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,7 @@ import java.util.ResourceBundle;
* factory methods to locate and load the service providers that are deployed as
* modules via {@link java.util.ServiceLoader ServiceLoader}.
*
- *
Developing resource bundle services
+ * Developing resource bundle services
*
* A service for a resource bundle of a given {@code baseName} must have
* a fully-qualified class name of the form:
@@ -55,7 +55,7 @@ import java.util.ResourceBundle;
* }
* }
*
- * Deploying resource bundle service providers
+ * Deploying resource bundle service providers
*
* Resource bundles can be deployed in one or more service providers
* in modules. For example, a provider for a service
@@ -114,7 +114,7 @@ import java.util.ResourceBundle;
* provides com.example.app.spi.MyResourcesProvider with com.example.impl.MyResourcesProviderImpl;
*
*
- *
+ *
*
* The module declaration of the consumer module that calls one of the
* {@code ResourceBundle.getBundle} factory methods to obtain a resource
diff --git a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java
index c93c0c87eba..038d5ad4e55 100644
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java
+++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java
@@ -103,10 +103,13 @@ public class URLClassPath {
DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.isEmpty() : false;
// This property will be removed in a later release
- p = props.getProperty("jdk.net.URLClassPath.disableClassPathURLCheck", "true");
-
+ p = props.getProperty("jdk.net.URLClassPath.disableClassPathURLCheck");
DISABLE_CP_URL_CHECK = p != null ? p.equals("true") || p.isEmpty() : false;
- DEBUG_CP_URL_CHECK = "debug".equals(p);
+
+ // Print a message for each Class-Path entry that is ignored (assuming
+ // the check is not disabled).
+ p = props.getProperty("jdk.net.URLClassPath.showIgnoredClassPathEntries");
+ DEBUG_CP_URL_CHECK = p != null ? p.equals("true") || p.isEmpty() : false;
}
/* The original search path of URLs. */
diff --git a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java
index 56061b19aa9..8757a1b0a3a 100644
--- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java
+++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java
@@ -342,15 +342,8 @@ public final class SSLSocketImpl
@Override
public synchronized SSLSession getHandshakeSession() {
- if (conContext.handshakeContext != null) {
- synchronized (this) {
- if (conContext.handshakeContext != null) {
- return conContext.handshakeContext.handshakeSession;
- }
- }
- }
-
- return null;
+ return conContext.handshakeContext == null ?
+ null : conContext.handshakeContext.handshakeSession;
}
@Override
diff --git a/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c b/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c
index 8cb4c59e357..3fccc34e8b1 100644
--- a/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c
+++ b/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c
@@ -1496,6 +1496,7 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, jint opt) {
CHECK_NULL_RETURN(ni_class, NULL);
}
ni = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, addr);
+ JNU_CHECK_EXCEPTION_RETURN(env, NULL);
if (ni) {
return ni;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IntegerStampShiftTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IntegerStampShiftTest.java
new file mode 100644
index 00000000000..c81fb55077e
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IntegerStampShiftTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+package org.graalvm.compiler.core.test;
+
+import org.junit.Test;
+
+public class IntegerStampShiftTest extends GraalCompilerTest {
+
+ public static int unsignedShiftPositiveInt(boolean f) {
+ int h = f ? 0x7FFFFFF0 : 0x7FFFFF00;
+ return h >>> 8;
+ }
+
+ @Test
+ public void testUnsignedShiftPositiveInt() {
+ test("unsignedShiftPositiveInt", false);
+ }
+
+ public static int unsignedShiftNegativeInt(boolean f) {
+ int h = f ? 0xFFFFFFF0 : 0xFFFFFF00;
+ return h >>> 8;
+ }
+
+ @Test
+ public void testUnsignedShiftNegativeInt() {
+ test("unsignedShiftNegativeInt", false);
+ }
+
+ public static long unsignedShiftPositiveLong(boolean f) {
+ long h = f ? 0x7FFFFFFFFFFFFFF0L : 0x7FFFFFFFFFFFFF00L;
+ return h >>> 8;
+ }
+
+ @Test
+ public void testUnsignedShiftPositiveLong() {
+ test("unsignedShiftPositiveLong", false);
+ }
+
+ public static long unsignedShiftNegativeLong(boolean f) {
+ long h = f ? 0xFFFFFFFFFFFFFFF0L : 0xFFFFFFFFFFFFFF00L;
+ return h >>> 8;
+ }
+
+ @Test
+ public void testUnsignedShiftNegativeLong() {
+ test("unsignedShiftNegativeLong", false);
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java
index c0aac79f234..b1feed131a3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java
@@ -25,7 +25,7 @@
package org.graalvm.compiler.core;
import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.ExitVM;
-import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
+import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAsFailure;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnException;
import static org.graalvm.compiler.core.GraalCompilerOptions.MaxCompilationProblemsPerAction;
@@ -45,14 +45,13 @@ import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
import org.graalvm.compiler.debug.PathUtilities;
import org.graalvm.compiler.debug.TTY;
-import org.graalvm.compiler.options.EnumOptionKey;
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.code.BailoutException;
/**
* Wrapper for a compilation that centralizes what action to take based on
- * {@link GraalCompilerOptions#CompilationBailoutAction} and
+ * {@link GraalCompilerOptions#CompilationBailoutAsFailure} and
* {@link GraalCompilerOptions#CompilationFailureAction} when an uncaught exception occurs during
* compilation.
*/
@@ -71,14 +70,17 @@ public abstract class CompilationWrapper {
* Print nothing to the console.
*/
Silent,
+
/**
* Print a stack trace to the console.
*/
Print,
+
/**
* An exception causes the compilation to be retried with extra diagnostics enabled.
*/
Diagnose,
+
/**
* Same as {@link #Diagnose} except that the VM process is exited after retrying.
*/
@@ -122,27 +124,30 @@ public abstract class CompilationWrapper {
protected abstract T handleException(Throwable t);
/**
- * Gets the action to take based on the value of {@code actionKey} in {@code options}.
+ * Gets the action to take based on the value of
+ * {@link GraalCompilerOptions#CompilationBailoutAsFailure},
+ * {@link GraalCompilerOptions#CompilationFailureAction} and
+ * {@link GraalCompilerOptions#ExitVMOnException} in {@code options}.
*
- * Subclasses can override this to choose a different action based on factors such as whether
- * {@code actionKey} has been explicitly set in {@code options} for example.
+ * Subclasses can override this to choose a different action.
*
* @param cause the cause of the bailout or failure
*/
- protected ExceptionAction lookupAction(OptionValues options, EnumOptionKey actionKey, Throwable cause) {
- if (actionKey == CompilationFailureAction) {
- if (ExitVMOnException.getValue(options)) {
- assert CompilationFailureAction.getDefaultValue() != ExceptionAction.ExitVM;
- assert ExitVMOnException.getDefaultValue() != true;
- if (CompilationFailureAction.hasBeenSet(options) && CompilationFailureAction.getValue(options) != ExceptionAction.ExitVM) {
- TTY.printf("WARNING: Ignoring %s=%s since %s=true has been explicitly specified.%n",
- CompilationFailureAction.getName(), CompilationFailureAction.getValue(options),
- ExitVMOnException.getName());
- }
- return ExceptionAction.ExitVM;
- }
+ protected ExceptionAction lookupAction(OptionValues options, Throwable cause) {
+ if (cause instanceof BailoutException && !CompilationBailoutAsFailure.getValue(options)) {
+ return ExceptionAction.Silent;
}
- return actionKey.getValue(options);
+ if (ExitVMOnException.getValue(options)) {
+ assert CompilationFailureAction.getDefaultValue() != ExceptionAction.ExitVM;
+ assert ExitVMOnException.getDefaultValue() != true;
+ if (CompilationFailureAction.hasBeenSet(options) && CompilationFailureAction.getValue(options) != ExceptionAction.ExitVM) {
+ TTY.printf("WARNING: Ignoring %s=%s since %s=true has been explicitly specified.%n",
+ CompilationFailureAction.getName(), CompilationFailureAction.getValue(options),
+ ExitVMOnException.getName());
+ }
+ return ExceptionAction.ExitVM;
+ }
+ return CompilationFailureAction.getValue(options);
}
/**
@@ -173,15 +178,6 @@ public abstract class CompilationWrapper {
} catch (Throwable cause) {
OptionValues initialOptions = initialDebug.getOptions();
- String causeType = "failure";
- EnumOptionKey actionKey;
- if (cause instanceof BailoutException) {
- actionKey = CompilationBailoutAction;
- causeType = "bailout";
- } else {
- actionKey = CompilationFailureAction;
- causeType = "failure";
- }
synchronized (CompilationFailureAction) {
// Serialize all compilation failure handling.
// This prevents retry compilation storms and interleaving
@@ -191,9 +187,9 @@ public abstract class CompilationWrapper {
// forced crash (i.e., use of GraalCompilerOptions.CrashAt)
// is truncated.
- ExceptionAction action = lookupAction(initialOptions, actionKey, cause);
+ ExceptionAction action = lookupAction(initialOptions, cause);
- action = adjustAction(initialOptions, actionKey, action);
+ action = adjustAction(initialOptions, action);
if (action == ExceptionAction.Silent) {
return handleException(cause);
@@ -204,16 +200,14 @@ public abstract class CompilationWrapper {
try (PrintStream ps = new PrintStream(baos)) {
ps.printf("%s: Compilation of %s failed: ", Thread.currentThread(), this);
cause.printStackTrace(ps);
- ps.printf("To disable compilation %s notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
- causeType,
- actionKey.getName(), ExceptionAction.Silent,
- actionKey.getName(), ExceptionAction.Silent);
- ps.printf("To capture more information for diagnosing or reporting a compilation %s, " +
+ ps.printf("To disable compilation failure notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
+ CompilationFailureAction.getName(), ExceptionAction.Silent,
+ CompilationFailureAction.getName(), ExceptionAction.Silent);
+ ps.printf("To capture more information for diagnosing or reporting a compilation failure, " +
"set %s to %s or %s (e.g., -Dgraal.%s=%s).%n",
- causeType,
- actionKey.getName(), ExceptionAction.Diagnose,
+ CompilationFailureAction.getName(), ExceptionAction.Diagnose,
ExceptionAction.ExitVM,
- actionKey.getName(), ExceptionAction.Diagnose);
+ CompilationFailureAction.getName(), ExceptionAction.Diagnose);
}
TTY.print(baos.toString());
return handleException(cause);
@@ -249,15 +243,13 @@ public abstract class CompilationWrapper {
try (PrintStream ps = new PrintStream(baos)) {
ps.printf("%s: Compilation of %s failed:%n", Thread.currentThread(), this);
cause.printStackTrace(ps);
- ps.printf("To disable compilation %s notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
- causeType,
- actionKey.getName(), ExceptionAction.Silent,
- actionKey.getName(), ExceptionAction.Silent);
- ps.printf("To print a message for a compilation %s without retrying the compilation, " +
+ ps.printf("To disable compilation failure notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
+ CompilationFailureAction.getName(), ExceptionAction.Silent,
+ CompilationFailureAction.getName(), ExceptionAction.Silent);
+ ps.printf("To print a message for a compilation failure without retrying the compilation, " +
"set %s to %s (e.g., -Dgraal.%s=%s).%n",
- causeType,
- actionKey.getName(), ExceptionAction.Print,
- actionKey.getName(), ExceptionAction.Print);
+ CompilationFailureAction.getName(), ExceptionAction.Print,
+ CompilationFailureAction.getName(), ExceptionAction.Print);
if (dumpPath != null) {
ps.println("Retrying compilation of " + this);
} else {
@@ -320,7 +312,7 @@ public abstract class CompilationWrapper {
* Adjusts {@code initialAction} if necessary based on
* {@link GraalCompilerOptions#MaxCompilationProblemsPerAction}.
*/
- private ExceptionAction adjustAction(OptionValues initialOptions, EnumOptionKey actionKey, ExceptionAction initialAction) {
+ private ExceptionAction adjustAction(OptionValues initialOptions, ExceptionAction initialAction) {
ExceptionAction action = initialAction;
int maxProblems = MaxCompilationProblemsPerAction.getValue(initialOptions);
if (action != ExceptionAction.ExitVM) {
@@ -329,7 +321,7 @@ public abstract class CompilationWrapper {
int problems = problemsHandledPerAction.getOrDefault(action, 0);
if (problems >= maxProblems) {
if (problems == maxProblems) {
- TTY.printf("Warning: adjusting %s from %s to %s after %s (%d) failed compilations%n", actionKey, action, action.quieter(),
+ TTY.printf("Warning: adjusting %s from %s to %s after %s (%d) failed compilations%n", CompilationFailureAction, action, action.quieter(),
MaxCompilationProblemsPerAction, maxProblems);
// Ensure that the message above is only printed once
problemsHandledPerAction.put(action, problems + 1);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java
index 3bea40e0b98..942d21b8170 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java
@@ -44,13 +44,12 @@ public class GraalCompilerOptions {
"suffix will raise a bailout exception and a ':PermanentBailout' " +
"suffix will raise a permanent bailout exception.", type = OptionType.Debug)
public static final OptionKey CrashAt = new OptionKey<>(null);
- @Option(help = "file:doc-files/CompilationBailoutActionHelp.txt", type = OptionType.User)
- public static final EnumOptionKey CompilationBailoutAction = new EnumOptionKey<>(ExceptionAction.Silent);
- @Option(help = "Specifies the action to take when compilation fails with a bailout exception. " +
- "The accepted values are the same as for CompilationBailoutAction.", type = OptionType.User)
- public static final EnumOptionKey CompilationFailureAction = new EnumOptionKey<>(ExceptionAction.Diagnose);
- @Option(help = "The maximum number of compilation failures or bailouts to handle with the action specified " +
- "by CompilationFailureAction or CompilationBailoutAction before changing to a less verbose action. " +
+ @Option(help = "Treat compilation bailouts like compilation failures.", type = OptionType.User)
+ public static final OptionKey CompilationBailoutAsFailure = new OptionKey<>(false);
+ @Option(help = "file:doc-files/CompilationFailureActionHelp.txt", type = OptionType.User)
+ public static final EnumOptionKey CompilationFailureAction = new EnumOptionKey<>(ExceptionAction.Silent);
+ @Option(help = "The maximum number of compilation failures to handle with the action specified " +
+ "by CompilationFailureAction before changing to a less verbose action. " +
"This does not apply to the ExitVM action.", type = OptionType.User)
public static final OptionKey MaxCompilationProblemsPerAction = new OptionKey<>(2);
@Option(help = "Alias for CompilationFailureAction=ExitVM.", type = OptionType.User)
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/doc-files/CompilationBailoutActionHelp.txt b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/doc-files/CompilationFailureActionHelp.txt
similarity index 76%
rename from src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/doc-files/CompilationBailoutActionHelp.txt
rename to src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/doc-files/CompilationFailureActionHelp.txt
index 1192fbf36fd..b8a739e411f 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/doc-files/CompilationBailoutActionHelp.txt
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/doc-files/CompilationFailureActionHelp.txt
@@ -1,4 +1,4 @@
-Specifies the action to take when compilation fails with a bailout exception.
+Specifies the action to take when compilation fails.
The accepted values are:
Silent - Print nothing to the console.
Print - Print a stack trace to the console.
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayEqualsStub.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayEqualsStub.java
new file mode 100644
index 00000000000..f3eb67978c6
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayEqualsStub.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.amd64;
+
+import org.graalvm.compiler.api.replacements.Snippet;
+import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
+import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
+import org.graalvm.compiler.hotspot.stubs.SnippetStub;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode;
+import jdk.internal.vm.compiler.word.Pointer;
+
+import jdk.vm.ci.meta.JavaKind;
+
+public final class AMD64ArrayEqualsStub extends SnippetStub {
+
+ public static final ForeignCallDescriptor STUB_BOOLEAN_ARRAY_EQUALS = new ForeignCallDescriptor(
+ "booleanArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
+ public static final ForeignCallDescriptor STUB_BYTE_ARRAY_EQUALS = new ForeignCallDescriptor(
+ "byteArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
+ public static final ForeignCallDescriptor STUB_CHAR_ARRAY_EQUALS = new ForeignCallDescriptor(
+ "charArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
+ public static final ForeignCallDescriptor STUB_SHORT_ARRAY_EQUALS = new ForeignCallDescriptor(
+ "shortArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
+ public static final ForeignCallDescriptor STUB_INT_ARRAY_EQUALS = new ForeignCallDescriptor(
+ "intArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
+ public static final ForeignCallDescriptor STUB_LONG_ARRAY_EQUALS = new ForeignCallDescriptor(
+ "longArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
+ public static final ForeignCallDescriptor STUB_FLOAT_ARRAY_EQUALS = new ForeignCallDescriptor(
+ "floatArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
+ public static final ForeignCallDescriptor STUB_DOUBLE_ARRAY_EQUALS = new ForeignCallDescriptor(
+ "doubleArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
+
+ public AMD64ArrayEqualsStub(ForeignCallDescriptor foreignCallDescriptor, OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
+ super(foreignCallDescriptor.getName(), options, providers, linkage);
+ }
+
+ @Snippet
+ private static boolean booleanArraysEquals(Pointer array1, Pointer array2, int length) {
+ return ArrayEqualsNode.equals(array1, array2, length, JavaKind.Boolean);
+ }
+
+ @Snippet
+ private static boolean byteArraysEquals(Pointer array1, Pointer array2, int length) {
+ return ArrayEqualsNode.equals(array1, array2, length, JavaKind.Byte);
+ }
+
+ @Snippet
+ private static boolean charArraysEquals(Pointer array1, Pointer array2, int length) {
+ return ArrayEqualsNode.equals(array1, array2, length, JavaKind.Char);
+ }
+
+ @Snippet
+ private static boolean shortArraysEquals(Pointer array1, Pointer array2, int length) {
+ return ArrayEqualsNode.equals(array1, array2, length, JavaKind.Short);
+ }
+
+ @Snippet
+ private static boolean intArraysEquals(Pointer array1, Pointer array2, int length) {
+ return ArrayEqualsNode.equals(array1, array2, length, JavaKind.Int);
+ }
+
+ @Snippet
+ private static boolean longArraysEquals(Pointer array1, Pointer array2, int length) {
+ return ArrayEqualsNode.equals(array1, array2, length, JavaKind.Long);
+ }
+
+ @Snippet
+ private static boolean floatArraysEquals(Pointer array1, Pointer array2, int length) {
+ return ArrayEqualsNode.equals(array1, array2, length, JavaKind.Float);
+ }
+
+ @Snippet
+ private static boolean doubleArraysEquals(Pointer array1, Pointer array2, int length) {
+ return ArrayEqualsNode.equals(array1, array2, length, JavaKind.Double);
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java
index 5921fef43ed..ec84ef9b88b 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java
@@ -25,6 +25,7 @@
package org.graalvm.compiler.hotspot.amd64;
import static jdk.vm.ci.common.InitTimer.timer;
+import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.JAVA_SPECIFICATION_VERSION;
import java.util.ArrayList;
import java.util.List;
@@ -160,7 +161,7 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess,
HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) {
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, replacements);
- AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, false);
+ AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, false, JAVA_SPECIFICATION_VERSION >= 9);
return plugins;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java
index aadd591fde6..042a789569a 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -121,6 +121,22 @@ public class AMD64HotSpotForeignCallsProvider extends HotSpotHostForeignCallsPro
link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS, options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_BOOLEAN_ARRAY_EQUALS, options, providers,
+ registerStubCall(AMD64ArrayEqualsStub.STUB_BOOLEAN_ARRAY_EQUALS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS, options, providers,
+ registerStubCall(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS, options, providers,
+ registerStubCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_SHORT_ARRAY_EQUALS, options, providers,
+ registerStubCall(AMD64ArrayEqualsStub.STUB_SHORT_ARRAY_EQUALS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_INT_ARRAY_EQUALS, options, providers,
+ registerStubCall(AMD64ArrayEqualsStub.STUB_INT_ARRAY_EQUALS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_LONG_ARRAY_EQUALS, options, providers,
+ registerStubCall(AMD64ArrayEqualsStub.STUB_LONG_ARRAY_EQUALS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_FLOAT_ARRAY_EQUALS, options, providers,
+ registerStubCall(AMD64ArrayEqualsStub.STUB_FLOAT_ARRAY_EQUALS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_DOUBLE_ARRAY_EQUALS, options, providers,
+ registerStubCall(AMD64ArrayEqualsStub.STUB_DOUBLE_ARRAY_EQUALS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
super.initialize(providers, options);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java
index 1f6b3e9dc7d..56e66ef14c3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -676,4 +676,32 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
protected StrategySwitchOp createStrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Variable key, AllocatableValue temp) {
return new AMD64HotSpotStrategySwitchOp(strategy, keyTargets, defaultTarget, key, temp);
}
+
+ @Override
+ public ForeignCallLinkage lookupArrayEqualsStub(JavaKind kind, int constantLength) {
+ if (constantLength >= 0 && constantLength * kind.getByteCount() < 2 * getMaxVectorSize()) {
+ // Yield constant-length arrays comparison assembly
+ return null;
+ }
+ switch (kind) {
+ case Boolean:
+ return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_BOOLEAN_ARRAY_EQUALS);
+ case Byte:
+ return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS);
+ case Char:
+ return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS);
+ case Short:
+ return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_SHORT_ARRAY_EQUALS);
+ case Int:
+ return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_INT_ARRAY_EQUALS);
+ case Long:
+ return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_LONG_ARRAY_EQUALS);
+ case Float:
+ return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_FLOAT_ARRAY_EQUALS);
+ case Double:
+ return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_DOUBLE_ARRAY_EQUALS);
+ default:
+ return null;
+ }
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java
index a70a0d2c54c..7312ae3f298 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java
@@ -26,8 +26,6 @@ package org.graalvm.compiler.hotspot.jdk9.test;
import static org.junit.Assume.assumeFalse;
-import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.hotspot.replacements.StringUTF16Substitutions;
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -35,9 +33,11 @@ import org.graalvm.compiler.nodes.java.NewArrayNode;
import org.graalvm.compiler.replacements.arraycopy.ArrayCopyCallNode;
import org.graalvm.compiler.replacements.test.MethodSubstitutionTest;
import org.graalvm.compiler.test.AddExports;
-import org.junit.Before;
import org.junit.Test;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
/**
* Test substitutions for (innate) methods StringUTF16.toBytes and StringUTF16.getChars provided by
* {@link StringUTF16Substitutions}.
@@ -48,8 +48,7 @@ public final class StringUTF16ToBytesGetCharsTest extends MethodSubstitutionTest
private static final int N = 1000;
private static final int N_OVERFLOW = 10;
- @Before
- public void checkAMD64() {
+ public StringUTF16ToBytesGetCharsTest() {
assumeFalse(Java8OrEarlier);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/BigIntegerIntrinsicsTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/BigIntegerIntrinsicsTest.java
index 939d9bdf587..73f178ca8d3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/BigIntegerIntrinsicsTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/BigIntegerIntrinsicsTest.java
@@ -21,6 +21,8 @@
* questions.
*/
+
+
package org.graalvm.compiler.hotspot.test;
import java.lang.reflect.InvocationTargetException;
@@ -193,8 +195,7 @@ public final class BigIntegerIntrinsicsTest extends GraalCompilerTest {
Object invokeCode(Object... args) {
try {
return testcode.executeVarargs(args);
- }
- catch (InvalidInstalledCodeException e) {
+ } catch (InvalidInstalledCodeException e) {
// Ensure the installed code is valid, possibly recompiled.
testcode = getCode(testmethod);
@@ -208,8 +209,7 @@ public final class BigIntegerIntrinsicsTest extends GraalCompilerTest {
private Object invokeSafe(ResolvedJavaMethod method, Object receiver, Object... args) {
try {
return invoke(method, receiver, args);
- } catch (IllegalAccessException | InvocationTargetException |
- IllegalArgumentException | InstantiationException e) {
+ } catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException | InstantiationException e) {
throw new RuntimeException(e);
}
}
@@ -220,8 +220,7 @@ public final class BigIntegerIntrinsicsTest extends GraalCompilerTest {
private InstalledCode testcode;
}
- private static GraalHotSpotVMConfig config =
- ((HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class)).getVMConfig();
+ private static GraalHotSpotVMConfig config = ((HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class)).getVMConfig();
private static BigInteger bigTwo = BigInteger.valueOf(2);
private static Random rnd = new Random(17);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java
index 516811509a1..f7fdfd10e49 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java
@@ -26,7 +26,7 @@ package org.graalvm.compiler.hotspot.test;
import static java.util.Collections.singletonList;
import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.Print;
-import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
+import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAsFailure;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
import static org.graalvm.compiler.core.test.ReflectionOptionDescriptors.extractEntries;
import static org.graalvm.compiler.debug.MemUseTrackerKey.getCurrentThreadAllocatedBytes;
@@ -215,7 +215,7 @@ public final class CompileTheWorld {
compilationOptionsCopy.putAll(compilationOptions);
// We want to see stack traces when a method fails to compile
- CompilationBailoutAction.putIfAbsent(compilationOptionsCopy, Print);
+ CompilationBailoutAsFailure.putIfAbsent(compilationOptionsCopy, true);
CompilationFailureAction.putIfAbsent(compilationOptionsCopy, Print);
// By default only report statistics for the CTW threads themselves
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java
index 613dc98f34a..12e4bf728bb 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java
@@ -24,7 +24,7 @@
package org.graalvm.compiler.hotspot.test;
-import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
+import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAsFailure;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
import jdk.internal.vm.compiler.collections.EconomicMap;
@@ -44,7 +44,7 @@ public class CompileTheWorldTest extends GraalCompilerTest {
@Test
public void testJDK() throws Throwable {
- ExceptionAction originalBailoutAction = CompilationBailoutAction.getValue(getInitialOptions());
+ boolean originalBailoutAction = CompilationBailoutAsFailure.getValue(getInitialOptions());
ExceptionAction originalFailureAction = CompilationFailureAction.getValue(getInitialOptions());
// Compile a couple classes in rt.jar
HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime();
@@ -52,7 +52,7 @@ public class CompileTheWorldTest extends GraalCompilerTest {
OptionValues initialOptions = getInitialOptions();
EconomicMap, Object> compilationOptions = CompileTheWorld.parseOptions("Inline=false");
new CompileTheWorld(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), CompileTheWorld.SUN_BOOT_CLASS_PATH, 1, 5, null, null, false, initialOptions, compilationOptions).compile();
- assert CompilationBailoutAction.getValue(initialOptions) == originalBailoutAction;
+ assert CompilationBailoutAsFailure.getValue(initialOptions) == originalBailoutAction;
assert CompilationFailureAction.getValue(initialOptions) == originalFailureAction;
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java
index e64e602fbc9..9c468808110 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java
@@ -31,7 +31,6 @@ import org.graalvm.compiler.bytecode.Bytecode;
import org.graalvm.compiler.bytecode.BytecodeDisassembler;
import org.graalvm.compiler.bytecode.BytecodeStream;
import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
-import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
import org.graalvm.compiler.core.GraalCompilerOptions;
import org.graalvm.compiler.core.target.Backend;
import org.graalvm.compiler.core.test.GraalCompilerTest;
@@ -134,8 +133,8 @@ public abstract class GraalOSRTestBase extends GraalCompilerTest {
OptionValues goptions = options;
// Silence diagnostics for permanent bailout errors as they
// are expected for some OSR tests.
- if (!GraalCompilerOptions.CompilationBailoutAction.hasBeenSet(options)) {
- goptions = new OptionValues(options, GraalCompilerOptions.CompilationBailoutAction, ExceptionAction.Silent);
+ if (!GraalCompilerOptions.CompilationBailoutAsFailure.hasBeenSet(options)) {
+ goptions = new OptionValues(options, GraalCompilerOptions.CompilationBailoutAsFailure, false);
}
// ensure eager resolving
StructuredGraph graph = parseEager(method, AllowAssumptions.YES, goptions);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java
index 30ebffa4449..092429bf201 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java
@@ -26,7 +26,7 @@ package org.graalvm.compiler.hotspot;
import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.Diagnose;
import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.ExitVM;
-import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
+import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAsFailure;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
import static org.graalvm.compiler.core.phases.HighTier.Options.Inline;
import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
@@ -47,7 +47,6 @@ import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugDumpScope;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TimerKey;
-import org.graalvm.compiler.options.EnumOptionKey;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
@@ -145,25 +144,34 @@ public class CompilationTask {
}
@Override
- protected ExceptionAction lookupAction(OptionValues values, EnumOptionKey actionKey, Throwable cause) {
- // Respect current action if it has been explicitly set.
- if (!actionKey.hasBeenSet(values)) {
- if (actionKey == CompilationFailureAction) {
- // Automatically exit on non-bailout during bootstrap
- // or when assertions are enabled.
- if (Assertions.assertionsEnabled() || compiler.getGraalRuntime().isBootstrapping()) {
- return ExitVM;
- }
- } else if (actionKey == CompilationBailoutAction && ((BailoutException) cause).isPermanent()) {
- // Get more info for permanent bailouts during bootstrap
- // or when assertions are enabled.
- assert CompilationBailoutAction.getDefaultValue() == ExceptionAction.Silent;
- if (Assertions.assertionsEnabled() || compiler.getGraalRuntime().isBootstrapping()) {
- return Diagnose;
+ protected ExceptionAction lookupAction(OptionValues values, Throwable cause) {
+ if (cause instanceof BailoutException) {
+ BailoutException bailout = (BailoutException) cause;
+ if (bailout.isPermanent()) {
+ // Respect current action if it has been explicitly set.
+ if (!CompilationBailoutAsFailure.hasBeenSet(values)) {
+ // Get more info for permanent bailouts during bootstrap
+ // or when assertions are enabled.
+ if (Assertions.assertionsEnabled() || compiler.getGraalRuntime().isBootstrapping()) {
+ return Diagnose;
+ }
+
}
}
+ if (!CompilationBailoutAsFailure.getValue(values)) {
+ return super.lookupAction(values, cause);
+ }
}
- return super.lookupAction(values, actionKey, cause);
+
+ // Respect current action if it has been explicitly set.
+ if (!CompilationFailureAction.hasBeenSet(values)) {
+ // Automatically exit on failure during bootstrap
+ // or when assertions are enabled.
+ if (Assertions.assertionsEnabled() || compiler.getGraalRuntime().isBootstrapping()) {
+ return ExitVM;
+ }
+ }
+ return super.lookupAction(values, cause);
}
@SuppressWarnings("try")
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java
index 20a01bd7c89..f87b2d36318 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java
@@ -41,6 +41,7 @@ import org.graalvm.compiler.options.OptionsParser;
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.common.NativeImageReinitialize;
+import jdk.vm.ci.services.Services;
/**
* The {@link #defaultOptions()} method returns the options values initialized in a HotSpot VM. The
@@ -89,15 +90,14 @@ public class HotSpotGraalOptionValues {
}
/**
- * Global options. The values for these options are initialized by parsing the file denoted by
- * the {@code VM.getSavedProperty(String) saved} system property named
- * {@value #GRAAL_OPTIONS_FILE_PROPERTY_NAME} if the file exists followed by parsing the options
- * encoded in saved system properties whose names start with
- * {@value #GRAAL_OPTION_PROPERTY_PREFIX}. Key/value pairs are parsed from the aforementioned
- * file with {@link Properties#load(java.io.Reader)}.
+ * Gets and parses options based on {@linkplain Services#getSavedProperties() saved system
+ * properties}. The values for these options are initialized by parsing the file denoted by the
+ * {@value #GRAAL_OPTIONS_FILE_PROPERTY_NAME} property followed by parsing the options encoded
+ * in properties whose names start with {@value #GRAAL_OPTION_PROPERTY_PREFIX}. Key/value pairs
+ * are parsed from the aforementioned file with {@link Properties#load(java.io.Reader)}.
*/
@SuppressWarnings("try")
- private static OptionValues initializeOptions() {
+ public static EconomicMap, Object> parseOptions() {
EconomicMap, Object> values = OptionValues.newOptionMap();
try (InitTimer t = timer("InitializeOptions")) {
@@ -142,7 +142,17 @@ public class HotSpotGraalOptionValues {
}
OptionsParser.parseOptions(optionSettings, values, loader);
- return new OptionValues(values);
+ return values;
}
}
+
+ /**
+ * Substituted by
+ * {@code com.oracle.svm.graal.hotspot.libgraal.Target_org_graalvm_compiler_hotspot_HotSpotGraalOptionValues}
+ * to update {@code com.oracle.svm.core.option.RuntimeOptionValues.singleton()} instead of
+ * creating a new {@link OptionValues} object.
+ */
+ private static OptionValues initializeOptions() {
+ return new OptionValues(parseOptions());
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java
index fab6e5f68ac..41ed56b99e6 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java
index 7296aa8ada9..9d54c15ebfc 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -268,6 +268,11 @@ public interface LIRGeneratorTool extends DiagnosticLIRGeneratorTool, ValueKindF
Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, int constantLength, boolean directPointers);
+ @SuppressWarnings("unused")
+ default ForeignCallLinkage lookupArrayEqualsStub(JavaKind kind, int constantLength) {
+ return null;
+ }
+
@SuppressWarnings("unused")
default Variable emitArrayEquals(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length, int constantLength, boolean directPointers) {
throw GraalError.unimplemented("Array.equals with different types substitution is not implemented on this architecture");
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.java
index 5f0d572daf7..60dccded067 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
package org.graalvm.compiler.nodes.calc;
+import jdk.vm.ci.code.CodeUtil;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp.UShr;
import org.graalvm.compiler.core.common.type.IntegerStamp;
@@ -84,10 +85,13 @@ public final class UnsignedRightShiftNode extends ShiftNode {
Stamp xStampGeneric = forX.stamp(view);
if (xStampGeneric instanceof IntegerStamp) {
IntegerStamp xStamp = (IntegerStamp) xStampGeneric;
+ long xMask = CodeUtil.mask(xStamp.getBits());
+ long xLowerBound = xStamp.lowerBound() & xMask;
+ long xUpperBound = xStamp.upperBound() & xMask;
- if (xStamp.lowerBound() >>> amount == xStamp.upperBound() >>> amount) {
+ if (xLowerBound >>> amount == xUpperBound >>> amount) {
// The result of the shift is constant.
- return ConstantNode.forIntegerKind(stamp.getStackKind(), xStamp.lowerBound() >>> amount);
+ return ConstantNode.forIntegerKind(stamp.getStackKind(), xLowerBound >>> amount);
}
if (amount == xStamp.getBits() - 1 && xStamp.lowerBound() == -1 && xStamp.upperBound() == 0) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java
index 026fb27bf1f..f10fb926300 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java
@@ -32,7 +32,6 @@ import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.Una
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10;
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.JAVA_SPECIFICATION_VERSION;
import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java11OrEarlier;
import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
@@ -71,7 +70,7 @@ import sun.misc.Unsafe;
public class AMD64GraphBuilderPlugins {
- public static void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, AMD64 arch, boolean explicitUnsafeNullChecks) {
+ public static void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, AMD64 arch, boolean explicitUnsafeNullChecks, boolean emitJDK9StringSubstitutions) {
InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
invocationPlugins.defer(new Runnable() {
@Override
@@ -83,8 +82,10 @@ public class AMD64GraphBuilderPlugins {
new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object, JavaKind.Boolean, JavaKind.Byte, JavaKind.Short, JavaKind.Char, JavaKind.Float, JavaKind.Double});
registerUnsafePlugins(invocationPlugins, replacementsBytecodeProvider, explicitUnsafeNullChecks);
registerStringPlugins(invocationPlugins, replacementsBytecodeProvider);
- registerStringLatin1Plugins(invocationPlugins, replacementsBytecodeProvider);
- registerStringUTF16Plugins(invocationPlugins, replacementsBytecodeProvider);
+ if (emitJDK9StringSubstitutions) {
+ registerStringLatin1Plugins(invocationPlugins, replacementsBytecodeProvider);
+ registerStringUTF16Plugins(invocationPlugins, replacementsBytecodeProvider);
+ }
registerMathPlugins(invocationPlugins, arch, replacementsBytecodeProvider);
registerArraysEqualsPlugins(invocationPlugins, replacementsBytecodeProvider);
}
@@ -215,30 +216,26 @@ public class AMD64GraphBuilderPlugins {
}
private static void registerStringLatin1Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
- if (JAVA_SPECIFICATION_VERSION >= 9) {
- Registration r = new Registration(plugins, "java.lang.StringLatin1", replacementsBytecodeProvider);
- r.setAllowOverwrite(true);
- r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class);
- r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareToUTF16", byte[].class, byte[].class);
- r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "inflate", byte[].class, int.class, char[].class, int.class, int.class);
- r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "inflate", byte[].class, int.class, byte[].class, int.class, int.class);
- r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "indexOf", byte[].class, int.class, int.class);
- r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "indexOf", byte[].class, int.class, byte[].class, int.class, int.class);
- }
+ Registration r = new Registration(plugins, "java.lang.StringLatin1", replacementsBytecodeProvider);
+ r.setAllowOverwrite(true);
+ r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class);
+ r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareToUTF16", byte[].class, byte[].class);
+ r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "inflate", byte[].class, int.class, char[].class, int.class, int.class);
+ r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "inflate", byte[].class, int.class, byte[].class, int.class, int.class);
+ r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "indexOf", byte[].class, int.class, int.class);
+ r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "indexOf", byte[].class, int.class, byte[].class, int.class, int.class);
}
private static void registerStringUTF16Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
- if (JAVA_SPECIFICATION_VERSION >= 9) {
- Registration r = new Registration(plugins, "java.lang.StringUTF16", replacementsBytecodeProvider);
- r.setAllowOverwrite(true);
- r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class);
- r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareToLatin1", byte[].class, byte[].class);
- r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compress", char[].class, int.class, byte[].class, int.class, int.class);
- r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compress", byte[].class, int.class, byte[].class, int.class, int.class);
- r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfCharUnsafe", byte[].class, int.class, int.class, int.class);
- r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfUnsafe", byte[].class, int.class, byte[].class, int.class, int.class);
- r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfLatin1Unsafe", byte[].class, int.class, byte[].class, int.class, int.class);
- }
+ Registration r = new Registration(plugins, "java.lang.StringUTF16", replacementsBytecodeProvider);
+ r.setAllowOverwrite(true);
+ r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class);
+ r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareToLatin1", byte[].class, byte[].class);
+ r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compress", char[].class, int.class, byte[].class, int.class, int.class);
+ r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compress", byte[].class, int.class, byte[].class, int.class, int.class);
+ r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfCharUnsafe", byte[].class, int.class, int.class, int.class);
+ r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfUnsafe", byte[].class, int.class, byte[].class, int.class, int.class);
+ r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfLatin1Unsafe", byte[].class, int.class, byte[].class, int.class, int.class);
}
private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider, boolean explicitUnsafeNullChecks) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java
index 993a29728d5..76ddb1e51fa 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,11 +26,14 @@ package org.graalvm.compiler.replacements.nodes;
import static org.graalvm.compiler.nodeinfo.InputType.Memory;
+import org.graalvm.compiler.api.replacements.Snippet;
+import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.Canonicalizable;
import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.nodeinfo.NodeCycles;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodeinfo.NodeSize;
@@ -48,11 +51,14 @@ import org.graalvm.compiler.nodes.spi.Virtualizable;
import org.graalvm.compiler.nodes.spi.VirtualizerTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
+import org.graalvm.compiler.options.Option;
+import org.graalvm.compiler.options.OptionKey;
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Value;
// JaCoCo Exclude
@@ -63,6 +69,13 @@ import jdk.vm.ci.meta.Value;
@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = NodeSize.SIZE_128)
public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess {
+ public static class Options {
+ // @formatter:off
+ @Option(help = "Use Array equals stubs instead of embedding all the emitted code.")
+ public static final OptionKey ArrayEqualsStubs = new OptionKey<>(true);
+ // @formatter:on
+ }
+
public static final NodeClass TYPE = NodeClass.create(ArrayEqualsNode.class);
/** {@link JavaKind} of the arrays to compare. */
protected final JavaKind kind;
@@ -178,7 +191,7 @@ public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLower
}
@NodeIntrinsic
- static native boolean equals(Object array1, Object array2, int length, @ConstantNodeParameter JavaKind kind);
+ public static native boolean equals(Object array1, Object array2, int length, @ConstantNodeParameter JavaKind kind);
public static boolean equals(boolean[] array1, boolean[] array2, int length) {
return equals(array1, array2, length, JavaKind.Boolean);
@@ -214,11 +227,25 @@ public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLower
@Override
public void generate(NodeLIRBuilderTool gen) {
+ LIRGeneratorTool tool = gen.getLIRGeneratorTool();
int constantLength = -1;
if (length.isConstant()) {
constantLength = length.asJavaConstant().asInt();
}
- Value result = gen.getLIRGeneratorTool().emitArrayEquals(kind, gen.operand(array1), gen.operand(array2), gen.operand(length), constantLength, false);
+
+ if (Options.ArrayEqualsStubs.getValue(graph().getOptions())) {
+ ResolvedJavaMethod method = graph().method();
+ if (method != null && method.getAnnotation(Snippet.class) == null) {
+ ForeignCallLinkage linkage = tool.lookupArrayEqualsStub(kind, constantLength);
+ if (linkage != null) {
+ Value result = tool.emitForeignCall(linkage, null, gen.operand(array1), gen.operand(array2), gen.operand(length));
+ gen.setResult(this, result);
+ return;
+ }
+ }
+ }
+
+ Value result = tool.emitArrayEquals(kind, gen.operand(array1), gen.operand(array2), gen.operand(length), constantLength, false);
gen.setResult(this, result);
}
diff --git a/src/utils/hsdis/Makefile b/src/utils/hsdis/Makefile
index cfaf3deca33..f73c813252b 100644
--- a/src/utils/hsdis/Makefile
+++ b/src/utils/hsdis/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# The Universal Permissive License (UPL), Version 1.0
@@ -201,6 +201,10 @@ LIBRARIES = $(TARGET_DIR)/bfd/libbfd.a \
$(TARGET_DIR)/opcodes/libopcodes.a \
$(TARGET_DIR)/libiberty/libiberty.a
+ifneq ($(MINGW),)
+LIBRARIES += $(TARGET_DIR)/zlib/libz.a
+endif
+
DEMO_TARGET = $(TARGET_DIR)/hsdis-demo
DEMO_SOURCE = hsdis-demo.c
diff --git a/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnsafeOffheapSwap.java b/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnsafeOffheapSwap.java
new file mode 100644
index 00000000000..44f4c7cbab7
--- /dev/null
+++ b/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnsafeOffheapSwap.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test TestUnsafeOffheapSwap
+ * @summary Miscompilation in Unsafe off-heap swap routines
+ * @key gc
+ * @requires vm.gc.Shenandoah
+ * @modules java.base/jdk.internal.misc:+open
+ *
+ * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:-TieredCompilation
+ * -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC
+ * TestUnsafeOffheapSwap
+ */
+
+import java.util.*;
+import jdk.internal.misc.Unsafe;
+
+public class TestUnsafeOffheapSwap {
+
+ static final int SIZE = 10000;
+ static final long SEED = 1;
+
+ static final jdk.internal.misc.Unsafe UNSAFE = Unsafe.getUnsafe();
+ static final int SCALE = UNSAFE.ARRAY_INT_INDEX_SCALE;
+
+ static Memory mem;
+ static int[] arr;
+
+ public static void main(String[] args) throws Exception {
+ // Bug is exposed when memory.addr is not known statically
+ mem = new Memory(SIZE*SCALE);
+ arr = new int[SIZE];
+
+ for (int i = 0; i < 10; i++) {
+ test();
+ }
+ }
+
+ static void test() {
+ Random rnd = new Random(SEED);
+ for (int i = 0; i < SIZE; i++) {
+ int value = rnd.nextInt();
+ mem.setInt(i, value);
+ arr[i] = value;
+ }
+
+ for (int i = 0; i < SIZE; i++) {
+ if (arr[i] != mem.getInt(i)) {
+ throw new IllegalStateException("TESTBUG: Values mismatch before swaps");
+ }
+ }
+
+ for (int i = 1; i < SIZE; i++) {
+ mem.swap(i - 1, i);
+ int tmp = arr[i - 1];
+ arr[i - 1] = arr[i];
+ arr[i] = tmp;
+ }
+
+ for (int i = 0; i < SIZE; i++) {
+ if (arr[i] != mem.getInt(i)) {
+ throw new IllegalStateException("Values mismatch after swaps");
+ }
+ }
+ }
+
+ static class Memory {
+ private final long addr;
+
+ Memory(int size) {
+ addr = UNSAFE.allocateMemory(size);
+ }
+
+ public int getInt(int idx) {
+ return UNSAFE.getInt(addr + idx*SCALE);
+ }
+
+ public void setInt(int idx, int val) {
+ UNSAFE.putInt(addr + idx*SCALE, val);
+ }
+
+ public void swap(int a, int b) {
+ int tmp = getInt(a);
+ setInt(a, getInt(b));
+ setInt(b, tmp);
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java
index 3a48fb09552..a84062370e2 100644
--- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java
+++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,7 @@ public class VMDeprecatedOptions {
{"InitialRAMFraction", "64"},
{"TLABStats", "false"},
{"ThreadLocalHandshakes", "true"},
+ {"AllowJNIEnvProxy", "true"},
// deprecated alias flags (see also aliased_jvm_flags):
{"DefaultMaxRAMFraction", "4"},
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004/TestDescription.java
index e72bbd8b4ee..c19476ab50d 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004/TestDescription.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* 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,6 +73,6 @@
* -waittime=5
* -debugee.vmkind=java
* -transport.address=dynamic
- * "-debugee.vmkeys=${test.vm.opts} ${test.java.opts}"
+ * "-debugee.vmkeys=${test.vm.opts} ${test.java.opts} -Dtest.timeout.factor=${test.timeout.factor}"
*/
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004/TestDescription.java
index 710059e8351..3dda6ee8b3d 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004/TestDescription.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -74,6 +74,6 @@
* -waittime=5
* -debugee.vmkind=java
* -transport.address=dynamic
- * "-debugee.vmkeys=${test.vm.opts} ${test.java.opts}"
+ * "-debugee.vmkeys=${test.vm.opts} ${test.java.opts} -Dtest.timeout.factor=${test.timeout.factor}"
*/
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Breakpoint/breakpoint001/breakpoint001.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Breakpoint/breakpoint001/breakpoint001.cpp
index 5284dd28151..2987f05d69d 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Breakpoint/breakpoint001/breakpoint001.cpp
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Breakpoint/breakpoint001/breakpoint001.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@ static volatile jint result = PASSED;
static jvmtiEnv *jvmti = NULL;
static jvmtiEventCallbacks callbacks;
-static int vm_started = 0;
+static volatile int callbacksEnabled = NSK_TRUE;
static jrawMonitorID agent_lock;
static void initCounters() {
@@ -82,7 +82,7 @@ ClassLoad(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) {
jvmti->RawMonitorEnter(agent_lock);
- if (vm_started) {
+ if (callbacksEnabled) {
// GetClassSignature may be called only during the start or the live phase
if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &sig, &generic)))
env->FatalError("failed to obtain a class signature\n");
@@ -196,11 +196,20 @@ void JNICALL
VMStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
jvmti->RawMonitorEnter(agent_lock);
- vm_started = 1;
+ callbacksEnabled = NSK_TRUE;
jvmti->RawMonitorExit(agent_lock);
}
+
+void JNICALL
+VMDeath(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+ jvmti->RawMonitorEnter(agent_lock);
+
+ callbacksEnabled = NSK_FALSE;
+
+ jvmti->RawMonitorExit(agent_lock);
+}
/************************/
JNIEXPORT jint JNICALL
@@ -268,6 +277,8 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
callbacks.ClassLoad = &ClassLoad;
callbacks.Breakpoint = &Breakpoint;
callbacks.VMStart = &VMStart;
+ callbacks.VMDeath = &VMDeath;
+
if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks))))
return JNI_ERR;
@@ -275,6 +286,8 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)))
return JNI_ERR;
+ if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))
+ return JNI_ERR;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL)))
return JNI_ERR;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL)))
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/FramePop/framepop002/framepop002.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/FramePop/framepop002/framepop002.cpp
index 84eec728f27..3b4125dcf52 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/FramePop/framepop002/framepop002.cpp
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/FramePop/framepop002/framepop002.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,6 +62,9 @@ static int thr_count = 0;
static int max_depth = 0;
static thr threads[MAX_THREADS];
+static volatile int callbacksEnabled = NSK_FALSE;
+static jrawMonitorID agent_lock;
+
static
int isTestThread(jvmtiEnv *jvmti_env, jthread thr) {
jvmtiError err;
@@ -211,12 +214,20 @@ void JNICALL MethodEntry(jvmtiEnv *jvmti_env, JNIEnv *env,
if (watch_events == JNI_FALSE) return;
+ jvmti->RawMonitorEnter(agent_lock);
+
+ if (!callbacksEnabled) {
+ jvmti->RawMonitorExit(agent_lock);
+ return;
+ }
+
err = jvmti_env->GetFrameCount(thr, &frameCount);
if (err != JVMTI_ERROR_NONE) {
printf("(GetFrameCount#entry) unexpected error: %s (%d)\n",
TranslateError(err), err);
printInfo(jvmti_env, thr, method, frameCount);
result = STATUS_FAILED;
+ jvmti->RawMonitorExit(agent_lock);
return;
}
@@ -259,6 +270,25 @@ void JNICALL MethodEntry(jvmtiEnv *jvmti_env, JNIEnv *env,
}
}
}
+
+ jvmti->RawMonitorExit(agent_lock);
+}
+
+void JNICALL VMStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+ jvmti->RawMonitorEnter(agent_lock);
+
+ callbacksEnabled = NSK_TRUE;
+
+ jvmti->RawMonitorExit(agent_lock);
+}
+
+
+void JNICALL VMDeath(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+ jvmti->RawMonitorEnter(agent_lock);
+
+ callbacksEnabled = NSK_FALSE;
+
+ jvmti->RawMonitorExit(agent_lock);
}
void JNICALL FramePop(jvmtiEnv *jvmti_env, JNIEnv *env,
@@ -266,12 +296,19 @@ void JNICALL FramePop(jvmtiEnv *jvmti_env, JNIEnv *env,
jvmtiError err;
jint frameCount;
+ jvmti->RawMonitorEnter(agent_lock);
+
+ if (!callbacksEnabled) {
+ jvmti->RawMonitorExit(agent_lock);
+ return;
+ }
err = jvmti_env->GetFrameCount(thr, &frameCount);
if (err != JVMTI_ERROR_NONE) {
printf("(GetFrameCount#entry) unexpected error: %s (%d)\n",
TranslateError(err), err);
printInfo(jvmti_env, thr, method, frameCount);
result = STATUS_FAILED;
+ jvmti->RawMonitorExit(agent_lock);
return;
}
@@ -296,6 +333,8 @@ void JNICALL FramePop(jvmtiEnv *jvmti_env, JNIEnv *env,
result = STATUS_FAILED;
}
}
+
+ jvmti->RawMonitorExit(agent_lock);
}
#ifdef STATIC_BUILD
@@ -355,12 +394,24 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
caps.can_generate_method_entry_events) {
callbacks.MethodEntry = &MethodEntry;
callbacks.FramePop = &FramePop;
+ callbacks.VMStart = &VMStart;
+ callbacks.VMDeath = &VMDeath;
+
err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
if (err != JVMTI_ERROR_NONE) {
printf("(SetEventCallbacks) unexpected error: %s (%d)\n",
TranslateError(err), err);
return JNI_ERR;
}
+ if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)))
+ return JNI_ERR;
+ if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))
+ return JNI_ERR;
+
+ if (jvmti->CreateRawMonitor("agent_lock", &agent_lock) != JVMTI_ERROR_NONE) {
+ return JNI_ERR;
+ }
+
} else {
printf("Warning: FramePop or MethodEntry event is not implemented\n");
}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep003/singlestep003.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep003/singlestep003.cpp
index 4448d55c3b1..e5fced2c839 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep003/singlestep003.cpp
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep003/singlestep003.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,6 +61,9 @@ static volatile jint result = PASSED;
static jvmtiEnv *jvmti = NULL;
static jvmtiEventCallbacks callbacks;
+static volatile int callbacksEnabled = NSK_FALSE;
+static jrawMonitorID agent_lock;
+
static void setBP(jvmtiEnv *jvmti_env, JNIEnv *env, jclass klass) {
jmethodID mid;
@@ -76,6 +79,13 @@ void JNICALL
ClassLoad(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) {
char *sig, *generic;
+ jvmti->RawMonitorEnter(agent_lock);
+
+ if (!callbacksEnabled) {
+ jvmti->RawMonitorExit(agent_lock);
+ return;
+ }
+
if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &sig, &generic)))
env->FatalError("failed to obtain a class signature\n");
@@ -86,6 +96,27 @@ ClassLoad(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) {
sig);
setBP(jvmti_env, env, klass);
}
+
+ jvmti->RawMonitorExit(agent_lock);
+}
+
+void JNICALL
+VMStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+ jvmti->RawMonitorEnter(agent_lock);
+
+ callbacksEnabled = NSK_TRUE;
+
+ jvmti->RawMonitorExit(agent_lock);
+}
+
+
+void JNICALL
+VMDeath(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+ jvmti->RawMonitorEnter(agent_lock);
+
+ callbacksEnabled = NSK_FALSE;
+
+ jvmti->RawMonitorExit(agent_lock);
}
void JNICALL
@@ -94,6 +125,13 @@ Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr, jmethodID method,
jclass klass;
char *sig, *generic;
+ jvmti->RawMonitorEnter(agent_lock);
+
+ if (!callbacksEnabled) {
+ jvmti->RawMonitorExit(agent_lock);
+ return;
+ }
+
NSK_DISPLAY0("Breakpoint event received\n");
if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &klass)))
NSK_COMPLAIN0("TEST FAILURE: unable to get method declaring class\n\n");
@@ -113,6 +151,8 @@ Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr, jmethodID method,
NSK_COMPLAIN1("TEST FAILURE: unexpected breakpoint event in method of class \"%s\"\n\n",
sig);
}
+
+ jvmti->RawMonitorExit(agent_lock);
}
void JNICALL
@@ -276,16 +316,27 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
callbacks.ClassLoad = &ClassLoad;
callbacks.Breakpoint = &Breakpoint;
callbacks.SingleStep = &SingleStep;
+ callbacks.VMStart = &VMStart;
+ callbacks.VMDeath = &VMDeath;
+
if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks))))
return JNI_ERR;
NSK_DISPLAY0("setting event callbacks done\nenabling JVMTI events ...\n");
+ if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)))
+ return JNI_ERR;
+ if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))
+ return JNI_ERR;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL)))
return JNI_ERR;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL)))
return JNI_ERR;
NSK_DISPLAY0("enabling the events done\n\n");
+ if (jvmti->CreateRawMonitor("agent_lock", &agent_lock) != JVMTI_ERROR_NONE) {
+ return JNI_ERR;
+ }
+
return JNI_OK;
}
diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
index 4147780e58f..ea1ad3c3f76 100644
--- a/test/jdk/ProblemList.txt
+++ b/test/jdk/ProblemList.txt
@@ -683,6 +683,7 @@ sun/security/pkcs11/tls/TestLeadingZeroesP11.java 8204203 windows-
sun/security/pkcs11/tls/TestMasterSecret.java 8204203 windows-all
sun/security/pkcs11/tls/TestPRF.java 8204203 windows-all
sun/security/pkcs11/tls/TestPremaster.java 8204203 windows-all
+sun/security/pkcs11/tls/tls12/TestTLS12.java 8221271 windows-all
sun/security/tools/keytool/NssTest.java 8204203 windows-all
############################################################################
diff --git a/test/jdk/java/net/Socket/AsyncShutdown.java b/test/jdk/java/net/Socket/AsyncShutdown.java
new file mode 100644
index 00000000000..c1aa8282b5e
--- /dev/null
+++ b/test/jdk/java/net/Socket/AsyncShutdown.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @requires (os.family == "linux" | os.family == "mac")
+ * @run testng AsyncShutdown
+ * @summary Test shutdownInput/shutdownOutput with threads blocked in read/write
+ */
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+@Test
+public class AsyncShutdown {
+
+ public void testShutdownInput1() throws IOException {
+ withConnection((s1, s2) -> {
+ scheduleShutdownInput(s1, 2000);
+ int n = s1.getInputStream().read();
+ assertTrue(n == -1);
+ });
+ }
+
+ public void testShutdownInput2() throws IOException {
+ withConnection((s1, s2) -> {
+ scheduleShutdownInput(s1, 2000);
+ s1.setSoTimeout(30*1000);
+ int n = s1.getInputStream().read();
+ assertTrue(n == -1);
+ });
+ }
+
+ public void testShutdownOutput1() throws IOException {
+ withConnection((s1, s2) -> {
+ scheduleShutdownOutput(s1, 2000);
+ byte[] data = new byte[128*1024];
+ try {
+ while (true) {
+ s1.getOutputStream().write(data);
+ }
+ } catch (IOException expected) { }
+ });
+ }
+
+ public void testShutdownOutput2() throws IOException {
+ withConnection((s1, s2) -> {
+ s1.setSoTimeout(100);
+ try {
+ s1.getInputStream().read();
+ assertTrue(false);
+ } catch (SocketTimeoutException e) { }
+
+ scheduleShutdownOutput(s1, 2000);
+ byte[] data = new byte[128*1024];
+ try {
+ while (true) {
+ s1.getOutputStream().write(data);
+ }
+ } catch (IOException expected) { }
+ });
+ }
+
+ static void scheduleShutdownInput(Socket s, long delay) {
+ schedule(() -> {
+ try {
+ s.shutdownInput();
+ } catch (IOException ioe) { }
+ }, delay);
+ }
+
+ static void scheduleShutdownOutput(Socket s, long delay) {
+ schedule(() -> {
+ try {
+ s.shutdownOutput();
+ } catch (IOException ioe) { }
+ }, delay);
+ }
+
+ static void schedule(Runnable task, long delay) {
+ ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+ try {
+ executor.schedule(task, delay, TimeUnit.MILLISECONDS);
+ } finally {
+ executor.shutdown();
+ }
+ }
+
+ interface ThrowingBiConsumer {
+ void accept(T t, U u) throws IOException;
+ }
+
+ static void withConnection(ThrowingBiConsumer consumer)
+ throws IOException
+ {
+ Socket s1 = null;
+ Socket s2 = null;
+ try (ServerSocket ss = new ServerSocket(0)) {
+ s1 = new Socket();
+ s1.connect(ss.getLocalSocketAddress());
+ s2 = ss.accept();
+ consumer.accept(s1, s2);
+ } finally {
+ if (s1 != null) s1.close();
+ if (s2 != null) s2.close();
+ }
+ }
+
+}
diff --git a/test/jdk/java/net/Socket/ConnectionReset.java b/test/jdk/java/net/Socket/ConnectionReset.java
new file mode 100644
index 00000000000..41ff326f382
--- /dev/null
+++ b/test/jdk/java/net/Socket/ConnectionReset.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @requires os.family != "solaris"
+ * @run testng ConnectionReset
+ * @summary Test behavior of read and available when a connection is reset
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+@Test
+public class ConnectionReset {
+
+ static final int REPEAT_COUNT = 5;
+
+ /**
+ * Tests available before read when there are no bytes to read
+ */
+ public void testAvailableBeforeRead1() throws IOException {
+ System.out.println("testAvailableBeforeRead1");
+ withResetConnection(null, s -> {
+ InputStream in = s.getInputStream();
+ for (int i=0; i %d%n", bytesAvailable);
+ assertTrue(bytesAvailable == 0);
+ try {
+ int bytesRead = in.read();
+ if (bytesRead == -1) {
+ System.out.println("read => EOF");
+ } else {
+ System.out.println("read => 1 byte");
+ }
+ assertTrue(false);
+ } catch (IOException ioe) {
+ System.out.format("read => %s (expected)%n", ioe);
+ }
+ }
+ });
+ }
+
+ /**
+ * Tests available before read when there are bytes to read
+ */
+ public void testAvailableBeforeRead2() throws IOException {
+ System.out.println("testAvailableBeforeRead2");
+ byte[] data = { 1, 2, 3 };
+ withResetConnection(data, s -> {
+ InputStream in = s.getInputStream();
+ int remaining = data.length;
+ for (int i=0; i %d%n", bytesAvailable);
+ assertTrue(bytesAvailable <= remaining);
+ try {
+ int bytesRead = in.read();
+ if (bytesRead == -1) {
+ System.out.println("read => EOF");
+ assertTrue(false);
+ } else {
+ System.out.println("read => 1 byte");
+ assertTrue(remaining > 0);
+ remaining--;
+ }
+ } catch (IOException ioe) {
+ System.out.format("read => %s%n", ioe);
+ remaining = 0;
+ }
+ }
+ });
+ }
+
+ /**
+ * Tests read before available when there are no bytes to read
+ */
+ public void testReadBeforeAvailable1() throws IOException {
+ System.out.println("testReadBeforeAvailable1");
+ withResetConnection(null, s -> {
+ InputStream in = s.getInputStream();
+ for (int i=0; i EOF");
+ } else {
+ System.out.println("read => 1 byte");
+ }
+ assertTrue(false);
+ } catch (IOException ioe) {
+ System.out.format("read => %s (expected)%n", ioe);
+ }
+ int bytesAvailable = in.available();
+ System.out.format("available => %d%n", bytesAvailable);
+ assertTrue(bytesAvailable == 0);
+ }
+ });
+ }
+
+ /**
+ * Tests read before available when there are bytes to read
+ */
+ public void testReadBeforeAvailable2() throws IOException {
+ System.out.println("testReadBeforeAvailable2");
+ byte[] data = { 1, 2, 3 };
+ withResetConnection(data, s -> {
+ InputStream in = s.getInputStream();
+ int remaining = data.length;
+ for (int i=0; i EOF");
+ assertTrue(false);
+ } else {
+ System.out.println("read => 1 byte");
+ assertTrue(remaining > 0);
+ remaining--;
+ }
+ } catch (IOException ioe) {
+ System.out.format("read => %s%n", ioe);
+ remaining = 0;
+ }
+ int bytesAvailable = in.available();
+ System.out.format("available => %d%n", bytesAvailable);
+ assertTrue(bytesAvailable <= remaining);
+ }
+ });
+ }
+
+ /**
+ * Tests available and read on a socket closed after connection reset
+ */
+ public void testAfterClose() throws IOException {
+ System.out.println("testAfterClose");
+ withResetConnection(null, s -> {
+ InputStream in = s.getInputStream();
+ try {
+ in.read();
+ assertTrue(false);
+ } catch (IOException ioe) {
+ // expected
+ }
+ s.close();
+ try {
+ int bytesAvailable = in.available();
+ System.out.format("available => %d%n", bytesAvailable);
+ assertTrue(false);
+ } catch (IOException ioe) {
+ System.out.format("available => %s (expected)%n", ioe);
+ }
+ try {
+ int n = in.read();
+ System.out.format("read => %d%n", n);
+ assertTrue(false);
+ } catch (IOException ioe) {
+ System.out.format("read => %s (expected)%n", ioe);
+ }
+ });
+ }
+
+ interface ThrowingConsumer {
+ void accept(T t) throws IOException;
+ }
+
+ /**
+ * Invokes a consumer with a Socket connected to a peer that has closed the
+ * connection with a "connection reset". The peer sends the given data bytes
+ * before closing (when data is not null).
+ */
+ static void withResetConnection(byte[] data, ThrowingConsumer consumer)
+ throws IOException
+ {
+ var loopback = InetAddress.getLoopbackAddress();
+ try (var listener = new ServerSocket()) {
+ listener.bind(new InetSocketAddress(loopback, 0));
+ try (var socket = new Socket()) {
+ socket.connect(listener.getLocalSocketAddress());
+ try (Socket peer = listener.accept()) {
+ if (data != null) {
+ peer.getOutputStream().write(data);
+ }
+ peer.setSoLinger(true, 0);
+ }
+ consumer.accept(socket);
+ }
+ }
+ }
+}
diff --git a/test/jdk/java/net/Socket/Timeouts.java b/test/jdk/java/net/Socket/Timeouts.java
new file mode 100644
index 00000000000..a3837484902
--- /dev/null
+++ b/test/jdk/java/net/Socket/Timeouts.java
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /test/lib
+ * @build jdk.test.lib.Utils
+ * @run testng Timeouts
+ * @summary Test Socket timeouts
+ */
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ConnectException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+import jdk.test.lib.Utils;
+
+@Test
+public class Timeouts {
+
+ /**
+ * Test timed connect where connection is established
+ */
+ public void testTimedConnect1() throws IOException {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ try (Socket s = new Socket()) {
+ s.connect(ss.getLocalSocketAddress(), 2000);
+ }
+ }
+ }
+
+ /**
+ * Test timed connect where connection is refused
+ */
+ public void testTimedConnect2() throws IOException {
+ try (Socket s = new Socket()) {
+ SocketAddress remote = Utils.refusingEndpoint();
+ try {
+ s.connect(remote, 2000);
+ } catch (ConnectException expected) { }
+ }
+ }
+
+ /**
+ * Test connect with a timeout of Integer.MAX_VALUE
+ */
+ public void testTimedConnect3() throws IOException {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ try (Socket s = new Socket()) {
+ s.connect(ss.getLocalSocketAddress(), Integer.MAX_VALUE);
+ }
+ }
+ }
+
+ /**
+ * Test connect with a negative timeout. This case is not currently specified
+ * but the long standing behavior is to throw IllegalArgumentException.
+ */
+ public void testTimedConnect4() throws IOException {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ try (Socket s = new Socket()) {
+ try {
+ s.connect(ss.getLocalSocketAddress(), -1);
+ assertTrue(false);
+ } catch (IllegalArgumentException expected) { }
+ }
+ }
+ }
+
+ /**
+ * Test timed read where the read succeeds immediately
+ */
+ public void testTimedRead1() throws IOException {
+ withConnection((s1, s2) -> {
+ s1.getOutputStream().write(99);
+ s2.setSoTimeout(30*1000);
+ int b = s2.getInputStream().read();
+ assertTrue(b == 99);
+ });
+ }
+
+ /**
+ * Test timed read where the read succeeds after a delay
+ */
+ public void testTimedRead2() throws IOException {
+ withConnection((s1, s2) -> {
+ scheduleWrite(s1.getOutputStream(), 99, 2000);
+ s2.setSoTimeout(30*1000);
+ int b = s2.getInputStream().read();
+ assertTrue(b == 99);
+ });
+ }
+
+ /**
+ * Test timed read where the read times out
+ */
+ public void testTimedRead3() throws IOException {
+ withConnection((s1, s2) -> {
+ s2.setSoTimeout(2000);
+ try {
+ s2.getInputStream().read();
+ assertTrue(false);
+ } catch (SocketTimeoutException expected) { }
+ });
+ }
+
+ /**
+ * Test timed read that succeeds after a previous read has timed out
+ */
+ public void testTimedRead4() throws IOException {
+ withConnection((s1, s2) -> {
+ s2.setSoTimeout(2000);
+ try {
+ s2.getInputStream().read();
+ assertTrue(false);
+ } catch (SocketTimeoutException e) { }
+ s1.getOutputStream().write(99);
+ int b = s2.getInputStream().read();
+ assertTrue(b == 99);
+ });
+ }
+
+ /**
+ * Test timed read that succeeds after a previous read has timed out and
+ * after a short delay
+ */
+ public void testTimedRead5() throws IOException {
+ withConnection((s1, s2) -> {
+ s2.setSoTimeout(2000);
+ try {
+ s2.getInputStream().read();
+ assertTrue(false);
+ } catch (SocketTimeoutException e) { }
+ s2.setSoTimeout(30*3000);
+ scheduleWrite(s1.getOutputStream(), 99, 2000);
+ int b = s2.getInputStream().read();
+ assertTrue(b == 99);
+ });
+ }
+
+ /**
+ * Test untimed read that succeeds after a previous read has timed out
+ */
+ public void testTimedRead6() throws IOException {
+ withConnection((s1, s2) -> {
+ s2.setSoTimeout(2000);
+ try {
+ s2.getInputStream().read();
+ assertTrue(false);
+ } catch (SocketTimeoutException e) { }
+ s1.getOutputStream().write(99);
+ s2.setSoTimeout(0);
+ int b = s2.getInputStream().read();
+ assertTrue(b == 99);
+ });
+ }
+
+ /**
+ * Test untimed read that succeeds after a previous read has timed out and
+ * after a short delay
+ */
+ public void testTimedRead7() throws IOException {
+ withConnection((s1, s2) -> {
+ s2.setSoTimeout(2000);
+ try {
+ s2.getInputStream().read();
+ assertTrue(false);
+ } catch (SocketTimeoutException e) { }
+ scheduleWrite(s1.getOutputStream(), 99, 2000);
+ s2.setSoTimeout(0);
+ int b = s2.getInputStream().read();
+ assertTrue(b == 99);
+ });
+ }
+
+ /**
+ * Test async close of timed read
+ */
+ public void testTimedRead8() throws IOException {
+ withConnection((s1, s2) -> {
+ s2.setSoTimeout(30*1000);
+ scheduleClose(s2, 2000);
+ try {
+ s2.getInputStream().read();
+ assertTrue(false);
+ } catch (SocketException expected) { }
+ });
+ }
+
+ /**
+ * Test read with a timeout of Integer.MAX_VALUE
+ */
+ public void testTimedRead9() throws IOException {
+ withConnection((s1, s2) -> {
+ scheduleWrite(s1.getOutputStream(), 99, 2000);
+ s2.setSoTimeout(Integer.MAX_VALUE);
+ int b = s2.getInputStream().read();
+ assertTrue(b == 99);
+ });
+ }
+
+ /**
+ * Test writing after a timed read.
+ */
+ public void testTimedWrite1() throws IOException {
+ withConnection((s1, s2) -> {
+ s1.getOutputStream().write(99);
+ s2.setSoTimeout(3000);
+ int b = s2.getInputStream().read();
+ assertTrue(b == 99);
+
+ // schedule thread to read s1 to EOF
+ scheduleReadToEOF(s1.getInputStream(), 3000);
+
+ // write a lot so that write blocks
+ byte[] data = new byte[128*1024];
+ for (int i = 0; i < 100; i++) {
+ s2.getOutputStream().write(data);
+ }
+ });
+ }
+
+ /**
+ * Test async close of writer (after a timed read).
+ */
+ public void testTimedWrite2() throws IOException {
+ withConnection((s1, s2) -> {
+ s1.getOutputStream().write(99);
+ s2.setSoTimeout(3000);
+ int b = s2.getInputStream().read();
+ assertTrue(b == 99);
+
+ // schedule s2 to be be closed
+ scheduleClose(s2, 3000);
+
+ // write a lot so that write blocks
+ byte[] data = new byte[128*1024];
+ try {
+ while (true) {
+ s2.getOutputStream().write(data);
+ }
+ } catch (SocketException expected) { }
+ });
+ }
+
+ /**
+ * Test timed accept where a connection is established immediately
+ */
+ public void testTimedAccept1() throws IOException {
+ Socket s1 = null;
+ Socket s2 = null;
+ try (ServerSocket ss = new ServerSocket(0)) {
+ s1 = new Socket();
+ s1.connect(ss.getLocalSocketAddress());
+ ss.setSoTimeout(30*1000);
+ s2 = ss.accept();
+ } finally {
+ if (s1 != null) s1.close();
+ if (s2 != null) s2.close();
+ }
+ }
+
+ /**
+ * Test timed accept where a connection is established after a short delay
+ */
+ public void testTimedAccept2() throws IOException {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ ss.setSoTimeout(30*1000);
+ scheduleConnect(ss.getLocalSocketAddress(), 2000);
+ Socket s = ss.accept();
+ s.close();
+ }
+ }
+
+ /**
+ * Test timed accept where the accept times out
+ */
+ public void testTimedAccept3() throws IOException {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ ss.setSoTimeout(2000);
+ try {
+ Socket s = ss.accept();
+ s.close();
+ assertTrue(false);
+ } catch (SocketTimeoutException expected) { }
+ }
+ }
+
+ /**
+ * Test timed accept where a connection is established immediately after a
+ * previous accept timed out.
+ */
+ public void testTimedAccept4() throws IOException {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ ss.setSoTimeout(2000);
+ try {
+ Socket s = ss.accept();
+ s.close();
+ assertTrue(false);
+ } catch (SocketTimeoutException expected) { }
+ try (Socket s1 = new Socket()) {
+ s1.connect(ss.getLocalSocketAddress());
+ Socket s2 = ss.accept();
+ s2.close();
+ }
+ }
+ }
+
+ /**
+ * Test untimed accept where a connection is established after a previous
+ * accept timed out
+ */
+ public void testTimedAccept5() throws IOException {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ ss.setSoTimeout(2000);
+ try {
+ Socket s = ss.accept();
+ s.close();
+ assertTrue(false);
+ } catch (SocketTimeoutException expected) { }
+ ss.setSoTimeout(0);
+ try (Socket s1 = new Socket()) {
+ s1.connect(ss.getLocalSocketAddress());
+ Socket s2 = ss.accept();
+ s2.close();
+ }
+ }
+ }
+
+ /**
+ * Test untimed accept where a connection is established after a previous
+ * accept timed out and after a short delay
+ */
+ public void testTimedAccept6() throws IOException {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ ss.setSoTimeout(2000);
+ try {
+ Socket s = ss.accept();
+ s.close();
+ assertTrue(false);
+ } catch (SocketTimeoutException expected) { }
+ ss.setSoTimeout(0);
+ scheduleConnect(ss.getLocalSocketAddress(), 2000);
+ Socket s = ss.accept();
+ s.close();
+ }
+ }
+
+ /**
+ * Test async close of a timed accept
+ */
+ public void testTimedAccept7() throws IOException {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ ss.setSoTimeout(30*1000);
+ scheduleClose(ss, 2000);
+ try {
+ ss.accept().close();
+ assertTrue(false);
+ } catch (SocketException expected) { }
+ }
+ }
+
+ /**
+ * Test Socket setSoTimeout with a negative timeout. This case is not currently
+ * specified but the long standing behavior is to throw IllegalArgumentException.
+ */
+ @Test(expectedExceptions = { IllegalArgumentException.class })
+ public void testBadTimeout1() throws IOException {
+ try (Socket s = new Socket()) {
+ s.setSoTimeout(-1);
+ }
+ }
+
+ /**
+ * Test ServerSocket setSoTimeout with a negative timeout. This case is not
+ * currently specified but the long standing behavior is to throw
+ * IllegalArgumentException.
+ */
+ @Test(expectedExceptions = { IllegalArgumentException.class })
+ public void testBadTimeout2() throws IOException {
+ try (ServerSocket ss = new ServerSocket()) {
+ ss.setSoTimeout(-1);
+ }
+ }
+
+ interface ThrowingBiConsumer {
+ void accept(T t, U u) throws IOException;
+ }
+
+ /**
+ * Invokes the consumer with a connected pair of sockets
+ */
+ static void withConnection(ThrowingBiConsumer consumer)
+ throws IOException
+ {
+ Socket s1 = null;
+ Socket s2 = null;
+ try (ServerSocket ss = new ServerSocket(0)) {
+ s1 = new Socket();
+ s1.connect(ss.getLocalSocketAddress());
+ s2 = ss.accept();
+ consumer.accept(s1, s2);
+ } finally {
+ if (s1 != null) s1.close();
+ if (s2 != null) s2.close();
+ }
+ }
+
+ /**
+ * Schedule c to be closed after a delay
+ */
+ static void scheduleClose(Closeable c, long delay) {
+ schedule(() -> {
+ try {
+ c.close();
+ } catch (IOException ioe) { }
+ }, delay);
+ }
+
+ /**
+ * Schedule a thread to connect to the given end point after a delay
+ */
+ static void scheduleConnect(SocketAddress remote, long delay) {
+ schedule(() -> {
+ try (Socket s = new Socket()) {
+ s.connect(remote);
+ } catch (IOException ioe) { }
+ }, delay);
+ }
+
+ /**
+ * Schedule a thread to read to EOF after a delay
+ */
+ static void scheduleReadToEOF(InputStream in, long delay) {
+ schedule(() -> {
+ byte[] bytes = new byte[8192];
+ try {
+ while (in.read(bytes) != -1) { }
+ } catch (IOException ioe) { }
+ }, delay);
+ }
+
+ /**
+ * Schedule a thread to write after a delay
+ */
+ static void scheduleWrite(OutputStream out, byte[] data, long delay) {
+ schedule(() -> {
+ try {
+ out.write(data);
+ } catch (IOException ioe) { }
+ }, delay);
+ }
+ static void scheduleWrite(OutputStream out, int b, long delay) {
+ scheduleWrite(out, new byte[] { (byte)b }, delay);
+ }
+
+ static void schedule(Runnable task, long delay) {
+ ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+ try {
+ executor.schedule(task, delay, TimeUnit.MILLISECONDS);
+ } finally {
+ executor.shutdown();
+ }
+ }
+}
diff --git a/test/jdk/java/net/Socket/UdpSocket.java b/test/jdk/java/net/Socket/UdpSocket.java
new file mode 100644
index 00000000000..6792bd9690d
--- /dev/null
+++ b/test/jdk/java/net/Socket/UdpSocket.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @run main UdpSocket
+ * @summary Basic test for a Socket to a UDP socket
+ */
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.DatagramChannel;
+import java.util.Arrays;
+
+public class UdpSocket {
+
+ static final String MESSAGE = "hello";
+
+ public static void main(String[] args) throws IOException {
+ try (DatagramChannel dc = DatagramChannel.open()) {
+ var loopback = InetAddress.getLoopbackAddress();
+ dc.bind(new InetSocketAddress(loopback, 0));
+
+ int port = ((InetSocketAddress) dc.getLocalAddress()).getPort();
+ try (Socket s = new Socket(loopback, port, false)) {
+
+ // send datagram with socket output stream
+ byte[] array1 = MESSAGE.getBytes("UTF-8");
+ s.getOutputStream().write(array1);
+
+ // receive the datagram
+ var buf = ByteBuffer.allocate(100);
+ SocketAddress remote = dc.receive(buf);
+ buf.flip();
+ if (buf.remaining() != MESSAGE.length())
+ throw new RuntimeException("Unexpected size");
+
+ // echo the datagram
+ dc.send(buf, remote);
+
+ // receive datagram with the socket input stream
+ byte[] array2 = new byte[100];
+ int n = s.getInputStream().read(array2);
+ if (n != MESSAGE.length())
+ throw new RuntimeException("Unexpected size");
+ if (!Arrays.equals(array1, 0, n, array2, 0, n))
+ throw new RuntimeException("Unexpected contents");
+ }
+ }
+ }
+}
diff --git a/test/jdk/java/util/Scanner/ScanTest.java b/test/jdk/java/util/Scanner/ScanTest.java
index 44ee2b0b463..f8e5ab29f47 100644
--- a/test/jdk/java/util/Scanner/ScanTest.java
+++ b/test/jdk/java/util/Scanner/ScanTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
/**
* @test
* @bug 4313885 4926319 4927634 5032610 5032622 5049968 5059533 6223711 6277261 6269946 6288823
- * 8072722 8139414 8166261
+ * 8072722 8139414 8166261 8172695
* @summary Basic tests of java.util.Scanner methods
* @key randomness
* @modules jdk.localedata
@@ -49,26 +49,12 @@ public class ScanTest {
private static File inputFile = new File(System.getProperty("test.src", "."), "input.txt");
public static void main(String[] args) throws Exception {
-
- Locale reservedLocale = Locale.getDefault();
- String lang = reservedLocale.getLanguage();
+ Locale defaultLocale = Locale.getDefault();
try {
- if (!"en".equals(lang) &&
- !"zh".equals(lang) &&
- !"ko".equals(lang) &&
- !"ja".equals(lang)) {
- //Before we have resource to improve the test to be ready for
- //arbitrary locale, force the default locale to be "English"
- //for now. First we check whether the "English" locale is
- //available on the system as it could be absent due to varying
- //configurations.
- if (!Arrays.asList(Locale.getAvailableLocales())
- .contains(Locale.ENGLISH)) {
- throw new RuntimeException
- ("The \"English\" Locale is unavailable on this system");
- }
- Locale.setDefault(Locale.ENGLISH);
- }
+ // Before we have resource to improve the test to be ready for
+ // arbitrary locale, force the default locale to be ROOT for now.
+ Locale.setDefault(Locale.US);
+
skipTest();
findInLineTest();
findWithinHorizonTest();
@@ -128,7 +114,7 @@ public class ScanTest {
System.err.println("OKAY: All tests passed.");
} finally {
// restore the default locale
- Locale.setDefault(reservedLocale);
+ Locale.setDefault(defaultLocale);
}
}
diff --git a/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java b/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java
index 95bfe2ea7e4..d4c9c3497ee 100644
--- a/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java
+++ b/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java
@@ -64,10 +64,15 @@ public class MetricsMemoryTester {
long count = Metrics.systemMetrics().getMemoryFailCount();
// Allocate 512M of data
- long[][] longs = new long[64][];
- for (int i = 1; i <= 64; i++) {
+ byte[][] bytes = new byte[64][];
+ for (int i = 0; i < 64; i++) {
try {
- longs[i] = new long[8 * 1024 * 1024];
+ bytes[i] = new byte[8 * 1024 * 1024];
+ // Break out as soon as we see an increase in failcount
+ // to avoid getting killed by the OOM killer.
+ if (Metrics.systemMetrics().getMemoryFailCount() > count) {
+ break;
+ }
} catch (Error e) { // OOM error
break;
}
diff --git a/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java b/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java
index ee3b5a35f04..2a4b44fb917 100644
--- a/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java
+++ b/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java
@@ -90,6 +90,7 @@ public class TestDockerMemoryMetrics {
new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsMemoryTester");
opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/")
.addDockerOpts("--memory=" + value)
+ .addJavaOpts("-Xmx" + value)
.addJavaOpts("-cp", "/test-classes/")
.addJavaOpts("--add-exports", "java.base/jdk.internal.platform=ALL-UNNAMED")
.addClassOptions("failcount");
diff --git a/test/jdk/sun/security/ec/SignatureDigestTruncate.java b/test/jdk/sun/security/ec/SignatureDigestTruncate.java
index aa58a9b7169..8bdf82fec10 100644
--- a/test/jdk/sun/security/ec/SignatureDigestTruncate.java
+++ b/test/jdk/sun/security/ec/SignatureDigestTruncate.java
@@ -91,22 +91,25 @@ public class SignatureDigestTruncate {
String privateKeyStr, String msgStr, String kStr, String sigStr)
throws Exception {
+ System.out.println("Testing " + alg + " with " + curveName);
+
byte[] privateKey = Convert.hexStringToByteArray(privateKeyStr);
byte[] msg = Convert.hexStringToByteArray(msgStr);
byte[] k = Convert.hexStringToByteArray(kStr);
byte[] expectedSig = Convert.hexStringToByteArray(sigStr);
- AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
+ AlgorithmParameters params =
+ AlgorithmParameters.getInstance("EC", "SunEC");
params.init(new ECGenParameterSpec(curveName));
ECParameterSpec ecParams =
params.getParameterSpec(ECParameterSpec.class);
- KeyFactory kf = KeyFactory.getInstance("EC");
+ KeyFactory kf = KeyFactory.getInstance("EC", "SunEC");
BigInteger s = new BigInteger(1, privateKey);
ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(s, ecParams);
PrivateKey privKey = kf.generatePrivate(privKeySpec);
- Signature sig = Signature.getInstance(alg);
+ Signature sig = Signature.getInstance(alg, "SunEC");
sig.initSign(privKey, new FixedRandom(k));
sig.update(msg);
byte[] computedSig = sig.sign();
diff --git a/test/jdk/sun/security/pkcs11/tls/tls12/TestTLS12.java b/test/jdk/sun/security/pkcs11/tls/tls12/TestTLS12.java
new file mode 100644
index 00000000000..227c00fef5f
--- /dev/null
+++ b/test/jdk/sun/security/pkcs11/tls/tls12/TestTLS12.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8029661
+ * @summary Test TLS 1.2
+ * @modules java.base/sun.security.internal.spec
+ * java.base/sun.security.util
+ * java.base/com.sun.crypto.provider
+ * @library /test/lib ../..
+ * @run main/othervm/timeout=120 TestTLS12
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManagerFactory;
+
+import sun.security.internal.spec.TlsMasterSecretParameterSpec;
+import sun.security.internal.spec.TlsPrfParameterSpec;
+import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
+
+public final class TestTLS12 extends SecmodTest {
+
+ private static final boolean enableDebug = true;
+
+ private static Provider sunPKCS11NSSProvider;
+ private static Provider sunJCEProvider;
+ private static KeyStore ks;
+ private static KeyStore ts;
+ private static char[] passphrase = "JAHshj131@@".toCharArray();
+ private static RSAPrivateKey privateKey;
+ private static RSAPublicKey publicKey;
+
+ public static void main(String[] args) throws Exception {
+ try {
+ initialize();
+ } catch (Exception e) {
+ System.out.println("Test skipped: failure during" +
+ " initialization");
+ if (enableDebug) {
+ System.out.println(e);
+ }
+ return;
+ }
+
+ if (shouldRun()) {
+ // Test against JCE
+ testTlsAuthenticationCodeGeneration();
+
+ // Self-integrity test (complete TLS 1.2 communication)
+ new testTLS12SunPKCS11Communication().run();
+
+ System.out.println("Test PASS - OK");
+ } else {
+ System.out.println("Test skipped: TLS 1.2 mechanisms" +
+ " not supported by current SunPKCS11 back-end");
+ }
+ }
+
+ private static boolean shouldRun() {
+ if (sunPKCS11NSSProvider == null) {
+ return false;
+ }
+ try {
+ KeyGenerator.getInstance("SunTls12MasterSecret",
+ sunPKCS11NSSProvider);
+ KeyGenerator.getInstance(
+ "SunTls12RsaPremasterSecret", sunPKCS11NSSProvider);
+ KeyGenerator.getInstance("SunTls12Prf", sunPKCS11NSSProvider);
+ } catch (NoSuchAlgorithmException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private static void testTlsAuthenticationCodeGeneration()
+ throws Exception {
+ // Generate RSA Pre-Master Secret in SunPKCS11 provider
+ SecretKey rsaPreMasterSecret = null;
+ @SuppressWarnings("deprecation")
+ TlsRsaPremasterSecretParameterSpec rsaPreMasterSecretSpec =
+ new TlsRsaPremasterSecretParameterSpec(0x0303, 0x0303);
+ {
+ KeyGenerator rsaPreMasterSecretKG = KeyGenerator.getInstance(
+ "SunTls12RsaPremasterSecret", sunPKCS11NSSProvider);
+ rsaPreMasterSecretKG.init(rsaPreMasterSecretSpec, null);
+ rsaPreMasterSecret = rsaPreMasterSecretKG.generateKey();
+ }
+
+ // Get RSA Pre-Master Secret in plain (from SunPKCS11 provider)
+ byte[] rsaPlainPreMasterSecret = null;
+ {
+ Cipher rsaPreMasterSecretWrapperCipher =
+ Cipher.getInstance("RSA/ECB/PKCS1Padding",
+ sunPKCS11NSSProvider);
+ rsaPreMasterSecretWrapperCipher.init(Cipher.WRAP_MODE, publicKey,
+ new SecureRandom());
+ byte[] rsaEncryptedPreMasterSecret =
+ rsaPreMasterSecretWrapperCipher.wrap(rsaPreMasterSecret);
+ Cipher rsaPreMasterSecretUnwrapperCipher =
+ Cipher.getInstance("RSA/ECB/PKCS1Padding", sunJCEProvider);
+ rsaPreMasterSecretUnwrapperCipher.init(Cipher.UNWRAP_MODE,
+ privateKey, rsaPreMasterSecretSpec);
+ rsaPlainPreMasterSecret = rsaPreMasterSecretUnwrapperCipher.unwrap(
+ rsaEncryptedPreMasterSecret, "TlsRsaPremasterSecret",
+ Cipher.SECRET_KEY).getEncoded();
+
+ if (enableDebug) {
+ System.out.println("rsaPlainPreMasterSecret:");
+ for (byte b : rsaPlainPreMasterSecret) {
+ System.out.printf("%02X, ", b);
+ }
+ System.out.println("");
+ }
+ }
+
+ // Generate Master Secret
+ SecretKey sunPKCS11MasterSecret = null;
+ SecretKey jceMasterSecret = null;
+ {
+ KeyGenerator sunPKCS11MasterSecretGenerator =
+ KeyGenerator.getInstance("SunTls12MasterSecret",
+ sunPKCS11NSSProvider);
+ KeyGenerator jceMasterSecretGenerator = KeyGenerator.getInstance(
+ "SunTls12MasterSecret", sunJCEProvider);
+ @SuppressWarnings("deprecation")
+ TlsMasterSecretParameterSpec sunPKCS11MasterSecretSpec =
+ new TlsMasterSecretParameterSpec(rsaPreMasterSecret, 3, 3,
+ new byte[32], new byte[32], "SHA-256", 32, 64);
+ @SuppressWarnings("deprecation")
+ TlsMasterSecretParameterSpec jceMasterSecretSpec =
+ new TlsMasterSecretParameterSpec(
+ new SecretKeySpec(rsaPlainPreMasterSecret,
+ "Generic"), 3, 3, new byte[32],
+ new byte[32], "SHA-256", 32, 64);
+ sunPKCS11MasterSecretGenerator.init(sunPKCS11MasterSecretSpec,
+ null);
+ jceMasterSecretGenerator.init(jceMasterSecretSpec, null);
+ sunPKCS11MasterSecret =
+ sunPKCS11MasterSecretGenerator.generateKey();
+ jceMasterSecret = jceMasterSecretGenerator.generateKey();
+ if (enableDebug) {
+ System.out.println("Master Secret (SunJCE):");
+ if (jceMasterSecret != null) {
+ for (byte b : jceMasterSecret.getEncoded()) {
+ System.out.printf("%02X, ", b);
+ }
+ System.out.println("");
+ }
+ }
+ }
+
+ // Generate authentication codes
+ byte[] sunPKCS11AuthenticationCode = null;
+ byte[] jceAuthenticationCode = null;
+ {
+ // Generate SunPKCS11 authentication code
+ {
+ @SuppressWarnings("deprecation")
+ TlsPrfParameterSpec sunPKCS11AuthenticationCodeSpec =
+ new TlsPrfParameterSpec(sunPKCS11MasterSecret,
+ "client finished", "a".getBytes(), 12,
+ "SHA-256", 32, 64);
+ KeyGenerator sunPKCS11AuthCodeGenerator =
+ KeyGenerator.getInstance("SunTls12Prf",
+ sunPKCS11NSSProvider);
+ sunPKCS11AuthCodeGenerator.init(
+ sunPKCS11AuthenticationCodeSpec);
+ sunPKCS11AuthenticationCode =
+ sunPKCS11AuthCodeGenerator.generateKey().getEncoded();
+ }
+
+ // Generate SunJCE authentication code
+ {
+ @SuppressWarnings("deprecation")
+ TlsPrfParameterSpec jceAuthenticationCodeSpec =
+ new TlsPrfParameterSpec(jceMasterSecret,
+ "client finished", "a".getBytes(), 12,
+ "SHA-256", 32, 64);
+ KeyGenerator jceAuthCodeGenerator =
+ KeyGenerator.getInstance("SunTls12Prf",
+ sunJCEProvider);
+ jceAuthCodeGenerator.init(jceAuthenticationCodeSpec);
+ jceAuthenticationCode =
+ jceAuthCodeGenerator.generateKey().getEncoded();
+ }
+
+ if (enableDebug) {
+ System.out.println("SunPKCS11 Authentication Code: ");
+ for (byte b : sunPKCS11AuthenticationCode) {
+ System.out.printf("%02X, ", b);
+ }
+ System.out.println("");
+ System.out.println("SunJCE Authentication Code: ");
+ for (byte b : jceAuthenticationCode) {
+ System.out.printf("%02X, ", b);
+ }
+ System.out.println("");
+ }
+ }
+
+ if (sunPKCS11AuthenticationCode == null ||
+ jceAuthenticationCode == null ||
+ sunPKCS11AuthenticationCode.length == 0 ||
+ jceAuthenticationCode.length == 0 ||
+ !Arrays.equals(sunPKCS11AuthenticationCode,
+ jceAuthenticationCode)) {
+ throw new Exception("Authentication codes from JCE" +
+ " and SunPKCS11 differ.");
+ }
+ }
+
+ private static class testTLS12SunPKCS11Communication {
+ public static void run() throws Exception {
+ SSLEngine[][] enginesToTest = getSSLEnginesToTest();
+
+ for (SSLEngine[] engineToTest : enginesToTest) {
+
+ SSLEngine clientSSLEngine = engineToTest[0];
+ SSLEngine serverSSLEngine = engineToTest[1];
+
+ // SSLEngine code based on RedhandshakeFinished.java
+
+ boolean dataDone = false;
+
+ ByteBuffer clientOut = null;
+ ByteBuffer clientIn = null;
+ ByteBuffer serverOut = null;
+ ByteBuffer serverIn = null;
+ ByteBuffer cTOs;
+ ByteBuffer sTOc;
+
+ SSLSession session = clientSSLEngine.getSession();
+ int appBufferMax = session.getApplicationBufferSize();
+ int netBufferMax = session.getPacketBufferSize();
+
+ clientIn = ByteBuffer.allocate(appBufferMax + 50);
+ serverIn = ByteBuffer.allocate(appBufferMax + 50);
+
+ cTOs = ByteBuffer.allocateDirect(netBufferMax);
+ sTOc = ByteBuffer.allocateDirect(netBufferMax);
+
+ clientOut = ByteBuffer.wrap(
+ "Hi Server, I'm Client".getBytes());
+ serverOut = ByteBuffer.wrap(
+ "Hello Client, I'm Server".getBytes());
+
+ SSLEngineResult clientResult;
+ SSLEngineResult serverResult;
+
+ while (!dataDone) {
+ clientResult = clientSSLEngine.wrap(clientOut, cTOs);
+ runDelegatedTasks(clientResult, clientSSLEngine);
+ serverResult = serverSSLEngine.wrap(serverOut, sTOc);
+ runDelegatedTasks(serverResult, serverSSLEngine);
+ cTOs.flip();
+ sTOc.flip();
+
+ if (enableDebug) {
+ System.out.println("Client -> Network");
+ printTlsNetworkPacket("", cTOs);
+ System.out.println("");
+ System.out.println("Server -> Network");
+ printTlsNetworkPacket("", sTOc);
+ System.out.println("");
+ }
+
+ clientResult = clientSSLEngine.unwrap(sTOc, clientIn);
+ runDelegatedTasks(clientResult, clientSSLEngine);
+ serverResult = serverSSLEngine.unwrap(cTOs, serverIn);
+ runDelegatedTasks(serverResult, serverSSLEngine);
+
+ cTOs.compact();
+ sTOc.compact();
+
+ if (!dataDone &&
+ (clientOut.limit() == serverIn.position()) &&
+ (serverOut.limit() == clientIn.position())) {
+ checkTransfer(serverOut, clientIn);
+ checkTransfer(clientOut, serverIn);
+ dataDone = true;
+ }
+ }
+ }
+ }
+
+ static void printTlsNetworkPacket(String prefix, ByteBuffer bb) {
+ ByteBuffer slice = bb.slice();
+ byte[] buffer = new byte[slice.remaining()];
+ slice.get(buffer);
+ for (int i = 0; i < buffer.length; i++) {
+ System.out.printf("%02X, ", (byte)(buffer[i] & (byte)0xFF));
+ if (i % 8 == 0 && i % 16 != 0) {
+ System.out.print(" ");
+ }
+ if (i % 16 == 0) {
+ System.out.println("");
+ }
+ }
+ System.out.flush();
+ }
+
+ private static void checkTransfer(ByteBuffer a, ByteBuffer b)
+ throws Exception {
+ a.flip();
+ b.flip();
+ if (!a.equals(b)) {
+ throw new Exception("Data didn't transfer cleanly");
+ }
+ a.position(a.limit());
+ b.position(b.limit());
+ a.limit(a.capacity());
+ b.limit(b.capacity());
+ }
+
+ private static void runDelegatedTasks(SSLEngineResult result,
+ SSLEngine engine) throws Exception {
+
+ if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ runnable.run();
+ }
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ }
+ }
+
+ private static SSLEngine[][] getSSLEnginesToTest() throws Exception {
+ SSLEngine[][] enginesToTest = new SSLEngine[2][2];
+ String[][] preferredSuites = new String[][]{ new String[] {
+ "TLS_RSA_WITH_AES_128_CBC_SHA256"
+ }, new String[] {
+ "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"
+ }};
+ for (int i = 0; i < enginesToTest.length; i++) {
+ enginesToTest[i][0] = createSSLEngine(true);
+ enginesToTest[i][1] = createSSLEngine(false);
+ enginesToTest[i][0].setEnabledCipherSuites(preferredSuites[i]);
+ enginesToTest[i][1].setEnabledCipherSuites(preferredSuites[i]);
+ }
+ return enginesToTest;
+ }
+
+ static private SSLEngine createSSLEngine(boolean client)
+ throws Exception {
+ SSLEngine ssle;
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX", "SunJSSE");
+ kmf.init(ks, passphrase);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX", "SunJSSE");
+ tmf.init(ts);
+
+ SSLContext sslCtx = SSLContext.getInstance("TLSv1.2", "SunJSSE");
+ sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ ssle = sslCtx.createSSLEngine("localhost", 443);
+ ssle.setUseClientMode(client);
+ SSLParameters sslParameters = ssle.getSSLParameters();
+ ssle.setSSLParameters(sslParameters);
+
+ return ssle;
+ }
+ }
+
+ private static void initialize() throws Exception {
+ if (initSecmod() == false) {
+ return;
+ }
+ String configName = BASE + SEP + "nss.cfg";
+ sunPKCS11NSSProvider = getSunPKCS11(configName);
+ System.out.println("SunPKCS11 provider: " + sunPKCS11NSSProvider);
+
+ List installedProviders = new LinkedList<>();
+ for (Provider p : Security.getProviders()){
+ installedProviders.add(p);
+ Security.removeProvider(p.getName());
+ }
+ Security.addProvider(sunPKCS11NSSProvider);
+ for (Provider p : installedProviders){
+ String providerName = p.getName();
+ if (providerName.equals("SunJSSE") ||
+ providerName.equals("SUN") ||
+ providerName.equals("SunJCE")) {
+ Security.addProvider(p);
+ if (providerName.equals("SunJCE")) {
+ sunJCEProvider = p;
+ }
+ }
+ }
+
+ ks = KeyStore.getInstance("PKCS11", sunPKCS11NSSProvider);
+ ks.load(null, "test12".toCharArray());
+ ts = ks;
+
+ KeyStore ksPlain = readTestKeyStore();
+ privateKey = (RSAPrivateKey)ksPlain.getKey("rh_rsa_sha256",
+ passphrase);
+ publicKey = (RSAPublicKey)ksPlain.getCertificate(
+ "rh_rsa_sha256").getPublicKey();
+
+ // Extended Master Secret is not currently supported in SunPKCS11
+ // cryptographic provider
+ System.setProperty("jdk.tls.useExtendedMasterSecret", "false");
+ String disabledAlgorithms =
+ Security.getProperty("jdk.tls.disabledAlgorithms");
+ if (disabledAlgorithms.length() > 0) {
+ disabledAlgorithms += ", ";
+ }
+ // RSASSA-PSS is not currently supported in SunPKCS11
+ // cryptographic provider
+ disabledAlgorithms += "RSASSA-PSS";
+ Security.setProperty("jdk.tls.disabledAlgorithms", disabledAlgorithms);
+ }
+
+ private static KeyStore readTestKeyStore() throws Exception {
+ File file = new File(System.getProperty("test.src", "."), "keystore");
+ InputStream in = new FileInputStream(file);
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(in, "passphrase".toCharArray());
+ in.close();
+ return ks;
+ }
+}
diff --git a/test/jdk/sun/security/pkcs11/tls/tls12/cert8.db b/test/jdk/sun/security/pkcs11/tls/tls12/cert8.db
new file mode 100644
index 00000000000..b80a6e7e4a3
Binary files /dev/null and b/test/jdk/sun/security/pkcs11/tls/tls12/cert8.db differ
diff --git a/test/jdk/sun/security/pkcs11/tls/tls12/key3.db b/test/jdk/sun/security/pkcs11/tls/tls12/key3.db
new file mode 100644
index 00000000000..ca8e43dd819
Binary files /dev/null and b/test/jdk/sun/security/pkcs11/tls/tls12/key3.db differ
diff --git a/test/jdk/sun/security/pkcs11/tls/tls12/keystore b/test/jdk/sun/security/pkcs11/tls/tls12/keystore
new file mode 100644
index 00000000000..f1db334f005
Binary files /dev/null and b/test/jdk/sun/security/pkcs11/tls/tls12/keystore differ
diff --git a/test/jdk/sun/security/pkcs11/tls/tls12/nss.cfg b/test/jdk/sun/security/pkcs11/tls/tls12/nss.cfg
new file mode 100644
index 00000000000..349c783af08
--- /dev/null
+++ b/test/jdk/sun/security/pkcs11/tls/tls12/nss.cfg
@@ -0,0 +1,19 @@
+
+name = NSSKeyStore
+
+nssSecmodDirectory = ${pkcs11test.nss.db}
+
+nssLibraryDirectory = ${pkcs11test.nss.libdir}
+
+nssModule = fips
+
+# NSS needs CKA_NETSCAPE_DB for DSA and DH private keys
+# just put an arbitrary value in there to make it happy
+
+attributes(*,CKO_PRIVATE_KEY,CKK_DSA) = {
+ CKA_NETSCAPE_DB = 0h00
+}
+
+attributes(*,CKO_PRIVATE_KEY,CKK_DH) = {
+ CKA_NETSCAPE_DB = 0h00
+}
diff --git a/test/jdk/sun/security/pkcs11/tls/tls12/secmod.db b/test/jdk/sun/security/pkcs11/tls/tls12/secmod.db
new file mode 100644
index 00000000000..5418eea41d6
Binary files /dev/null and b/test/jdk/sun/security/pkcs11/tls/tls12/secmod.db differ
diff --git a/test/langtools/tools/javac/modules/MOptionTest.java b/test/langtools/tools/javac/modules/MOptionTest.java
index c6642ca93c9..ff08960b0bc 100644
--- a/test/langtools/tools/javac/modules/MOptionTest.java
+++ b/test/langtools/tools/javac/modules/MOptionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* 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 8146946 8176743
+ * @bug 8146946 8176743 8200286
* @summary implement javac -m option
* @library /tools/lib
* @modules
@@ -39,7 +39,6 @@ import java.nio.file.attribute.FileTime;
import toolbox.JavacTask;
import toolbox.Task;
-import toolbox.ToolBox;
public class MOptionTest extends ModuleTestBase {
public static void main(String... args) throws Exception {
@@ -93,9 +92,10 @@ public class MOptionTest extends ModuleTestBase {
throw new AssertionError("Classfile update!");
}
- Thread.sleep(2000); //timestamps
-
- Files.setLastModifiedTime(testTest, FileTime.fromMillis(System.currentTimeMillis()));
+ // Date back the source file by one second compared to the current time.
+ // Cases have been observed where the resulting class file had an earlier
+ // timestamp than the java source.
+ Files.setLastModifiedTime(testTest, FileTime.fromMillis(System.currentTimeMillis() - 1000));
new JavacTask(tb)
.options("-m", "m1x", "--module-source-path", src.toString(), "-d", build.toString())
@@ -235,10 +235,11 @@ public class MOptionTest extends ModuleTestBase {
throw new AssertionError("Classfile update!");
}
- Thread.sleep(2000); //timestamps
-
- Files.setLastModifiedTime(C1Source, FileTime.fromMillis(System.currentTimeMillis()));
- Files.setLastModifiedTime(C2Source, FileTime.fromMillis(System.currentTimeMillis()));
+ // Date back the source file by one second compared to the current time.
+ // Cases have been observed where the resulting class file had an earlier
+ // timestamp than the java source.
+ Files.setLastModifiedTime(C1Source, FileTime.fromMillis(System.currentTimeMillis() - 1000));
+ Files.setLastModifiedTime(C2Source, FileTime.fromMillis(System.currentTimeMillis() - 1000));
new JavacTask(tb)
.options("-m", "m1x,m2x", "--module-source-path", src.toString(), "-d", build.toString())