# HG changeset patch
# User duke
# Date 1499279878 -7200
# Node ID a9714a11e787ed3ebca7481dd45d79eb0738b32e
# Parent 97f4fef2d420956087d5b046a8ca10c95bad6eea# Parent 2845f18bee3d78dce43fe2bb2f20cc32c4a0d97c
Merge
diff -r 97f4fef2d420 -r a9714a11e787 .hgtags-top-repo
--- a/.hgtags-top-repo Thu Jun 11 20:20:05 2015 -0700
+++ b/.hgtags-top-repo Wed Jul 05 20:37:58 2017 +0200
@@ -310,3 +310,4 @@
7c31f9d7b932f7924f1258d52885b1c7c3e078c2 jdk9-b65
dc6e8336f51bb6b67b7245766179eab5ca7720b4 jdk9-b66
f546760134eb861fcfecd4ce611b0040b0d25a6a jdk9-b67
+70e4272790b6199e9ca89df2758ff9cb58ec4125 jdk9-b68
diff -r 97f4fef2d420 -r a9714a11e787 corba/.hgtags
--- a/corba/.hgtags Thu Jun 11 20:20:05 2015 -0700
+++ b/corba/.hgtags Wed Jul 05 20:37:58 2017 +0200
@@ -310,3 +310,4 @@
afc1e295c4bf83f9a5dd539c29914edd4a754a3f jdk9-b65
44ee68f7dbacab24a45115fd6a8ccdc7eb6e8f0b jdk9-b66
4418697e56f1f43597f55c7cb6573549c6117868 jdk9-b67
+8efad64f40eb8cd4df376c0a5275892eeb396bbd jdk9-b68
diff -r 97f4fef2d420 -r a9714a11e787 corba/src/java.corba/share/classes/org/omg/CORBA/BoundsHelper.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/src/java.corba/share/classes/org/omg/CORBA/BoundsHelper.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.omg.CORBA;
+
+
+/**
+ * This Helper class is used to facilitate the marshalling of Bounds.
+ * For more information on Helper files, see
+ *
+ * "Generated Files: Helper Files".
+ */
+
+abstract public class BoundsHelper
+{
+ private static String _id = "IDL:omg.org/CORBA/Bounds:1.0";
+
+ public static void insert (org.omg.CORBA.Any a, org.omg.CORBA.Bounds that)
+ {
+ org.omg.CORBA.portable.OutputStream out = a.create_output_stream ();
+ a.type (type ());
+ write (out, that);
+ a.read_value (out.create_input_stream (), type ());
+ }
+
+ public static org.omg.CORBA.Bounds extract (org.omg.CORBA.Any a)
+ {
+ return read (a.create_input_stream ());
+ }
+
+ private static org.omg.CORBA.TypeCode __typeCode = null;
+ private static boolean __active = false;
+ synchronized public static org.omg.CORBA.TypeCode type ()
+ {
+ if (__typeCode == null)
+ {
+ synchronized (org.omg.CORBA.TypeCode.class)
+ {
+ if (__typeCode == null)
+ {
+ if (__active)
+ {
+ return org.omg.CORBA.ORB.init().create_recursive_tc ( _id );
+ }
+ __active = true;
+ org.omg.CORBA.StructMember[] _members0 = new org.omg.CORBA.StructMember [0];
+ org.omg.CORBA.TypeCode _tcOf_members0 = null;
+ __typeCode = org.omg.CORBA.ORB.init ().create_exception_tc (org.omg.CORBA.BoundsHelper.id (), "Bounds", _members0);
+ __active = false;
+ }
+ }
+ }
+ return __typeCode;
+ }
+
+ public static String id ()
+ {
+ return _id;
+ }
+
+ public static org.omg.CORBA.Bounds read (org.omg.CORBA.portable.InputStream istream)
+ {
+ org.omg.CORBA.Bounds value = new org.omg.CORBA.Bounds ();
+ // read and discard the repository ID
+ istream.read_string ();
+ return value;
+ }
+
+ public static void write (org.omg.CORBA.portable.OutputStream ostream, org.omg.CORBA.Bounds value)
+ {
+ // write the repository ID
+ ostream.write_string (id ());
+ }
+
+}
diff -r 97f4fef2d420 -r a9714a11e787 corba/src/java.corba/share/classes/org/omg/CORBA/ORBPackage/InvalidNameHelper.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/src/java.corba/share/classes/org/omg/CORBA/ORBPackage/InvalidNameHelper.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.omg.CORBA.ORBPackage;
+
+
+/**
+ * This Helper class is used to facilitate the marshalling of
+ * ORBPackage/InvalidName.
+ * For more information on Helper files, see
+ *
+ * "Generated Files: Helper Files".
+ */
+
+abstract public class InvalidNameHelper
+{
+ private static String _id = "IDL:omg.org.CORBA/ORB/InvalidName:1.0";
+
+ public static void insert (org.omg.CORBA.Any a, org.omg.CORBA.ORBPackage.InvalidName that)
+ {
+ org.omg.CORBA.portable.OutputStream out = a.create_output_stream ();
+ a.type (type ());
+ write (out, that);
+ a.read_value (out.create_input_stream (), type ());
+ }
+
+ public static org.omg.CORBA.ORBPackage.InvalidName extract (org.omg.CORBA.Any a)
+ {
+ return read (a.create_input_stream ());
+ }
+
+ private static org.omg.CORBA.TypeCode __typeCode = null;
+ private static boolean __active = false;
+ synchronized public static org.omg.CORBA.TypeCode type ()
+ {
+ if (__typeCode == null)
+ {
+ synchronized (org.omg.CORBA.TypeCode.class)
+ {
+ if (__typeCode == null)
+ {
+ if (__active)
+ {
+ return org.omg.CORBA.ORB.init().create_recursive_tc ( _id );
+ }
+ __active = true;
+ org.omg.CORBA.StructMember[] _members0 = new org.omg.CORBA.StructMember [0];
+ org.omg.CORBA.TypeCode _tcOf_members0 = null;
+ __typeCode = org.omg.CORBA.ORB.init ().create_exception_tc (org.omg.CORBA.ORBPackage.InvalidNameHelper.id (), "InvalidName", _members0);
+ __active = false;
+ }
+ }
+ }
+ return __typeCode;
+ }
+
+ public static String id ()
+ {
+ return _id;
+ }
+
+ public static org.omg.CORBA.ORBPackage.InvalidName read (org.omg.CORBA.portable.InputStream istream)
+ {
+ org.omg.CORBA.ORBPackage.InvalidName value = new org.omg.CORBA.ORBPackage.InvalidName ();
+ // read and discard the repository ID
+ istream.read_string ();
+ return value;
+ }
+
+ public static void write (org.omg.CORBA.portable.OutputStream ostream, org.omg.CORBA.ORBPackage.InvalidName value)
+ {
+ // write the repository ID
+ ostream.write_string (id ());
+ }
+
+}
diff -r 97f4fef2d420 -r a9714a11e787 corba/src/java.corba/share/classes/org/omg/CORBA/TypeCodePackage/BadKindHelper.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/src/java.corba/share/classes/org/omg/CORBA/TypeCodePackage/BadKindHelper.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.omg.CORBA.TypeCodePackage;
+
+
+/**
+ * This Helper class is used to facilitate the marshalling of
+ * TypeCodePackage/BadKind.
+ * For more information on Helper files, see
+ *
+ * "Generated Files: Helper Files".
+ */
+
+abstract public class BadKindHelper
+{
+ private static String _id = "IDL:omg.org.CORBA/TypeCode/BadKind:1.0";
+
+ public static void insert (org.omg.CORBA.Any a, org.omg.CORBA.TypeCodePackage.BadKind that)
+ {
+ org.omg.CORBA.portable.OutputStream out = a.create_output_stream ();
+ a.type (type ());
+ write (out, that);
+ a.read_value (out.create_input_stream (), type ());
+ }
+
+ public static org.omg.CORBA.TypeCodePackage.BadKind extract (org.omg.CORBA.Any a)
+ {
+ return read (a.create_input_stream ());
+ }
+
+ private static org.omg.CORBA.TypeCode __typeCode = null;
+ private static boolean __active = false;
+ synchronized public static org.omg.CORBA.TypeCode type ()
+ {
+ if (__typeCode == null)
+ {
+ synchronized (org.omg.CORBA.TypeCode.class)
+ {
+ if (__typeCode == null)
+ {
+ if (__active)
+ {
+ return org.omg.CORBA.ORB.init().create_recursive_tc ( _id );
+ }
+ __active = true;
+ org.omg.CORBA.StructMember[] _members0 = new org.omg.CORBA.StructMember [0];
+ org.omg.CORBA.TypeCode _tcOf_members0 = null;
+ __typeCode = org.omg.CORBA.ORB.init ().create_exception_tc (org.omg.CORBA.TypeCodePackage.BadKindHelper.id (), "BadKind", _members0);
+ __active = false;
+ }
+ }
+ }
+ return __typeCode;
+ }
+
+ public static String id ()
+ {
+ return _id;
+ }
+
+ public static org.omg.CORBA.TypeCodePackage.BadKind read (org.omg.CORBA.portable.InputStream istream)
+ {
+ org.omg.CORBA.TypeCodePackage.BadKind value = new org.omg.CORBA.TypeCodePackage.BadKind ();
+ // read and discard the repository ID
+ istream.read_string ();
+ return value;
+ }
+
+ public static void write (org.omg.CORBA.portable.OutputStream ostream, org.omg.CORBA.TypeCodePackage.BadKind value)
+ {
+ // write the repository ID
+ ostream.write_string (id ());
+ }
+
+}
diff -r 97f4fef2d420 -r a9714a11e787 corba/src/java.corba/share/classes/org/omg/CORBA/TypeCodePackage/BoundsHelper.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/src/java.corba/share/classes/org/omg/CORBA/TypeCodePackage/BoundsHelper.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.omg.CORBA.TypeCodePackage;
+
+
+/**
+ * This Helper class is used to facilitate the marshalling of
+ * TypeCodePackage/Bounds.
+ * For more information on Helper files, see
+ *
+ * "Generated Files: Helper Files".
+ */
+
+abstract public class BoundsHelper
+{
+ private static String _id = "IDL:omg.org.CORBA/TypeCode/Bounds:1.0";
+
+ public static void insert (org.omg.CORBA.Any a, org.omg.CORBA.TypeCodePackage.Bounds that)
+ {
+ org.omg.CORBA.portable.OutputStream out = a.create_output_stream ();
+ a.type (type ());
+ write (out, that);
+ a.read_value (out.create_input_stream (), type ());
+ }
+
+ public static org.omg.CORBA.TypeCodePackage.Bounds extract (org.omg.CORBA.Any a)
+ {
+ return read (a.create_input_stream ());
+ }
+
+ private static org.omg.CORBA.TypeCode __typeCode = null;
+ private static boolean __active = false;
+ synchronized public static org.omg.CORBA.TypeCode type ()
+ {
+ if (__typeCode == null)
+ {
+ synchronized (org.omg.CORBA.TypeCode.class)
+ {
+ if (__typeCode == null)
+ {
+ if (__active)
+ {
+ return org.omg.CORBA.ORB.init().create_recursive_tc ( _id );
+ }
+ __active = true;
+ org.omg.CORBA.StructMember[] _members0 = new org.omg.CORBA.StructMember [0];
+ org.omg.CORBA.TypeCode _tcOf_members0 = null;
+ __typeCode = org.omg.CORBA.ORB.init ().create_exception_tc (org.omg.CORBA.TypeCodePackage.BoundsHelper.id (), "Bounds", _members0);
+ __active = false;
+ }
+ }
+ }
+ return __typeCode;
+ }
+
+ public static String id ()
+ {
+ return _id;
+ }
+
+ public static org.omg.CORBA.TypeCodePackage.Bounds read (org.omg.CORBA.portable.InputStream istream)
+ {
+ org.omg.CORBA.TypeCodePackage.Bounds value = new org.omg.CORBA.TypeCodePackage.Bounds ();
+ // read and discard the repository ID
+ istream.read_string ();
+ return value;
+ }
+
+ public static void write (org.omg.CORBA.portable.OutputStream ostream, org.omg.CORBA.TypeCodePackage.Bounds value)
+ {
+ // write the repository ID
+ ostream.write_string (id ());
+ }
+
+}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/.hgtags
--- a/hotspot/.hgtags Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/.hgtags Wed Jul 05 20:37:58 2017 +0200
@@ -470,3 +470,4 @@
e7ae94c4f35e940ea423fc1dd260435df34a77c0 jdk9-b65
197e94e0dacddd16816f101d24fc0442ab518326 jdk9-b66
d47dfabd16d48eb96a451edd1b61194a39ee0eb5 jdk9-b67
+11af3990d56c97b40318bc1f20608e86f051a3f7 jdk9-b68
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/make/linux/makefiles/dtrace.make
--- a/hotspot/make/linux/makefiles/dtrace.make Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/make/linux/makefiles/dtrace.make Wed Jul 05 20:37:58 2017 +0200
@@ -31,8 +31,8 @@
REASON = "This JDK does not support SDT probes"
else
-# We need a recent GCC for the default
-ifeq "$(shell expr \( $(CC_VER_MAJOR) \>= 4 \) \& \( $(CC_VER_MINOR) \>= 4 \) )" "0"
+# We need a recent GCC for the default (4.4 or later)
+ifeq "$(shell expr \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 4 \) \) \| \( $(CC_VER_MAJOR) \>= 5 \) )" "0"
REASON = "gcc version is too old"
else
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/make/test/JtregNative.gmk
--- a/hotspot/make/test/JtregNative.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/make/test/JtregNative.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -44,6 +44,7 @@
$(HOTSPOT_TOPDIR)/test/native_sanity \
$(HOTSPOT_TOPDIR)/test/runtime/jni/8025979 \
$(HOTSPOT_TOPDIR)/test/runtime/jni/8033445 \
+ $(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \
#
BUILD_HOTSPOT_JTREG_OUTPUT_DIR := $(BUILD_OUTPUT)/support/test/hotspot/jtreg/native
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/cpu/sparc/vm/sparc.ad
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Wed Jul 05 20:37:58 2017 +0200
@@ -3372,6 +3372,25 @@
interface(CONST_INTER);
%}
+// Integer Immediate: 0-bit
+operand immI0() %{
+ predicate(n->get_int() == 0);
+ match(ConI);
+ op_cost(0);
+
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
+// Integer Immediate: 5-bit
+operand immI5() %{
+ predicate(Assembler::is_simm5(n->get_int()));
+ match(ConI);
+ op_cost(0);
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
// Integer Immediate: 8-bit
operand immI8() %{
predicate(Assembler::is_simm8(n->get_int()));
@@ -3381,6 +3400,25 @@
interface(CONST_INTER);
%}
+// Integer Immediate: the value 10
+operand immI10() %{
+ predicate(n->get_int() == 10);
+ match(ConI);
+ op_cost(0);
+
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
+// Integer Immediate: 11-bit
+operand immI11() %{
+ predicate(Assembler::is_simm11(n->get_int()));
+ match(ConI);
+ op_cost(0);
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
// Integer Immediate: 13-bit
operand immI13() %{
predicate(Assembler::is_simm13(n->get_int()));
@@ -3410,84 +3448,6 @@
interface(CONST_INTER);
%}
-// Unsigned Integer Immediate: 12-bit (non-negative that fits in simm13)
-operand immU12() %{
- predicate((0 <= n->get_int()) && Assembler::is_simm13(n->get_int()));
- match(ConI);
- op_cost(0);
-
- format %{ %}
- interface(CONST_INTER);
-%}
-
-// Integer Immediate: 6-bit
-operand immU6() %{
- predicate(n->get_int() >= 0 && n->get_int() <= 63);
- match(ConI);
- op_cost(0);
- format %{ %}
- interface(CONST_INTER);
-%}
-
-// Integer Immediate: 11-bit
-operand immI11() %{
- predicate(Assembler::is_simm11(n->get_int()));
- match(ConI);
- op_cost(0);
- format %{ %}
- interface(CONST_INTER);
-%}
-
-// Integer Immediate: 5-bit
-operand immI5() %{
- predicate(Assembler::is_simm5(n->get_int()));
- match(ConI);
- op_cost(0);
- format %{ %}
- interface(CONST_INTER);
-%}
-
-// Int Immediate non-negative
-operand immU31()
-%{
- predicate(n->get_int() >= 0);
- match(ConI);
-
- op_cost(0);
- format %{ %}
- interface(CONST_INTER);
-%}
-
-// Integer Immediate: 0-bit
-operand immI0() %{
- predicate(n->get_int() == 0);
- match(ConI);
- op_cost(0);
-
- format %{ %}
- interface(CONST_INTER);
-%}
-
-// Integer Immediate: the value 10
-operand immI10() %{
- predicate(n->get_int() == 10);
- match(ConI);
- op_cost(0);
-
- format %{ %}
- interface(CONST_INTER);
-%}
-
-// Integer Immediate: the values 0-31
-operand immU5() %{
- predicate(n->get_int() >= 0 && n->get_int() <= 31);
- match(ConI);
- op_cost(0);
-
- format %{ %}
- interface(CONST_INTER);
-%}
-
// Integer Immediate: the values 1-31
operand immI_1_31() %{
predicate(n->get_int() >= 1 && n->get_int() <= 31);
@@ -3529,7 +3489,6 @@
format %{ %}
interface(CONST_INTER);
%}
-
// Integer Immediate: the value 255
operand immI_255() %{
predicate( n->get_int() == 255 );
@@ -3550,6 +3509,46 @@
interface(CONST_INTER);
%}
+// Integer Immediate: the values 0-31
+operand immU5() %{
+ predicate(n->get_int() >= 0 && n->get_int() <= 31);
+ match(ConI);
+ op_cost(0);
+
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
+// Integer Immediate: 6-bit
+operand immU6() %{
+ predicate(n->get_int() >= 0 && n->get_int() <= 63);
+ match(ConI);
+ op_cost(0);
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
+// Unsigned Integer Immediate: 12-bit (non-negative that fits in simm13)
+operand immU12() %{
+ predicate((0 <= n->get_int()) && Assembler::is_simm13(n->get_int()));
+ match(ConI);
+ op_cost(0);
+
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
+// Integer Immediate non-negative
+operand immU31()
+%{
+ predicate(n->get_int() >= 0);
+ match(ConI);
+
+ op_cost(0);
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
// Long Immediate: the value FF
operand immL_FF() %{
predicate( n->get_long() == 0xFFL );
@@ -5653,17 +5652,17 @@
ins_pipe(iload_mem);
%}
-// Load Unsigned Byte (8 bit UNsigned) with 8-bit mask into Long Register
-instruct loadUB2L_immI8(iRegL dst, memory mem, immI8 mask) %{
+// Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register
+instruct loadUB2L_immI(iRegL dst, memory mem, immI mask) %{
match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
ins_cost(MEMORY_REF_COST + DEFAULT_COST);
size(2*4);
- format %{ "LDUB $mem,$dst\t# ubyte & 8-bit mask -> long\n\t"
- "AND $dst,$mask,$dst" %}
+ format %{ "LDUB $mem,$dst\t# ubyte & 32-bit mask -> long\n\t"
+ "AND $dst,right_n_bits($mask, 8),$dst" %}
ins_encode %{
__ ldub($mem$$Address, $dst$$Register);
- __ and3($dst$$Register, $mask$$constant, $dst$$Register);
+ __ and3($dst$$Register, $mask$$constant & right_n_bits(8), $dst$$Register);
%}
ins_pipe(iload_mem);
%}
@@ -5776,20 +5775,20 @@
ins_pipe(iload_mem);
%}
-// Load Unsigned Short/Char (16bit UNsigned) with a 16-bit mask into a Long Register
-instruct loadUS2L_immI16(iRegL dst, memory mem, immI16 mask, iRegL tmp) %{
+// Load Unsigned Short/Char (16bit UNsigned) with a 32-bit mask into a Long Register
+instruct loadUS2L_immI(iRegL dst, memory mem, immI mask, iRegL tmp) %{
match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
effect(TEMP dst, TEMP tmp);
ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
- format %{ "LDUH $mem,$dst\t! ushort/char & 16-bit mask -> long\n\t"
- "SET $mask,$tmp\n\t"
+ format %{ "LDUH $mem,$dst\t! ushort/char & 32-bit mask -> long\n\t"
+ "SET right_n_bits($mask, 16),$tmp\n\t"
"AND $dst,$tmp,$dst" %}
ins_encode %{
Register Rdst = $dst$$Register;
Register Rtmp = $tmp$$Register;
__ lduh($mem$$Address, Rdst);
- __ set($mask$$constant, Rtmp);
+ __ set($mask$$constant & right_n_bits(16), Rtmp);
__ and3(Rdst, Rtmp, Rdst);
%}
ins_pipe(iload_mem);
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/cpu/x86/vm/interp_masm_x86.cpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/cpu/x86/vm/interp_masm_x86.hpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/cpu/x86/vm/x86_32.ad
--- a/hotspot/src/cpu/x86/vm/x86_32.ad Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad Wed Jul 05 20:37:58 2017 +0200
@@ -5431,18 +5431,18 @@
%}
// Load Unsigned Byte (8 bit UNsigned) with mask into Long Register
-instruct loadUB2L_immI8(eRegL dst, memory mem, immI8 mask, eFlagsReg cr) %{
+instruct loadUB2L_immI(eRegL dst, memory mem, immI mask, eFlagsReg cr) %{
match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
effect(KILL cr);
- format %{ "MOVZX8 $dst.lo,$mem\t# ubyte & 8-bit mask -> long\n\t"
+ format %{ "MOVZX8 $dst.lo,$mem\t# ubyte & 32-bit mask -> long\n\t"
"XOR $dst.hi,$dst.hi\n\t"
- "AND $dst.lo,$mask" %}
+ "AND $dst.lo,right_n_bits($mask, 8)" %}
ins_encode %{
Register Rdst = $dst$$Register;
__ movzbl(Rdst, $mem$$Address);
__ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
- __ andl(Rdst, $mask$$constant);
+ __ andl(Rdst, $mask$$constant & right_n_bits(8));
%}
ins_pipe(ialu_reg_mem);
%}
@@ -5550,19 +5550,19 @@
ins_pipe(ialu_reg_mem);
%}
-// Load Unsigned Short/Char (16 bit UNsigned) with a 16-bit mask into Long Register
-instruct loadUS2L_immI16(eRegL dst, memory mem, immI16 mask, eFlagsReg cr) %{
+// Load Unsigned Short/Char (16 bit UNsigned) with a 32-bit mask into Long Register
+instruct loadUS2L_immI(eRegL dst, memory mem, immI mask, eFlagsReg cr) %{
match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
effect(KILL cr);
- format %{ "MOVZX $dst.lo, $mem\t# ushort/char & 16-bit mask -> long\n\t"
+ format %{ "MOVZX $dst.lo, $mem\t# ushort/char & 32-bit mask -> long\n\t"
"XOR $dst.hi,$dst.hi\n\t"
- "AND $dst.lo,$mask" %}
+ "AND $dst.lo,right_n_bits($mask, 16)" %}
ins_encode %{
Register Rdst = $dst$$Register;
__ movzwl(Rdst, $mem$$Address);
__ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
- __ andl(Rdst, $mask$$constant);
+ __ andl(Rdst, $mask$$constant & right_n_bits(16));
%}
ins_pipe(ialu_reg_mem);
%}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/cpu/x86/vm/x86_64.ad
--- a/hotspot/src/cpu/x86/vm/x86_64.ad Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad Wed Jul 05 20:37:58 2017 +0200
@@ -4753,17 +4753,17 @@
ins_pipe(ialu_reg_mem);
%}
-// Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register
-instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{
+// Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register
+instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
effect(KILL cr);
- format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t"
- "andl $dst, $mask" %}
+ format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t"
+ "andl $dst, right_n_bits($mask, 8)" %}
ins_encode %{
Register Rdst = $dst$$Register;
__ movzbq(Rdst, $mem$$Address);
- __ andl(Rdst, $mask$$constant);
+ __ andl(Rdst, $mask$$constant & right_n_bits(8));
%}
ins_pipe(ialu_reg_mem);
%}
@@ -4863,17 +4863,17 @@
ins_pipe(ialu_reg_mem);
%}
-// Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register
-instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{
+// Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register
+instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
effect(KILL cr);
- format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t"
- "andl $dst, $mask" %}
+ format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t"
+ "andl $dst, right_n_bits($mask, 16)" %}
ins_encode %{
Register Rdst = $dst$$Register;
__ movzwq(Rdst, $mem$$Address);
- __ andl(Rdst, $mask$$constant);
+ __ andl(Rdst, $mask$$constant & right_n_bits(16));
%}
ins_pipe(ialu_reg_mem);
%}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/os/aix/vm/os_aix.cpp
--- a/hotspot/src/os/aix/vm/os_aix.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/os/aix/vm/os_aix.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1267,10 +1267,6 @@
// Note: os::abort() might be called very early during initialization, or
// called from signal handler. Before adding something to os::abort(), make
// sure it is async-safe and can handle partially initialized VM.
-void os::abort(bool dump_core) {
- abort(dump_core, NULL, NULL);
-}
-
void os::abort(bool dump_core, void* siginfo, void* context) {
os::shutdown();
if (dump_core) {
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/os/bsd/vm/os_bsd.cpp
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1131,10 +1131,6 @@
// Note: os::abort() might be called very early during initialization, or
// called from signal handler. Before adding something to os::abort(), make
// sure it is async-safe and can handle partially initialized VM.
-void os::abort(bool dump_core) {
- abort(dump_core, NULL, NULL);
-}
-
void os::abort(bool dump_core, void* siginfo, void* context) {
os::shutdown();
if (dump_core) {
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/os/linux/vm/os_linux.cpp
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1478,10 +1478,6 @@
// Note: os::abort() might be called very early during initialization, or
// called from signal handler. Before adding something to os::abort(), make
// sure it is async-safe and can handle partially initialized VM.
-void os::abort(bool dump_core) {
- abort(dump_core, NULL, NULL);
-}
-
void os::abort(bool dump_core, void* siginfo, void* context) {
os::shutdown();
if (dump_core) {
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/os/solaris/vm/os_solaris.cpp
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1520,10 +1520,6 @@
// Note: os::abort() might be called very early during initialization, or
// called from signal handler. Before adding something to os::abort(), make
// sure it is async-safe and can handle partially initialized VM.
-void os::abort(bool dump_core) {
- abort(dump_core, NULL, NULL);
-}
-
void os::abort(bool dump_core, void* siginfo, void* context) {
os::shutdown();
if (dump_core) {
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/os/windows/vm/os_windows.cpp
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -997,7 +997,16 @@
if (!FLAG_IS_DEFAULT(CreateCoredumpOnCrash) && !CreateCoredumpOnCrash) {
jio_snprintf(buffer, buffsz, "CreateCoredumpOnCrash is disabled from command line");
status = false;
- } else {
+ }
+
+#ifndef ASSERT
+ if (!os::win32::is_windows_server() && FLAG_IS_DEFAULT(CreateCoredumpOnCrash)) {
+ jio_snprintf(buffer, buffsz, "Minidumps are not enabled by default on client versions of Windows");
+ status = false;
+ }
+#endif
+
+ if (status) {
const char* cwd = get_current_directory(NULL, 0);
int pid = current_process_id();
if (cwd != NULL) {
@@ -1086,10 +1095,6 @@
win32::exit_process_or_thread(win32::EPT_PROCESS, 1);
}
-void os::abort(bool dump_core) {
- abort(dump_core, NULL, NULL);
-}
-
// Die immediately, no exit hook, no abort hook, no cleanup.
void os::die() {
win32::exit_process_or_thread(win32::EPT_PROCESS_DIE, -1);
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/ci/ciCallSite.cpp
--- a/hotspot/src/share/vm/ci/ciCallSite.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciCallSite.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -50,25 +50,6 @@
}
// ------------------------------------------------------------------
-// ciCallSite::get_context
-//
-// Return the target MethodHandle of this CallSite.
-ciKlass* ciCallSite::get_context() {
- assert(!is_constant_call_site(), "");
-
- VM_ENTRY_MARK;
- oop call_site_oop = get_oop();
- InstanceKlass* ctxk = MethodHandles::get_call_site_context(call_site_oop);
- if (ctxk == NULL) {
- // The call site doesn't have a context associated. Set it to the default context.
- oop def_context_oop = java_lang_invoke_CallSite::default_context();
- java_lang_invoke_CallSite::set_context_cas(call_site_oop, def_context_oop, /*expected=*/NULL);
- ctxk = MethodHandles::get_call_site_context(call_site_oop);
- }
- return (CURRENT_ENV->get_metadata(ctxk))->as_klass();
-}
-
-// ------------------------------------------------------------------
// ciCallSite::print
//
// Print debugging information about the CallSite.
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/ci/ciCallSite.hpp
--- a/hotspot/src/share/vm/ci/ciCallSite.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciCallSite.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -43,7 +43,6 @@
// Return the target MethodHandle of this CallSite.
ciMethodHandle* get_target() const;
- ciKlass* get_context();
void print();
};
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/ci/ciEnv.cpp
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -709,24 +709,23 @@
KlassHandle h_holder(THREAD, holder);
LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL));
methodHandle dest_method;
+ LinkInfo link_info(h_holder, name, sig, h_accessor, /*check_access*/true);
switch (bc) {
case Bytecodes::_invokestatic:
dest_method =
- LinkResolver::resolve_static_call_or_null(h_holder, name, sig, h_accessor);
+ LinkResolver::resolve_static_call_or_null(link_info);
break;
case Bytecodes::_invokespecial:
dest_method =
- LinkResolver::resolve_special_call_or_null(h_holder, name, sig, h_accessor);
+ LinkResolver::resolve_special_call_or_null(link_info);
break;
case Bytecodes::_invokeinterface:
dest_method =
- LinkResolver::linktime_resolve_interface_method_or_null(h_holder, name, sig,
- h_accessor, true);
+ LinkResolver::linktime_resolve_interface_method_or_null(link_info);
break;
case Bytecodes::_invokevirtual:
dest_method =
- LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, name, sig,
- h_accessor, true);
+ LinkResolver::linktime_resolve_virtual_method_or_null(link_info);
break;
default: ShouldNotReachHere();
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/ci/ciField.cpp
--- a/hotspot/src/share/vm/ci/ciField.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciField.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -352,11 +352,11 @@
}
}
+ LinkInfo link_info(_holder->get_instanceKlass(),
+ _name->get_symbol(), _signature->get_symbol(),
+ accessing_klass->get_Klass());
fieldDescriptor result;
- LinkResolver::resolve_field(result, _holder->get_instanceKlass(),
- _name->get_symbol(), _signature->get_symbol(),
- accessing_klass->get_Klass(), bc, true, false,
- KILL_COMPILE_ON_FATAL_(false));
+ LinkResolver::resolve_field(result, link_info, bc, false, KILL_COMPILE_ON_FATAL_(false));
// update the hit-cache, unless there is a problem with memory scoping:
if (accessing_klass->is_shared() || !is_shared()) {
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/ci/ciInstanceKlass.cpp
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -453,8 +453,12 @@
if (fields == NULL) {
// This can happen if this class (java.lang.Class) has invisible fields.
- _nonstatic_fields = super_fields;
- return super_fields->length();
+ if (super_fields != NULL) {
+ _nonstatic_fields = super_fields;
+ return super_fields->length();
+ } else {
+ return 0;
+ }
}
int flen = fields->length();
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/ci/ciMethod.cpp
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, 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
@@ -786,6 +786,7 @@
Symbol* h_name = name()->get_symbol();
Symbol* h_signature = signature()->get_symbol();
+ LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass, check_access);
methodHandle m;
// Only do exact lookup if receiver klass has been linked. Otherwise,
// the vtable has not been setup, and the LinkResolver will fail.
@@ -793,9 +794,9 @@
||
InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) {
if (holder()->is_interface()) {
- m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass, check_access);
+ m = LinkResolver::resolve_interface_call_or_null(h_recv, link_info);
} else {
- m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass, check_access);
+ m = LinkResolver::resolve_virtual_call_or_null(h_recv, link_info);
}
}
@@ -839,7 +840,8 @@
Symbol* h_name = name()->get_symbol();
Symbol* h_signature = signature()->get_symbol();
- vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass);
+ LinkInfo link_info(h_recv, h_name, h_signature, caller_klass);
+ vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, link_info);
if (vtable_index == Method::nonvirtual_vtable_index) {
// A statically bound method. Return "no such index".
vtable_index = Method::invalid_vtable_index;
@@ -1285,10 +1287,8 @@
EXCEPTION_MARK;
HandleMark hm(THREAD);
constantPoolHandle pool (THREAD, get_Method()->constants());
- methodHandle spec_method;
- KlassHandle spec_klass;
Bytecodes::Code code = (is_static ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual);
- LinkResolver::resolve_method_statically(spec_method, spec_klass, code, pool, refinfo_index, THREAD);
+ methodHandle spec_method = LinkResolver::resolve_method_statically(code, pool, refinfo_index, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return false;
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/ci/ciStreams.cpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/classfile/classLoaderData.cpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/classfile/classLoaderData.hpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/classfile/javaClasses.cpp
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -2967,47 +2967,42 @@
int java_lang_invoke_CallSite::_target_offset;
int java_lang_invoke_CallSite::_context_offset;
-int java_lang_invoke_CallSite::_default_context_offset;
void java_lang_invoke_CallSite::compute_offsets() {
Klass* k = SystemDictionary::CallSite_klass();
if (k != NULL) {
compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature());
- compute_offset(_context_offset, k, vmSymbols::context_name(), vmSymbols::sun_misc_Cleaner_signature());
- compute_offset(_default_context_offset, k,
- vmSymbols::DEFAULT_CONTEXT_name(), vmSymbols::sun_misc_Cleaner_signature(),
- /*is_static=*/true, /*allow_super=*/false);
+ compute_offset(_context_offset, k, vmSymbols::context_name(),
+ vmSymbols::java_lang_invoke_MethodHandleNatives_CallSiteContext_signature());
}
}
-oop java_lang_invoke_CallSite::context_volatile(oop call_site) {
- assert(java_lang_invoke_CallSite::is_instance(call_site), "");
-
- oop dep_oop = call_site->obj_field_volatile(_context_offset);
- return dep_oop;
-}
-
-void java_lang_invoke_CallSite::set_context_volatile(oop call_site, oop context) {
+oop java_lang_invoke_CallSite::context(oop call_site) {
assert(java_lang_invoke_CallSite::is_instance(call_site), "");
- call_site->obj_field_put_volatile(_context_offset, context);
-}
-
-bool java_lang_invoke_CallSite::set_context_cas(oop call_site, oop context, oop expected) {
- assert(java_lang_invoke_CallSite::is_instance(call_site), "");
- HeapWord* context_addr = call_site->obj_field_addr(_context_offset);
- oop res = oopDesc::atomic_compare_exchange_oop(context, context_addr, expected, true);
- bool success = (res == expected);
- if (success) {
- update_barrier_set((void*)context_addr, context);
+
+ oop dep_oop = call_site->obj_field(_context_offset);
+ return dep_oop;
+}
+
+// Support for java_lang_invoke_MethodHandleNatives_CallSiteContext
+
+int java_lang_invoke_MethodHandleNatives_CallSiteContext::_vmdependencies_offset;
+
+void java_lang_invoke_MethodHandleNatives_CallSiteContext::compute_offsets() {
+ Klass* k = SystemDictionary::Context_klass();
+ if (k != NULL) {
+ CALLSITECONTEXT_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
}
- return success;
-}
-
-oop java_lang_invoke_CallSite::default_context() {
- InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::CallSite_klass());
- oop def_context_oop = ik->java_mirror()->obj_field(_default_context_offset);
- assert(!oopDesc::is_null(def_context_oop), "");
- return def_context_oop;
+}
+
+nmethodBucket* java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(oop call_site) {
+ assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), "");
+ return (nmethodBucket*) (address) call_site->long_field(_vmdependencies_offset);
+}
+
+void java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(oop call_site, nmethodBucket* context) {
+ assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), "");
+ call_site->long_field_put(_vmdependencies_offset, (jlong) (address) context);
}
// Support for java_security_AccessControlContext
@@ -3403,6 +3398,7 @@
java_lang_invoke_LambdaForm::compute_offsets();
java_lang_invoke_MethodType::compute_offsets();
java_lang_invoke_CallSite::compute_offsets();
+ java_lang_invoke_MethodHandleNatives_CallSiteContext::compute_offsets();
java_security_AccessControlContext::compute_offsets();
// Initialize reflection classes. The layouts of these classes
// changed with the new reflection implementation in JDK 1.4, and
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/classfile/javaClasses.hpp
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -1170,8 +1170,6 @@
private:
static int _target_offset;
static int _context_offset;
- static int _default_context_offset;
-
static void compute_offsets();
@@ -1181,11 +1179,7 @@
static void set_target( oop site, oop target);
static void set_target_volatile( oop site, oop target);
- static oop context_volatile(oop site);
- static void set_context_volatile(oop site, oop context);
- static bool set_context_cas (oop site, oop context, oop expected);
-
- static oop default_context();
+ static oop context(oop site);
// Testers
static bool is_subclass(Klass* klass) {
@@ -1197,6 +1191,31 @@
static int target_offset_in_bytes() { return _target_offset; }
};
+// Interface to java.lang.invoke.MethodHandleNatives$CallSiteContext objects
+
+#define CALLSITECONTEXT_INJECTED_FIELDS(macro) \
+ macro(java_lang_invoke_MethodHandleNatives_CallSiteContext, vmdependencies, intptr_signature, false)
+
+class java_lang_invoke_MethodHandleNatives_CallSiteContext : AllStatic {
+ friend class JavaClasses;
+
+private:
+ static int _vmdependencies_offset;
+
+ static void compute_offsets();
+
+public:
+ // Accessors
+ static nmethodBucket* vmdependencies(oop context);
+ static void set_vmdependencies(oop context, nmethodBucket* bucket);
+
+ // Testers
+ static bool is_subclass(Klass* klass) {
+ return klass->is_subclass_of(SystemDictionary::Context_klass());
+ }
+ static bool is_instance(oop obj);
+};
+
// Interface to java.security.AccessControlContext objects
class java_security_AccessControlContext: AllStatic {
@@ -1406,7 +1425,8 @@
#define ALL_INJECTED_FIELDS(macro) \
CLASS_INJECTED_FIELDS(macro) \
CLASSLOADER_INJECTED_FIELDS(macro) \
- MEMBERNAME_INJECTED_FIELDS(macro)
+ MEMBERNAME_INJECTED_FIELDS(macro) \
+ CALLSITECONTEXT_INJECTED_FIELDS(macro)
// Interface to hard-coded offset checking
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/classfile/javaClasses.inline.hpp
--- a/hotspot/src/share/vm/classfile/javaClasses.inline.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.inline.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -49,6 +49,10 @@
return obj != NULL && is_subclass(obj->klass());
}
+inline bool java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(oop obj) {
+ return obj != NULL && is_subclass(obj->klass());
+}
+
inline bool java_lang_invoke_MemberName::is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/classfile/systemDictionary.hpp
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -159,6 +159,7 @@
do_klass(MethodType_klass, java_lang_invoke_MethodType, Pre ) \
do_klass(BootstrapMethodError_klass, java_lang_BootstrapMethodError, Pre ) \
do_klass(CallSite_klass, java_lang_invoke_CallSite, Pre ) \
+ do_klass(Context_klass, java_lang_invoke_MethodHandleNatives_CallSiteContext, Pre ) \
do_klass(ConstantCallSite_klass, java_lang_invoke_ConstantCallSite, Pre ) \
do_klass(MutableCallSite_klass, java_lang_invoke_MutableCallSite, Pre ) \
do_klass(VolatileCallSite_klass, java_lang_invoke_VolatileCallSite, Pre ) \
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/classfile/verifier.cpp
--- a/hotspot/src/share/vm/classfile/verifier.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -45,6 +45,8 @@
#include "runtime/javaCalls.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/os.hpp"
+#include "runtime/thread.hpp"
+#include "services/threadService.hpp"
#include "utilities/bytes.hpp"
#define NOFAILOVER_MAJOR_VERSION 51
@@ -130,6 +132,16 @@
return true;
}
+ // Timer includes any side effects of class verification (resolution,
+ // etc), but not recursive calls to Verifier::verify().
+ JavaThread* jt = (JavaThread*)THREAD;
+ PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
+ ClassLoader::perf_class_verify_selftime(),
+ ClassLoader::perf_classes_verified(),
+ jt->get_thread_stat()->perf_recursion_counts_addr(),
+ jt->get_thread_stat()->perf_timers_addr(),
+ PerfClassTraceTime::CLASS_VERIFY);
+
// If the class should be verified, first see if we can use the split
// verifier. If not, or if verification fails and FailOverToOldVerifier
// is set, then call the inference verifier.
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/classfile/vmSymbols.hpp
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -274,12 +274,14 @@
/* internal classes known only to the JVM: */ \
template(java_lang_invoke_MemberName, "java/lang/invoke/MemberName") \
template(java_lang_invoke_MethodHandleNatives, "java/lang/invoke/MethodHandleNatives") \
+ template(java_lang_invoke_MethodHandleNatives_CallSiteContext, "java/lang/invoke/MethodHandleNatives$CallSiteContext") \
template(java_lang_invoke_LambdaForm, "java/lang/invoke/LambdaForm") \
template(java_lang_invoke_ForceInline_signature, "Ljava/lang/invoke/ForceInline;") \
template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \
template(java_lang_invoke_Stable_signature, "Ljava/lang/invoke/Stable;") \
template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \
+ template(java_lang_invoke_MethodHandleNatives_CallSiteContext_signature, "Ljava/lang/invoke/MethodHandleNatives$CallSiteContext;") \
/* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \
template(findMethodHandleType_name, "findMethodHandleType") \
template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \
@@ -401,7 +403,7 @@
template(protection_domain_name, "protection_domain") \
template(signers_name, "signers_name") \
template(loader_data_name, "loader_data") \
- template(dependencies_name, "dependencies") \
+ template(vmdependencies_name, "vmdependencies") \
template(input_stream_void_signature, "(Ljava/io/InputStream;)V") \
template(getFileURL_name, "getFileURL") \
template(getFileURL_signature, "(Ljava/io/File;)Ljava/net/URL;") \
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/code/codeCache.cpp
--- a/hotspot/src/share/vm/code/codeCache.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/code/codeCache.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1047,40 +1047,6 @@
}
}
-// Flushes compiled methods dependent on a particular CallSite
-// instance when its target is different than the given MethodHandle.
-void CodeCache::flush_dependents_on(Handle call_site, Handle method_handle) {
- assert_lock_strong(Compile_lock);
-
- if (number_of_nmethods_with_dependencies() == 0) return;
-
- // CodeCache can only be updated by a thread_in_VM and they will all be
- // stopped during the safepoint so CodeCache will be safe to update without
- // holding the CodeCache_lock.
-
- CallSiteDepChange changes(call_site(), method_handle());
-
- // Compute the dependent nmethods that have a reference to a
- // CallSite object. We use InstanceKlass::mark_dependent_nmethod
- // directly instead of CodeCache::mark_for_deoptimization because we
- // want dependents on the call site class only not all classes in
- // the ContextStream.
- int marked = 0;
- {
- MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- InstanceKlass* ctxk = MethodHandles::get_call_site_context(call_site());
- if (ctxk == NULL) {
- return; // No dependencies to invalidate yet.
- }
- marked = ctxk->mark_dependent_nmethods(changes);
- }
- if (marked > 0) {
- // At least one nmethod has been marked for deoptimization
- VM_Deoptimize op;
- VMThread::execute(&op);
- }
-}
-
#ifdef HOTSWAP
// Flushes compiled methods dependent on dependee in the evolutionary sense
void CodeCache::flush_evol_dependents_on(instanceKlassHandle ev_k_h) {
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/code/codeCache.hpp
--- a/hotspot/src/share/vm/code/codeCache.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/code/codeCache.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -224,7 +224,6 @@
// Flushing and deoptimization
static void flush_dependents_on(instanceKlassHandle dependee);
- static void flush_dependents_on(Handle call_site, Handle method_handle);
#ifdef HOTSWAP
// Flushing and deoptimization in case of evolution
static void flush_evol_dependents_on(instanceKlassHandle dependee);
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/code/dependencies.cpp
--- a/hotspot/src/share/vm/code/dependencies.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/code/dependencies.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -117,9 +117,7 @@
}
void Dependencies::assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle) {
- ciKlass* ctxk = call_site->get_context();
- check_ctxk(ctxk);
- assert_common_3(call_site_target_value, ctxk, call_site, method_handle);
+ assert_common_2(call_site_target_value, call_site, method_handle);
}
// Helper function. If we are adding a new dep. under ctxk2,
@@ -175,7 +173,6 @@
}
}
} else {
- assert(dep_implicit_context_arg(dept) == 0, "sanity");
if (note_dep_seen(dept, x0) && note_dep_seen(dept, x1)) {
// look in this bucket for redundant assertions
const int stride = 2;
@@ -389,7 +386,7 @@
3, // unique_concrete_subtypes_2 ctxk, k1, k2
3, // unique_concrete_methods_2 ctxk, m1, m2
1, // no_finalizable_subclasses ctxk
- 3 // call_site_target_value ctxk, call_site, method_handle
+ 2 // call_site_target_value call_site, method_handle
};
const char* Dependencies::dep_name(Dependencies::DepType dept) {
@@ -1515,16 +1512,11 @@
return find_finalizable_subclass(search_at);
}
-Klass* Dependencies::check_call_site_target_value(Klass* recorded_ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes) {
+Klass* Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) {
+ assert(!oopDesc::is_null(call_site), "sanity");
+ assert(!oopDesc::is_null(method_handle), "sanity");
assert(call_site->is_a(SystemDictionary::CallSite_klass()), "sanity");
- assert(!oopDesc::is_null(method_handle), "sanity");
- Klass* call_site_ctxk = MethodHandles::get_call_site_context(call_site);
- assert(!Klass::is_null(call_site_ctxk), "call site context should be initialized already");
- if (recorded_ctxk != call_site_ctxk) {
- // Stale context
- return recorded_ctxk;
- }
if (changes == NULL) {
// Validate all CallSites
if (java_lang_invoke_CallSite::target(call_site) != method_handle)
@@ -1599,7 +1591,7 @@
Klass* witness = NULL;
switch (type()) {
case call_site_target_value:
- witness = check_call_site_target_value(context_type(), argument_oop(1), argument_oop(2), changes);
+ witness = check_call_site_target_value(argument_oop(0), argument_oop(1), changes);
break;
default:
witness = NULL;
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/code/dependencies.hpp
--- a/hotspot/src/share/vm/code/dependencies.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/code/dependencies.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -173,7 +173,7 @@
non_klass_types = (1 << call_site_target_value),
klass_types = all_types & ~non_klass_types,
- non_ctxk_types = (1 << evol_method),
+ non_ctxk_types = (1 << evol_method) | (1 << call_site_target_value),
implicit_ctxk_types = 0,
explicit_ctxk_types = all_types & ~(non_ctxk_types | implicit_ctxk_types),
@@ -330,7 +330,7 @@
static Klass* check_exclusive_concrete_methods(Klass* ctxk, Method* m1, Method* m2,
KlassDepChange* changes = NULL);
static Klass* check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes = NULL);
- static Klass* check_call_site_target_value(Klass* recorded_ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
+ static Klass* check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
// A returned Klass* is NULL if the dependency assertion is still
// valid. A non-NULL Klass* is a 'witness' to the assertion
// failure, a point in the class hierarchy where the assertion has
@@ -496,7 +496,7 @@
bool next();
DepType type() { return _type; }
- bool is_oop_argument(int i) { return type() == call_site_target_value && i > 0; }
+ bool is_oop_argument(int i) { return type() == call_site_target_value; }
uintptr_t get_identifier(int i);
int argument_count() { return dep_args(type()); }
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/code/nmethod.cpp
--- a/hotspot/src/share/vm/code/nmethod.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -565,13 +565,18 @@
// the number of methods compiled. For applications with a lot
// classes the slow way is too slow.
for (Dependencies::DepStream deps(nm); deps.next(); ) {
- Klass* klass = deps.context_type();
- if (klass == NULL) {
- continue; // ignore things like evol_method
+ if (deps.type() == Dependencies::call_site_target_value) {
+ // CallSite dependencies are managed on per-CallSite instance basis.
+ oop call_site = deps.argument_oop(0);
+ MethodHandles::add_dependent_nmethod(call_site, nm);
+ } else {
+ Klass* klass = deps.context_type();
+ if (klass == NULL) {
+ continue; // ignore things like evol_method
+ }
+ // record this nmethod as dependent on this klass
+ InstanceKlass::cast(klass)->add_dependent_nmethod(nm);
}
-
- // record this nmethod as dependent on this klass
- InstanceKlass::cast(klass)->add_dependent_nmethod(nm);
}
NOT_PRODUCT(nmethod_stats.note_nmethod(nm));
if (PrintAssembly || CompilerOracle::has_option_string(method, "PrintAssembly")) {
@@ -1464,13 +1469,20 @@
if (!has_flushed_dependencies()) {
set_has_flushed_dependencies();
for (Dependencies::DepStream deps(this); deps.next(); ) {
- Klass* klass = deps.context_type();
- if (klass == NULL) continue; // ignore things like evol_method
-
- // During GC the is_alive closure is non-NULL, and is used to
- // determine liveness of dependees that need to be updated.
- if (is_alive == NULL || klass->is_loader_alive(is_alive)) {
- InstanceKlass::cast(klass)->remove_dependent_nmethod(this);
+ if (deps.type() == Dependencies::call_site_target_value) {
+ // CallSite dependencies are managed on per-CallSite instance basis.
+ oop call_site = deps.argument_oop(0);
+ MethodHandles::remove_dependent_nmethod(call_site, this);
+ } else {
+ Klass* klass = deps.context_type();
+ if (klass == NULL) {
+ continue; // ignore things like evol_method
+ }
+ // During GC the is_alive closure is non-NULL, and is used to
+ // determine liveness of dependees that need to be updated.
+ if (is_alive == NULL || klass->is_loader_alive(is_alive)) {
+ InstanceKlass::cast(klass)->remove_dependent_nmethod(this);
+ }
}
}
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp
--- a/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -254,9 +254,9 @@
if (_gc_cause != GCCause::_gc_locker &&
gch->total_full_collections_completed() <= _full_gc_count_before) {
// maybe we should change the condition to test _gc_cause ==
- // GCCause::_java_lang_system_gc, instead of
- // _gc_cause != GCCause::_gc_locker
- assert(_gc_cause == GCCause::_java_lang_system_gc,
+ // GCCause::_java_lang_system_gc or GCCause::_dcmd_gc_run,
+ // instead of _gc_cause != GCCause::_gc_locker
+ assert(GCCause::is_user_requested_gc(_gc_cause),
"the only way to get here if this was a System.gc()-induced GC");
assert(ExplicitGCInvokesConcurrent, "Error");
// Now, wait for witnessing concurrent gc cycle to complete,
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/cms/yieldingWorkgroup.cpp
--- a/hotspot/src/share/vm/gc/cms/yieldingWorkgroup.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/yieldingWorkgroup.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -43,7 +43,7 @@
}
// Run a task; returns when the task is done, or the workers yield,
-// or the task is aborted, or the work gang is terminated via stop().
+// or the task is aborted.
// A task that has been yielded can be continued via this interface
// by using the same task repeatedly as the argument to the call.
// It is expected that the YieldingFlexibleGangTask carries the appropriate
@@ -297,16 +297,9 @@
WorkData data;
int id;
while (true) {
- // Check if there is work to do or if we have been asked
- // to terminate
+ // Check if there is work to do.
gang()->internal_worker_poll(&data);
- if (data.terminate()) {
- // We have been asked to terminate.
- assert(gang()->task() == NULL, "No task binding");
- // set_status(TERMINATED);
- return;
- } else if (data.task() != NULL &&
- data.sequence_number() != previous_sequence_number) {
+ if (data.task() != NULL && data.sequence_number() != previous_sequence_number) {
// There is work to be done.
// First check if we need to become active or if there
// are already the requisite number of workers
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/cms/yieldingWorkgroup.hpp
--- a/hotspot/src/share/vm/gc/cms/yieldingWorkgroup.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/yieldingWorkgroup.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -176,7 +176,7 @@
GangWorker* allocate_worker(uint which);
// Run a task; returns when the task is done, or the workers yield,
- // or the task is aborted, or the work gang is terminated via stop().
+ // or the task is aborted.
// A task that has been yielded can be continued via this same interface
// by using the same task repeatedly as the argument to the call.
// It is expected that the YieldingFlexibleGangTask carries the appropriate
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1183,7 +1183,7 @@
IsGCActiveMark x;
// Timing
- assert(gc_cause() != GCCause::_java_lang_system_gc || explicit_gc, "invariant");
+ assert(!GCCause::is_user_requested_gc(gc_cause()) || explicit_gc, "invariant");
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
{
@@ -2199,6 +2199,7 @@
switch (cause) {
case GCCause::_gc_locker: return GCLockerInvokesConcurrent;
case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent;
+ case GCCause::_dcmd_gc_run: return ExplicitGCInvokesConcurrent;
case GCCause::_g1_humongous_allocation: return true;
case GCCause::_update_allocation_context_stats_inc: return true;
case GCCause::_wb_conc_mark: return true;
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -324,7 +324,8 @@
// explicitly started if:
// (a) cause == _gc_locker and +GCLockerInvokesConcurrent, or
// (b) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent.
- // (c) cause == _g1_humongous_allocation
+ // (c) cause == _dcmd_gc_run and +ExplicitGCInvokesConcurrent.
+ // (d) cause == _g1_humongous_allocation
bool should_do_concurrent_full_gc(GCCause::Cause cause);
// Keeps track of how many "old marking cycles" (i.e., Full GCs or
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp
--- a/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -168,7 +168,7 @@
// +ExplicitGCInvokesConcurrent, we have to wait here for the cycle
// that just started (or maybe one that was already in progress) to
// finish.
- if (_gc_cause == GCCause::_java_lang_system_gc &&
+ if (GCCause::is_user_requested_gc(_gc_cause) &&
_should_initiate_conc_mark) {
assert(ExplicitGCInvokesConcurrent,
"the only way to be here is if ExplicitGCInvokesConcurrent is set");
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp
--- a/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -130,7 +130,7 @@
// Update the pause time.
_major_timer.stop();
- if (gc_cause != GCCause::_java_lang_system_gc ||
+ if (!GCCause::is_user_requested_gc(gc_cause) ||
UseAdaptiveSizePolicyWithSystemGC) {
double major_pause_in_seconds = _major_timer.seconds();
double major_pause_in_ms = major_pause_in_seconds * MILLIUNITS;
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp
--- a/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -272,7 +272,7 @@
// Don't check if the size_policy is ready here. Let
// the size_policy check that internally.
if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
- ((gc_cause != GCCause::_java_lang_system_gc) ||
+ (!GCCause::is_user_requested_gc(gc_cause) ||
UseAdaptiveSizePolicyWithSystemGC)) {
// Swap the survivor spaces if from_space is empty. The
// resize_young_gen() called below is normally used after
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -2053,7 +2053,7 @@
marking_phase(vmthread_cm, maximum_heap_compaction, &_gc_tracer);
bool max_on_system_gc = UseMaximumCompactionOnSystemGC
- && gc_cause == GCCause::_java_lang_system_gc;
+ && GCCause::is_user_requested_gc(gc_cause);
summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
@@ -2089,7 +2089,7 @@
// Don't check if the size_policy is ready here. Let
// the size_policy check that internally.
if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
- ((gc_cause != GCCause::_java_lang_system_gc) ||
+ (!GCCause::is_user_requested_gc(gc_cause) ||
UseAdaptiveSizePolicyWithSystemGC)) {
// Swap the survivor spaces if from_space is empty. The
// resize_young_gen() called below is normally used after
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/parallel/psScavenge.cpp
--- a/hotspot/src/share/vm/gc/parallel/psScavenge.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psScavenge.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -290,7 +290,7 @@
AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
- if ((gc_cause != GCCause::_java_lang_system_gc) ||
+ if (!GCCause::is_user_requested_gc(gc_cause) ||
UseAdaptiveSizePolicyWithSystemGC) {
// Gather the feedback data for eden occupancy.
young_gen->eden_space()->accumulate_statistics();
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/serial/defNewGeneration.cpp
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -960,7 +960,7 @@
GCCause::to_string(gch->gc_cause()));
}
assert(gch->gc_cause() == GCCause::_scavenge_alot ||
- (gch->gc_cause() == GCCause::_java_lang_system_gc && UseConcMarkSweepGC && ExplicitGCInvokesConcurrent) ||
+ (GCCause::is_user_requested_gc(gch->gc_cause()) && UseConcMarkSweepGC && ExplicitGCInvokesConcurrent) ||
!gch->incremental_collection_failed(),
"Twice in a row");
seen_incremental_collection_failed = false;
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.cpp
--- a/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -244,7 +244,7 @@
// Update the pause time.
_minor_timer.stop();
- if (gc_cause != GCCause::_java_lang_system_gc ||
+ if (!GCCause::is_user_requested_gc(gc_cause) ||
UseAdaptiveSizePolicyWithSystemGC) {
double minor_pause_in_seconds = _minor_timer.seconds();
double minor_pause_in_ms = minor_pause_in_seconds * MILLIUNITS;
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/shared/gcCause.cpp
--- a/hotspot/src/share/vm/gc/shared/gcCause.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcCause.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -103,6 +103,9 @@
case _last_ditch_collection:
return "Last ditch collection";
+ case _dcmd_gc_run:
+ return "Diagnostic Command";
+
case _last_gc_cause:
return "ILLEGAL VALUE - last gc cause - ILLEGAL VALUE";
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/shared/gcCause.hpp
--- a/hotspot/src/share/vm/gc/shared/gcCause.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcCause.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -74,12 +74,15 @@
_g1_humongous_allocation,
_last_ditch_collection,
+
+ _dcmd_gc_run,
+
_last_gc_cause
};
inline static bool is_user_requested_gc(GCCause::Cause cause) {
return (cause == GCCause::_java_lang_system_gc ||
- cause == GCCause::_jvmti_force_gc);
+ cause == GCCause::_dcmd_gc_run);
}
inline static bool is_serviceability_requested_gc(GCCause::Cause
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -304,9 +304,16 @@
}
bool GenCollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) {
- return UseConcMarkSweepGC &&
- ((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
- (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent));
+ if (!UseConcMarkSweepGC) {
+ return false;
+ }
+
+ switch (cause) {
+ case GCCause::_gc_locker: return GCLockerInvokesConcurrent;
+ case GCCause::_java_lang_system_gc:
+ case GCCause::_dcmd_gc_run: return ExplicitGCInvokesConcurrent;
+ default: return false;
+ }
}
void GenCollectedHeap::collect_generation(Generation* gen, bool full, size_t size,
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/shared/workgroup.cpp
--- a/hotspot/src/share/vm/gc/shared/workgroup.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/workgroup.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -47,7 +47,6 @@
/* allow_vm_block */ are_GC_task_threads,
Monitor::_safepoint_check_sometimes);
assert(monitor() != NULL, "Failed to allocate monitor");
- _terminate = false;
_task = NULL;
_sequence_number = 0;
_started_workers = 0;
@@ -106,18 +105,6 @@
return true;
}
-AbstractWorkGang::~AbstractWorkGang() {
- if (TraceWorkGang) {
- tty->print_cr("Destructing work gang %s", name());
- }
- stop(); // stop all the workers
- for (uint worker = 0; worker < total_workers(); worker += 1) {
- delete gang_worker(worker);
- }
- delete gang_workers();
- delete monitor();
-}
-
GangWorker* AbstractWorkGang::gang_worker(uint i) const {
// Array index bounds checking.
GangWorker* result = NULL;
@@ -175,28 +162,9 @@
WorkGang::run_task(task, (uint) active_workers());
}
-void AbstractWorkGang::stop() {
- // Tell all workers to terminate, then wait for them to become inactive.
- MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
- if (TraceWorkGang) {
- tty->print_cr("Stopping work gang %s task %s", name(), task()->name());
- }
- _task = NULL;
- _terminate = true;
- monitor()->notify_all();
- while (finished_workers() < active_workers()) {
- if (TraceWorkGang) {
- tty->print_cr("Waiting in work gang %s: %u/%u finished",
- name(), finished_workers(), active_workers());
- }
- monitor()->wait(/* no_safepoint_check */ true);
- }
-}
-
void AbstractWorkGang::internal_worker_poll(WorkData* data) const {
assert(monitor()->owned_by_self(), "worker_poll is an internal method");
assert(data != NULL, "worker data is null");
- data->set_terminate(terminate());
data->set_task(task());
data->set_sequence_number(sequence_number());
}
@@ -259,7 +227,7 @@
void GangWorker::loop() {
int previous_sequence_number = 0;
Monitor* gang_monitor = gang()->monitor();
- for ( ; /* !terminate() */; ) {
+ for ( ; ; ) {
WorkData data;
int part; // Initialized below.
{
@@ -272,8 +240,6 @@
if (TraceWorkGang) {
tty->print("Polled outside for work in gang %s worker %u",
gang()->name(), id());
- tty->print(" terminate: %s",
- data.terminate() ? "true" : "false");
tty->print(" sequence: %d (prev: %d)",
data.sequence_number(), previous_sequence_number);
if (data.task() != NULL) {
@@ -283,13 +249,7 @@
}
tty->cr();
}
- for ( ; /* break or return */; ) {
- // Terminate if requested.
- if (data.terminate()) {
- gang()->internal_note_finish();
- gang_monitor->notify_all();
- return;
- }
+ for ( ; /* break */; ) {
// Check for new work.
if ((data.task() != NULL) &&
(data.sequence_number() != previous_sequence_number)) {
@@ -306,8 +266,6 @@
if (TraceWorkGang) {
tty->print("Polled inside for work in gang %s worker %u",
gang()->name(), id());
- tty->print(" terminate: %s",
- data.terminate() ? "true" : "false");
tty->print(" sequence: %d (prev: %d)",
data.sequence_number(), previous_sequence_number);
if (data.task() != NULL) {
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/gc/shared/workgroup.hpp
--- a/hotspot/src/share/vm/gc/shared/workgroup.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/workgroup.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -103,16 +103,15 @@
// An abstract class representing a gang of workers.
// You subclass this to supply an implementation of run_task().
class AbstractWorkGang: public CHeapObj {
- // Here's the public interface to this class.
+protected:
+ // Work gangs are never deleted, so no need to cleanup.
+ ~AbstractWorkGang() { ShouldNotReachHere(); }
public:
- // Constructor and destructor.
+ // Constructor.
AbstractWorkGang(const char* name, bool are_GC_task_threads,
bool are_ConcurrentGC_threads);
- ~AbstractWorkGang();
// Run a task, returns when the task is done (or terminated).
virtual void run_task(AbstractGangTask* task) = 0;
- // Stop and terminate all workers.
- virtual void stop();
// Return true if more workers should be applied to the task.
virtual bool needs_more_workers() const { return true; }
public:
@@ -129,8 +128,6 @@
Monitor* _monitor;
// The count of the number of workers in the gang.
uint _total_workers;
- // Whether the workers should terminate.
- bool _terminate;
// The array of worker threads for this gang.
// This is only needed for cleaning up.
GangWorker** _gang_workers;
@@ -153,9 +150,6 @@
virtual uint active_workers() const {
return _total_workers;
}
- bool terminate() const {
- return _terminate;
- }
GangWorker** gang_workers() const {
return _gang_workers;
}
@@ -205,21 +199,16 @@
class WorkData: public StackObj {
// This would be a struct, but I want accessor methods.
private:
- bool _terminate;
AbstractGangTask* _task;
int _sequence_number;
public:
// Constructor and destructor
WorkData() {
- _terminate = false;
_task = NULL;
_sequence_number = 0;
}
~WorkData() {
}
- // Accessors and modifiers
- bool terminate() const { return _terminate; }
- void set_terminate(bool value) { _terminate = value; }
AbstractGangTask* task() const { return _task; }
void set_task(AbstractGangTask* value) { _task = value; }
int sequence_number() const { return _sequence_number; }
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/interpreter/bytecode.cpp
--- a/hotspot/src/share/vm/interpreter/bytecode.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecode.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -147,13 +147,10 @@
methodHandle Bytecode_invoke::static_target(TRAPS) {
- methodHandle m;
- KlassHandle resolved_klass;
constantPoolHandle constants(THREAD, this->constants());
Bytecodes::Code bc = invoke_code();
- LinkResolver::resolve_method_statically(m, resolved_klass, bc, constants, index(), CHECK_(methodHandle()));
- return m;
+ return LinkResolver::resolve_method_statically(bc, constants, index(), THREAD);
}
Handle Bytecode_invoke::appendix(TRAPS) {
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/interpreter/linkResolver.cpp
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -52,13 +52,17 @@
// Implementation of CallInfo
-void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) {
+void CallInfo::set_static(KlassHandle resolved_klass, const methodHandle& resolved_method, TRAPS) {
int vtable_index = Method::nonvirtual_vtable_index;
set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK);
}
-void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index, TRAPS) {
+void CallInfo::set_interface(KlassHandle resolved_klass,
+ KlassHandle selected_klass,
+ const methodHandle& resolved_method,
+ const methodHandle& selected_method,
+ int itable_index, TRAPS) {
// This is only called for interface methods. If the resolved_method
// comes from java/lang/Object, it can be the subject of a virtual call, so
// we should pick the vtable index from the resolved method.
@@ -68,7 +72,11 @@
set_common(resolved_klass, selected_klass, resolved_method, selected_method, CallInfo::itable_call, itable_index, CHECK);
}
-void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
+void CallInfo::set_virtual(KlassHandle resolved_klass,
+ KlassHandle selected_klass,
+ const methodHandle& resolved_method,
+ const methodHandle& selected_method,
+ int vtable_index, TRAPS) {
assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, "valid index");
assert(vtable_index < 0 || !resolved_method->has_vtable_index() || vtable_index == resolved_method->vtable_index(), "");
CallKind kind = (vtable_index >= 0 && !resolved_method->can_be_statically_bound() ? CallInfo::vtable_call : CallInfo::direct_call);
@@ -76,7 +84,9 @@
assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call");
}
-void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS) {
+void CallInfo::set_handle(const methodHandle& resolved_method,
+ Handle resolved_appendix,
+ Handle resolved_method_type, TRAPS) {
if (resolved_method.is_null()) {
THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null");
}
@@ -93,8 +103,8 @@
void CallInfo::set_common(KlassHandle resolved_klass,
KlassHandle selected_klass,
- methodHandle resolved_method,
- methodHandle selected_method,
+ const methodHandle& resolved_method,
+ const methodHandle& selected_method,
CallKind kind,
int index,
TRAPS) {
@@ -210,8 +220,52 @@
}
#endif //ASSERT
+#ifndef PRODUCT
+void CallInfo::print() {
+ ResourceMark rm;
+ const char* kindstr = "unknown";
+ switch (_call_kind) {
+ case direct_call: kindstr = "direct"; break;
+ case vtable_call: kindstr = "vtable"; break;
+ case itable_call: kindstr = "itable"; break;
+ }
+ tty->print_cr("Call %s@%d %s", kindstr, _call_index,
+ _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
+}
+#endif
+//------------------------------------------------------------------------------------------------------------------------
+// Implementation of LinkInfo
+LinkInfo::LinkInfo(constantPoolHandle pool, int index, TRAPS) {
+ // resolve klass
+ Klass* result = pool->klass_ref_at(index, CHECK);
+ _resolved_klass = KlassHandle(THREAD, result);
+
+ // Get name, signature, and static klass
+ _name = pool->name_ref_at(index);
+ _signature = pool->signature_ref_at(index);
+ _current_klass = KlassHandle(THREAD, pool->pool_holder());
+
+ // Coming from the constant pool always checks access
+ _check_access = true;
+}
+
+char* LinkInfo::method_string() const {
+ return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
+}
+
+#ifndef PRODUCT
+void LinkInfo::print() {
+ ResourceMark rm;
+ tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
+ _resolved_klass->name()->as_C_string(),
+ _name->as_C_string(),
+ _signature->as_C_string(),
+ _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
+ _check_access ? "true" : "false");
+}
+#endif // PRODUCT
//------------------------------------------------------------------------------------------------------------------------
// Klass resolution
@@ -231,11 +285,6 @@
}
}
-void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
- Klass* result_oop = pool->klass_ref_at(index, CHECK);
- result = KlassHandle(THREAD, result_oop);
-}
-
//------------------------------------------------------------------------------------------------------------------------
// Method resolution
//
@@ -243,76 +292,84 @@
// Look up method in klasses, including static methods
// Then look up local default methods
-void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) {
+methodHandle LinkResolver::lookup_method_in_klasses(const LinkInfo& link_info,
+ bool checkpolymorphism,
+ bool in_imethod_resolve, TRAPS) {
+ KlassHandle klass = link_info.resolved_klass();
+ Symbol* name = link_info.name();
+ Symbol* signature = link_info.signature();
+
// Ignore overpasses so statics can be found during resolution
- Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::skip_overpass);
+ Method* result = klass->uncached_lookup_method(name, signature, Klass::skip_overpass);
if (klass->oop_is_array()) {
// Only consider klass and super klass for arrays
- result = methodHandle(THREAD, result_oop);
- return;
+ return methodHandle(THREAD, result);
}
// JDK 8, JVMS 5.4.3.4: Interface method resolution should
// ignore static and non-public methods of java.lang.Object,
// like clone, finalize, registerNatives.
if (in_imethod_resolve &&
- result_oop != NULL &&
+ result != NULL &&
klass->is_interface() &&
- (result_oop->is_static() || !result_oop->is_public()) &&
- result_oop->method_holder() == SystemDictionary::Object_klass()) {
- result_oop = NULL;
+ (result->is_static() || !result->is_public()) &&
+ result->method_holder() == SystemDictionary::Object_klass()) {
+ result = NULL;
}
// Before considering default methods, check for an overpass in the
// current class if a method has not been found.
- if (result_oop == NULL) {
- result_oop = InstanceKlass::cast(klass())->find_method(name, signature);
+ if (result == NULL) {
+ result = InstanceKlass::cast(klass())->find_method(name, signature);
}
- if (result_oop == NULL) {
+ if (result == NULL) {
Array* default_methods = InstanceKlass::cast(klass())->default_methods();
if (default_methods != NULL) {
- result_oop = InstanceKlass::find_method(default_methods, name, signature);
+ result = InstanceKlass::find_method(default_methods, name, signature);
}
}
- if (checkpolymorphism && result_oop != NULL) {
- vmIntrinsics::ID iid = result_oop->intrinsic_id();
+ if (checkpolymorphism && result != NULL) {
+ vmIntrinsics::ID iid = result->intrinsic_id();
if (MethodHandles::is_signature_polymorphic(iid)) {
// Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method.
- return;
+ return NULL;
}
}
- result = methodHandle(THREAD, result_oop);
+ return methodHandle(THREAD, result);
}
// returns first instance method
// Looks up method in classes, then looks up local default methods
-void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
- Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::find_overpass);
- result = methodHandle(THREAD, result_oop);
- while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) {
- KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super());
- result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::find_overpass));
+methodHandle LinkResolver::lookup_instance_method_in_klasses(KlassHandle klass,
+ Symbol* name,
+ Symbol* signature, TRAPS) {
+ Method* result = klass->uncached_lookup_method(name, signature, Klass::find_overpass);
+
+ while (result != NULL && result->is_static() && result->method_holder()->super() != NULL) {
+ Klass* super_klass = result->method_holder()->super();
+ result = super_klass->uncached_lookup_method(name, signature, Klass::find_overpass);
}
if (klass->oop_is_array()) {
// Only consider klass and super klass for arrays
- return;
+ return methodHandle(THREAD, result);
}
- if (result.is_null()) {
+ if (result == NULL) {
Array* default_methods = InstanceKlass::cast(klass())->default_methods();
if (default_methods != NULL) {
- result = methodHandle(InstanceKlass::find_method(default_methods, name, signature));
- assert(result.is_null() || !result->is_static(), "static defaults not allowed");
+ result = InstanceKlass::find_method(default_methods, name, signature);
+ assert(result == NULL || !result->is_static(), "static defaults not allowed");
}
}
+ return methodHandle(THREAD, result);
}
int LinkResolver::vtable_index_of_interface_method(KlassHandle klass,
- methodHandle resolved_method) {
+ const methodHandle& resolved_method) {
int vtable_index = Method::invalid_vtable_index;
Symbol* name = resolved_method->name();
@@ -336,21 +393,26 @@
return vtable_index;
}
-void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
- InstanceKlass *ik = InstanceKlass::cast(klass());
+methodHandle LinkResolver::lookup_method_in_interfaces(const LinkInfo& cp_info, TRAPS) {
+ InstanceKlass *ik = InstanceKlass::cast(cp_info.resolved_klass()());
// Specify 'true' in order to skip default methods when searching the
// interfaces. Function lookup_method_in_klasses() already looked for
// the method in the default methods table.
- result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, Klass::skip_defaults));
+ return methodHandle(THREAD,
+ ik->lookup_method_in_all_interfaces(cp_info.name(), cp_info.signature(),
+ Klass::skip_defaults));
}
-void LinkResolver::lookup_polymorphic_method(methodHandle& result,
- KlassHandle klass, Symbol* name, Symbol* full_signature,
- KlassHandle current_klass,
+methodHandle LinkResolver::lookup_polymorphic_method(
+ const LinkInfo& link_info,
Handle *appendix_result_or_null,
Handle *method_type_result,
TRAPS) {
+ KlassHandle klass = link_info.resolved_klass();
+ Symbol* name = link_info.name();
+ Symbol* full_signature = link_info.signature();
+
vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name);
if (TraceMethodHandles) {
ResourceMark rm(THREAD);
@@ -365,7 +427,7 @@
// Do not erase last argument type (MemberName) if it is a static linkTo method.
bool keep_last_arg = MethodHandles::is_signature_polymorphic_static(iid);
TempNewSymbol basic_signature =
- MethodHandles::lookup_basic_type_signature(full_signature, keep_last_arg, CHECK);
+ MethodHandles::lookup_basic_type_signature(full_signature, keep_last_arg, CHECK_NULL);
if (TraceMethodHandles) {
ResourceMark rm(THREAD);
tty->print_cr("lookup_polymorphic_method %s %s => basic %s",
@@ -373,9 +435,9 @@
full_signature->as_C_string(),
basic_signature->as_C_string());
}
- result = SystemDictionary::find_method_handle_intrinsic(iid,
+ methodHandle result = SystemDictionary::find_method_handle_intrinsic(iid,
basic_signature,
- CHECK);
+ CHECK_NULL);
if (result.not_null()) {
assert(result->is_method_handle_intrinsic(), "MH.invokeBasic or MH.linkTo* intrinsic");
assert(result->intrinsic_id() != vmIntrinsics::_invokeGeneric, "wrong place to find this");
@@ -384,8 +446,8 @@
tty->print("lookup_polymorphic_method => intrinsic ");
result->print_on(tty);
}
- return;
}
+ return result;
} else if (iid == vmIntrinsics::_invokeGeneric
&& !THREAD->is_Compiler_thread()
&& appendix_result_or_null != NULL) {
@@ -399,18 +461,19 @@
Handle(),
Handle(),
true,
- CHECK);
+ CHECK_NULL);
}
}
Handle appendix;
Handle method_type;
- result = SystemDictionary::find_method_handle_invoker(name,
+ methodHandle result = SystemDictionary::find_method_handle_invoker(
+ name,
full_signature,
- current_klass,
+ link_info.current_klass(),
&appendix,
&method_type,
- CHECK);
+ CHECK_NULL);
if (TraceMethodHandles) {
tty->print("lookup_polymorphic_method => (via Java) ");
result->print_on(tty);
@@ -423,7 +486,7 @@
ResourceMark rm(THREAD);
TempNewSymbol basic_signature =
- MethodHandles::lookup_basic_type_signature(full_signature, CHECK);
+ MethodHandles::lookup_basic_type_signature(full_signature, CHECK_NULL);
int actual_size_of_params = result->size_of_parameters();
int expected_size_of_params = ArgumentSizeComputer(basic_signature).size();
// +1 for MethodHandle.this, +1 for trailing MethodType
@@ -441,16 +504,17 @@
assert(appendix_result_or_null != NULL, "");
(*appendix_result_or_null) = appendix;
(*method_type_result) = method_type;
- return;
}
+ return result;
}
}
+ return NULL;
}
void LinkResolver::check_method_accessability(KlassHandle ref_klass,
KlassHandle resolved_klass,
KlassHandle sel_klass,
- methodHandle sel_method,
+ const methodHandle& sel_method,
TRAPS) {
AccessFlags flags = sel_method->access_flags();
@@ -493,8 +557,8 @@
}
}
-void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass,
- Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) {
+methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code,
+ constantPoolHandle pool, int index, TRAPS) {
// This method is used only
// (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
// and
@@ -502,49 +566,108 @@
// It appears to fail when applied to an invokeinterface call site.
// FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
// resolve klass
+ KlassHandle resolved_klass;
if (code == Bytecodes::_invokedynamic) {
resolved_klass = SystemDictionary::MethodHandle_klass();
Symbol* method_name = vmSymbols::invoke_name();
Symbol* method_signature = pool->signature_ref_at(index);
KlassHandle current_klass(THREAD, pool->pool_holder());
- resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
- return;
+ LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
+ return resolve_method(link_info, /*require_methodref*/false, THREAD);
}
- resolve_klass(resolved_klass, pool, index, CHECK);
-
- Symbol* method_name = pool->name_ref_at(index);
- Symbol* method_signature = pool->signature_ref_at(index);
- KlassHandle current_klass(THREAD, pool->pool_holder());
+ LinkInfo link_info(pool, index, CHECK_NULL);
+ resolved_klass = link_info.resolved_klass();
if (pool->has_preresolution()
|| (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
- MethodHandles::is_signature_polymorphic_name(resolved_klass(), method_name))) {
- Method* result_oop = ConstantPool::method_at_if_loaded(pool, index);
- if (result_oop != NULL) {
- resolved_method = methodHandle(THREAD, result_oop);
- return;
+ MethodHandles::is_signature_polymorphic_name(resolved_klass(), link_info.name()))) {
+ Method* result = ConstantPool::method_at_if_loaded(pool, index);
+ if (result != NULL) {
+ return methodHandle(THREAD, result);
}
}
if (code == Bytecodes::_invokeinterface) {
- resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
+ return resolve_interface_method(link_info, true, THREAD);
} else if (code == Bytecodes::_invokevirtual) {
- resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
+ return resolve_method(link_info, /*require_methodref*/true, THREAD);
} else if (!resolved_klass->is_interface()) {
- resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
+ return resolve_method(link_info, /*require_methodref*/false, THREAD);
} else {
bool nostatics = (code == Bytecodes::_invokestatic) ? false : true;
- resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, nostatics, CHECK);
+ return resolve_interface_method(link_info, nostatics, THREAD);
}
}
-void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
- Symbol* method_name, Symbol* method_signature,
- KlassHandle current_klass, bool check_access,
- bool require_methodref, TRAPS) {
+// Check and print a loader constraint violation message for method or interface method
+void LinkResolver::check_method_loader_constraints(const LinkInfo& link_info,
+ const methodHandle& resolved_method,
+ const char* method_type, TRAPS) {
+ Handle current_loader(THREAD, link_info.current_klass()->class_loader());
+ Handle resolved_loader(THREAD, resolved_method->method_holder()->class_loader());
+
+ ResourceMark rm(THREAD);
+ Symbol* failed_type_symbol =
+ SystemDictionary::check_signature_loaders(link_info.signature(), current_loader,
+ resolved_loader, true, CHECK);
+ if (failed_type_symbol != NULL) {
+ const char* msg = "loader constraint violation: when resolving %s"
+ " \"%s\" the class loader (instance of %s) of the current class, %s,"
+ " and the class loader (instance of %s) for the method's defining class, %s, have"
+ " different Class objects for the type %s used in the signature";
+ char* sig = link_info.method_string();
+ const char* loader1_name = SystemDictionary::loader_name(current_loader());
+ char* current = link_info.current_klass()->name()->as_C_string();
+ const char* loader2_name = SystemDictionary::loader_name(resolved_loader());
+ char* target = resolved_method->method_holder()->name()->as_C_string();
+ char* failed_type_name = failed_type_symbol->as_C_string();
+ size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1_name) +
+ strlen(current) + strlen(loader2_name) + strlen(target) +
+ strlen(failed_type_name) + strlen(method_type) + 1;
+ char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
+ jio_snprintf(buf, buflen, msg, method_type, sig, loader1_name, current, loader2_name,
+ target, failed_type_name);
+ THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
+ }
+}
+
+void LinkResolver::check_field_loader_constraints(Symbol* field, Symbol* sig,
+ KlassHandle current_klass,
+ KlassHandle sel_klass, TRAPS) {
+ Handle ref_loader(THREAD, current_klass->class_loader());
+ Handle sel_loader(THREAD, sel_klass->class_loader());
+
+ ResourceMark rm(THREAD); // needed for check_signature_loaders
+ Symbol* failed_type_symbol =
+ SystemDictionary::check_signature_loaders(sig,
+ ref_loader, sel_loader,
+ false,
+ CHECK);
+ if (failed_type_symbol != NULL) {
+ const char* msg = "loader constraint violation: when resolving field"
+ " \"%s\" the class loader (instance of %s) of the referring class, "
+ "%s, and the class loader (instance of %s) for the field's resolved "
+ "type, %s, have different Class objects for that type";
+ char* field_name = field->as_C_string();
+ const char* loader1_name = SystemDictionary::loader_name(ref_loader());
+ char* sel = sel_klass->name()->as_C_string();
+ const char* loader2_name = SystemDictionary::loader_name(sel_loader());
+ char* failed_type_name = failed_type_symbol->as_C_string();
+ size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1_name) +
+ strlen(sel) + strlen(loader2_name) + strlen(failed_type_name) + 1;
+ char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
+ jio_snprintf(buf, buflen, msg, field_name, loader1_name, sel, loader2_name,
+ failed_type_name);
+ THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
+ }
+}
+
+methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
+ bool require_methodref, TRAPS) {
Handle nested_exception;
+ KlassHandle resolved_klass = link_info.resolved_klass();
// 1. check if methodref required, that resolved_klass is not interfacemethodref
if (require_methodref && resolved_klass->is_interface()) {
@@ -552,20 +675,19 @@
char buf[200];
jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
resolved_klass()->external_name());
- THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
+ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
// 2. lookup method in resolved klass and its super klasses
- lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK);
+ methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
if (resolved_method.is_null() && !resolved_klass->oop_is_array()) { // not found in the class hierarchy
// 3. lookup method in all the interfaces implemented by the resolved klass
- lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
+ resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
if (resolved_method.is_null()) {
// JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
- lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
- current_klass, (Handle*)NULL, (Handle*)NULL, THREAD);
+ resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
if (HAS_PENDING_EXCEPTION) {
nested_exception = Handle(THREAD, PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
@@ -576,15 +698,16 @@
if (resolved_method.is_null()) {
// 4. method lookup failed
ResourceMark rm(THREAD);
- THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
+ THROW_MSG_CAUSE_(vmSymbols::java_lang_NoSuchMethodError(),
Method::name_and_sig_as_C_string(resolved_klass(),
- method_name,
- method_signature),
- nested_exception);
+ link_info.name(),
+ link_info.signature()),
+ nested_exception, NULL);
}
// 5. access checks, access checking may be turned off when calling from within the VM.
- if (check_access) {
+ KlassHandle current_klass = link_info.current_klass();
+ if (link_info.check_access()) {
assert(current_klass.not_null() , "current_klass should not be null");
// check if method can be accessed by the referring class
@@ -592,76 +715,50 @@
resolved_klass,
KlassHandle(THREAD, resolved_method->method_holder()),
resolved_method,
- CHECK);
+ CHECK_NULL);
// check loader constraints
- Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
- Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
- {
- ResourceMark rm(THREAD);
- Symbol* failed_type_symbol =
- SystemDictionary::check_signature_loaders(method_signature, loader,
- class_loader, true, CHECK);
- if (failed_type_symbol != NULL) {
- const char* msg = "loader constraint violation: when resolving method"
- " \"%s\" the class loader (instance of %s) of the current class, %s,"
- " and the class loader (instance of %s) for the method's defining class, %s, have"
- " different Class objects for the type %s used in the signature";
- char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature);
- const char* loader1 = SystemDictionary::loader_name(loader());
- char* current = InstanceKlass::cast(current_klass())->name()->as_C_string();
- const char* loader2 = SystemDictionary::loader_name(class_loader());
- char* target = InstanceKlass::cast(resolved_method->method_holder())
- ->name()->as_C_string();
- char* failed_type_name = failed_type_symbol->as_C_string();
- size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
- strlen(current) + strlen(loader2) + strlen(target) +
- strlen(failed_type_name) + 1;
- char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
- jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
- target, failed_type_name);
- THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
- }
- }
+ check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL);
}
+
+ return resolved_method;
}
-void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
- KlassHandle resolved_klass,
- Symbol* method_name,
- Symbol* method_signature,
- KlassHandle current_klass,
- bool check_access,
- bool nostatics, TRAPS) {
+methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
+ bool nostatics, TRAPS) {
+
+ KlassHandle resolved_klass = link_info.resolved_klass();
// check if klass is interface
if (!resolved_klass->is_interface()) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
- THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
+ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
// lookup method in this interface or its super, java.lang.Object
// JDK8: also look for static methods
- lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK);
+ methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
if (resolved_method.is_null() && !resolved_klass->oop_is_array()) {
// lookup method in all the super-interfaces
- lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
+ resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
}
if (resolved_method.is_null()) {
// no method found
ResourceMark rm(THREAD);
- THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
- Method::name_and_sig_as_C_string(resolved_klass(),
- method_name,
- method_signature));
+ THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(),
+ Method::name_and_sig_as_C_string(resolved_klass(),
+ link_info.name(),
+ link_info.signature()));
}
- if (check_access) {
+ if (link_info.check_access()) {
// JDK8 adds non-public interface methods, and accessability check requirement
+ KlassHandle current_klass = link_info.current_klass();
+
assert(current_klass.not_null() , "current_klass should not be null");
// check if method can be accessed by the referring class
@@ -669,38 +766,9 @@
resolved_klass,
KlassHandle(THREAD, resolved_method->method_holder()),
resolved_method,
- CHECK);
+ CHECK_NULL);
- HandleMark hm(THREAD);
- Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
- Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
- {
- ResourceMark rm(THREAD);
- Symbol* failed_type_symbol =
- SystemDictionary::check_signature_loaders(method_signature, loader,
- class_loader, true, CHECK);
- if (failed_type_symbol != NULL) {
- const char* msg = "loader constraint violation: when resolving "
- "interface method \"%s\" the class loader (instance of %s) of the "
- "current class, %s, and the class loader (instance of %s) for "
- "the method's defining class, %s, have different Class objects for the type %s "
- "used in the signature";
- char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature);
- const char* loader1 = SystemDictionary::loader_name(loader());
- char* current = InstanceKlass::cast(current_klass())->name()->as_C_string();
- const char* loader2 = SystemDictionary::loader_name(class_loader());
- char* target = InstanceKlass::cast(resolved_method->method_holder())
- ->name()->as_C_string();
- char* failed_type_name = failed_type_symbol->as_C_string();
- size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
- strlen(current) + strlen(loader2) + strlen(target) +
- strlen(failed_type_name) + 1;
- char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
- jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
- target, failed_type_name);
- THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
- }
- }
+ check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL);
}
if (nostatics && resolved_method->is_static()) {
@@ -709,28 +777,16 @@
jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
Method::name_and_sig_as_C_string(resolved_klass(),
resolved_method->name(), resolved_method->signature()));
- THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
+ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
if (TraceItables && Verbose) {
- ResourceMark rm(THREAD);
- tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
- (current_klass.is_null() ? "" : current_klass->internal_name()),
- (resolved_klass.is_null() ? "" : resolved_klass->internal_name()),
- Method::name_and_sig_as_C_string(resolved_klass(),
- resolved_method->name(),
- resolved_method->signature()),
- resolved_method->method_holder()->internal_name()
- );
- resolved_method->access_flags().print_on(tty);
- if (resolved_method->is_default_method()) {
- tty->print("default ");
- }
- if (resolved_method->is_overpass()) {
- tty->print("overpass");
- }
+ trace_method_resolution("invokeinterface resolved method: caller-class",
+ link_info.current_klass(), resolved_klass, resolved_method);
tty->cr();
}
+
+ return resolved_method;
}
//------------------------------------------------------------------------------------------------------------------------
@@ -739,7 +795,7 @@
void LinkResolver::check_field_accessability(KlassHandle ref_klass,
KlassHandle resolved_klass,
KlassHandle sel_klass,
- fieldDescriptor& fd,
+ const fieldDescriptor& fd,
TRAPS) {
if (!Reflection::verify_field_access(ref_klass(),
resolved_klass(),
@@ -759,30 +815,27 @@
}
}
-void LinkResolver::resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
- // Load these early in case the resolve of the containing klass fails
- Symbol* field = pool->name_ref_at(index);
- Symbol* sig = pool->signature_ref_at(index);
-
- // resolve specified klass
- KlassHandle resolved_klass;
- resolve_klass(resolved_klass, pool, index, CHECK);
-
- KlassHandle current_klass(THREAD, pool->pool_holder());
- resolve_field(result, resolved_klass, field, sig, current_klass, byte, true, true, CHECK);
+void LinkResolver::resolve_field_access(fieldDescriptor& fd, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
+ LinkInfo link_info(pool, index, CHECK);
+ resolve_field(fd, link_info, byte, true, CHECK);
}
-void LinkResolver::resolve_field(fieldDescriptor& fd, KlassHandle resolved_klass, Symbol* field, Symbol* sig,
- KlassHandle current_klass, Bytecodes::Code byte, bool check_access, bool initialize_class,
+void LinkResolver::resolve_field(fieldDescriptor& fd,
+ const LinkInfo& link_info,
+ Bytecodes::Code byte, bool initialize_class,
TRAPS) {
assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
byte == Bytecodes::_getfield || byte == Bytecodes::_putfield ||
byte == Bytecodes::_nofast_getfield || byte == Bytecodes::_nofast_putfield ||
- (byte == Bytecodes::_nop && !check_access), "bad field access bytecode");
+ (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);
// Check if there's a resolved klass containing the field
+ KlassHandle resolved_klass = link_info.resolved_klass();
+ Symbol* field = link_info.name();
+ Symbol* sig = link_info.signature();
+
if (resolved_klass.is_null()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
@@ -796,11 +849,12 @@
THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
}
- if (!check_access)
+ if (!link_info.check_access())
// Access checking may be turned off when calling from within the VM.
return;
// check access
+ KlassHandle current_klass = link_info.current_klass();
check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
// check for errors
@@ -827,34 +881,7 @@
}
if (sel_klass() != current_klass()) {
- HandleMark hm(THREAD);
- Handle ref_loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
- Handle sel_loader (THREAD, InstanceKlass::cast(sel_klass())->class_loader());
- {
- ResourceMark rm(THREAD);
- Symbol* failed_type_symbol =
- SystemDictionary::check_signature_loaders(sig,
- ref_loader, sel_loader,
- false,
- CHECK);
- if (failed_type_symbol != NULL) {
- const char* msg = "loader constraint violation: when resolving field"
- " \"%s\" the class loader (instance of %s) of the referring class, "
- "%s, and the class loader (instance of %s) for the field's resolved "
- "type, %s, have different Class objects for that type";
- char* field_name = field->as_C_string();
- const char* loader1 = SystemDictionary::loader_name(ref_loader());
- char* sel = InstanceKlass::cast(sel_klass())->name()->as_C_string();
- const char* loader2 = SystemDictionary::loader_name(sel_loader());
- char* failed_type_name = failed_type_symbol->as_C_string();
- size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) +
- strlen(sel) + strlen(loader2) + strlen(failed_type_name) + 1;
- char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
- jio_snprintf(buf, buflen, msg, field_name, loader1, sel, loader2,
- failed_type_name);
- THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
- }
- }
+ check_field_loader_constraints(field, sig, current_klass, sel_klass, CHECK);
}
// return information. note that the klass is set to the actual klass containing the
@@ -873,32 +900,38 @@
// recv_klass the receiver klass
-void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name,
- Symbol* method_signature, KlassHandle current_klass,
- bool check_access, bool initialize_class, TRAPS) {
- methodHandle resolved_method;
- linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
- resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
+void LinkResolver::resolve_static_call(CallInfo& result,
+ const LinkInfo& link_info,
+ bool initialize_class, TRAPS) {
+ methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK);
+ // The resolved class can change as a result of this resolution.
+ KlassHandle resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
+
+ Method* save_resolved_method = resolved_method();
// Initialize klass (this should only happen if everything is ok)
if (initialize_class && resolved_klass->should_be_initialized()) {
resolved_klass->initialize(CHECK);
- linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
+ // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
+ LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
+ link_info.current_klass(), link_info.check_access());
+ resolved_method = linktime_resolve_static_method(new_info, CHECK);
}
+ assert(save_resolved_method == resolved_method(), "does this change?");
// setup result
result.set_static(resolved_klass, resolved_method, CHECK);
}
// throws linktime exceptions
-void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass,
- Symbol* method_name, Symbol* method_signature,
- KlassHandle current_klass, bool check_access, TRAPS) {
+methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
+ KlassHandle resolved_klass = link_info.resolved_klass();
+ methodHandle resolved_method;
if (!resolved_klass->is_interface()) {
- resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
+ resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
} else {
- resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
+ resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL);
}
assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
@@ -909,22 +942,25 @@
jio_snprintf(buf, sizeof(buf), "Expected static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
resolved_method->name(),
resolved_method->signature()));
- THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
+ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
+ return resolved_method;
}
-void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, Symbol* method_name,
- Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
- methodHandle resolved_method;
- linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
- runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK);
+void LinkResolver::resolve_special_call(CallInfo& result,
+ const LinkInfo& link_info,
+ TRAPS) {
+ methodHandle resolved_method = linktime_resolve_special_method(link_info, CHECK);
+ runtime_resolve_special_method(result, resolved_method,
+ link_info.resolved_klass(),
+ link_info.current_klass(),
+ link_info.check_access(), CHECK);
}
// throws linktime exceptions
-void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass,
- Symbol* method_name, Symbol* method_signature,
- KlassHandle current_klass, bool check_access, TRAPS) {
+methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info,
+ TRAPS) {
// Invokespecial is called for multiple special reasons:
//
@@ -932,11 +968,13 @@
// superclass.method, which can also resolve to a default method
// and the selected method is recalculated relative to the direct superclass
// superinterface.method, which explicitly does not check shadowing
+ KlassHandle resolved_klass = link_info.resolved_klass();
+ methodHandle resolved_method;
if (!resolved_klass->is_interface()) {
- resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
+ resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
} else {
- resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
+ resolved_method = resolve_interface_method(link_info, /*nostatics*/true, CHECK_NULL);
}
// check if method name is , that it is found in same klass as static type
@@ -951,10 +989,11 @@
resolved_method->name()->as_C_string(),
resolved_method->signature()->as_C_string()
);
- return;
+ return NULL;
}
// check if invokespecial's interface method reference is in an indirect superinterface
+ KlassHandle current_klass = link_info.current_klass();
if (!current_klass.is_null() && resolved_klass->is_interface()) {
Klass *klass_to_check = !InstanceKlass::cast(current_klass())->is_anonymous() ?
current_klass() :
@@ -973,7 +1012,7 @@
resolved_method->name(),
resolved_method->signature()),
current_klass->external_name());
- THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
+ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
}
@@ -984,35 +1023,26 @@
jio_snprintf(buf, sizeof(buf),
"Expecting non-static method %s",
Method::name_and_sig_as_C_string(resolved_klass(),
- resolved_method->name(),
- resolved_method->signature()));
- THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
+ resolved_method->name(),
+ resolved_method->signature()));
+ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
if (TraceItables && Verbose) {
- ResourceMark rm(THREAD);
- tty->print("invokespecial resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
- (current_klass.is_null() ? "" : current_klass->internal_name()),
- (resolved_klass.is_null() ? "" : resolved_klass->internal_name()),
- Method::name_and_sig_as_C_string(resolved_klass(),
- resolved_method->name(),
- resolved_method->signature()),
- resolved_method->method_holder()->internal_name()
- );
- resolved_method->access_flags().print_on(tty);
- if (resolved_method->is_default_method()) {
- tty->print("default ");
- }
- if (resolved_method->is_overpass()) {
- tty->print("overpass");
- }
+ trace_method_resolution("invokespecial resolved method: caller-class:",
+ current_klass, resolved_klass, resolved_method);
tty->cr();
}
+
+ return resolved_method;
}
// throws runtime exceptions
-void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
- KlassHandle current_klass, bool check_access, TRAPS) {
+void LinkResolver::runtime_resolve_special_method(CallInfo& result,
+ const methodHandle& resolved_method,
+ KlassHandle resolved_klass,
+ KlassHandle current_klass,
+ bool check_access, TRAPS) {
// resolved method is selected method unless we have an old-style lookup
// for a superclass method
@@ -1037,7 +1067,7 @@
resolved_method->name() != vmSymbols::object_initializer_name()) {
// Lookup super method
KlassHandle super_klass(THREAD, current_klass->super());
- lookup_instance_method_in_klasses(sel_method, super_klass,
+ sel_method = lookup_instance_method_in_klasses(super_klass,
resolved_method->name(),
resolved_method->signature(), CHECK);
// check if found
@@ -1066,26 +1096,13 @@
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
Method::name_and_sig_as_C_string(resolved_klass(),
- sel_method->name(),
- sel_method->signature()));
+ sel_method->name(),
+ sel_method->signature()));
}
if (TraceItables && Verbose) {
- ResourceMark rm(THREAD);
- tty->print("invokespecial selected method: resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
- (resolved_klass.is_null() ? "" : resolved_klass->internal_name()),
- Method::name_and_sig_as_C_string(resolved_klass(),
- sel_method->name(),
- sel_method->signature()),
- sel_method->method_holder()->internal_name()
- );
- sel_method->access_flags().print_on(tty);
- if (sel_method->is_default_method()) {
- tty->print("default ");
- }
- if (sel_method->is_overpass()) {
- tty->print("overpass");
- }
+ trace_method_resolution("invokespecial selected method: resolved-class:",
+ resolved_klass, resolved_klass, sel_method);
tty->cr();
}
@@ -1093,25 +1110,29 @@
result.set_static(resolved_klass, sel_method, CHECK);
}
-void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass,
- Symbol* method_name, Symbol* method_signature, KlassHandle current_klass,
- bool check_access, bool check_null_and_abstract, TRAPS) {
- methodHandle resolved_method;
- linktime_resolve_virtual_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
- runtime_resolve_virtual_method(result, resolved_method, resolved_klass, recv, receiver_klass, check_null_and_abstract, CHECK);
+void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass,
+ const LinkInfo& link_info,
+ bool check_null_and_abstract, TRAPS) {
+ methodHandle resolved_method = linktime_resolve_virtual_method(link_info, CHECK);
+ runtime_resolve_virtual_method(result, resolved_method,
+ link_info.resolved_klass(),
+ recv, receiver_klass,
+ check_null_and_abstract, CHECK);
}
// throws linktime exceptions
-void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method, KlassHandle resolved_klass,
- Symbol* method_name, Symbol* method_signature,
- KlassHandle current_klass, bool check_access, TRAPS) {
+methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info,
+ TRAPS) {
// normal method resolution
- resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
+ methodHandle resolved_method = resolve_method(link_info, /*require_methodref*/true, CHECK_NULL);
assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
// check if private interface method
+ KlassHandle resolved_klass = link_info.resolved_klass();
+ KlassHandle current_klass = link_info.current_klass();
+
if (resolved_klass->is_interface() && resolved_method->is_private()) {
ResourceMark rm(THREAD);
char buf[200];
@@ -1120,7 +1141,7 @@
resolved_method->name(),
resolved_method->signature()),
(current_klass.is_null() ? "" : current_klass->internal_name()));
- THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
+ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
// check if not static
@@ -1130,33 +1151,21 @@
jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
resolved_method->name(),
resolved_method->signature()));
- THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
+ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
if (PrintVtables && Verbose) {
- ResourceMark rm(THREAD);
- tty->print("invokevirtual resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
- (current_klass.is_null() ? "" : current_klass->internal_name()),
- (resolved_klass.is_null() ? "" : resolved_klass->internal_name()),
- Method::name_and_sig_as_C_string(resolved_klass(),
- resolved_method->name(),
- resolved_method->signature()),
- resolved_method->method_holder()->internal_name()
- );
- resolved_method->access_flags().print_on(tty);
- if (resolved_method->is_default_method()) {
- tty->print("default ");
- }
- if (resolved_method->is_overpass()) {
- tty->print("overpass");
- }
+ trace_method_resolution("invokevirtual resolved method: caller-class:",
+ current_klass, resolved_klass, resolved_method);
tty->cr();
}
+
+ return resolved_method;
}
// throws runtime exceptions
void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
- methodHandle resolved_method,
+ const methodHandle& resolved_method,
KlassHandle resolved_klass,
Handle recv,
KlassHandle recv_klass,
@@ -1227,50 +1236,40 @@
}
if (PrintVtables && Verbose) {
- ResourceMark rm(THREAD);
- tty->print("invokevirtual selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, vtable_index:%d, access_flags: ",
- (recv_klass.is_null() ? "" : recv_klass->internal_name()),
- (resolved_klass.is_null() ? "" : resolved_klass->internal_name()),
- Method::name_and_sig_as_C_string(resolved_klass(),
- resolved_method->name(),
- resolved_method->signature()),
- selected_method->method_holder()->internal_name(),
- vtable_index
- );
- selected_method->access_flags().print_on(tty);
- if (selected_method->is_default_method()) {
- tty->print("default ");
- }
- if (selected_method->is_overpass()) {
- tty->print("overpass");
- }
- tty->cr();
+ trace_method_resolution("invokevirtual selected method: receiver-class:",
+ recv_klass, resolved_klass, selected_method);
+ tty->print_cr("vtable_index:%d", vtable_index);
}
// setup result
result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
}
-void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass,
- Symbol* method_name, Symbol* method_signature, KlassHandle current_klass,
- bool check_access, bool check_null_and_abstract, TRAPS) {
- methodHandle resolved_method;
- linktime_resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
- runtime_resolve_interface_method(result, resolved_method, resolved_klass, recv, recv_klass, check_null_and_abstract, CHECK);
+void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass,
+ const LinkInfo& link_info,
+ bool check_null_and_abstract, TRAPS) {
+ // throws linktime exceptions
+ methodHandle resolved_method = linktime_resolve_interface_method(link_info, CHECK);
+ runtime_resolve_interface_method(result, resolved_method,link_info.resolved_klass(),
+ recv, recv_klass, check_null_and_abstract, CHECK);
}
-// throws linktime exceptions
-void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name,
- Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
+methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info,
+ TRAPS) {
// normal interface method resolution
- resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
-
+ methodHandle resolved_method = resolve_interface_method(link_info, true, CHECK_NULL);
assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
+
+ return resolved_method;
}
// throws runtime exceptions
-void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
- Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) {
+void LinkResolver::runtime_resolve_interface_method(CallInfo& result,
+ const methodHandle& resolved_method,
+ KlassHandle resolved_klass,
+ Handle recv,
+ KlassHandle recv_klass,
+ bool check_null_and_abstract, TRAPS) {
// check if receiver exists
if (check_null_and_abstract && recv.is_null()) {
THROW(vmSymbols::java_lang_NullPointerException());
@@ -1298,12 +1297,11 @@
}
// do lookup based on receiver klass
- methodHandle sel_method;
// This search must match the linktime preparation search for itable initialization
// to correctly enforce loader constraints for interface method inheritance
- lookup_instance_method_in_klasses(sel_method, recv_klass,
- resolved_method->name(),
- resolved_method->signature(), CHECK);
+ methodHandle sel_method = lookup_instance_method_in_klasses(recv_klass,
+ resolved_method->name(),
+ resolved_method->signature(), CHECK);
if (sel_method.is_null() && !check_null_and_abstract) {
// In theory this is a harmless placeholder value, but
// in practice leaving in null affects the nsk default method tests.
@@ -1314,9 +1312,9 @@
if (sel_method.is_null()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
- Method::name_and_sig_as_C_string(recv_klass(),
- resolved_method->name(),
- resolved_method->signature()));
+ Method::name_and_sig_as_C_string(recv_klass(),
+ resolved_method->name(),
+ resolved_method->signature()));
}
// check access
// Throw Illegal Access Error if sel_method is not public.
@@ -1337,22 +1335,8 @@
}
if (TraceItables && Verbose) {
- ResourceMark rm(THREAD);
- tty->print("invokeinterface selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
- (recv_klass.is_null() ? "" : recv_klass->internal_name()),
- (resolved_klass.is_null() ? "" : resolved_klass->internal_name()),
- Method::name_and_sig_as_C_string(resolved_klass(),
- resolved_method->name(),
- resolved_method->signature()),
- sel_method->method_holder()->internal_name()
- );
- sel_method->access_flags().print_on(tty);
- if (sel_method->is_default_method()) {
- tty->print("default ");
- }
- if (sel_method->is_overpass()) {
- tty->print("overpass");
- }
+ trace_method_resolution("invokeinterface selected method: receiver-class",
+ recv_klass, resolved_klass, sel_method);
tty->cr();
}
// setup result
@@ -1368,14 +1352,9 @@
methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
- KlassHandle resolved_klass,
- Symbol* method_name,
- Symbol* method_signature,
- KlassHandle current_klass,
- bool check_access) {
+ const LinkInfo& link_info) {
EXCEPTION_MARK;
- methodHandle method_result;
- linktime_resolve_interface_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD);
+ methodHandle method_result = linktime_resolve_interface_method(link_info, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return methodHandle();
@@ -1385,14 +1364,9 @@
}
methodHandle LinkResolver::linktime_resolve_virtual_method_or_null(
- KlassHandle resolved_klass,
- Symbol* method_name,
- Symbol* method_signature,
- KlassHandle current_klass,
- bool check_access) {
+ const LinkInfo& link_info) {
EXCEPTION_MARK;
- methodHandle method_result;
- linktime_resolve_virtual_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD);
+ methodHandle method_result = linktime_resolve_virtual_method(link_info, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return methodHandle();
@@ -1403,14 +1377,10 @@
methodHandle LinkResolver::resolve_virtual_call_or_null(
KlassHandle receiver_klass,
- KlassHandle resolved_klass,
- Symbol* name,
- Symbol* signature,
- KlassHandle current_klass,
- bool check_access) {
+ const LinkInfo& link_info) {
EXCEPTION_MARK;
CallInfo info;
- resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, check_access, false, THREAD);
+ resolve_virtual_call(info, Handle(), receiver_klass, link_info, false, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return methodHandle();
@@ -1420,14 +1390,10 @@
methodHandle LinkResolver::resolve_interface_call_or_null(
KlassHandle receiver_klass,
- KlassHandle resolved_klass,
- Symbol* name,
- Symbol* signature,
- KlassHandle current_klass,
- bool check_access) {
+ const LinkInfo& link_info) {
EXCEPTION_MARK;
CallInfo info;
- resolve_interface_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, check_access, false, THREAD);
+ resolve_interface_call(info, Handle(), receiver_klass, link_info, false, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return methodHandle();
@@ -1435,15 +1401,12 @@
return info.selected_method();
}
-int LinkResolver::resolve_virtual_vtable_index(
- KlassHandle receiver_klass,
- KlassHandle resolved_klass,
- Symbol* name,
- Symbol* signature,
- KlassHandle current_klass) {
+int LinkResolver::resolve_virtual_vtable_index(KlassHandle receiver_klass,
+ const LinkInfo& link_info) {
EXCEPTION_MARK;
CallInfo info;
- resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD);
+ resolve_virtual_call(info, Handle(), receiver_klass, link_info,
+ /*check_null_or_abstract*/false, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return Method::invalid_vtable_index;
@@ -1451,15 +1414,10 @@
return info.vtable_index();
}
-methodHandle LinkResolver::resolve_static_call_or_null(
- KlassHandle resolved_klass,
- Symbol* name,
- Symbol* signature,
- KlassHandle current_klass,
- bool check_access) {
+methodHandle LinkResolver::resolve_static_call_or_null(const LinkInfo& link_info) {
EXCEPTION_MARK;
CallInfo info;
- resolve_static_call(info, resolved_klass, name, signature, current_klass, check_access, false, THREAD);
+ resolve_static_call(info, link_info, /*initialize_class*/false, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return methodHandle();
@@ -1467,15 +1425,10 @@
return info.selected_method();
}
-methodHandle LinkResolver::resolve_special_call_or_null(
- KlassHandle resolved_klass,
- Symbol* name,
- Symbol* signature,
- KlassHandle current_klass,
- bool check_access) {
+methodHandle LinkResolver::resolve_special_call_or_null(const LinkInfo& link_info) {
EXCEPTION_MARK;
CallInfo info;
- resolve_special_call(info, resolved_klass, name, signature, current_klass, check_access, THREAD);
+ resolve_special_call(info, link_info, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return methodHandle();
@@ -1500,35 +1453,15 @@
return;
}
-void LinkResolver::resolve_pool(KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature,
- KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS) {
- // resolve klass
- resolve_klass(resolved_klass, pool, index, CHECK);
-
- // Get name, signature, and static klass
- method_name = pool->name_ref_at(index);
- method_signature = pool->signature_ref_at(index);
- current_klass = KlassHandle(THREAD, pool->pool_holder());
-}
-
-
void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
- KlassHandle resolved_klass;
- Symbol* method_name = NULL;
- Symbol* method_signature = NULL;
- KlassHandle current_klass;
- resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
- resolve_static_call(result, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
+ LinkInfo link_info(pool, index, CHECK);
+ resolve_static_call(result, link_info, /*initialize_class*/true, CHECK);
}
void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
- KlassHandle resolved_klass;
- Symbol* method_name = NULL;
- Symbol* method_signature = NULL;
- KlassHandle current_klass;
- resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
- resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
+ LinkInfo link_info(pool, index, CHECK);
+ resolve_special_call(result, link_info, CHECK);
}
@@ -1536,54 +1469,40 @@
constantPoolHandle pool, int index,
TRAPS) {
- KlassHandle resolved_klass;
- Symbol* method_name = NULL;
- Symbol* method_signature = NULL;
- KlassHandle current_klass;
- resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
+ LinkInfo link_info(pool, index, CHECK);
KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass());
- resolve_virtual_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
+ resolve_virtual_call(result, recv, recvrKlass, link_info, /*check_null_or_abstract*/true, CHECK);
}
void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) {
- KlassHandle resolved_klass;
- Symbol* method_name = NULL;
- Symbol* method_signature = NULL;
- KlassHandle current_klass;
- resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
+ LinkInfo link_info(pool, index, CHECK);
KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass());
- resolve_interface_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
+ resolve_interface_call(result, recv, recvrKlass, link_info, true, CHECK);
}
void LinkResolver::resolve_invokehandle(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
// This guy is reached from InterpreterRuntime::resolve_invokehandle.
- KlassHandle resolved_klass;
- Symbol* method_name = NULL;
- Symbol* method_signature = NULL;
- KlassHandle current_klass;
- resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
+ LinkInfo link_info(pool, index, CHECK);
if (TraceMethodHandles) {
ResourceMark rm(THREAD);
- tty->print_cr("resolve_invokehandle %s %s", method_name->as_C_string(), method_signature->as_C_string());
+ tty->print_cr("resolve_invokehandle %s %s", link_info.name()->as_C_string(),
+ link_info.signature()->as_C_string());
}
- resolve_handle_call(result, resolved_klass, method_name, method_signature, current_klass, CHECK);
+ resolve_handle_call(result, link_info, CHECK);
}
-void LinkResolver::resolve_handle_call(CallInfo& result, KlassHandle resolved_klass,
- Symbol* method_name, Symbol* method_signature,
- KlassHandle current_klass,
+void LinkResolver::resolve_handle_call(CallInfo& result,
+ const LinkInfo& link_info,
TRAPS) {
// JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar
- assert(resolved_klass() == SystemDictionary::MethodHandle_klass(), "");
- assert(MethodHandles::is_signature_polymorphic_name(method_name), "");
- methodHandle resolved_method;
+ assert(link_info.resolved_klass()() == SystemDictionary::MethodHandle_klass(), "");
+ assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), "");
Handle resolved_appendix;
Handle resolved_method_type;
- lookup_polymorphic_method(resolved_method, resolved_klass,
- method_name, method_signature,
- current_klass, &resolved_appendix, &resolved_method_type, CHECK);
+ methodHandle resolved_method = lookup_polymorphic_method(link_info,
+ &resolved_appendix, &resolved_method_type, CHECK);
result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK);
}
@@ -1609,7 +1528,6 @@
}
void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
- //resolve_pool(, method_name, method_signature, current_klass, pool, index, CHECK);
Symbol* method_name = pool->name_ref_at(index);
Symbol* method_signature = pool->signature_ref_at(index);
KlassHandle current_klass = KlassHandle(THREAD, pool->pool_holder());
@@ -1667,19 +1585,27 @@
wrap_invokedynamic_exception(CHECK);
}
-//------------------------------------------------------------------------------------------------------------------------
#ifndef PRODUCT
-
-void CallInfo::print() {
+void LinkResolver::trace_method_resolution(const char* prefix,
+ KlassHandle klass,
+ KlassHandle resolved_klass,
+ const methodHandle& method) {
ResourceMark rm;
- const char* kindstr = "unknown";
- switch (_call_kind) {
- case direct_call: kindstr = "direct"; break;
- case vtable_call: kindstr = "vtable"; break;
- case itable_call: kindstr = "itable"; break;
+ tty->print("%s%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
+ prefix,
+ (klass.is_null() ? "" : klass->internal_name()),
+ (resolved_klass.is_null() ? "" : resolved_klass->internal_name()),
+ Method::name_and_sig_as_C_string(resolved_klass(),
+ method->name(),
+ method->signature()),
+ method->method_holder()->internal_name()
+ );
+ method->access_flags().print_on(tty);
+ if (method->is_default_method()) {
+ tty->print("default ");
}
- tty->print_cr("Call %s@%d %s", kindstr, _call_index,
- _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
+ if (method->is_overpass()) {
+ tty->print("overpass ");
+ }
}
-
-#endif
+#endif // PRODUCT
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/interpreter/linkResolver.hpp
--- a/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -36,7 +36,7 @@
// that method. If the info is invalid, the link has not been resolved
// successfully.
-class CallInfo VALUE_OBJ_CLASS_SPEC {
+class CallInfo : public StackObj {
public:
// Ways that a method call might be selected (or not) based on receiver type.
// Note that an invokevirtual instruction might be linked with no_dispatch,
@@ -58,11 +58,22 @@
Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix)
Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites)
- void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS);
- void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index , TRAPS);
- void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS);
- void set_handle( methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS);
- void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, CallKind kind, int index, TRAPS);
+ void set_static(KlassHandle resolved_klass, const methodHandle& resolved_method, TRAPS);
+ void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass,
+ const methodHandle& resolved_method,
+ const methodHandle& selected_method,
+ int itable_index, TRAPS);
+ void set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass,
+ const methodHandle& resolved_method,
+ const methodHandle& selected_method,
+ int vtable_index, TRAPS);
+ void set_handle(const methodHandle& resolved_method,
+ Handle resolved_appendix, Handle resolved_method_type, TRAPS);
+ void set_common(KlassHandle resolved_klass, KlassHandle selected_klass,
+ const methodHandle& resolved_method,
+ const methodHandle& selected_method,
+ CallKind kind,
+ int index, TRAPS);
friend class LinkResolver;
@@ -113,6 +124,37 @@
void print() PRODUCT_RETURN;
};
+
+// Condensed information from constant pool to use to resolve the method or field.
+// resolved_klass = specified class (i.e., static receiver class)
+// current_klass = sending method holder (i.e., class containing the method
+// containing the call being resolved)
+class LinkInfo : public StackObj {
+ Symbol* _name; // extracted from JVM_CONSTANT_NameAndType
+ Symbol* _signature;
+ KlassHandle _resolved_klass; // class that the constant pool entry points to
+ KlassHandle _current_klass; // class that owns the constant pool
+ bool _check_access;
+ public:
+ LinkInfo(constantPoolHandle pool, int index, TRAPS);
+ // Condensed information from other call sites within the vm.
+ LinkInfo(KlassHandle resolved_klass, Symbol* name, Symbol* signature,
+ KlassHandle current_klass, bool check_access = true) :
+ _resolved_klass(resolved_klass),
+ _name(name), _signature(signature), _current_klass(current_klass),
+ _check_access(check_access) {}
+
+ // accessors
+ Symbol* name() const { return _name; }
+ Symbol* signature() const { return _signature; }
+ KlassHandle resolved_klass() const { return _resolved_klass; }
+ KlassHandle current_klass() const { return _current_klass; }
+ bool check_access() const { return _check_access; }
+ char* method_string() const;
+
+ void print() PRODUCT_RETURN;
+};
+
// Link information for getfield/putfield & getstatic/putstatic bytecodes
// is represented using a fieldDescriptor.
@@ -124,85 +166,136 @@
friend class klassItable;
private:
- static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS);
- static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
- static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
- static void lookup_polymorphic_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature,
- KlassHandle current_klass, Handle *appendix_result_or_null, Handle *method_type_result, TRAPS);
+
+ static methodHandle lookup_method_in_klasses(const LinkInfo& link_info,
+ bool checkpolymorphism,
+ bool in_imethod_resolve, TRAPS);
+ static methodHandle lookup_method_in_interfaces(const LinkInfo& link_info, TRAPS);
+ static methodHandle lookup_polymorphic_method(const LinkInfo& link_info,
+ Handle *appendix_result_or_null,
+ Handle *method_type_result, TRAPS);
+ // Not Linktime so doesn't take LinkInfo
+ static methodHandle lookup_instance_method_in_klasses (
+ KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
- static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS);
+ // Similar loader constraint checking functions that throw
+ // LinkageError with descriptive message.
+ static void check_method_loader_constraints(const LinkInfo& link_info,
+ const methodHandle& resolved_method,
+ const char* method_type, TRAPS);
+ static void check_field_loader_constraints(Symbol* field, Symbol* sig,
+ KlassHandle current_klass,
+ KlassHandle sel_klass, TRAPS);
- static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
+ static methodHandle resolve_interface_method(const LinkInfo& link_info, bool nostatics, TRAPS);
+ static methodHandle resolve_method (const LinkInfo& link_info, bool require_methodref, TRAPS);
- static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool nostatics, TRAPS);
- static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool require_methodref, TRAPS);
+ static methodHandle linktime_resolve_static_method (const LinkInfo& link_info, TRAPS);
+ static methodHandle linktime_resolve_special_method (const LinkInfo& link_info, TRAPS);
+ static methodHandle linktime_resolve_virtual_method (const LinkInfo& link_info, TRAPS);
+ static methodHandle linktime_resolve_interface_method (const LinkInfo& link_info, TRAPS);
- static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
- static void linktime_resolve_special_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
- static void linktime_resolve_virtual_method (methodHandle &resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature,KlassHandle current_klass, bool check_access, TRAPS);
- static void linktime_resolve_interface_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
+ static void runtime_resolve_special_method (CallInfo& result,
+ const methodHandle& resolved_method,
+ KlassHandle resolved_klass,
+ KlassHandle current_klass,
+ bool check_access, TRAPS);
+ static void runtime_resolve_virtual_method (CallInfo& result,
+ const methodHandle& resolved_method,
+ KlassHandle resolved_klass,
+ Handle recv,
+ KlassHandle recv_klass,
+ bool check_null_and_abstract, TRAPS);
+ static void runtime_resolve_interface_method (CallInfo& result,
+ const methodHandle& resolved_method,
+ KlassHandle resolved_klass,
+ Handle recv,
+ KlassHandle recv_klass,
+ bool check_null_and_abstract, TRAPS);
- static void runtime_resolve_special_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, KlassHandle current_klass, bool check_access, TRAPS);
- static void runtime_resolve_virtual_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS);
- static void runtime_resolve_interface_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS);
+ static void check_field_accessability(KlassHandle ref_klass,
+ KlassHandle resolved_klass,
+ KlassHandle sel_klass,
+ const fieldDescriptor& fd, TRAPS);
+ static void check_method_accessability(KlassHandle ref_klass,
+ KlassHandle resolved_klass,
+ KlassHandle sel_klass,
+ const methodHandle& sel_method, TRAPS);
- static void check_field_accessability (KlassHandle ref_klass, KlassHandle resolved_klass, KlassHandle sel_klass, fieldDescriptor& fd, TRAPS);
- static void check_method_accessability (KlassHandle ref_klass, KlassHandle resolved_klass, KlassHandle sel_klass, methodHandle sel_method, TRAPS);
-
+ // runtime resolving from constant pool
+ static void resolve_invokestatic (CallInfo& result,
+ constantPoolHandle pool, int index, TRAPS);
+ static void resolve_invokespecial (CallInfo& result,
+ constantPoolHandle pool, int index, TRAPS);
+ static void resolve_invokevirtual (CallInfo& result, Handle recv,
+ constantPoolHandle pool, int index, TRAPS);
+ static void resolve_invokeinterface(CallInfo& result, Handle recv,
+ constantPoolHandle pool, int index, TRAPS);
+ static void resolve_invokedynamic (CallInfo& result,
+ constantPoolHandle pool, int index, TRAPS);
+ static void resolve_invokehandle (CallInfo& result,
+ constantPoolHandle pool, int index, TRAPS);
public:
// constant pool resolving
static void check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS);
- // static resolving calls (will not run any Java code); used only from Bytecode_invoke::static_target
- static void resolve_method_statically(methodHandle& method_result, KlassHandle& klass_result,
- Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS);
+ // static resolving calls (will not run any Java code);
+ // used only from Bytecode_invoke::static_target
+ static methodHandle resolve_method_statically(Bytecodes::Code code,
+ constantPoolHandle pool,
+ int index, TRAPS);
- // runtime/static resolving for fields
- static void resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
- static void resolve_field(fieldDescriptor& result, KlassHandle resolved_klass, Symbol* field_name, Symbol* field_signature,
- KlassHandle current_klass, Bytecodes::Code access_kind, bool check_access, bool initialize_class, TRAPS);
-
- // source of access_kind codes:
- static Bytecodes::Code field_access_kind(bool is_static, bool is_put) {
- return (is_static
- ? (is_put ? Bytecodes::_putstatic : Bytecodes::_getstatic)
- : (is_put ? Bytecodes::_putfield : Bytecodes::_getfield ));
- }
+ static void resolve_field_access(fieldDescriptor& result,
+ constantPoolHandle pool,
+ int index, Bytecodes::Code byte, TRAPS);
+ static void resolve_field(fieldDescriptor& result, const LinkInfo& link_info,
+ Bytecodes::Code access_kind,
+ bool initialize_class, TRAPS);
- // runtime resolving:
- // resolved_klass = specified class (i.e., static receiver class)
- // current_klass = sending method holder (i.e., class containing the method containing the call being resolved)
- static void resolve_static_call (CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool initialize_klass, TRAPS);
- static void resolve_special_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
- static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
- static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
- static void resolve_handle_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, TRAPS);
- static void resolve_dynamic_call (CallInfo& result, Handle bootstrap_specifier, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, TRAPS);
+ static void resolve_static_call (CallInfo& result,
+ const LinkInfo& link_info,
+ bool initialize_klass, TRAPS);
+ static void resolve_special_call (CallInfo& result,
+ const LinkInfo& link_info,
+ TRAPS);
+ static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass,
+ const LinkInfo& link_info,
+ bool check_null_and_abstract, TRAPS);
+ static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass,
+ const LinkInfo& link_info,
+ bool check_null_and_abstract, TRAPS);
+ static void resolve_handle_call (CallInfo& result,
+ const LinkInfo& link_info, TRAPS);
+ static void resolve_dynamic_call (CallInfo& result, Handle bootstrap_specifier,
+ Symbol* method_name, Symbol* method_signature,
+ KlassHandle current_klass, TRAPS);
- // same as above for compile-time resolution; but returns null handle instead of throwing an exception on error
- // also, does not initialize klass (i.e., no side effects)
- static methodHandle resolve_virtual_call_or_null (KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
- static methodHandle resolve_interface_call_or_null(KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
- static methodHandle resolve_static_call_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
- static methodHandle resolve_special_call_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
- static int vtable_index_of_interface_method(KlassHandle klass, methodHandle resolved_method);
+ // same as above for compile-time resolution; but returns null handle instead of throwing
+ // an exception on error also, does not initialize klass (i.e., no side effects)
+ static methodHandle resolve_virtual_call_or_null (KlassHandle receiver_klass,
+ const LinkInfo& link_info);
+ static methodHandle resolve_interface_call_or_null(KlassHandle receiver_klass,
+ const LinkInfo& link_info);
+ static methodHandle resolve_static_call_or_null (const LinkInfo& link_info);
+ static methodHandle resolve_special_call_or_null (const LinkInfo& link_info);
+
+ static int vtable_index_of_interface_method(KlassHandle klass, const methodHandle& resolved_method);
// same as above for compile-time resolution; returns vtable_index if current_klass if linked
- static int resolve_virtual_vtable_index (KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass);
+ static int resolve_virtual_vtable_index (KlassHandle receiver_klass,
+ const LinkInfo& link_info);
// static resolving for compiler (does not throw exceptions, returns null handle if unsuccessful)
- static methodHandle linktime_resolve_virtual_method_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access);
- static methodHandle linktime_resolve_interface_method_or_null(KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access);
+ static methodHandle linktime_resolve_virtual_method_or_null (const LinkInfo& link_info);
+ static methodHandle linktime_resolve_interface_method_or_null(const LinkInfo& link_info);
// runtime resolving from constant pool
- static void resolve_invokestatic (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
- static void resolve_invokespecial (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
- static void resolve_invokevirtual (CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS);
- static void resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS);
- static void resolve_invokedynamic (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
- static void resolve_invokehandle (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
-
- static void resolve_invoke (CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
+ static void resolve_invoke(CallInfo& result, Handle recv,
+ constantPoolHandle pool, int index,
+ Bytecodes::Code byte, TRAPS);
+ private:
+ static void trace_method_resolution(const char* prefix, KlassHandle klass,
+ KlassHandle resolved_klass,
+ const methodHandle& method) PRODUCT_RETURN;
};
-
#endif // SHARE_VM_INTERPRETER_LINKRESOLVER_HPP
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/memory/metaspace.cpp
--- a/hotspot/src/share/vm/memory/metaspace.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -614,8 +614,7 @@
Metachunk* _chunks_in_use[NumberOfInUseLists];
Metachunk* _current_chunk;
- // Number of small chunks to allocate to a manager
- // If class space manager, small chunks are unlimited
+ // Maximum number of small chunks to allocate to a SpaceManager
static uint const _small_chunk_limit;
// Sum of all space in allocated chunks
@@ -730,6 +729,8 @@
// Block allocation and deallocation.
// Allocates a block from the current chunk
MetaWord* allocate(size_t word_size);
+ // Allocates a block from a small chunk
+ MetaWord* get_small_chunk_and_allocate(size_t word_size);
// Helper for allocations
MetaWord* allocate_work(size_t word_size);
@@ -2011,9 +2012,8 @@
size_t SpaceManager::calc_chunk_size(size_t word_size) {
// Decide between a small chunk and a medium chunk. Up to
- // _small_chunk_limit small chunks can be allocated but
- // once a medium chunk has been allocated, no more small
- // chunks will be allocated.
+ // _small_chunk_limit small chunks can be allocated.
+ // After that a medium chunk is preferred.
size_t chunk_word_size;
if (chunks_in_use(MediumIndex) == NULL &&
sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) {
@@ -2081,7 +2081,7 @@
word_size, words_used, words_left);
}
- // Get another chunk out of the virtual space
+ // Get another chunk
size_t grow_chunks_by_words = calc_chunk_size(word_size);
Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words);
@@ -2412,6 +2412,43 @@
return next;
}
+/*
+ * The policy is to allocate up to _small_chunk_limit small chunks
+ * after which only medium chunks are allocated. This is done to
+ * reduce fragmentation. In some cases, this can result in a lot
+ * of small chunks being allocated to the point where it's not
+ * possible to expand. If this happens, there may be no medium chunks
+ * available and OOME would be thrown. Instead of doing that,
+ * if the allocation request size fits in a small chunk, an attempt
+ * will be made to allocate a small chunk.
+ */
+MetaWord* SpaceManager::get_small_chunk_and_allocate(size_t word_size) {
+ if (word_size + Metachunk::overhead() > small_chunk_size()) {
+ return NULL;
+ }
+
+ MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
+ MutexLockerEx cl1(expand_lock(), Mutex::_no_safepoint_check_flag);
+
+ Metachunk* chunk = chunk_manager()->chunk_freelist_allocate(small_chunk_size());
+
+ MetaWord* mem = NULL;
+
+ if (chunk != NULL) {
+ // Add chunk to the in-use chunk list and do an allocation from it.
+ // Add to this manager's list of chunks in use.
+ add_chunk(chunk, false);
+ mem = chunk->allocate(word_size);
+
+ inc_used_metrics(word_size);
+
+ // Track metaspace memory usage statistic.
+ track_metaspace_memory_usage();
+ }
+
+ return mem;
+}
+
MetaWord* SpaceManager::allocate(size_t word_size) {
MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
@@ -3560,7 +3597,18 @@
}
if (result == NULL) {
- report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL);
+ SpaceManager* sm;
+ if (is_class_space_allocation(mdtype)) {
+ sm = loader_data->metaspace_non_null()->class_vsm();
+ } else {
+ sm = loader_data->metaspace_non_null()->vsm();
+ }
+
+ result = sm->get_small_chunk_and_allocate(word_size);
+
+ if (result == NULL) {
+ report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL);
+ }
}
// Zero initialize.
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/oops/constantPool.cpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/oops/constantPool.hpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/oops/instanceKlass.cpp
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -622,14 +622,6 @@
if (!this_k->is_linked()) {
if (!this_k->is_rewritten()) {
{
- // Timer includes any side effects of class verification (resolution,
- // etc), but not recursive entry into verify_code().
- PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
- ClassLoader::perf_class_verify_selftime(),
- ClassLoader::perf_classes_verified(),
- jt->get_thread_stat()->perf_recursion_counts_addr(),
- jt->get_thread_stat()->perf_timers_addr(),
- PerfClassTraceTime::CLASS_VERIFY);
bool verify_ok = verify_code(this_k, throw_verifyerror, THREAD);
if (!verify_ok) {
return false;
@@ -1830,11 +1822,10 @@
// are dependent on the changes that were passed in and mark them for
// deoptimization. Returns the number of nmethods found.
//
-int InstanceKlass::mark_dependent_nmethods(DepChange& changes) {
+int nmethodBucket::mark_dependent_nmethods(nmethodBucket* deps, DepChange& changes) {
assert_locked_or_safepoint(CodeCache_lock);
int found = 0;
- nmethodBucket* b = _dependencies;
- while (b != NULL) {
+ for (nmethodBucket* b = deps; b != NULL; b = b->next()) {
nmethod* nm = b->get_nmethod();
// since dependencies aren't removed until an nmethod becomes a zombie,
// the dependency list may contain nmethods which aren't alive.
@@ -1842,7 +1833,6 @@
if (TraceDependencies) {
ResourceMark rm;
tty->print_cr("Marked for deoptimization");
- tty->print_cr(" context = %s", this->external_name());
changes.print();
nm->print();
nm->print_dependencies();
@@ -1850,36 +1840,119 @@
nm->mark_for_deoptimization();
found++;
}
- b = b->next();
}
return found;
}
+//
+// Add an nmethodBucket to the list of dependencies for this nmethod.
+// It's possible that an nmethod has multiple dependencies on this klass
+// so a count is kept for each bucket to guarantee that creation and
+// deletion of dependencies is consistent. Returns new head of the list.
+//
+nmethodBucket* nmethodBucket::add_dependent_nmethod(nmethodBucket* deps, nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
+ for (nmethodBucket* b = deps; b != NULL; b = b->next()) {
+ if (nm == b->get_nmethod()) {
+ b->increment();
+ return deps;
+ }
+ }
+ return new nmethodBucket(nm, deps);
+}
+
+//
+// Decrement count of the nmethod in the dependency list and remove
+// the bucket completely when the count goes to 0. This method must
+// find a corresponding bucket otherwise there's a bug in the
+// recording of dependencies. Returns true if the bucket is ready for reclamation.
+//
+bool nmethodBucket::remove_dependent_nmethod(nmethodBucket* deps, nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
+
+ for (nmethodBucket* b = deps; b != NULL; b = b->next()) {
+ if (nm == b->get_nmethod()) {
+ int val = b->decrement();
+ guarantee(val >= 0, err_msg("Underflow: %d", val));
+ return (val == 0);
+ }
+ }
+#ifdef ASSERT
+ tty->print_raw_cr("### can't find dependent nmethod");
+ nm->print();
+#endif // ASSERT
+ ShouldNotReachHere();
+ return false;
+}
+
+//
+// Reclaim all unused buckets. Returns new head of the list.
+//
+nmethodBucket* nmethodBucket::clean_dependent_nmethods(nmethodBucket* deps) {
+ nmethodBucket* first = deps;
+ nmethodBucket* last = NULL;
+ nmethodBucket* b = first;
+
+ while (b != NULL) {
+ assert(b->count() >= 0, err_msg("bucket count: %d", b->count()));
+ nmethodBucket* next = b->next();
+ if (b->count() == 0) {
+ if (last == NULL) {
+ first = next;
+ } else {
+ last->set_next(next);
+ }
+ delete b;
+ // last stays the same.
+ } else {
+ last = b;
+ }
+ b = next;
+ }
+ return first;
+}
+
+#ifndef PRODUCT
+void nmethodBucket::print_dependent_nmethods(nmethodBucket* deps, bool verbose) {
+ int idx = 0;
+ for (nmethodBucket* b = deps; b != NULL; b = b->next()) {
+ nmethod* nm = b->get_nmethod();
+ tty->print("[%d] count=%d { ", idx++, b->count());
+ if (!verbose) {
+ nm->print_on(tty, "nmethod");
+ tty->print_cr(" } ");
+ } else {
+ nm->print();
+ nm->print_dependencies();
+ tty->print_cr("--- } ");
+ }
+ }
+}
+
+bool nmethodBucket::is_dependent_nmethod(nmethodBucket* deps, nmethod* nm) {
+ for (nmethodBucket* b = deps; b != NULL; b = b->next()) {
+ if (nm == b->get_nmethod()) {
+#ifdef ASSERT
+ int count = b->count();
+ assert(count >= 0, err_msg("count shouldn't be negative: %d", count));
+#endif
+ return true;
+ }
+ }
+ return false;
+}
+#endif //PRODUCT
+
+int InstanceKlass::mark_dependent_nmethods(DepChange& changes) {
+ assert_locked_or_safepoint(CodeCache_lock);
+ return nmethodBucket::mark_dependent_nmethods(_dependencies, changes);
+}
+
void InstanceKlass::clean_dependent_nmethods() {
assert_locked_or_safepoint(CodeCache_lock);
if (has_unloaded_dependent()) {
- nmethodBucket* b = _dependencies;
- nmethodBucket* last = NULL;
- while (b != NULL) {
- assert(b->count() >= 0, err_msg("bucket count: %d", b->count()));
-
- nmethodBucket* next = b->next();
-
- if (b->count() == 0) {
- if (last == NULL) {
- _dependencies = next;
- } else {
- last->set_next(next);
- }
- delete b;
- // last stays the same.
- } else {
- last = b;
- }
-
- b = next;
- }
+ _dependencies = nmethodBucket::clean_dependent_nmethods(_dependencies);
set_has_unloaded_dependent(false);
}
#ifdef ASSERT
@@ -1893,90 +1966,26 @@
#endif
}
-//
-// Add an nmethodBucket to the list of dependencies for this nmethod.
-// It's possible that an nmethod has multiple dependencies on this klass
-// so a count is kept for each bucket to guarantee that creation and
-// deletion of dependencies is consistent.
-//
void InstanceKlass::add_dependent_nmethod(nmethod* nm) {
assert_locked_or_safepoint(CodeCache_lock);
- nmethodBucket* b = _dependencies;
- nmethodBucket* last = NULL;
- while (b != NULL) {
- if (nm == b->get_nmethod()) {
- b->increment();
- return;
- }
- b = b->next();
- }
- _dependencies = new nmethodBucket(nm, _dependencies);
+ _dependencies = nmethodBucket::add_dependent_nmethod(_dependencies, nm);
}
-
-//
-// Decrement count of the nmethod in the dependency list and remove
-// the bucket competely when the count goes to 0. This method must
-// find a corresponding bucket otherwise there's a bug in the
-// recording of dependecies.
-//
void InstanceKlass::remove_dependent_nmethod(nmethod* nm) {
assert_locked_or_safepoint(CodeCache_lock);
- nmethodBucket* b = _dependencies;
- nmethodBucket* last = NULL;
- while (b != NULL) {
- if (nm == b->get_nmethod()) {
- int val = b->decrement();
- guarantee(val >= 0, err_msg("Underflow: %d", val));
- if (val == 0) {
- set_has_unloaded_dependent(true);
- }
- return;
- }
- last = b;
- b = b->next();
+
+ if (nmethodBucket::remove_dependent_nmethod(_dependencies, nm)) {
+ set_has_unloaded_dependent(true);
}
-#ifdef ASSERT
- tty->print_cr("### %s can't find dependent nmethod:", this->external_name());
- nm->print();
-#endif // ASSERT
- ShouldNotReachHere();
}
-
#ifndef PRODUCT
void InstanceKlass::print_dependent_nmethods(bool verbose) {
- nmethodBucket* b = _dependencies;
- int idx = 0;
- while (b != NULL) {
- nmethod* nm = b->get_nmethod();
- tty->print("[%d] count=%d { ", idx++, b->count());
- if (!verbose) {
- nm->print_on(tty, "nmethod");
- tty->print_cr(" } ");
- } else {
- nm->print();
- nm->print_dependencies();
- tty->print_cr("--- } ");
- }
- b = b->next();
- }
+ nmethodBucket::print_dependent_nmethods(_dependencies, verbose);
}
-
bool InstanceKlass::is_dependent_nmethod(nmethod* nm) {
- nmethodBucket* b = _dependencies;
- while (b != NULL) {
- if (nm == b->get_nmethod()) {
-#ifdef ASSERT
- int count = b->count();
- assert(count >= 0, err_msg("count shouldn't be negative: %d", count));
-#endif
- return true;
- }
- b = b->next();
- }
- return false;
+ return nmethodBucket::is_dependent_nmethod(_dependencies, nm);
}
#endif //PRODUCT
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/oops/instanceKlass.hpp
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -1290,6 +1290,15 @@
nmethodBucket* next() { return _next; }
void set_next(nmethodBucket* b) { _next = b; }
nmethod* get_nmethod() { return _nmethod; }
+
+ static int mark_dependent_nmethods(nmethodBucket* deps, DepChange& changes);
+ static nmethodBucket* add_dependent_nmethod(nmethodBucket* deps, nmethod* nm);
+ static bool remove_dependent_nmethod(nmethodBucket* deps, nmethod* nm);
+ static nmethodBucket* clean_dependent_nmethods(nmethodBucket* deps);
+#ifndef PRODUCT
+ static void print_dependent_nmethods(nmethodBucket* deps, bool verbose);
+ static bool is_dependent_nmethod(nmethodBucket* deps, nmethod* nm);
+#endif //PRODUCT
};
// An iterator that's used to access the inner classes indices in the
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/oops/klassVtable.cpp
--- a/hotspot/src/share/vm/oops/klassVtable.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1136,7 +1136,7 @@
if (m->has_itable_index()) {
// This search must match the runtime resolution, i.e. selection search for invokeinterface
// to correctly enforce loader constraints for interface method inheritance
- LinkResolver::lookup_instance_method_in_klasses(target, _klass, m->name(), m->signature(), CHECK);
+ target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(), CHECK);
}
if (target == NULL || !target->is_public() || target->is_abstract()) {
// Entry does not resolve. Leave it empty for AbstractMethodError.
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/arraycopynode.cpp
--- a/hotspot/src/share/vm/opto/arraycopynode.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/arraycopynode.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -599,10 +599,14 @@
}
bool ArrayCopyNode::may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) {
- const TypeOopPtr* dest_t = phase->type(in(ArrayCopyNode::Dest))->is_oopptr();
+ Node* dest = in(ArrayCopyNode::Dest);
+ if (dest->is_top()) {
+ return false;
+ }
+ const TypeOopPtr* dest_t = phase->type(dest)->is_oopptr();
assert(!dest_t->is_known_instance() || _dest_type->is_known_instance(), "result of EA not recorded");
- const TypeOopPtr* src_t = phase->type(in(ArrayCopyNode::Src))->is_oopptr();
- assert(!src_t->is_known_instance() || _src_type->is_known_instance(), "result of EA not recorded");
+ assert(in(ArrayCopyNode::Src)->is_top() || !phase->type(in(ArrayCopyNode::Src))->is_oopptr()->is_known_instance() ||
+ _src_type->is_known_instance(), "result of EA not recorded");
if (_dest_type != TypeOopPtr::BOTTOM || t_oop->is_known_instance()) {
assert(_dest_type == TypeOopPtr::BOTTOM || _dest_type->is_known_instance(), "result of EA is known instance");
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/callnode.cpp
--- a/hotspot/src/share/vm/opto/callnode.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/callnode.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1946,7 +1946,7 @@
}
}
}
- if (may_modify_arraycopy_helper(phase->type(dest)->is_oopptr(), t_oop, phase)) {
+ if (!dest->is_top() && may_modify_arraycopy_helper(phase->type(dest)->is_oopptr(), t_oop, phase)) {
return true;
}
return false;
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/graphKit.cpp
--- a/hotspot/src/share/vm/opto/graphKit.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1457,18 +1457,18 @@
// factory methods in "int adr_idx"
Node* GraphKit::make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
int adr_idx,
- MemNode::MemOrd mo, bool require_atomic_access) {
+ MemNode::MemOrd mo, LoadNode::ControlDependency control_dependency, bool require_atomic_access) {
assert(adr_idx != Compile::AliasIdxTop, "use other make_load factory" );
const TypePtr* adr_type = NULL; // debug-mode-only argument
debug_only(adr_type = C->get_adr_type(adr_idx));
Node* mem = memory(adr_idx);
Node* ld;
if (require_atomic_access && bt == T_LONG) {
- ld = LoadLNode::make_atomic(ctl, mem, adr, adr_type, t, mo);
+ ld = LoadLNode::make_atomic(ctl, mem, adr, adr_type, t, mo, control_dependency);
} else if (require_atomic_access && bt == T_DOUBLE) {
- ld = LoadDNode::make_atomic(ctl, mem, adr, adr_type, t, mo);
+ ld = LoadDNode::make_atomic(ctl, mem, adr, adr_type, t, mo, control_dependency);
} else {
- ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo);
+ ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo, control_dependency);
}
ld = _gvn.transform(ld);
if ((bt == T_OBJECT) && C->do_escape_analysis() || C->eliminate_boxing()) {
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/graphKit.hpp
--- a/hotspot/src/share/vm/opto/graphKit.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -512,21 +512,24 @@
// adapted the `do_put_xxx' and `do_get_xxx' procedures for the case
// of volatile fields.
Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
- MemNode::MemOrd mo, bool require_atomic_access = false) {
+ MemNode::MemOrd mo, LoadNode::ControlDependency control_dependency = LoadNode::DependsOnlyOnTest,
+ bool require_atomic_access = false) {
// This version computes alias_index from bottom_type
return make_load(ctl, adr, t, bt, adr->bottom_type()->is_ptr(),
- mo, require_atomic_access);
+ mo, control_dependency, require_atomic_access);
}
Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, const TypePtr* adr_type,
- MemNode::MemOrd mo, bool require_atomic_access = false) {
+ MemNode::MemOrd mo, LoadNode::ControlDependency control_dependency = LoadNode::DependsOnlyOnTest,
+ bool require_atomic_access = false) {
// This version computes alias_index from an address type
assert(adr_type != NULL, "use other make_load factory");
return make_load(ctl, adr, t, bt, C->get_alias_index(adr_type),
- mo, require_atomic_access);
+ mo, control_dependency, require_atomic_access);
}
// This is the base version which is given an alias index.
Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, int adr_idx,
- MemNode::MemOrd mo, bool require_atomic_access = false);
+ MemNode::MemOrd mo, LoadNode::ControlDependency control_dependency = LoadNode::DependsOnlyOnTest,
+ bool require_atomic_access = false);
// Create & transform a StoreNode and store the effect into the
// parser's memory state.
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/library_call.cpp
--- a/hotspot/src/share/vm/opto/library_call.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -2631,7 +2631,9 @@
if (!is_store) {
MemNode::MemOrd mo = is_volatile ? MemNode::acquire : MemNode::unordered;
- Node* p = make_load(control(), adr, value_type, type, adr_type, mo, is_volatile);
+ // To be valid, unsafe loads may depend on other conditions than
+ // the one that guards them: pin the Load node
+ Node* p = make_load(control(), adr, value_type, type, adr_type, mo, LoadNode::Pinned, is_volatile);
// load value
switch (type) {
case T_BOOLEAN:
@@ -5488,7 +5490,7 @@
}
// Build the load.
MemNode::MemOrd mo = is_vol ? MemNode::acquire : MemNode::unordered;
- Node* loadedField = make_load(NULL, adr, type, bt, adr_type, mo, is_vol);
+ Node* loadedField = make_load(NULL, adr, type, bt, adr_type, mo, LoadNode::DependsOnlyOnTest, is_vol);
// If reference is volatile, prevent following memory ops from
// floating up past the volatile read. Also prevents commoning
// another volatile read.
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/loopPredicate.cpp
--- a/hotspot/src/share/vm/opto/loopPredicate.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/loopPredicate.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -437,7 +437,13 @@
}
}
if (all_inputs_invariant) {
- _invariant.set(n->_idx); // I am a invariant too
+ // If n's control is a predicate that was moved out of the
+ // loop, it was marked invariant but n is only invariant if
+ // it depends only on that test. Otherwise, unless that test
+ // is out of the loop, it's not invariant.
+ if (n->is_CFG() || n->depends_only_on_test() || n->in(0) == NULL || !_phase->is_member(_lpt, n->in(0))) {
+ _invariant.set(n->_idx); // I am a invariant too
+ }
}
} else { // process next input
_stack.set_index(idx + 1);
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/loopTransform.cpp
--- a/hotspot/src/share/vm/opto/loopTransform.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1582,13 +1582,36 @@
if (opc != ReductionNode::opcode(opc, def_node->bottom_type()->basic_type())) {
if (!def_node->is_reduction()) { // Not marked yet
// To be a reduction, the arithmetic node must have the phi as input and provide a def to it
+ bool ok = false;
for (unsigned j = 1; j < def_node->req(); j++) {
Node* in = def_node->in(j);
if (in == phi) {
- def_node->add_flag(Node::Flag_is_reduction);
+ ok = true;
break;
}
}
+
+ // do nothing if we did not match the initial criteria
+ if (ok == false) {
+ continue;
+ }
+
+ // The result of the reduction must not be used in the loop
+ for (DUIterator_Fast imax, i = def_node->fast_outs(imax); i < imax && ok; i++) {
+ Node* u = def_node->fast_out(i);
+ if (has_ctrl(u) && !loop->is_member(get_loop(get_ctrl(u)))) {
+ continue;
+ }
+ if (u == phi) {
+ continue;
+ }
+ ok = false;
+ }
+
+ // iff the uses conform
+ if (ok) {
+ def_node->add_flag(Node::Flag_is_reduction);
+ }
}
}
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/loopopts.cpp
--- a/hotspot/src/share/vm/opto/loopopts.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/loopopts.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -718,7 +718,7 @@
}
// Use same limit as split_if_with_blocks_post
- if( C->unique() > 35000 ) return n; // Method too big
+ if( C->live_nodes() > 35000 ) return n; // Method too big
// Split 'n' through the merge point if it is profitable
Node *phi = split_thru_phi( n, n_blk, policy );
@@ -802,7 +802,7 @@
// Cloning Cmp through Phi's involves the split-if transform.
// FastLock is not used by an If
if( n->is_Cmp() && !n->is_FastLock() ) {
- if( C->unique() > 35000 ) return; // Method too big
+ if( C->live_nodes() > 35000 ) return; // Method too big
// Do not do 'split-if' if irreducible loops are present.
if( _has_irreducible_loops )
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/matcher.cpp
--- a/hotspot/src/share/vm/opto/matcher.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/matcher.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -844,7 +844,7 @@
MachNode *spillCP = match_tree(new LoadNNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM,MemNode::unordered));
#endif
MachNode *spillI = match_tree(new LoadINode(NULL,mem,fp,atp,TypeInt::INT,MemNode::unordered));
- MachNode *spillL = match_tree(new LoadLNode(NULL,mem,fp,atp,TypeLong::LONG,MemNode::unordered,false));
+ MachNode *spillL = match_tree(new LoadLNode(NULL,mem,fp,atp,TypeLong::LONG,MemNode::unordered, LoadNode::DependsOnlyOnTest, false));
MachNode *spillF = match_tree(new LoadFNode(NULL,mem,fp,atp,Type::FLOAT,MemNode::unordered));
MachNode *spillD = match_tree(new LoadDNode(NULL,mem,fp,atp,Type::DOUBLE,MemNode::unordered));
MachNode *spillP = match_tree(new LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM,MemNode::unordered));
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/memnode.cpp
--- a/hotspot/src/share/vm/opto/memnode.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -784,6 +784,9 @@
// standard dump does this in Verbose and WizardMode
st->print(" #"); _type->dump_on(st);
}
+ if (!_depends_only_on_test) {
+ st->print(" (does not depend only on test)");
+ }
}
#endif
@@ -800,7 +803,7 @@
//----------------------------LoadNode::make-----------------------------------
// Polymorphic factory method:
-Node *LoadNode::make(PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const TypePtr* adr_type, const Type *rt, BasicType bt, MemOrd mo) {
+Node *LoadNode::make(PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const TypePtr* adr_type, const Type *rt, BasicType bt, MemOrd mo, ControlDependency control_dependency) {
Compile* C = gvn.C;
// sanity check the alias category against the created node type
@@ -816,39 +819,39 @@
rt->isa_oopptr() || is_immutable_value(adr),
"raw memory operations should have control edge");
switch (bt) {
- case T_BOOLEAN: return new LoadUBNode(ctl, mem, adr, adr_type, rt->is_int(), mo);
- case T_BYTE: return new LoadBNode (ctl, mem, adr, adr_type, rt->is_int(), mo);
- case T_INT: return new LoadINode (ctl, mem, adr, adr_type, rt->is_int(), mo);
- case T_CHAR: return new LoadUSNode(ctl, mem, adr, adr_type, rt->is_int(), mo);
- case T_SHORT: return new LoadSNode (ctl, mem, adr, adr_type, rt->is_int(), mo);
- case T_LONG: return new LoadLNode (ctl, mem, adr, adr_type, rt->is_long(), mo);
- case T_FLOAT: return new LoadFNode (ctl, mem, adr, adr_type, rt, mo);
- case T_DOUBLE: return new LoadDNode (ctl, mem, adr, adr_type, rt, mo);
- case T_ADDRESS: return new LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr(), mo);
+ case T_BOOLEAN: return new LoadUBNode(ctl, mem, adr, adr_type, rt->is_int(), mo, control_dependency);
+ case T_BYTE: return new LoadBNode (ctl, mem, adr, adr_type, rt->is_int(), mo, control_dependency);
+ case T_INT: return new LoadINode (ctl, mem, adr, adr_type, rt->is_int(), mo, control_dependency);
+ case T_CHAR: return new LoadUSNode(ctl, mem, adr, adr_type, rt->is_int(), mo, control_dependency);
+ case T_SHORT: return new LoadSNode (ctl, mem, adr, adr_type, rt->is_int(), mo, control_dependency);
+ case T_LONG: return new LoadLNode (ctl, mem, adr, adr_type, rt->is_long(), mo, control_dependency);
+ case T_FLOAT: return new LoadFNode (ctl, mem, adr, adr_type, rt, mo, control_dependency);
+ case T_DOUBLE: return new LoadDNode (ctl, mem, adr, adr_type, rt, mo, control_dependency);
+ case T_ADDRESS: return new LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr(), mo, control_dependency);
case T_OBJECT:
#ifdef _LP64
if (adr->bottom_type()->is_ptr_to_narrowoop()) {
- Node* load = gvn.transform(new LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop(), mo));
+ Node* load = gvn.transform(new LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop(), mo, control_dependency));
return new DecodeNNode(load, load->bottom_type()->make_ptr());
} else
#endif
{
assert(!adr->bottom_type()->is_ptr_to_narrowoop() && !adr->bottom_type()->is_ptr_to_narrowklass(), "should have got back a narrow oop");
- return new LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr(), mo);
+ return new LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr(), mo, control_dependency);
}
}
ShouldNotReachHere();
return (LoadNode*)NULL;
}
-LoadLNode* LoadLNode::make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo) {
+LoadLNode* LoadLNode::make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo, ControlDependency control_dependency) {
bool require_atomic = true;
- return new LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), mo, require_atomic);
+ return new LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), mo, control_dependency, require_atomic);
}
-LoadDNode* LoadDNode::make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo) {
+LoadDNode* LoadDNode::make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo, ControlDependency control_dependency) {
bool require_atomic = true;
- return new LoadDNode(ctl, mem, adr, adr_type, rt, mo, require_atomic);
+ return new LoadDNode(ctl, mem, adr, adr_type, rt, mo, control_dependency, require_atomic);
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/memnode.hpp
--- a/hotspot/src/share/vm/opto/memnode.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/memnode.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -137,7 +137,33 @@
//------------------------------LoadNode---------------------------------------
// Load value; requires Memory and Address
class LoadNode : public MemNode {
+public:
+ // Some loads (from unsafe) should be pinned: they don't depend only
+ // on the dominating test. The boolean field _depends_only_on_test
+ // below records whether that node depends only on the dominating
+ // test.
+ // Methods used to build LoadNodes pass an argument of type enum
+ // ControlDependency instead of a boolean because those methods
+ // typically have multiple boolean parameters with default values:
+ // passing the wrong boolean to one of these parameters by mistake
+ // goes easily unnoticed. Using an enum, the compiler can check that
+ // the type of a value and the type of the parameter match.
+ enum ControlDependency {
+ Pinned,
+ DependsOnlyOnTest
+ };
private:
+ // LoadNode::hash() doesn't take the _depends_only_on_test field
+ // into account: If the graph already has a non-pinned LoadNode and
+ // we add a pinned LoadNode with the same inputs, it's safe for GVN
+ // to replace the pinned LoadNode with the non-pinned LoadNode,
+ // otherwise it wouldn't be safe to have a non pinned LoadNode with
+ // those inputs in the first place. If the graph already has a
+ // pinned LoadNode and we add a non pinned LoadNode with the same
+ // inputs, it's safe (but suboptimal) for GVN to replace the
+ // non-pinned LoadNode by the pinned LoadNode.
+ bool _depends_only_on_test;
+
// On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish
// loads that can be reordered, and such requiring acquire semantics to
// adhere to the Java specification. The required behaviour is stored in
@@ -154,8 +180,8 @@
virtual Node* find_previous_arraycopy(PhaseTransform* phase, Node* ld_alloc, Node*& mem, bool can_see_stored_value) const;
public:
- LoadNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt, MemOrd mo)
- : MemNode(c,mem,adr,at), _type(rt), _mo(mo) {
+ LoadNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt, MemOrd mo, ControlDependency control_dependency)
+ : MemNode(c,mem,adr,at), _type(rt), _mo(mo), _depends_only_on_test(control_dependency == DependsOnlyOnTest) {
init_class_id(Class_Load);
}
inline bool is_unordered() const { return !is_acquire(); }
@@ -166,7 +192,8 @@
// Polymorphic factory method:
static Node* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr,
- const TypePtr* at, const Type *rt, BasicType bt, MemOrd mo);
+ const TypePtr* at, const Type *rt, BasicType bt,
+ MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest);
virtual uint hash() const; // Check the type
@@ -234,16 +261,15 @@
// which produce results (new raw memory state) inside of loops preventing all
// manner of other optimizations). Basically, it's ugly but so is the alternative.
// See comment in macro.cpp, around line 125 expand_allocate_common().
- virtual bool depends_only_on_test() const { return adr_type() != TypeRawPtr::BOTTOM; }
-
+ virtual bool depends_only_on_test() const { return adr_type() != TypeRawPtr::BOTTOM && _depends_only_on_test; }
};
//------------------------------LoadBNode--------------------------------------
// Load a byte (8bits signed) from memory
class LoadBNode : public LoadNode {
public:
- LoadBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
- : LoadNode(c, mem, adr, at, ti, mo) {}
+ LoadBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadNode(c, mem, adr, at, ti, mo, control_dependency) {}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegI; }
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
@@ -256,8 +282,8 @@
// Load a unsigned byte (8bits unsigned) from memory
class LoadUBNode : public LoadNode {
public:
- LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti, MemOrd mo)
- : LoadNode(c, mem, adr, at, ti, mo) {}
+ LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadNode(c, mem, adr, at, ti, mo, control_dependency) {}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegI; }
virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
@@ -270,8 +296,8 @@
// Load an unsigned short/char (16bits unsigned) from memory
class LoadUSNode : public LoadNode {
public:
- LoadUSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
- : LoadNode(c, mem, adr, at, ti, mo) {}
+ LoadUSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadNode(c, mem, adr, at, ti, mo, control_dependency) {}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegI; }
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
@@ -284,8 +310,8 @@
// Load a short (16bits signed) from memory
class LoadSNode : public LoadNode {
public:
- LoadSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
- : LoadNode(c, mem, adr, at, ti, mo) {}
+ LoadSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadNode(c, mem, adr, at, ti, mo, control_dependency) {}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegI; }
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
@@ -298,8 +324,8 @@
// Load an integer from memory
class LoadINode : public LoadNode {
public:
- LoadINode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
- : LoadNode(c, mem, adr, at, ti, mo) {}
+ LoadINode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadNode(c, mem, adr, at, ti, mo, control_dependency) {}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegI; }
virtual int store_Opcode() const { return Op_StoreI; }
@@ -331,15 +357,15 @@
public:
LoadLNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeLong *tl,
- MemOrd mo, bool require_atomic_access = false)
- : LoadNode(c, mem, adr, at, tl, mo), _require_atomic_access(require_atomic_access) {}
+ MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest, bool require_atomic_access = false)
+ : LoadNode(c, mem, adr, at, tl, mo, control_dependency), _require_atomic_access(require_atomic_access) {}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegL; }
virtual int store_Opcode() const { return Op_StoreL; }
virtual BasicType memory_type() const { return T_LONG; }
bool require_atomic_access() const { return _require_atomic_access; }
static LoadLNode* make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type,
- const Type* rt, MemOrd mo);
+ const Type* rt, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest);
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const {
LoadNode::dump_spec(st);
@@ -352,8 +378,8 @@
// Load a long from unaligned memory
class LoadL_unalignedNode : public LoadLNode {
public:
- LoadL_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo)
- : LoadLNode(c, mem, adr, at, TypeLong::LONG, mo) {}
+ LoadL_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadLNode(c, mem, adr, at, TypeLong::LONG, mo, control_dependency) {}
virtual int Opcode() const;
};
@@ -361,8 +387,8 @@
// Load a float (64 bits) from memory
class LoadFNode : public LoadNode {
public:
- LoadFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo)
- : LoadNode(c, mem, adr, at, t, mo) {}
+ LoadFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadNode(c, mem, adr, at, t, mo, control_dependency) {}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegF; }
virtual int store_Opcode() const { return Op_StoreF; }
@@ -382,15 +408,15 @@
public:
LoadDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t,
- MemOrd mo, bool require_atomic_access = false)
- : LoadNode(c, mem, adr, at, t, mo), _require_atomic_access(require_atomic_access) {}
+ MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest, bool require_atomic_access = false)
+ : LoadNode(c, mem, adr, at, t, mo, control_dependency), _require_atomic_access(require_atomic_access) {}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegD; }
virtual int store_Opcode() const { return Op_StoreD; }
virtual BasicType memory_type() const { return T_DOUBLE; }
bool require_atomic_access() const { return _require_atomic_access; }
static LoadDNode* make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type,
- const Type* rt, MemOrd mo);
+ const Type* rt, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest);
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const {
LoadNode::dump_spec(st);
@@ -403,8 +429,8 @@
// Load a double from unaligned memory
class LoadD_unalignedNode : public LoadDNode {
public:
- LoadD_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo)
- : LoadDNode(c, mem, adr, at, Type::DOUBLE, mo) {}
+ LoadD_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadDNode(c, mem, adr, at, Type::DOUBLE, mo, control_dependency) {}
virtual int Opcode() const;
};
@@ -412,8 +438,8 @@
// Load a pointer from memory (either object or array)
class LoadPNode : public LoadNode {
public:
- LoadPNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t, MemOrd mo)
- : LoadNode(c, mem, adr, at, t, mo) {}
+ LoadPNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadNode(c, mem, adr, at, t, mo, control_dependency) {}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegP; }
virtual int store_Opcode() const { return Op_StoreP; }
@@ -425,8 +451,8 @@
// Load a narrow oop from memory (either object or array)
class LoadNNode : public LoadNode {
public:
- LoadNNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t, MemOrd mo)
- : LoadNode(c, mem, adr, at, t, mo) {}
+ LoadNNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadNode(c, mem, adr, at, t, mo, control_dependency) {}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegN; }
virtual int store_Opcode() const { return Op_StoreN; }
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/parse3.cpp
--- a/hotspot/src/share/vm/opto/parse3.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/parse3.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -235,7 +235,7 @@
//
MemNode::MemOrd mo = is_vol ? MemNode::acquire : MemNode::unordered;
bool needs_atomic_access = is_vol || AlwaysAtomicAccesses;
- Node* ld = make_load(NULL, adr, type, bt, adr_type, mo, needs_atomic_access);
+ Node* ld = make_load(NULL, adr, type, bt, adr_type, mo, LoadNode::DependsOnlyOnTest, needs_atomic_access);
// Adjust Java stack
if (type2size[bt] == 1)
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/phaseX.cpp
--- a/hotspot/src/share/vm/opto/phaseX.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/phaseX.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1573,11 +1573,12 @@
set_type(n, t);
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
Node* m = n->fast_out(i); // Get user
- if( m->is_Region() ) { // New path to Region? Must recheck Phis too
+ if (m->is_Region()) { // New path to Region? Must recheck Phis too
for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
Node* p = m->fast_out(i2); // Propagate changes to uses
- if( p->bottom_type() != type(p) ) // If not already bottomed out
+ if (p->bottom_type() != type(p)) { // If not already bottomed out
worklist.push(p); // Propagate change to user
+ }
}
}
// If we changed the receiver type to a call, we need to revisit
@@ -1587,12 +1588,31 @@
if (m->is_Call()) {
for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
Node* p = m->fast_out(i2); // Propagate changes to uses
- if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1)
+ if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1) {
worklist.push(p->unique_out());
+ }
}
}
- if( m->bottom_type() != type(m) ) // If not already bottomed out
+ if (m->bottom_type() != type(m)) { // If not already bottomed out
worklist.push(m); // Propagate change to user
+ }
+
+ // CmpU nodes can get their type information from two nodes up in the
+ // graph (instead of from the nodes immediately above). Make sure they
+ // are added to the worklist if nodes they depend on are updated, since
+ // they could be missed and get wrong types otherwise.
+ uint m_op = m->Opcode();
+ if (m_op == Op_AddI || m_op == Op_SubI) {
+ for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
+ Node* p = m->fast_out(i2); // Propagate changes to uses
+ if (p->Opcode() == Op_CmpU) {
+ // Got a CmpU which might need the new type information from node n.
+ if(p->bottom_type() != type(p)) { // If not already bottomed out
+ worklist.push(p); // Propagate change to user
+ }
+ }
+ }
+ }
}
}
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/superword.cpp
--- a/hotspot/src/share/vm/opto/superword.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/superword.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1631,7 +1631,7 @@
}
Node* adr = low_adr->in(MemNode::Address);
const TypePtr* atyp = n->adr_type();
- vn = LoadVectorNode::make(opc, ctl, mem, adr, atyp, vlen, velt_basic_type(n));
+ vn = LoadVectorNode::make(opc, ctl, mem, adr, atyp, vlen, velt_basic_type(n), control_dependency(p));
vlen_in_bytes = vn->as_LoadVector()->memory_size();
} else if (n->is_Store()) {
// Promote value to be stored to vector
@@ -2280,6 +2280,19 @@
return n;
}
+LoadNode::ControlDependency SuperWord::control_dependency(Node_List* p) {
+ LoadNode::ControlDependency dep = LoadNode::DependsOnlyOnTest;
+ for (uint i = 0; i < p->size(); i++) {
+ Node* n = p->at(i);
+ assert(n->is_Load(), "only meaningful for loads");
+ if (!n->depends_only_on_test()) {
+ dep = LoadNode::Pinned;
+ }
+ }
+ return dep;
+}
+
+
//----------------------------align_initial_loop_index---------------------------
// Adjust pre-loop limit so that in main loop, a load/store reference
// to align_to_ref will be a position zero in the vector.
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/superword.hpp
--- a/hotspot/src/share/vm/opto/superword.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/superword.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -428,6 +428,7 @@
Node* executed_first(Node_List* p);
// Return the node executed last in pack p.
Node* executed_last(Node_List* p);
+ static LoadNode::ControlDependency control_dependency(Node_List* p);
// Alignment within a vector memory reference
int memory_alignment(MemNode* s, int iv_adjust);
// (Start, end] half-open range defining which operands are vector
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/vectornode.cpp
--- a/hotspot/src/share/vm/opto/vectornode.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/vectornode.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -406,9 +406,11 @@
// Return the vector version of a scalar load node.
LoadVectorNode* LoadVectorNode::make(int opc, Node* ctl, Node* mem,
- Node* adr, const TypePtr* atyp, uint vlen, BasicType bt) {
+ Node* adr, const TypePtr* atyp,
+ uint vlen, BasicType bt,
+ ControlDependency control_dependency) {
const TypeVect* vt = TypeVect::make(bt, vlen);
- return new LoadVectorNode(ctl, mem, adr, atyp, vt);
+ return new LoadVectorNode(ctl, mem, adr, atyp, vt, control_dependency);
}
// Return the vector version of a scalar store node.
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/opto/vectornode.hpp
--- a/hotspot/src/share/vm/opto/vectornode.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/opto/vectornode.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -454,8 +454,8 @@
// Load Vector from memory
class LoadVectorNode : public LoadNode {
public:
- LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt)
- : LoadNode(c, mem, adr, at, vt, MemNode::unordered) {
+ LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, ControlDependency control_dependency = LoadNode::DependsOnlyOnTest)
+ : LoadNode(c, mem, adr, at, vt, MemNode::unordered, control_dependency) {
init_class_id(Class_LoadVector);
}
@@ -471,7 +471,9 @@
virtual int store_Opcode() const { return Op_StoreVector; }
static LoadVectorNode* make(int opc, Node* ctl, Node* mem,
- Node* adr, const TypePtr* atyp, uint vlen, BasicType bt);
+ Node* adr, const TypePtr* atyp,
+ uint vlen, BasicType bt,
+ ControlDependency control_dependency = LoadNode::DependsOnlyOnTest);
};
//------------------------------StoreVectorNode--------------------------------
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/prims/jni.cpp
--- a/hotspot/src/share/vm/prims/jni.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1126,39 +1126,32 @@
Method* m = Method::resolve_jmethod_id(method_id);
number_of_parameters = m->size_of_parameters();
Klass* holder = m->method_holder();
- if (!(holder)->is_interface()) {
+ if (call_type != JNI_VIRTUAL) {
+ selected_method = m;
+ } else if (!m->has_itable_index()) {
// non-interface call -- for that little speed boost, don't handlize
debug_only(No_Safepoint_Verifier nosafepoint;)
- if (call_type == JNI_VIRTUAL) {
- // jni_GetMethodID makes sure class is linked and initialized
- // so m should have a valid vtable index.
- assert(!m->has_itable_index(), "");
- int vtbl_index = m->vtable_index();
- if (vtbl_index != Method::nonvirtual_vtable_index) {
- Klass* k = h_recv->klass();
- // k might be an arrayKlassOop but all vtables start at
- // the same place. The cast is to avoid virtual call and assertion.
- InstanceKlass *ik = (InstanceKlass*)k;
- selected_method = ik->method_at_vtable(vtbl_index);
- } else {
- // final method
- selected_method = m;
- }
+ // jni_GetMethodID makes sure class is linked and initialized
+ // so m should have a valid vtable index.
+ assert(m->valid_vtable_index(), "no valid vtable index");
+ int vtbl_index = m->vtable_index();
+ if (vtbl_index != Method::nonvirtual_vtable_index) {
+ Klass* k = h_recv->klass();
+ // k might be an arrayKlassOop but all vtables start at
+ // the same place. The cast is to avoid virtual call and assertion.
+ InstanceKlass *ik = (InstanceKlass*)k;
+ selected_method = ik->method_at_vtable(vtbl_index);
} else {
- // JNI_NONVIRTUAL call
+ // final method
selected_method = m;
}
} else {
// interface call
KlassHandle h_holder(THREAD, holder);
- if (call_type == JNI_VIRTUAL) {
- int itbl_index = m->itable_index();
- Klass* k = h_recv->klass();
- selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK);
- } else {
- selected_method = m;
- }
+ int itbl_index = m->itable_index();
+ Klass* k = h_recv->klass();
+ selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK);
}
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/prims/jvmtiEnvBase.cpp
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -842,7 +842,7 @@
// optimize to limit the number of times that java_sender() is called
javaVFrame *jvf_cursor = jvf;
javaVFrame *jvf_prev = NULL;
- javaVFrame *jvf_prev_prev;
+ javaVFrame *jvf_prev_prev = NULL;
int j = 0;
while (jvf_cursor != NULL) {
jvf_prev_prev = jvf_prev;
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/prims/methodHandles.cpp
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -677,24 +677,24 @@
case IS_METHOD:
{
CallInfo result;
+ LinkInfo link_info(defc, name, type, caller, caller.not_null());
{
assert(!HAS_PENDING_EXCEPTION, "");
if (ref_kind == JVM_REF_invokeStatic) {
LinkResolver::resolve_static_call(result,
- defc, name, type, caller, caller.not_null(), false, THREAD);
+ link_info, false, THREAD);
} else if (ref_kind == JVM_REF_invokeInterface) {
LinkResolver::resolve_interface_call(result, Handle(), defc,
- defc, name, type, caller, caller.not_null(), false, THREAD);
+ link_info, false, THREAD);
} else if (mh_invoke_id != vmIntrinsics::_none) {
assert(!is_signature_polymorphic_static(mh_invoke_id), "");
- LinkResolver::resolve_handle_call(result,
- defc, name, type, caller, THREAD);
+ LinkResolver::resolve_handle_call(result, link_info, THREAD);
} else if (ref_kind == JVM_REF_invokeSpecial) {
LinkResolver::resolve_special_call(result,
- defc, name, type, caller, caller.not_null(), THREAD);
+ link_info, THREAD);
} else if (ref_kind == JVM_REF_invokeVirtual) {
LinkResolver::resolve_virtual_call(result, Handle(), defc,
- defc, name, type, caller, caller.not_null(), false, THREAD);
+ link_info, false, THREAD);
} else {
assert(false, err_msg("ref_kind=%d", ref_kind));
}
@@ -714,11 +714,11 @@
case IS_CONSTRUCTOR:
{
CallInfo result;
+ LinkInfo link_info(defc, name, type, caller, caller.not_null());
{
assert(!HAS_PENDING_EXCEPTION, "");
if (name == vmSymbols::object_initializer_name()) {
- LinkResolver::resolve_special_call(result,
- defc, name, type, caller, caller.not_null(), THREAD);
+ LinkResolver::resolve_special_call(result, link_info, THREAD);
} else {
break; // will throw after end of switch
}
@@ -735,7 +735,8 @@
fieldDescriptor result; // find_field initializes fd if found
{
assert(!HAS_PENDING_EXCEPTION, "");
- LinkResolver::resolve_field(result, defc, name, type, caller, Bytecodes::_nop, false, false, THREAD);
+ LinkInfo link_info(defc, name, type, caller, /*check_access*/false);
+ LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD);
if (HAS_PENDING_EXCEPTION) {
return empty;
}
@@ -942,22 +943,56 @@
return rfill + overflow;
}
-// Get context class for a CallSite instance: either extract existing context or use default one.
-InstanceKlass* MethodHandles::get_call_site_context(oop call_site) {
- // In order to extract a context the following traversal is performed:
- // CallSite.context => Cleaner.referent => Class._klass => Klass
- assert(java_lang_invoke_CallSite::is_instance(call_site), "");
- oop context_oop = java_lang_invoke_CallSite::context_volatile(call_site);
- if (oopDesc::is_null(context_oop)) {
- return NULL; // The context hasn't been initialized yet.
+void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
+
+ oop context = java_lang_invoke_CallSite::context(call_site);
+ nmethodBucket* deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
+
+ nmethodBucket* new_deps = nmethodBucket::add_dependent_nmethod(deps, nm);
+ if (deps != new_deps) {
+ java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context, new_deps);
+ }
+}
+
+void MethodHandles::remove_dependent_nmethod(oop call_site, nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
+
+ oop context = java_lang_invoke_CallSite::context(call_site);
+ nmethodBucket* deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
+
+ if (nmethodBucket::remove_dependent_nmethod(deps, nm)) {
+ nmethodBucket* new_deps = nmethodBucket::clean_dependent_nmethods(deps);
+ if (deps != new_deps) {
+ java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context, new_deps);
+ }
}
- oop context_class_oop = java_lang_ref_Reference::referent(context_oop);
- if (oopDesc::is_null(context_class_oop)) {
- // The context reference was cleared by GC, so current dependency context
- // isn't usable anymore. Context should be fetched from CallSite again.
- return NULL;
+}
+
+void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) {
+ assert_lock_strong(Compile_lock);
+
+ int marked = 0;
+ CallSiteDepChange changes(call_site(), target());
+ {
+ MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+
+ oop context = java_lang_invoke_CallSite::context(call_site());
+ nmethodBucket* deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
+
+ marked = nmethodBucket::mark_dependent_nmethods(deps, changes);
+ if (marked > 0) {
+ nmethodBucket* new_deps = nmethodBucket::clean_dependent_nmethods(deps);
+ if (deps != new_deps) {
+ java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context, new_deps);
+ }
+ }
}
- return InstanceKlass::cast(java_lang_Class::as_Klass(context_class_oop));
+ if (marked > 0) {
+ // At least one nmethod has been marked for deoptimization
+ VM_Deoptimize op;
+ VMThread::execute(&op);
+ }
}
//------------------------------------------------------------------------------
@@ -1276,7 +1311,7 @@
{
// Walk all nmethods depending on this call site.
MutexLocker mu(Compile_lock, thread);
- CodeCache::flush_dependents_on(call_site, target);
+ MethodHandles::flush_dependent_nmethods(call_site, target);
java_lang_invoke_CallSite::set_target(call_site(), target());
}
}
@@ -1288,30 +1323,34 @@
{
// Walk all nmethods depending on this call site.
MutexLocker mu(Compile_lock, thread);
- CodeCache::flush_dependents_on(call_site, target);
+ MethodHandles::flush_dependent_nmethods(call_site, target);
java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
}
}
JVM_END
-JVM_ENTRY(void, MHN_invalidateDependentNMethods(JNIEnv* env, jobject igcls, jobject call_site_jh)) {
- Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
+JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
+ Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
{
// Walk all nmethods depending on this call site.
MutexLocker mu1(Compile_lock, thread);
- CallSiteDepChange changes(call_site(), Handle());
-
- InstanceKlass* ctxk = MethodHandles::get_call_site_context(call_site());
- if (ctxk == NULL) {
- return; // No dependencies to invalidate yet.
- }
int marked = 0;
{
MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- marked = ctxk->mark_dependent_nmethods(changes);
+ nmethodBucket* b = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context());
+ while(b != NULL) {
+ nmethod* nm = b->get_nmethod();
+ if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization()) {
+ nm->mark_for_deoptimization();
+ marked++;
+ }
+ nmethodBucket* next = b->next();
+ delete b;
+ b = next;
+ }
+ java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context(), NULL); // reset context
}
- java_lang_invoke_CallSite::set_context_volatile(call_site(), NULL); // Reset call site to initial state
if (marked > 0) {
// At least one nmethod has been marked for deoptimization
VM_Deoptimize op;
@@ -1357,6 +1396,7 @@
#define MT JLINV"MethodType;"
#define MH JLINV"MethodHandle;"
#define MEM JLINV"MemberName;"
+#define CTX JLINV"MethodHandleNatives$CallSiteContext;"
#define CC (char*) /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
@@ -1374,7 +1414,7 @@
{CC"objectFieldOffset", CC"("MEM")J", FN_PTR(MHN_objectFieldOffset)},
{CC"setCallSiteTargetNormal", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetNormal)},
{CC"setCallSiteTargetVolatile", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetVolatile)},
- {CC"invalidateDependentNMethods", CC"("CS")V", FN_PTR(MHN_invalidateDependentNMethods)},
+ {CC"clearCallSiteContext", CC"("CTX")V", FN_PTR(MHN_clearCallSiteContext)},
{CC"staticFieldOffset", CC"("MEM")J", FN_PTR(MHN_staticFieldOffset)},
{CC"staticFieldBase", CC"("MEM")"OBJ, FN_PTR(MHN_staticFieldBase)},
{CC"getMemberVMInfo", CC"("MEM")"OBJ, FN_PTR(MHN_getMemberVMInfo)}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/prims/methodHandles.hpp
--- a/hotspot/src/share/vm/prims/methodHandles.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -69,7 +69,10 @@
enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
// CallSite support
- static InstanceKlass* get_call_site_context(oop call_site);
+ static void add_dependent_nmethod(oop call_site, nmethod* nm);
+ static void remove_dependent_nmethod(oop call_site, nmethod* nm);
+
+ static void flush_dependent_nmethods(Handle call_site, Handle target);
// Generate MethodHandles adapters.
static bool generate_adapters();
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -64,7 +64,7 @@
}
#endif
-#ifdef SPARC
+#if defined SPARC || defined AARCH64
if (FLAG_IS_DEFAULT(InlineSmallCode)) {
FLAG_SET_DEFAULT(InlineSmallCode, 2500);
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/runtime/javaCalls.cpp
--- a/hotspot/src/share/vm/runtime/javaCalls.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/runtime/javaCalls.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -179,9 +179,9 @@
CallInfo callinfo;
Handle receiver = args->receiver();
KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass());
+ LinkInfo link_info(spec_klass, name, signature, KlassHandle(), /*check_access*/false);
LinkResolver::resolve_virtual_call(
- callinfo, receiver, recvrKlass, spec_klass, name, signature,
- KlassHandle(), false, true, CHECK);
+ callinfo, receiver, recvrKlass, link_info, true, CHECK);
methodHandle method = callinfo.selected_method();
assert(method.not_null(), "should have thrown exception");
@@ -216,7 +216,8 @@
void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
CallInfo callinfo;
- LinkResolver::resolve_special_call(callinfo, klass, name, signature, KlassHandle(), false, CHECK);
+ LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false);
+ LinkResolver::resolve_special_call(callinfo, link_info, CHECK);
methodHandle method = callinfo.selected_method();
assert(method.not_null(), "should have thrown exception");
@@ -250,7 +251,8 @@
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
CallInfo callinfo;
- LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK);
+ LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false);
+ LinkResolver::resolve_static_call(callinfo, link_info, true, CHECK);
methodHandle method = callinfo.selected_method();
assert(method.not_null(), "should have thrown exception");
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/runtime/os.cpp
--- a/hotspot/src/share/vm/runtime/os.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -775,6 +775,10 @@
pd_start_thread(thread);
}
+void os::abort(bool dump_core) {
+ abort(dump_core && CreateCoredumpOnCrash, NULL, NULL);
+}
+
//---------------------------------------------------------------------------
// Helper functions for fatal error handler
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/runtime/reflection.cpp
--- a/hotspot/src/share/vm/runtime/reflection.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -831,9 +831,9 @@
CallInfo info;
Symbol* signature = method->signature();
Symbol* name = method->name();
- LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass,
- name, signature,
- KlassHandle(), false, true,
+ LinkResolver::resolve_interface_call(info, receiver, recv_klass,
+ LinkInfo(klass, name, signature, KlassHandle(), false),
+ true,
CHECK_(methodHandle()));
return info.selected_method();
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/runtime/vmStructs.cpp
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/services/diagnosticCommand.cpp
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Wed Jul 05 20:37:58 2017 +0200
@@ -315,7 +315,7 @@
void SystemGCDCmd::execute(DCmdSource source, TRAPS) {
if (!DisableExplicitGC) {
- Universe::heap()->collect(GCCause::_java_lang_system_gc);
+ Universe::heap()->collect(GCCause::_dcmd_gc_run);
} else {
output()->print_cr("Explicit GC is disabled, no GC has been performed.");
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/src/share/vm/utilities/fakeRttiSupport.hpp
--- a/hotspot/src/share/vm/utilities/fakeRttiSupport.hpp Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/src/share/vm/utilities/fakeRttiSupport.hpp Wed Jul 05 20:37:58 2017 +0200
@@ -89,11 +89,11 @@
return ((uintx)1) << validate_tag(tag);
}
- static TagType validate_tag(uintx tag) {
- // Type of tag is not TagType to dodge useless MacOSX compiler warning.
- assert(tag < (sizeof(uintx) * BitsPerByte),
- err_msg("Tag " UINTX_FORMAT " is too large", tag));
- return static_cast(tag);
+ static TagType validate_tag(TagType tag) {
+ assert(0 <= tag, err_msg("Tag " INTX_FORMAT " is negative", (intx)tag));
+ assert(tag < BitsPerWord,
+ err_msg("Tag " UINTX_FORMAT " is too large", (uintx)tag));
+ return tag;
}
};
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/compiler/arraycopy/TestDeadArrayCopyOnMemChain.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/arraycopy/TestDeadArrayCopyOnMemChain.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8080699
+ * @summary eliminated arraycopy node still reachable through exception edges
+ * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation TestDeadArrayCopyOnMemChain
+ *
+ */
+
+public class TestDeadArrayCopyOnMemChain {
+ static class A {
+ int f;
+ }
+
+ static void test_helper(Object o) {
+ }
+
+ static void test(int src_off, boolean flag) {
+ // dst is eliminated first. Eliminating dst causes src to be
+ // eliminated. When working on the safepoint at the uncommon
+ // trap in the exception handler, the eliminated ArrayCopyNode
+ // is reached through the exception edges.
+ Object[] dst = new Object[10];
+ Object[] src = new Object[10];
+
+ // src_off causes the exception handler to be run sometimes
+ try {
+ System.arraycopy(src, src_off, dst, 0, 10);
+ } catch (IndexOutOfBoundsException ioobe) {
+ // flag always false so test becomes uncommon trap. Make
+ // sure src is live at the unc.
+ if (flag) {
+ test_helper(src);
+ }
+ }
+ }
+
+ static public void main(String[] args) {
+ for (int i = 0; i < 20000; i++) {
+ test((i%2) == 0 ? 0 : -1, false);
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/compiler/jsr292/CallSiteDepContextTest.java
--- a/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -24,12 +24,15 @@
/**
* @test
* @bug 8057967
- * @ignore 8079205
- * @run main/bootclasspath -Xbatch java.lang.invoke.CallSiteDepContextTest
+ * @run main/bootclasspath -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+TraceClassUnloading
+ * -XX:+PrintCompilation -XX:+TraceDependencies -XX:+TraceReferenceGC
+ * -verbose:gc java.lang.invoke.CallSiteDepContextTest
*/
package java.lang.invoke;
import java.lang.ref.*;
+import java.lang.reflect.Field;
+
import jdk.internal.org.objectweb.asm.*;
import sun.misc.Unsafe;
@@ -96,6 +99,13 @@
}
}
+ public static void testHiddenDepField() throws Exception {
+ try {
+ Field f = MethodHandleNatives.CallSiteContext.class.getDeclaredField("vmdependencies");
+ throw new AssertionError("Context.dependencies field should be hidden");
+ } catch(NoSuchFieldException e) { /* expected */ }
+ }
+
public static void testSharedCallSite() throws Throwable {
Class> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_1"), null);
Class> cls2 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_2"), null);
@@ -132,12 +142,14 @@
static ReferenceQueue rq = new ReferenceQueue();
static PhantomReference ref;
- public static void testGC() throws Throwable {
+ public static void testGC(boolean clear, boolean precompile) throws Throwable {
+ String id = "_" + clear + "_" + precompile;
+
mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
Class>[] cls = new Class[] {
- UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_1"), null),
- UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_2"), null),
+ UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_1" + id), null),
+ UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_2" + id), null),
};
MethodHandle[] mhs = new MethodHandle[] {
@@ -151,30 +163,38 @@
execute(1, mhs);
ref = new PhantomReference<>(cls[0], rq);
- cls[0] = UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_3"), null);
+ cls[0] = UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_3" + id), null);
mhs[0] = LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE);
do {
System.gc();
try {
- Reference ref1 = rq.remove(1000);
+ Reference ref1 = rq.remove(100);
if (ref1 == ref) {
- ref1.clear();
- System.gc(); // Ensure that the stale context is cleared
break;
}
} catch(InterruptedException e) { /* ignore */ }
} while (true);
- execute(1, mhs);
+ if (clear) {
+ ref.clear();
+ System.gc(); // Ensure that the stale context is unloaded
+ }
+ if (precompile) {
+ execute(1, mhs);
+ }
mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
execute(2, mhs);
}
public static void main(String[] args) throws Throwable {
+ testHiddenDepField();
testSharedCallSite();
testNonBoundCallSite();
- testGC();
+ testGC(false, false);
+ testGC(false, true);
+ testGC( true, false);
+ testGC( true, true);
System.out.println("TEST PASSED");
}
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/compiler/loopopts/superword/TestReductionWithLoopVariantUse.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/loopopts/superword/TestReductionWithLoopVariantUse.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8080976
+ * @summary Loop variant use in reduction should prevent vectorization
+ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestReductionWithLoopVariantUse
+ *
+ */
+
+public class TestReductionWithLoopVariantUse {
+ static int m(int[] array) {
+ int c = 0;
+ for (int i = 0; i < 256; i++) {
+ c += array[i];
+ array[i] = c;
+ }
+ return c;
+ }
+
+ static public void main(String[] args) {
+ int[] array = new int[256];
+ int[] array2 = new int[256];
+ for (int j = 0; j < 256; j++) {
+ array2[j] = j;
+ }
+ for (int i = 0; i < 20000; i++) {
+ System.arraycopy(array2, 0, array, 0, 256);
+ int res = m(array);
+ boolean success = true;
+ int c = 0;
+ for (int j = 0; j < 256; j++) {
+ c += array2[j];
+ if (array[j] != c) {
+ System.out.println("Failed for " + j + " : " + array[j] + " != " + c);
+ success = false;
+ }
+ }
+ if (c != res) {
+ System.out.println("Failed for sum: " + c + " != " + res);
+ }
+ if (!success) {
+ throw new RuntimeException("Test failed");
+ }
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/compiler/types/TestTypePropagationToCmpU.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/TestTypePropagationToCmpU.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8080156 8060036
+ * @summary Test correctness of type propagation to CmpUNodes.
+ * @run main TestTypePropagationToCmpU
+ */
+public class TestTypePropagationToCmpU {
+ public static void main(String[] args) {
+ try {
+ // Trigger compilation
+ for (int i = 0; i < 100_000; ++i) {
+ test();
+ }
+ } catch (NullPointerException e) {
+ // Test should never throw a NullPointerException
+ throw new RuntimeException("Test failed");
+ }
+ }
+
+ static int global = 42;
+
+ public static void test() {
+ int a = Integer.MIN_VALUE;
+ int b = global;
+ char[] buf = { 0 };
+ for (int i = 0; i <= b; ++i) {
+ a = i - b;
+ }
+ // C2 adds a range check and an uncommon trap here to ensure that the array index
+ // is in bounds. If type information is not propagated correctly to the corresponding
+ // CmpUNode, this trap may be always taken. Because C2 also removes the unnecessary
+ // allocation of 'buf', a NullPointerException is thrown in this case.
+ char c = buf[(a * 11) / 2 - a]; // a is 0 here if global >= 0
+ buf[0] = 0;
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/compiler/unsafe/TestUnsafeLoadControl.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/unsafe/TestUnsafeLoadControl.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8077504
+ * @summary Unsafe load can loose control dependency and cause crash
+ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestUnsafeLoadControl
+ *
+ */
+
+import java.lang.reflect.Field;
+import sun.misc.Unsafe;
+
+public class TestUnsafeLoadControl {
+
+ private static final Unsafe UNSAFE;
+
+ static {
+ try {
+ Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+ unsafeField.setAccessible(true);
+ UNSAFE = (Unsafe) unsafeField.get(null);
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static int val;
+ static void test1(int[] a, boolean[] flags, boolean flag, long j) {
+ for (int i = 0; i < 10; i++) {
+ if (flags[i]) {
+ if (flag) {
+ long address = (j << 2) + UNSAFE.ARRAY_INT_BASE_OFFSET;
+ int v = UNSAFE.getInt(a, address);
+ val = v;
+ }
+ }
+ }
+ }
+
+ static int test2(int[] a, boolean[] flags, boolean flag, long j) {
+ int sum = 0;
+ for (int i = 0; i < 10; i++) {
+ if (flags[i]) {
+ if (flag) {
+ long address = (j << 2) + UNSAFE.ARRAY_INT_BASE_OFFSET;
+ int v = UNSAFE.getInt(a, address);
+ if (v == 0) {
+ sum++;
+ }
+ }
+ }
+ }
+ return sum;
+ }
+
+ static public void main(String[] args) {
+ boolean[] flags = new boolean[10];
+ for (int i = 0; i < flags.length; i++) {
+ flags[i] = true;
+ }
+ int[] array = new int[10];
+ for (int i = 0; i < 20000; i++) {
+ test1(array, flags, true, 0);
+ }
+ for (int i = 0; i < flags.length; i++) {
+ flags[i] = false;
+ }
+ test1(array, flags, true, Long.MAX_VALUE/4);
+
+ for (int i = 0; i < flags.length; i++) {
+ flags[i] = true;
+ }
+ for (int i = 0; i < 20000; i++) {
+ test2(array, flags, true, 0);
+ }
+ for (int i = 0; i < flags.length; i++) {
+ flags[i] = false;
+ }
+ test2(array, flags, true, Long.MAX_VALUE/4);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/gc/TestSmallHeap.java
--- a/hotspot/test/gc/TestSmallHeap.java Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/test/gc/TestSmallHeap.java Wed Jul 05 20:37:58 2017 +0200
@@ -27,6 +27,7 @@
* @requires vm.gc=="null"
* @requires (vm.opt.AggressiveOpts=="null") | (vm.opt.AggressiveOpts=="false")
* @requires vm.compMode != "Xcomp"
+ * @requires vm.opt.UseCompressedOops != false
* @summary Verify that starting the VM with a small heap works
* @library /testlibrary /../../test/lib
* @modules java.management/sun.management
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/runtime/jni/ToStringInInterfaceTest/ImplementationOfWithToString.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/ToStringInInterfaceTest/ImplementationOfWithToString.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/**
+ * Implementation of InterfaceWithToString.
+ */
+public class ImplementationOfWithToString implements InterfaceWithToString {
+
+ /**
+ * @see InterfaceWithToString#someMethod()
+ * {@inheritDoc}
+ */
+ @Override
+ public void someMethod() {
+ // May do something here.
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "toString() from " + getClass().getName();
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/runtime/jni/ToStringInInterfaceTest/InterfaceWithToString.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/ToStringInInterfaceTest/InterfaceWithToString.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/**
+ * Interface with toString declared.
+ */
+public interface InterfaceWithToString {
+
+ void someMethod();
+
+ /**
+ * Same as Object.toString().
+ *
+ * @return some custom string.
+ */
+ String toString();
+}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/runtime/jni/ToStringInInterfaceTest/ToStringTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/ToStringInInterfaceTest/ToStringTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8072588
+ * @build InterfaceWithToString
+ * @build ImplementationOfWithToString
+ * @run main/native ToStringTest
+ */
+public final class ToStringTest {
+
+ static {
+ System.loadLibrary("ToStringTest");
+ }
+
+ native static void nTest();
+
+ public static void main(String[] args) throws Exception {
+ nTest();
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/runtime/jni/ToStringInInterfaceTest/libToStringTest.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/ToStringInInterfaceTest/libToStringTest.c Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * Native test for ToStringInInterfaceTest.
+ */
+
+#include "jni.h"
+
+#define checkException(env) if ((*env)->ExceptionCheck(env)) { return; }
+
+jstring callStringMethod(JNIEnv* env, jobject jobj, jmethodID id, ...)
+{
+ jstring value;
+
+ va_list ap;
+ va_start(ap, id);
+ value = (jstring)(*env)->CallObjectMethodV(env, jobj, id, ap);
+ va_end(ap);
+ return value;
+}
+
+JNIEXPORT void JNICALL Java_ToStringTest_nTest(JNIEnv* env, jclass jclazz)
+{
+ jclass classOfInterfaceWithToString;
+ jclass classOfImplementationOfWithToString;
+ jmethodID constructorOfImplementationOfWithToString;
+ jobject instanceOfImplementationOfWithToString;
+ jmethodID toStringOfInterfaceWithToString;
+ jmethodID toStringOfImplementationOfWithToString;
+ jstring jstr;
+ const char *chars;
+
+ classOfInterfaceWithToString = (*env)->FindClass(env, "InterfaceWithToString");
+ checkException(env);
+ classOfImplementationOfWithToString = (*env)->FindClass(env, "ImplementationOfWithToString");
+ checkException(env);
+
+ constructorOfImplementationOfWithToString = (*env)->GetMethodID(env, classOfImplementationOfWithToString, "", "()V");
+ checkException(env);
+
+ instanceOfImplementationOfWithToString = (*env)->NewObject(env, classOfImplementationOfWithToString, constructorOfImplementationOfWithToString);
+ checkException(env);
+
+ toStringOfInterfaceWithToString = (*env)->GetMethodID(env, classOfInterfaceWithToString, "toString", "()Ljava/lang/String;");
+ checkException(env);
+
+ toStringOfImplementationOfWithToString = (*env)->GetMethodID(env, classOfImplementationOfWithToString, "toString", "()Ljava/lang/String;");
+ checkException(env);
+
+ jstr = callStringMethod(env, instanceOfImplementationOfWithToString, toStringOfImplementationOfWithToString);
+ checkException(env);
+
+ chars = (*env)->GetStringUTFChars(env, jstr, NULL);
+ (*env)->ReleaseStringUTFChars(env, jstr, chars);
+
+ jstr = callStringMethod(env, instanceOfImplementationOfWithToString, toStringOfInterfaceWithToString);
+ checkException(env);
+
+ chars = (*env)->GetStringUTFChars(env, jstr, NULL);
+ (*env)->ReleaseStringUTFChars(env, jstr, chars);
+}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/serviceability/dcmd/gc/RunGCTest.java
--- a/hotspot/test/serviceability/dcmd/gc/RunGCTest.java Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/test/serviceability/dcmd/gc/RunGCTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -59,7 +59,7 @@
}
OutputAnalyzer output = new OutputAnalyzer(gcLog, "");
- output.shouldMatch(".*\\[Full GC \\(System(\\.gc\\(\\))?.*");
+ output.shouldContain("[Full GC (Diagnostic Command)");
}
@Test
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/serviceability/sa/TestClassLoaderStats.java
--- a/hotspot/test/serviceability/sa/TestClassLoaderStats.java Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/test/serviceability/sa/TestClassLoaderStats.java Wed Jul 05 20:37:58 2017 +0200
@@ -24,11 +24,14 @@
import jdk.test.lib.Platform;
import jdk.test.lib.ProcessTools;
import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.apps.LingeredApp;
/*
* @test
+ * @library /../../test/lib/share/classes
* @library /testlibrary
* @build jdk.test.lib.*
+ * @build jdk.test.lib.apps.*
* @run main TestClassLoaderStats
*/
public class TestClassLoaderStats {
@@ -39,19 +42,27 @@
return;
}
- ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
- "-XX:+UsePerfData",
- "sun.jvm.hotspot.tools.ClassLoaderStats",
- Integer.toString(ProcessTools.getProcessId()));
- OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
- System.out.println(output.getOutput());
+ LingeredApp app = null;
+ try {
+ app = LingeredApp.startApp();
- output.shouldHaveExitValue(0);
- output.shouldContain("Debugger attached successfully.");
- // The class loader stats header needs to be presented in the output:
- output.shouldMatch("class_loader\\W+classes\\W+bytes\\W+parent_loader\\W+alive?\\W+type");
- output.stderrShouldNotMatch("[E|e]xception");
- output.stderrShouldNotMatch("[E|e]rror");
+ System.out.println("Attaching sun.jvm.hotspot.tools.ClassLoaderStats to " + app.getPid());
+ ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UsePerfData",
+ "sun.jvm.hotspot.tools.ClassLoaderStats",
+ Long.toString(app.getPid()));
+ OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
+ System.out.println(output.getOutput());
+
+ output.shouldHaveExitValue(0);
+ output.shouldContain("Debugger attached successfully.");
+ // The class loader stats header needs to be presented in the output:
+ output.shouldMatch("class_loader\\W+classes\\W+bytes\\W+parent_loader\\W+alive?\\W+type");
+ output.stderrShouldNotMatch("[E|e]xception");
+ output.stderrShouldNotMatch("[E|e]rror");
+ } finally {
+ app.stopApp();
+ }
}
}
diff -r 97f4fef2d420 -r a9714a11e787 hotspot/test/serviceability/sa/TestStackTrace.java
--- a/hotspot/test/serviceability/sa/TestStackTrace.java Thu Jun 11 20:20:05 2015 -0700
+++ b/hotspot/test/serviceability/sa/TestStackTrace.java Wed Jul 05 20:37:58 2017 +0200
@@ -24,11 +24,14 @@
import jdk.test.lib.OutputAnalyzer;
import jdk.test.lib.Platform;
import jdk.test.lib.ProcessTools;
+import jdk.test.lib.apps.LingeredApp;
/*
* @test
+ * @library /../../test/lib/share/classes
* @library /testlibrary
* @build jdk.test.lib.*
+ * @build jdk.test.lib.apps.*
* @run main TestStackTrace
*/
public class TestStackTrace {
@@ -39,17 +42,25 @@
return;
}
- ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
- "-XX:+UsePerfData",
- "sun.jvm.hotspot.tools.StackTrace",
- Integer.toString(ProcessTools.getProcessId()));
- OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
- System.out.println(output.getOutput());
+ LingeredApp app = null;
+ try {
+ app = LingeredApp.startApp();
- output.shouldHaveExitValue(0);
- output.shouldContain("Debugger attached successfully.");
- output.stderrShouldNotMatch("[E|e]xception");
- output.stderrShouldNotMatch("[E|e]rror");
+ System.out.println("Attaching sun.jvm.hotspot.tools.StackTrace to " + app.getPid());
+ ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UsePerfData",
+ "sun.jvm.hotspot.tools.StackTrace",
+ Long.toString(app.getPid()));
+ OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
+ System.out.println(output.getOutput());
+
+ output.shouldHaveExitValue(0);
+ output.shouldContain("Debugger attached successfully.");
+ output.stderrShouldNotMatch("[E|e]xception");
+ output.stderrShouldNotMatch("[E|e]rror");
+ } finally {
+ app.stopApp();
+ }
}
}
diff -r 97f4fef2d420 -r a9714a11e787 jaxp/.hgtags
--- a/jaxp/.hgtags Thu Jun 11 20:20:05 2015 -0700
+++ b/jaxp/.hgtags Wed Jul 05 20:37:58 2017 +0200
@@ -310,3 +310,4 @@
ae7406e82828fe1c245ac7507a9da5fd5b1c9529 jdk9-b65
d5963ccce28d7a3e96ee3e2dc8a8676e61699b70 jdk9-b66
78c2685daabafae827c686ca2d1bb2e451faed2b jdk9-b67
+82aae947938ec9b0119fdd78a616d0b7263072ee jdk9-b68
diff -r 97f4fef2d420 -r a9714a11e787 jaxp/test/javax/xml/jaxp/functional/TEST.properties
--- a/jaxp/test/javax/xml/jaxp/functional/TEST.properties Thu Jun 11 20:20:05 2015 -0700
+++ b/jaxp/test/javax/xml/jaxp/functional/TEST.properties Wed Jul 05 20:37:58 2017 +0200
@@ -7,3 +7,6 @@
# Tests that must run in othervm mode
othervm.dirs= /javax/xml/jaxp/functional
+# Declare module dependency
+modules=java.xml
+
diff -r 97f4fef2d420 -r a9714a11e787 jaxp/test/javax/xml/jaxp/unittest/TEST.properties
--- a/jaxp/test/javax/xml/jaxp/unittest/TEST.properties Thu Jun 11 20:20:05 2015 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/TEST.properties Wed Jul 05 20:37:58 2017 +0200
@@ -1,3 +1,6 @@
# jaxp test uses TestNG
TestNG.dirs = .
+# Declare module dependency
+modules=java.xml
+
diff -r 97f4fef2d420 -r a9714a11e787 jaxp/test/javax/xml/jaxp/unittest/javax/xml/parsers/xinclude/Bug6794483Test.java
--- a/jaxp/test/javax/xml/jaxp/unittest/javax/xml/parsers/xinclude/Bug6794483Test.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/javax/xml/parsers/xinclude/Bug6794483Test.java Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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,37 +23,47 @@
package javax.xml.parsers.xinclude;
+import static java.lang.System.lineSeparator;
+import static org.testng.Assert.assertEquals;
+
import java.io.File;
-import java.io.IOException;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
-import org.testng.Assert;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
+import org.w3c.dom.NodeList;
/*
- * @bug 6794483
- * @summary Test JAXP parser can parse xml file using to include another xml, which has an empty element.
+ * @bug 6794483 8080908
+ * @summary Test JAXP parser can resolve the included content properly if the
+ * included xml contains an empty tag that ends with "/>", refer to XERCESJ-1134.
*/
public class Bug6794483Test {
@Test
- public final void test() {
- String xml = getClass().getResource("test1.xml").getPath();
- Document doc = parseXmlFile(xml);
+ public final void test() throws Exception {
+ Document doc = parseXmlFile(getClass().getResource("test1.xml").getPath());
+
+ // check node4
+ NodeList nodeList = doc.getElementsByTagName("node4");
+ assertEquals(nodeList.getLength(), 1);
+ assertEquals(nodeList.item(0).getTextContent(), "Node4 Value", "The data of node4 is missed in parsing: " + lineSeparator() + printXmlDoc(doc));
+ // check node6
+ nodeList = doc.getElementsByTagName("node6");
+ assertEquals(nodeList.getLength(), 1);
+ assertEquals(nodeList.item(0).getTextContent(), "Node6 Value", "The data of node6 is missed in parsing: " + lineSeparator() + printXmlDoc(doc));
+ }
+
+ public String printXmlDoc(Document doc) throws Exception {
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
@@ -61,27 +71,16 @@
transformerFact.setAttribute("indent-number", new Integer(4));
Transformer transformer;
- try {
- transformer = transformerFact.newTransformer();
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- transformer.setOutputProperty(OutputKeys.METHOD, "xml");
- transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "text/xml");
+ transformer = transformerFact.newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+ transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "text/xml");
- // "true" indicate Append content If file exist in system
- transformer.transform(new DOMSource(doc), result);
- System.out.println("test" + sw);
-
- } catch (TransformerConfigurationException ex) {
- ex.printStackTrace();
- Assert.fail("unexpected TransformerConfigurationException");
- } catch (TransformerException ex) {
- ex.printStackTrace();
- Assert.fail("unexpected TransformerException");
- }
-
+ transformer.transform(new DOMSource(doc), result);
+ return sw.toString();
}
- public Document parseXmlFile(String fileName) {
+ public Document parseXmlFile(String fileName) throws Exception {
System.out.println("Parsing XML file... " + fileName);
DocumentBuilder docBuilder = null;
Document doc = null;
@@ -92,20 +91,10 @@
docBuilderFactory.setNamespaceAware(true);
docBuilderFactory.setExpandEntityReferences(true);
- try {
- docBuilder = docBuilderFactory.newDocumentBuilder();
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- }
+ docBuilder = docBuilderFactory.newDocumentBuilder();
File sourceFile = new File(fileName);
- try {
- doc = docBuilder.parse(sourceFile);
- } catch (SAXException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
+ doc = docBuilder.parse(sourceFile);
System.out.println("XML file parsed");
return doc;
diff -r 97f4fef2d420 -r a9714a11e787 jaxp/test/javax/xml/jaxp/unittest/org/w3c/dom/ls/LSSerializerTest.java
--- a/jaxp/test/javax/xml/jaxp/unittest/org/w3c/dom/ls/LSSerializerTest.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/org/w3c/dom/ls/LSSerializerTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -44,6 +44,7 @@
/*
+ * @bug 6439439 8080906
* @summary Test LSSerializer.
*/
public class LSSerializerTest {
@@ -98,6 +99,17 @@
}
}
+ /*
+ * @bug 8080906
+ * It will fail in a Jigsaw build until JDK-8080266 is fixed.
+ */
+ @Test
+ public void testDefaultLSSerializer() throws Exception {
+ DOMImplementationLS domImpl = (DOMImplementationLS) DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
+ LSSerializer lsSerializer = domImpl.createLSSerializer();
+ Assert.assertTrue(lsSerializer.getClass().getName().endsWith("dom3.LSSerializerImpl"));
+ }
+
@Test
public void testDOMErrorHandler() {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/.hgtags
--- a/jdk/.hgtags Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/.hgtags Wed Jul 05 20:37:58 2017 +0200
@@ -310,3 +310,4 @@
ed94f3e7ba6bbfec0772de6d24e39543e13f6d88 jdk9-b65
4fbcca8ab812198c7fb747ea7b213b6e404f36e9 jdk9-b66
1abd45df5480a04bff98fba1851d66a5230e67d4 jdk9-b67
+046fd17bb9a0cdf6681124866df9626d17b0516a jdk9-b68
diff -r 97f4fef2d420 -r a9714a11e787 jdk/make/lib/Lib-java.instrument.gmk
--- a/jdk/make/lib/Lib-java.instrument.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/make/lib/Lib-java.instrument.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -61,7 +61,7 @@
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBINSTRUMENT_SRC), \
OPTIMIZATION := LOW, \
- CFLAGS := $(LIBINSTRUMENT_CFLAGS) $(CFLAGS_WARNINGS_ARE_ERRORS), \
+ CFLAGS := $(LIBINSTRUMENT_CFLAGS), \
CFLAGS_debug := -DJPLIS_LOGGING, \
CFLAGS_release := -DNO_JPLIS_LOGGING, \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libinstrument/mapfile-vers, \
diff -r 97f4fef2d420 -r a9714a11e787 jdk/make/lib/Lib-java.management.gmk
--- a/jdk/make/lib/Lib-java.management.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/make/lib/Lib-java.management.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -50,7 +50,7 @@
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBMANAGEMENT_SRC), \
OPTIMIZATION := $(LIBMANAGEMENT_OPTIMIZATION), \
- CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) $(LIBMANAGEMENT_CFLAGS), \
+ CFLAGS := $(CFLAGS_JDKLIB) $(LIBMANAGEMENT_CFLAGS), \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libmanagement/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
diff -r 97f4fef2d420 -r a9714a11e787 jdk/make/lib/Lib-jdk.attach.gmk
--- a/jdk/make/lib/Lib-jdk.attach.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/make/lib/Lib-jdk.attach.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,7 @@
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(call FindSrcDirsForLib, jdk.attach, attach), \
OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \
+ CFLAGS := $(CFLAGS_JDKLIB) \
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.attach \
$(LIBJAVA_HEADER_FLAGS) $(LIBATTACH_CFLAGS), \
CFLAGS_windows := /Gy, \
diff -r 97f4fef2d420 -r a9714a11e787 jdk/make/lib/Lib-jdk.hprof.agent.gmk
--- a/jdk/make/lib/Lib-jdk.hprof.agent.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/make/lib/Lib-jdk.hprof.agent.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, 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
@@ -31,7 +31,7 @@
BUILD_LIBHPROF_CFLAGS := $(addprefix -I, $(BUILD_LIBHPROF_SRC)) \
-I$(JDK_TOPDIR)/src/demo/share/jvmti/java_crw_demo
-
+
BUILD_LIBHPROF_LDFLAGS :=
LIBHPROF_OPTIMIZATION := HIGHEST
@@ -46,7 +46,7 @@
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(BUILD_LIBHPROF_SRC), \
OPTIMIZATION := $(LIBHPROF_OPTIMIZATION), \
- CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \
+ CFLAGS := $(CFLAGS_JDKLIB) \
$(BUILD_LIBHPROF_CFLAGS), \
CFLAGS_debug := -DHPROF_LOGGING, \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libhprof/mapfile-vers, \
@@ -75,7 +75,7 @@
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJAVA_CRW_DEMO_SRC), \
OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \
+ CFLAGS := $(CFLAGS_JDKLIB) \
$(addprefix -I, $(LIBJAVA_CRW_DEMO_SRC)), \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjava_crw_demo/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
diff -r 97f4fef2d420 -r a9714a11e787 jdk/make/lib/Lib-jdk.jdi.gmk
--- a/jdk/make/lib/Lib-jdk.jdi.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/make/lib/Lib-jdk.jdi.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, 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
@@ -44,7 +44,7 @@
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBDT_SHMEM_SRC), \
OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) -DUSE_MMAP \
+ CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \
$(LIBDT_SHMEM_CPPFLAGS), \
LDFLAGS := $(LDFLAGS_JDKLIB), \
LDFLAGS_windows := -export:jdwpTransport_OnLoad, \
diff -r 97f4fef2d420 -r a9714a11e787 jdk/make/lib/Lib-jdk.jdwp.agent.gmk
--- a/jdk/make/lib/Lib-jdk.jdwp.agent.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/make/lib/Lib-jdk.jdwp.agent.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, 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
@@ -41,7 +41,7 @@
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBDT_SOCKET_SRC), \
OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_CFLAGS_WARNINGS_ARE_ERRORS) -DUSE_MMAP \
+ CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \
$(LIBDT_SOCKET_CPPFLAGS), \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libdt_socket/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
@@ -77,7 +77,7 @@
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJDWP_SRC), \
OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) -DJDWP_LOGGING \
+ CFLAGS := $(CFLAGS_JDKLIB) -DJDWP_LOGGING \
$(LIBJDWP_CPPFLAGS) \
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.jdwp.agent, \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjdwp/mapfile-vers, \
diff -r 97f4fef2d420 -r a9714a11e787 jdk/make/lib/Lib-jdk.management.gmk
--- a/jdk/make/lib/Lib-jdk.management.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/make/lib/Lib-jdk.management.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -59,7 +59,7 @@
SRC := $(LIBMANAGEMENT_EXT_SRC), \
LANG := C, \
OPTIMIZATION := $(LIBMANAGEMENT_EXT_OPTIMIZATION), \
- CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) $(LIBMANAGEMENT_EXT_CFLAGS), \
+ CFLAGS := $(CFLAGS_JDKLIB) $(LIBMANAGEMENT_EXT_CFLAGS), \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libmanagement_ext/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
diff -r 97f4fef2d420 -r a9714a11e787 jdk/make/lib/Lib-jdk.sctp.gmk
--- a/jdk/make/lib/Lib-jdk.sctp.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/make/lib/Lib-jdk.sctp.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -30,12 +30,8 @@
ifeq ($(OPENJDK_TARGET_OS_TYPE), unix)
ifeq (, $(filter $(OPENJDK_TARGET_OS), macosx aix))
-
- # Suppress unused parameters required by exported JNI functions.
- SCTP_WERROR := -Werror -Wno-error=unused-parameter
- ifeq ($(OPENJDK_TARGET_CPU_ARCH), ppc)
- SCTP_WERROR :=
- endif
+ # DISABLED_WARNINGS_gcc := unused-parameter needed to
+ # suppress unused parameters required by exported JNI functions.
$(eval $(call SetupNativeCompilation,BUILD_LIBSCTP, \
LIBRARY := sctp, \
@@ -49,7 +45,7 @@
$(LIBJAVA_HEADER_FLAGS) \
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.sctp \
-I$(SUPPORT_OUTPUTDIR)/headers/java.base, \
- CFLAGS_linux := $(SCTP_WERROR), \
+ DISABLED_WARNINGS_gcc := unused-parameter, \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libsctp/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
diff -r 97f4fef2d420 -r a9714a11e787 jdk/make/mapfiles/libjava/mapfile-vers
--- a/jdk/make/mapfiles/libjava/mapfile-vers Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Wed Jul 05 20:37:58 2017 +0200
@@ -129,11 +129,11 @@
Java_java_lang_ClassLoader_defineClass0;
Java_java_lang_ClassLoader_defineClass1;
Java_java_lang_ClassLoader_defineClass2;
+ Java_java_lang_ClassLoader_findBuiltinLib;
Java_java_lang_ClassLoader_findLoadedClass0;
Java_java_lang_ClassLoader_00024NativeLibrary_find;
Java_java_lang_ClassLoader_00024NativeLibrary_load;
Java_java_lang_ClassLoader_00024NativeLibrary_unload;
- Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib;
Java_java_lang_ClassLoader_registerNatives;
Java_java_lang_Double_longBitsToDouble;
Java_java_lang_Double_doubleToRawLongBits;
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/com/sun/net/ssl/SSLContext.java
--- a/jdk/src/java.base/share/classes/com/sun/net/ssl/SSLContext.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/com/sun/net/ssl/SSLContext.java Wed Jul 05 20:37:58 2017 +0200
@@ -58,7 +58,7 @@
*
* @param contextSpi the delegate
* @param provider the provider
- * @param algorithm the algorithm
+ * @param protocol the protocol
*/
protected SSLContext(SSLContextSpi contextSpi, Provider provider,
String protocol) {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/com/sun/net/ssl/SSLContextSpi.java
--- a/jdk/src/java.base/share/classes/com/sun/net/ssl/SSLContextSpi.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/com/sun/net/ssl/SSLContextSpi.java Wed Jul 05 20:37:58 2017 +0200
@@ -49,9 +49,9 @@
/**
* Initializes this context.
*
- * @param km the sources of authentication keys
- * @param tm the sources of peer authentication trust decisions
- * @param random the source of randomness for this generator
+ * @param ah the sources of authentication keys
+ * @param th the sources of peer authentication trust decisions
+ * @param sr the source of randomness for this generator
*/
protected abstract void engineInit(KeyManager[] ah, TrustManager[] th,
SecureRandom sr) throws KeyManagementException;
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/com/sun/net/ssl/SSLPermission.java
--- a/jdk/src/java.base/share/classes/com/sun/net/ssl/SSLPermission.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/com/sun/net/ssl/SSLPermission.java Wed Jul 05 20:37:58 2017 +0200
@@ -52,7 +52,6 @@
* The following table lists all the possible SSLPermission target names,
* and for each provides a description of what the permission allows
* and a discussion of the risks of granting code the permission.
- *
*
*
*
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/io/File.java
--- a/jdk/src/java.base/share/classes/java/io/File.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/io/File.java Wed Jul 05 20:37:58 2017 +0200
@@ -2148,7 +2148,7 @@
* WriteObject is called to save this filename.
* The separator character is saved also so it can be replaced
* in case the path is reconstituted on a different host type.
- *
+ *
* @serialData Default fields followed by separator character.
*/
private synchronized void writeObject(java.io.ObjectOutputStream s)
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/io/FilePermission.java
--- a/jdk/src/java.base/share/classes/java/io/FilePermission.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/io/FilePermission.java Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,11 +27,9 @@
import java.security.*;
import java.util.Enumeration;
-import java.util.List;
-import java.util.ArrayList;
+import java.util.StringJoiner;
import java.util.Vector;
-import java.util.Collections;
-import java.util.StringJoiner;
+import java.util.concurrent.ConcurrentHashMap;
import sun.security.util.SecurityConstants;
/**
@@ -288,7 +286,6 @@
* @param path the pathname of the file/directory.
* @param mask the action mask to use.
*/
-
// package private for use by the FilePermissionCollection add method
FilePermission(String path, int mask) {
super(path);
@@ -315,6 +312,7 @@
* null and is implied by this object,
* false otherwise.
*/
+ @Override
public boolean implies(Permission p) {
if (!(p instanceof FilePermission))
return false;
@@ -387,6 +385,7 @@
* pathname and actions as this FilePermission object,
* false otherwise.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -407,6 +406,7 @@
*
* @return a hash code value for this object.
*/
+ @Override
public int hashCode() {
return 0;
}
@@ -587,6 +587,7 @@
*
* @return the canonical string representation of the actions.
*/
+ @Override
public String getActions() {
if (actions == null)
actions = getActions(this.mask);
@@ -625,6 +626,7 @@
* @return a new PermissionCollection object suitable for storing
* FilePermissions.
*/
+ @Override
public PermissionCollection newPermissionCollection() {
return new FilePermissionCollection();
}
@@ -689,13 +691,13 @@
implements Serializable
{
// Not serialized; see serialization section at end of class
- private transient List perms;
+ private transient ConcurrentHashMap perms;
/**
* Create an empty FilePermissionCollection object.
*/
public FilePermissionCollection() {
- perms = new ArrayList<>();
+ perms = new ConcurrentHashMap<>();
}
/**
@@ -710,6 +712,7 @@
* @exception SecurityException - if this FilePermissionCollection object
* has been marked readonly
*/
+ @Override
public void add(Permission permission) {
if (! (permission instanceof FilePermission))
throw new IllegalArgumentException("invalid permission: "+
@@ -718,9 +721,31 @@
throw new SecurityException(
"attempt to add a Permission to a readonly PermissionCollection");
- synchronized (this) {
- perms.add(permission);
- }
+ FilePermission fp = (FilePermission)permission;
+
+ // Add permission to map if it is absent, or replace with new
+ // permission if applicable. NOTE: cannot use lambda for
+ // remappingFunction parameter until JDK-8076596 is fixed.
+ perms.merge(fp.getName(), fp,
+ new java.util.function.BiFunction<>() {
+ @Override
+ public Permission apply(Permission existingVal,
+ Permission newVal) {
+ int oldMask = ((FilePermission)existingVal).getMask();
+ int newMask = ((FilePermission)newVal).getMask();
+ if (oldMask != newMask) {
+ int effective = oldMask | newMask;
+ if (effective == newMask) {
+ return newVal;
+ }
+ if (effective != oldMask) {
+ return new FilePermission(fp.getName(), effective);
+ }
+ }
+ return existingVal;
+ }
+ }
+ );
}
/**
@@ -732,26 +757,25 @@
* @return true if "permission" is a proper subset of a permission in
* the set, false if not.
*/
+ @Override
public boolean implies(Permission permission) {
if (! (permission instanceof FilePermission))
return false;
- FilePermission fp = (FilePermission) permission;
+ FilePermission fperm = (FilePermission) permission;
- int desired = fp.getMask();
+ int desired = fperm.getMask();
int effective = 0;
int needed = desired;
- synchronized (this) {
- int len = perms.size();
- for (int i = 0; i < len; i++) {
- FilePermission x = (FilePermission) perms.get(i);
- if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(fp)) {
- effective |= x.getMask();
- if ((effective & desired) == desired)
- return true;
- needed = (desired ^ effective);
+ for (Permission perm : perms.values()) {
+ FilePermission fp = (FilePermission)perm;
+ if (((needed & fp.getMask()) != 0) && fp.impliesIgnoreMask(fperm)) {
+ effective |= fp.getMask();
+ if ((effective & desired) == desired) {
+ return true;
}
+ needed = (desired ^ effective);
}
}
return false;
@@ -763,11 +787,9 @@
*
* @return an enumeration of all the FilePermission objects.
*/
+ @Override
public Enumeration elements() {
- // Convert Iterator into Enumeration
- synchronized (this) {
- return Collections.enumeration(perms);
- }
+ return perms.elements();
}
private static final long serialVersionUID = 2202956749081564585L;
@@ -795,10 +817,7 @@
// Don't call out.defaultWriteObject()
// Write out Vector
- Vector permissions = new Vector<>(perms.size());
- synchronized (this) {
- permissions.addAll(perms);
- }
+ Vector permissions = new Vector<>(perms.values());
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", permissions);
@@ -819,7 +838,9 @@
// Get the one we want
@SuppressWarnings("unchecked")
Vector permissions = (Vector)gfields.get("permissions", null);
- perms = new ArrayList<>(permissions.size());
- perms.addAll(permissions);
+ perms = new ConcurrentHashMap<>(permissions.size());
+ for (Permission perm : permissions) {
+ perms.put(perm.getName(), perm);
+ }
}
}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/lang/Class.java
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/lang/ClassLoader.java
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Wed Jul 05 20:37:58 2017 +0200
@@ -1702,7 +1702,6 @@
native long find(String name);
native void unload(String name, boolean isBuiltin);
- static native String findBuiltinLib(String name);
public NativeLibrary(Class> fromClass, String name, boolean isBuiltin) {
this.name = name;
@@ -1861,9 +1860,11 @@
throw new UnsatisfiedLinkError("no " + name + " in java.library.path");
}
+ static native String findBuiltinLib(String name);
+
private static boolean loadLibrary0(Class> fromClass, final File file) {
// Check to see if we're attempting to access a static library
- String name = NativeLibrary.findBuiltinLib(file.getName());
+ String name = findBuiltinLib(file.getName());
boolean isBuiltin = (name != null);
if (!isBuiltin) {
name = AccessController.doPrivileged(
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/lang/Process.java
--- a/jdk/src/java.base/share/classes/java/lang/Process.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Process.java Wed Jul 05 20:37:58 2017 +0200
@@ -368,7 +368,7 @@
* Processes returned from {@link ProcessBuilder#start} override the
* default implementation to provide an efficient mechanism to wait
* for process exit.
- *
+ *
* @apiNote
* Using {@link #onExit() onExit} is an alternative to
* {@link #waitFor() waitFor} that enables both additional concurrency
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/lang/ProcessHandle.java
--- a/jdk/src/java.base/share/classes/java/lang/ProcessHandle.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessHandle.java Wed Jul 05 20:37:58 2017 +0200
@@ -71,7 +71,7 @@
* The ability to control processes is also restricted by the native system,
* ProcessHandle provides no more access to, or control over, the native process
* than would be allowed by a native application.
- *
+ *
* @implSpec
* In the case where ProcessHandles cannot be supported then the factory
* methods must consistently throw {@link java.lang.UnsupportedOperationException}.
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java Wed Jul 05 20:37:58 2017 +0200
@@ -27,8 +27,6 @@
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-import java.lang.reflect.Field;
-import sun.misc.Cleaner;
/**
* A {@code CallSite} is a holder for a variable {@link MethodHandle},
@@ -138,47 +136,9 @@
/**
* {@code CallSite} dependency context.
- * VM uses context class to store nmethod dependencies on the call site target.
- * Can be in 2 states: (a) null; or (b) {@code Cleaner} instance pointing to some Class instance.
- * Lazily initialized when CallSite instance is linked to some indy call site or VM needs
- * it to store dependencies. As a corollary, "null" context means there are no dependencies
- * registered yet. {@code Cleaner} is used in 2 roles:
- * (a) context class access for VM;
- * (b) stale context class cleanup.
- * {@code Cleaner} holds the context class until cleanup action is finished (see {@code PhantomReference}).
- * Though it's impossible to get the context class using {@code Reference.get()}, VM extracts it directly
- * from {@code Reference.referent} field.
- */
- private volatile Cleaner context = null;
-
- /**
- * Default context.
- * VM uses it to initialize non-linked CallSite context.
+ * JVM uses CallSite.context to store nmethod dependencies on the call site target.
*/
- private static class DefaultContext {}
- private static final Cleaner DEFAULT_CONTEXT = makeContext(DefaultContext.class, null);
-
- private static Cleaner makeContext(Class> referent, final CallSite holder) {
- return Cleaner.create(referent,
- new Runnable() {
- @Override public void run() {
- MethodHandleNatives.invalidateDependentNMethods(holder);
- }
- });
- }
-
- /** Initialize context class used for nmethod dependency tracking */
- /*package-private*/
- void initContext(Class> newContext) {
- // If there are concurrent actions, exactly one succeeds.
- if (context == null) {
- UNSAFE.compareAndSwapObject(this, CONTEXT_OFFSET, /*expected=*/null, makeContext(newContext, this));
- // No need to care about failed CAS attempt.
- // Since initContext is called from indy call site linkage in newContext class, there's no risk
- // that the context class becomes dead while corresponding context cleaner is alive (causing cleanup
- // action in the wrong context).
- }
- }
+ private final MethodHandleNatives.CallSiteContext context = MethodHandleNatives.CallSiteContext.make(this);
/**
* Returns the type of this call site's target.
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Wed Jul 05 20:37:58 2017 +0200
@@ -30,6 +30,7 @@
import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+import sun.misc.Cleaner;
/**
* The JVM interface for the method handles package is all here.
@@ -61,8 +62,27 @@
static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
- /** Invalidate CallSite context: clean up dependent nmethods and reset call site context to initial state (null). */
- static native void invalidateDependentNMethods(CallSite site);
+ /** Represents a context to track nmethod dependencies on CallSite instance target. */
+ static class CallSiteContext implements Runnable {
+ //@Injected JVM_nmethodBucket* vmdependencies;
+
+ static CallSiteContext make(CallSite cs) {
+ final CallSiteContext newContext = new CallSiteContext();
+ // Cleaner is attached to CallSite instance and it clears native structures allocated for CallSite context.
+ // Though the CallSite can become unreachable, its Context is retained by the Cleaner instance (which is
+ // referenced from Cleaner class) until cleanup is performed.
+ Cleaner.create(cs, newContext);
+ return newContext;
+ }
+
+ @Override
+ public void run() {
+ MethodHandleNatives.clearCallSiteContext(this);
+ }
+ }
+
+ /** Invalidate all recorded nmethods. */
+ private static native void clearCallSiteContext(CallSiteContext context);
private static native void registerNatives();
static {
@@ -235,7 +255,6 @@
return Invokers.linkToTargetMethod(type);
} else {
appendixResult[0] = callSite;
- callSite.initContext(caller);
return Invokers.linkToCallSiteMethod(type);
}
}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/net/SocketPermission.java
--- a/jdk/src/java.base/share/classes/java/net/SocketPermission.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/net/SocketPermission.java Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,24 +25,24 @@
package java.net;
-import java.util.Enumeration;
-import java.util.Vector;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.StringJoiner;
-import java.util.StringTokenizer;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.io.Serializable;
import java.net.InetAddress;
+import java.security.AccessController;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
-import java.security.AccessController;
import java.security.Security;
-import java.io.Serializable;
-import java.io.ObjectStreamField;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.StringJoiner;
+import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentSkipListMap;
import sun.net.util.IPAddressUtil;
import sun.net.RegisteredDomain;
import sun.net.PortConfig;
@@ -832,6 +832,7 @@
* @return true if the specified permission is implied by this object,
* false if not.
*/
+ @Override
public boolean implies(Permission p) {
int i,j;
@@ -1010,6 +1011,7 @@
* SocketPermission object. However, port range will be ignored
* in the comparison if obj only contains the action, 'resolve'.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -1069,7 +1071,7 @@
*
* @return a hash code value for this object.
*/
-
+ @Override
public int hashCode() {
/*
* If this SocketPermission was initialized with an IP address
@@ -1137,6 +1139,7 @@
*
* @return the canonical string representation of the actions.
*/
+ @Override
public String getActions()
{
if (actions == null)
@@ -1156,7 +1159,7 @@
*
* @return a new PermissionCollection object suitable for storing SocketPermissions.
*/
-
+ @Override
public PermissionCollection newPermissionCollection() {
return new SocketPermissionCollection();
}
@@ -1320,15 +1323,16 @@
implements Serializable
{
// Not serialized; see serialization section at end of class
- private transient List perms;
+ // A ConcurrentSkipListMap is used to preserve order, so that most
+ // recently added permissions are checked first (see JDK-4301064).
+ private transient ConcurrentSkipListMap perms;
/**
* Create an empty SocketPermissions object.
*
*/
-
public SocketPermissionCollection() {
- perms = new ArrayList<>();
+ perms = new ConcurrentSkipListMap<>(new SPCComparator());
}
/**
@@ -1343,6 +1347,7 @@
* @exception SecurityException - if this SocketPermissionCollection object
* has been marked readonly
*/
+ @Override
public void add(Permission permission) {
if (! (permission instanceof SocketPermission))
throw new IllegalArgumentException("invalid permission: "+
@@ -1351,11 +1356,32 @@
throw new SecurityException(
"attempt to add a Permission to a readonly PermissionCollection");
- // optimization to ensure perms most likely to be tested
- // show up early (4301064)
- synchronized (this) {
- perms.add(0, (SocketPermission)permission);
- }
+ SocketPermission sp = (SocketPermission)permission;
+
+ // Add permission to map if it is absent, or replace with new
+ // permission if applicable. NOTE: cannot use lambda for
+ // remappingFunction parameter until JDK-8076596 is fixed.
+ perms.merge(sp.getName(), sp,
+ new java.util.function.BiFunction<>() {
+ @Override
+ public SocketPermission apply(SocketPermission existingVal,
+ SocketPermission newVal) {
+ int oldMask = existingVal.getMask();
+ int newMask = newVal.getMask();
+ if (oldMask != newMask) {
+ int effective = oldMask | newMask;
+ if (effective == newMask) {
+ return newVal;
+ }
+ if (effective != oldMask) {
+ return new SocketPermission(sp.getName(),
+ effective);
+ }
+ }
+ return existingVal;
+ }
+ }
+ );
}
/**
@@ -1367,7 +1393,7 @@
* @return true if "permission" is a proper subset of a permission in
* the collection, false if not.
*/
-
+ @Override
public boolean implies(Permission permission)
{
if (! (permission instanceof SocketPermission))
@@ -1379,18 +1405,15 @@
int effective = 0;
int needed = desired;
- synchronized (this) {
- int len = perms.size();
- //System.out.println("implies "+np);
- for (int i = 0; i < len; i++) {
- SocketPermission x = perms.get(i);
- //System.out.println(" trying "+x);
- if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(np)) {
- effective |= x.getMask();
- if ((effective & desired) == desired)
- return true;
- needed = (desired ^ effective);
+ //System.out.println("implies "+np);
+ for (SocketPermission x : perms.values()) {
+ //System.out.println(" trying "+x);
+ if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(np)) {
+ effective |= x.getMask();
+ if ((effective & desired) == desired) {
+ return true;
}
+ needed = (desired ^ effective);
}
}
return false;
@@ -1402,13 +1425,10 @@
*
* @return an enumeration of all the SocketPermission objects.
*/
-
+ @Override
@SuppressWarnings("unchecked")
public Enumeration elements() {
- // Convert Iterator into Enumeration
- synchronized (this) {
- return Collections.enumeration((List)(List)perms);
- }
+ return (Enumeration)Collections.enumeration(perms.values());
}
private static final long serialVersionUID = 2787186408602843674L;
@@ -1441,11 +1461,7 @@
// Don't call out.defaultWriteObject()
// Write out Vector
- Vector permissions = new Vector<>(perms.size());
-
- synchronized (this) {
- permissions.addAll(perms);
- }
+ Vector permissions = new Vector<>(perms.values());
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", permissions);
@@ -1466,7 +1482,22 @@
// Get the one we want
@SuppressWarnings("unchecked")
Vector permissions = (Vector)gfields.get("permissions", null);
- perms = new ArrayList<>(permissions.size());
- perms.addAll(permissions);
+ perms = new ConcurrentSkipListMap<>(new SPCComparator());
+ for (SocketPermission sp : permissions) {
+ perms.put(sp.getName(), sp);
+ }
+ }
+
+ /**
+ * A simple comparator that orders new non-equal entries at the beginning.
+ */
+ private static class SPCComparator implements Comparator {
+ @Override
+ public int compare(String s1, String s2) {
+ if (s1.equals(s2)) {
+ return 0;
+ }
+ return -1;
+ }
}
}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/security/BasicPermission.java
--- a/jdk/src/java.base/share/classes/java/security/BasicPermission.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/security/BasicPermission.java Wed Jul 05 20:37:58 2017 +0200
@@ -25,15 +25,13 @@
package java.security;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
import java.util.Enumeration;
-import java.util.Map;
-import java.util.HashMap;
import java.util.Hashtable;
-import java.util.Collections;
-import java.io.ObjectStreamField;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
/**
* The BasicPermission class extends the Permission class, and
@@ -165,6 +163,7 @@
* @return true if the passed permission is equal to or
* implied by this permission, false otherwise.
*/
+ @Override
public boolean implies(Permission p) {
if ((p == null) || (p.getClass() != getClass()))
return false;
@@ -200,6 +199,7 @@
* @return true if {@code obj}'s class is the same as this object's class
* and has the same name as this BasicPermission object, false otherwise.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -221,6 +221,7 @@
*
* @return a hash code value for this object.
*/
+ @Override
public int hashCode() {
return this.getName().hashCode();
}
@@ -232,6 +233,7 @@
*
* @return the empty string "".
*/
+ @Override
public String getActions() {
return "";
}
@@ -248,6 +250,7 @@
* @return a new PermissionCollection object suitable for
* storing BasicPermissions.
*/
+ @Override
public PermissionCollection newPermissionCollection() {
return new BasicPermissionCollection(this.getClass());
}
@@ -308,7 +311,7 @@
* collection must be of the same type.
* Not serialized; see serialization section at end of class.
*/
- private transient Map perms;
+ private transient ConcurrentHashMap perms;
/**
* This is set to {@code true} if this BasicPermissionCollection
@@ -320,7 +323,7 @@
/**
* The class to which all BasicPermissions in this
- * BasicPermissionCollection belongs.
+ * BasicPermissionCollection belong.
*
* @see #serialPersistentFields
*/
@@ -330,9 +333,8 @@
* Create an empty BasicPermissionCollection object.
*
*/
-
public BasicPermissionCollection(Class> clazz) {
- perms = new HashMap<>(11);
+ perms = new ConcurrentHashMap<>(11);
all_allowed = false;
permClass = clazz;
}
@@ -352,6 +354,7 @@
* @exception SecurityException - if this BasicPermissionCollection object
* has been marked readonly
*/
+ @Override
public void add(Permission permission) {
if (! (permission instanceof BasicPermission))
throw new IllegalArgumentException("invalid permission: "+
@@ -373,13 +376,12 @@
permission);
}
- synchronized (this) {
- perms.put(bp.getCanonicalName(), permission);
- }
+ String canonName = bp.getCanonicalName();
+ perms.put(canonName, permission);
// No sync on all_allowed; staleness OK
if (!all_allowed) {
- if (bp.getCanonicalName().equals("*"))
+ if (canonName.equals("*"))
all_allowed = true;
}
}
@@ -393,6 +395,7 @@
* @return true if "permission" is a proper subset of a permission in
* the set, false if not.
*/
+ @Override
public boolean implies(Permission permission) {
if (! (permission instanceof BasicPermission))
return false;
@@ -414,11 +417,7 @@
String path = bp.getCanonicalName();
//System.out.println("check "+path);
- Permission x;
-
- synchronized (this) {
- x = perms.get(path);
- }
+ Permission x = perms.get(path);
if (x != null) {
// we have a direct hit!
@@ -435,9 +434,7 @@
path = path.substring(0, last+1) + "*";
//System.out.println("check "+path);
- synchronized (this) {
- x = perms.get(path);
- }
+ x = perms.get(path);
if (x != null) {
return x.implies(permission);
@@ -456,11 +453,9 @@
*
* @return an enumeration of all the BasicPermission objects.
*/
+ @Override
public Enumeration elements() {
- // Convert Iterator of Map values into an Enumeration
- synchronized (this) {
- return Collections.enumeration(perms.values());
- }
+ return perms.elements();
}
// Need to maintain serialization interoperability with earlier releases,
@@ -503,9 +498,7 @@
Hashtable permissions =
new Hashtable<>(perms.size()*2);
- synchronized (this) {
- permissions.putAll(perms);
- }
+ permissions.putAll(perms);
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
@@ -533,7 +526,7 @@
@SuppressWarnings("unchecked")
Hashtable permissions =
(Hashtable)gfields.get("permissions", null);
- perms = new HashMap<>(permissions.size()*2);
+ perms = new ConcurrentHashMap<>(permissions.size()*2);
perms.putAll(permissions);
// Get all_allowed
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/security/Permissions.java
--- a/jdk/src/java.base/share/classes/java/security/Permissions.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/security/Permissions.java Wed Jul 05 20:37:58 2017 +0200
@@ -33,6 +33,7 @@
import java.util.List;
import java.util.Iterator;
import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
import java.io.Serializable;
import java.io.ObjectStreamField;
import java.io.ObjectOutputStream;
@@ -85,7 +86,7 @@
* Key is permissions Class, value is PermissionCollection for that class.
* Not serialized; see serialization section at end of class.
*/
- private transient Map, PermissionCollection> permsMap;
+ private transient ConcurrentHashMap, PermissionCollection> permsMap;
// optimization. keep track of whether unresolved permissions need to be
// checked
@@ -99,7 +100,7 @@
* Creates a new Permissions object containing no PermissionCollections.
*/
public Permissions() {
- permsMap = new HashMap<>(11);
+ permsMap = new ConcurrentHashMap<>(11);
allPermission = null;
}
@@ -120,18 +121,14 @@
*
* @see PermissionCollection#isReadOnly()
*/
-
+ @Override
public void add(Permission permission) {
if (isReadOnly())
throw new SecurityException(
"attempt to add a Permission to a readonly Permissions object");
- PermissionCollection pc;
-
- synchronized (this) {
- pc = getPermissionCollection(permission, true);
- pc.add(permission);
- }
+ PermissionCollection pc = getPermissionCollection(permission, true);
+ pc.add(permission);
// No sync; staleness -> optimizations delayed, which is OK
if (permission instanceof AllPermission) {
@@ -169,21 +166,19 @@
* PermissionCollection it
* belongs to, false if not.
*/
-
+ @Override
public boolean implies(Permission permission) {
// No sync; staleness -> skip optimization, which is OK
if (allPermission != null) {
return true; // AllPermission has already been added
} else {
- synchronized (this) {
- PermissionCollection pc = getPermissionCollection(permission,
- false);
- if (pc != null) {
- return pc.implies(permission);
- } else {
- // none found
- return false;
- }
+ PermissionCollection pc = getPermissionCollection(permission,
+ false);
+ if (pc != null) {
+ return pc.implies(permission);
+ } else {
+ // none found
+ return false;
}
}
}
@@ -194,14 +189,12 @@
*
* @return an enumeration of all the Permissions.
*/
-
+ @Override
public Enumeration elements() {
// go through each Permissions in the hash table
// and call their elements() function.
- synchronized (this) {
- return new PermissionsEnumerator(permsMap.values().iterator());
- }
+ return new PermissionsEnumerator(permsMap.values().iterator());
}
/**
@@ -236,34 +229,39 @@
* It should be set to true when invoked from add().
*/
private PermissionCollection getPermissionCollection(Permission p,
- boolean createEmpty) {
+ boolean createEmpty) {
Class> c = p.getClass();
- PermissionCollection pc = permsMap.get(c);
-
if (!hasUnresolved && !createEmpty) {
- return pc;
- } else if (pc == null) {
+ return permsMap.get(c);
+ }
- // Check for unresolved permissions
- pc = (hasUnresolved ? getUnresolvedPermissions(p) : null);
-
- // if still null, create a new collection
- if (pc == null && createEmpty) {
-
- pc = p.newPermissionCollection();
+ // Create and add permission collection to map if it is absent.
+ // NOTE: cannot use lambda for mappingFunction parameter until
+ // JDK-8076596 is fixed.
+ return permsMap.computeIfAbsent(c,
+ new java.util.function.Function<>() {
+ @Override
+ public PermissionCollection apply(Class> k) {
+ // Check for unresolved permissions
+ PermissionCollection pc =
+ (hasUnresolved ? getUnresolvedPermissions(p) : null);
- // still no PermissionCollection?
- // We'll give them a PermissionsHash.
- if (pc == null)
- pc = new PermissionsHash();
- }
+ // if still null, create a new collection
+ if (pc == null && createEmpty) {
+
+ pc = p.newPermissionCollection();
- if (pc != null) {
- permsMap.put(c, pc);
+ // still no PermissionCollection?
+ // We'll give them a PermissionsHash.
+ if (pc == null) {
+ pc = new PermissionsHash();
+ }
+ }
+ return pc;
+ }
}
- }
- return pc;
+ );
}
/**
@@ -277,8 +275,6 @@
*/
private PermissionCollection getUnresolvedPermissions(Permission p)
{
- // Called from within synchronized method so permsMap doesn't need lock
-
UnresolvedPermissionCollection uc =
(UnresolvedPermissionCollection) permsMap.get(UnresolvedPermission.class);
@@ -362,9 +358,7 @@
// Copy perms into a Hashtable
Hashtable, PermissionCollection> perms =
new Hashtable<>(permsMap.size()*2); // no sync; estimate
- synchronized (this) {
- perms.putAll(permsMap);
- }
+ perms.putAll(permsMap);
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
@@ -394,7 +388,7 @@
@SuppressWarnings("unchecked")
Hashtable, PermissionCollection> perms =
(Hashtable, PermissionCollection>)gfields.get("perms", null);
- permsMap = new HashMap<>(perms.size()*2);
+ permsMap = new ConcurrentHashMap<>(perms.size()*2);
permsMap.putAll(perms);
// Set hasUnresolved
@@ -481,14 +475,13 @@
* Key and value are (same) permissions objects.
* Not serialized; see serialization section at end of class.
*/
- private transient Map permsMap;
+ private transient ConcurrentHashMap permsMap;
/**
* Create an empty PermissionsHash object.
*/
-
PermissionsHash() {
- permsMap = new HashMap<>(11);
+ permsMap = new ConcurrentHashMap<>(11);
}
/**
@@ -496,11 +489,9 @@
*
* @param permission the Permission object to add.
*/
-
+ @Override
public void add(Permission permission) {
- synchronized (this) {
- permsMap.put(permission, permission);
- }
+ permsMap.put(permission, permission);
}
/**
@@ -512,23 +503,21 @@
* @return true if "permission" is a proper subset of a permission in
* the set, false if not.
*/
-
+ @Override
public boolean implies(Permission permission) {
// attempt a fast lookup and implies. If that fails
// then enumerate through all the permissions.
- synchronized (this) {
- Permission p = permsMap.get(permission);
+ Permission p = permsMap.get(permission);
- // If permission is found, then p.equals(permission)
- if (p == null) {
- for (Permission p_ : permsMap.values()) {
- if (p_.implies(permission))
- return true;
- }
- return false;
- } else {
- return true;
+ // If permission is found, then p.equals(permission)
+ if (p == null) {
+ for (Permission p_ : permsMap.values()) {
+ if (p_.implies(permission))
+ return true;
}
+ return false;
+ } else {
+ return true;
}
}
@@ -537,12 +526,9 @@
*
* @return an enumeration of all the Permissions.
*/
-
+ @Override
public Enumeration elements() {
- // Convert Iterator of Map values into an Enumeration
- synchronized (this) {
- return Collections.enumeration(permsMap.values());
- }
+ return permsMap.elements();
}
private static final long serialVersionUID = -8491988220802933440L;
@@ -570,9 +556,7 @@
// Copy perms into a Hashtable
Hashtable perms =
new Hashtable<>(permsMap.size()*2);
- synchronized (this) {
- perms.putAll(permsMap);
- }
+ perms.putAll(permsMap);
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
@@ -597,7 +581,7 @@
@SuppressWarnings("unchecked")
Hashtable perms =
(Hashtable)gfields.get("perms", null);
- permsMap = new HashMap<>(perms.size()*2);
+ permsMap = new ConcurrentHashMap<>(perms.size()*2);
permsMap.putAll(perms);
}
}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/security/UnresolvedPermissionCollection.java
--- a/jdk/src/java.base/share/classes/java/security/UnresolvedPermissionCollection.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/security/UnresolvedPermissionCollection.java Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,13 @@
package java.security;
-import java.util.*;
-import java.io.ObjectStreamField;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
+import java.io.ObjectStreamField;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* A UnresolvedPermissionCollection stores a collection
@@ -54,14 +56,14 @@
* of the same type.
* Not serialized; see serialization section at end of class.
*/
- private transient Map> perms;
+ private transient ConcurrentHashMap> perms;
/**
* Create an empty UnresolvedPermissionCollection object.
*
*/
public UnresolvedPermissionCollection() {
- perms = new HashMap<>(11);
+ perms = new ConcurrentHashMap<>(11);
}
/**
@@ -70,25 +72,32 @@
*
* @param permission the Permission object to add.
*/
-
- public void add(Permission permission)
- {
+ @Override
+ public void add(Permission permission) {
if (! (permission instanceof UnresolvedPermission))
throw new IllegalArgumentException("invalid permission: "+
permission);
UnresolvedPermission up = (UnresolvedPermission) permission;
- List v;
- synchronized (this) {
- v = perms.get(up.getName());
- if (v == null) {
- v = new ArrayList<>();
- perms.put(up.getName(), v);
+ // Add permission to map. NOTE: cannot use lambda for
+ // remappingFunction parameter until JDK-8076596 is fixed.
+ perms.compute(up.getName(),
+ new java.util.function.BiFunction<>() {
+ @Override
+ public List apply(String key,
+ List oldValue) {
+ if (oldValue == null) {
+ List v =
+ new CopyOnWriteArrayList<>();
+ v.add(up);
+ return v;
+ } else {
+ oldValue.add(up);
+ return oldValue;
+ }
+ }
}
- }
- synchronized (v) {
- v.add(up);
- }
+ );
}
/**
@@ -96,17 +105,15 @@
* and return the List containing them.
*/
List getUnresolvedPermissions(Permission p) {
- synchronized (this) {
- return perms.get(p.getClass().getName());
- }
+ return perms.get(p.getClass().getName());
}
/**
* always returns false for unresolved permissions
*
*/
- public boolean implies(Permission permission)
- {
+ @Override
+ public boolean implies(Permission permission) {
return false;
}
@@ -116,18 +123,14 @@
*
* @return an enumeration of all the UnresolvedPermission objects.
*/
-
+ @Override
public Enumeration elements() {
List results =
new ArrayList<>(); // where results are stored
// Get iterator of Map values (which are lists of permissions)
- synchronized (this) {
- for (List l : perms.values()) {
- synchronized (l) {
- results.addAll(l);
- }
- }
+ for (List l : perms.values()) {
+ results.addAll(l);
}
return Collections.enumeration(results);
@@ -164,19 +167,14 @@
new Hashtable<>(perms.size()*2);
// Convert each entry (List) into a Vector
- synchronized (this) {
- Set>> set = perms.entrySet();
- for (Map.Entry> e : set) {
- // Convert list into Vector
- List list = e.getValue();
- Vector vec = new Vector<>(list.size());
- synchronized (list) {
- vec.addAll(list);
- }
+ Set>> set = perms.entrySet();
+ for (Map.Entry> e : set) {
+ // Convert list into Vector
+ List list = e.getValue();
+ Vector vec = new Vector<>(list);
- // Add to Hashtable being serialized
- permissions.put(e.getKey(), vec);
- }
+ // Add to Hashtable being serialized
+ permissions.put(e.getKey(), vec);
}
// Write out serializable fields
@@ -203,15 +201,14 @@
Hashtable> permissions =
(Hashtable>)
gfields.get("permissions", null);
- perms = new HashMap<>(permissions.size()*2);
+ perms = new ConcurrentHashMap<>(permissions.size()*2);
// Convert each entry (Vector) into a List
Set>> set = permissions.entrySet();
for (Map.Entry> e : set) {
// Convert Vector into ArrayList
Vector vec = e.getValue();
- List list = new ArrayList<>(vec.size());
- list.addAll(vec);
+ List list = new CopyOnWriteArrayList<>(vec);
// Add to Hashtable being serialized
perms.put(e.getKey(), list);
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/text/SimpleDateFormat.java
--- a/jdk/src/java.base/share/classes/java/text/SimpleDateFormat.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/text/SimpleDateFormat.java Wed Jul 05 20:37:58 2017 +0200
@@ -2374,7 +2374,7 @@
/**
* After reading an object from the input stream, the format
* pattern in the object is verified.
- *
+ *
* @exception InvalidObjectException if the pattern is invalid
*/
private void readObject(ObjectInputStream stream)
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/util/DualPivotQuicksort.java
--- a/jdk/src/java.base/share/classes/java/util/DualPivotQuicksort.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/util/DualPivotQuicksort.java Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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,11 +61,6 @@
private static final int MAX_RUN_COUNT = 67;
/**
- * The maximum length of run in merge sort.
- */
- private static final int MAX_RUN_LENGTH = 33;
-
- /**
* If the length of an array to be sorted is less than this
* constant, Quicksort is used in preference to merge sort.
*/
@@ -121,20 +116,24 @@
// Check if the array is nearly sorted
for (int k = left; k < right; run[count] = k) {
+ // Equal items in the beginning of the sequence
+ while (k < right && a[k] == a[k + 1])
+ k++;
+ if (k == right) break; // Sequence finishes with equal items
if (a[k] < a[k + 1]) { // ascending
while (++k <= right && a[k - 1] <= a[k]);
} else if (a[k] > a[k + 1]) { // descending
while (++k <= right && a[k - 1] >= a[k]);
+ // Transform into an ascending sequence
for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
int t = a[lo]; a[lo] = a[hi]; a[hi] = t;
}
- } else { // equal
- for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
- if (--m == 0) {
- sort(a, left, right, true);
- return;
- }
- }
+ }
+
+ // Merge a transformed descending sequence followed by an
+ // ascending sequence
+ if (run[count] > left && a[run[count]] >= a[run[count] - 1]) {
+ count--;
}
/*
@@ -151,7 +150,7 @@
// Implementation note: variable "right" is increased by 1.
if (run[count] == right++) { // The last run contains one element
run[++count] = right;
- } else if (count == 1) { // The array is already sorted
+ } else if (count <= 1) { // The array is already sorted
return;
}
@@ -569,20 +568,24 @@
// Check if the array is nearly sorted
for (int k = left; k < right; run[count] = k) {
+ // Equal items in the beginning of the sequence
+ while (k < right && a[k] == a[k + 1])
+ k++;
+ if (k == right) break; // Sequence finishes with equal items
if (a[k] < a[k + 1]) { // ascending
while (++k <= right && a[k - 1] <= a[k]);
} else if (a[k] > a[k + 1]) { // descending
while (++k <= right && a[k - 1] >= a[k]);
+ // Transform into an ascending sequence
for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
long t = a[lo]; a[lo] = a[hi]; a[hi] = t;
}
- } else { // equal
- for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
- if (--m == 0) {
- sort(a, left, right, true);
- return;
- }
- }
+ }
+
+ // Merge a transformed descending sequence followed by an
+ // ascending sequence
+ if (run[count] > left && a[run[count]] >= a[run[count] - 1]) {
+ count--;
}
/*
@@ -599,7 +602,7 @@
// Implementation note: variable "right" is increased by 1.
if (run[count] == right++) { // The last run contains one element
run[++count] = right;
- } else if (count == 1) { // The array is already sorted
+ } else if (count <= 1) { // The array is already sorted
return;
}
@@ -1053,20 +1056,24 @@
// Check if the array is nearly sorted
for (int k = left; k < right; run[count] = k) {
+ // Equal items in the beginning of the sequence
+ while (k < right && a[k] == a[k + 1])
+ k++;
+ if (k == right) break; // Sequence finishes with equal items
if (a[k] < a[k + 1]) { // ascending
while (++k <= right && a[k - 1] <= a[k]);
} else if (a[k] > a[k + 1]) { // descending
while (++k <= right && a[k - 1] >= a[k]);
+ // Transform into an ascending sequence
for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
short t = a[lo]; a[lo] = a[hi]; a[hi] = t;
}
- } else { // equal
- for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
- if (--m == 0) {
- sort(a, left, right, true);
- return;
- }
- }
+ }
+
+ // Merge a transformed descending sequence followed by an
+ // ascending sequence
+ if (run[count] > left && a[run[count]] >= a[run[count] - 1]) {
+ count--;
}
/*
@@ -1083,7 +1090,7 @@
// Implementation note: variable "right" is increased by 1.
if (run[count] == right++) { // The last run contains one element
run[++count] = right;
- } else if (count == 1) { // The array is already sorted
+ } else if (count <= 1) { // The array is already sorted
return;
}
@@ -1537,20 +1544,24 @@
// Check if the array is nearly sorted
for (int k = left; k < right; run[count] = k) {
+ // Equal items in the beginning of the sequence
+ while (k < right && a[k] == a[k + 1])
+ k++;
+ if (k == right) break; // Sequence finishes with equal items
if (a[k] < a[k + 1]) { // ascending
while (++k <= right && a[k - 1] <= a[k]);
} else if (a[k] > a[k + 1]) { // descending
while (++k <= right && a[k - 1] >= a[k]);
+ // Transform into an ascending sequence
for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
char t = a[lo]; a[lo] = a[hi]; a[hi] = t;
}
- } else { // equal
- for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
- if (--m == 0) {
- sort(a, left, right, true);
- return;
- }
- }
+ }
+
+ // Merge a transformed descending sequence followed by an
+ // ascending sequence
+ if (run[count] > left && a[run[count]] >= a[run[count] - 1]) {
+ count--;
}
/*
@@ -1567,7 +1578,7 @@
// Implementation note: variable "right" is increased by 1.
if (run[count] == right++) { // The last run contains one element
run[++count] = right;
- } else if (count == 1) { // The array is already sorted
+ } else if (count <= 1) { // The array is already sorted
return;
}
@@ -2117,20 +2128,24 @@
// Check if the array is nearly sorted
for (int k = left; k < right; run[count] = k) {
+ // Equal items in the beginning of the sequence
+ while (k < right && a[k] == a[k + 1])
+ k++;
+ if (k == right) break; // Sequence finishes with equal items
if (a[k] < a[k + 1]) { // ascending
while (++k <= right && a[k - 1] <= a[k]);
} else if (a[k] > a[k + 1]) { // descending
while (++k <= right && a[k - 1] >= a[k]);
+ // Transform into an ascending sequence
for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
float t = a[lo]; a[lo] = a[hi]; a[hi] = t;
}
- } else { // equal
- for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
- if (--m == 0) {
- sort(a, left, right, true);
- return;
- }
- }
+ }
+
+ // Merge a transformed descending sequence followed by an
+ // ascending sequence
+ if (run[count] > left && a[run[count]] >= a[run[count] - 1]) {
+ count--;
}
/*
@@ -2147,7 +2162,7 @@
// Implementation note: variable "right" is increased by 1.
if (run[count] == right++) { // The last run contains one element
run[++count] = right;
- } else if (count == 1) { // The array is already sorted
+ } else if (count <= 1) { // The array is already sorted
return;
}
@@ -2656,20 +2671,24 @@
// Check if the array is nearly sorted
for (int k = left; k < right; run[count] = k) {
+ // Equal items in the beginning of the sequence
+ while (k < right && a[k] == a[k + 1])
+ k++;
+ if (k == right) break; // Sequence finishes with equal items
if (a[k] < a[k + 1]) { // ascending
while (++k <= right && a[k - 1] <= a[k]);
} else if (a[k] > a[k + 1]) { // descending
while (++k <= right && a[k - 1] >= a[k]);
+ // Transform into an ascending sequence
for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
double t = a[lo]; a[lo] = a[hi]; a[hi] = t;
}
- } else { // equal
- for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
- if (--m == 0) {
- sort(a, left, right, true);
- return;
- }
- }
+ }
+
+ // Merge a transformed descending sequence followed by an
+ // ascending sequence
+ if (run[count] > left && a[run[count]] >= a[run[count] - 1]) {
+ count--;
}
/*
@@ -2686,7 +2705,7 @@
// Implementation note: variable "right" is increased by 1.
if (run[count] == right++) { // The last run contains one element
run[++count] = right;
- } else if (count == 1) { // The array is already sorted
+ } else if (count <= 1) { // The array is already sorted
return;
}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/java/util/PropertyPermission.java
--- a/jdk/src/java.base/share/classes/java/util/PropertyPermission.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/util/PropertyPermission.java Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,18 +25,15 @@
package java.util;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
import java.io.Serializable;
-import java.io.IOException;
import java.security.*;
-import java.util.Map;
-import java.util.HashMap;
import java.util.Enumeration;
import java.util.Hashtable;
-import java.util.Collections;
-import java.io.ObjectStreamField;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
import sun.security.util.SecurityConstants;
/**
@@ -162,6 +159,16 @@
}
/**
+ * Creates a PropertyPermission object with the specified name and
+ * a pre-calculated mask. Avoids the overhead of re-computing the mask.
+ * Called by PropertyPermissionCollection.
+ */
+ PropertyPermission(String name, int mask) {
+ super(name, getActions(mask));
+ this.mask = mask;
+ }
+
+ /**
* Checks if this PropertyPermission object "implies" the specified
* permission.
*
@@ -178,6 +185,7 @@
* @return true if the specified permission is implied by this object,
* false if not.
*/
+ @Override
public boolean implies(Permission p) {
if (!(p instanceof PropertyPermission))
return false;
@@ -198,6 +206,7 @@
* @return true if obj is a PropertyPermission, and has the same name and
* actions as this PropertyPermission object.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -219,6 +228,7 @@
*
* @return a hash code value for this object.
*/
+ @Override
public int hashCode() {
return this.getName().hashCode();
}
@@ -345,6 +355,7 @@
*
* @return the canonical string representation of the actions.
*/
+ @Override
public String getActions() {
if (actions == null)
actions = getActions(this.mask);
@@ -369,6 +380,7 @@
* @return a new PermissionCollection object suitable for storing
* PropertyPermissions.
*/
+ @Override
public PermissionCollection newPermissionCollection() {
return new PropertyPermissionCollection();
}
@@ -425,7 +437,7 @@
* Key is property name; value is PropertyPermission.
* Not serialized; see serialization section at end of class.
*/
- private transient Map perms;
+ private transient ConcurrentHashMap perms;
/**
* Boolean saying if "*" is in the collection.
@@ -439,7 +451,7 @@
* Create an empty PropertyPermissionCollection object.
*/
public PropertyPermissionCollection() {
- perms = new HashMap<>(32); // Capacity for default policy
+ perms = new ConcurrentHashMap<>(32); // Capacity for default policy
all_allowed = false;
}
@@ -455,6 +467,7 @@
* @exception SecurityException - if this PropertyPermissionCollection
* object has been marked readonly
*/
+ @Override
public void add(Permission permission) {
if (! (permission instanceof PropertyPermission))
throw new IllegalArgumentException("invalid permission: "+
@@ -466,21 +479,30 @@
PropertyPermission pp = (PropertyPermission) permission;
String propName = pp.getName();
- synchronized (this) {
- PropertyPermission existing = perms.get(propName);
+ // Add permission to map if it is absent, or replace with new
+ // permission if applicable. NOTE: cannot use lambda for
+ // remappingFunction parameter until JDK-8076596 is fixed.
+ perms.merge(propName, pp,
+ new java.util.function.BiFunction<>() {
+ @Override
+ public PropertyPermission apply(PropertyPermission existingVal,
+ PropertyPermission newVal) {
- if (existing != null) {
- int oldMask = existing.getMask();
- int newMask = pp.getMask();
- if (oldMask != newMask) {
- int effective = oldMask | newMask;
- String actions = PropertyPermission.getActions(effective);
- perms.put(propName, new PropertyPermission(propName, actions));
+ int oldMask = existingVal.getMask();
+ int newMask = newVal.getMask();
+ if (oldMask != newMask) {
+ int effective = oldMask | newMask;
+ if (effective == newMask) {
+ return newVal;
+ }
+ if (effective != oldMask) {
+ return new PropertyPermission(propName, effective);
+ }
+ }
+ return existingVal;
}
- } else {
- perms.put(propName, pp);
}
- }
+ );
if (!all_allowed) {
if (propName.equals("*"))
@@ -497,9 +519,10 @@
* @return true if "permission" is a proper subset of a permission in
* the set, false if not.
*/
+ @Override
public boolean implies(Permission permission) {
if (! (permission instanceof PropertyPermission))
- return false;
+ return false;
PropertyPermission pp = (PropertyPermission) permission;
PropertyPermission x;
@@ -509,9 +532,7 @@
// short circuit if the "*" Permission was added
if (all_allowed) {
- synchronized (this) {
- x = perms.get("*");
- }
+ x = perms.get("*");
if (x != null) {
effective |= x.getMask();
if ((effective & desired) == desired)
@@ -526,9 +547,7 @@
String name = pp.getName();
//System.out.println("check "+name);
- synchronized (this) {
- x = perms.get(name);
- }
+ x = perms.get(name);
if (x != null) {
// we have a direct hit!
@@ -546,9 +565,7 @@
name = name.substring(0, last+1) + "*";
//System.out.println("check "+name);
- synchronized (this) {
- x = perms.get(name);
- }
+ x = perms.get(name);
if (x != null) {
effective |= x.getMask();
@@ -569,16 +586,14 @@
*
* @return an enumeration of all the PropertyPermission objects.
*/
+ @Override
@SuppressWarnings("unchecked")
public Enumeration elements() {
- // Convert Iterator of Map values into an Enumeration
- synchronized (this) {
- /**
- * Casting to rawtype since Enumeration
- * cannot be directly cast to Enumeration
- */
- return (Enumeration)Collections.enumeration(perms.values());
- }
+ /**
+ * Casting to rawtype since Enumeration
+ * cannot be directly cast to Enumeration
+ */
+ return (Enumeration)perms.elements();
}
private static final long serialVersionUID = 7015263904581634791L;
@@ -616,9 +631,7 @@
// Copy perms into a Hashtable
Hashtable permissions =
new Hashtable<>(perms.size()*2);
- synchronized (this) {
- permissions.putAll(perms);
- }
+ permissions.putAll(perms);
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
@@ -646,7 +659,7 @@
@SuppressWarnings("unchecked")
Hashtable permissions =
(Hashtable)gfields.get("permissions", null);
- perms = new HashMap<>(permissions.size()*2);
+ perms = new ConcurrentHashMap<>(permissions.size()*2);
perms.putAll(permissions);
}
}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/javax/security/auth/Subject.java
--- a/jdk/src/java.base/share/classes/javax/security/auth/Subject.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/javax/security/auth/Subject.java Wed Jul 05 20:37:58 2017 +0200
@@ -1401,8 +1401,6 @@
/**
* Writes this object out to a stream (i.e., serializes it).
*
- *
- *
* @serialData If this is a private credential set,
* a security check is performed to ensure that
* the caller has permission to access each credential
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java
--- a/jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java Wed Jul 05 20:37:58 2017 +0200
@@ -74,36 +74,34 @@
* visitor chain to trace the class that is visited at a given point in this
* chain. This may be useful for debugging purposes.
*
- * The trace printed when visiting the Hello class is the following:
- *
+ * The trace printed when visiting the {@code Hello} class is the following:
*
{@code
* public class Hello {
*
* public static void main(String[] args) {
- * System.out.println("hello");
+ * System.out.println("hello");
* }
* }
- *
+ * }
*
*
*
@@ -137,7 +135,7 @@
*
* @param cv
* the {@link ClassVisitor} to which this visitor delegates
- * calls. May be null.
+ * calls. May be {@code null}.
* @param pw
* the print writer to be used to print the class.
*/
@@ -150,7 +148,7 @@
*
* @param cv
* the {@link ClassVisitor} to which this visitor delegates
- * calls. May be null.
+ * calls. May be {@code null}.
* @param p
* the object that actually converts visit events into text.
* @param pw
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/invoke/util/BytecodeName.java
--- a/jdk/src/java.base/share/classes/sun/invoke/util/BytecodeName.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/BytecodeName.java Wed Jul 05 20:37:58 2017 +0200
@@ -464,7 +464,7 @@
* Report whether a character is safe in a bytecode name.
* This is true of any unicode character except the following
* dangerous characters: {@code ".;:$[]<>/"}.
- * @param s the proposed character
+ * @param c the proposed character
* @return true if the character is safe to use in classfiles
*/
public static boolean isSafeBytecodeChar(char c) {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/misc/ExtensionDependency.java
--- a/jdk/src/java.base/share/classes/sun/misc/ExtensionDependency.java Thu Jun 11 20:20:05 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,554 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.FileNotFoundException;
-import java.util.StringTokenizer;
-import java.util.Vector;
-import java.util.Enumeration;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-import java.util.jar.Attributes;
-import java.util.jar.Attributes.Name;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
-import java.net.URL;
-import java.net.MalformedURLException;
-import sun.net.www.ParseUtil;
-
-/**
- * This class checks dependent extensions a particular jar file may have
- * declared through its manifest attributes.
- *
- * Jar file declared dependent extensions through the extension-list
- * attribute. The extension-list contains a list of keys used to
- * fetch the other attributes describing the required extension.
- * If key is the extension key declared in the extension-list
- * attribute, the following describing attribute can be found in
- * the manifest:
- *
key-Implementation-URL: (URL to download the requested extension)
- *
- *
- * This class also maintain versioning consistency of installed
- * extensions dependencies declared in jar file manifest.
- *
- * @deprecated this class will be removed in a future release.
- * @author Jerome Dochez
- */
-@Deprecated
-public class ExtensionDependency {
-
- /* Callbak interfaces to delegate installation of missing extensions */
- private static Vector providers;
-
- /**
- * Register an ExtensionInstallationProvider. The provider is responsible
- * for handling the installation (upgrade) of any missing extensions.
- *
- * @param eip ExtensionInstallationProvider implementation
- */
- public synchronized static void addExtensionInstallationProvider
- (ExtensionInstallationProvider eip)
- {
- if (providers == null) {
- providers = new Vector<>();
- }
- providers.add(eip);
- }
-
- /**
- * Unregister a previously installed installation provider
- */
- public synchronized static void removeExtensionInstallationProvider
- (ExtensionInstallationProvider eip)
- {
- providers.remove(eip);
- }
-
- /**
- * Checks the dependencies of the jar file on installed extension.
- *
- * @param jar containing the attributes declaring the dependencies
- */
- public static boolean checkExtensionsDependencies(JarFile jar)
- {
- if (providers == null) {
- // no need to bother, nobody is registered to install missing
- // extensions
- return true;
- }
-
- try {
- ExtensionDependency extDep = new ExtensionDependency();
- return extDep.checkExtensions(jar);
- } catch (ExtensionInstallationException e) {
- debug(e.getMessage());
- }
- return false;
- }
-
- /*
- * Check for all declared required extensions in the jar file
- * manifest.
- */
- protected boolean checkExtensions(JarFile jar)
- throws ExtensionInstallationException
- {
- Manifest man;
- try {
- man = jar.getManifest();
- } catch (IOException e) {
- return false;
- }
-
- if (man == null) {
- // The applet does not define a manifest file, so
- // we just assume all dependencies are satisfied.
- return true;
- }
-
- boolean result = true;
- Attributes attr = man.getMainAttributes();
- if (attr != null) {
- // Let's get the list of declared dependencies
- String value = attr.getValue(Name.EXTENSION_LIST);
- if (value != null) {
- StringTokenizer st = new StringTokenizer(value);
- // Iterate over all declared dependencies
- while (st.hasMoreTokens()) {
- String extensionName = st.nextToken();
- debug("The file " + jar.getName() +
- " appears to depend on " + extensionName);
- // Sanity Check
- String extName = extensionName + "-" +
- Name.EXTENSION_NAME.toString();
- if (attr.getValue(extName) == null) {
- debug("The jar file " + jar.getName() +
- " appers to depend on "
- + extensionName + " but does not define the " +
- extName + " attribute in its manifest ");
-
- } else {
- if (!checkExtension(extensionName, attr)) {
- debug("Failed installing " + extensionName);
- result = false;
- }
- }
- }
- } else {
- debug("No dependencies for " + jar.getName());
- }
- }
- return result;
- }
-
-
- /*
- * Check that a particular dependency on an extension is satisfied.
- *
- * @param extensionName is the key used for the attributes in the manifest
- * @param attr is the attributes of the manifest file
- *
- * @return true if the dependency is satisfied by the installed extensions
- */
- protected synchronized boolean checkExtension(final String extensionName,
- final Attributes attr)
- throws ExtensionInstallationException
- {
- debug("Checking extension " + extensionName);
- if (checkExtensionAgainstInstalled(extensionName, attr))
- return true;
-
- debug("Extension not currently installed ");
- ExtensionInfo reqInfo = new ExtensionInfo(extensionName, attr);
- return installExtension(reqInfo, null);
- }
-
- /*
- * Check if a particular extension is part of the currently installed
- * extensions.
- *
- * @param extensionName is the key for the attributes in the manifest
- * @param attr is the attributes of the manifest
- *
- * @return true if the requested extension is already installed
- */
- boolean checkExtensionAgainstInstalled(String extensionName,
- Attributes attr)
- throws ExtensionInstallationException
- {
- File fExtension = checkExtensionExists(extensionName);
-
- if (fExtension != null) {
- // Extension already installed, just check against this one
- try {
- if (checkExtensionAgainst(extensionName, attr, fExtension))
- return true;
- } catch (FileNotFoundException e) {
- debugException(e);
- } catch (IOException e) {
- debugException(e);
- }
- return false;
-
- } else {
- // Not sure if extension is already installed, so check all the
- // installed extension jar files to see if we get a match
-
- File[] installedExts;
-
- try {
- // Get the list of installed extension jar files so we can
- // compare the installed versus the requested extension
- installedExts = getInstalledExtensions();
- } catch(IOException e) {
- debugException(e);
- return false;
- }
-
- for (int i=0;i() {
- public Manifest run()
- throws IOException, FileNotFoundException {
- if (!file.exists())
- throw new FileNotFoundException(file.getName());
- JarFile jarFile = new JarFile(file);
- return jarFile.getManifest();
- }
- });
- } catch(PrivilegedActionException e) {
- if (e.getException() instanceof FileNotFoundException)
- throw (FileNotFoundException) e.getException();
- throw (IOException) e.getException();
- }
-
- // Construct the extension information object
- ExtensionInfo reqInfo = new ExtensionInfo(extensionName, attr);
- debug("Requested Extension : " + reqInfo);
-
- int isCompatible = ExtensionInfo.INCOMPATIBLE;
- ExtensionInfo instInfo = null;
-
- if (man != null) {
- Attributes instAttr = man.getMainAttributes();
- if (instAttr != null) {
- instInfo = new ExtensionInfo(null, instAttr);
- debug("Extension Installed " + instInfo);
- isCompatible = instInfo.isCompatibleWith(reqInfo);
- switch(isCompatible) {
- case ExtensionInfo.COMPATIBLE:
- debug("Extensions are compatible");
- return true;
-
- case ExtensionInfo.INCOMPATIBLE:
- debug("Extensions are incompatible");
- return false;
-
- default:
- // everything else
- debug("Extensions require an upgrade or vendor switch");
- return installExtension(reqInfo, instInfo);
-
- }
- }
- }
- return false;
- }
-
- /*
- * An required extension is missing, if an ExtensionInstallationProvider is
- * registered, delegate the installation of that particular extension to it.
- *
- * @param reqInfo Missing extension information
- * @param instInfo Older installed version information
- *
- * @return true if the installation is successful
- */
- protected boolean installExtension(ExtensionInfo reqInfo,
- ExtensionInfo instInfo)
- throws ExtensionInstallationException
- {
- Vector currentProviders;
- synchronized(providers) {
- @SuppressWarnings("unchecked")
- Vector tmp =
- (Vector) providers.clone();
- currentProviders = tmp;
- }
- for (Enumeration e = currentProviders.elements();
- e.hasMoreElements();) {
- ExtensionInstallationProvider eip = e.nextElement();
-
- if (eip!=null) {
- // delegate the installation to the provider
- if (eip.installExtension(reqInfo, instInfo)) {
- debug(reqInfo.name + " installation successful");
- Launcher.ExtClassLoader cl = (Launcher.ExtClassLoader)
- Launcher.getLauncher().getClassLoader().getParent();
- addNewExtensionsToClassLoader(cl);
- return true;
- }
- }
- }
- // We have tried all of our providers, noone could install this
- // extension, we just return failure at this point
- debug(reqInfo.name + " installation failed");
- return false;
- }
-
- /**
- * Checks if the extension, that is specified in the extension-list in
- * the applet jar manifest, is already installed (i.e. exists in the
- * extension directory).
- *
- * @param extensionName extension name in the extension-list
- *
- * @return the extension if it exists in the extension directory
- */
- private File checkExtensionExists(String extensionName) {
- // Function added to fix bug 4504166
- final String extName = extensionName;
- final String[] fileExt = {".jar", ".zip"};
-
- return AccessController.doPrivileged(
- new PrivilegedAction() {
- public File run() {
- try {
- File fExtension;
- File[] dirs = getExtDirs();
-
- // Search the extension directories for the extension that is specified
- // in the attribute extension-list in the applet jar manifest
- for (int i=0;i urls = new Vector();
- for (int i = 0; i < dirs.length; i++) {
- String[] files = dirs[i].list(new JarFilter());
- if (files != null) {
- debug("getExtFiles files.length " + files.length);
- for (int j = 0; j < files.length; j++) {
- File f = new File(dirs[i], files[j]);
- urls.add(f);
- debug("getExtFiles f["+j+"] "+ f);
- }
- }
- }
- File[] ua = new File[urls.size()];
- urls.copyInto(ua);
- debug("getExtFiles ua.length " + ua.length);
- return ua;
- }
-
- /*
- * @return the list of installed extensions jar files
- */
- private File[] getInstalledExtensions() throws IOException {
- return AccessController.doPrivileged(
- new PrivilegedAction() {
- public File[] run() {
- try {
- return getExtFiles(getExtDirs());
- } catch(IOException e) {
- debug("Cannot get list of installed extensions");
- debugException(e);
- return new File[0];
- }
- }
- });
- }
-
- /*
- * Add the newly installed jar file to the extension class loader.
- *
- * @param cl the current installed extension class loader
- *
- * @return true if successful
- */
- private Boolean addNewExtensionsToClassLoader(Launcher.ExtClassLoader cl) {
- try {
- File[] installedExts = getInstalledExtensions();
- for (int i=0;i() {
- public URL run() {
- try {
- return ParseUtil.fileToEncodedURL(instFile);
- } catch (MalformedURLException e) {
- debugException(e);
- return null;
- }
- }
- });
- if (instURL != null) {
- URL[] urls = cl.getURLs();
- boolean found=false;
- for (int j = 0; j{@code
- * < 0 if source < version
- * > 0 if source > version
- * = 0 if source = version}
- */
- private int compareExtensionVersion(String source, String target)
- throws NumberFormatException
- {
- source = source.toLowerCase();
- target = target.toLowerCase();
-
- return strictCompareExtensionVersion(source, target);
- }
-
-
- /*
- * helper method to compare two versions.
- * version are in the x.y.z.t pattern.
- *
- * @param source version to compare to
- * @param target version used to compare against
- * @return
{@code
- * < 0 if source < version
- * > 0 if source > version
- * = 0 if source = version}
- */
- private int strictCompareExtensionVersion(String source, String target)
- throws NumberFormatException
- {
- if (source.equals(target))
- return 0;
-
- StringTokenizer stk = new StringTokenizer(source, ".,");
- StringTokenizer ttk = new StringTokenizer(target, ".,");
-
- // Compare number
- int n = 0, m = 0, result = 0;
-
- // Convert token into meaning number for comparision
- if (stk.hasMoreTokens())
- n = convertToken(stk.nextToken().toString());
-
- // Convert token into meaning number for comparision
- if (ttk.hasMoreTokens())
- m = convertToken(ttk.nextToken().toString());
-
- if (n > m)
- return 1;
- else if (m > n)
- return -1;
- else
- {
- // Look for index of "." in the string
- int sIdx = source.indexOf('.');
- int tIdx = target.indexOf('.');
-
- if (sIdx == -1)
- sIdx = source.length() - 1;
-
- if (tIdx == -1)
- tIdx = target.length() - 1;
-
- return strictCompareExtensionVersion(source.substring(sIdx + 1),
- target.substring(tIdx + 1));
- }
- }
-
- private int convertToken(String token)
- {
- if (token == null || token.equals(""))
- return 0;
-
- int charValue = 0;
- int charVersion = 0;
- int patchVersion = 0;
- int strLength = token.length();
- int endIndex = strLength;
- char lastChar;
-
- Object[] args = {name};
- MessageFormat mf = new MessageFormat(rb.getString("optpkg.versionerror"));
- String versionError = mf.format(args);
-
- // Look for "-" for pre-release
- int prIndex = token.indexOf('-');
-
- // Look for "_" for patch release
- int patchIndex = token.indexOf('_');
-
- if (prIndex == -1 && patchIndex == -1)
- {
- // This is a FCS release
- try {
- return Integer.parseInt(token) * 100;
- } catch (NumberFormatException e) {
- System.out.println(versionError);
- return 0;
- }
- }
- else if (patchIndex != -1)
- {
- // This is a patch (update) release
- int prversion;
- try {
- // Obtain the version
- prversion = Integer.parseInt(token.substring(0, patchIndex));
-
- // Check to see if the patch version is in the n.n.n_nnl format (special release)
- lastChar = token.charAt(strLength-1);
- if (Character.isLetter(lastChar)) {
- // letters a-z have values from 10-35
- charValue = Character.getNumericValue(lastChar);
- endIndex = strLength-1;
-
- // Obtain the patch version id
- patchVersion = Integer.parseInt(token.substring(patchIndex+1, endIndex));
-
- if (charValue >= Character.getNumericValue('a') && charValue <= Character.getNumericValue('z')) {
- // This is a special release
- charVersion = (patchVersion * 100) + charValue;
- } else {
- // character is not a a-z letter, ignore
- charVersion = 0;
- System.out.println(versionError);
- }
- } else {
- // This is a regular update release. Obtain the patch version id
- patchVersion = Integer.parseInt(token.substring(patchIndex+1, endIndex));
- }
- } catch (NumberFormatException e) {
- System.out.println(versionError);
- return 0;
- }
- return prversion * 100 + (patchVersion + charVersion);
- }
- else
- {
- //This is a milestone release, either a early access, alpha, beta, or RC
-
- // Obtain the version
- int mrversion;
- try {
- mrversion = Integer.parseInt(token.substring(0, prIndex));
- } catch (NumberFormatException e) {
- System.out.println(versionError);
- return 0;
- }
-
- // Obtain the patch version string, including the milestone + version
- String prString = token.substring(prIndex + 1);
-
- // Milestone version
- String msVersion = "";
- int delta = 0;
-
- if (prString.indexOf("ea") != -1)
- {
- msVersion = prString.substring(2);
- delta = 50;
- }
- else if (prString.indexOf("alpha") != -1)
- {
- msVersion = prString.substring(5);
- delta = 40;
- }
- else if (prString.indexOf("beta") != -1)
- {
- msVersion = prString.substring(4);
- delta = 30;
- }
- else if (prString.indexOf("rc") != -1)
- {
- msVersion = prString.substring(2);
- delta = 20;
- }
-
- if (msVersion == null || msVersion.equals(""))
- {
- // No version after the milestone, assume 0
- return mrversion * 100 - delta ;
- }
- else
- {
- // Convert the milestone version
- try {
- return mrversion * 100 - delta + Integer.parseInt(msVersion);
- } catch (NumberFormatException e) {
- System.out.println(versionError);
- return 0;
- }
- }
- }
- }
-}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/misc/ExtensionInstallationException.java
--- a/jdk/src/java.base/share/classes/sun/misc/ExtensionInstallationException.java Thu Jun 11 20:20:05 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-/*
- * Exception when installation of an extension has failed for
- * any reason
- *
- * @deprecated this class will be removed in a future release.
- * @author Jerome Dochez
- */
-@Deprecated
-public class ExtensionInstallationException extends Exception {
-
- static final long serialVersionUID = 3139688306909345924L;
-
- /*
- *
- * Construct a new exception with an exception reason
- *
- */
- public ExtensionInstallationException(String s) {
- super(s);
- }
-}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/misc/ExtensionInstallationProvider.java
--- a/jdk/src/java.base/share/classes/sun/misc/ExtensionInstallationProvider.java Thu Jun 11 20:20:05 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-/**
- * This interface defines the contract a extension installation capable
- * provided to the extension installation dependency mechanism to
- * install new extensions on the user's disk
- *
- * @deprecated this class will be removed in a future release.
- * @author Jerome Dochez
- */
-@Deprecated
-public interface ExtensionInstallationProvider {
-
- /*
- *
- * Request the installation of an extension in the extension directory
- *
- *
- * @param requestExtInfo information on the extension that need to be
- * installed
- * @param installedExtInfo information on the current compatible installed
- * extension. Can be null if no current installation has been found.
- * @return true if the installation is successful, false if the
- * installation could not be attempted.
- * @exception ExtensionInstallationException if an installation was
- * attempted but did not succeed.
- */
- boolean installExtension(ExtensionInfo requestExtInfo,
- ExtensionInfo installedExtInfo)
- throws ExtensionInstallationException;
-}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/net/TelnetInputStream.java
--- a/jdk/src/java.base/share/classes/sun/net/TelnetInputStream.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/TelnetInputStream.java Wed Jul 05 20:37:58 2017 +0200
@@ -31,7 +31,7 @@
* This class provides input and output streams for telnet clients.
* This class overrides read to do CRLF processing as specified in
* RFC 854. The class assumes it is running on a system where lines
- * are terminated with a single newline character.
+ * are terminated with a single newline {@literal } character.
*
* This is the relevant section of RFC 824 regarding CRLF processing:
*
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/net/TelnetOutputStream.java
--- a/jdk/src/java.base/share/classes/sun/net/TelnetOutputStream.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/TelnetOutputStream.java Wed Jul 05 20:37:58 2017 +0200
@@ -31,7 +31,7 @@
* This class provides input and output streams for telnet clients.
* This class overrides write to do CRLF processing as specified in
* RFC 854. The class assumes it is running on a system where lines
- * are terminated with a single newline character.
+ * are terminated with a single newline {@literal } character.
*
* This is the relevant section of RFC 824 regarding CRLF processing:
*
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/net/URLCanonicalizer.java
--- a/jdk/src/java.base/share/classes/sun/net/URLCanonicalizer.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/URLCanonicalizer.java Wed Jul 05 20:37:58 2017 +0200
@@ -28,10 +28,12 @@
/**
* Helper class to map URL "abbreviations" to real URLs.
* The default implementation supports the following mappings:
+ *
*
* Full URLs (those including a protocol name) are passed through unchanged.
*
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java
--- a/jdk/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java Wed Jul 05 20:37:58 2017 +0200
@@ -1211,7 +1211,7 @@
* The OutputStream is not closed by this method at the end
* of the transfer.
*
- * @param name a String containing the name of the file to
+ * @param name a {@code String} containing the name of the file to
* retreive from the server.
* @param local the OutputStream the file should be written to.
* @throws IOException if the transfer fails.
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/net/www/MessageHeader.java
--- a/jdk/src/java.base/share/classes/sun/net/www/MessageHeader.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/MessageHeader.java Wed Jul 05 20:37:58 2017 +0200
@@ -411,7 +411,7 @@
}
/** Convert a message-id string to canonical form (strips off
- leading and trailing <>s) */
+ leading and trailing {@literal <>s}) */
public static String canonicalID(String id) {
if (id == null)
return "";
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java
--- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java Wed Jul 05 20:37:58 2017 +0200
@@ -625,7 +625,7 @@
}
/** Parse the first line of the HTTP request. It usually looks
- something like: "HTTP/1.0 comment\r\n". */
+ something like: {@literal "HTTP/1.0 comment\r\n"}. */
public boolean parseHTTP(MessageHeader responses, ProgressSource pi, HttpURLConnection httpuc)
throws IOException {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Wed Jul 05 20:37:58 2017 +0200
@@ -68,13 +68,14 @@
*
Disconnect
*
* You should not have to use it directly in most cases because all will be handled
- * in a abstract layer. Here is an example of how to use the class :
- *
- * URL url = new URL("ftp://ftp.sun.com/pub/test.txt");
- * UrlConnection con = url.openConnection();
- * InputStream is = con.getInputStream();
- * ...
- * is.close();
+ * in a abstract layer. Here is an example of how to use the class:
+ *
{@code
+ * URL url = new URL("ftp://ftp.sun.com/pub/test.txt");
+ * UrlConnection con = url.openConnection();
+ * InputStream is = con.getInputStream();
+ * ...
+ * is.close();
+ * }
*
* @see sun.net.ftp.FtpClient
*/
@@ -158,7 +159,7 @@
/**
* Creates an FtpURLConnection from a URL.
*
- * @param url The URL to retrieve or store.
+ * @param url The {@code URL} to retrieve or store.
*/
public FtpURLConnection(URL url) {
this(url, null);
@@ -382,7 +383,7 @@
* Get the InputStream to retreive the remote file. It will issue the
* "get" (or "dir") command to the ftp server.
*
- * @return the InputStream to the connection.
+ * @return the {@code InputStream} to the connection.
*
* @throws IOException if already opened for output
* @throws FtpProtocolException if errors occur during the transfert.
@@ -495,7 +496,7 @@
* Get the OutputStream to store the remote file. It will issue the
* "put" command to the ftp server.
*
- * @return the OutputStream to the connection.
+ * @return the {@code OutputStream} to the connection.
*
* @throws IOException if already opened for input or the URL
* points to a directory
@@ -548,9 +549,9 @@
}
/**
- * Gets the Permission associated with the host & port.
+ * Gets the {@code Permission} associated with the host and port.
*
- * @return The Permission object.
+ * @return The {@code Permission} object.
*/
@Override
public Permission getPermission() {
@@ -568,7 +569,7 @@
* exists, overwrite its value with the new value.
*
* @param key the keyword by which the request is known
- * (e.g., "accept").
+ * (e.g., "{@code accept}").
* @param value the value associated with it.
* @throws IllegalStateException if already connected
* @see #getRequestProperty(java.lang.String)
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpAuthenticator.java
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpAuthenticator.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpAuthenticator.java Wed Jul 05 20:37:58 2017 +0200
@@ -59,6 +59,7 @@
* supplied or could be found.
*
*/
public String authString (URL u, String scheme, String realm);
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Jul 05 20:37:58 2017 +0200
@@ -1954,7 +1954,7 @@
/**
* Set the tunneling status.
*
- * @param the state
+ * @param tunnelState the state
*/
public void setTunnelState(TunnelState tunnelState) {
this.tunnelState = tunnelState;
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java Wed Jul 05 20:37:58 2017 +0200
@@ -338,7 +338,7 @@
* Sets the value of the ifModifiedSince field of
* this URLConnection to the specified value.
*
- * @param value the new value.
+ * @param ifmodifiedsince the new value.
* @see java.net.URLConnection#ifModifiedSince
*/
public void setIfModifiedSince(long ifmodifiedsince) {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/reflect/Reflection.java
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java Wed Jul 05 20:37:58 2017 +0200
@@ -295,7 +295,7 @@
/**
* Returns an annotation of the given type backed by the given
- * member -> value map.
+ * member {@literal ->} value map.
*/
public static Annotation annotationForMap(final Class extends Annotation> type,
final Map memberValues)
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java Wed Jul 05 20:37:58 2017 +0200
@@ -73,8 +73,8 @@
/**
* Returns an AnnotationType instance for the specified annotation type.
*
- * @throw IllegalArgumentException if the specified class object for
- * does not represent a valid annotation type
+ * @throws IllegalArgumentException if the specified class object
+ * does not represent a valid annotation type
*/
public static AnnotationType getInstance(
Class extends Annotation> annotationClass)
@@ -183,7 +183,7 @@
/**
* Returns member types for this annotation type
- * (member name -> type mapping).
+ * (member name {@literal ->} type mapping).
*/
public Map> memberTypes() {
return memberTypes;
@@ -191,7 +191,7 @@
/**
* Returns members of this annotation type
- * (member name -> associated Method object mapping).
+ * (member name {@literal ->} associated Method object mapping).
*/
public Map members() {
return members;
@@ -199,7 +199,7 @@
/**
* Returns the default values for this annotation type
- * (Member name -> default value mapping).
+ * (Member name {@literal ->} default value mapping).
*/
public Map memberDefaults() {
return memberDefaults;
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java Wed Jul 05 20:37:58 2017 +0200
@@ -199,7 +199,7 @@
* Regular Annotations on TypeVariables are stored in the type
* annotation byte[] in the class file.
*
- * @param genericsDecl the declaration declaring the type variable
+ * @param genericDecl the declaration declaring the type variable
* @param typeVarIndex the 0-based index of this type variable in the declaration
*/
public static Annotation[] parseTypeVariableAnnotations(D genericDecl,
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java Wed Jul 05 20:37:58 2017 +0200
@@ -73,17 +73,17 @@
*
This method throws a MalformedParameterizedTypeException
* under the following circumstances:
* If the number of actual type arguments (i.e., the size of the
- * array typeArgs) does not correspond to the number of
+ * array {@code typeArgs}) does not correspond to the number of
* formal type arguments.
* If any of the actual type arguments is not an instance of the
* bounds on the corresponding formal.
* @param rawType the Class representing the generic type declaration being
* instantiated
- * @param actualTypeArguments - a (possibly empty) array of types
+ * @param actualTypeArguments a (possibly empty) array of types
* representing the actual type arguments to the parameterized type
- * @param ownerType - the enclosing type, if known.
- * @return An instance of ParameterizedType
- * @throws MalformedParameterizedTypeException - if the instantiation
+ * @param ownerType the enclosing type, if known.
+ * @return An instance of {@code ParameterizedType}
+ * @throws MalformedParameterizedTypeException if the instantiation
* is invalid
*/
public static ParameterizedTypeImpl make(Class> rawType,
@@ -95,18 +95,18 @@
/**
- * Returns an array of Type objects representing the actual type
+ * Returns an array of {@code Type} objects representing the actual type
* arguments to this type.
*
*
Note that in some cases, the returned array be empty. This can occur
* if this type represents a non-parameterized type nested within
* a parameterized type.
*
- * @return an array of Type objects representing the actual type
+ * @return an array of {@code Type} objects representing the actual type
* arguments to this type
- * @throws TypeNotPresentException if any of the
+ * @throws TypeNotPresentException if any of the
* actual type arguments refers to a non-existent type declaration
- * @throws MalformedParameterizedTypeException if any of the
+ * @throws MalformedParameterizedTypeException if any of the
* actual type parameters refer to a parameterized type that cannot
* be instantiated for any reason
* @since 1.5
@@ -116,10 +116,10 @@
}
/**
- * Returns the Type object representing the class or interface
+ * Returns the {@code Type} object representing the class or interface
* that declared this type.
*
- * @return the Type object representing the class or interface
+ * @return the {@code Type} object representing the class or interface
* that declared this type
*/
public Class> getRawType() {
@@ -128,18 +128,18 @@
/**
- * Returns a Type object representing the type that this type
- * is a member of. For example, if this type is O.I,
- * return a representation of O.
+ * Returns a {@code Type} object representing the type that this type
+ * is a member of. For example, if this type is {@code O.I},
+ * return a representation of {@code O}.
*
- *
If this type is a top-level type, null is returned.
+ *
If this type is a top-level type, {@code null} is returned.
*
- * @return a Type object representing the type that
+ * @return a {@code Type} object representing the type that
* this type is a member of. If this type is a top-level type,
- * null is returned
- * @throws TypeNotPresentException if the owner type
+ * {@code null} is returned
+ * @throws TypeNotPresentException if the owner type
* refers to a non-existent type declaration
- * @throws MalformedParameterizedTypeException if the owner type
+ * @throws MalformedParameterizedTypeException if the owner type
* refers to a parameterized type that cannot be instantiated
* for any reason
*
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/reflect/generics/scope/ConstructorScope.java
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/ConstructorScope.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/ConstructorScope.java Wed Jul 05 20:37:58 2017 +0200
@@ -56,9 +56,9 @@
}
/**
- * Factory method. Takes a Constructor object and creates a
+ * Factory method. Takes a {@code Constructor} object and creates a
* scope for it.
- * @param m - A Constructor whose scope we want to obtain
+ * @param c - A Constructor whose scope we want to obtain
* @return The type-variable scope for the constructor m
*/
public static ConstructorScope make(Constructor> c) {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Wed Jul 05 20:37:58 2017 +0200
@@ -28,6 +28,7 @@
import java.security.AlgorithmConstraints;
import java.security.CryptoPrimitive;
import java.security.PrivateKey;
+import java.security.Security;
import java.util.Set;
import java.util.HashSet;
@@ -415,10 +416,12 @@
"SHA1withRSA", --p);
supports(HashAlgorithm.SHA1, SignatureAlgorithm.ECDSA,
"SHA1withECDSA", --p);
+ if (Security.getProvider("SunMSCAPI") == null) {
supports(HashAlgorithm.SHA224, SignatureAlgorithm.RSA,
"SHA224withRSA", --p);
supports(HashAlgorithm.SHA224, SignatureAlgorithm.ECDSA,
"SHA224withECDSA", --p);
+ }
supports(HashAlgorithm.SHA256, SignatureAlgorithm.RSA,
"SHA256withRSA", --p);
supports(HashAlgorithm.SHA256, SignatureAlgorithm.ECDSA,
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/text/resources/en/FormatData_en_SG.java
--- a/jdk/src/java.base/share/classes/sun/text/resources/en/FormatData_en_SG.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/text/resources/en/FormatData_en_SG.java Wed Jul 05 20:37:58 2017 +0200
@@ -88,6 +88,14 @@
"NaN",
}
},
+ { "DatePatterns",
+ new String[] {
+ "EEEE, d MMMM, yyyy", // full date pattern
+ "d MMMM, yyyy", // long date pattern
+ "d MMM, yyyy", // medium date pattern
+ "d/M/yy", // short date pattern
+ }
+ },
};
}
}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/util/PreHashedMap.java
--- a/jdk/src/java.base/share/classes/sun/util/PreHashedMap.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/PreHashedMap.java Wed Jul 05 20:37:58 2017 +0200
@@ -121,8 +121,7 @@
*
This method must construct the map's hash chains and store them into
* the appropriate elements of the given hash-table row array.
*
- * @param rows
- * The row array to be initialized
+ * @param ht The row array to be initialized
*/
protected abstract void init(Object[] ht);
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/util/calendar/BaseCalendar.java
--- a/jdk/src/java.base/share/classes/sun/util/calendar/BaseCalendar.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/calendar/BaseCalendar.java Wed Jul 05 20:37:58 2017 +0200
@@ -28,7 +28,7 @@
import java.util.TimeZone;
/**
- * The BaseCalendar provides basic calendar calculation
+ * The {@code BaseCalendar} provides basic calendar calculation
* functions to support the Julian, Gregorian, and Gregorian-based
* calendar systems.
*
@@ -290,11 +290,11 @@
/**
* Returns 366 if the specified date is in a leap year, or 365
* otherwise This method does not perform the normalization with
- * the specified CalendarDate. The
- * CalendarDate must be normalized to get a correct
+ * the specified {@code CalendarDate}. The
+ * {@code CalendarDate} must be normalized to get a correct
* value.
*
- * @param a CalendarDate
+ * @param date a {@code CalendarDate}
* @return a year length in days
* @throws ClassCastException if the specified date is not a
* {@link BaseCalendar.Date}
@@ -412,7 +412,7 @@
/**
* Calculates calendar fields and store them in the specified
- * CalendarDate.
+ * {@code CalendarDate}.
*/
// should be 'protected'
public void getCalendarDateFromFixedDate(CalendarDate date,
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/util/calendar/CalendarUtils.java
--- a/jdk/src/java.base/share/classes/sun/util/calendar/CalendarUtils.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/calendar/CalendarUtils.java Wed Jul 05 20:37:58 2017 +0200
@@ -94,7 +94,7 @@
* 0 and -1%4 is -1.
*
* @param n the numerator
- * @param d a divisor which must be > 0
+ * @param d a divisor which must be {@literal > 0}
* @param r an array of at least one element in which the value
* mod(n, d) is returned.
* @return the floor of the quotient.
@@ -117,7 +117,7 @@
* 0 and -1%4 is -1.
*
* @param n the numerator
- * @param d a divisor which must be > 0
+ * @param d a divisor which must be {@literal > 0}
* @param r an array of at least one element in which the value
* mod(n, d) is returned.
* @return the floor of the quotient.
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfo.java
--- a/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfo.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfo.java Wed Jul 05 20:37:58 2017 +0200
@@ -364,7 +364,7 @@
* 0 for January.
* @param day The day-in-month of the given date.
* @param dayOfWeek The day-of-week of the given date.
- * @param millis The milliseconds in day in standard local time.
+ * @param milliseconds The milliseconds in day in standard local time.
* @return The milliseconds to add to UTC to get local time.
*/
public int getOffset(int era, int year, int month, int day,
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java Wed Jul 05 20:37:58 2017 +0200
@@ -72,7 +72,7 @@
* If the name returned cannot be localized according to locale,
* (say, the provider does not have a Japanese name for Croatian),
* this method returns null.
- * @param languageCode the ISO 639 language code string in the form of two
+ * @param lang the ISO 639 language code string in the form of two
* lower-case letters between 'a' (U+0061) and 'z' (U+007A)
* @param locale the desired locale
* @return the name of the given language code for the specified locale, or null if it's not
@@ -129,7 +129,7 @@
* If the name returned cannot be localized according to locale,
* (say, the provider does not have a Japanese name for Croatia),
* this method returns null.
- * @param countryCode the ISO 3166 country code string in the form of two
+ * @param ctry the ISO 3166 country code string in the form of two
* upper-case letters between 'A' (U+0041) and 'Z' (U+005A)
* @param locale the desired locale
* @return the name of the given country code for the specified locale, or null if it's not
@@ -152,7 +152,7 @@
* is appropriate for display to the user.
* If the name returned cannot be localized according to locale,
* this method returns null.
- * @param variant the variant string
+ * @param vrnt the variant string
* @param locale the desired locale
* @return the name of the given variant string for the specified locale, or null if it's not
* available.
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java Wed Jul 05 20:37:58 2017 +0200
@@ -79,7 +79,7 @@
* appropriate for daylight saving time even if the specified time zone
* has not observed daylight saving time in the past.
*
- * @param ID a time zone ID string
+ * @param id a time zone ID string
* @param daylight if true, return the daylight saving name.
* @param style either {@link java.util.TimeZone#LONG TimeZone.LONG} or
* {@link java.util.TimeZone#SHORT TimeZone.SHORT}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java
--- a/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java Wed Jul 05 20:37:58 2017 +0200
@@ -74,10 +74,10 @@
* java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
*
* Limitation:
- * /conf/logging.properties is the system-wide logging
+ * {@code /conf/logging.properties} is the system-wide logging
* configuration defined in the specification and read in the
* default case to configure any java.util.logging.Logger instances.
- * Platform loggers will not detect if /conf/logging.properties
+ * Platform loggers will not detect if {@code /conf/logging.properties}
* is modified. In other words, unless the java.util.logging API
* is used at runtime or the logging system properties is set,
* the platform loggers will use the default setting described above.
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNamesBundle.java
--- a/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNamesBundle.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNamesBundle.java Wed Jul 05 20:37:58 2017 +0200
@@ -55,7 +55,7 @@
* array for the enumeration returned by getKeys.
*
Inserts the time zone ID (the key of the bundle entries) into
* the string arrays returned by handleGetObject.
- *
+ *
* All TimeZoneNames resource bundles must extend this
* class and implement the getContents method.
*/
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/share/native/libjava/ClassLoader.c
--- a/jdk/src/java.base/share/native/libjava/ClassLoader.c Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/share/native/libjava/ClassLoader.c Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -479,12 +479,12 @@
return res;
}
/*
- * Class: java_lang_ClassLoader_NativeLibrary
+ * Class: java_lang_ClassLoader
* Method: findBuiltinLib
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
-Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib
+Java_java_lang_ClassLoader_findBuiltinLib
(JNIEnv *env, jclass cls, jstring name)
{
const char *cname;
@@ -500,8 +500,6 @@
JNU_ThrowInternalError(env, "NULL filename for native library");
return NULL;
}
- // Can't call initIDs because it will recurse into NativeLibrary via
- // FindClass to check context so set prochandle here as well.
procHandle = getProcessHandle();
cname = JNU_GetStringPlatformChars(env, name, 0);
if (cname == NULL) {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/unix/classes/sun/misc/FileURLMapper.java
--- a/jdk/src/java.base/unix/classes/sun/misc/FileURLMapper.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/unix/classes/sun/misc/FileURLMapper.java Wed Jul 05 20:37:58 2017 +0200
@@ -50,7 +50,7 @@
}
/**
- * @returns the platform specific path corresponding to the URL
+ * @return the platform specific path corresponding to the URL
* so long as the URL does not contain a hostname in the authority field.
*/
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java
--- a/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Wed Jul 05 20:37:58 2017 +0200
@@ -113,7 +113,8 @@
Client client;
/**
* Create a NTLMAuthentication:
- * Username may be specified as domainusername in the application Authenticator.
+ * Username may be specified as {@literal domainusername}
+ * in the application Authenticator.
* If this notation is not used, then the domain will be taken
* from a system property: "http.auth.ntlm.domain".
*/
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/unix/native/libnet/Inet4AddressImpl.c
--- a/jdk/src/java.base/unix/native/libnet/Inet4AddressImpl.c Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/unix/native/libnet/Inet4AddressImpl.c Wed Jul 05 20:37:58 2017 +0200
@@ -121,7 +121,7 @@
jobjectArray ret = 0;
int retLen = 0;
- int error=0;
+ int getaddrinfo_error=0;
struct addrinfo hints, *res, *resNew = NULL;
initInetAddressIDs(env);
@@ -149,22 +149,24 @@
return NULL;
}
+
+ getaddrinfo_error = getaddrinfo(hostname, NULL, &hints, &res);
+
#ifdef MACOSX
- /* If we're looking up the local machine, bypass DNS lookups and get
- * address from getifaddrs.
- */
- ret = lookupIfLocalhost(env, hostname, JNI_FALSE);
- if (ret != NULL || (*env)->ExceptionCheck(env)) {
- JNU_ReleaseStringPlatformChars(env, host, hostname);
- return ret;
+ if (getaddrinfo_error) {
+ // If getaddrinfo fails try getifaddrs.
+ ret = lookupIfLocalhost(env, hostname, JNI_FALSE);
+ if (ret != NULL || (*env)->ExceptionCheck(env)) {
+ JNU_ReleaseStringPlatformChars(env, host, hostname);
+ return ret;
+ }
}
#endif
- error = getaddrinfo(hostname, NULL, &hints, &res);
-
- if (error) {
+ if (getaddrinfo_error) {
/* report error */
- NET_ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
+ NET_ThrowUnknownHostExceptionWithGaiError(
+ env, hostname, getaddrinfo_error);
JNU_ReleaseStringPlatformChars(env, host, hostname);
return NULL;
} else {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/unix/native/libnet/Inet6AddressImpl.c
--- a/jdk/src/java.base/unix/native/libnet/Inet6AddressImpl.c Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/unix/native/libnet/Inet6AddressImpl.c Wed Jul 05 20:37:58 2017 +0200
@@ -254,7 +254,7 @@
jobjectArray ret = 0;
int retLen = 0;
- int error=0;
+ int getaddrinfo_error=0;
#ifdef AF_INET6
struct addrinfo hints, *res, *resNew = NULL;
#endif /* AF_INET6 */
@@ -269,19 +269,6 @@
hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
CHECK_NULL_RETURN(hostname, NULL);
-#ifdef MACOSX
- /*
- * If we're looking up the local machine, attempt to get the address
- * from getifaddrs. This ensures we get an IPv6 address for the local
- * machine.
- */
- ret = lookupIfLocalhost(env, hostname, JNI_TRUE);
- if (ret != NULL || (*env)->ExceptionCheck(env)) {
- JNU_ReleaseStringPlatformChars(env, host, hostname);
- return ret;
- }
-#endif
-
#ifdef AF_INET6
/* Try once, with our static buffer. */
memset(&hints, 0, sizeof(hints));
@@ -301,11 +288,27 @@
}
#endif
- error = getaddrinfo(hostname, NULL, &hints, &res);
+ getaddrinfo_error = getaddrinfo(hostname, NULL, &hints, &res);
- if (error) {
+#ifdef MACOSX
+ if (getaddrinfo_error) {
+ /*
+ * If getaddrinfo fails looking up the local machine, attempt to get the
+ * address from getifaddrs. This ensures we get an IPv6 address for the
+ * local machine.
+ */
+ ret = lookupIfLocalhost(env, hostname, JNI_TRUE);
+ if (ret != NULL || (*env)->ExceptionCheck(env)) {
+ JNU_ReleaseStringPlatformChars(env, host, hostname);
+ return ret;
+ }
+ }
+#endif
+
+ if (getaddrinfo_error) {
/* report error */
- NET_ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
+ NET_ThrowUnknownHostExceptionWithGaiError(
+ env, hostname, getaddrinfo_error);
JNU_ReleaseStringPlatformChars(env, host, hostname);
return NULL;
} else {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/windows/classes/sun/misc/FileURLMapper.java
--- a/jdk/src/java.base/windows/classes/sun/misc/FileURLMapper.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/windows/classes/sun/misc/FileURLMapper.java Wed Jul 05 20:37:58 2017 +0200
@@ -46,7 +46,7 @@
}
/**
- * @returns the platform specific path corresponding to the URL, and in particular
+ * @return the platform specific path corresponding to the URL, and in particular
* returns a UNC when the authority contains a hostname
*/
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java
--- a/jdk/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Wed Jul 05 20:37:58 2017 +0200
@@ -83,7 +83,8 @@
/**
* Create a NTLMAuthentication:
- * Username may be specified as domainusername in the application Authenticator.
+ * Username may be specified as {@literal domainusername}
+ * in the application Authenticator.
* If this notation is not used, then the domain will be taken
* from a system property: "http.auth.ntlm.domain".
*/
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.datatransfer/share/classes/sun/datatransfer/DataFlavorUtil.java
--- a/jdk/src/java.datatransfer/share/classes/sun/datatransfer/DataFlavorUtil.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.datatransfer/share/classes/sun/datatransfer/DataFlavorUtil.java Wed Jul 05 20:37:58 2017 +0200
@@ -55,7 +55,7 @@
/**
* Utility class with different datatransfer helper functions
*
- * @see 1.9
+ * @since 1.9
*/
public class DataFlavorUtil {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java Wed Jul 05 20:37:58 2017 +0200
@@ -97,7 +97,8 @@
/**
- * Converts an OSType (e.g. "macs" from ) into an int.
+ * Converts an OSType (e.g. "macs"
+ * from {@literal }) into an int.
*
* @param type the 4 character type to convert.
* @return an int representing the 4 character value
@@ -355,7 +356,7 @@
/**
* Moves the specified file to the Trash
*
- * @param file
+ * @param file the file
* @return returns true if the NSFileManager successfully moved the file to the Trash.
* @throws FileNotFoundException
*
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java Wed Jul 05 20:37:58 2017 +0200
@@ -344,12 +344,14 @@
* Execute applet events.
* Here is the state transition diagram
*
+ *
*
* In the legacy lifecycle model. The applet gets loaded, inited and started. So it stays
* in the APPLET_START state unless the applet goes away(refresh page or leave the page).
@@ -364,10 +366,9 @@
* APPLET_STOP to APPLET_DESTROY and to APPLET_INIT .
*
* Also, the applet can jump from APPLET_INIT state to APPLET_DESTROY (in Netscape/Mozilla case).
- * Same as APPLET_LOAD to
+ * Same as APPLET_LOAD to
* APPLET_DISPOSE since all of this are triggered by browser.
*
- *
*/
@Override
public void run() {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java Wed Jul 05 20:37:58 2017 +0200
@@ -1093,7 +1093,7 @@
}
/**
- * Scan an html file for
+ *
Absolute URIs
*
- *
rmi://1234@hostname:2099/remoteobjectname -
- * Specifies the Java Virtual Machine identified by lvmid
- * 1234 on host hostname accessed
- * using the rmi: protocol through the rmi remote
- * object named remoteobjectname as registered with
- * the rmiserver on port 2099 on host
- * hostname.
- *
- *
file:/path/file - Identifies a Java Virtual Machine
- * through accessing a special file based protocol to use as
- * the communications mechanism.
- *
+ *
rmi://1234@hostname:2099/remoteobjectname -
+ * Specifies the Java Virtual Machine identified by lvmid
+ * 1234 on host hostname accessed
+ * using the rmi: protocol through the rmi remote
+ * object named remoteobjectname as registered with
+ * the rmiserver on port 2099 on host
+ * hostname.
+ *
+ *
file:/path/file - Identifies a Java Virtual Machine
+ * through accessing a special file based protocol to use as
+ * the communications mechanism.
+ *
*
+ *
*
- *
*
* @see URI
* @see HostIdentifier
@@ -236,16 +235,14 @@
* missing components will have result in the HostIdentifier assigning
* assumed defaults that allow the VmIdentifier to be resolved according
* to those defaults.
- *
*
- * For example, a VmIdentifier that specifies only a lvmid
+ * For example, a VmIdentifier that specifies only a {@code lvmid}
* will result in a HostIdentifier for localhost utilizing
* the default local protocol, local:. A VmIdentifier that
- * specifies both a vmid and a hostname will result
+ * specifies both a {@code vmid} and a {@code hostname} will result
* in a HostIdentifier for the specified host with the default remote
* protocol, rmi:, using the protocol defaults for the
- * port and servername components.
- *
+ * {@code port} and {@code servername} components.
*
* @return HostIdentifier - the host identifier for the host containing
* the Java Virtual Machine represented by this
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java Wed Jul 05 20:37:58 2017 +0200
@@ -108,7 +108,8 @@
*
* @param patternString a string containing a pattern as described in
* {@link java.util.regex.Pattern}.
- * @return List - a List of {@link Monitor} objects that can be used to
+ * @return {@code List} - a List of {@link Monitor}
+ * objects that can be used to
* monitor the instrumentation objects whose names match
* the given pattern. If no instrumentation objects have`
* names matching the given pattern, then an empty List
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfDataBufferImpl.java
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfDataBufferImpl.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfDataBufferImpl.java Wed Jul 05 20:37:58 2017 +0200
@@ -266,7 +266,8 @@
*
* @param patternString a string containing a pattern as described in
* {@link java.util.regex.Pattern}.
- * @return List - a List of {@link Monitor} objects that can be used to
+ * @return {@code List} - a List of {@link Monitor}
+ * objects that can be used to
* monitor the instrumentation objects whose names match
* the given pattern. If no instrumentation objects have`
* names matching the given pattern, then an empty List
diff -r 97f4fef2d420 -r a9714a11e787 jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsName.java
--- a/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsName.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsName.java Wed Jul 05 20:37:58 2017 +0200
@@ -580,7 +580,7 @@
* Serializes only the domain name string, for compactness and to avoid
* any implementation dependency.
*
- * @serialdata The domain name string.
+ * @serialData The domain name string.
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/com/sun/corba/7130985/CorbaExceptionsCompileTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/7130985/CorbaExceptionsCompileTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 7130985
+ * @summary Four helper classes missing in Sun JDK
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @run main CorbaExceptionsCompileTest
+ */
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.rmi.RemoteException;
+import org.omg.CORBA.ORBPackage.InvalidName;
+import org.omg.CORBA.TypeCodePackage.BadKind;
+import org.omg.CORBA.TypeCodePackage.Bounds;
+
+import jdk.testlibrary.FileUtils;
+import jdk.testlibrary.JDKToolLauncher;
+
+public class CorbaExceptionsCompileTest implements CorbaExceptionsTest {
+
+ public CorbaExceptionsCompileTest() {
+ super();
+ }
+
+ public void testExceptionInvalidName()
+ throws java.rmi.RemoteException, InvalidName {}
+
+ public void testExceptionBounds()
+ throws java.rmi.RemoteException, Bounds {}
+
+ public void testExceptionBadKind()
+ throws java.rmi.RemoteException, BadKind {}
+
+ public void testExceptionCorba_Bounds()
+ throws java.rmi.RemoteException, org.omg.CORBA.Bounds {}
+
+ public static void main(String[] args) throws Exception {
+ final File f = new File(
+ CorbaExceptionsCompileTest.class.getProtectionDomain()
+ .getCodeSource().getLocation().getPath());
+ System.out.println(f.getCanonicalPath());
+ ProcessBuilder pb = new ProcessBuilder("ls", "-l");
+ pb.directory(f);
+ Process p = pb.start();
+ p.waitFor();
+ if (p.exitValue() == 0) {
+ try (BufferedReader br = new BufferedReader(
+ new InputStreamReader(p.getInputStream()))) {
+ StringBuilder builder = new StringBuilder();
+ String line = null;
+ while ( (line = br.readLine()) != null) {
+ builder.append(line + "\n");
+ }
+ String result = builder.toString();
+ System.out.println(result);
+ }
+ }
+
+ Path outDir = Paths.get("CorbaExceptionsCompileTest-compiled");
+ outDir = Files.createDirectory(outDir).toAbsolutePath();
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("rmic");
+ launcher.addToolArg("-classpath").addToolArg(f.getCanonicalPath())
+ .addToolArg("-d").addToolArg(outDir.toString())
+ .addToolArg("-iiop").addToolArg("CorbaExceptionsCompileTest");
+
+ pb = new ProcessBuilder(launcher.getCommand());
+ pb.directory(f);
+ System.out.println("Working Directory: " + pb.directory());
+ System.out.println("CorbaExceptionsCompileTest.class exists: "
+ + new File(f, "CorbaExceptionsCompileTest.class").exists());
+
+ p = pb.start();
+ p.waitFor();
+ if (p.exitValue() != 0) {
+ try (BufferedReader br = new BufferedReader(
+ new InputStreamReader(p.getInputStream()))) {
+ StringBuilder builder = new StringBuilder();
+ String line = null;
+ while ( (line = br.readLine()) != null) {
+ builder.append(line + "\n");
+ }
+ String result = builder.toString();
+ System.out.println(result);
+ throw new RuntimeException(launcher.getCommand() +
+ " -iiop CorbaExceptionsCompileTest failed with status: "
+ + p.exitValue());
+ }
+ }
+
+ if (Files.exists(outDir))
+ FileUtils.deleteFileTreeWithRetry(outDir);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/com/sun/corba/7130985/CorbaExceptionsTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/7130985/CorbaExceptionsTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.rmi.Remote;
+import org.omg.CORBA.ORBPackage.InvalidName;
+import org.omg.CORBA.TypeCodePackage.BadKind;
+import org.omg.CORBA.TypeCodePackage.Bounds;
+
+public interface CorbaExceptionsTest extends Remote {
+ public void testExceptionInvalidName() throws java.rmi.RemoteException, InvalidName;
+ public void testExceptionBounds() throws java.rmi.RemoteException, Bounds;
+ public void testExceptionBadKind() throws java.rmi.RemoteException, BadKind;
+ public void testExceptionCorba_Bounds() throws java.rmi.RemoteException, org.omg.CORBA.Bounds;
+}
+
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/io/FilePermission/FilePermissionCollection.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/FilePermission/FilePermissionCollection.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for FilePermissionCollection subclass
+ */
+
+import java.io.FilePermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+
+public class FilePermissionCollection {
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ FilePermission perm = new FilePermission("/tmp/foo", "read");
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println
+ ("test 1: add throws IllegalArgExc for wrong perm type");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong perm type");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println("test 3: implies returns true for match on " +
+ "name and action");
+ perms.add(new FilePermission("/tmp/foo", "read"));
+ if (!perms.implies(new FilePermission("/tmp/foo", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println("test 4: implies returns false for match on " +
+ "name but not action");
+ if (perms.implies(new FilePermission("/tmp/foo", "write"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println("test 5: implies returns true for match on " +
+ "name and subset of actions");
+ perms.add(new FilePermission("/tmp/bar", "read, write"));
+ if (!perms.implies(new FilePermission("/tmp/bar", "write"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 6
+ System.out.println("test 6: implies returns true for aggregate " +
+ "match on name and action");
+ perms.add(new FilePermission("/tmp/baz", "read"));
+ perms.add(new FilePermission("/tmp/baz", "write"));
+ if (!perms.implies(new FilePermission("/tmp/baz", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+ if (!perms.implies(new FilePermission("/tmp/baz", "write,read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 7
+ System.out.println("test 7: implies returns true for wildcard " +
+ "and match on action");
+ perms.add(new FilePermission("/usr/tmp/*", "read"));
+ if (!perms.implies(new FilePermission("/usr/tmp/foo", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println
+ ("test 8: implies returns false for non-match on wildcard");
+ if (perms.implies(new FilePermission("/usr/tmp/bar/foo", "read"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 9
+ System.out.println
+ ("test 9: implies returns true for deep wildcard match");
+ perms.add(new FilePermission("/usr/tmp/-", "read"));
+ if (!perms.implies(new FilePermission("/usr/tmp/bar/foo", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 10
+ System.out.println("test 10: implies returns true for relative match");
+ perms.add(new FilePermission(".", "read"));
+ if (!perms.implies(new FilePermission(System.getProperty("user.dir"),
+ "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 11
+ System.out.println("test 11: implies returns true for all " +
+ "wildcard and match on action");
+ perms.add(new FilePermission("<>", "read"));
+ if (!perms.implies(new FilePermission("/tmp/foobar", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 12
+ System.out.println("test 12: implies returns false for wildcard " +
+ "and non-match on action");
+ if (perms.implies(new FilePermission("/tmp/foobar", "write"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 13
+ System.out.println("test 13: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ // the two "/tmp/baz" entries were combined into one
+ if (numPerms != 7) {
+ System.err.println("Expected 7, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/lang/Runtime/exec/LotsOfOutput.java
--- a/jdk/test/java/lang/Runtime/exec/LotsOfOutput.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/test/java/lang/Runtime/exec/LotsOfOutput.java Wed Jul 05 20:37:58 2017 +0200
@@ -48,20 +48,21 @@
UnixCommands.ensureCommandsAvailable("cat");
Process p = runtime.exec(UnixCommands.cat() + " /dev/zero");
- long initMemory = usedMemory();
- boolean growing = false;
+ long prev = usedMemory();
+ int growing = 0;
for (int i = 1; i < 10; i++) {
Thread.sleep(100);
long used = usedMemory();
- if (used != initMemory) {
- System.out.printf("consuming memory: i: %d, initial: %d, used: %d, delta: %d%n",
- i, initMemory, used, used - initMemory);
+ if (used != prev) {
+ System.out.printf("consuming memory: i: %d, prev: %d, used: %d, delta: %d%n",
+ i, prev, used, used - prev);
}
- if (used > initMemory + THRESHOLD)
- growing = true;
+ if (used > prev + THRESHOLD)
+ growing += 1;
+ prev = used;
}
- if (growing)
- throw new Exception("Process consumes memory.");
+ if (growing > 2)
+ throw new Exception("Process consumes memory: growing " + growing);
}
}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java
--- a/jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java Wed Jul 05 20:37:58 2017 +0200
@@ -38,12 +38,19 @@
failures++;
} catch (InvocationTargetException e) {
Throwable c = e.getCause();
- if (expected.isInstance(c))
- System.out.println("EXPECTED: " + expected.getName() + ", "+ c);
- else {
- failures++;
- System.out.println("FAIL: Unexpected wrapped exception " + c);
- e.printStackTrace(System.out);
+ if (BootstrapMethodError.class.isInstance(c)) {
+ c = c.getCause();
+ if (expected.isInstance(c))
+ System.out.println("EXPECTED: " + expected.getName() + ", "+ c);
+ else {
+ failures++;
+ System.out.println("FAIL: Unexpected wrapped exception " + c);
+ e.printStackTrace(System.out);
+ }
+ } else {
+ failures++;
+ System.out.println("FAIL: Exception from MethodHandle invocation not wrapped in BootstrapMethodError " + c);
+ e.printStackTrace(System.out);
}
} catch (Throwable e) {
failures++;
@@ -74,14 +81,19 @@
Invoker.invoke();
System.out.println("FAIL: No exception throw, probably failed to load modified bytecodes for MethodSupplier");
failures++;
- } catch (Throwable e) {
- if (expected.isInstance(e))
- System.out.println("EXPECTED: " + expected.getName() + ", "+ e);
+ } catch (BootstrapMethodError e) {
+ Throwable c = e.getCause();
+ if (expected.isInstance(c))
+ System.out.println("EXPECTED: " + expected.getName() + ", "+ c);
else {
+ failures++;
+ System.out.println("FAIL: Unexpected exception has been caught " + c);
+ e.printStackTrace(System.out);
+ }
+ } catch (Throwable e) {
failures++;
- System.out.println("FAIL: Unexpected exception has been caught " + e);
+ System.out.println("FAIL: Exception from MethodHandle invocation not wrapped in BootstrapMethodError " + e);
e.printStackTrace(System.out);
- }
}
System.out.println();
try {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java
--- a/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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 @@
/*
* @test LFGarbageCollectedTest
* @bug 8046703
+ * @ignore 8078602
* @summary Test verifies that lambda forms are garbage collected
* @author kshefov
* @library /lib/testlibrary/jsr292 /lib/testlibrary
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/net/SocketPermission/SocketPermissionCollection.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/SocketPermission/SocketPermissionCollection.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for PermissionCollection subclasses
+ */
+
+import java.net.SocketPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+
+public class SocketPermissionCollection {
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ SocketPermission perm = new SocketPermission("www.example.com",
+ "connect");
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println
+ ("test 1: add throws IllegalArgExc for wrong perm type");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong perm type");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println
+ ("test 3: implies returns true for match on name and action");
+ perms.add(new SocketPermission("www.example.com", "connect"));
+ if (!perms.implies(new SocketPermission("www.example.com", "connect"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println
+ ("test 4: implies returns false for match on name but not action");
+ if (perms.implies(new SocketPermission("www.example.com", "accept"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println("test 5: implies returns true for match on " +
+ "name and subset of actions");
+ perms.add(new SocketPermission("www.example.org", "accept, connect"));
+ if (!perms.implies(new SocketPermission("www.example.org", "connect"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 6
+ System.out.println("test 6: implies returns true for aggregate " +
+ "match on name and action");
+ perms.add(new SocketPermission("www.example.us", "accept"));
+ perms.add(new SocketPermission("www.example.us", "connect"));
+ if (!perms.implies(new SocketPermission("www.example.us", "accept"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+ if (!perms.implies(new SocketPermission("www.example.us",
+ "connect,accept"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 7
+ System.out.println("test 7: implies returns true for wildcard " +
+ "and match on action");
+ perms.add(new SocketPermission("*.example.edu", "resolve"));
+ if (!perms.implies(new SocketPermission("foo.example.edu", "resolve"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println("test 8: implies returns false for non-match " +
+ "on wildcard");
+ if (perms.implies(new SocketPermission("foo.example.edu", "connect"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 9
+ System.out.println("test 9: implies returns true for matching " +
+ "port range and action");
+ perms.add(new SocketPermission("204.160.241.0:1024-65535", "connect"));
+ if (!perms.implies(new SocketPermission("204.160.241.0:1025", "connect"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 13
+ System.out.println("test 13: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ // the two "/tmp/baz" entries were combined into one
+ if (numPerms != 5) {
+ System.err.println("Expected 5, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/security/BasicPermission/BasicPermissionCollection.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/BasicPermission/BasicPermissionCollection.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for BasicPermissionCollection subclass
+ */
+
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+
+public class BasicPermissionCollection {
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ TestPermission perm = new TestPermission("foo");
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println("test 1: add throws IllegalArgumentExc");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong class");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println("test 3: implies returns true for match on name");
+ perms.add(new TestPermission("foo"));
+ if (!perms.implies(new TestPermission("foo"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println("test 4: implies returns true for wildcard match");
+ perms.add(new TestPermission("bar.*"));
+ if (!perms.implies(new TestPermission("bar.foo"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println
+ ("test 5: implies returns false for invalid wildcard");
+ perms.add(new TestPermission("baz*"));
+ if (perms.implies(new TestPermission("baz.foo"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 6
+ System.out.println
+ ("test 6: implies returns true for deep wildcard match");
+ if (!perms.implies(new TestPermission("bar.foo.baz"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 7
+ System.out.println
+ ("test 7: implies returns true for all wildcard match");
+ perms.add(new TestPermission("*"));
+ if (!perms.implies(new TestPermission("yes"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println("test 8: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ if (numPerms != 4) {
+ System.err.println("Expected 4, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+
+ private static class TestPermission extends BasicPermission {
+ TestPermission(String name) {
+ super(name);
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/security/PermissionCollection/Concurrent.java
--- a/jdk/test/java/security/PermissionCollection/Concurrent.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/test/java/security/PermissionCollection/Concurrent.java Wed Jul 05 20:37:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -104,13 +104,11 @@
System.out.println(perm[perm.length-1] + " implies " + result);
}
- synchronized (pc) {
- Enumeration en = pc.elements();
- while (en.hasMoreElements()) {
- Object obj = en.nextElement();
- if (debug) {
- System.out.println(obj);
- }
+ Enumeration en = pc.elements();
+ while (en.hasMoreElements()) {
+ Object obj = en.nextElement();
+ if (debug) {
+ System.out.println(obj);
}
}
}
@@ -151,13 +149,11 @@
}
}
- synchronized (pc) {
- Enumeration en = pc.elements();
- while (en.hasMoreElements()) {
- Object obj = en.nextElement();
- if (debug) {
- System.out.println(obj);
- }
+ Enumeration en = pc.elements();
+ while (en.hasMoreElements()) {
+ Object obj = en.nextElement();
+ if (debug) {
+ System.out.println(obj);
}
}
}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/text/Format/DateFormat/LocaleDateFormats.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Format/DateFormat/LocaleDateFormats.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8080774
+ * @run testng/othervm -Djava.locale.providers=JRE,CLDR LocaleDateFormats
+ * @summary This file contains tests for JRE locales date formats
+ */
+
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class LocaleDateFormats {
+
+ @Test(dataProvider = "dateFormats")
+ public void testDateFormat(Locale loc, int style, int year, int month, int date, String expectedString) {
+ Calendar cal = Calendar.getInstance(loc);
+ cal.set(year, month-1, date);
+ // Create date formatter based on requested style and test locale
+ DateFormat df = DateFormat.getDateInstance(style, loc);
+ // Test the date format
+ assertEquals(df.format(cal.getTime()), expectedString);
+ }
+
+ @DataProvider(name = "dateFormats" )
+ private Object[][] dateFormats() {
+ return new Object[][] {
+ //8080774
+ //Locale, Format type, year, month, date, expected result
+ {localeEnSG, DateFormat.SHORT, 2015, 5, 6, "6/5/15"},
+ {localeEnSG, DateFormat.MEDIUM, 2015, 5, 6, "6 May, 2015"},
+ {localeEnSG, DateFormat.LONG, 2015, 5, 6, "6 May, 2015"},
+ {localeEnSG, DateFormat.FULL, 2015, 5, 6, "Wednesday, 6 May, 2015"}
+ };
+ }
+ // en_SG Locale instance
+ private static final Locale localeEnSG = new Locale("en", "SG");
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/util/Arrays/SortingIntBenchmarkTestJMH.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Arrays/SortingIntBenchmarkTestJMH.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,708 @@
+/*
+ * Copyright 2015 Goldman Sachs.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+@State(Scope.Thread)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+public class SortingIntBenchmarkTestJMH {
+ private static final int QUICKSORT_THRESHOLD = 286;
+ private static final int MAX_RUN_COUNT = 67;
+ private static final int INSERTION_SORT_THRESHOLD = 47;
+ public static final int MAX_VALUE = 1_000_000;
+
+ @Param({"pairFlipZeroPairFlip", "pairFlipOneHundredPairFlip"
+ , "zeroHi", "hiZeroLow", "hiFlatLow", "identical",
+ "randomDups", "randomNoDups", "sortedReversedSorted", "pairFlip", "endLessThan"})
+
+ public String listType;
+
+ private int[] array;
+ private static final int LIST_SIZE = 10_000_000;
+ public static final int NUMBER_OF_ITERATIONS = 10;
+
+ @Setup
+ public void setUp() {
+ Random random = new Random(123456789012345L);
+ this.array = new int[LIST_SIZE];
+ int threeQuarters = (int) (LIST_SIZE * 0.75);
+ if ("zeroHi".equals(this.listType)) {
+ for (int i = 0; i < threeQuarters; i++) {
+ this.array[i] = 0;
+ }
+ int k = 1;
+ for (int i = threeQuarters; i < LIST_SIZE; i++) {
+ this.array[i] = k;
+ k++;
+ }
+ }
+ else if ("hiFlatLow".equals(this.listType)) {
+ int oneThird = LIST_SIZE / 3;
+ for (int i = 0; i < oneThird; i++) {
+ this.array[i] = i;
+ }
+ int twoThirds = oneThird * 2;
+ int constant = oneThird - 1;
+ for (int i = oneThird; i < twoThirds; i++) {
+ this.array[i] = constant;
+ }
+ for (int i = twoThirds; i < LIST_SIZE; i++) {
+ this.array[i] = constant - i + twoThirds;
+ }
+ }
+ else if ("hiZeroLow".equals(this.listType)) {
+ int oneThird = LIST_SIZE / 3;
+ for (int i = 0; i < oneThird; i++) {
+ this.array[i] = i;
+ }
+ int twoThirds = oneThird * 2;
+ for (int i = oneThird; i < twoThirds; i++) {
+ this.array[i] = 0;
+ }
+ for (int i = twoThirds; i < LIST_SIZE; i++) {
+ this.array[i] = oneThird - i + twoThirds;
+ }
+ }
+ else if ("identical".equals(this.listType)) {
+ for (int i = 0; i < LIST_SIZE; i++) {
+ this.array[i] = 0;
+ }
+ }
+ else if ("randomDups".equals(this.listType)) {
+ for (int i = 0; i < LIST_SIZE; i++) {
+ this.array[i] = random.nextInt(1000);
+ }
+ }
+ else if ("randomNoDups".equals(this.listType)) {
+ Set set = new HashSet();
+ while (set.size() < LIST_SIZE + 1) {
+ set.add(random.nextInt());
+ }
+ List list = new ArrayList<>(LIST_SIZE);
+ list.addAll(set);
+ for (int i = 0; i < LIST_SIZE; i++) {
+ this.array[i] = list.get(i);
+ }
+ }
+ else if ("sortedReversedSorted".equals(this.listType)) {
+ for (int i = 0; i < LIST_SIZE / 2; i++) {
+ this.array[i] = i;
+ }
+ int num = 0;
+ for (int i = LIST_SIZE / 2; i < LIST_SIZE; i++) {
+ this.array[i] = LIST_SIZE - num;
+ num++;
+ }
+ }
+ else if ("pairFlip".equals(this.listType)) {
+ for (int i = 0; i < LIST_SIZE; i++) {
+ this.array[i] = i;
+ }
+ for (int i = 0; i < LIST_SIZE; i += 2) {
+ int temp = this.array[i];
+ this.array[i] = this.array[i + 1];
+ this.array[i + 1] = temp;
+ }
+ }
+ else if ("endLessThan".equals(this.listType)) {
+ for (int i = 0; i < LIST_SIZE - 1; i++) {
+ this.array[i] = 3;
+ }
+ this.array[LIST_SIZE - 1] = 1;
+ }
+ else if ("pairFlipZeroPairFlip".equals(this.listType)) {
+ //pairflip
+ for (int i = 0; i < 64; i++) {
+ this.array[i] = i;
+ }
+ for (int i = 0; i < 64; i += 2) {
+ int temp = this.array[i];
+ this.array[i] = this.array[i + 1];
+ this.array[i + 1] = temp;
+ }
+ //zero
+ for (int i = 64; i < this.array.length - 64; i++) {
+ this.array[i] = 0;
+ }
+ //pairflip
+ for (int i = this.array.length - 64; i < this.array.length; i++) {
+ this.array[i] = i;
+ }
+ for (int i = this.array.length - 64; i < this.array.length; i += 2) {
+ int temp = this.array[i];
+ this.array[i] = this.array[i + 1];
+ this.array[i + 1] = temp;
+ }
+ }
+ else if ("pairFlipOneHundredPairFlip".equals(this.listType)) {
+ //10, 5
+ for (int i = 0; i < 64; i++) {
+ if (i % 2 == 0) {
+ this.array[i] = 10;
+ }
+ else {
+ this.array[i] = 5;
+ }
+ }
+
+ //100
+ for (int i = 64; i < this.array.length - 64; i++) {
+ this.array[i] = 100;
+ }
+
+ //10, 5
+ for (int i = this.array.length - 64; i < this.array.length; i++) {
+ if (i % 2 == 0) {
+ this.array[i] = 10;
+ }
+ else {
+ this.array[i] = 5;
+ }
+ }
+ }
+ }
+
+ @Warmup(iterations = 20)
+ @Measurement(iterations = 10)
+ @Benchmark
+ public void sortNewWay() {
+ for (int i = 0; i < NUMBER_OF_ITERATIONS; i++) {
+ SortingIntTestJMH.sort(this.array, 0, this.array.length - 1, null, 0, 0);
+ }
+ }
+
+ @Warmup(iterations = 20)
+ @Measurement(iterations = 10)
+ @Benchmark
+ public void sortCurrentWay() {
+ for (int i = 0; i < NUMBER_OF_ITERATIONS; i++) {
+ Arrays.sort(this.array);
+ }
+ }
+
+ static void sort(int[] a, int left, int right,
+ int[] work, int workBase, int workLen) {
+ // Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ SortingIntTestJMH.sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT + 1];
+ int count = 0;
+ run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ while (k < right && a[k] == a[k + 1])
+ k++;
+ if (k == right) break;
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]) ;
+ }
+ else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]) ;
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ int t = a[lo];
+ a[lo] = a[hi];
+ a[hi] = t;
+ }
+ }
+ if (run[count] > left && a[run[count]] >= a[run[count] - 1]) {
+ count--;
+ }
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ // Implementation note: variable "right" is increased by 1.
+ if (run[count] == right++) {
+ run[++count] = right;
+ }
+ if (count <= 1) { // The array is already sorted
+ return;
+ }
+
+ // Determine alternation base for merge
+ byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1) {
+ }
+
+ // Use or create temporary array b for merging
+ int[] b; // temp array; alternates with a
+ int ao, bo; // array offsets from 'left'
+ int blen = right - left; // space needed for b
+ if (work == null || workLen < blen || workBase + blen > work.length) {
+ work = new int[blen];
+ workBase = 0;
+ }
+ if (odd == 0) {
+ System.arraycopy(a, left, work, workBase, blen);
+ b = a;
+ bo = 0;
+ a = work;
+ ao = workBase - left;
+ }
+ else {
+ b = work;
+ ao = 0;
+ bo = workBase - left;
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) {
+ b[i + bo] = a[p++ + ao];
+ }
+ else {
+ b[i + bo] = a[q++ + ao];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i + bo] = a[i + ao]
+ ) {
+ }
+ run[++last] = right;
+ }
+ int[] t = a;
+ a = b;
+ b = t;
+ int o = ao;
+ ao = bo;
+ bo = o;
+ }
+ }
+
+ private static void sort(int[] a, int left, int right, boolean leftmost) {
+ int length = right - left + 1;
+
+ // Use insertion sort on tiny arrays
+ if (length < INSERTION_SORT_THRESHOLD) {
+ if (leftmost) {
+ /*
+ * Traditional (without sentinel) insertion sort,
+ * optimized for server VM, is used in case of
+ * the leftmost part.
+ */
+ for (int i = left, j = i; i < right; j = ++i) {
+ int ai = a[i + 1];
+ while (ai < a[j]) {
+ a[j + 1] = a[j];
+ if (j-- == left) {
+ break;
+ }
+ }
+ a[j + 1] = ai;
+ }
+ }
+ else {
+ /*
+ * Skip the longest ascending sequence.
+ */
+ do {
+ if (left >= right) {
+ return;
+ }
+ }
+ while (a[++left] >= a[left - 1]);
+
+ /*
+ * Every element from adjoining part plays the role
+ * of sentinel, therefore this allows us to avoid the
+ * left range check on each iteration. Moreover, we use
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
+ */
+ for (int k = left; ++left <= right; k = ++left) {
+ int a1 = a[k], a2 = a[left];
+
+ if (a1 < a2) {
+ a2 = a1;
+ a1 = a[left];
+ }
+ while (a1 < a[--k]) {
+ a[k + 2] = a[k];
+ }
+ a[++k + 1] = a1;
+
+ while (a2 < a[--k]) {
+ a[k + 1] = a[k];
+ }
+ a[k + 1] = a2;
+ }
+ int last = a[right];
+
+ while (last < a[--right]) {
+ a[right + 1] = a[right];
+ }
+ a[right + 1] = last;
+ }
+ return;
+ }
+
+ // Inexpensive approximation of length / 7
+ int seventh = (length >> 3) + (length >> 6) + 1;
+
+ /*
+ * Sort five evenly spaced elements around (and including) the
+ * center element in the range. These elements will be used for
+ * pivot selection as described below. The choice for spacing
+ * these elements was empirically determined to work well on
+ * a wide variety of inputs.
+ */
+ int e3 = (left + right) >>> 1; // The midpoint
+ int e2 = e3 - seventh;
+ int e1 = e2 - seventh;
+ int e4 = e3 + seventh;
+ int e5 = e4 + seventh;
+
+ // Sort these elements using insertion sort
+ if (a[e2] < a[e1]) {
+ int t = a[e2];
+ a[e2] = a[e1];
+ a[e1] = t;
+ }
+
+ if (a[e3] < a[e2]) {
+ int t = a[e3];
+ a[e3] = a[e2];
+ a[e2] = t;
+ if (t < a[e1]) {
+ a[e2] = a[e1];
+ a[e1] = t;
+ }
+ }
+ if (a[e4] < a[e3]) {
+ int t = a[e4];
+ a[e4] = a[e3];
+ a[e3] = t;
+ if (t < a[e2]) {
+ a[e3] = a[e2];
+ a[e2] = t;
+ if (t < a[e1]) {
+ a[e2] = a[e1];
+ a[e1] = t;
+ }
+ }
+ }
+ if (a[e5] < a[e4]) {
+ int t = a[e5];
+ a[e5] = a[e4];
+ a[e4] = t;
+ if (t < a[e3]) {
+ a[e4] = a[e3];
+ a[e3] = t;
+ if (t < a[e2]) {
+ a[e3] = a[e2];
+ a[e2] = t;
+ if (t < a[e1]) {
+ a[e2] = a[e1];
+ a[e1] = t;
+ }
+ }
+ }
+ }
+
+ // Pointers
+ int less = left; // The index of the first element of center part
+ int great = right; // The index before the first element of right part
+
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ int pivot1 = a[e2];
+ int pivot2 = a[e4];
+
+ /*
+ * The first and the last elements to be sorted are moved to the
+ * locations formerly occupied by the pivots. When partitioning
+ * is complete, the pivots are swapped back into their final
+ * positions, and excluded from subsequent sorting.
+ */
+ a[e2] = a[left];
+ a[e4] = a[right];
+
+ /*
+ * Skip elements, which are less or greater than pivot values.
+ */
+ while (a[++less] < pivot1) {
+ }
+ while (a[--great] > pivot2) {
+ }
+
+ /*
+ * Partitioning:
+ *
+ * left part center part right part
+ * +--------------------------------------------------------------+
+ * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 |
+ * +--------------------------------------------------------------+
+ * ^ ^ ^
+ * | | |
+ * less k great
+ *
+ * Invariants:
+ *
+ * all in (left, less) < pivot1
+ * pivot1 <= all in [less, k) <= pivot2
+ * all in (great, right) > pivot2
+ *
+ * Pointer k is the first index of ?-part.
+ */
+ outer:
+ for (int k = less - 1; ++k <= great; ) {
+ int ak = a[k];
+ if (ak < pivot1) { // Move a[k] to left part
+ a[k] = a[less];
+ /*
+ * Here and below we use "a[i] = b; i++;" instead
+ * of "a[i++] = b;" due to performance issue.
+ */
+ a[less] = ak;
+ ++less;
+ }
+ else if (ak > pivot2) { // Move a[k] to right part
+ while (a[great] > pivot2) {
+ if (great-- == k) {
+ break outer;
+ }
+ }
+ if (a[great] < pivot1) { // a[great] <= pivot2
+ a[k] = a[less];
+ a[less] = a[great];
+ ++less;
+ }
+ else { // pivot1 <= a[great] <= pivot2
+ a[k] = a[great];
+ }
+ /*
+ * Here and below we use "a[i] = b; i--;" instead
+ * of "a[i--] = b;" due to performance issue.
+ */
+ a[great] = ak;
+ --great;
+ }
+ }
+
+ // Swap pivots into their final positions
+ a[left] = a[less - 1];
+ a[less - 1] = pivot1;
+ a[right] = a[great + 1];
+ a[great + 1] = pivot2;
+
+ // Sort left and right parts recursively, excluding known pivots
+ SortingIntTestJMH.sort(a, left, less - 2, leftmost);
+ SortingIntTestJMH.sort(a, great + 2, right, false);
+
+ /*
+ * If center part is too large (comprises > 4/7 of the array),
+ * swap internal pivot values to ends.
+ */
+ if (less < e1 && e5 < great) {
+ /*
+ * Skip elements, which are equal to pivot values.
+ */
+ while (a[less] == pivot1) {
+ ++less;
+ }
+
+ while (a[great] == pivot2) {
+ --great;
+ }
+
+ /*
+ * Partitioning:
+ *
+ * left part center part right part
+ * +----------------------------------------------------------+
+ * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 |
+ * +----------------------------------------------------------+
+ * ^ ^ ^
+ * | | |
+ * less k great
+ *
+ * Invariants:
+ *
+ * all in (*, less) == pivot1
+ * pivot1 < all in [less, k) < pivot2
+ * all in (great, *) == pivot2
+ *
+ * Pointer k is the first index of ?-part.
+ */
+ outer:
+ for (int k = less - 1; ++k <= great; ) {
+ int ak = a[k];
+ if (ak == pivot1) { // Move a[k] to left part
+ a[k] = a[less];
+ a[less] = ak;
+ ++less;
+ }
+ else if (ak == pivot2) { // Move a[k] to right part
+ while (a[great] == pivot2) {
+ if (great-- == k) {
+ break outer;
+ }
+ }
+ if (a[great] == pivot1) { // a[great] < pivot2
+ a[k] = a[less];
+ /*
+ * Even though a[great] equals to pivot1, the
+ * assignment a[less] = pivot1 may be incorrect,
+ * if a[great] and pivot1 are floating-point zeros
+ * of different signs. Therefore in float and
+ * double sorting methods we have to use more
+ * accurate assignment a[less] = a[great].
+ */
+ a[less] = pivot1;
+ ++less;
+ }
+ else { // pivot1 < a[great] < pivot2
+ a[k] = a[great];
+ }
+ a[great] = ak;
+ --great;
+ }
+ }
+ }
+
+ // Sort center part recursively
+ SortingIntTestJMH.sort(a, less, great, false);
+ }
+ else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ int pivot = a[e3];
+
+ /*
+ * Partitioning degenerates to the traditional 3-way
+ * (or "Dutch National Flag") schema:
+ *
+ * left part center part right part
+ * +-------------------------------------------------+
+ * | < pivot | == pivot | ? | > pivot |
+ * +-------------------------------------------------+
+ * ^ ^ ^
+ * | | |
+ * less k great
+ *
+ * Invariants:
+ *
+ * all in (left, less) < pivot
+ * all in [less, k) == pivot
+ * all in (great, right) > pivot
+ *
+ * Pointer k is the first index of ?-part.
+ */
+ for (int k = less; k <= great; ++k) {
+ if (a[k] == pivot) {
+ continue;
+ }
+ int ak = a[k];
+ if (ak < pivot) { // Move a[k] to left part
+ a[k] = a[less];
+ a[less] = ak;
+ ++less;
+ }
+ else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
+ }
+ if (a[great] < pivot) { // a[great] <= pivot
+ a[k] = a[less];
+ a[less] = a[great];
+ ++less;
+ }
+ else { // a[great] == pivot
+ /*
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
+ * zeros of different signs. Therefore in float
+ * and double sorting methods we have to use
+ * more accurate assignment a[k] = a[great].
+ */
+ a[k] = pivot;
+ }
+ a[great] = ak;
+ --great;
+ }
+ }
+
+ /*
+ * Sort left and right parts recursively.
+ * All elements from center part are equal
+ * and, therefore, already sorted.
+ */
+ SortingIntTestJMH.sort(a, left, less - 1, leftmost);
+ SortingIntTestJMH.sort(a, great + 1, right, false);
+ }
+ }
+
+ private static void swap(int[] arr, int i, int j) {
+ int tmp = arr[i];
+ arr[i] = arr[j];
+ arr[j] = tmp;
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/util/Arrays/SortingLongBenchmarkTestJMH.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Arrays/SortingLongBenchmarkTestJMH.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,725 @@
+/*
+ * Copyright 2015 Goldman Sachs.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+@State(Scope.Thread)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+public class SortingLongBenchmarkTestJMH {
+ private static final int QUICKSORT_THRESHOLD = 286;
+ private static final int MAX_RUN_COUNT = 67;
+ private static final int INSERTION_SORT_THRESHOLD = 47;
+ public static final int MAX_VALUE = 1_000_000;
+
+ @Param({"pairFlipZeroPairFlip", "descendingAscending", "zeroHi", "hiZeroLow", "hiFlatLow", "identical",
+ "randomDups", "randomNoDups", "sortedReversedSorted", "pairFlip", "endLessThan"})
+ public String listType;
+
+ private long[] array;
+ private static final int LIST_SIZE = 10_000_000;
+ public static final int NUMBER_OF_ITERATIONS = 10;
+
+ @Setup
+ public void setUp() {
+ Random random = new Random(123456789012345L);
+ this.array = new long[LIST_SIZE];
+ int threeQuarters = (int) (LIST_SIZE * 0.75);
+ if ("zeroHi".equals(this.listType)) {
+ for (int i = 0; i < threeQuarters; i++) {
+ this.array[i] = 0;
+ }
+ int k = 1;
+ for (int i = threeQuarters; i < LIST_SIZE; i++) {
+ this.array[i] = k;
+ k++;
+ }
+ }
+ else if ("hiFlatLow".equals(this.listType)) {
+ int oneThird = LIST_SIZE / 3;
+ for (int i = 0; i < oneThird; i++) {
+ this.array[i] = i;
+ }
+ int twoThirds = oneThird * 2;
+ int constant = oneThird - 1;
+ for (int i = oneThird; i < twoThirds; i++) {
+ this.array[i] = constant;
+ }
+ for (int i = twoThirds; i < LIST_SIZE; i++) {
+ this.array[i] = constant - i + twoThirds;
+ }
+ }
+ else if ("hiZeroLow".equals(this.listType)) {
+ int oneThird = LIST_SIZE / 3;
+ for (int i = 0; i < oneThird; i++) {
+ this.array[i] = i;
+ }
+ int twoThirds = oneThird * 2;
+ for (int i = oneThird; i < twoThirds; i++) {
+ this.array[i] = 0;
+ }
+ for (int i = twoThirds; i < LIST_SIZE; i++) {
+ this.array[i] = oneThird - i + twoThirds;
+ }
+ }
+ else if ("identical".equals(this.listType)) {
+ for (int i = 0; i < LIST_SIZE; i++) {
+ this.array[i] = 0;
+ }
+ }
+ else if ("randomDups".equals(this.listType)) {
+ for (int i = 0; i < LIST_SIZE; i++) {
+ this.array[i] = random.nextInt(1000);
+ }
+ }
+ else if ("randomNoDups".equals(this.listType)) {
+ Set set = new HashSet<>();
+ while (set.size() < LIST_SIZE + 1) {
+ set.add(random.nextInt());
+ }
+ List list = new ArrayList<>(LIST_SIZE);
+ list.addAll(set);
+ for (int i = 0; i < LIST_SIZE; i++) {
+ this.array[i] = list.get(i);
+ }
+ }
+ else if ("sortedReversedSorted".equals(this.listType)) {
+ for (int i = 0; i < LIST_SIZE / 2; i++) {
+ this.array[i] = i;
+ }
+ int num = 0;
+ for (int i = LIST_SIZE / 2; i < LIST_SIZE; i++) {
+ this.array[i] = LIST_SIZE - num;
+ num++;
+ }
+ }
+ else if ("pairFlip".equals(this.listType)) {
+ for (int i = 0; i < LIST_SIZE; i++) {
+ this.array[i] = i;
+ }
+ for (int i = 0; i < LIST_SIZE; i += 2) {
+ long temp = this.array[i];
+ this.array[i] = this.array[i + 1];
+ this.array[i + 1] = temp;
+ }
+ }
+ else if ("endLessThan".equals(this.listType)) {
+ for (int i = 0; i < LIST_SIZE - 1; i++) {
+ this.array[i] = 3;
+ }
+ this.array[LIST_SIZE - 1] = 1;
+ }
+ else if ("pairFlipZeroPairFlip".equals(this.listType)) {
+ //pairflip
+ for (int i = 0; i < 64; i++) {
+ this.array[i] = i;
+ }
+ for (int i = 0; i < 64; i += 2) {
+ long temp = this.array[i];
+ this.array[i] = this.array[i + 1];
+ this.array[i + 1] = temp;
+ }
+ //zero
+ for (int i = 64; i < this.array.length - 64; i++) {
+ this.array[i] = 0;
+ }
+ //pairflip
+ for (int i = this.array.length - 64; i < this.array.length; i++) {
+ this.array[i] = i;
+ }
+ for (int i = this.array.length - 64; i < this.array.length; i += 2) {
+ long temp = this.array[i];
+ this.array[i] = this.array[i + 1];
+ this.array[i + 1] = temp;
+ }
+ }
+ else if ("pairFlipOneHundredPairFlip".equals(this.listType)) {
+ //10, 5
+ for (int i = 0; i < 64; i++) {
+ if (i % 2 == 0) {
+ this.array[i] = 10;
+ }
+ else {
+ this.array[i] = 5;
+ }
+ }
+
+ //100
+ for (int i = 64; i < this.array.length - 64; i++) {
+ this.array[i] = 100;
+ }
+
+ //10, 5
+ for (int i = this.array.length - 64; i < this.array.length; i++) {
+ if (i % 2 == 0) {
+ this.array[i] = 10;
+ }
+ else {
+ this.array[i] = 5;
+ }
+ }
+ }
+ }
+
+ @Warmup(iterations = 20)
+ @Measurement(iterations = 10)
+ @Benchmark
+ public void sortNewWay() {
+ for (int i = 0; i < NUMBER_OF_ITERATIONS; i++) {
+ SortingLongTestJMH.sort(this.array, 0, this.array.length - 1, null, 0, 0);
+ }
+ }
+
+ @Warmup(iterations = 20)
+ @Measurement(iterations = 10)
+ @Benchmark
+ public void sortOldWay() {
+ for (int i = 0; i < NUMBER_OF_ITERATIONS; i++) {
+ Arrays.sort(this.array);
+ }
+ }
+
+ /**
+ * Sorts the specified range of the array using the given
+ * workspace array slice if possible for merging
+ *
+ * @param a the array to be sorted
+ * @param left the index of the first element, inclusive, to be sorted
+ * @param right the index of the last element, inclusive, to be sorted
+ * @param work a workspace array (slice)
+ * @param workBase origin of usable space in work array
+ * @param workLen usable size of work array
+ */
+ static void sort(long[] a, int left, int right,
+ long[] work, int workBase, int workLen) {
+// Use Quicksort on small arrays
+ if (right - left < QUICKSORT_THRESHOLD) {
+ SortingLongTestJMH.sort(a, left, right, true);
+ return;
+ }
+
+ /*
+ * Index run[i] is the start of i-th run
+ * (ascending or descending sequence).
+ */
+ int[] run = new int[MAX_RUN_COUNT + 1];
+ int count = 0;
+ run[0] = left;
+
+ // Check if the array is nearly sorted
+ for (int k = left; k < right; run[count] = k) {
+ while (k < right && a[k] == a[k + 1])
+ k++;
+ if (k == right) break;
+ if (a[k] < a[k + 1]) { // ascending
+ while (++k <= right && a[k - 1] <= a[k]) ;
+ }
+ else if (a[k] > a[k + 1]) { // descending
+ while (++k <= right && a[k - 1] >= a[k]) ;
+ for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
+ long t = a[lo];
+ a[lo] = a[hi];
+ a[hi] = t;
+ }
+ }
+ if (run[count] > left && a[run[count]] >= a[run[count] - 1]) {
+ count--;
+ }
+ /*
+ * The array is not highly structured,
+ * use Quicksort instead of merge sort.
+ */
+ if (++count == MAX_RUN_COUNT) {
+ sort(a, left, right, true);
+ return;
+ }
+ }
+
+ // Check special cases
+ // Implementation note: variable "right" is increased by 1.
+ if (run[count] == right++) {
+ run[++count] = right;
+ }
+ if (count <= 1) { // The array is already sorted
+ return;
+ }
+
+ // Determine alternation base for merge
+ byte odd = 0;
+ for (int n = 1; (n <<= 1) < count; odd ^= 1) {
+ }
+
+ // Use or create temporary array b for merging
+ long[] b; // temp array; alternates with a
+ int ao, bo; // array offsets from 'left'
+ int blen = right - left; // space needed for b
+ if (work == null || workLen < blen || workBase + blen > work.length) {
+ work = new long[blen];
+ workBase = 0;
+ }
+ if (odd == 0) {
+ System.arraycopy(a, left, work, workBase, blen);
+ b = a;
+ bo = 0;
+ a = work;
+ ao = workBase - left;
+ }
+ else {
+ b = work;
+ ao = 0;
+ bo = workBase - left;
+ }
+
+ // Merging
+ for (int last; count > 1; count = last) {
+ for (int k = (last = 0) + 2; k <= count; k += 2) {
+ int hi = run[k], mi = run[k - 1];
+ for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
+ if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) {
+ b[i + bo] = a[p++ + ao];
+ }
+ else {
+ b[i + bo] = a[q++ + ao];
+ }
+ }
+ run[++last] = hi;
+ }
+ if ((count & 1) != 0) {
+ for (int i = right, lo = run[count - 1]; --i >= lo;
+ b[i + bo] = a[i + ao]
+ ) {
+ }
+ run[++last] = right;
+ }
+ long[] t = a;
+ a = b;
+ b = t;
+ int o = ao;
+ ao = bo;
+ bo = o;
+ }
+ }
+
+ /**
+ * Sorts the specified range of the array by Dual-Pivot Quicksort.
+ *
+ * @param a the array to be sorted
+ * @param left the index of the first element, inclusive, to be sorted
+ * @param right the index of the last element, inclusive, to be sorted
+ * @param leftmost indicates if this part is the leftmost in the range
+ */
+ private static void sort(long[] a, int left, int right, boolean leftmost) {
+ int length = right - left + 1;
+
+ // Use insertion sort on tiny arrays
+ if (length < INSERTION_SORT_THRESHOLD) {
+ if (leftmost) {
+ /*
+ * Traditional (without sentinel) insertion sort,
+ * optimized for server VM, is used in case of
+ * the leftmost part.
+ */
+ for (int i = left, j = i; i < right; j = ++i) {
+ long ai = a[i + 1];
+ while (ai < a[j]) {
+ a[j + 1] = a[j];
+ if (j-- == left) {
+ break;
+ }
+ }
+ a[j + 1] = ai;
+ }
+ }
+ else {
+ /*
+ * Skip the longest ascending sequence.
+ */
+ do {
+ if (left >= right) {
+ return;
+ }
+ }
+ while (a[++left] >= a[left - 1]);
+
+ /*
+ * Every element from adjoining part plays the role
+ * of sentinel, therefore this allows us to avoid the
+ * left range check on each iteration. Moreover, we use
+ * the more optimized algorithm, so called pair insertion
+ * sort, which is faster (in the context of Quicksort)
+ * than traditional implementation of insertion sort.
+ */
+ for (int k = left; ++left <= right; k = ++left) {
+ long a1 = a[k], a2 = a[left];
+
+ if (a1 < a2) {
+ a2 = a1;
+ a1 = a[left];
+ }
+ while (a1 < a[--k]) {
+ a[k + 2] = a[k];
+ }
+ a[++k + 1] = a1;
+
+ while (a2 < a[--k]) {
+ a[k + 1] = a[k];
+ }
+ a[k + 1] = a2;
+ }
+ long last = a[right];
+
+ while (last < a[--right]) {
+ a[right + 1] = a[right];
+ }
+ a[right + 1] = last;
+ }
+ return;
+ }
+
+ // Inexpensive approximation of length / 7
+ int seventh = (length >> 3) + (length >> 6) + 1;
+
+ /*
+ * Sort five evenly spaced elements around (and including) the
+ * center element in the range. These elements will be used for
+ * pivot selection as described below. The choice for spacing
+ * these elements was empirically determined to work well on
+ * a wide variety of inputs.
+ */
+ int e3 = (left + right) >>> 1; // The midpoint
+ int e2 = e3 - seventh;
+ int e1 = e2 - seventh;
+ int e4 = e3 + seventh;
+ int e5 = e4 + seventh;
+
+ // Sort these elements using insertion sort
+ if (a[e2] < a[e1]) {
+ long t = a[e2];
+ a[e2] = a[e1];
+ a[e1] = t;
+ }
+
+ if (a[e3] < a[e2]) {
+ long t = a[e3];
+ a[e3] = a[e2];
+ a[e2] = t;
+ if (t < a[e1]) {
+ a[e2] = a[e1];
+ a[e1] = t;
+ }
+ }
+ if (a[e4] < a[e3]) {
+ long t = a[e4];
+ a[e4] = a[e3];
+ a[e3] = t;
+ if (t < a[e2]) {
+ a[e3] = a[e2];
+ a[e2] = t;
+ if (t < a[e1]) {
+ a[e2] = a[e1];
+ a[e1] = t;
+ }
+ }
+ }
+ if (a[e5] < a[e4]) {
+ long t = a[e5];
+ a[e5] = a[e4];
+ a[e4] = t;
+ if (t < a[e3]) {
+ a[e4] = a[e3];
+ a[e3] = t;
+ if (t < a[e2]) {
+ a[e3] = a[e2];
+ a[e2] = t;
+ if (t < a[e1]) {
+ a[e2] = a[e1];
+ a[e1] = t;
+ }
+ }
+ }
+ }
+
+ // Pointers
+ int less = left; // The index of the first element of center part
+ int great = right; // The index before the first element of right part
+
+ if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
+ /*
+ * Use the second and fourth of the five sorted elements as pivots.
+ * These values are inexpensive approximations of the first and
+ * second terciles of the array. Note that pivot1 <= pivot2.
+ */
+ long pivot1 = a[e2];
+ long pivot2 = a[e4];
+
+ /*
+ * The first and the last elements to be sorted are moved to the
+ * locations formerly occupied by the pivots. When partitioning
+ * is complete, the pivots are swapped back into their final
+ * positions, and excluded from subsequent sorting.
+ */
+ a[e2] = a[left];
+ a[e4] = a[right];
+
+ /*
+ * Skip elements, which are less or greater than pivot values.
+ */
+ while (a[++less] < pivot1) {
+ }
+ while (a[--great] > pivot2) {
+ }
+
+ /*
+ * Partitioning:
+ *
+ * left part center part right part
+ * +--------------------------------------------------------------+
+ * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 |
+ * +--------------------------------------------------------------+
+ * ^ ^ ^
+ * | | |
+ * less k great
+ *
+ * Invariants:
+ *
+ * all in (left, less) < pivot1
+ * pivot1 <= all in [less, k) <= pivot2
+ * all in (great, right) > pivot2
+ *
+ * Pointer k is the first index of ?-part.
+ */
+ outer:
+ for (int k = less - 1; ++k <= great; ) {
+ long ak = a[k];
+ if (ak < pivot1) { // Move a[k] to left part
+ a[k] = a[less];
+ /*
+ * Here and below we use "a[i] = b; i++;" instead
+ * of "a[i++] = b;" due to performance issue.
+ */
+ a[less] = ak;
+ ++less;
+ }
+ else if (ak > pivot2) { // Move a[k] to right part
+ while (a[great] > pivot2) {
+ if (great-- == k) {
+ break outer;
+ }
+ }
+ if (a[great] < pivot1) { // a[great] <= pivot2
+ a[k] = a[less];
+ a[less] = a[great];
+ ++less;
+ }
+ else { // pivot1 <= a[great] <= pivot2
+ a[k] = a[great];
+ }
+ /*
+ * Here and below we use "a[i] = b; i--;" instead
+ * of "a[i--] = b;" due to performance issue.
+ */
+ a[great] = ak;
+ --great;
+ }
+ }
+
+ // Swap pivots into their final positions
+ a[left] = a[less - 1];
+ a[less - 1] = pivot1;
+ a[right] = a[great + 1];
+ a[great + 1] = pivot2;
+
+ // Sort left and right parts recursively, excluding known pivots
+ SortingLongTestJMH.sort(a, left, less - 2, leftmost);
+ SortingLongTestJMH.sort(a, great + 2, right, false);
+
+ /*
+ * If center part is too large (comprises > 4/7 of the array),
+ * swap internal pivot values to ends.
+ */
+ if (less < e1 && e5 < great) {
+ /*
+ * Skip elements, which are equal to pivot values.
+ */
+ while (a[less] == pivot1) {
+ ++less;
+ }
+
+ while (a[great] == pivot2) {
+ --great;
+ }
+
+ /*
+ * Partitioning:
+ *
+ * left part center part right part
+ * +----------------------------------------------------------+
+ * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 |
+ * +----------------------------------------------------------+
+ * ^ ^ ^
+ * | | |
+ * less k great
+ *
+ * Invariants:
+ *
+ * all in (*, less) == pivot1
+ * pivot1 < all in [less, k) < pivot2
+ * all in (great, *) == pivot2
+ *
+ * Pointer k is the first index of ?-part.
+ */
+ outer:
+ for (int k = less - 1; ++k <= great; ) {
+ long ak = a[k];
+ if (ak == pivot1) { // Move a[k] to left part
+ a[k] = a[less];
+ a[less] = ak;
+ ++less;
+ }
+ else if (ak == pivot2) { // Move a[k] to right part
+ while (a[great] == pivot2) {
+ if (great-- == k) {
+ break outer;
+ }
+ }
+ if (a[great] == pivot1) { // a[great] < pivot2
+ a[k] = a[less];
+ /*
+ * Even though a[great] equals to pivot1, the
+ * assignment a[less] = pivot1 may be incorrect,
+ * if a[great] and pivot1 are floating-point zeros
+ * of different signs. Therefore in float and
+ * double sorting methods we have to use more
+ * accurate assignment a[less] = a[great].
+ */
+ a[less] = pivot1;
+ ++less;
+ }
+ else { // pivot1 < a[great] < pivot2
+ a[k] = a[great];
+ }
+ a[great] = ak;
+ --great;
+ }
+ }
+ }
+
+ // Sort center part recursively
+ SortingLongTestJMH.sort(a, less, great, false);
+ }
+ else { // Partitioning with one pivot
+ /*
+ * Use the third of the five sorted elements as pivot.
+ * This value is inexpensive approximation of the median.
+ */
+ long pivot = a[e3];
+
+ /*
+ * Partitioning degenerates to the traditional 3-way
+ * (or "Dutch National Flag") schema:
+ *
+ * left part center part right part
+ * +-------------------------------------------------+
+ * | < pivot | == pivot | ? | > pivot |
+ * +-------------------------------------------------+
+ * ^ ^ ^
+ * | | |
+ * less k great
+ *
+ * Invariants:
+ *
+ * all in (left, less) < pivot
+ * all in [less, k) == pivot
+ * all in (great, right) > pivot
+ *
+ * Pointer k is the first index of ?-part.
+ */
+ for (int k = less; k <= great; ++k) {
+ if (a[k] == pivot) {
+ continue;
+ }
+ long ak = a[k];
+ if (ak < pivot) { // Move a[k] to left part
+ a[k] = a[less];
+ a[less] = ak;
+ ++less;
+ }
+ else { // a[k] > pivot - Move a[k] to right part
+ while (a[great] > pivot) {
+ --great;
+ }
+ if (a[great] < pivot) { // a[great] <= pivot
+ a[k] = a[less];
+ a[less] = a[great];
+ ++less;
+ }
+ else { // a[great] == pivot
+ /*
+ * Even though a[great] equals to pivot, the
+ * assignment a[k] = pivot may be incorrect,
+ * if a[great] and pivot are floating-point
+ * zeros of different signs. Therefore in float
+ * and double sorting methods we have to use
+ * more accurate assignment a[k] = a[great].
+ */
+ a[k] = pivot;
+ }
+ a[great] = ak;
+ --great;
+ }
+ }
+
+ /*
+ * Sort left and right parts recursively.
+ * All elements from center part are equal
+ * and, therefore, already sorted.
+ */
+ SortingLongTestJMH.sort(a, left, less - 1, leftmost);
+ SortingLongTestJMH.sort(a, great + 1, right, false);
+ }
+ }
+
+ private static void swap(long[] arr, int i, int j) {
+ long tmp = arr[i];
+ arr[i] = arr[j];
+ arr[j] = tmp;
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/util/Arrays/SortingNearlySortedPrimitive.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Arrays/SortingNearlySortedPrimitive.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2015 Goldman Sachs.
+ * Copyright (c) 2015, 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
+ * @summary Tests the sorting of a large array of sorted primitive values,
+ * predominently for cases where the array is nearly sorted. This tests
+ * code that detects patterns in the array to determine if it is nearly
+ * sorted and if so employs and optimizes merge sort rather than a
+ * Dual-Pivot QuickSort.
+ *
+ * @run testng SortingNearlySortedPrimitive
+ */
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.function.Supplier;
+
+public class SortingNearlySortedPrimitive {
+ private static final int ARRAY_SIZE = 1_000_000;
+
+ @DataProvider(name = "arrays")
+ public Object[][] createData() {
+ return new Object[][]{
+ {"hiZeroLowTest", (Supplier) this::hiZeroLowData},
+ {"endLessThanTest", (Supplier) this::endLessThanData},
+ {"highFlatLowTest", (Supplier) this::highFlatLowData},
+ {"identicalTest", (Supplier) this::identicalData},
+ {"sortedReversedSortedTest", (Supplier) this::sortedReversedSortedData},
+ {"pairFlipTest", (Supplier) this::pairFlipData},
+ {"zeroHiTest", (Supplier) this::zeroHiData},
+ };
+ }
+
+ @Test(dataProvider = "arrays")
+ public void runTests(String testName, Supplier dataMethod) throws Exception {
+ int[] intSourceArray = dataMethod.get();
+
+ // Clone source array to ensure it is not modified
+ this.sortAndAssert(intSourceArray.clone());
+ this.sortAndAssert(floatCopyFromInt(intSourceArray));
+ this.sortAndAssert(doubleCopyFromInt(intSourceArray));
+ this.sortAndAssert(longCopyFromInt(intSourceArray));
+ this.sortAndAssert(shortCopyFromInt(intSourceArray));
+ this.sortAndAssert(charCopyFromInt(intSourceArray));
+ }
+
+ private float[] floatCopyFromInt(int[] src) {
+ float[] result = new float[src.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = src[i];
+ }
+ return result;
+ }
+
+ private double[] doubleCopyFromInt(int[] src) {
+ double[] result = new double[src.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = src[i];
+ }
+ return result;
+ }
+
+ private long[] longCopyFromInt(int[] src) {
+ long[] result = new long[src.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = src[i];
+ }
+ return result;
+ }
+
+ private short[] shortCopyFromInt(int[] src) {
+ short[] result = new short[src.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = (short) src[i];
+ }
+ return result;
+ }
+
+ private char[] charCopyFromInt(int[] src) {
+ char[] result = new char[src.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = (char) src[i];
+ }
+ return result;
+ }
+
+ private void sortAndAssert(int[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < ARRAY_SIZE; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ Assert.assertEquals(ARRAY_SIZE, array.length);
+ }
+
+ private void sortAndAssert(char[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < ARRAY_SIZE; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ Assert.assertEquals(ARRAY_SIZE, array.length);
+ }
+
+ private void sortAndAssert(short[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < ARRAY_SIZE; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ Assert.assertEquals(ARRAY_SIZE, array.length);
+ }
+
+ private void sortAndAssert(double[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < ARRAY_SIZE; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ Assert.assertEquals(ARRAY_SIZE, array.length);
+ }
+
+ private void sortAndAssert(float[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < ARRAY_SIZE; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ Assert.assertEquals(ARRAY_SIZE, array.length);
+ }
+
+ private void sortAndAssert(long[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < ARRAY_SIZE; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ Assert.assertEquals(ARRAY_SIZE, array.length);
+ }
+
+ private int[] zeroHiData() {
+ int[] array = new int[ARRAY_SIZE];
+
+ int threeQuarters = (int) (ARRAY_SIZE * 0.75);
+ for (int i = 0; i < threeQuarters; i++) {
+ array[i] = 0;
+ }
+ int k = 1;
+ for (int i = threeQuarters; i < ARRAY_SIZE; i++) {
+ array[i] = k;
+ k++;
+ }
+
+ return array;
+ }
+
+ private int[] hiZeroLowData() {
+ int[] array = new int[ARRAY_SIZE];
+
+ int oneThird = ARRAY_SIZE / 3;
+ for (int i = 0; i < oneThird; i++) {
+ array[i] = i;
+ }
+ int twoThirds = oneThird * 2;
+ for (int i = oneThird; i < twoThirds; i++) {
+ array[i] = 0;
+ }
+ for (int i = twoThirds; i < ARRAY_SIZE; i++) {
+ array[i] = oneThird - i + twoThirds;
+ }
+ return array;
+ }
+
+ private int[] highFlatLowData() {
+ int[] array = new int[ARRAY_SIZE];
+
+ int oneThird = ARRAY_SIZE / 3;
+ for (int i = 0; i < oneThird; i++) {
+ array[i] = i;
+ }
+ int twoThirds = oneThird * 2;
+ int constant = oneThird - 1;
+ for (int i = oneThird; i < twoThirds; i++) {
+ array[i] = constant;
+ }
+ for (int i = twoThirds; i < ARRAY_SIZE; i++) {
+ array[i] = constant - i + twoThirds;
+ }
+
+ return array;
+ }
+
+ private int[] identicalData() {
+ int[] array = new int[ARRAY_SIZE];
+ int listNumber = 24;
+
+ for (int i = 0; i < ARRAY_SIZE; i++) {
+ array[i] = listNumber;
+ }
+
+ return array;
+ }
+
+ private int[] endLessThanData() {
+ int[] array = new int[ARRAY_SIZE];
+
+ for (int i = 0; i < ARRAY_SIZE - 1; i++) {
+ array[i] = 3;
+ }
+ array[ARRAY_SIZE - 1] = 1;
+
+ return array;
+ }
+
+ private int[] sortedReversedSortedData() {
+ int[] array = new int[ARRAY_SIZE];
+
+ for (int i = 0; i < ARRAY_SIZE / 2; i++) {
+ array[i] = i;
+ }
+ int num = 0;
+ for (int i = ARRAY_SIZE / 2; i < ARRAY_SIZE; i++) {
+ array[i] = ARRAY_SIZE - num;
+ num++;
+ }
+
+ return array;
+ }
+
+ private int[] pairFlipData() {
+ int[] array = new int[ARRAY_SIZE];
+
+ for (int i = 0; i < ARRAY_SIZE; i++) {
+ array[i] = i;
+ }
+ for (int i = 0; i < ARRAY_SIZE; i += 2) {
+ int temp = array[i];
+ array[i] = array[i + 1];
+ array[i + 1] = temp;
+ }
+
+ return array;
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/java/util/PropertyPermission/PropertyPermissionCollection.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PropertyPermission/PropertyPermissionCollection.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for PropertyPermissionCollection subclass
+ */
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+import java.util.PropertyPermission;
+
+public class PropertyPermissionCollection {
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ PropertyPermission perm = new PropertyPermission("user.home", "read");
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println
+ ("test 1: add throws IllegalArgExc for wrong perm type");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong perm type");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println
+ ("test 3: implies returns true for match on name and action");
+ perms.add(new PropertyPermission("user.home", "read"));
+ if (!perms.implies(new PropertyPermission("user.home", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println
+ ("test 4: implies returns false for match on name but not action");
+ if (perms.implies(new PropertyPermission("user.home", "write"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println("test 5: implies returns true for match " +
+ "on name and subset of actions");
+ perms.add(new PropertyPermission("java.home", "read, write"));
+ if (!perms.implies(new PropertyPermission("java.home", "write"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 6
+ System.out.println("test 6: implies returns true for aggregate " +
+ "match on name and action");
+ perms.add(new PropertyPermission("user.name", "read"));
+ perms.add(new PropertyPermission("user.name", "write"));
+ if (!perms.implies(new PropertyPermission("user.name", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+ if (!perms.implies(new PropertyPermission("user.name", "write,read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 7
+ System.out.println("test 7: implies returns true for wildcard " +
+ "and match on action");
+ perms.add(new PropertyPermission("foo.*", "read"));
+ if (!perms.implies(new PropertyPermission("foo.bar", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println("test 8: implies returns true for deep " +
+ "wildcard and match on action");
+ if (!perms.implies(new PropertyPermission("foo.bar.baz", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println
+ ("test 8: implies returns false for invalid wildcard");
+ perms.add(new PropertyPermission("baz*", "read"));
+ if (perms.implies(new PropertyPermission("baz.foo", "read"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 9
+ System.out.println("test 9: implies returns true for all " +
+ "wildcard and match on action");
+ perms.add(new PropertyPermission("*", "read"));
+ if (!perms.implies(new PropertyPermission("java.version", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 10
+ System.out.println("test 10: implies returns false for wildcard " +
+ "and non-match on action");
+ if (perms.implies(new PropertyPermission("java.version", "write"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 11
+ System.out.println("test 11: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ // the 2 user.name permissions added were combined into one
+ if (numPerms != 6) {
+ System.err.println("Expected 6, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSBufferOverflowUnderflowTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSBufferOverflowUnderflowTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS buffer overflow and underflow status when dealing with
+ * application data.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm DTLSBufferOverflowUnderflowTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm_sni DTLSBufferOverflowUnderflowTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=krb DTLSBufferOverflowUnderflowTest
+ */
+
+/**
+ * Testing DTLS incorrect app data packages unwrapping.
+ */
+public class DTLSBufferOverflowUnderflowTest {
+ public static void main(String[] args) {
+ BufferOverflowUnderflowTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSDataExchangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSDataExchangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS application data exchange using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm DTLSDataExchangeTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm_sni DTLSDataExchangeTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=krb DTLSDataExchangeTest
+ */
+
+/**
+ * Testing DTLS application data exchange using each of the supported cipher
+ * suites.
+ */
+public class DTLSDataExchangeTest {
+ public static void main(String[] args) {
+ DataExchangeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSEnginesClosureTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSEnginesClosureTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines closing using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm DTLSEnginesClosureTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm_sni DTLSEnginesClosureTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=krb DTLSEnginesClosureTest
+ */
+
+/**
+ * Testing DTLS engines closing using each of the supported cipher suites.
+ */
+public class DTLSEnginesClosureTest {
+ public static void main(String[] args) {
+ EnginesClosureTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSHandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSHandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines handshake using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm DTLSHandshakeTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm_sni DTLSHandshakeTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=krb DTLSHandshakeTest
+ */
+
+/**
+ * Testing DTLS engines handshake using each of the supported cipher suites.
+ */
+public class DTLSHandshakeTest {
+ public static void main(String[] args) {
+ HandshakeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSHandshakeWithReplicatedPacketsTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSHandshakeWithReplicatedPacketsTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines handshake using each of the supported
+ * cipher suites with replicated packets check.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm DTLSHandshakeWithReplicatedPacketsTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm_sni DTLSHandshakeWithReplicatedPacketsTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=krb DTLSHandshakeWithReplicatedPacketsTest
+ */
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+
+/**
+ * Testing DTLS engines handshake using each of the supported cipher suites with
+ * replicated packets check.
+ */
+public class DTLSHandshakeWithReplicatedPacketsTest extends SSLEngineTestCase {
+
+ private static String testMode;
+
+ public static void main(String[] args) {
+ DTLSHandshakeWithReplicatedPacketsTest test
+ = new DTLSHandshakeWithReplicatedPacketsTest();
+ setUpAndStartKDCIfNeeded();
+ test.runTests();
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) throws SSLException {
+ SSLContext context = getContext();
+ int maxPacketSize = getMaxPacketSize();
+ boolean useSNI = !TEST_MODE.equals("norm");
+ SSLEngine clientEngine = getClientSSLEngine(context, useSNI);
+ SSLEngine serverEngine = getServerSSLEngine(context, useSNI);
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setNeedClientAuth(!cipher.contains("anon"));
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.INITIAL_HANDSHAKE, true);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSIncorrectAppDataTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSIncorrectAppDataTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS incorrect app data packages unwrapping.
+ * @key randomness
+ * @library /sun/security/krb5/auto /lib/testlibrary /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm DTLSIncorrectAppDataTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm_sni DTLSIncorrectAppDataTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=krb DTLSIncorrectAppDataTest
+ */
+
+import java.nio.ByteBuffer;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+import java.util.Random;
+import jdk.testlibrary.RandomFactory;
+
+/**
+ * Testing DTLS incorrect app data packages unwrapping. Incorrect application
+ * data packages should be ignored by DTLS SSLEngine.
+ */
+public class DTLSIncorrectAppDataTest extends SSLEngineTestCase {
+
+ private final String MESSAGE = "Hello peer!";
+
+ public static void main(String[] s) {
+ DTLSIncorrectAppDataTest test = new DTLSIncorrectAppDataTest();
+ setUpAndStartKDCIfNeeded();
+ test.runTests();
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) {
+ SSLContext context = getContext();
+ int maxPacketSize = getMaxPacketSize();
+ boolean useSNI = !TEST_MODE.equals("norm");
+ SSLEngine clientEngine = getClientSSLEngine(context, useSNI);
+ SSLEngine serverEngine = getServerSSLEngine(context, useSNI);
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setNeedClientAuth(!cipher.contains("anon"));
+ try {
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.INITIAL_HANDSHAKE);
+ checkIncorrectAppDataUnwrap(clientEngine, serverEngine);
+ checkIncorrectAppDataUnwrap(serverEngine, clientEngine);
+ } catch (SSLException ssle) {
+ throw new AssertionError("Error during handshake or sending app data",
+ ssle);
+ }
+ }
+
+ private void checkIncorrectAppDataUnwrap(SSLEngine sendEngine,
+ SSLEngine recvEngine) throws SSLException {
+ String direction = sendEngine.getUseClientMode() ? "client"
+ : "server";
+ System.out.println("================================================="
+ + "===========");
+ System.out.println("Testing DTLS incorrect app data packages unwrapping"
+ + " by sending data from " + direction);
+ ByteBuffer app = ByteBuffer.wrap(MESSAGE.getBytes());
+ ByteBuffer net = doWrap(sendEngine, direction, 0, app);
+ final Random RNG = RandomFactory.getRandom();
+ int randomPlace = RNG.nextInt(net.remaining());
+ net.array()[randomPlace] += 1;
+ app = ByteBuffer.allocate(recvEngine.getSession()
+ .getApplicationBufferSize());
+ recvEngine.unwrap(net, app);
+ app.flip();
+ int length = app.remaining();
+ System.out.println("Unwrapped " + length + " bytes.");
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSMFLNTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSMFLNTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines handshake using each of the supported
+ * cipher suites with different maximum fragment length. Testing of
+ * MFLN extension.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm DTLSMFLNTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm_sni DTLSMFLNTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=krb DTLSMFLNTest
+ */
+
+/**
+ * Testing DTLS engines handshake using each of the supported cipher suites with
+ * different maximum fragment length. Testing of MFLN extension.
+ */
+public class DTLSMFLNTest {
+ public static void main(String[] args) {
+ MFLNTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSNotEnabledRC4Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSNotEnabledRC4Test.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines do not enable RC4 ciphers by default.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS DTLSNotEnabledRC4Test
+ */
+
+/**
+ * Testing DTLS engines do not enable RC4 ciphers by default.
+ */
+public class DTLSNotEnabledRC4Test {
+ public static void main(String[] args) throws Exception {
+ NotEnabledRC4Test.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSRehandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSRehandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines re-handshaking using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm DTLSRehandshakeTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm_sni DTLSRehandshakeTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=krb DTLSRehandshakeTest
+ */
+
+/**
+ * Testing DTLS engines re-handshaking using each of the supported cipher
+ * suites.
+ */
+public class DTLSRehandshakeTest {
+ public static void main(String[] args) {
+ RehandshakeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSRehandshakeWithCipherChangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSRehandshakeWithCipherChangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines re-handshaking with cipher change. New cipher
+ * is taken randomly from the supporetd ciphers list.
+ * @key randomness
+ * @library /sun/security/krb5/auto /lib/testlibrary /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * DTLSRehandshakeWithCipherChangeTest
+ */
+
+/**
+ * Testing DTLS engines re-handshaking with cipher change. New cipher is taken
+ * randomly from the supported ciphers list.
+ */
+public class DTLSRehandshakeWithCipherChangeTest {
+ public static void main(String[] args) {
+ RehandshakeWithCipherChangeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSRehandshakeWithDataExTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSRehandshakeWithDataExTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines re-handshaking using each of the supported
+ * cipher suites with application data exchange before and after
+ * re-handshake and closing of the engines.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm DTLSRehandshakeWithDataExTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm_sni DTLSRehandshakeWithDataExTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=krb DTLSRehandshakeWithDataExTest
+ */
+
+/**
+ * Testing DTLS engines re-handshaking using each of the supported cipher suites
+ * with application data exchange before and after re-handshake and closing of
+ * the engines.
+ */
+public class DTLSRehandshakeWithDataExTest {
+ public static void main(String[] args) {
+ RehandshakeWithDataExTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSSequenceNumberTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSSequenceNumberTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS records sequence number property support in application
+ * data exchange.
+ * @key randomness
+ * @library /sun/security/krb5/auto /lib/testlibrary /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm DTLSSequenceNumberTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=norm_sni DTLSSequenceNumberTest
+ * @run main/othervm -Dtest.security.protocol=DTLS
+ * -Dtest.mode=krb DTLSSequenceNumberTest
+ */
+
+import java.nio.ByteBuffer;
+import java.util.TreeMap;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+import java.util.Random;
+import jdk.testlibrary.RandomFactory;
+
+/**
+ * Testing DTLS records sequence number property support in application data
+ * exchange.
+ */
+public class DTLSSequenceNumberTest extends SSLEngineTestCase {
+
+ private final String BIG_MESSAGE = "Very very big message. One two three"
+ + " four five six seven eight nine ten eleven twelve thirteen"
+ + " fourteen fifteen sixteen seventeen eighteen nineteen twenty.";
+ private final byte[] BIG_MESSAGE_BYTES = BIG_MESSAGE.getBytes();
+ private final int PIECES_NUMBER = 15;
+
+ public static void main(String[] args) {
+ DTLSSequenceNumberTest test = new DTLSSequenceNumberTest();
+ setUpAndStartKDCIfNeeded();
+ test.runTests();
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) throws SSLException {
+ SSLContext context = getContext();
+ int maxPacketSize = getMaxPacketSize();
+ boolean useSNI = !TEST_MODE.equals("norm");
+ SSLEngine clientEngine = getClientSSLEngine(context, useSNI);
+ SSLEngine serverEngine = getServerSSLEngine(context, useSNI);
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setNeedClientAuth(!cipher.contains("anon"));
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.INITIAL_HANDSHAKE);
+ checkSeqNumPropertyWithAppDataSend(clientEngine, serverEngine);
+ checkSeqNumPropertyWithAppDataSend(serverEngine, clientEngine);
+ }
+
+ private void checkSeqNumPropertyWithAppDataSend(SSLEngine sendEngine,
+ SSLEngine recvEngine) throws SSLException {
+ String sender, reciever;
+ if (sendEngine.getUseClientMode() && !recvEngine.getUseClientMode()) {
+ sender = "Client";
+ reciever = "Server";
+ } else if (recvEngine.getUseClientMode() && !sendEngine.getUseClientMode()) {
+ sender = "Server";
+ reciever = "Client";
+ } else {
+ throw new Error("Both engines are in the same mode");
+ }
+ System.out.println("================================================="
+ + "===========");
+ System.out.println("Checking DTLS sequence number support"
+ + " by sending data from " + sender + " to " + reciever);
+ ByteBuffer[] sentMessages = new ByteBuffer[PIECES_NUMBER];
+ ByteBuffer[] netBuffers = new ByteBuffer[PIECES_NUMBER];
+ TreeMap recvMap = new TreeMap<>(Long::compareUnsigned);
+ int symbolsInAMessage;
+ int symbolsInTheLastMessage;
+ int[] recievingSequence = new int[PIECES_NUMBER];
+ for (int i = 0; i < PIECES_NUMBER; i++) {
+ recievingSequence[i] = i;
+ }
+ shuffleArray(recievingSequence);
+ if (BIG_MESSAGE.length() % PIECES_NUMBER == 0) {
+ symbolsInAMessage = BIG_MESSAGE.length() / PIECES_NUMBER;
+ symbolsInTheLastMessage = symbolsInAMessage;
+ } else {
+ symbolsInAMessage = BIG_MESSAGE.length() / (PIECES_NUMBER - 1);
+ symbolsInTheLastMessage = BIG_MESSAGE.length() % (PIECES_NUMBER - 1);
+ }
+ for (int i = 0; i < PIECES_NUMBER - 1; i++) {
+ sentMessages[i] = ByteBuffer.wrap(BIG_MESSAGE_BYTES,
+ i * symbolsInAMessage, symbolsInAMessage);
+ }
+ sentMessages[PIECES_NUMBER - 1] = ByteBuffer.wrap(BIG_MESSAGE_BYTES,
+ (PIECES_NUMBER - 1) * symbolsInAMessage, symbolsInTheLastMessage);
+ long prevSeqNum = 0L;
+ //Wrapping massages in direct order
+ for (int i = 0; i < PIECES_NUMBER; i++) {
+ netBuffers[i] = ByteBuffer.allocate(sendEngine.getSession()
+ .getPacketBufferSize());
+ SSLEngineResult[] r = new SSLEngineResult[1];
+ netBuffers[i] = doWrap(sendEngine, sender, 0, sentMessages[i], r);
+ long seqNum = r[0].sequenceNumber();
+ if (Long.compareUnsigned(seqNum, prevSeqNum) <= 0) {
+ throw new AssertionError("Sequence number of the wrapped "
+ + "message is less or equal than that of the"
+ + " previous one! "
+ + "Was " + prevSeqNum + ", now " + seqNum + ".");
+ }
+ prevSeqNum = seqNum;
+ }
+ //Unwrapping messages in random order and trying to reconstruct order
+ //from sequence number.
+ for (int i = 0; i < PIECES_NUMBER; i++) {
+ int recvNow = recievingSequence[i];
+ SSLEngineResult[] r = new SSLEngineResult[1];
+ ByteBuffer recvMassage = doUnWrap(recvEngine, reciever,
+ netBuffers[recvNow], r);
+ long seqNum = r[0].sequenceNumber();
+ recvMap.put(seqNum, recvMassage);
+ }
+ int mapSize = recvMap.size();
+ if (mapSize != PIECES_NUMBER) {
+ throw new AssertionError("The number of received massages "
+ + mapSize + " is not equal to the number of sent messages "
+ + PIECES_NUMBER + "!");
+ }
+ byte[] recvBigMsgBytes = new byte[BIG_MESSAGE_BYTES.length];
+ int counter = 0;
+ for (ByteBuffer msg : recvMap.values()) {
+ System.arraycopy(msg.array(), 0, recvBigMsgBytes,
+ counter * symbolsInAMessage, msg.remaining());
+ counter++;
+ }
+ String recvBigMsg = new String(recvBigMsgBytes);
+ if (!recvBigMsg.equals(BIG_MESSAGE)) {
+ throw new AssertionError("Received big message is not equal to"
+ + " one that was sent! Received message is: " + recvBigMsg);
+ }
+ }
+
+ private static void shuffleArray(int[] ar) {
+ final Random RNG = RandomFactory.getRandom();
+ for (int i = ar.length - 1; i > 0; i--) {
+ int index = RNG.nextInt(i + 1);
+ int a = ar[index];
+ ar[index] = ar[i];
+ ar[i] = a;
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/DTLSUnsupportedCiphersTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSUnsupportedCiphersTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing that try to enable unsupported ciphers
+ * causes IllegalArgumentException.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLS DTLSUnsupportedCiphersTest
+ */
+
+/**
+ * Testing that a try to enable unsupported ciphers causes IllegalArgumentException.
+ */
+public class DTLSUnsupportedCiphersTest {
+ public static void main(String[] args) {
+ UnsupportedCiphersTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLS/TEST.properties
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLS/TEST.properties Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,1 @@
+modules=java.base java.security.jgss
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10BufferOverflowUnderflowTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10BufferOverflowUnderflowTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS buffer overflow and underflow status when dealing with
+ * application data.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm DTLSv10BufferOverflowUnderflowTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm_sni DTLSv10BufferOverflowUnderflowTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=krb DTLSv10BufferOverflowUnderflowTest
+ */
+
+/**
+ * Testing DTLS incorrect app data packages unwrapping.
+ */
+public class DTLSv10BufferOverflowUnderflowTest {
+ public static void main(String[] args) {
+ BufferOverflowUnderflowTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10DataExchangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10DataExchangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS application data exchange using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm DTLSv10DataExchangeTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm_sni DTLSv10DataExchangeTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=krb DTLSv10DataExchangeTest
+ */
+
+/**
+ * Testing DTLS application data exchange using each of the supported cipher
+ * suites.
+ */
+public class DTLSv10DataExchangeTest {
+ public static void main(String[] args) {
+ DataExchangeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10EnginesClosureTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10EnginesClosureTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines closing using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm DTLSv10EnginesClosureTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm_sni DTLSv10EnginesClosureTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=krb DTLSv10EnginesClosureTest
+ */
+
+/**
+ * Testing DTLS engines closing using each of the supported cipher suites.
+ */
+public class DTLSv10EnginesClosureTest {
+ public static void main(String[] args) {
+ EnginesClosureTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10HandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10HandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines handshake using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm DTLSv10HandshakeTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm_sni DTLSv10HandshakeTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=krb DTLSv10HandshakeTest
+ */
+
+/**
+ * Testing DTLS engines handshake using each of the supported cipher suites.
+ */
+public class DTLSv10HandshakeTest {
+ public static void main(String[] args) {
+ HandshakeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10HandshakeWithReplicatedPacketsTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10HandshakeWithReplicatedPacketsTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines handshake using each of the supported
+ * cipher suites with replicated packets check.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon /javax/net/ssl/DTLS
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm DTLSv10HandshakeWithReplicatedPacketsTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm_sni DTLSv10HandshakeWithReplicatedPacketsTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=krb DTLSv10HandshakeWithReplicatedPacketsTest
+ */
+
+/**
+ * Testing DTLS engines handshake using each of the supported cipher suites with
+ * replicated packets check.
+ */
+public class DTLSv10HandshakeWithReplicatedPacketsTest {
+ public static void main(String[] args) {
+ DTLSHandshakeWithReplicatedPacketsTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10IncorrectAppDataTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10IncorrectAppDataTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS incorrect app data packages unwrapping.
+ * @key randomness
+ * @library /sun/security/krb5/auto /lib/testlibrary /javax/net/ssl/TLSCommon /javax/net/ssl/DTLS
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm DTLSIncorrectAppDataTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm_sni DTLSIncorrectAppDataTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=krb DTLSIncorrectAppDataTest
+ */
+
+/**
+ * Testing DTLS incorrect app data packages unwrapping. Incorrect application
+ * data packages should be ignored by DTLS SSLEngine.
+ */
+public class DTLSv10IncorrectAppDataTest {
+ public static void main(String[] args) {
+ DTLSIncorrectAppDataTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10MFLNTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10MFLNTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines handshake using each of the supported
+ * cipher suites with different maximum fragment length. Testing of
+ * MFLN extension.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm DTLSv10MFLNTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm_sni DTLSv10MFLNTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=krb DTLSv10MFLNTest
+ */
+
+/**
+ * Testing DTLS engines handshake using each of the supported cipher suites with
+ * different maximum fragment length. Testing of MFLN extension.
+ */
+public class DTLSv10MFLNTest {
+ public static void main(String[] args) {
+ MFLNTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10NotEnabledRC4Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10NotEnabledRC4Test.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines do not enable RC4 ciphers by default.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0 DTLSv10NotEnabledRC4Test
+ */
+
+/**
+ * Testing DTLS engines do not enable RC4 ciphers by default.
+ */
+public class DTLSv10NotEnabledRC4Test {
+ public static void main(String[] args) throws Exception {
+ NotEnabledRC4Test.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10RehandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10RehandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines re-handshaking using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm DTLSv10RehandshakeTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm_sni DTLSv10RehandshakeTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=krb DTLSv10RehandshakeTest
+ */
+
+/**
+ * Testing DTLS engines re-handshaking using each of the supported cipher
+ * suites.
+ */
+public class DTLSv10RehandshakeTest {
+ public static void main(String[] args) {
+ RehandshakeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10RehandshakeWithCipherChangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10RehandshakeWithCipherChangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines re-handshaking with cipher change. New cipher
+ * is taken randomly from the supporetd ciphers list.
+ * @key randomness
+ * @library /sun/security/krb5/auto /lib/testlibrary /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * DTLSv10RehandshakeWithCipherChangeTest
+ */
+
+/**
+ * Testing DTLS engines re-handshaking with cipher change. New cipher is taken
+ * randomly from the supported ciphers list.
+ */
+public class DTLSv10RehandshakeWithCipherChangeTest {
+ public static void main(String[] args) {
+ RehandshakeWithCipherChangeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10RehandshakeWithDataExTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10RehandshakeWithDataExTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS engines re-handshaking using each of the supported
+ * cipher suites with application data exchange before and after
+ * re-handshake and closing of the engines.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm DTLSv10RehandshakeWithDataExTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm_sni DTLSv10RehandshakeWithDataExTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=krb DTLSv10RehandshakeWithDataExTest
+ */
+
+/**
+ * Testing DTLS engines re-handshaking using each of the supported cipher suites
+ * with application data exchange before and after re-handshake and closing of
+ * the engines.
+ */
+public class DTLSv10RehandshakeWithDataExTest {
+ public static void main(String[] args) {
+ RehandshakeWithDataExTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10SequenceNumberTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10SequenceNumberTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing DTLS records sequence number property support in application
+ * data exchange.
+ * @key randomness
+ * @library /sun/security/krb5/auto /lib/testlibrary /javax/net/ssl/TLSCommon /javax/net/ssl/DTLS
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm DTLSv10SequenceNumberTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=norm_sni DTLSv10SequenceNumberTest
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * -Dtest.mode=krb DTLSv10SequenceNumberTest
+ */
+
+/**
+ * Testing DTLS records sequence number property support in application data
+ * exchange.
+ */
+public class DTLSv10SequenceNumberTest {
+ public static void main(String[] args) {
+ DTLSHandshakeWithReplicatedPacketsTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/DTLSv10UnsupportedCiphersTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/DTLSv10UnsupportedCiphersTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043758
+ * @summary Testing that try to enable unsupported ciphers
+ * causes IllegalArgumentException.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=DTLSv1.0
+ * DTLSv10UnsupportedCiphersTest
+ */
+
+/**
+ * Testing that a try to enable unsupported ciphers causes IllegalArgumentException.
+ */
+public class DTLSv10UnsupportedCiphersTest {
+ public static void main(String[] args) {
+ UnsupportedCiphersTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/DTLSv10/TEST.properties
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/DTLSv10/TEST.properties Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,1 @@
+modules=java.base java.security.jgss
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLS/TLSDataExchangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/TLSDataExchangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS application data exchange using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm TLSDataExchangeTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm_sni TLSDataExchangeTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=krb TLSDataExchangeTest
+ */
+
+/**
+ * Testing TLS application data exchange using each of the supported cipher
+ * suites.
+ */
+public class TLSDataExchangeTest {
+ public static void main(String[] args) {
+ DataExchangeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLS/TLSEnginesClosureTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/TLSEnginesClosureTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines closing using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm TLSEnginesClosureTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm_sni TLSEnginesClosureTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=krb TLSEnginesClosureTest
+ */
+
+/**
+ * Testing TLS engines closing using each of the supported cipher suites.
+ */
+public class TLSEnginesClosureTest {
+ public static void main(String[] args) {
+ EnginesClosureTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLS/TLSHandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/TLSHandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines handshake using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm TLSHandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm_sni TLSHandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=krb TLSHandshakeTest
+ */
+
+/**
+ * Testing TLS engines handshake using each of the supported cipher suites.
+ */
+public class TLSHandshakeTest {
+ public static void main(String[] args) {
+ HandshakeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLS/TLSMFLNTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/TLSMFLNTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines handshake using each of the supported
+ * cipher suites with different maximum fragment length. Testing of
+ * MFLN extension.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm TLSMFLNTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm_sni TLSMFLNTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=krb TLSMFLNTest
+ */
+
+/**
+ * Testing TLS engines handshake using each of the supported cipher suites with
+ * different maximum fragment length. Testing of MFLN extension.
+ */
+public class TLSMFLNTest {
+ public static void main(String[] args) {
+ MFLNTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLS/TLSNotEnabledRC4Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/TLSNotEnabledRC4Test.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines do not enable RC4 ciphers by default.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLS TLSNotEnabledRC4Test
+ */
+
+/**
+ * Testing DTLS engines do not enable RC4 ciphers by default.
+ */
+public class TLSNotEnabledRC4Test {
+ public static void main(String[] args) throws Exception {
+ NotEnabledRC4Test.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLS/TLSRehandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/TLSRehandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines re-handshaking using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm TLSRehandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm_sni TLSRehandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=krb TLSRehandshakeTest
+ */
+
+/**
+ * Testing TLS engines re-handshaking using each of the supported cipher
+ * suites.
+ */
+public class TLSRehandshakeTest {
+ public static void main(String[] args) {
+ RehandshakeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLS/TLSRehandshakeWithCipherChangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/TLSRehandshakeWithCipherChangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines re-handshaking with cipher change. New cipher
+ * is taken randomly from the supporetd ciphers list.
+ * @key randomness
+ * @library /sun/security/krb5/auto /lib/testlibrary /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLS TLSRehandshakeWithCipherChangeTest
+ */
+
+/**
+ * Testing TLS engines re-handshaking with cipher change. New cipher is taken
+ * randomly from the supported ciphers list.
+ */
+public class TLSRehandshakeWithCipherChangeTest {
+ public static void main(String[] args) {
+ RehandshakeWithCipherChangeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLS/TLSRehandshakeWithDataExTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/TLSRehandshakeWithDataExTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines re-handshaking using each of the supported
+ * cipher suites with application data exchange before and after
+ * re-handshake and closing of the engines.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm TLSRehandshakeWithDataExTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=norm_sni TLSRehandshakeWithDataExTest
+ * @run main/othervm -Dtest.security.protocol=TLS -Dtest.mode=krb TLSRehandshakeWithDataExTest
+ */
+
+/**
+ * Testing TLS engines re-handshaking using each of the supported cipher suites
+ * with application data exchange before and after re-handshake and closing of
+ * the engines.
+ */
+public class TLSRehandshakeWithDataExTest {
+ public static void main(String[] args) {
+ RehandshakeWithDataExTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLS/TLSUnsupportedCiphersTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/TLSUnsupportedCiphersTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing that try to enable unsupported ciphers
+ * causes IllegalArgumentException.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLS TLSUnsupportedCiphersTest
+ */
+
+/**
+ * Testing that a try to enable unsupported ciphers causes IllegalArgumentException.
+ */
+public class TLSUnsupportedCiphersTest {
+ public static void main(String[] args) {
+ UnsupportedCiphersTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/BufferOverflowUnderflowTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/BufferOverflowUnderflowTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.ByteBuffer;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+
+/**
+ * Testing SSLEngine incorrect app data packages unwrapping.
+ */
+public class BufferOverflowUnderflowTest extends SSLEngineTestCase {
+
+ private final String MESSAGE = "Hello peer!";
+
+ public static void main(String[] args) {
+ BufferOverflowUnderflowTest test = new BufferOverflowUnderflowTest();
+ setUpAndStartKDCIfNeeded();
+ test.runTests();
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) throws SSLException {
+ SSLContext context = getContext();
+ int maxPacketSize = getMaxPacketSize();
+ boolean useSNI = !TEST_MODE.equals("norm");
+ SSLEngine clientEngine = getClientSSLEngine(context, useSNI);
+ SSLEngine serverEngine = getServerSSLEngine(context, useSNI);
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setNeedClientAuth(!cipher.contains("anon"));
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.INITIAL_HANDSHAKE);
+ checkBufferOverflowOnWrap(clientEngine);
+ checkBufferOverflowOnWrap(serverEngine);
+ checkBufferOverflowOnUnWrap(clientEngine, serverEngine);
+ checkBufferOverflowOnUnWrap(serverEngine, clientEngine);
+ checkBufferUnderflowOnUnWrap(serverEngine, clientEngine);
+ checkBufferUnderflowOnUnWrap(clientEngine, serverEngine);
+ }
+
+ private void checkBufferOverflowOnWrap(SSLEngine engine)
+ throws SSLException {
+ String mode = engine.getUseClientMode() ? "client"
+ : "server";
+ System.out.println("================================================="
+ + "===========");
+ System.out.println("Testing SSLEngine buffer overflow"
+ + " on wrap by " + mode);
+ ByteBuffer app = ByteBuffer.wrap(MESSAGE.getBytes());
+ //Making net buffer size less than required by 1 byte.
+ ByteBuffer net = ByteBuffer
+ .allocate(engine.getSession().getPacketBufferSize() - 1);
+ SSLEngineResult r = engine.wrap(app, net);
+ checkResult(r, SSLEngineResult.Status.BUFFER_OVERFLOW);
+ System.out.println("Passed");
+ }
+
+ private void checkBufferOverflowOnUnWrap(SSLEngine wrappingEngine,
+ SSLEngine unwrappingEngine)
+ throws SSLException {
+ String wrapperMode = wrappingEngine.getUseClientMode() ? "client"
+ : "server";
+ String unwrapperMode = unwrappingEngine.getUseClientMode() ? "client"
+ : "server";
+ if (wrapperMode.equals(unwrapperMode)) {
+ throw new Error("Test error: both engines are in the same mode!");
+ }
+ System.out.println("================================================="
+ + "===========");
+ System.out.println("Testing SSLEngine buffer overflow"
+ + " on unwrap by " + unwrapperMode);
+ ByteBuffer app = ByteBuffer.wrap(MESSAGE.getBytes());
+ ByteBuffer net = ByteBuffer
+ .allocate(wrappingEngine.getSession().getPacketBufferSize());
+ SSLEngineResult r = wrappingEngine.wrap(app, net);
+ checkResult(r, SSLEngineResult.Status.OK);
+ //Making app buffer size less than required by 1 byte.
+ app = ByteBuffer.allocate(MESSAGE.length() - 1);
+ net.flip();
+ r = unwrappingEngine.unwrap(net, app);
+ checkResult(r, SSLEngineResult.Status.BUFFER_OVERFLOW);
+ System.out.println("Passed");
+ }
+
+ private void checkBufferUnderflowOnUnWrap(SSLEngine wrappingEngine,
+ SSLEngine unwrappingEngine)
+ throws SSLException {
+ String wrapperMode = wrappingEngine.getUseClientMode() ? "client"
+ : "server";
+ String unwrapperMode = unwrappingEngine.getUseClientMode() ? "client"
+ : "server";
+ if (wrapperMode.equals(unwrapperMode)) {
+ throw new Error("Test error: both engines are in the same mode!");
+ }
+ System.out.println("================================================="
+ + "===========");
+ System.out.println("Testing SSLEngine buffer underflow"
+ + " on unwrap by " + unwrapperMode);
+ ByteBuffer app = ByteBuffer.wrap(MESSAGE.getBytes());
+ ByteBuffer net = ByteBuffer
+ .allocate(wrappingEngine.getSession().getPacketBufferSize());
+ SSLEngineResult r = wrappingEngine.wrap(app, net);
+ checkResult(r, SSLEngineResult.Status.OK);
+ app = ByteBuffer.allocate(unwrappingEngine.getSession()
+ .getApplicationBufferSize());
+ net.flip();
+ //Making net buffer size less than size of dtls message.
+ net.limit(net.limit() - 1);
+ r = unwrappingEngine.unwrap(net, app);
+ checkResult(r, SSLEngineResult.Status.BUFFER_UNDERFLOW);
+ System.out.println("Passed");
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/DataExchangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/DataExchangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+
+/**
+ * Testing SSLEngine application data exchange using each of the supported cipher
+ * suites.
+ */
+public class DataExchangeTest extends SSLEngineTestCase {
+
+ public static void main(String[] args) {
+ DataExchangeTest test = new DataExchangeTest();
+ setUpAndStartKDCIfNeeded();
+ test.runTests();
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) throws SSLException {
+ SSLContext context = getContext();
+ int maxPacketSize = getMaxPacketSize();
+ boolean useSNI = !TEST_MODE.equals("norm");
+ SSLEngine clientEngine = getClientSSLEngine(context, useSNI);
+ SSLEngine serverEngine = getServerSSLEngine(context, useSNI);
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setNeedClientAuth(!cipher.contains("anon"));
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.INITIAL_HANDSHAKE);
+ sendApplicationData(clientEngine, serverEngine);
+ sendApplicationData(serverEngine, clientEngine);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/EnginesClosureTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/EnginesClosureTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+
+/**
+ * Testing SSLEngines closing using each of the supported cipher suites.
+ */
+public class EnginesClosureTest extends SSLEngineTestCase {
+
+ public static void main(String[] args) {
+ EnginesClosureTest test = new EnginesClosureTest();
+ setUpAndStartKDCIfNeeded();
+ test.runTests();
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) throws SSLException {
+ closingTest(cipher, true);
+ closingTest(cipher, false);
+ }
+
+ private void closingTest(String cipher, boolean clientCloses)
+ throws SSLException {
+ SSLContext context = getContext();
+ int maxPacketSize = getMaxPacketSize();
+ boolean useSNI = !TEST_MODE.equals("norm");
+ SSLEngine clientEngine = getClientSSLEngine(context, useSNI);
+ SSLEngine serverEngine = getServerSSLEngine(context, useSNI);
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setNeedClientAuth(!cipher.contains("anon"));
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.INITIAL_HANDSHAKE);
+ if (clientCloses) {
+ closeEngines(clientEngine, serverEngine);
+ } else {
+ closeEngines(serverEngine, clientEngine);
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/HandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/HandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+
+/**
+ * Testing SSLEngines handshake using each of the supported cipher suites.
+ */
+public class HandshakeTest extends SSLEngineTestCase {
+
+ public static void main(String[] args) {
+ HandshakeTest test = new HandshakeTest();
+ setUpAndStartKDCIfNeeded();
+ test.runTests();
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) throws SSLException {
+ SSLContext context = getContext();
+ int maxPacketSize = getMaxPacketSize();
+ boolean useSNI = !TEST_MODE.equals("norm");
+ SSLEngine clientEngine = getClientSSLEngine(context, useSNI);
+ SSLEngine serverEngine = getServerSSLEngine(context, useSNI);
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setNeedClientAuth(!cipher.contains("anon"));
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.INITIAL_HANDSHAKE);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/MFLNTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/MFLNTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+
+/**
+ * Testing SSLEngines handshake using each of the supported cipher suites with
+ * different maximum fragment length. Testing of MFLN extension.
+ */
+public class MFLNTest extends SSLEngineTestCase {
+
+ public static void main(String[] args) {
+ setUpAndStartKDCIfNeeded();
+ System.setProperty("jsse.enableMFLNExtension", "true");
+ for (int mfl = 4096; mfl >= 256; mfl /= 2) {
+ System.out.println("=============================================="
+ + "==============");
+ System.out.printf("Testsing DTLS handshake with MFL = %d%n", mfl);
+ MFLNTest test = new MFLNTest(mfl);
+ test.runTests();
+ }
+ }
+
+ protected MFLNTest(int maxPacketSize) {
+ super(maxPacketSize);
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) throws SSLException {
+ SSLContext context = getContext();
+ int maxPacketSize = getMaxPacketSize();
+ boolean useSNI = !TEST_MODE.equals("norm");
+ SSLEngine clientEngine = getClientSSLEngine(context, useSNI);
+ SSLEngine serverEngine = getServerSSLEngine(context, useSNI);
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setNeedClientAuth(!cipher.contains("anon"));
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.INITIAL_HANDSHAKE);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/NotEnabledRC4Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/NotEnabledRC4Test.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+
+/**
+ * Testing SSLEngines do not enable RC4 ciphers by default.
+ */
+public class NotEnabledRC4Test {
+
+ public static void main(String[] s) throws Exception {
+ SSLContext context = SSLEngineTestCase.getContext();
+ SSLEngine clientEngine = context.createSSLEngine();
+ clientEngine.setUseClientMode(true);
+ SSLEngine serverEngine = context.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+ String[] cliEnabledCiphers = clientEngine.getEnabledCipherSuites();
+ rc4Test(cliEnabledCiphers, true);
+ String[] srvEnabledCiphers = serverEngine.getEnabledCipherSuites();
+ rc4Test(srvEnabledCiphers, false);
+ }
+
+ private static void rc4Test(String[] ciphers, boolean isClient) {
+ String mode = isClient ? "client" : "server";
+ for (String cipher : ciphers) {
+ if (cipher.contains("RC4")) {
+ throw new AssertionError("RC4 cipher " + cipher + " is enabled"
+ + " by default on " + mode + " SSLEngine,"
+ + " but it should not!");
+ }
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/RehandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/RehandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+
+/**
+ * Testing SSLEngines re-handshaking using each of the supported cipher
+ * suites.
+ */
+public class RehandshakeTest extends SSLEngineTestCase {
+
+ public static void main(String[] args) {
+ RehandshakeTest test = new RehandshakeTest();
+ setUpAndStartKDCIfNeeded();
+ test.runTests();
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) throws SSLException {
+ SSLContext context = getContext();
+ int maxPacketSize = getMaxPacketSize();
+ boolean useSNI = !TEST_MODE.equals("norm");
+ SSLEngine clientEngine = getClientSSLEngine(context, useSNI);
+ SSLEngine serverEngine = getServerSSLEngine(context, useSNI);
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setNeedClientAuth(!cipher.contains("anon"));
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.INITIAL_HANDSHAKE);
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.REHANDSHAKE_BEGIN_CLIENT);
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.REHANDSHAKE_BEGIN_SERVER);
+ }
+
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/RehandshakeWithCipherChangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/RehandshakeWithCipherChangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+import java.util.Random;
+import jdk.testlibrary.RandomFactory;
+
+/**
+ * Testing SSLEngines re-handshaking with cipher change. New cipher is taken
+ * randomly from the supported ciphers list.
+ */
+public class RehandshakeWithCipherChangeTest extends SSLEngineTestCase {
+
+ public static void main(String[] s) {
+ RehandshakeWithCipherChangeTest test
+ = new RehandshakeWithCipherChangeTest();
+ test.runTests(Ciphers.ENABLED_NON_KRB_NOT_ANON_CIPHERS);
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) throws SSLException {
+ SSLContext context = getContext();
+ int maxPacketSize = getMaxPacketSize();
+ SSLEngine clientEngine = context.createSSLEngine();
+ clientEngine.setUseClientMode(true);
+ SSLEngine serverEngine = context.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setEnabledCipherSuites(
+ Ciphers.ENABLED_NON_KRB_NOT_ANON_CIPHERS.ciphers);
+ String randomCipher;
+ serverEngine.setNeedClientAuth(true);
+ long initialEpoch = 0;
+ long secondEpoch = 0;
+ SSLEngineResult r;
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.INITIAL_HANDSHAKE);
+ sendApplicationData(clientEngine, serverEngine);
+ r = sendApplicationData(serverEngine, clientEngine);
+ if (TESTED_SECURITY_PROTOCOL.contains("DTLS")) {
+ initialEpoch = r.sequenceNumber() >> 48;
+ }
+ final Random RNG = RandomFactory.getRandom();
+ randomCipher = Ciphers.ENABLED_NON_KRB_NOT_ANON_CIPHERS.ciphers[RNG
+ .nextInt(Ciphers.ENABLED_NON_KRB_NOT_ANON_CIPHERS.ciphers.length)];
+ clientEngine.setEnabledCipherSuites(new String[]{randomCipher});
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.REHANDSHAKE_BEGIN_CLIENT);
+ sendApplicationData(clientEngine, serverEngine);
+ r = sendApplicationData(serverEngine, clientEngine);
+ if (TESTED_SECURITY_PROTOCOL.contains("DTLS")) {
+ secondEpoch = r.sequenceNumber() >> 48;
+ AssertionError epochError = new AssertionError("Epoch number"
+ + " did not grow after re-handshake! "
+ + " Was " + initialEpoch + ", now " + secondEpoch + ".");
+ if (Long.compareUnsigned(secondEpoch, initialEpoch) <= 0) {
+ throw epochError;
+ }
+ }
+ closeEngines(clientEngine, serverEngine);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/RehandshakeWithDataExTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/RehandshakeWithDataExTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+
+/**
+ * Testing SSLEngines re-handshaking using each of the supported cipher suites
+ * with application data exchange before and after re-handshake and closing of
+ * the engines.
+ */
+public class RehandshakeWithDataExTest extends SSLEngineTestCase {
+
+ public static void main(String[] args) {
+ RehandshakeWithDataExTest test = new RehandshakeWithDataExTest();
+ setUpAndStartKDCIfNeeded();
+ test.runTests();
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) throws SSLException {
+ SSLContext context = getContext();
+ int maxPacketSize = getMaxPacketSize();
+ boolean useSNI = !TEST_MODE.equals("norm");
+ SSLEngine clientEngine = getClientSSLEngine(context, useSNI);
+ SSLEngine serverEngine = getServerSSLEngine(context, useSNI);
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setEnabledCipherSuites(new String[]{cipher});
+ serverEngine.setNeedClientAuth(!cipher.contains("anon"));
+ long initialEpoch = 0;
+ long secondEpoch = 0;
+ long thirdEpoch = 0;
+ SSLEngineResult r;
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.INITIAL_HANDSHAKE);
+ sendApplicationData(clientEngine, serverEngine);
+ r = sendApplicationData(serverEngine, clientEngine);
+ if (TESTED_SECURITY_PROTOCOL.contains("DTLS")) {
+ initialEpoch = r.sequenceNumber() >> 48;
+ }
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.REHANDSHAKE_BEGIN_CLIENT);
+ sendApplicationData(clientEngine, serverEngine);
+ r = sendApplicationData(serverEngine, clientEngine);
+ AssertionError epochError = new AssertionError("Epoch number"
+ + " did not grow after re-handshake! "
+ + " Was " + initialEpoch + ", now " + secondEpoch + ".");
+ if (TESTED_SECURITY_PROTOCOL.contains("DTLS")) {
+ secondEpoch = r.sequenceNumber() >> 48;
+ if (Long.compareUnsigned(secondEpoch, initialEpoch) <= 0) {
+ throw epochError;
+ }
+ }
+ doHandshake(clientEngine, serverEngine, maxPacketSize,
+ HandshakeMode.REHANDSHAKE_BEGIN_SERVER);
+ sendApplicationData(clientEngine, serverEngine);
+ r = sendApplicationData(serverEngine, clientEngine);
+ if (TESTED_SECURITY_PROTOCOL.contains("DTLS")) {
+ thirdEpoch = r.sequenceNumber() >> 48;
+ if (Long.compareUnsigned(thirdEpoch, secondEpoch) <= 0) {
+ throw epochError;
+ }
+ }
+ closeEngines(clientEngine, serverEngine);
+ }
+
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/SSLEngineTestCase.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/SSLEngineTestCase.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIMatcher;
+import javax.net.ssl.SNIServerName;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.TrustManagerFactory;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Basic class to inherit SSLEngine test cases from it. Tests apply for
+ * the TLS or DTLS security protocols and their versions.
+ */
+abstract public class SSLEngineTestCase {
+
+ public enum Ciphers {
+
+ /**
+ * Ciphers supported by the tested SSLEngine without those with kerberos
+ * authentication.
+ */
+ SUPPORTED_NON_KRB_CIPHERS(SSLEngineTestCase.SUPPORTED_NON_KRB_CIPHERS,
+ "Supported non kerberos"),
+ /**
+ * Ciphers supported by the tested SSLEngine without those with kerberos
+ * authentication and without those with SHA256 ans SHA384.
+ */
+ SUPPORTED_NON_KRB_NON_SHA_CIPHERS(SSLEngineTestCase.SUPPORTED_NON_KRB_NON_SHA_CIPHERS,
+ "Supported non kerberos non SHA256 and SHA384"),
+ /**
+ * Ciphers supported by the tested SSLEngine with kerberos authentication.
+ */
+ SUPPORTED_KRB_CIPHERS(SSLEngineTestCase.SUPPORTED_KRB_CIPHERS,
+ "Supported kerberos"),
+ /**
+ * Ciphers enabled by default for the tested SSLEngine without kerberos
+ * and anon.
+ */
+ ENABLED_NON_KRB_NOT_ANON_CIPHERS(
+ SSLEngineTestCase.ENABLED_NON_KRB_NOT_ANON_CIPHERS,
+ "Enabled by default non kerberos not anonymous"),
+ /**
+ * Ciphers unsupported by the tested SSLEngine.
+ */
+ UNSUPPORTED_CIPHERS(SSLEngineTestCase.UNSUPPORTED_CIPHERS,
+ "Unsupported");
+
+ Ciphers(String[] ciphers, String description) {
+ this.ciphers = ciphers;
+ this.description = description;
+ }
+
+ final String[] ciphers;
+ final String description;
+ }
+
+ /**
+ * Enumeration used to distinguish handshake mode in
+ * {@link SSLEngineTestCase#doHandshake(javax.net.ssl.SSLEngine,
+ * javax.net.ssl.SSLEngine, int, SSLEngineTestCase.HandshakeMode, boolean)
+ * SSLEngineTestCase.doHandshake} method.
+ */
+ public enum HandshakeMode {
+
+ /**
+ * Initial handshake done for the first time: both engines call
+ * {@link SSLEngine#beginHandshake()} method.
+ */
+ INITIAL_HANDSHAKE,
+ /**
+ * Repeated handshake done by client: client engine calls
+ * {@link SSLEngine#beginHandshake()} method.
+ */
+ REHANDSHAKE_BEGIN_CLIENT,
+ /**
+ * Repeated handshake done by server: server engine calls
+ * {@link SSLEngine#beginHandshake()} method.
+ */
+ REHANDSHAKE_BEGIN_SERVER;
+ }
+ /**
+ * Security protocol to be tested: "TLS" or "DTLS" or their versions,
+ * e.g. "TLSv1", "TLSv1.1", "TLSv1.2", "DTLSv1.0", "DTLSv1.2".
+ */
+ public static final String TESTED_SECURITY_PROTOCOL
+ = System.getProperty("test.security.protocol", "TLS");
+ /**
+ * Test mode: "norm", "norm_sni" or "krb".
+ * Modes "norm" and "norm_sni" are used to run
+ * with all supported non-kerberos ciphers.
+ * Mode "krb" is used to run with kerberos ciphers.
+ */
+ public static final String TEST_MODE
+ = System.getProperty("test.mode", "norm");
+
+ private static final String FS = System.getProperty("file.separator", "/");
+ private static final String PATH_TO_STORES = ".." + FS + "etc";
+ private static final String KEY_STORE_FILE = "keystore";
+ private static final String TRUST_STORE_FILE = "truststore";
+ private static final String PASSWD = "passphrase";
+
+ private static final String KEY_FILE_NAME
+ = System.getProperty("test.src", ".") + FS + PATH_TO_STORES
+ + FS + KEY_STORE_FILE;
+ private static final String TRUST_FILE_NAME
+ = System.getProperty("test.src", ".") + FS + PATH_TO_STORES
+ + FS + TRUST_STORE_FILE;
+
+ private static ByteBuffer net;
+ private static ByteBuffer netReplicatedClient;
+ private static ByteBuffer netReplicatedServer;
+ private static final int MAX_HANDSHAKE_LOOPS = 100;
+ private static final String EXCHANGE_MSG_SENT = "Hello, peer!";
+ private static boolean doUnwrapForNotHandshakingStatus;
+ private static boolean endHandshakeLoop = false;
+ private static final String TEST_SRC = System.getProperty("test.src", ".");
+ private static final String KTAB_FILENAME = "krb5.keytab.data";
+ private static final String KRB_REALM = "TEST.REALM";
+ private static final String KRBTGT_PRINCIPAL = "krbtgt/" + KRB_REALM;
+ private static final String KRB_USER = "USER";
+ private static final String KRB_USER_PASSWORD = "password";
+ private static final String KRB_USER_PRINCIPAL = KRB_USER + "@" + KRB_REALM;
+ private static final String KRB5_CONF_FILENAME = "krb5.conf";
+ private static final String PATH_TO_COMMON = ".." + FS + "TLSCommon";
+ private static final String JAAS_CONF_FILE = PATH_TO_COMMON
+ + FS + "jaas.conf";
+ private static final int DELAY = 1000;
+ private static final String HOST = "localhost";
+ private static final String SERVER_NAME = "service.localhost";
+ private static final String SNI_PATTERN = ".*";
+
+ private static final String[] SUPPORTED_NON_KRB_CIPHERS;
+
+ static {
+ try {
+ String[] allSupportedCiphers = getContext()
+ .createSSLEngine().getSupportedCipherSuites();
+ List supportedCiphersList = new LinkedList<>();
+ for (String cipher : allSupportedCiphers) {
+ if (!cipher.contains("KRB5")
+ && !cipher.contains("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
+ supportedCiphersList.add(cipher);
+ }
+ }
+ SUPPORTED_NON_KRB_CIPHERS = supportedCiphersList.toArray(new String[0]);
+ } catch (Exception ex) {
+ throw new Error("Unexpected issue", ex);
+ }
+ }
+
+ private static final String[] SUPPORTED_NON_KRB_NON_SHA_CIPHERS;
+
+ static {
+ try {
+ String[] allSupportedCiphers = getContext()
+ .createSSLEngine().getSupportedCipherSuites();
+ List supportedCiphersList = new LinkedList<>();
+ for (String cipher : allSupportedCiphers) {
+ if (!cipher.contains("KRB5")
+ && !cipher.contains("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")
+ && !cipher.endsWith("_SHA256")
+ && !cipher.endsWith("_SHA384")) {
+ supportedCiphersList.add(cipher);
+ }
+ }
+ SUPPORTED_NON_KRB_NON_SHA_CIPHERS
+ = supportedCiphersList.toArray(new String[0]);
+ } catch (Exception ex) {
+ throw new Error("Unexpected issue", ex);
+ }
+ }
+
+ private static final String[] SUPPORTED_KRB_CIPHERS;
+
+ static {
+ try {
+ String[] allSupportedCiphers = getContext()
+ .createSSLEngine().getSupportedCipherSuites();
+ List supportedCiphersList = new LinkedList<>();
+ for (String cipher : allSupportedCiphers) {
+ if (cipher.contains("KRB5")
+ && !cipher.contains("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
+ supportedCiphersList.add(cipher);
+ }
+ }
+ SUPPORTED_KRB_CIPHERS = supportedCiphersList.toArray(new String[0]);
+ } catch (Exception ex) {
+ throw new Error("Unexpected issue", ex);
+ }
+ }
+
+ private static final String[] ENABLED_NON_KRB_NOT_ANON_CIPHERS;
+
+ static {
+ try {
+ SSLEngine temporary = getContext().createSSLEngine();
+ temporary.setUseClientMode(true);
+ String[] enabledCiphers = temporary.getEnabledCipherSuites();
+ List enabledCiphersList = new LinkedList<>();
+ for (String cipher : enabledCiphers) {
+ if (!cipher.contains("anon") && !cipher.contains("KRB5")
+ && !cipher.contains("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
+ enabledCiphersList.add(cipher);
+ }
+ }
+ ENABLED_NON_KRB_NOT_ANON_CIPHERS = enabledCiphersList.toArray(new String[0]);
+ } catch (Exception ex) {
+ throw new Error("Unexpected issue", ex);
+ }
+ }
+
+ private static final String[] UNSUPPORTED_CIPHERS = {
+ "SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA",
+ "SSL_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA",
+ "SSL_DHE_DSS_WITH_RC4_128_SHA",
+ "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA",
+ "SSL_DH_DSS_WITH_DES_CBC_SHA",
+ "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA",
+ "SSL_DH_RSA_WITH_DES_CBC_SHA",
+ "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA",
+ "SSL_FORTEZZA_DMS_WITH_NULL_SHA",
+ "SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA",
+ "SSL_RSA_EXPORT1024_WITH_RC4_56_SHA",
+ "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5",
+ "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA",
+ "SSL_RSA_FIPS_WITH_DES_CBC_SHA",
+ "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5",
+ "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA",
+ "TLS_KRB5_WITH_IDEA_CBC_MD5",
+ "TLS_KRB5_WITH_IDEA_CBC_SHA",
+ "SSL_RSA_WITH_IDEA_CBC_SHA",
+ "TLS_DH_RSA_WITH_AES_128_GCM_SHA256",
+ "TLS_DH_RSA_WITH_AES_256_GCM_SHA384",
+ "TLS_DH_DSS_WITH_AES_128_GCM_SHA256",
+ "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"
+ };
+
+ private final int maxPacketSize;
+
+ /**
+ * Constructs test case with the given MFLN maxMacketSize.
+ *
+ * @param maxPacketSize - MLFN extension max packet size.
+ */
+ public SSLEngineTestCase(int maxPacketSize) {
+ this.maxPacketSize = maxPacketSize;
+ }
+
+ /**
+ * Constructs test case with {@code maxPacketSize = 0}.
+ */
+ public SSLEngineTestCase() {
+ this.maxPacketSize = 0;
+ }
+
+ /**
+ * Wraps data with the specified engine.
+ *
+ * @param engine - SSLEngine that wraps data.
+ * @param wrapper - Set wrapper id, e.g. "server" of "client". Used for
+ * logging only.
+ * @param maxPacketSize - Max packet size to check that MFLN extension works
+ * or zero for no check.
+ * @param app - Buffer with data to wrap.
+ * @return - Buffer with wrapped data.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static ByteBuffer doWrap(SSLEngine engine, String wrapper,
+ int maxPacketSize, ByteBuffer app)
+ throws SSLException {
+ return doWrap(engine, wrapper, maxPacketSize,
+ app, SSLEngineResult.Status.OK, null);
+ }
+
+ /**
+ * Wraps data with the specified engine.
+ *
+ * @param engine - SSLEngine that wraps data.
+ * @param wrapper - Set wrapper id, e.g. "server" of "client". Used for
+ * logging only.
+ * @param maxPacketSize - Max packet size to check that MFLN extension works
+ * or zero for no check.
+ * @param app - Buffer with data to wrap.
+ * @param result - Array which first element will be used to output wrap
+ * result object.
+ * @return - Buffer with wrapped data.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static ByteBuffer doWrap(SSLEngine engine, String wrapper,
+ int maxPacketSize, ByteBuffer app,
+ SSLEngineResult[] result)
+ throws SSLException {
+ return doWrap(engine, wrapper, maxPacketSize,
+ app, SSLEngineResult.Status.OK, result);
+ }
+
+ /**
+ * Wraps data with the specified engine.
+ *
+ * @param engine - SSLEngine that wraps data.
+ * @param wrapper - Set wrapper id, e.g. "server" of "client". Used for
+ * logging only.
+ * @param maxPacketSize - Max packet size to check that MFLN extension works
+ * or zero for no check.
+ * @param app - Buffer with data to wrap.
+ * @param wantedStatus - Specifies expected result status of wrapping.
+ * @return - Buffer with wrapped data.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static ByteBuffer doWrap(SSLEngine engine, String wrapper,
+ int maxPacketSize, ByteBuffer app,
+ SSLEngineResult.Status wantedStatus)
+ throws SSLException {
+ return doWrap(engine, wrapper, maxPacketSize,
+ app, wantedStatus, null);
+ }
+
+ /**
+ * Wraps data with the specified engine.
+ *
+ * @param engine - SSLEngine that wraps data.
+ * @param wrapper - Set wrapper id, e.g. "server" of "client". Used for
+ * logging only.
+ * @param maxPacketSize - Max packet size to check that MFLN extension works
+ * or zero for no check.
+ * @param app - Buffer with data to wrap.
+ * @param wantedStatus - Specifies expected result status of wrapping.
+ * @param result - Array which first element will be used to output wrap
+ * result object.
+ * @return - Buffer with wrapped data.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static ByteBuffer doWrap(SSLEngine engine, String wrapper,
+ int maxPacketSize, ByteBuffer app,
+ SSLEngineResult.Status wantedStatus,
+ SSLEngineResult[] result)
+ throws SSLException {
+ ByteBuffer net = ByteBuffer.allocate(engine.getSession()
+ .getPacketBufferSize());
+ SSLEngineResult r = engine.wrap(app, net);
+ net.flip();
+ int length = net.remaining();
+ System.out.println(wrapper + " wrapped " + length + " bytes.");
+ System.out.println(wrapper + " handshake status is "
+ + engine.getHandshakeStatus());
+ if (maxPacketSize < length && maxPacketSize != 0) {
+ throw new AssertionError("Handshake wrapped net buffer length "
+ + length + " exceeds maximum packet size "
+ + maxPacketSize);
+ }
+ checkResult(r, wantedStatus);
+ if (result != null && result.length > 0) {
+ result[0] = r;
+ }
+ return net;
+ }
+
+ /**
+ * Unwraps data with the specified engine.
+ *
+ * @param engine - SSLEngine that unwraps data.
+ * @param unwrapper - Set unwrapper id, e.g. "server" of "client". Used for
+ * logging only.
+ * @param net - Buffer with data to unwrap.
+ * @return - Buffer with unwrapped data.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static ByteBuffer doUnWrap(SSLEngine engine, String unwrapper,
+ ByteBuffer net)
+ throws SSLException {
+ return doUnWrap(engine, unwrapper, net, SSLEngineResult.Status.OK, null);
+ }
+
+ /**
+ * Unwraps data with the specified engine.
+ *
+ * @param engine - SSLEngine that unwraps data.
+ * @param unwrapper - Set unwrapper id, e.g. "server" of "client". Used for
+ * logging only.
+ * @param net - Buffer with data to unwrap.
+ * @param result - Array which first element will be used to output wrap
+ * result object.
+ * @return - Buffer with unwrapped data.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static ByteBuffer doUnWrap(SSLEngine engine, String unwrapper,
+ ByteBuffer net, SSLEngineResult[] result)
+ throws SSLException {
+ return doUnWrap(engine, unwrapper, net, SSLEngineResult.Status.OK, result);
+ }
+
+ /**
+ * Unwraps data with the specified engine.
+ *
+ * @param engine - SSLEngine that unwraps data.
+ * @param unwrapper - Set unwrapper id, e.g. "server" of "client". Used for
+ * logging only.
+ * @param net - Buffer with data to unwrap.
+ * @param wantedStatus - Specifies expected result status of wrapping.
+ * @return - Buffer with unwrapped data.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static ByteBuffer doUnWrap(SSLEngine engine, String unwrapper,
+ ByteBuffer net,
+ SSLEngineResult.Status wantedStatus)
+ throws SSLException {
+ return doUnWrap(engine, unwrapper, net, wantedStatus, null);
+ }
+
+ /**
+ * Unwraps data with the specified engine.
+ *
+ * @param engine - SSLEngine that unwraps data.
+ * @param unwrapper - Set unwrapper id, e.g. "server" of "client". Used for
+ * logging only.
+ * @param net - Buffer with data to unwrap.
+ * @param wantedStatus - Specifies expected result status of wrapping.
+ * @param result - Array which first element will be used to output wrap
+ * result object.
+ * @return - Buffer with unwrapped data.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static ByteBuffer doUnWrap(SSLEngine engine, String unwrapper,
+ ByteBuffer net,
+ SSLEngineResult.Status wantedStatus,
+ SSLEngineResult[] result)
+ throws SSLException {
+ ByteBuffer app = ByteBuffer.allocate(engine.getSession()
+ .getApplicationBufferSize());
+ int length = net.remaining();
+ System.out.println(unwrapper + " unwrapping "
+ + length + " bytes...");
+ SSLEngineResult r = engine.unwrap(net, app);
+ app.flip();
+ System.out.println(unwrapper + " handshake status is "
+ + engine.getHandshakeStatus());
+ checkResult(r, wantedStatus);
+ if (result != null && result.length > 0) {
+ result[0] = r;
+ }
+ return app;
+ }
+
+ /**
+ * Does the handshake of the two specified engines according to the
+ * {@code mode} specified.
+ *
+ * @param clientEngine - Client SSLEngine.
+ * @param serverEngine - Server SSLEngine.
+ * @param maxPacketSize - Maximum packet size for MFLN of zero for no limit.
+ * @param mode - Handshake mode according to {@link HandshakeMode} enum.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static void doHandshake(SSLEngine clientEngine,
+ SSLEngine serverEngine,
+ int maxPacketSize, HandshakeMode mode)
+ throws SSLException {
+ doHandshake(clientEngine, serverEngine, maxPacketSize, mode, false);
+ }
+
+ /**
+ * Does the handshake of the two specified engines according to the
+ * {@code mode} specified.
+ *
+ * @param clientEngine - Client SSLEngine.
+ * @param serverEngine - Server SSLEngine.
+ * @param maxPacketSize - Maximum packet size for MFLN of zero for no limit.
+ * @param mode - Handshake mode according to {@link HandshakeMode} enum.
+ * @param enableReplicatedPacks - Set {@code true} to enable replicated
+ * packet sending.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static void doHandshake(SSLEngine clientEngine,
+ SSLEngine serverEngine, int maxPacketSize,
+ HandshakeMode mode,
+ boolean enableReplicatedPacks)
+ throws SSLException {
+ System.out.println("================================================="
+ + "===========");
+ System.out.println("Starting handshake " + mode.name());
+ int loop = 0;
+ if (maxPacketSize < 0) {
+ throw new Error("Test issue: maxPacketSize is less than zero!");
+ }
+ SSLParameters params = clientEngine.getSSLParameters();
+ params.setMaximumPacketSize(maxPacketSize);
+ clientEngine.setSSLParameters(params);
+ params = serverEngine.getSSLParameters();
+ params.setMaximumPacketSize(maxPacketSize);
+ serverEngine.setSSLParameters(params);
+ SSLEngine firstEngine;
+ SSLEngine secondEngine;
+ switch (mode) {
+ case INITIAL_HANDSHAKE:
+ firstEngine = clientEngine;
+ secondEngine = serverEngine;
+ doUnwrapForNotHandshakingStatus = false;
+ clientEngine.beginHandshake();
+ serverEngine.beginHandshake();
+ break;
+ case REHANDSHAKE_BEGIN_CLIENT:
+ firstEngine = clientEngine;
+ secondEngine = serverEngine;
+ doUnwrapForNotHandshakingStatus = true;
+ clientEngine.beginHandshake();
+ break;
+ case REHANDSHAKE_BEGIN_SERVER:
+ firstEngine = serverEngine;
+ secondEngine = clientEngine;
+ doUnwrapForNotHandshakingStatus = true;
+ serverEngine.beginHandshake();
+ break;
+ default:
+ throw new Error("Test issue: unknown handshake mode");
+ }
+ endHandshakeLoop = false;
+ while (!endHandshakeLoop) {
+ if (++loop > MAX_HANDSHAKE_LOOPS) {
+ throw new Error("Too much loops for handshaking");
+ }
+ System.out.println("==============================================");
+ System.out.println("Handshake loop " + loop);
+ SSLEngineResult.HandshakeStatus clientHSStatus
+ = clientEngine.getHandshakeStatus();
+ SSLEngineResult.HandshakeStatus serverHSStatus
+ = serverEngine.getHandshakeStatus();
+ System.out.println("Client handshake status "
+ + clientHSStatus.name());
+ System.out.println("Server handshake status "
+ + serverHSStatus.name());
+ handshakeProcess(firstEngine, secondEngine, maxPacketSize,
+ enableReplicatedPacks);
+ handshakeProcess(secondEngine, firstEngine, maxPacketSize,
+ enableReplicatedPacks);
+ }
+ }
+
+ /**
+ * Routine to send application data from one SSLEngine to another.
+ *
+ * @param fromEngine - Sending engine.
+ * @param toEngine - Receiving engine.
+ * @return - Result of unwrap method of the receiving engine.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static SSLEngineResult sendApplicationData(SSLEngine fromEngine,
+ SSLEngine toEngine)
+ throws SSLException {
+ String sender = null;
+ String reciever = null;
+ String excMsgSent = EXCHANGE_MSG_SENT;
+ if (fromEngine.getUseClientMode() && !toEngine.getUseClientMode()) {
+ sender = "Client";
+ reciever = "Server";
+ excMsgSent += " Client.";
+ } else if (toEngine.getUseClientMode() && !fromEngine.getUseClientMode()) {
+ sender = "Server";
+ reciever = "Client";
+ excMsgSent += " Server.";
+ } else {
+ throw new Error("Test issue: both engines are in the same mode");
+ }
+ System.out.println("================================================="
+ + "===========");
+ System.out.println("Trying to send application data from " + sender
+ + " to " + reciever);
+ ByteBuffer clientAppSent
+ = ByteBuffer.wrap(excMsgSent.getBytes());
+ net = doWrap(fromEngine, sender, 0, clientAppSent);
+ SSLEngineResult[] r = new SSLEngineResult[1];
+ ByteBuffer serverAppRecv = doUnWrap(toEngine, reciever, net, r);
+ byte[] serverAppRecvTrunc = Arrays.copyOf(serverAppRecv.array(),
+ serverAppRecv.limit());
+ String msgRecv = new String(serverAppRecvTrunc);
+ if (!msgRecv.equals(excMsgSent)) {
+ throw new AssertionError(sender + " to " + reciever
+ + ": application data"
+ + " has been altered while sending."
+ + " Message sent: " + "\"" + excMsgSent + "\"."
+ + " Message recieved: " + "\"" + msgRecv + "\".");
+ }
+ System.out.println("Successful sending application data from " + sender
+ + " to " + reciever);
+ return r[0];
+ }
+
+ /**
+ * Close engines by sending "close outbound" message from one SSLEngine to
+ * another.
+ *
+ * @param fromEngine - Sending engine.
+ * @param toEngine - Receiving engine.
+ * @throws SSLException - thrown on engine errors.
+ */
+ public static void closeEngines(SSLEngine fromEngine,
+ SSLEngine toEngine) throws SSLException {
+ String from = null;
+ String to = null;
+ ByteBuffer app;
+ if (fromEngine.getUseClientMode() && !toEngine.getUseClientMode()) {
+ from = "Client";
+ to = "Server";
+ } else if (toEngine.getUseClientMode() && !fromEngine.getUseClientMode()) {
+ from = "Server";
+ to = "Client";
+ } else {
+ throw new Error("Both engines are in the same mode");
+ }
+ System.out.println("=========================================================");
+ System.out.println("Trying to close engines from " + from + " to " + to);
+ // Sending close outbound request to peer
+ fromEngine.closeOutbound();
+ app = ByteBuffer.allocate(fromEngine.getSession().getApplicationBufferSize());
+ net = doWrap(fromEngine, from, 0, app, SSLEngineResult.Status.CLOSED);
+ doUnWrap(toEngine, to, net, SSLEngineResult.Status.CLOSED);
+ app = ByteBuffer.allocate(fromEngine.getSession().getApplicationBufferSize());
+ net = doWrap(toEngine, to, 0, app, SSLEngineResult.Status.CLOSED);
+ doUnWrap(fromEngine, from, net, SSLEngineResult.Status.CLOSED);
+ if (!toEngine.isInboundDone()) {
+ throw new AssertionError(from + " sent close request to " + to
+ + ", but " + to + "did not close inbound.");
+ }
+ // Executing close inbound
+ fromEngine.closeInbound();
+ app = ByteBuffer.allocate(fromEngine.getSession().getApplicationBufferSize());
+ net = doWrap(fromEngine, from, 0, app, SSLEngineResult.Status.CLOSED);
+ doUnWrap(toEngine, to, net, SSLEngineResult.Status.CLOSED);
+ if (!toEngine.isOutboundDone()) {
+ throw new AssertionError(from + "sent close request to " + to
+ + ", but " + to + "did not close outbound.");
+ }
+ System.out.println("Successful closing from " + from + " to " + to);
+ }
+
+ /**
+ * Runs the same test case for all given {@code ciphers}. Method counts all
+ * failures and throws {@code AssertionError} if one or more tests fail.
+ *
+ * @param ciphers - Ciphers that should be tested.
+ */
+ public void runTests(Ciphers ciphers) {
+ int total = ciphers.ciphers.length;
+ int failed = testSomeCiphers(ciphers);
+ if (failed > 0) {
+ throw new AssertionError("" + failed + " of " + total
+ + " tests failed!");
+ }
+ System.out.println("All tests passed!");
+ }
+
+ /**
+ * Runs test cases for ciphers defined by the test mode.
+ */
+ public void runTests() {
+ switch (TEST_MODE) {
+ case "norm":
+ case "norm_sni":
+ switch (TESTED_SECURITY_PROTOCOL) {
+ case "DTLSv1.0":
+ case "TLSv1":
+ case "TLSv1.1":
+ runTests(Ciphers.SUPPORTED_NON_KRB_NON_SHA_CIPHERS);
+ break;
+ default:
+ runTests(Ciphers.SUPPORTED_NON_KRB_CIPHERS);
+ }
+ break;
+ case "krb":
+ runTests(Ciphers.SUPPORTED_KRB_CIPHERS);
+ break;
+ default:
+ throw new Error("Test error: unexpected test mode: " + TEST_MODE);
+ }
+ }
+
+ /**
+ * Returns maxPacketSize value used for MFLN extension testing
+ *
+ * @return - MLFN extension max packet size.
+ */
+ public int getMaxPacketSize() {
+ return maxPacketSize;
+ }
+
+ /**
+ * Checks that status of result {@code r} is {@code wantedStatus}.
+ *
+ * @param r - Result.
+ * @param wantedStatus - Wanted status of the result.
+ * @throws AssertionError - if status or {@code r} is not
+ * {@code wantedStatus}.
+ */
+ public static void checkResult(SSLEngineResult r,
+ SSLEngineResult.Status wantedStatus) {
+ SSLEngineResult.Status rs = r.getStatus();
+ if (!rs.equals(wantedStatus)) {
+ throw new AssertionError("Unexpected status " + rs.name()
+ + ", should be " + wantedStatus.name());
+ }
+ }
+
+ /**
+ * Returns SSLContext with TESTED_SECURITY_PROTOCOL protocol and sets up keys.
+ *
+ * @return - SSLContext with a protocol specified by TESTED_SECURITY_PROTOCOL.
+ */
+ public static SSLContext getContext() {
+ try {
+ KeyStore ks = KeyStore.getInstance("JKS");
+ KeyStore ts = KeyStore.getInstance("JKS");
+ char[] passphrase = PASSWD.toCharArray();
+ try (FileInputStream keyFileStream = new FileInputStream(KEY_FILE_NAME)) {
+ ks.load(keyFileStream, passphrase);
+ }
+ try (FileInputStream trustFileStream = new FileInputStream(TRUST_FILE_NAME)) {
+ ts.load(trustFileStream, passphrase);
+ }
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ts);
+ SSLContext sslCtx = SSLContext.getInstance(TESTED_SECURITY_PROTOCOL);
+ sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ return sslCtx;
+ } catch (KeyStoreException | IOException | NoSuchAlgorithmException |
+ CertificateException | UnrecoverableKeyException |
+ KeyManagementException ex) {
+ throw new Error("Unexpected exception", ex);
+ }
+ }
+
+ /**
+ * Sets up and starts kerberos KDC server.
+ */
+ public static void setUpAndStartKDC() {
+ String servicePrincipal = "host/" + SERVER_NAME + "@" + KRB_REALM;
+ Map principals = new HashMap<>();
+ principals.put(KRB_USER_PRINCIPAL, KRB_USER_PASSWORD);
+ principals.put(KRBTGT_PRINCIPAL, null);
+ principals.put(servicePrincipal, null);
+ System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME);
+ startKDC(KRB_REALM, principals, KTAB_FILENAME);
+ System.setProperty("java.security.auth.login.config",
+ TEST_SRC + FS + JAAS_CONF_FILE);
+ System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
+ }
+
+ /**
+ * Sets up and starts kerberos KDC server if SSLEngineTestCase.TEST_MODE is "krb".
+ */
+ public static void setUpAndStartKDCIfNeeded() {
+ if (TEST_MODE.equals("krb")) {
+ setUpAndStartKDC();
+ }
+ }
+
+ /**
+ * Returns client ssl engine.
+ *
+ * @param context - SSLContext to get SSLEngine from.
+ * @param useSNI - flag used to enable or disable using SNI extension.
+ * Needed for Kerberos.
+ */
+ public static SSLEngine getClientSSLEngine(SSLContext context, boolean useSNI) {
+ SSLEngine clientEngine = context.createSSLEngine(HOST, 80);
+ clientEngine.setUseClientMode(true);
+ if (useSNI) {
+ SNIHostName serverName = new SNIHostName(SERVER_NAME);
+ List serverNames = new ArrayList<>();
+ serverNames.add(serverName);
+ SSLParameters params = clientEngine.getSSLParameters();
+ params.setServerNames(serverNames);
+ clientEngine.setSSLParameters(params);
+ }
+ return clientEngine;
+ }
+
+ /**
+ * Returns server ssl engine.
+ *
+ * @param context - SSLContext to get SSLEngine from.
+ * @param useSNI - flag used to enable or disable using SNI extension.
+ * Needed for Kerberos.
+ */
+ public static SSLEngine getServerSSLEngine(SSLContext context, boolean useSNI) {
+ SSLEngine serverEngine = context.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+ if (useSNI) {
+ SNIMatcher matcher = SNIHostName.createSNIMatcher(SNI_PATTERN);
+ List matchers = new ArrayList<>();
+ matchers.add(matcher);
+ SSLParameters params = serverEngine.getSSLParameters();
+ params.setSNIMatchers(matchers);
+ serverEngine.setSSLParameters(params);
+ }
+ return serverEngine;
+ }
+
+ /**
+ * Runs the test case for one cipher suite.
+ *
+ * @param cipher - Cipher suite name.
+ * @throws SSLException - If tests fails.
+ */
+ abstract protected void testOneCipher(String cipher)
+ throws SSLException;
+
+ /**
+ * Iterates through an array of ciphers and runs the same test case for
+ * every entry.
+ *
+ * @param ciphers - Array of cipher names.
+ * @return - Number of tests failed.
+ */
+ protected int testSomeCiphers(Ciphers ciphers) {
+ int failedNum = 0;
+ String description = ciphers.description;
+ System.out.println("==================================================="
+ + "=========");
+ System.out.println(description + " ciphers testing");
+ System.out.println("==================================================="
+ + "=========");
+ for (String cs : ciphers.ciphers) {
+ System.out.println("-----------------------------------------------"
+ + "-------------");
+ System.out.println("Testing cipher suite " + cs);
+ System.out.println("-----------------------------------------------"
+ + "-------------");
+ Throwable error = null;
+ try {
+ testOneCipher(cs);
+ } catch (Throwable t) {
+ error = t;
+ }
+ switch (ciphers) {
+ case SUPPORTED_NON_KRB_CIPHERS:
+ case SUPPORTED_NON_KRB_NON_SHA_CIPHERS:
+ case SUPPORTED_KRB_CIPHERS:
+ case ENABLED_NON_KRB_NOT_ANON_CIPHERS:
+ if (error != null) {
+ System.out.println("Test Failed: " + cs);
+ System.err.println("Test Exception for " + cs);
+ error.printStackTrace();
+ failedNum++;
+ } else {
+ System.out.println("Test Passed: " + cs);
+ }
+ break;
+ case UNSUPPORTED_CIPHERS:
+ if (error == null) {
+ System.out.println("Test Failed: " + cs);
+ System.err.println("Test for " + cs + " should have thrown"
+ + " IllegalArgumentException, but it has not!");
+ failedNum++;
+ } else if (!(error instanceof IllegalArgumentException)) {
+ System.out.println("Test Failed: " + cs);
+ System.err.println("Test Exception for " + cs);
+ error.printStackTrace();
+ failedNum++;
+ } else {
+ System.out.println("Test Passed: " + cs);
+ }
+ break;
+ default:
+ throw new Error("Test issue: unexpected ciphers: "
+ + ciphers.name());
+ }
+ }
+ return failedNum;
+ }
+
+ /**
+ * Method used for the handshake routine.
+ *
+ * @param wrapingEngine - Engine that is expected to wrap data.
+ * @param unwrapingEngine - Engine that is expected to unwrap data.
+ * @param maxPacketSize - Maximum packet size for MFLN of zero for no limit.
+ * @param enableReplicatedPacks - Set {@code true} to enable replicated
+ * packet sending.
+ * @throws SSLException - thrown on engine errors.
+ */
+ private static void handshakeProcess(SSLEngine wrapingEngine,
+ SSLEngine unwrapingEngine,
+ int maxPacketSize,
+ boolean enableReplicatedPacks)
+ throws SSLException {
+ SSLEngineResult.HandshakeStatus wrapingHSStatus = wrapingEngine
+ .getHandshakeStatus();
+ SSLEngineResult.HandshakeStatus unwrapingHSStatus = unwrapingEngine
+ .getHandshakeStatus();
+ SSLEngineResult r;
+ String wrapper, unwrapper;
+ if (wrapingEngine.getUseClientMode()
+ && !unwrapingEngine.getUseClientMode()) {
+ wrapper = "Client";
+ unwrapper = "Server";
+ } else if (unwrapingEngine.getUseClientMode()
+ && !wrapingEngine.getUseClientMode()) {
+ wrapper = "Server";
+ unwrapper = "Client";
+ } else {
+ throw new Error("Both engines are in the same mode");
+ }
+ switch (wrapingHSStatus) {
+ case NEED_WRAP:
+ if (enableReplicatedPacks) {
+ if (net != null) {
+ net.flip();
+ if (net.remaining() != 0) {
+ if (wrapingEngine.getUseClientMode()) {
+ netReplicatedServer = net;
+ } else {
+ netReplicatedClient = net;
+ }
+ }
+ }
+ }
+ ByteBuffer app = ByteBuffer.allocate(wrapingEngine.getSession()
+ .getApplicationBufferSize());
+ net = doWrap(wrapingEngine, wrapper, maxPacketSize, app);
+ case NOT_HANDSHAKING:
+ switch (unwrapingHSStatus) {
+ case NEED_TASK:
+ runDelegatedTasks(unwrapingEngine);
+ case NEED_UNWRAP:
+ doUnWrap(unwrapingEngine, unwrapper, net);
+ if (enableReplicatedPacks) {
+ System.out.println("Unwrapping replicated packet...");
+ if (unwrapingEngine.getHandshakeStatus()
+ .equals(SSLEngineResult.HandshakeStatus.NEED_TASK)) {
+ runDelegatedTasks(unwrapingEngine);
+ }
+ runDelegatedTasks(unwrapingEngine);
+ ByteBuffer netReplicated;
+ if (unwrapingEngine.getUseClientMode()) {
+ netReplicated = netReplicatedClient;
+ } else {
+ netReplicated = netReplicatedServer;
+ }
+ if (netReplicated != null) {
+ doUnWrap(unwrapingEngine, unwrapper, netReplicated);
+ } else {
+ net.flip();
+ doUnWrap(unwrapingEngine, unwrapper, net);
+ }
+ }
+ break;
+ case NEED_UNWRAP_AGAIN:
+ break;
+ case NOT_HANDSHAKING:
+ if (doUnwrapForNotHandshakingStatus) {
+ doUnWrap(unwrapingEngine, unwrapper, net);
+ doUnwrapForNotHandshakingStatus = false;
+ break;
+ } else {
+ endHandshakeLoop = true;
+ }
+ break;
+ default:
+ throw new Error("Unexpected unwraping engine handshake status "
+ + unwrapingHSStatus.name());
+ }
+ break;
+ case NEED_UNWRAP:
+ break;
+ case NEED_UNWRAP_AGAIN:
+ net.flip();
+ doUnWrap(wrapingEngine, wrapper, net);
+ break;
+ case NEED_TASK:
+ runDelegatedTasks(wrapingEngine);
+ break;
+ default:
+ throw new Error("Unexpected wraping engine handshake status "
+ + wrapingHSStatus.name());
+ }
+ }
+
+ private static void runDelegatedTasks(SSLEngine engine) {
+ Runnable runnable;
+ System.out.println("Running delegated tasks...");
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ runnable.run();
+ }
+ SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
+ if (hs == SSLEngineResult.HandshakeStatus.NEED_TASK) {
+ throw new Error("Handshake shouldn't need additional tasks.");
+ }
+ }
+
+ /**
+ * Start a KDC server:
+ * - create a KDC instance
+ * - create Kerberos principals
+ * - save Kerberos configuration
+ * - save keys to keytab file
+ * - no pre-auth is required
+ */
+ private static void startKDC(String realm, Map principals,
+ String ktab) {
+ try {
+ KDC kdc = KDC.create(realm, HOST, 0, true);
+ kdc.setOption(KDC.Option.PREAUTH_REQUIRED, Boolean.FALSE);
+ if (principals != null) {
+ principals.entrySet().stream().forEach((entry) -> {
+ String name = entry.getKey();
+ String password = entry.getValue();
+ if (password == null || password.isEmpty()) {
+ System.out.println("KDC: add a principal '" + name
+ + "' with a random password");
+ kdc.addPrincipalRandKey(name);
+ } else {
+ System.out.println("KDC: add a principal '" + name
+ + "' with '" + password + "' password");
+ kdc.addPrincipal(name, password.toCharArray());
+ }
+ });
+ }
+ KDC.saveConfig(KRB5_CONF_FILENAME, kdc);
+ if (ktab != null) {
+ File ktabFile = new File(ktab);
+ if (ktabFile.exists()) {
+ System.out.println("KDC: append keys to an exising "
+ + "keytab file " + ktab);
+ kdc.appendKtab(ktab);
+ } else {
+ System.out.println("KDC: create a new keytab file "
+ + ktab);
+ kdc.writeKtab(ktab);
+ }
+ }
+ System.out.println("KDC: started on " + HOST + ":" + kdc.getPort()
+ + " with '" + realm + "' realm");
+ } catch (Exception e) {
+ throw new RuntimeException("KDC: unexpected exception", e);
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/UnsupportedCiphersTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/UnsupportedCiphersTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+
+/**
+ * Testing that try to enable unsupported ciphers causes IllegalArgumentException.
+ */
+public class UnsupportedCiphersTest extends SSLEngineTestCase {
+
+ public static void main(String[] s) {
+ UnsupportedCiphersTest test = new UnsupportedCiphersTest();
+ test.runTests(Ciphers.UNSUPPORTED_CIPHERS);
+ }
+
+ @Override
+ protected void testOneCipher(String cipher) {
+ unsupTest(cipher, true);
+ unsupTest(cipher, false);
+ }
+
+ private void unsupTest(String cipher, boolean clientTest) {
+ SSLContext context = getContext();
+ SSLEngine clientEngine = context.createSSLEngine();
+ clientEngine.setUseClientMode(true);
+ SSLEngine serverEngine = context.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+ if (clientTest) {
+ clientEngine.setEnabledCipherSuites(new String[]{cipher});
+ } else {
+ serverEngine.setEnabledCipherSuites(new String[]{cipher});
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSCommon/jaas.conf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSCommon/jaas.conf Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,17 @@
+com.sun.net.ssl.client {
+ com.sun.security.auth.module.Krb5LoginModule required
+ principal="USER@TEST.REALM"
+ doNotPrompt=true
+ useKeyTab=true
+ keyTab="krb5.keytab.data";
+};
+
+com.sun.net.ssl.server {
+ com.sun.security.auth.module.Krb5LoginModule required
+ principal="host/service.localhost@TEST.REALM"
+ isInitiator=false
+ useKeyTab=true
+ keyTab="krb5.keytab.data"
+ storeKey=true;
+};
+
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv1/TLSDataExchangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv1/TLSDataExchangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS application data exchange using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm TLSDataExchangeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm_sni TLSDataExchangeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=krb TLSDataExchangeTest
+ */
+
+/**
+ * Testing TLS application data exchange using each of the supported cipher
+ * suites.
+ */
+public class TLSDataExchangeTest {
+ public static void main(String[] args) {
+ DataExchangeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv1/TLSEnginesClosureTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv1/TLSEnginesClosureTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines closing using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm TLSEnginesClosureTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm_sni TLSEnginesClosureTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=krb TLSEnginesClosureTest
+ */
+
+/**
+ * Testing TLS engines closing using each of the supported cipher suites.
+ */
+public class TLSEnginesClosureTest {
+ public static void main(String[] args) {
+ EnginesClosureTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv1/TLSHandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv1/TLSHandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines handshake using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm TLSHandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm_sni TLSHandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=krb TLSHandshakeTest
+ */
+
+/**
+ * Testing TLS engines handshake using each of the supported cipher suites.
+ */
+public class TLSHandshakeTest {
+ public static void main(String[] args) {
+ HandshakeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv1/TLSMFLNTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv1/TLSMFLNTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines handshake using each of the supported
+ * cipher suites with different maximum fragment length. Testing of
+ * MFLN extension.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm TLSMFLNTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm_sni TLSMFLNTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=krb TLSMFLNTest
+ */
+
+/**
+ * Testing TLS engines handshake using each of the supported cipher suites with
+ * different maximum fragment length. Testing of MFLN extension.
+ */
+public class TLSMFLNTest {
+ public static void main(String[] args) {
+ MFLNTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv1/TLSNotEnabledRC4Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv1/TLSNotEnabledRC4Test.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines do not enable RC4 ciphers by default.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1 TLSNotEnabledRC4Test
+ */
+
+/**
+ * Testing DTLS engines do not enable RC4 ciphers by default.
+ */
+public class TLSNotEnabledRC4Test {
+ public static void main(String[] args) throws Exception {
+ NotEnabledRC4Test.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv1/TLSRehandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv1/TLSRehandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines re-handshaking using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm TLSRehandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm_sni TLSRehandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=krb TLSRehandshakeTest
+ */
+
+/**
+ * Testing TLS engines re-handshaking using each of the supported cipher
+ * suites.
+ */
+public class TLSRehandshakeTest {
+ public static void main(String[] args) {
+ RehandshakeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv1/TLSRehandshakeWithCipherChangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv1/TLSRehandshakeWithCipherChangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines re-handshaking with cipher change. New cipher
+ * is taken randomly from the supporetd ciphers list.
+ * @key randomness
+ * @library /sun/security/krb5/auto /lib/testlibrary /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1 TLSRehandshakeWithCipherChangeTest
+ */
+
+/**
+ * Testing TLS engines re-handshaking with cipher change. New cipher is taken
+ * randomly from the supported ciphers list.
+ */
+public class TLSRehandshakeWithCipherChangeTest {
+ public static void main(String[] args) {
+ RehandshakeWithCipherChangeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv1/TLSRehandshakeWithDataExTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv1/TLSRehandshakeWithDataExTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines re-handshaking using each of the supported
+ * cipher suites with application data exchange before and after
+ * re-handshake and closing of the engines.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm TLSRehandshakeWithDataExTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=norm_sni TLSRehandshakeWithDataExTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1 -Dtest.mode=krb TLSRehandshakeWithDataExTest
+ */
+
+/**
+ * Testing TLS engines re-handshaking using each of the supported cipher suites
+ * with application data exchange before and after re-handshake and closing of
+ * the engines.
+ */
+public class TLSRehandshakeWithDataExTest {
+ public static void main(String[] args) {
+ RehandshakeWithDataExTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv1/TLSUnsupportedCiphersTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv1/TLSUnsupportedCiphersTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing that try to enable unsupported ciphers
+ * causes IllegalArgumentException.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1 TLSUnsupportedCiphersTest
+ */
+
+/**
+ * Testing that a try to enable unsupported ciphers causes IllegalArgumentException.
+ */
+public class TLSUnsupportedCiphersTest {
+ public static void main(String[] args) {
+ UnsupportedCiphersTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv11/TLSDataExchangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv11/TLSDataExchangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS application data exchange using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm TLSDataExchangeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm_sni TLSDataExchangeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=krb TLSDataExchangeTest
+ */
+
+/**
+ * Testing TLS application data exchange using each of the supported cipher
+ * suites.
+ */
+public class TLSDataExchangeTest {
+ public static void main(String[] args) {
+ DataExchangeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv11/TLSEnginesClosureTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv11/TLSEnginesClosureTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines closing using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm TLSEnginesClosureTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm_sni TLSEnginesClosureTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=krb TLSEnginesClosureTest
+ */
+
+/**
+ * Testing TLS engines closing using each of the supported cipher suites.
+ */
+public class TLSEnginesClosureTest {
+ public static void main(String[] args) {
+ EnginesClosureTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv11/TLSHandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv11/TLSHandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines handshake using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm TLSHandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm_sni TLSHandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=krb TLSHandshakeTest
+ */
+
+/**
+ * Testing TLS engines handshake using each of the supported cipher suites.
+ */
+public class TLSHandshakeTest {
+ public static void main(String[] args) {
+ HandshakeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv11/TLSMFLNTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv11/TLSMFLNTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines handshake using each of the supported
+ * cipher suites with different maximum fragment length. Testing of
+ * MFLN extension.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm TLSMFLNTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm_sni TLSMFLNTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=krb TLSMFLNTest
+ */
+
+/**
+ * Testing TLS engines handshake using each of the supported cipher suites with
+ * different maximum fragment length. Testing of MFLN extension.
+ */
+public class TLSMFLNTest {
+ public static void main(String[] args) {
+ MFLNTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv11/TLSNotEnabledRC4Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv11/TLSNotEnabledRC4Test.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines do not enable RC4 ciphers by default.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 TLSNotEnabledRC4Test
+ */
+
+/**
+ * Testing DTLS engines do not enable RC4 ciphers by default.
+ */
+public class TLSNotEnabledRC4Test {
+ public static void main(String[] args) throws Exception {
+ NotEnabledRC4Test.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv11/TLSRehandshakeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv11/TLSRehandshakeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines re-handshaking using each of the supported
+ * cipher suites.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm TLSRehandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm_sni TLSRehandshakeTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=krb TLSRehandshakeTest
+ */
+
+/**
+ * Testing TLS engines re-handshaking using each of the supported cipher
+ * suites.
+ */
+public class TLSRehandshakeTest {
+ public static void main(String[] args) {
+ RehandshakeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv11/TLSRehandshakeWithCipherChangeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv11/TLSRehandshakeWithCipherChangeTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines re-handshaking with cipher change. New cipher
+ * is taken randomly from the supporetd ciphers list.
+ * @key randomness
+ * @library /sun/security/krb5/auto /lib/testlibrary /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 TLSRehandshakeWithCipherChangeTest
+ */
+
+/**
+ * Testing TLS engines re-handshaking with cipher change. New cipher is taken
+ * randomly from the supported ciphers list.
+ */
+public class TLSRehandshakeWithCipherChangeTest {
+ public static void main(String[] args) {
+ RehandshakeWithCipherChangeTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv11/TLSRehandshakeWithDataExTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv11/TLSRehandshakeWithDataExTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing TLS engines re-handshaking using each of the supported
+ * cipher suites with application data exchange before and after
+ * re-handshake and closing of the engines.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm TLSRehandshakeWithDataExTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=norm_sni TLSRehandshakeWithDataExTest
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 -Dtest.mode=krb TLSRehandshakeWithDataExTest
+ */
+
+/**
+ * Testing TLS engines re-handshaking using each of the supported cipher suites
+ * with application data exchange before and after re-handshake and closing of
+ * the engines.
+ */
+public class TLSRehandshakeWithDataExTest {
+ public static void main(String[] args) {
+ RehandshakeWithDataExTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/net/ssl/TLSv11/TLSUnsupportedCiphersTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv11/TLSUnsupportedCiphersTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8085979
+ * @summary Testing that try to enable unsupported ciphers
+ * causes IllegalArgumentException.
+ * @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
+ * @run main/othervm -Dtest.security.protocol=TLSv1.1 TLSUnsupportedCiphersTest
+ */
+
+/**
+ * Testing that a try to enable unsupported ciphers causes IllegalArgumentException.
+ */
+public class TLSUnsupportedCiphersTest {
+ public static void main(String[] args) {
+ UnsupportedCiphersTest.main(args);
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/security/auth/kerberos/DelegationPermissionCollection.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/kerberos/DelegationPermissionCollection.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for DelegationPermissionCollection subclass
+ */
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+import javax.security.auth.kerberos.DelegationPermission;
+
+public class DelegationPermissionCollection {
+
+ private static final String FOO = "\"host/foo.example.com@EXAMPLE.COM\"";
+ private static final String BAR = "\"host/bar.example.com@EXAMPLE.COM\"";
+ private static final String TGT = "\"krbtgt/EXAMPLE.COM@EXAMPLE.COM\"";
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ DelegationPermission perm = new DelegationPermission(FOO + " " + TGT);
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println
+ ("test 1: add throws IllegalArgException for wrong perm type");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong perm type");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println("test 3: implies returns true for match on name");
+ perms.add(new DelegationPermission(FOO + " " + TGT));
+ if (!perms.implies(new DelegationPermission(FOO + " " + TGT))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println
+ ("test 4: implies returns false for non-match on name");
+ if (perms.implies(new DelegationPermission(BAR + " " + TGT))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println("test 5: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ if (numPerms != 1) {
+ System.err.println("Expected 1, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/javax/security/auth/kerberos/ServicePermissionCollection.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/kerberos/ServicePermissionCollection.java Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for ServicePermissionCollection subclass
+ */
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+import javax.security.auth.kerberos.ServicePermission;
+
+public class ServicePermissionCollection {
+
+ private static final String FOO = "host/foo.example.com@EXAMPLE.COM";
+ private static final String BAR = "host/bar.example.com@EXAMPLE.COM";
+ private static final String BAZ = "host/baz.example.com@EXAMPLE.COM";
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ ServicePermission perm = new ServicePermission(FOO, "accept");
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println
+ ("test 1: add throws IllegalArgExc for wrong permission type");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong perm type");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println
+ ("test 3: implies returns true for match on name and action");
+ perms.add(new ServicePermission(FOO, "accept"));
+ if (!perms.implies(new ServicePermission(FOO, "accept"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println
+ ("test 4: implies returns false for match on name but not action");
+ if (perms.implies(new ServicePermission(FOO, "initiate"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println("test 5: implies returns true for match on " +
+ "name and subset of actions");
+ perms.add(new ServicePermission(BAR, "accept, initiate"));
+ if (!perms.implies(new ServicePermission(BAR, "accept"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 6
+ System.out.println("test 6: implies returns false for aggregate " +
+ "match on name and action");
+ perms.add(new ServicePermission(BAZ, "accept"));
+ perms.add(new ServicePermission(BAZ, "initiate"));
+ if (!perms.implies(new ServicePermission(BAZ, "initiate"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+ if (!perms.implies(new ServicePermission(BAZ, "initiate, accept"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 7
+ System.out.println("test 7: implies returns true for wildcard " +
+ "match on name and action");
+ perms.add(new ServicePermission("*", "initiate"));
+ if (!perms.implies(new ServicePermission("Duke", "initiate"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println("test 8: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ // the 2 FOO permissions and the 2 BAZ permisssions
+ // are combined into one
+ if (numPerms != 4) {
+ System.err.println("Expected 4, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/sun/text/resources/LocaleData
--- a/jdk/test/sun/text/resources/LocaleData Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/test/sun/text/resources/LocaleData Wed Jul 05 20:37:58 2017 +0200
@@ -5414,11 +5414,13 @@
FormatData/en_SG/TimePatterns/1=h:mm:ss a z
FormatData/en_SG/TimePatterns/2=h:mm:ss a
FormatData/en_SG/TimePatterns/3=h:mm a
-FormatData/en_SG/DatePatterns/0=EEEE, MMMM d, yyyy
-FormatData/en_SG/DatePatterns/1=MMMM d, yyyy
-FormatData/en_SG/DatePatterns/2=MMM d, yyyy
-FormatData/en_SG/DatePatterns/3=M/d/yy
FormatData/en_SG/DateTimePatterns/0={1} {0}
+# bug# 8080774
+# Day should precede month for all date formats in en_SG - CLDR 27.0.0
+FormatData/en_SG/DatePatterns/0=EEEE, d MMMM, yyyy
+FormatData/en_SG/DatePatterns/1=d MMMM, yyyy
+FormatData/en_SG/DatePatterns/2=d MMM, yyyy
+FormatData/en_SG/DatePatterns/3=d/M/yy
# Use approved data
FormatData/ms/Eras/0=BCE
FormatData/ms/Eras/1=CE
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/sun/text/resources/LocaleDataTest.java
--- a/jdk/test/sun/text/resources/LocaleDataTest.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/test/sun/text/resources/LocaleDataTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -36,7 +36,7 @@
* 6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203 7101495
* 7003124 7085757 7028073 7171028 7189611 8000983 7195759 8004489 8006509
* 7114053 7074882 7040556 8013836 8021121 6192407 6931564 8027695 8017142
- * 8037343 8055222 8042126 8074791 8075173
+ * 8037343 8055222 8042126 8074791 8075173 8080774
* @summary Verify locale data
*
*/
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java
--- a/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java Wed Jul 05 20:37:58 2017 +0200
@@ -21,25 +21,29 @@
* questions.
*/
-/*
- * @test
- * @bug 8042397
- * @summary Unit test for jmap utility test heap configuration reader
- * @library /lib/testlibrary
- * @modules java.management
- * @build jdk.testlibrary.*
- * @build JMapHeapConfigTest LingeredApp TmtoolTestScenario
- * @run main JMapHeapConfigTest
- */
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+
+import jdk.test.lib.apps.LingeredApp;
import jdk.testlibrary.Utils;
import jdk.testlibrary.Platform;
+/*
+ * @test
+ * @bug 8042397
+ * @summary Unit test for jmap utility test heap configuration reader
+ * @library /../../test/lib/share/classes
+ * @library /lib/testlibrary
+ * @modules java.management
+ * @build jdk.testlibrary.*
+ * @build jdk.test.lib.apps.*
+ * @build JMapHeapConfigTest TmtoolTestScenario
+ * @run main JMapHeapConfigTest
+ */
public class JMapHeapConfigTest {
static final String expectedJMapValues[] = {
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java
--- a/jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java Thu Jun 11 20:20:05 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,431 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.file.Files;
-import java.nio.file.NoSuchFileException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.attribute.FileTime;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-/**
- * This is a framework to launch an app that could be synchronized with caller
- * to make further attach actions reliable across supported platforms
-
- * Caller example:
- * SmartTestApp a = SmartTestApp.startApp(cmd);
- * // do something
- * a.stopApp();
- *
- * or fine grained control
- *
- * a = new SmartTestApp("MyLock.lck");
- * a.createLock();
- * a.runApp();
- * a.waitAppReady();
- * // do something
- * a.deleteLock();
- * a.waitAppTerminate();
- *
- * Then you can work with app output and process object
- *
- * output = a.getAppOutput();
- * process = a.getProcess();
- *
- */
-public class LingeredApp {
-
- private static final long spinDelay = 1000;
-
- private final String lockFileName;
- private long lockCreationTime;
- private Process appProcess;
- private final ArrayList storedAppOutput;
-
- /*
- * Drain child process output, store it into string array
- */
- class InputGobbler extends Thread {
-
- InputStream is;
- List astr;
-
- InputGobbler(InputStream is, List astr) {
- this.is = is;
- this.astr = astr;
- }
-
- public void run() {
- try {
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
- String line = null;
- while ((line = br.readLine()) != null) {
- astr.add(line);
- }
- } catch (IOException ex) {
- // pass
- }
- }
- }
-
- /**
- * Create LingeredApp object on caller side. Lock file have be a valid filename
- * at writable location
- *
- * @param lockFileName - the name of lock file
- */
- public LingeredApp(String lockFileName) {
- this.lockFileName = lockFileName;
- this.storedAppOutput = new ArrayList();
- }
-
- /**
- *
- * @return name of lock file
- */
- public String getLockFileName() {
- return this.lockFileName;
- }
-
- /**
- *
- * @return name of testapp
- */
- public String getAppName() {
- return this.getClass().getName();
- }
-
- /**
- *
- * @return pid of java process running testapp
- */
- public long getPid() {
- if (appProcess == null) {
- throw new RuntimeException("Process is not alive");
- }
- return appProcess.getPid();
- }
-
- /**
- *
- * @return process object
- */
- public Process getProcess() {
- return appProcess;
- }
-
- /**
- *
- * @return application output as string array. Empty array if application produced no output
- */
- List getAppOutput() {
- if (appProcess.isAlive()) {
- throw new RuntimeException("Process is still alive. Can't get its output.");
- }
- return storedAppOutput;
- }
-
- /* Make sure all part of the app use the same method to get dates,
- as different methods could produce different results
- */
- private static long epoch() {
- return new Date().getTime();
- }
-
- private static long lastModified(String fileName) throws IOException {
- Path path = Paths.get(fileName);
- BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);
- return attr.lastModifiedTime().toMillis();
- }
-
- private static void setLastModified(String fileName, long newTime) throws IOException {
- Path path = Paths.get(fileName);
- FileTime fileTime = FileTime.fromMillis(newTime);
- Files.setLastModifiedTime(path, fileTime);
- }
-
- /**
- * create lock
- *
- * @throws IOException
- */
- public void createLock() throws IOException {
- Path path = Paths.get(lockFileName);
- // Files.deleteIfExists(path);
- Files.createFile(path);
- lockCreationTime = lastModified(lockFileName);
- }
-
- /**
- * Delete lock
- *
- * @throws IOException
- */
- public void deleteLock() throws IOException {
- try {
- Path path = Paths.get(lockFileName);
- Files.delete(path);
- } catch (NoSuchFileException ex) {
- // Lock already deleted. Ignore error
- }
- }
-
- public void waitAppTerminate() {
- while (true) {
- try {
- appProcess.waitFor();
- break;
- } catch (InterruptedException ex) {
- // pass
- }
- }
- }
-
- /**
- * The app touches the lock file when it's started
- * wait while it happens. Caller have to delete lock on wait error.
- *
- * @param timeout
- * @throws java.io.IOException
- */
- public void waitAppReady(long timeout) throws IOException {
- long here = epoch();
- while (true) {
- long epoch = epoch();
- if (epoch - here > (timeout * 1000)) {
- throw new IOException("App waiting timeout");
- }
-
- // Live process should touch lock file every second
- long lm = lastModified(lockFileName);
- if (lm > lockCreationTime) {
- break;
- }
-
- // Make sure process didn't already exit
- if (!appProcess.isAlive()) {
- throw new IOException("App exited unexpectedly with " + appProcess.exitValue());
- }
-
- try {
- Thread.sleep(spinDelay);
- } catch (InterruptedException ex) {
- // pass
- }
- }
- }
-
- /**
- * Run the app
- *
- * @param vmArguments
- * @throws IOException
- */
- public void runApp(List vmArguments)
- throws IOException {
-
- // We should always use testjava or throw an exception,
- // so we can't use JDKToolFinder.getJDKTool("java");
- // that falls back to compile java on error
- String jdkPath = System.getProperty("test.jdk");
- if (jdkPath == null) {
- // we are not under jtreg, try env
- Map env = System.getenv();
- jdkPath = env.get("TESTJAVA");
- }
-
- if (jdkPath == null) {
- throw new RuntimeException("Can't determine jdk path neither test.jdk property no TESTJAVA env are set");
- }
-
- String osname = System.getProperty("os.name");
- String javapath = jdkPath + ((osname.startsWith("window")) ? "/bin/java.exe" : "/bin/java");
-
- List cmd = new ArrayList();
- cmd.add(javapath);
-
-
- if (vmArguments == null) {
- // Propagate test.vm.options to LingeredApp, filter out possible empty options
- String testVmOpts[] = System.getProperty("test.vm.opts","").split("\\s+");
- for (String s : testVmOpts) {
- if (!s.equals("")) {
- cmd.add(s);
- }
- }
- }
- else{
- // Lets user manage LingerApp options
- cmd.addAll(vmArguments);
- }
-
- // Make sure we set correct classpath to run the app
- cmd.add("-cp");
- String classpath = System.getProperty("test.class.path");
- cmd.add((classpath == null) ? "." : classpath);
-
- cmd.add(this.getAppName());
- cmd.add(lockFileName);
-
- // Reporting
- StringBuilder cmdLine = new StringBuilder();
- for (String strCmd : cmd) {
- cmdLine.append("'").append(strCmd).append("' ");
- }
-
- // A bit of verbosity
- System.out.println("Command line: [" + cmdLine.toString() + "]");
-
- ProcessBuilder pb = new ProcessBuilder(cmd);
- // we don't expect any error output but make sure we are not stuck on pipe
- // pb.redirectErrorStream(false);
- pb.redirectError(ProcessBuilder.Redirect.INHERIT);
-
- appProcess = pb.start();
-
- // Create pipe reader for process, and read stdin and stderr to array of strings
- InputGobbler gb = new InputGobbler(appProcess.getInputStream(), storedAppOutput);
- gb.start();
- }
-
- /**
- * High level interface for test writers
- */
- /**
- * Factory method that creates SmartAppTest object with ready to use application
- * lock name is autogenerated, wait timeout is hardcoded
- * @param cmd - vm options, could be null to auto add testvm.options
- * @return LingeredApp object
- * @throws IOException
- */
- public static LingeredApp startApp(List cmd) throws IOException {
- final String lockName = UUID.randomUUID().toString() + ".lck";
- final int waitTime = 10;
-
- LingeredApp a = new LingeredApp(lockName);
- a.createLock();
- try {
- a.runApp(cmd);
- a.waitAppReady(waitTime);
- } catch (Exception ex) {
- a.deleteLock();
- throw ex;
- }
-
- return a;
- }
-
- public static LingeredApp startApp() throws IOException {
- return startApp(null);
- }
-
- /**
- * Delete lock file that signal app to terminate, then
- * waits until app is actually terminated.
- * @throws IOException
- */
- public void stopApp() throws IOException {
- deleteLock();
- waitAppTerminate();
- int exitcode = appProcess.exitValue();
- if (exitcode != 0) {
- throw new IOException("LingeredApp terminated with non-zero exit code " + exitcode);
- }
- }
-
- /**
- * LastModified time might not work correctly in some cases it might
- * cause later failures
- */
-
- public static boolean isLastModifiedWorking() {
- boolean sane = true;
- try {
- long lm = lastModified(".");
- if (lm == 0) {
- System.err.println("SANITY Warning! The lastModifiedTime() doesn't work on this system, it returns 0");
- sane = false;
- }
-
- long now = epoch();
- if (lm > now) {
- System.err.println("SANITY Warning! The Clock is wrong on this system lastModifiedTime() > getTime()");
- sane = false;
- }
-
- setLastModified(".", epoch());
- long lm1 = lastModified(".");
- if (lm1 <= lm) {
- System.err.println("SANITY Warning! The setLastModified doesn't work on this system");
- sane = false;
- }
- }
- catch(IOException e) {
- System.err.println("SANITY Warning! IOException during sanity check " + e);
- sane = false;
- }
-
- return sane;
- }
-
- /**
- * This part is the application it self
- */
- public static void main(String args[]) {
-
- if (args.length != 1) {
- System.err.println("Lock file name is not specified");
- System.exit(7);
- }
-
- String theLockFileName = args[0];
-
- try {
- Path path = Paths.get(theLockFileName);
-
- while (Files.exists(path)) {
- // Touch the lock to indicate our readiness
- setLastModified(theLockFileName, epoch());
- Thread.sleep(spinDelay);
- }
- } catch (NoSuchFileException ex) {
- // Lock deleted while we are setting last modified time.
- // Ignore error and lets the app exits
- } catch (Exception ex) {
- System.err.println("LingeredApp ERROR: " + ex);
- // Leave exit_code = 1 to Java launcher
- System.exit(3);
- }
-
- System.exit(0);
- }
-}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java
--- a/jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java Thu Jun 11 20:20:05 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2015, 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
- * @summary Unit test for LingeredApp
- * @compile LingeredAppTest.java
- * @compile LingeredApp.java
- * @run main LingeredAppTest
- */
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class LingeredAppTest {
-
- public static void main(String[] args) {
- try {
- System.out.println("Starting LingeredApp with default parameters");
-
- ArrayList cmd = new ArrayList();
-
- // Propagate test.vm.options to LingeredApp, filter out possible empty options
- String testVmOpts[] = System.getProperty("test.vm.opts","").split("\\s+");
- for (String s : testVmOpts) {
- if (!s.equals("")) {
- cmd.add(s);
- }
- }
-
- cmd.add("-XX:+PrintFlagsFinal");
-
- LingeredApp a = LingeredApp.startApp(cmd);
- System.out.printf("App pid: %d\n", a.getPid());
- a.stopApp();
-
- System.out.println("App output:");
- int count = 0;
- for (String line : a.getAppOutput()) {
- count += 1;
- }
- System.out.println("Found " + count + " lines in VM output");
- System.out.println("Test PASSED");
- } catch (IOException ex) {
- ex.printStackTrace();
- System.out.println("Test ERROR");
- System.exit(3);
- }
- }
-}
diff -r 97f4fef2d420 -r a9714a11e787 jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java
--- a/jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java Thu Jun 11 20:20:05 2015 -0700
+++ b/jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java Wed Jul 05 20:37:58 2017 +0200
@@ -31,6 +31,8 @@
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
+
+import jdk.test.lib.apps.LingeredApp;
import jdk.testlibrary.JDKToolLauncher;
import jdk.testlibrary.Utils;
diff -r 97f4fef2d420 -r a9714a11e787 make/CompileJavaModules.gmk
--- a/make/CompileJavaModules.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/make/CompileJavaModules.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -507,6 +507,10 @@
# space separated list.
JDK_USER_DEFINED_FILTER := $(strip $(subst $(COMMA),$(SPACE), $(JDK_FILTER)))
+# Create an empty directory to set the bootclasspath to.
+EMPTY_BOOTCLASSPATH := $(SUPPORT_OUTPUTDIR)/empty-dir
+$(call MakeDir, $(EMPTY_BOOTCLASSPATH))
+
# This macro sets up compilation of a module and declares dependencies for it.
# Param 1 - module name
define SetupModuleCompilation
@@ -525,7 +529,7 @@
$1_CLASSPATH := $$($1_CLASSPATH) $$(addprefix $(JDK_OUTPUTDIR)/modules/,jdk.hotspot.agent)
endif
$1_CLASSPATH := $$(subst $$(SPACE),$$(PATH_SEP),$$($1_CLASSPATH))
- $1_JAVAC_FLAGS := -bootclasspath "$$($1_CLASSPATH)" $$($1_ADD_JAVAC_FLAGS)
+ $1_JAVAC_FLAGS := -bootclasspath $(EMPTY_BOOTCLASSPATH) -classpath "$$($1_CLASSPATH)" $$($1_ADD_JAVAC_FLAGS)
$$(eval $$(call SetupJavaCompilation,$1, \
SETUP := $$(if $$($1_SETUP), $$($1_SETUP), GENERATE_JDKBYTECODE), \
diff -r 97f4fef2d420 -r a9714a11e787 make/common/JavaCompilation.gmk
--- a/make/common/JavaCompilation.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/make/common/JavaCompilation.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -561,10 +561,6 @@
$$($1_BIN)/_the.$1_batch: $$($1_SRCS) $$($1_DEPENDS) $$($1_VARDEPS_FILE)
$(MKDIR) -p $$(@D) $$(dir $$($1_SJAVAC_PORTFILE))
- # As a workaround for sjavac not tracking api changed from the classpath, force full
- # recompile if an external dependency, which is something other than a source
- # change, triggered this compilation.
- $$(if $$(filter-out $$($1_SRCS), $$?), $(FIND) $$(@D) -name "*.class" $(FIND_DELETE))
$$(call ListPathsSafely,$1_SRCS,\n, >> $$($1_BIN)/_the.$1_batch.tmp)
$(ECHO) Compiling $1
($$($1_JVM) $$($1_SJAVAC) \
diff -r 97f4fef2d420 -r a9714a11e787 make/common/NativeCompilation.gmk
--- a/make/common/NativeCompilation.gmk Thu Jun 11 20:20:05 2015 -0700
+++ b/make/common/NativeCompilation.gmk Wed Jul 05 20:37:58 2017 +0200
@@ -449,6 +449,16 @@
$1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_$(OPENJDK_TARGET_OS)_release)
endif
+ # If no C++ flags are explicitly set, default to using the C flags.
+ # After that, we can set additional C++ flags that should not interfere
+ # with the mechanism for copying the C flags by default.
+ ifeq ($$($1_CXXFLAGS),)
+ $1_CXXFLAGS:=$$($1_CFLAGS)
+ endif
+ ifeq ($$(strip $$($1_EXTRA_CXXFLAGS)),)
+ $1_EXTRA_CXXFLAGS:=$$($1_EXTRA_CFLAGS)
+ endif
+
ifeq ($$($1_DEBUG_SYMBOLS), true)
ifeq ($(ENABLE_DEBUG_SYMBOLS), true)
ifdef OPENJDK
@@ -466,16 +476,6 @@
endif
endif
- # If no C++ flags are explicitly set, default to using the C flags.
- # After that, we can set additional C++ flags that should not interfere
- # with the mechanism for copying the C flags by default.
- ifeq ($$($1_CXXFLAGS),)
- $1_CXXFLAGS:=$$($1_CFLAGS)
- endif
- ifeq ($$(strip $$($1_EXTRA_CXXFLAGS)),)
- $1_EXTRA_CXXFLAGS:=$$($1_EXTRA_CFLAGS)
- endif
-
ifneq (,$$($1_REORDER))
$1_EXTRA_CFLAGS += $$(C_FLAG_REORDER)
$1_EXTRA_CXXFLAGS += $$(CXX_FLAG_REORDER)
diff -r 97f4fef2d420 -r a9714a11e787 nashorn/.hgtags
--- a/nashorn/.hgtags Thu Jun 11 20:20:05 2015 -0700
+++ b/nashorn/.hgtags Wed Jul 05 20:37:58 2017 +0200
@@ -301,3 +301,4 @@
2054d01ae32649d3179e93d14108fdd6259c1c0d jdk9-b65
9dd95cff9dae897e8dee712f1f0303c460262288 jdk9-b66
f822b749821e364cae0b7bd7c8f667d9437e6d83 jdk9-b67
+dd6dd848b854dbd3f3cc422668276b1ae0834179 jdk9-b68
diff -r 97f4fef2d420 -r a9714a11e787 nashorn/samples/autoimports.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/autoimports.js Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,151 @@
+# autoimports script requires -scripting mode
+
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * It is tedious to import Java classes used in a script. Sometimes it is easier
+ * use simple names of java classes and have a script auto import Java classes.
+ * You can load this script at the start of an interactive jjs session or at the
+ * start of your script. This script defines a __noSuchProperty__ hook to auto
+ * import Java classes as needed and when they are referred to for the first time
+ * in your script. You can also call the "autoimports" function to print script
+ * statements that you need to use in your script, i.e., have the function generate
+ * a script to import Java classes used by your script so far. After running your
+ * script, you can call autoimports to get the exact Java imports you need and replace
+ * the autoimports load with the generated import statements (to avoid costly init of
+ * the autoimports script).
+ */
+
+(function() {
+ var ArrayList = Java.type("java.util.ArrayList");
+ var HashMap = Java.type("java.util.HashMap");
+ var Files = Java.type("java.nio.file.Files");
+ var FileSystems = Java.type("java.nio.file.FileSystems");
+ var URI = Java.type("java.net.URI");
+
+ // initialize a class to package map by iterating all
+ // classes available in the system by walking through "jrt fs"
+ var fs = FileSystems.getFileSystem(URI.create("jrt:/"));
+ var root = fs.getPath('/');
+
+ var clsToPkg = new HashMap();
+
+ function addToClsToPkg(c, p) {
+ if (clsToPkg.containsKey(c)) {
+ var val = clsToPkg.get(c);
+ if (val instanceof ArrayList) {
+ val.add(p);
+ } else {
+ var al = new ArrayList();
+ al.add(val);
+ al.add(p);
+ clsToPkg.put(c, al);
+ }
+ } else {
+ clsToPkg.put(c, p);
+ }
+ }
+
+ // handle collision and allow user to choose package
+ function getPkgOfCls(c) {
+ var val = clsToPkg.get(c);
+ if (val instanceof ArrayList) {
+ var count = 1;
+ print("Multiple matches for " + c + ", choose package:");
+ for each (var v in val) {
+ print(count + ". " + v);
+ count++;
+ }
+ var choice = parseInt(readLine());
+ if (isNaN(choice) || choice < 1 || choice > val.size()) {
+ print("invalid choice: " + choice);
+ return undefined;
+ }
+ return val.get(choice - 1);
+ } else {
+ return val;
+ }
+ }
+
+ Files.walk(root).forEach(function(p) {
+ if (Files.isRegularFile(p)) {
+ var str = p.toString();
+ if (str.endsWith(".class")) {
+ str = str.substring(1);
+ var idx = str.indexOf('/');
+ if (idx != -1) {
+ str = str.substring(idx + 1);
+ if (str.startsWith("java") ||
+ str.startsWith("javax") ||
+ str.startsWith("org")) {
+ var lastIdx = str.lastIndexOf('/');
+ if (lastIdx != -1) {
+ var pkg = str.substring(0, lastIdx).replaceAll('/', '.');
+ var cls = str.substring(lastIdx + 1, str.lastIndexOf(".class"));
+ addToClsToPkg(cls, pkg);
+ }
+ }
+ }
+ }
+ }
+ });
+
+ var imports = new ArrayList();
+ var global = this;
+ var oldNoSuchProp = global.__noSuchProperty__;
+ this.__noSuchProperty__ = function(name) {
+ 'use strict';
+
+ if (clsToPkg.containsKey(name)) {
+ var pkg = getPkgOfCls(name);
+ if (pkg) {
+ var clsName = pkg + "." + name;
+ imports.add("var " + name + " = Java.type('" + clsName + "');");
+ return global[name] = Java.type(clsName);
+ }
+ } else if (typeof oldNoSuchProp == 'function') {
+ return oldNoSuchProp.call(this, name);
+ }
+
+ if (typeof this == 'undefined') {
+ throw new ReferenceError(name);
+ } else {
+ return undefined;
+ }
+ }
+
+ this.autoimports = function() {
+ for each (var im in imports) {
+ print(im);
+ }
+ }
+})();
diff -r 97f4fef2d420 -r a9714a11e787 nashorn/samples/dateconversion.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/dateconversion.js Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Converting between #javascript Date and #java8 LocalDateTime with #nashorn
+
+// JavaScript Date with current time
+var d = new Date();
+print(d);
+
+// Java 8 java.time classes used
+var Instant = java.time.Instant;
+var LocalDateTime = java.time.LocalDateTime;
+var ZoneId = java.time.ZoneId;
+
+// Date.prototype.getTime
+
+// getTime() method returns the numeric value corresponding to the time
+// for the specified date according to universal time. The value returned
+// by the getTime() method is the number of milliseconds since 1 January 1970 00:00:00 UTC.
+// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime
+
+// Java Instant.ofEpochMilli to convert time in milliseconds to Instant object
+// https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#ofEpochMilli-long-
+
+var instant = Instant.ofEpochMilli(d.getTime());
+
+// Instant to LocalDateTime using LocalDateTime.ofInstant
+// https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#ofInstant-java.time.Instant-java.time.ZoneId-
+
+var ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+print(ldt);
+
+// converting a LocalDateTime to JavaScript Date
+// convert LocalDateTime to Instant first
+// https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#atZone-java.time.ZoneId-
+
+var instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
+
+// instant to to epoch milliseconds
+// https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#toEpochMilli--
+// and then to JavaScript Date from time in milliseconds
+// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date
+
+var d1 = new Date(instant.toEpochMilli());
+print(d1);
diff -r 97f4fef2d420 -r a9714a11e787 nashorn/samples/exec.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/exec.js Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,50 @@
+# exec script requires -scripting mode
+
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// The $EXEC builtin function can be used to run external commands:
+$EXEC("ls")
+$EXEC("ls -la")
+
+// It can also be given a string to use as stdin:
+$EXEC("cat", "Hello, world!")
+
+// Additional arguments can be passed after the stdin argument, as an array of
+// strings, or a sequence of varargs:
+$EXEC("ls", "" /* no stdin */, "-l", "-a")
+$EXEC("ls", "" /* no stdin */, ["-l", "-a"])
+
+// Output of running external commands is returned from $EXEC:
+print($EXEC("ls"))
+
+// apply on $EXEC
+print($EXEC.apply(this, ["ls"]));
diff -r 97f4fef2d420 -r a9714a11e787 nashorn/samples/javahelp.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/javahelp.js Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// script helpers to print meta info on Java instances and classes
+
+// print instance methods info on a Java object or static methods info of a Java class
+function methods(jobj) {
+ if (! Java.isJavaObject(jobj)) {
+ throw new TypeError("not a Java object");
+ }
+
+ var isStatic = Java.isType(jobj);
+ var obj = Object.bindProperties({}, jobj);
+ for each (var i in obj) {
+ if (Java.isJavaMethod(i)) {
+ var str = String(i);
+ var idx = str.indexOf(' ');
+ var overloaded = str.substring(0, idx).endsWith("OverloadedDynamicMethod");
+ var lastIdx = isStatic? str.lastIndexOf('] on') : str.lastIndexOf(']');
+ print(str.substring(idx + 1, lastIdx) + (overloaded? "*" : ""))
+ }
+ }
+}
+
+// print instance field names of a Java object or static field names of a Java class
+function fields(jobj) {
+ if (! Java.isJavaObject(jobj)) {
+ throw new TypeError("not a Java object");
+ }
+
+ var obj = Object.bindProperties({}, jobj);
+ for (var i in obj) {
+ if (! Java.isJavaMethod(obj[i])) {
+ print(i);
+ }
+ }
+}
+
+undefined;
diff -r 97f4fef2d420 -r a9714a11e787 nashorn/samples/secondssince.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/secondssince.js Wed Jul 05 20:37:58 2017 +0200
@@ -0,0 +1,43 @@
+# usage: jjs secondssince.js
+
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Number of seconds elapsed since the specified Instance #nashorn #javascript #java
+// Input date and time in ISO 8601 format
+// Example: 2001-01-01T00:00:00Z for 1 Jan 2001, 0 GMT
+
+var Instant = java.time.Instant;
+var ChronoUnit = java.time.temporal.ChronoUnit;
+print("Enter date time:");
+var sec = Instant.parse(readLine()).
+ until(Instant.now(), ChronoUnit.SECONDS);
+print(sec);
diff -r 97f4fef2d420 -r a9714a11e787 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinker.java
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinker.java Thu Jun 11 20:20:05 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinker.java Wed Jul 05 20:37:58 2017 +0200
@@ -99,10 +99,12 @@
import jdk.internal.dynalink.support.RuntimeContextLinkRequestImpl;
/**
- * The linker for {@link RelinkableCallSite} objects. Users of it (scripting frameworks and language runtimes) have to
- * create a linker using the {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic bootstrap
- * methods to set the target of all the call sites in the code they generate. Usual usage would be to create one class
- * per language runtime to contain one linker instance as:
+ * The linker for {@link RelinkableCallSite} objects. Users of it (scripting
+ * frameworks and language runtimes) have to create a linker using the
+ * {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic
+ * bootstrap methods to set the target of all the call sites in the code they
+ * generate. Usual usage would be to create one class per language runtime to
+ * contain one linker instance as:
*
*
* class MyLanguageRuntime {
@@ -123,19 +125,27 @@
*
* Note how there are three components you will need to provide here:
*
- *
You're expected to provide a {@link GuardingDynamicLinker} for your own language. If your runtime doesn't
- * have its own language and/or object model (i.e. it's a generic scripting shell), you don't need to implement a
- * dynamic linker; you would simply not invoke the {@code setPrioritizedLinker} method on the factory, or even better,
- * simply use {@link DefaultBootstrapper}.
- *
The performance of the programs can depend on your choice of the class to represent call sites. The above
- * example used {@link MonomorphicCallSite}, but you might want to use {@link ChainedCallSite} instead. You'll need to
- * experiment and decide what fits your language runtime the best. You can subclass either of these or roll your own if
- * you need to.
- *
You also need to provide {@link CallSiteDescriptor}s to your call sites. They are immutable objects that contain
- * all the information about the call site: the class performing the lookups, the name of the method being invoked, and
- * the method signature. The library has a default {@link CallSiteDescriptorFactory} for descriptors that you can use,
- * or you can create your own descriptor classes, especially if you need to add further information (values passed in
+ *
+ *
You're expected to provide a {@link GuardingDynamicLinker} for your own
+ * language. If your runtime doesn't have its own language and/or object model
+ * (i.e., it's a generic scripting shell), you don't need to implement a dynamic
+ * linker; you would simply not invoke the {@code setPrioritizedLinker} method
+ * on the factory, or even better, simply use {@link DefaultBootstrapper}.
+ *
+ *
The performance of the programs can depend on your choice of the class to
+ * represent call sites. The above example used {@link MonomorphicCallSite}, but
+ * you might want to use {@link ChainedCallSite} instead. You'll need to
+ * experiment and decide what fits your language runtime the best. You can
+ * subclass either of these or roll your own if you need to.
+ *
+ *
You also need to provide {@link CallSiteDescriptor}s to your call sites.
+ * They are immutable objects that contain all the information about the call
+ * site: the class performing the lookups, the name of the method being invoked,
+ * and the method signature. The library has a default {@link CallSiteDescriptorFactory}
+ * for descriptors that you can use, or you can create your own descriptor
+ * classes, especially if you need to add further information (values passed in
* additional parameters to the bootstrap method) to them.
+ *
*
*
* @author Attila Szegedi
@@ -176,11 +186,15 @@
}
/**
- * Links an invokedynamic call site. It will install a method handle into the call site that invokes the relinking
- * mechanism of this linker. Next time the call site is invoked, it will be linked for the actual arguments it was
- * invoked with.
+ * Links an invokedynamic call site. It will install a method handle into
+ * the call site that invokes the relinking mechanism of this linker. Next
+ * time the call site is invoked, it will be linked for the actual arguments
+ * it was invoked with.
*
+ * @param the particular subclass of {@link RelinkableCallSite} for
+ * which to create a link.
* @param callSite the call site to link.
+ *
* @return the callSite, for easy call chaining.
*/
public T link(final T callSite) {
@@ -189,10 +203,13 @@
}
/**
- * Returns the object representing the lower level linker services of this class that are normally exposed to
- * individual language-specific linkers. While as a user of this class you normally only care about the
- * {@link #link(RelinkableCallSite)} method, in certain circumstances you might want to use the lower level services
- * directly; either to lookup specific method handles, to access the type converters, and so on.
+ * Returns the object representing the lower level linker services of this
+ * class that are normally exposed to individual language-specific linkers.
+ * While as a user of this class you normally only care about the
+ * {@link #link(RelinkableCallSite)} method, in certain circumstances you
+ * might want to use the lower level services directly; either to lookup
+ * specific method handles, to access the type converters, and so on.
+ *
* @return the object representing the linker services of this class.
*/
public LinkerServices getLinkerServices() {
@@ -218,7 +235,9 @@
*
* @param callSite the call site itself
* @param arguments arguments to the invocation
+ *
* @return return the method handle for the invocation
+ *
* @throws Exception rethrows any exception thrown by the linkers
*/
@SuppressWarnings("unused")
@@ -272,11 +291,15 @@
}
/**
- * Returns a stack trace element describing the location of the call site currently being linked on the current
- * thread. The operation internally creates a Throwable object and inspects its stack trace, so it's potentially
- * expensive. The recommended usage for it is in writing diagnostics code.
- * @return a stack trace element describing the location of the call site currently being linked, or null if it is
- * not invoked while a call site is being linked.
+ * Returns a stack trace element describing the location of the call site
+ * currently being linked on the current thread. The operation internally
+ * creates a Throwable object and inspects its stack trace, so it's
+ * potentially expensive. The recommended usage for it is in writing
+ * diagnostics code.
+ *
+ * @return a stack trace element describing the location of the call site
+ * currently being linked, or null if it is not invoked while a call
+ * site is being linked.
*/
public static StackTraceElement getLinkedCallSiteLocation() {
final StackTraceElement[] trace = new Throwable().getStackTrace();
@@ -290,8 +313,10 @@
}
/**
- * Deprecated because of not precise name.
+ * Deprecated because of imprecise name.
+ *
* @deprecated Use {@link #getLinkedCallSiteLocation()} instead.
+ *
* @return see non-deprecated method
*/
@Deprecated
@@ -300,20 +325,26 @@
}
/**
- * Returns true if the frame represents {@code MethodHandleNatives.linkCallSite()}, the frame immediately on top of
- * the call site frame when the call site is being linked for the first time.
+ * Returns {@code true} if the frame represents {@code MethodHandleNatives.linkCallSite()},
+ * the frame immediately on top of the call site frame when the call site is
+ * being linked for the first time.
+ *
* @param frame the frame
- * @return true if this frame represents {@code MethodHandleNatives.linkCallSite()}
+ *
+ * @return {@code true} if this frame represents {@code MethodHandleNatives.linkCallSite()}.
*/
private static boolean isInitialLinkFrame(final StackTraceElement frame) {
return testFrame(frame, INITIAL_LINK_METHOD_NAME, INITIAL_LINK_CLASS_NAME);
}
/**
- * Returns true if the frame represents {@code DynamicLinker.relink()}, the frame immediately on top of the call
- * site frame when the call site is being relinked (linked for second and subsequent times).
+ * Returns {@code true} if the frame represents {@code DynamicLinker.relink()},
+ * the frame immediately on top of the call site frame when the call site is
+ * being relinked (linked for second and subsequent times).
+ *
* @param frame the frame
- * @return true if this frame represents {@code DynamicLinker.relink()}
+ *
+ * @return {@code true} if this frame represents {@code DynamicLinker.relink()}.
*/
private static boolean isRelinkFrame(final StackTraceElement frame) {
return testFrame(frame, RELINK_METHOD_NAME, CLASS_NAME);
diff -r 97f4fef2d420 -r a9714a11e787 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Thu Jun 11 20:20:05 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Wed Jul 05 20:37:58 2017 +0200
@@ -178,8 +178,7 @@
* denies {@code RuntimePermission("nashorn.setConfig")}
*/
public ScriptEngine getScriptEngine(final ClassFilter classFilter) {
- Objects.requireNonNull(classFilter);
- return newEngine(DEFAULT_OPTIONS, getAppClassLoader(), classFilter);
+ return newEngine(DEFAULT_OPTIONS, getAppClassLoader(), Objects.requireNonNull(classFilter));
}
/**
@@ -193,8 +192,7 @@
* denies {@code RuntimePermission("nashorn.setConfig")}
*/
public ScriptEngine getScriptEngine(final String... args) {
- Objects.requireNonNull(args);
- return newEngine(args, getAppClassLoader(), null);
+ return newEngine(Objects.requireNonNull(args), getAppClassLoader(), null);
}
/**
@@ -209,8 +207,7 @@
* denies {@code RuntimePermission("nashorn.setConfig")}
*/
public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader) {
- Objects.requireNonNull(args);
- return newEngine(args, appLoader, null);
+ return newEngine(Objects.requireNonNull(args), appLoader, null);
}
/**
@@ -226,9 +223,7 @@
* denies {@code RuntimePermission("nashorn.setConfig")}
*/
public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) {
- Objects.requireNonNull(args);
- Objects.requireNonNull(classFilter);
- return newEngine(args, appLoader, classFilter);
+ return newEngine(Objects.requireNonNull(args), appLoader, Objects.requireNonNull(classFilter));
}
private ScriptEngine newEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) {
diff -r 97f4fef2d420 -r a9714a11e787 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptObjectMirror.java
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptObjectMirror.java Thu Jun 11 20:20:05 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptObjectMirror.java Wed Jul 05 20:37:58 2017 +0200
@@ -255,14 +255,12 @@
@Override
public void removeMember(final String name) {
- Objects.requireNonNull(name);
- remove(name);
+ remove(Objects.requireNonNull(name));
}
@Override
public void setMember(final String name, final Object value) {
- Objects.requireNonNull(name);
- put(name, value);
+ put(Objects.requireNonNull(name), value);
}
@Override
@@ -429,7 +427,7 @@
@Override
public void putAll(final Map extends String, ? extends Object> map) {
- Objects.requireNonNull(map, "map is null");
+ Objects.requireNonNull(map);
final ScriptObject oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
inGlobal(new Callable