From 94d9355a640e7a51ec86fafbaf7dc8fb13570e1c Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Wed, 20 Mar 2019 17:13:08 +0100 Subject: [PATCH 01/24] Added tag jdk-12-ga for changeset b67884871b5f --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index c130ac5425b..083de4c1ae7 100644 --- a/.hgtags +++ b/.hgtags @@ -536,3 +536,4 @@ f15d443f97318e9b40e6f451e327ff69ed4ec361 jdk-12+27 b5f7bb57de2f797be34f6c75d45c3245ad37ab97 jdk-12+31 4ce47bc1fb92cf94c6e3d1f49d582f02dcb851ab jdk-12+32 b67884871b5fff79c5ef3eb8ac74dd48d71ea9b1 jdk-12+33 +b67884871b5fff79c5ef3eb8ac74dd48d71ea9b1 jdk-12-ga From ea61da4d5f421c533ea14f00146f3565c9f5b84d Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Wed, 20 Mar 2019 22:53:44 +0100 Subject: [PATCH 02/24] 8220389: Update Graal Reviewed-by: kvn, dlong --- .../core/test/IntegerStampShiftTest.java | 71 +++++++++++++ .../compiler/core/CompilationWrapper.java | 88 +++++++-------- .../compiler/core/GraalCompilerOptions.java | 13 ++- ...p.txt => CompilationFailureActionHelp.txt} | 2 +- .../hotspot/amd64/AMD64ArrayEqualsStub.java | 100 ++++++++++++++++++ .../amd64/AMD64HotSpotBackendFactory.java | 3 +- .../AMD64HotSpotForeignCallsProvider.java | 18 +++- .../amd64/AMD64HotSpotLIRGenerator.java | 30 +++++- .../test/StringUTF16ToBytesGetCharsTest.java | 9 +- .../test/BigIntegerIntrinsicsTest.java | 11 +- .../hotspot/test/CompileTheWorld.java | 4 +- .../hotspot/test/CompileTheWorldTest.java | 6 +- .../hotspot/test/GraalOSRTestBase.java | 5 +- .../compiler/hotspot/CompilationTask.java | 44 ++++---- .../hotspot/HotSpotGraalOptionValues.java | 26 +++-- .../lir/amd64/AMD64ArrayIndexOfOp.java | 2 +- .../compiler/lir/gen/LIRGeneratorTool.java | 7 +- .../nodes/calc/UnsignedRightShiftNode.java | 10 +- .../amd64/AMD64GraphBuilderPlugins.java | 47 ++++---- .../replacements/nodes/ArrayEqualsNode.java | 33 +++++- 20 files changed, 392 insertions(+), 137 deletions(-) create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IntegerStampShiftTest.java rename src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/doc-files/{CompilationBailoutActionHelp.txt => CompilationFailureActionHelp.txt} (76%) create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayEqualsStub.java 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); } From 7bb74f80dac41436fe54565636f575a4b2b48c14 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 20 Mar 2019 18:01:42 -0400 Subject: [PATCH 03/24] 8218446: SuspendAtExit hangs Reviewed-by: rehn, dcubed --- src/hotspot/share/runtime/thread.cpp | 87 ++++++++++------------------ src/hotspot/share/runtime/thread.hpp | 12 +++- 2 files changed, 38 insertions(+), 61 deletions(-) diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp index 07baa46cc20..8e031347de1 100644 --- a/src/hotspot/share/runtime/thread.cpp +++ b/src/hotspot/share/runtime/thread.cpp @@ -2264,48 +2264,19 @@ void JavaThread::check_and_handle_async_exceptions(bool check_unsafe_error) { void JavaThread::handle_special_runtime_exit_condition(bool check_asyncs) { // - // Check for pending external suspend. Internal suspend requests do - // not use handle_special_runtime_exit_condition(). + // Check for pending external suspend. // If JNIEnv proxies are allowed, don't self-suspend if the target // thread is not the current thread. In older versions of jdbx, jdbx // threads could call into the VM with another thread's JNIEnv so we // can be here operating on behalf of a suspended thread (4432884). bool do_self_suspend = is_external_suspend_with_lock(); if (do_self_suspend && (!AllowJNIEnvProxy || this == JavaThread::current())) { - // - // Because thread is external suspended the safepoint code will count - // thread as at a safepoint. This can be odd because we can be here - // as _thread_in_Java which would normally transition to _thread_blocked - // at a safepoint. We would like to mark the thread as _thread_blocked - // before calling java_suspend_self like all other callers of it but - // we must then observe proper safepoint protocol. (We can't leave - // _thread_blocked with a safepoint in progress). However we can be - // here as _thread_in_native_trans so we can't use a normal transition - // constructor/destructor pair because they assert on that type of - // transition. We could do something like: - // - // JavaThreadState state = thread_state(); - // set_thread_state(_thread_in_vm); - // { - // ThreadBlockInVM tbivm(this); - // java_suspend_self() - // } - // set_thread_state(_thread_in_vm_trans); - // if (safepoint) block; - // set_thread_state(state); - // - // but that is pretty messy. Instead we just go with the way the - // code has worked before and note that this is the only path to - // java_suspend_self that doesn't put the thread in _thread_blocked - // mode. - frame_anchor()->make_walkable(this); - java_suspend_self(); - - // We might be here for reasons in addition to the self-suspend request - // so check for other async requests. + java_suspend_self_with_safepoint_check(); } + // We might be here for reasons in addition to the self-suspend request + // so check for other async requests. if (check_asyncs) { check_and_handle_async_exceptions(); } @@ -2424,6 +2395,7 @@ void JavaThread::java_suspend() { // to complete an external suspend request. // int JavaThread::java_suspend_self() { + assert(thread_state() == _thread_blocked, "wrong state for java_suspend_self()"); int ret = 0; // we are in the process of exiting so don't suspend @@ -2471,6 +2443,27 @@ int JavaThread::java_suspend_self() { return ret; } +// Helper routine to set up the correct thread state before calling java_suspend_self. +// This is called when regular thread-state transition helpers can't be used because +// we can be in various states, in particular _thread_in_native_trans. +// Because this thread is external suspended the safepoint code will count it as at +// a safepoint, regardless of what its actual current thread-state is. But +// is_ext_suspend_completed() may be waiting to see a thread transition from +// _thread_in_native_trans to _thread_blocked. So we set the thread state directly +// to _thread_blocked. The problem with setting thread state directly is that a +// safepoint could happen just after java_suspend_self() returns after being resumed, +// and the VM thread will see the _thread_blocked state. So we must check for a safepoint +// after restoring the state to make sure we won't leave while a safepoint is in progress. +void JavaThread::java_suspend_self_with_safepoint_check() { + assert(this == Thread::current(), "invariant"); + JavaThreadState state = thread_state(); + set_thread_state(_thread_blocked); + java_suspend_self(); + set_thread_state(state); + InterfaceSupport::serialize_thread_state_with_handler(this); + SafepointMechanism::block_if_requested(this); +} + #ifdef ASSERT // Verify the JavaThread has not yet been published in the Threads::list, and // hence doesn't need protection from concurrent access at this stage. @@ -2502,33 +2495,11 @@ void JavaThread::check_safepoint_and_suspend_for_native_trans(JavaThread *thread // threads could call into the VM with another thread's JNIEnv so we // can be here operating on behalf of a suspended thread (4432884). if (do_self_suspend && (!AllowJNIEnvProxy || curJT == thread)) { - JavaThreadState state = thread->thread_state(); - - // We mark this thread_blocked state as a suspend-equivalent so - // that a caller to is_ext_suspend_completed() won't be confused. - // The suspend-equivalent state is cleared by java_suspend_self(). - thread->set_suspend_equivalent(); - - // If the safepoint code sees the _thread_in_native_trans state, it will - // wait until the thread changes to other thread state. There is no - // guarantee on how soon we can obtain the SR_lock and complete the - // self-suspend request. It would be a bad idea to let safepoint wait for - // too long. Temporarily change the state to _thread_blocked to - // let the VM thread know that this thread is ready for GC. The problem - // of changing thread state is that safepoint could happen just after - // java_suspend_self() returns after being resumed, and VM thread will - // see the _thread_blocked state. We must check for safepoint - // after restoring the state and make sure we won't leave while a safepoint - // is in progress. - thread->set_thread_state(_thread_blocked); - thread->java_suspend_self(); - thread->set_thread_state(state); - - InterfaceSupport::serialize_thread_state_with_handler(thread); + thread->java_suspend_self_with_safepoint_check(); + } else { + SafepointMechanism::block_if_requested(curJT); } - SafepointMechanism::block_if_requested(curJT); - if (thread->is_deopt_suspend()) { thread->clear_deopt_suspend(); RegisterMap map(thread, false); diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index 4db0d7e4324..7d7fb7a3905 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -1348,10 +1348,16 @@ class JavaThread: public Thread { inline void clear_ext_suspended(); public: - void java_suspend(); - void java_resume(); - int java_suspend_self(); + void java_suspend(); // higher-level suspension logic called by the public APIs + void java_resume(); // higher-level resume logic called by the public APIs + int java_suspend_self(); // low-level self-suspension mechanics + private: + // mid-level wrapper around java_suspend_self to set up correct state and + // check for a pending safepoint at the end + void java_suspend_self_with_safepoint_check(); + + public: void check_and_wait_while_suspended() { assert(JavaThread::current() == this, "sanity check"); From 2df0f4b4dd924cd248e26422fc174dd02cf52102 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 20 Mar 2019 15:35:26 -0700 Subject: [PATCH 04/24] 8220249: fix headings in java.compiler Reviewed-by: erikj, darcy --- .../share/classes/java/io/DataInput.java | 4 +-- src/java.base/share/classes/java/io/File.java | 2 +- .../share/classes/java/lang/Character.java | 4 +-- .../share/classes/java/lang/ClassLoader.java | 4 +-- .../share/classes/java/lang/ModuleLayer.java | 4 +-- .../java/lang/doc-files/ValueBased.html | 2 +- .../doc-files/threadPrimitiveDeprecation.html | 32 ++++++++--------- .../java/lang/invoke/MethodHandle.java | 22 ++++++------ .../java/lang/invoke/MethodHandleInfo.java | 8 ++--- .../java/lang/invoke/MethodHandles.java | 10 +++--- .../java/lang/invoke/MutableCallSite.java | 4 +-- .../classes/java/lang/invoke/VarHandle.java | 12 +++---- .../java/lang/invoke/package-info.java | 14 ++++---- .../java/lang/module/Configuration.java | 4 +-- .../java/lang/module/package-info.java | 16 ++++----- .../classes/java/lang/reflect/Proxy.java | 4 +-- .../share/classes/java/net/Inet4Address.java | 6 ++-- .../share/classes/java/net/Inet6Address.java | 8 ++--- .../share/classes/java/net/InetAddress.java | 10 +++--- src/java.base/share/classes/java/net/URI.java | 14 ++++---- .../share/classes/java/text/ChoiceFormat.java | 4 +-- .../java/text/CompactNumberFormat.java | 10 +++--- .../share/classes/java/text/DateFormat.java | 4 +-- .../classes/java/text/DecimalFormat.java | 16 ++++----- .../share/classes/java/text/Format.java | 6 ++-- .../classes/java/text/MessageFormat.java | 8 ++--- .../share/classes/java/text/NumberFormat.java | 4 +-- .../classes/java/text/SimpleDateFormat.java | 6 ++-- .../share/classes/java/time/Instant.java | 4 +-- .../share/classes/java/time/ZoneId.java | 6 ++-- .../java/time/chrono/ChronoLocalDate.java | 4 +-- .../java/time/chrono/ChronoLocalDateImpl.java | 4 +-- .../java/time/chrono/ChronoLocalDateTime.java | 4 +-- .../java/time/chrono/ChronoZonedDateTime.java | 4 +-- .../classes/java/time/chrono/Chronology.java | 4 +-- .../java/time/format/DateTimeFormatter.java | 8 ++--- .../classes/java/time/temporal/IsoFields.java | 6 ++-- .../java/time/temporal/JulianFields.java | 6 ++-- .../classes/java/time/temporal/Temporal.java | 4 +-- .../java/time/temporal/WeekFields.java | 8 ++--- .../share/classes/java/util/Calendar.java | 12 +++---- .../share/classes/java/util/Formatter.java | 36 +++++++++---------- .../classes/java/util/GregorianCalendar.java | 8 ++--- .../share/classes/java/util/Locale.java | 32 ++++++++--------- .../classes/java/util/ResourceBundle.java | 16 ++++----- .../share/classes/java/util/Scanner.java | 6 ++-- .../classes/java/util/ServiceLoader.java | 20 +++++------ .../share/classes/java/util/TimeZone.java | 4 +-- .../java/util/doc-files/coll-designfaq.html | 28 +++++++-------- .../classes/java/util/regex/Pattern.java | 20 +++++------ .../java/util/spi/LocaleServiceProvider.java | 6 ++-- .../java/util/spi/ResourceBundleProvider.java | 8 ++--- 52 files changed, 250 insertions(+), 250 deletions(-) diff --git a/src/java.base/share/classes/java/io/DataInput.java b/src/java.base/share/classes/java/io/DataInput.java index 86d8d3eb9fd..303b612e8be 100644 --- a/src/java.base/share/classes/java/io/DataInput.java +++ b/src/java.base/share/classes/java/io/DataInput.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -48,7 +48,7 @@ package java.io; * may be thrown if the input stream has been * closed. * - *

Modified UTF-8

+ *

Modified UTF-8

*

* Implementations of the DataInput and DataOutput interfaces represent * Unicode strings in a format that is a slight modification of UTF-8. diff --git a/src/java.base/share/classes/java/io/File.java b/src/java.base/share/classes/java/io/File.java index 3dbbd1a291a..c5d67f42cf2 100644 --- a/src/java.base/share/classes/java/io/File.java +++ b/src/java.base/share/classes/java/io/File.java @@ -128,7 +128,7 @@ import sun.security.action.GetPropertyAction; * created, the abstract pathname represented by a File object * will never change. * - *

Interoperability with {@code java.nio.file} package

+ *

Interoperability with {@code java.nio.file} package

* *

The {@code java.nio.file} * package defines interfaces and classes for the Java virtual machine to access diff --git a/src/java.base/share/classes/java/lang/Character.java b/src/java.base/share/classes/java/lang/Character.java index dc713058615..1fa7d4ba977 100644 --- a/src/java.base/share/classes/java/lang/Character.java +++ b/src/java.base/share/classes/java/lang/Character.java @@ -44,7 +44,7 @@ import jdk.internal.misc.VM; * and for converting characters from uppercase to lowercase and vice * versa. * - *

Unicode Conformance

+ *

Unicode Conformance

*

* The fields and methods of class {@code Character} are defined in terms * of character information from the Unicode Standard, specifically the @@ -59,7 +59,7 @@ import jdk.internal.misc.VM; * {@code U+32FF}, from the first version of the Unicode Standard * after 11.0 that assigns the code point. * - *

Unicode Character Representations

+ *

Unicode Character Representations

* *

The {@code char} data type (and therefore the value that a * {@code Character} object encapsulates) are based on the diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java index 60e5a2f4aef..983158b2064 100644 --- a/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/src/java.base/share/classes/java/lang/ClassLoader.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 @@ -126,7 +126,7 @@ import sun.security.util.SecurityConstants; * duration of the class loading process (see {@link #loadClass * loadClass} methods). * - *

Run-time Built-in Class Loaders

+ *

Run-time Built-in Class Loaders

* * The Java run-time has the following built-in class loaders: * diff --git a/src/java.base/share/classes/java/lang/ModuleLayer.java b/src/java.base/share/classes/java/lang/ModuleLayer.java index 4be9e7ba087..183e55f68bf 100644 --- a/src/java.base/share/classes/java/lang/ModuleLayer.java +++ b/src/java.base/share/classes/java/lang/ModuleLayer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -120,7 +120,7 @@ import sun.security.util.SecurityConstants; * in this class causes a {@link NullPointerException NullPointerException} to * be thrown.

* - *

Example usage:

+ *

Example usage:

* *

This example creates a configuration by resolving a module named * "{@code myapp}" with the configuration for the boot layer as the parent. It diff --git a/src/java.base/share/classes/java/lang/doc-files/ValueBased.html b/src/java.base/share/classes/java/lang/doc-files/ValueBased.html index d5f31be7098..cbd554662dd 100644 --- a/src/java.base/share/classes/java/lang/doc-files/ValueBased.html +++ b/src/java.base/share/classes/java/lang/doc-files/ValueBased.html @@ -5,7 +5,7 @@ -

Value-based Classes

+

Value-based Classes

Some classes, such as java.util.Optional and java.time.LocalDateTime, are value-based. Instances of a diff --git a/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html b/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html index 37123b3cade..9d69fc6a17f 100644 --- a/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html +++ b/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html @@ -1,6 +1,6 @@
This document answers frequently asked questions concerning the design of the Java collections framework. It is derived from the large volume of traffic on the collections-comments alias. It serves as a design rationale for the collections framework. -

Core Interfaces - General Questions

+

Core Interfaces - General Questions

  1. Why don't you support immutability directly in the core collection interfaces so that you can do away with @@ -50,7 +50,7 @@ throw an UnsupportedOperationException?
  2. Why didn't you use "Beans-style names" for consistency?
-

Collection Interface

+

Collection Interface

  1. Why doesn't Collection extend Cloneable and Serializable?
  2. @@ -67,7 +67,7 @@ JDK have Enumeration (or Iterator) constructors?
  3. Why don't you provide an Iterator.add method?
-

List Interface

+

List Interface

  1. Why don't you rename the List interface to Sequence; doesn't "list" generally suggest "linked list"? Also, @@ -75,12 +75,12 @@ doesn't it conflict with java.awt.List?
  2. Why don't you rename List's set method to replace, to avoid confusion with Set.
-

Map Interface

+

Map Interface

  1. Why doesn't Map extend Collection?
-

Iterator Interface

+

Iterator Interface

  1. Why doesn't Iterator extend Enumeration?
  2. @@ -88,7 +88,7 @@ Enumeration? that allows you to look at the next element in an iteration without advancing the iterator?
-

Miscellaneous

+

Miscellaneous

  1. Why did you write a new collections framework instead of adopting JGL (a preexisting collections package from @@ -102,7 +102,7 @@ collections that send out Events when they're modified?

-

Core Interfaces - General Questions

+

Core Interfaces - General Questions

  1. Why don't you support immutability directly in the core collection interfaces so that you can do away @@ -204,7 +204,7 @@ case. Thus, we adopted the "traditional" JDK style rather than the Beans style.

-

Collection Interface

+

Collection Interface

  1. Why doesn't Collection extend Cloneable and Serializable? @@ -264,7 +264,7 @@ guarantee the order of the iteration.


-

List Interface

+

List Interface

  1. Why don't you rename the List interface to Sequence; doesn't "list" generally suggest "linked @@ -288,7 +288,7 @@ enough enshrined in the language that we'd stick with it.


-

Map Interface

+

Map Interface

  1. Why doesn't Map extend Collection? @@ -314,7 +314,7 @@ Lists.


-

Iterator Interface

+

Iterator Interface

  1. Why doesn't Iterator extend Enumeration? @@ -335,7 +335,7 @@ that everyone has to implement.


-

Miscellaneous

+

Miscellaneous

  1. Why did you write a new collections framework instead of adopting JGL (a preexisting collections diff --git a/src/java.base/share/classes/java/util/regex/Pattern.java b/src/java.base/share/classes/java/util/regex/Pattern.java index 92c964fdefa..ab5229a70f6 100644 --- a/src/java.base/share/classes/java/util/regex/Pattern.java +++ b/src/java.base/share/classes/java/util/regex/Pattern.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -77,7 +77,7 @@ import java.util.stream.StreamSupport; * such use. * * - *

    Summary of regular-expression constructs

    + *

    Summary of regular-expression constructs

    * * * @@ -378,7 +378,7 @@ import java.util.stream.StreamSupport; *
    * * - *

    Backslashes, escapes, and quoting

    + *

    Backslashes, escapes, and quoting

    * *

    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

    + *

    Character Classes

    * *

    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. * - *

    Line terminators

    + *

    Line terminators

    * *

    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. * - *

    Groups and capturing

    + *

    Groups and capturing

    * - *

    Group number

    + *

    Group number

    *

    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. * - *

    Group name

    + *

    Group name

    *

    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; * * - *

    Obtaining resource bundles from providers

    + *

    Obtaining resource bundles from providers

    * * The module declaration of the consumer module that calls one of the * {@code ResourceBundle.getBundle} factory methods to obtain a resource From ce6818a60bd2c112fbcfc5459d9d4e25818390e3 Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Thu, 21 Mar 2019 01:49:27 +0100 Subject: [PATCH 05/24] Added tag jdk-13+13 for changeset 83cace4142c8 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index b22db7c3c06..f43637f7385 100644 --- a/.hgtags +++ b/.hgtags @@ -550,3 +550,4 @@ b67884871b5fff79c5ef3eb8ac74dd48d71ea9b1 jdk-12+33 21ea4076a275a0f498afa517e9ee1b94a9cf0255 jdk-13+11 1d7aec80147a6d92b101a76aef92f3ddc88bedf4 jdk-13+12 b67884871b5fff79c5ef3eb8ac74dd48d71ea9b1 jdk-12-ga +83cace4142c8563b6a921787db02388e1bc48d01 jdk-13+13 From 87283a7568a9582ecd6d9be55f6b4b300bcc1cb2 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 20 Mar 2019 23:32:57 -0400 Subject: [PATCH 06/24] 8221180: Deprecate AllowJNIEnvProxy Reviewed-by: coleenp, dcubed --- src/hotspot/share/runtime/arguments.cpp | 1 + src/hotspot/share/runtime/globals.hpp | 2 +- .../hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index ca61eff25a8..95a0d93ab6a 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -530,6 +530,7 @@ static SpecialFlag const special_jvm_flags[] = { { "UseMembar", JDK_Version::jdk(10), JDK_Version::jdk(12), JDK_Version::undefined() }, { "CompilationPolicyChoice", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::undefined() }, { "FailOverToOldVerifier", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::undefined() }, + { "AllowJNIEnvProxy", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::jdk(15) }, { "ThreadLocalHandshakes", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::jdk(15) }, // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in: diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index facb94d02f0..b1daa5dba7a 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -861,7 +861,7 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G); "by the application (Solaris & Linux only)") \ \ product(bool, AllowJNIEnvProxy, false, \ - "Allow JNIEnv proxies for jdbx") \ + "(Deprecated) Allow JNIEnv proxies for jdbx") \ \ product(bool, RestoreMXCSROnJNICalls, false, \ "Restore MXCSR when returning from JNI calls") \ 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"}, From 762ce676b35d73f66efe68f9140c6b699ee92c5b Mon Sep 17 00:00:00 2001 From: David Holmes Date: Thu, 21 Mar 2019 03:00:28 -0400 Subject: [PATCH 07/24] 8221208: Backout JDK-8218446 Reviewed-by: iignatyev, rehn --- src/hotspot/share/runtime/thread.cpp | 87 ++++++++++++++++++---------- src/hotspot/share/runtime/thread.hpp | 12 +--- 2 files changed, 61 insertions(+), 38 deletions(-) diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp index 8e031347de1..07baa46cc20 100644 --- a/src/hotspot/share/runtime/thread.cpp +++ b/src/hotspot/share/runtime/thread.cpp @@ -2264,19 +2264,48 @@ void JavaThread::check_and_handle_async_exceptions(bool check_unsafe_error) { void JavaThread::handle_special_runtime_exit_condition(bool check_asyncs) { // - // Check for pending external suspend. + // Check for pending external suspend. Internal suspend requests do + // not use handle_special_runtime_exit_condition(). // If JNIEnv proxies are allowed, don't self-suspend if the target // thread is not the current thread. In older versions of jdbx, jdbx // threads could call into the VM with another thread's JNIEnv so we // can be here operating on behalf of a suspended thread (4432884). bool do_self_suspend = is_external_suspend_with_lock(); if (do_self_suspend && (!AllowJNIEnvProxy || this == JavaThread::current())) { + // + // Because thread is external suspended the safepoint code will count + // thread as at a safepoint. This can be odd because we can be here + // as _thread_in_Java which would normally transition to _thread_blocked + // at a safepoint. We would like to mark the thread as _thread_blocked + // before calling java_suspend_self like all other callers of it but + // we must then observe proper safepoint protocol. (We can't leave + // _thread_blocked with a safepoint in progress). However we can be + // here as _thread_in_native_trans so we can't use a normal transition + // constructor/destructor pair because they assert on that type of + // transition. We could do something like: + // + // JavaThreadState state = thread_state(); + // set_thread_state(_thread_in_vm); + // { + // ThreadBlockInVM tbivm(this); + // java_suspend_self() + // } + // set_thread_state(_thread_in_vm_trans); + // if (safepoint) block; + // set_thread_state(state); + // + // but that is pretty messy. Instead we just go with the way the + // code has worked before and note that this is the only path to + // java_suspend_self that doesn't put the thread in _thread_blocked + // mode. + frame_anchor()->make_walkable(this); - java_suspend_self_with_safepoint_check(); + java_suspend_self(); + + // We might be here for reasons in addition to the self-suspend request + // so check for other async requests. } - // We might be here for reasons in addition to the self-suspend request - // so check for other async requests. if (check_asyncs) { check_and_handle_async_exceptions(); } @@ -2395,7 +2424,6 @@ void JavaThread::java_suspend() { // to complete an external suspend request. // int JavaThread::java_suspend_self() { - assert(thread_state() == _thread_blocked, "wrong state for java_suspend_self()"); int ret = 0; // we are in the process of exiting so don't suspend @@ -2443,27 +2471,6 @@ int JavaThread::java_suspend_self() { return ret; } -// Helper routine to set up the correct thread state before calling java_suspend_self. -// This is called when regular thread-state transition helpers can't be used because -// we can be in various states, in particular _thread_in_native_trans. -// Because this thread is external suspended the safepoint code will count it as at -// a safepoint, regardless of what its actual current thread-state is. But -// is_ext_suspend_completed() may be waiting to see a thread transition from -// _thread_in_native_trans to _thread_blocked. So we set the thread state directly -// to _thread_blocked. The problem with setting thread state directly is that a -// safepoint could happen just after java_suspend_self() returns after being resumed, -// and the VM thread will see the _thread_blocked state. So we must check for a safepoint -// after restoring the state to make sure we won't leave while a safepoint is in progress. -void JavaThread::java_suspend_self_with_safepoint_check() { - assert(this == Thread::current(), "invariant"); - JavaThreadState state = thread_state(); - set_thread_state(_thread_blocked); - java_suspend_self(); - set_thread_state(state); - InterfaceSupport::serialize_thread_state_with_handler(this); - SafepointMechanism::block_if_requested(this); -} - #ifdef ASSERT // Verify the JavaThread has not yet been published in the Threads::list, and // hence doesn't need protection from concurrent access at this stage. @@ -2495,11 +2502,33 @@ void JavaThread::check_safepoint_and_suspend_for_native_trans(JavaThread *thread // threads could call into the VM with another thread's JNIEnv so we // can be here operating on behalf of a suspended thread (4432884). if (do_self_suspend && (!AllowJNIEnvProxy || curJT == thread)) { - thread->java_suspend_self_with_safepoint_check(); - } else { - SafepointMechanism::block_if_requested(curJT); + JavaThreadState state = thread->thread_state(); + + // We mark this thread_blocked state as a suspend-equivalent so + // that a caller to is_ext_suspend_completed() won't be confused. + // The suspend-equivalent state is cleared by java_suspend_self(). + thread->set_suspend_equivalent(); + + // If the safepoint code sees the _thread_in_native_trans state, it will + // wait until the thread changes to other thread state. There is no + // guarantee on how soon we can obtain the SR_lock and complete the + // self-suspend request. It would be a bad idea to let safepoint wait for + // too long. Temporarily change the state to _thread_blocked to + // let the VM thread know that this thread is ready for GC. The problem + // of changing thread state is that safepoint could happen just after + // java_suspend_self() returns after being resumed, and VM thread will + // see the _thread_blocked state. We must check for safepoint + // after restoring the state and make sure we won't leave while a safepoint + // is in progress. + thread->set_thread_state(_thread_blocked); + thread->java_suspend_self(); + thread->set_thread_state(state); + + InterfaceSupport::serialize_thread_state_with_handler(thread); } + SafepointMechanism::block_if_requested(curJT); + if (thread->is_deopt_suspend()) { thread->clear_deopt_suspend(); RegisterMap map(thread, false); diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index 7d7fb7a3905..4db0d7e4324 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -1348,16 +1348,10 @@ class JavaThread: public Thread { inline void clear_ext_suspended(); public: - void java_suspend(); // higher-level suspension logic called by the public APIs - void java_resume(); // higher-level resume logic called by the public APIs - int java_suspend_self(); // low-level self-suspension mechanics + void java_suspend(); + void java_resume(); + int java_suspend_self(); - private: - // mid-level wrapper around java_suspend_self to set up correct state and - // check for a pending safepoint at the end - void java_suspend_self_with_safepoint_check(); - - public: void check_and_wait_while_suspended() { assert(JavaThread::current() == this, "sanity check"); From 26358daaee398ef8d548562a918bef8abc77331b Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Thu, 21 Mar 2019 09:16:58 +0100 Subject: [PATCH 08/24] 8172695: (scanner) java/util/Scanner/ScanTest.java fails Reviewed-by: smarks, bpb --- test/jdk/java/util/Scanner/ScanTest.java | 30 +++++++----------------- 1 file changed, 8 insertions(+), 22 deletions(-) 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); } } From 2c4b9e0778e170a17b04217bee66bb6c4fb18c0c Mon Sep 17 00:00:00 2001 From: Jie Fu Date: Thu, 21 Mar 2019 04:55:20 -0400 Subject: [PATCH 09/24] 8220658: Improve the readability of container information in the error log Reviewed-by: dholmes, bobv --- src/hotspot/os/linux/os_linux.cpp | 67 +++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 443f01577bc..ecbbecc776f 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -2140,46 +2140,87 @@ void os::Linux::print_container_info(outputStream* st) { st->print("container (cgroup) information:\n"); const char *p_ct = OSContainer::container_type(); - st->print("container_type: %s\n", p_ct != NULL ? p_ct : "failed"); + st->print("container_type: %s\n", p_ct != NULL ? p_ct : "not supported"); char *p = OSContainer::cpu_cpuset_cpus(); - st->print("cpu_cpuset_cpus: %s\n", p != NULL ? p : "failed"); + st->print("cpu_cpuset_cpus: %s\n", p != NULL ? p : "not supported"); free(p); p = OSContainer::cpu_cpuset_memory_nodes(); - st->print("cpu_memory_nodes: %s\n", p != NULL ? p : "failed"); + st->print("cpu_memory_nodes: %s\n", p != NULL ? p : "not supported"); free(p); int i = OSContainer::active_processor_count(); + st->print("active_processor_count: "); if (i > 0) { - st->print("active_processor_count: %d\n", i); + st->print("%d\n", i); } else { - st->print("active_processor_count: failed\n"); + st->print("not supported\n"); } i = OSContainer::cpu_quota(); - st->print("cpu_quota: %d\n", i); + st->print("cpu_quota: "); + if (i > 0) { + st->print("%d\n", i); + } else { + st->print("%s\n", i == OSCONTAINER_ERROR ? "not supported" : "no quota"); + } i = OSContainer::cpu_period(); - st->print("cpu_period: %d\n", i); + st->print("cpu_period: "); + if (i > 0) { + st->print("%d\n", i); + } else { + st->print("%s\n", i == OSCONTAINER_ERROR ? "not supported" : "no period"); + } i = OSContainer::cpu_shares(); - st->print("cpu_shares: %d\n", i); + st->print("cpu_shares: "); + if (i > 0) { + st->print("%d\n", i); + } else { + st->print("%s\n", i == OSCONTAINER_ERROR ? "not supported" : "no shares"); + } jlong j = OSContainer::memory_limit_in_bytes(); - st->print("memory_limit_in_bytes: " JLONG_FORMAT "\n", j); + st->print("memory_limit_in_bytes: "); + if (j > 0) { + st->print(JLONG_FORMAT "\n", j); + } else { + st->print("%s\n", j == OSCONTAINER_ERROR ? "not supported" : "unlimited"); + } j = OSContainer::memory_and_swap_limit_in_bytes(); - st->print("memory_and_swap_limit_in_bytes: " JLONG_FORMAT "\n", j); + st->print("memory_and_swap_limit_in_bytes: "); + if (j > 0) { + st->print(JLONG_FORMAT "\n", j); + } else { + st->print("%s\n", j == OSCONTAINER_ERROR ? "not supported" : "unlimited"); + } j = OSContainer::memory_soft_limit_in_bytes(); - st->print("memory_soft_limit_in_bytes: " JLONG_FORMAT "\n", j); + st->print("memory_soft_limit_in_bytes: "); + if (j > 0) { + st->print(JLONG_FORMAT "\n", j); + } else { + st->print("%s\n", j == OSCONTAINER_ERROR ? "not supported" : "unlimited"); + } j = OSContainer::OSContainer::memory_usage_in_bytes(); - st->print("memory_usage_in_bytes: " JLONG_FORMAT "\n", j); + st->print("memory_usage_in_bytes: "); + if (j > 0) { + st->print(JLONG_FORMAT "\n", j); + } else { + st->print("%s\n", j == OSCONTAINER_ERROR ? "not supported" : "unlimited"); + } j = OSContainer::OSContainer::memory_max_usage_in_bytes(); - st->print("memory_max_usage_in_bytes: " JLONG_FORMAT "\n", j); + st->print("memory_max_usage_in_bytes: "); + if (j > 0) { + st->print(JLONG_FORMAT "\n", j); + } else { + st->print("%s\n", j == OSCONTAINER_ERROR ? "not supported" : "unlimited"); + } st->cr(); } From 0f0d24ebb412918acdb24b532c7f5569cb71d2b8 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Thu, 21 Mar 2019 21:17:54 +0900 Subject: [PATCH 10/24] 8220784: hsdis cannot be built with MinGW64 Reviewed-by: iklam, dholmes --- src/utils/hsdis/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 From 0814229ebc94f6821789391df29c34610164b47f Mon Sep 17 00:00:00 2001 From: Martin Balao Date: Thu, 21 Mar 2019 01:51:25 -0300 Subject: [PATCH 11/24] 8220753: Re-introduce the test case for TLS 1.2 algorithms in SunPKCS11 crypto provider Reviewed-by: xuelei --- .../security/pkcs11/tls/tls12/TestTLS12.java | 474 ++++++++++++++++++ .../sun/security/pkcs11/tls/tls12/cert8.db | Bin 0 -> 65536 bytes .../jdk/sun/security/pkcs11/tls/tls12/key3.db | Bin 0 -> 32768 bytes .../sun/security/pkcs11/tls/tls12/keystore | Bin 0 -> 2113 bytes .../jdk/sun/security/pkcs11/tls/tls12/nss.cfg | 19 + .../sun/security/pkcs11/tls/tls12/secmod.db | Bin 0 -> 32768 bytes 6 files changed, 493 insertions(+) create mode 100644 test/jdk/sun/security/pkcs11/tls/tls12/TestTLS12.java create mode 100644 test/jdk/sun/security/pkcs11/tls/tls12/cert8.db create mode 100644 test/jdk/sun/security/pkcs11/tls/tls12/key3.db create mode 100644 test/jdk/sun/security/pkcs11/tls/tls12/keystore create mode 100644 test/jdk/sun/security/pkcs11/tls/tls12/nss.cfg create mode 100644 test/jdk/sun/security/pkcs11/tls/tls12/secmod.db 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 0000000000000000000000000000000000000000..b80a6e7e4a3b20898a8c405b0af22dec102e9626 GIT binary patch literal 65536 zcmeI*eOwLs9tZH5Ij2+U;gp_`(u2^0n$xp7dPWj@lyaq$PKoqzN=mFwl+{vdU0qkJ zs7<+6dx=!8&?*sS?{>pQ+j__ng;ZPF?wodc<@LJv<^HiR`r|Y6n%B&4W?nPj*L&tW z|9!thaMT0@K~Myt)IktV%qF2o5G1pbEQHMO8_e<19jwvy=plkF+5U6%mix?FGD*&n zEFXQ6`7NH0eqY=W0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bcLhY3)Q{f@nk zPaJzMILI5;@S+w0knV1fVyAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX?}I{_KyFVhsk zA&5l5T9JStGMSl~>_obJTD*-XN6T_p{%np4}N55mzHso%+zNDhfbq5(P`v;iftG6;0dk3ku}P2&*)bmNwyU634&8m z9yKx*Mn{;&Z-_Qs9kZU+)=;2%G>>OP(>z-%I*1usGehg&hvOtlalu$UQi@=ScQb-J zDY2M1;c;L^HF^G;PHXfiF8&y2dTeWoey`+Pc#H znnqWf=bXQ%{8YPd^!R=b4pok>cee6P1?Plq(PFD()W{+$GFfPq9dX92*|!G#+hcGE3H5F%-~)`f@ZLX-x5-4w%4wV`Nw9|)|j$q=ap=X4H*bO z*(Be&KO$_sW(wKwG2MN^<>BJx1;CGZ}~uuzIq=&5&p}&CdpLty-X!Oad6`=qA{t-8XvhQ z!+cDa2}SXdG0_CUalFHC;a}h%;3xC#`G$P^1-2_~|FG@?xDW&&009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=<4xdQ=`_npQaa7zGv(8ROzE_wkXw!;&6G}Gw`H@&Tj8|14O1;`W%;&n z+FVjREg6oF;!URdypmZ=-tv*mV49?8`ps5fvDSu(hCb~c`KDbDI{TC>efZsOM4h%{ z>S^y8k@HqM>3I(Y&fUFyu=djHYP#?00sp8rv3;tRWz5U)kji!Yy}m9kD0s|HQPR7( zw5F`>*UEa$0sDZ?`qC0LE_-NO-#;&D*HKn}DnaTw=6xGp9XA%V8FjzZV@>|*hCA6n zsS$Z0UfF8;a!n_4tI`fX-7eR&eClgSX#E|9>Hj(~_ukdBfBTd5nSiR~z2!B7c2ClN z3GkGgE1eeM9T<>R{X^i=M{&|h;?#T&vyJ!h$_R5r_+@48&l!B^k(h2Q4gvwkc( zu5Em>WJ6AL(N?)ZU8~R+L!q0<>Gn;j*GH;W(R*I+`Cfhg!2RXL79E|1UD8upzSBwZ<*HX? z$~Y~UDgS1us?6}hq2k5MG&K^$XXTp7zMC`b_~3V|S&sUAP_9=|_^;tyeuJ zn70-72W{RL+P!&N$B#2_4(`>myIvjhC@9Zx)vZHI%L4A4Uh?R@cb;WN&?c1Xe6zTu zoCURCTJ+7iCt4wt_N-3dM5#`GBByuBpuej$>yUwGGJ9KHk8#)A;_pw>1>t`de=8D% zXw527ykJ%Q8iBc$H9_bTgrW;Qji*Ixjy6zGQS}jq>9`9Lbo_+z2|7M8F$p@Z&a4lf zAwv;_?g!7J-oHEZ$swF1GxdT{WIi{~nDl5ZWKkqVQA|{08aBu=-<=NyDe0xav*FPe zv^meh!fFoFOTp57%<#h(NF(*e-c-`(AdTb_OjHx7G?FChUYT&~L*{!XHGZiqtPtyk z*$hVpPFb6je9G;5v}TxoxlOA;w{o{fFRP!-|JJR>vE8h1#K7g$FAWZby;V|K0*53{ z@Xn-S{bQ#_+TzPYHgZF+@oJ0QFP{A?=g8w9IvdkB+Dv_#S)TrNIj=)BGez_6);dk@ z$d0_JvjPNm!}1C`eA}4z{S$kxHRT>oSBnVoF6*iCk%@h@U0$0z^GZ+Zsv*lrzoc0X z*88qhj#MSOO;Wur-BLEcayZ!eVg2)Nr{1itR~8|W8g|LmJDM~X8|dqP)&11|ul(x4F*o_Uq4ncI`XvCHTB_^1m0>$jz=9YU#{8`(2b+UUgZcX@t5X$LJze zQLOEMvUySVfJudinMgS=*@}LxH+wjQnNy>@6|2W zi4m)eEcZAo_tEq2<}B$t){+=MZ!*Uy)MJ}TfeAOI%VWYE**V9bPw1w?LK|izYa40` z^E=p^%hJ474wP{f=C~T%x{|r#PDNgc!rk1G%Iwcqsw`?qzkRB;vd3#u<4xz1I5VT} z292(Wo6f00e*l5C8%|;J-!y z#&f{)ooAhAmS>13k0*{N?;58yXBqoz_EXS+01yBIKmZ5;0U!VbfB+Bx0zd!=00AHX z1b_e#00KY&2mk>f00jOs0;KdLkn?Af`k&Pm>@)T-`?(PAL8Ky}P$>Zz^|@$`=zRnU z4LJ#^6f+t9U(Z2FNXQ~cCMTnOt3Uq08OWv4m-<$8mDxrXPI5k{2tNpls$%K#si
      UGRTvzG`G0+ z-~mpWFTHUgmPDK-tIM}(6?wOY-BywF^;9Hst5faa5ict&8 z`D<{F;WxZNhIA}1A5bV?6Q(&iYA6$JFDTYEL9+UUlMwh=M`7VZ(%h$0U4f=wJYyp! z+Na%?jYvom#{0FXWG3?WErQeRHiCH;=7lE@A95+YZS+{ONEfx4D!5)|`k_{D>1Sq| zRhMJ3Ld@v3PzKfbM^a9|G86y*WaeMb{mxA2T}p-C%TGU{i-j*W)YWM=_XZ_uW;X5V zi!-IZ@j6$XWO795iPOr6O=3Embf5TI+<7&4tDKr8dlPd#4X4xz6Nx#lv99Ndh7S^L zcUvpz@~Ti@e6cN;XPEwcnzt4iCGA)pn|Fl=nm;`~ITK(Qtzp4v+JhZQ#ABJ8v(0s+ zzi4|5biREd5$XqR+-x6d`pASim~X2M^_isIM)d?!Shq+o!zv-HSI%r zFjMMYHoJXWE1xL!(VDNRQ~j?z?qZjMXpi`B^pUfw)sAWVm~3$DR*E7z3`dGTDuy67 zm%~%S33)Kc9Jzgq%glszOC^;+SrI~!WS`<;u+P{R272*o_i1VUar#_2nKWFz^%ULG zW0vv(`|g$yPNkBE$~9r(yoGK>lBv^Duu-LsnVz#YIXb2JQF2meF`>tpAdhE|53e++ z4ybxkbh%}nNPA(VlZLnN58s%%{N3T)RfGU8G*r1>ZU?nV`uO~a8Z$?a-TA}Ac_wzV zs%25h6eZDWAuF_Hj<_QUtW&-4W=_UQGz_;m6Xx1R1-vU13+h(d>Tj|1c691v>L%>*W zm1qbTEovwDB?H6z^wWJN6a~_g`IT;Xk4sun;JuFi-8_*t@;V;ogr1gy@cs+r-_ZET z9k@6fQ6#}WZz0*F24gCl-h;G@{xul>1_)s+Jbang)BGv7?VEF%VD)? zdrBGUP0$q#hkUddr-!lF_}f3fASF1>U0UC@!w#{hNT%ahCdmK(sXJX*>#XF5L-?{@ zw&r`$m3Z2Ed;5Ff93p~$>n7oC>*hmhg2j0| zd$>cOJP`I>_Eq-X|C)*fa1kH?1b_e#00KY&2mk>f00e*l5C8%|00;m9AOHk_01yBI zKmZ5;fqzzj6he!0vcY-V+ITzJ%E-z8e3T{IlM?yA^KB{PDE#AD=cxM|?K-ND;4sq|^M{^ak5edUdfmTygIk3ICvkrE$ovBgt;z8HlC@zlu zXctP%(WmG{=k%}g#lA@8-sG*jVwz!Q6=X7S3{!zg((dcG<- zvXGob5vd&;hmm1-u4MMHHCIOC{W7kTWW6$}t(zDNN1|p!>k~cpOj@?>3jdf=eWJAE ztQw2Obe%U+Ca$Hz$~EnKUf_g(r1p)eqNV*bzc8IJi_UC~ZZnbXnGt*6+m@rRMu!<( zN!}GOZ*M27?7d(xXy`X}(_9iBhKJ&X+M^@;4j-=UJ5A7CT-3i17j^a95ow71v#)Um z5V(bGl^ns0IiZlcFP{Rj!E<7&8Eb%5Xx@Q7`s78d)&fr?*v%*P@@0*yE9 zG2%l~kAx z|AEnzZ(3lyXpj@iN@8r7nWx;ueNY)Sq(pwoty@lH9_eUdn(sf+!XsNBrL~GjXdaKc z?Nrwg{ku!tmN7%lNq0q9HY{m~!(luadE|u$+P9J&?|$yWMtLNzoSYN|&%Fp3NI5Td z#cRTeu8z{dNh*(ISySh1dCvZsYnFwvAL5h@B#$InpyAEWcx!l3@?K<(eSx8p@QZJR zhIXL*l2d|gL5qsyT=p^9ajUWTSZUb7O-ynYFdn>o{*@L(``UegABkYdWrixjaUCQsf1d%=m9Ywqr)GAgGv z6eRV&aY$CYkY%XBQW1Vj!p|E&uOmGktUk0oS`nDlpycDVpRXc+55bbhE@{q1*Fdf+ zpyBF?x`AyifuDdm?`OJ^vc(Qfn<%PQuCPMjX(Hq z$L|a!S+PAAmX#4-yniVb9eS;S5PgLx!);sVPt+#B+xea2gXq7^wySEIkG|d(r|ZI~ z>jd+UGSL8VB8!WNG^Cj5DjkoyL0uNL@jGzMPF! z)sFmh<2hnQ5pLYInV)6|A9B-ywa8TvC#}L($@~g^flXL|Y$`39AojCl?c_gGwg#dC z0U!VbfB+Bx0zd!=00AHX1b_e#00KY&2mk>f00e*l5C8%|00;m9AOHk_01yBI|0;pM E0~ESv82|tP literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f1db334f005c756d7f76b88d86bc23ae2383e36b GIT binary patch literal 2113 zcmah}X*iS%8=iM&jCD-L5?Qh)V|$0e5XMflAaXhsW1q3r5avi}vZa(QDY8dXY9!ml zNgqC{o}ds>w2E&y6@|{cb0aRAP@+255Rwcq=foX zqKUrIp+o~C<2^PA4^uRRKm?#54ZZ`4BSf?j035(TB>+GG0;j>hlElNwg~6$x(Hg09 zMx&wHPe-~B3pa`<>gc_(Vls0d!wAjq25QtbJF;DjPjKGJ#vCXbE}wq$YPrRX`sYC$ z#!9gB#y-P=64~76e{YflKV;pId#15+NZR;g#Qo-;FCwOlt3WA!$D2Iw&!hWL<`6oJ zGU>D`aLa4WQq5dGH;oYP&_80C=O>_=<0#MU-WSLI8N6maGii=H9OV@A8QnZqeP^iQ zFs3zlVVo*ZW0tA{(EK?tYAh4-?b(xweYjA7dqu&&nK{$XeAm3QQ1k zlf&7K6HDu3TYK+B&kw0g6|4GSyx12MfkEzl&E!Ay{raA0mA{ZVo5;@{aszZ&LGD5Y z0k-8b^bcXM2k3*h#$u&N#2b-p@99)-c_{IwX<0!H$cGM*W~P($k~*$0CZ!CoHFGI4 z38%k#B87V!$PT-X#R4BDO=Li}N+$A;C~m5u@CyCm99Hg_m!&J*XXrd)F>AAu0OLSi zt?Hwa^8%VOKU*iY#d~Yz6qKEK9hW!f#!12}SGJzgbjNM56s`~Z-Ma3fhu+KcEu+^- zv#VCLE+a%+Y}!{r`g8{SV)<9WYw{G`x-EG1E=R+;Q*d(_9 z%|^@ZY)njEG?nay4kH6AY%T&{?RoqKtI#&e_r* zPRWiC^ATGG6i2s4i7e(6Z%qW832B$g> zC@d2%&DnylK89Oc`fW@PDVc5YX0x7Hc;O%a0OH;pU;DJ2r)wXz9dnsvJ0m6Qi+B{! zZ76m`I43;xZA(Ai;6zrgq*=Swi`b; z^Lv);69e9|)fZ2G74Mvn*|6i22nBkrakmdfR2OlHcD#wpK|?R3nt7EwM|Nw~|FY0^ zYC`{oP$_Re1ZW$LIk)KvrLPBo~52+ z)=dos7~Sfa!zb7p)1jc?j@)HS@ja?ctI`Jf(JWSZVDuYD*Ndb-p08JSsy8>be8dgnEz5ByH}`7KQw7$?S+D z{TV*mt2YI4-pRq7@a`muTv*v}%R_DMPCxPR{FONIqmQ!C(Ry39g5?BBfka%Es(Sv- z+gEf`#x?aQ|4t7~Ds3K#if>-QzPrYBXY-qaYA^?Ktko@imu=dssQ3>@`||2xwzyO6 zo@j&BYRhKDV%MdJ86j%0fM>_-;|iBv@=32kzh!J6b-Xa*XDaOm^ZMrL|COY`Z+b?c z>0V{7fHde5NCViVFem_pLd9)BBtjUI>Xf>H1OQP12zU^y2+AX1o^Y6?lzUL1vJ){z z*&`@AM%g_oDn{AX8dTbk#F}71L(l+gXlP{m`+g+O;Ft0LFQ5UczaHIdWEc%VLH529 zfzki~(y^w4>hg0q7T=RA5mbLwHPB?6bmjm#p4wp7A1NQG#xP+MRhlxL*I^q#QLSAI z;gddpSHq^^N4I6^I#b{l(J~%!?s|NsT1~_5NHoJQ4&~p6ZL4rYujFW*YndVqk_T?YgH2)c$|1HaDPRZ1_f&)TPxjWf|u1)hmYl_E^9+! z00gKo1hJq5Lf9|W2}s?v0RT8028FOe)Lt}-l5imq0RX#D00N5sL!kaqft_D%-OF;% zRsf=G+}Jmcs}R$cSlBkx{}N({8t5R5f4{t7%YWudOn)Tz@o0;vZp+r-Tt;hW_*F5f z(>;12G6V#s9a>+h1jgU_nofxhDq+!C#8lYy*|NwtXrO=h zA*zy=d{EI8{1Tn!dUlhJLYmrYjP+)CbL#I_At!RGnr^3`m2~M&8E;@W@mytlMy;zZ z=wrTh?_UfV734kT77xx#p`_i)X4X<3IbVIfS{3YWUc^d{SM0UDO^jVvRxU}ZOa4La Wq>r5PWrVpzo_q;=7vIO1>-Y~{1G!KD literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..5418eea41d65e3e7e740b5387f473a31fc55e48c GIT binary patch literal 32768 zcmeI)%Su8~6adhZK{yGTG}RLgE=>e;d}$B_5{2Lw__&H>8dgw)pmFoQFQV@VyLyG1 zG?Tzs8#d>)Igj-LC+zHZLI|Z0_TEE?c{l8au$4E94CPfPUtdmaFWco(QS>@_`pD-N zv8Y+(pGUd4&!3;`Kmr5^5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAh0%pQuVFcs2)`tm2Tx`ZM)it009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0Rja6yTDF};brURkL|~+Cl_-Em+f|JPVTbV zq%)3Z%~m_M&QII%uwIWB)BgQ9%gaxD)5%~o?2l$?QcGelo87f$* Date: Thu, 21 Mar 2019 10:47:48 -0400 Subject: [PATCH 12/24] 8221096: Description of -XX:+PrintFlagsRanges is incorrect Remove the phrase: and exit VM Reviewed-by: lfoltan --- src/hotspot/share/runtime/globals.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index b1daa5dba7a..23a36ea3dbb 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -1234,7 +1234,7 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G); "exit") \ \ product(bool, PrintFlagsRanges, false, \ - "Print VM flags and their ranges and exit VM") \ + "Print VM flags and their ranges") \ \ diagnostic(bool, SerializeVMOutput, true, \ "Use a mutex to serialize output to tty and LogFile") \ From 04a50576cf3e03d48ce3302cfd203168160cc29a Mon Sep 17 00:00:00 2001 From: Adam Petcher Date: Thu, 21 Mar 2019 13:10:37 -0400 Subject: [PATCH 13/24] 8221172: SunEC specific test is not limited to SunEC Fixing a minor test bug in the SignatureDigestTruncate regression test Reviewed-by: mullan --- test/jdk/sun/security/ec/SignatureDigestTruncate.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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(); From fd14375ae262f68cb9f76b0e45d1627438e37c75 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Thu, 21 Mar 2019 17:38:41 +0000 Subject: [PATCH 14/24] 8221259: New tests for java.net.Socket to exercise long standing behavior Reviewed-by: chegar --- test/jdk/java/net/Socket/AsyncShutdown.java | 137 +++++ test/jdk/java/net/Socket/ConnectionReset.java | 218 ++++++++ test/jdk/java/net/Socket/Timeouts.java | 497 ++++++++++++++++++ test/jdk/java/net/Socket/UdpSocket.java | 75 +++ 4 files changed, 927 insertions(+) create mode 100644 test/jdk/java/net/Socket/AsyncShutdown.java create mode 100644 test/jdk/java/net/Socket/ConnectionReset.java create mode 100644 test/jdk/java/net/Socket/Timeouts.java create mode 100644 test/jdk/java/net/Socket/UdpSocket.java 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"); + } + } + } +} From af5c78efffca2e953e0f4b27d64821aa998aed3e Mon Sep 17 00:00:00 2001 From: Bob Vandette Date: Thu, 21 Mar 2019 14:40:04 -0400 Subject: [PATCH 15/24] 8220674: [TESTBUG] MetricsMemoryTester failcount test in docker container only works with debug JVMs Reviewed-by: sspitsyn, sgehwolf --- .../internal/platform/docker/MetricsMemoryTester.java | 11 ++++++++--- .../platform/docker/TestDockerMemoryMetrics.java | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) 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"); From bd4dd311fd783cefae5813d853a634719c44e201 Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Thu, 21 Mar 2019 11:58:00 -0700 Subject: [PATCH 16/24] 8211941: Enable checking/ignoring of non-conforming Class-Path entries Reviewed-by: alanb, mchung --- .../share/classes/jdk/internal/loader/URLClassPath.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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. */ From 9f5bcd46f036aa29ced5160fafa3eca0c999f5bf Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Thu, 21 Mar 2019 12:28:58 -0700 Subject: [PATCH 17/24] 8170494: JNI exception pending in PlainDatagramSocketImpl.c Reviewed-by: clanger, vtewari --- src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c | 1 + 1 file changed, 1 insertion(+) 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; } From ed5a2f1e06e11529a919fafe6990d796995c6f9c Mon Sep 17 00:00:00 2001 From: Daniil Titov Date: Thu, 21 Mar 2019 19:56:31 +0000 Subject: [PATCH 18/24] 8218401: WRONG_PHASE: vmTestbase/nsk/jvmti test crash Reviewed-by: sspitsyn, jcbeyler --- .../breakpoint001/breakpoint001.cpp | 21 ++++++-- .../FramePop/framepop002/framepop002.cpp | 53 ++++++++++++++++++- .../singlestep003/singlestep003.cpp | 53 ++++++++++++++++++- 3 files changed, 121 insertions(+), 6 deletions(-) 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; } From 901e797c0c8c29c7496b797e8b2ad45b4017b577 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Thu, 21 Mar 2019 13:32:08 -0700 Subject: [PATCH 19/24] 8221270: Duplicated synchronized keywords in SSLSocketImpl Reviewed-by: mullan --- .../share/classes/sun/security/ssl/SSLSocketImpl.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) 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 From 9f0b9da2d7c0478277cd4912881cad42cfff29a9 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Thu, 21 Mar 2019 14:18:34 -0700 Subject: [PATCH 20/24] 8221273: put sun/security/pkcs11/tls/tls12/TestTLS12.java on ProblemList.txt Reviewed-by: mullan --- test/jdk/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 64a0e35afb7..6d38d852bd9 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 ############################################################################ From 29843b4dfb9348b0e7abaf0f204ab42e1e139066 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Thu, 21 Mar 2019 22:37:36 +0100 Subject: [PATCH 21/24] 8221278: Shenandoah should not enqueue string dedup candidates during root scan Reviewed-by: shade --- .../gc/shenandoah/shenandoahConcurrentMark.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp index 989c8ae80a5..b980a5457d4 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp @@ -48,7 +48,7 @@ #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" -template +template class ShenandoahInitMarkRootsClosure : public OopClosure { private: ShenandoahObjToScanQueue* _queue; @@ -57,7 +57,7 @@ private: template inline void do_oop_work(T* p) { - ShenandoahConcurrentMark::mark_through_ref(p, _heap, _queue, _mark_context); + ShenandoahConcurrentMark::mark_through_ref(p, _heap, _queue, _mark_context); } public: @@ -99,13 +99,8 @@ public: ShenandoahObjToScanQueue* q = queues->queue(worker_id); - if (ShenandoahStringDedup::is_enabled()) { - ShenandoahInitMarkRootsClosure mark_cl(q); - do_work(heap, &mark_cl, worker_id); - } else { - ShenandoahInitMarkRootsClosure mark_cl(q); - do_work(heap, &mark_cl, worker_id); - } + ShenandoahInitMarkRootsClosure mark_cl(q); + do_work(heap, &mark_cl, worker_id); } private: From 59a025d90b96f14801516f52f6ad8546c5a2c77e Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 15 Mar 2019 09:57:42 +0100 Subject: [PATCH 22/24] 8220714: C2 Compilation failure when accessing off-heap memory using Unsafe Reviewed-by: vlivanov, roland --- src/hotspot/share/opto/library_call.cpp | 2 +- .../compiler/TestUnsafeOffheapSwap.java | 109 ++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/gc/shenandoah/compiler/TestUnsafeOffheapSwap.java diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 8931ce33b5b..70a5675ceed 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -2407,7 +2407,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c } // Can base be NULL? Otherwise, always on-heap access. - bool can_access_non_heap = TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop)); + bool can_access_non_heap = TypePtr::NULL_PTR->higher_equal(_gvn.type(base)); if (!can_access_non_heap) { decorators |= IN_HEAP; 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); + } + } +} From 1925ff3540e130a9b30ff3c321d2763f19ab637a Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Fri, 22 Mar 2019 03:04:09 +0000 Subject: [PATCH 23/24] 8220451: jdi/EventQueue/remove/remove004 failed due to "ERROR: thread2 is not alive" 8220456: jdi/EventQueue/remove_l/remove_l004 failed due to "TIMEOUT while waiting for event" Reviewed-by: sspitsyn, dcubed, gadams --- .../nsk/jdi/EventQueue/remove/remove004/TestDescription.java | 4 ++-- .../jdi/EventQueue/remove_l/remove_l004/TestDescription.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) 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}" */ From 1a48fa0fb7c97fe0eb2732df3fdfbaf6c27bf5b6 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Fri, 22 Mar 2019 08:56:30 +0100 Subject: [PATCH 24/24] 8200286: (testbug) MOptionTest test fails with java.lang.AssertionError: Classfiles too old! Reviewed-by: stuefe, jjg --- .../tools/javac/modules/MOptionTest.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) 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())
    Regular expression constructs, and what they match