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