From 3a1062775ada000b51703c3c38acaf5f7eab3bdf Mon Sep 17 00:00:00 2001 From: Andreas Eriksson Date: Thu, 18 Feb 2016 16:15:15 +0100 Subject: [PATCH 01/27] 8149743: JVM crash after debugger hotswap with lambdas Reviewed-by: sspitsyn, coleenp, dcubed --- .../com/sun/jdi/RedefineAddPrivateMethod.sh | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 jdk/test/com/sun/jdi/RedefineAddPrivateMethod.sh diff --git a/jdk/test/com/sun/jdi/RedefineAddPrivateMethod.sh b/jdk/test/com/sun/jdi/RedefineAddPrivateMethod.sh new file mode 100644 index 00000000000..bb9eefd8968 --- /dev/null +++ b/jdk/test/com/sun/jdi/RedefineAddPrivateMethod.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +# +# Copyright (c) 2016, 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 8149743 +# @summary crash when adding a breakpoint after redefining to add a private static method +# @run shell RedefineAddPrivateMethod.sh + +compileOptions=-g + +createJavaFile() +{ + cat < $1.java.1 +public class $1 { + static public void main(String[] args) { + // @1 breakpoint @2 breakpoint + } + + // @1 uncomment private static void test() {} +} +EOF +} + +# This is called to feed cmds to jdb. +dojdbCmds() +{ + setBkpts @1 + runToBkpt @1 + redefineClass @1 + setBkpts @2 + cmd allowExit cont +} + + +mysetup() +{ + if [ -z "$TESTSRC" ] ; then + TESTSRC=. + fi + + for ii in . $TESTSRC $TESTSRC/.. ; do + if [ -r "$ii/ShellScaffold.sh" ] ; then + . $ii/ShellScaffold.sh + break + fi + done +} + +# You could replace this next line with the contents +# of ShellScaffold.sh and this script will run just the same. +mysetup + +runit +debuggeeFailIfPresent "Internal exception:" +pass From ef5eb42e40bfd979df5b4acd6a77e71134f71a15 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 23 Feb 2016 17:55:28 +0300 Subject: [PATCH 02/27] 8150180: String.value contents should be trusted Reviewed-by: vlivanov, redestad, jrose, twisti --- .../share/classes/java/lang/String.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/jdk/src/java.base/share/classes/java/lang/String.java b/jdk/src/java.base/share/classes/java/lang/String.java index 86ec043d5b1..85d22cbc1ec 100644 --- a/jdk/src/java.base/share/classes/java/lang/String.java +++ b/jdk/src/java.base/share/classes/java/lang/String.java @@ -42,6 +42,7 @@ import java.util.regex.PatternSyntaxException; import java.util.stream.IntStream; import java.util.stream.StreamSupport; import jdk.internal.HotSpotIntrinsicCandidate; +import jdk.internal.vm.annotation.Stable; /** * The {@code String} class represents character strings. All @@ -119,7 +120,18 @@ import jdk.internal.HotSpotIntrinsicCandidate; public final class String implements java.io.Serializable, Comparable, CharSequence { - /** The value is used for character storage. */ + /** + * The value is used for character storage. + * + * @implNote This field is trusted by the VM, and is a subject to + * constant folding if String instance is constant. Overwriting this + * field after construction will cause problems. + * + * Additionally, it is marked with {@link Stable} to trust the contents + * of the array. No other facility in JDK provides this functionality (yet). + * {@link Stable} is safe here, because value is never null. + */ + @Stable private final byte[] value; /** @@ -129,6 +141,9 @@ public final class String * LATIN1 * UTF16 * + * @implNote This field is trusted by the VM, and is a subject to + * constant folding if String instance is constant. Overwriting this + * field after construction will cause problems. */ private final byte coder; From 7386fd03857982ae1ab216e8c093a5e17ae7229f Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 23 Feb 2016 22:10:02 +0300 Subject: [PATCH 03/27] 8148146: Integrate new internal Unsafe entry points, and basic intrinsic support for VarHandles Reviewed-by: psandoz, kvn, jrose, adinn, simonis, coleenp --- .../classes/jdk/internal/misc/Unsafe.java | 355 ++++++++++++++++++ 1 file changed, 355 insertions(+) diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java index 5818d4835a1..8905977111b 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java @@ -782,6 +782,46 @@ public final class Unsafe { Object expected, Object x); + @HotSpotIntrinsicCandidate + public final native Object compareAndExchangeObjectVolatile(Object o, long offset, + Object expected, + Object x); + + @HotSpotIntrinsicCandidate + public final Object compareAndExchangeObjectAcquire(Object o, long offset, + Object expected, + Object x) { + return compareAndExchangeObjectVolatile(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final Object compareAndExchangeObjectRelease(Object o, long offset, + Object expected, + Object x) { + return compareAndExchangeObjectVolatile(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapObject(Object o, long offset, + Object expected, + Object x) { + return compareAndSwapObject(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapObjectAcquire(Object o, long offset, + Object expected, + Object x) { + return compareAndSwapObject(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapObjectRelease(Object o, long offset, + Object expected, + Object x) { + return compareAndSwapObject(o, offset, expected, x); + } + /** * Atomically updates Java variable to {@code x} if it is currently * holding {@code expected}. @@ -796,6 +836,46 @@ public final class Unsafe { int expected, int x); + @HotSpotIntrinsicCandidate + public final native int compareAndExchangeIntVolatile(Object o, long offset, + int expected, + int x); + + @HotSpotIntrinsicCandidate + public final int compareAndExchangeIntAcquire(Object o, long offset, + int expected, + int x) { + return compareAndExchangeIntVolatile(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final int compareAndExchangeIntRelease(Object o, long offset, + int expected, + int x) { + return compareAndExchangeIntVolatile(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapInt(Object o, long offset, + int expected, + int x) { + return compareAndSwapInt(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapIntAcquire(Object o, long offset, + int expected, + int x) { + return compareAndSwapInt(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapIntRelease(Object o, long offset, + int expected, + int x) { + return compareAndSwapInt(o, offset, expected, x); + } + /** * Atomically updates Java variable to {@code x} if it is currently * holding {@code expected}. @@ -810,6 +890,46 @@ public final class Unsafe { long expected, long x); + @HotSpotIntrinsicCandidate + public final native long compareAndExchangeLongVolatile(Object o, long offset, + long expected, + long x); + + @HotSpotIntrinsicCandidate + public final long compareAndExchangeLongAcquire(Object o, long offset, + long expected, + long x) { + return compareAndExchangeLongVolatile(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final long compareAndExchangeLongRelease(Object o, long offset, + long expected, + long x) { + return compareAndExchangeLongVolatile(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapLong(Object o, long offset, + long expected, + long x) { + return compareAndSwapLong(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapLongAcquire(Object o, long offset, + long expected, + long x) { + return compareAndSwapLong(o, offset, expected, x); + } + + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapLongRelease(Object o, long offset, + long expected, + long x) { + return compareAndSwapLong(o, offset, expected, x); + } + /** * Fetches a reference value from a given Java variable, with volatile * load semantics. Otherwise identical to {@link #getObject(Object, long)} @@ -908,6 +1028,224 @@ public final class Unsafe { @HotSpotIntrinsicCandidate public native void putOrderedLong(Object o, long offset, long x); + /** Acquire version of {@link #getObjectVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final Object getObjectAcquire(Object o, long offset) { + return getObjectVolatile(o, offset); + } + + /** Acquire version of {@link #getBooleanVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final boolean getBooleanAcquire(Object o, long offset) { + return getBooleanVolatile(o, offset); + } + + /** Acquire version of {@link #getByteVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final byte getByteAcquire(Object o, long offset) { + return getByteVolatile(o, offset); + } + + /** Acquire version of {@link #getShortVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final short getShortAcquire(Object o, long offset) { + return getShortVolatile(o, offset); + } + + /** Acquire version of {@link #getCharVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final char getCharAcquire(Object o, long offset) { + return getCharVolatile(o, offset); + } + + /** Acquire version of {@link #getIntVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final int getIntAcquire(Object o, long offset) { + return getIntVolatile(o, offset); + } + + /** Acquire version of {@link #getFloatVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final float getFloatAcquire(Object o, long offset) { + return getFloatVolatile(o, offset); + } + + /** Acquire version of {@link #getLongVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final long getLongAcquire(Object o, long offset) { + return getLongVolatile(o, offset); + } + + /** Acquire version of {@link #getDoubleVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final double getDoubleAcquire(Object o, long offset) { + return getDoubleVolatile(o, offset); + } + + /** Release version of {@link #putObjectVolatile(Object, long, Object)} */ + @HotSpotIntrinsicCandidate + public final void putObjectRelease(Object o, long offset, Object x) { + putObjectVolatile(o, offset, x); + } + + /** Release version of {@link #putBooleanVolatile(Object, long, boolean)} */ + @HotSpotIntrinsicCandidate + public final void putBooleanRelease(Object o, long offset, boolean x) { + putBooleanVolatile(o, offset, x); + } + + /** Release version of {@link #putByteVolatile(Object, long, byte)} */ + @HotSpotIntrinsicCandidate + public final void putByteRelease(Object o, long offset, byte x) { + putByteVolatile(o, offset, x); + } + + /** Release version of {@link #putShortVolatile(Object, long, short)} */ + @HotSpotIntrinsicCandidate + public final void putShortRelease(Object o, long offset, short x) { + putShortVolatile(o, offset, x); + } + + /** Release version of {@link #putCharVolatile(Object, long, char)} */ + @HotSpotIntrinsicCandidate + public final void putCharRelease(Object o, long offset, char x) { + putCharVolatile(o, offset, x); + } + + /** Release version of {@link #putIntVolatile(Object, long, int)} */ + @HotSpotIntrinsicCandidate + public final void putIntRelease(Object o, long offset, int x) { + putIntVolatile(o, offset, x); + } + + /** Release version of {@link #putFloatVolatile(Object, long, float)} */ + @HotSpotIntrinsicCandidate + public final void putFloatRelease(Object o, long offset, float x) { + putFloatVolatile(o, offset, x); + } + + /** Release version of {@link #putLongVolatile(Object, long, long)} */ + @HotSpotIntrinsicCandidate + public final void putLongRelease(Object o, long offset, long x) { + putLongVolatile(o, offset, x); + } + + /** Release version of {@link #putDoubleVolatile(Object, long, double)} */ + @HotSpotIntrinsicCandidate + public final void putDoubleRelease(Object o, long offset, double x) { + putDoubleVolatile(o, offset, x); + } + + // ------------------------------ Opaque -------------------------------------- + + /** Opaque version of {@link #getObjectVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final Object getObjectOpaque(Object o, long offset) { + return getObjectVolatile(o, offset); + } + + /** Opaque version of {@link #getBooleanVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final boolean getBooleanOpaque(Object o, long offset) { + return getBooleanVolatile(o, offset); + } + + /** Opaque version of {@link #getByteVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final byte getByteOpaque(Object o, long offset) { + return getByteVolatile(o, offset); + } + + /** Opaque version of {@link #getShortVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final short getShortOpaque(Object o, long offset) { + return getShortVolatile(o, offset); + } + + /** Opaque version of {@link #getCharVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final char getCharOpaque(Object o, long offset) { + return getCharVolatile(o, offset); + } + + /** Opaque version of {@link #getIntVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final int getIntOpaque(Object o, long offset) { + return getIntVolatile(o, offset); + } + + /** Opaque version of {@link #getFloatVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final float getFloatOpaque(Object o, long offset) { + return getFloatVolatile(o, offset); + } + + /** Opaque version of {@link #getLongVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final long getLongOpaque(Object o, long offset) { + return getLongVolatile(o, offset); + } + + /** Opaque version of {@link #getDoubleVolatile(Object, long)} */ + @HotSpotIntrinsicCandidate + public final double getDoubleOpaque(Object o, long offset) { + return getDoubleVolatile(o, offset); + } + + /** Opaque version of {@link #putObjectVolatile(Object, long, Object)} */ + @HotSpotIntrinsicCandidate + public final void putObjectOpaque(Object o, long offset, Object x) { + putObjectVolatile(o, offset, x); + } + + /** Opaque version of {@link #putBooleanVolatile(Object, long, boolean)} */ + @HotSpotIntrinsicCandidate + public final void putBooleanOpaque(Object o, long offset, boolean x) { + putBooleanVolatile(o, offset, x); + } + + /** Opaque version of {@link #putByteVolatile(Object, long, byte)} */ + @HotSpotIntrinsicCandidate + public final void putByteOpaque(Object o, long offset, byte x) { + putByteVolatile(o, offset, x); + } + + /** Opaque version of {@link #putShortVolatile(Object, long, short)} */ + @HotSpotIntrinsicCandidate + public final void putShortOpaque(Object o, long offset, short x) { + putShortVolatile(o, offset, x); + } + + /** Opaque version of {@link #putCharVolatile(Object, long, char)} */ + @HotSpotIntrinsicCandidate + public final void putCharOpaque(Object o, long offset, char x) { + putCharVolatile(o, offset, x); + } + + /** Opaque version of {@link #putIntVolatile(Object, long, int)} */ + @HotSpotIntrinsicCandidate + public final void putIntOpaque(Object o, long offset, int x) { + putIntVolatile(o, offset, x); + } + + /** Opaque version of {@link #putFloatVolatile(Object, long, float)} */ + @HotSpotIntrinsicCandidate + public final void putFloatOpaque(Object o, long offset, float x) { + putFloatVolatile(o, offset, x); + } + + /** Opaque version of {@link #putLongVolatile(Object, long, long)} */ + @HotSpotIntrinsicCandidate + public final void putLongOpaque(Object o, long offset, long x) { + putLongVolatile(o, offset, x); + } + + /** Opaque version of {@link #putDoubleVolatile(Object, long, double)} */ + @HotSpotIntrinsicCandidate + public final void putDoubleOpaque(Object o, long offset, double x) { + putDoubleVolatile(o, offset, x); + } + /** * Unblocks the given thread blocked on {@code park}, or, if it is * not blocked, causes the subsequent call to {@code park} not to @@ -1100,6 +1438,23 @@ public final class Unsafe { @HotSpotIntrinsicCandidate public native void fullFence(); + /** + * Ensures that loads before the fence will not be reordered with + * loads after the fence. + */ + public final void loadLoadFence() { + loadFence(); + } + + /** + * Ensures that stores before the fence will not be reordered with + * stores after the fence. + */ + public final void storeStoreFence() { + storeFence(); + } + + /** * Throws IllegalAccessError; for use by the VM for access control * error support. From fb338bec25d6a355f2baabff7dff7e220947d73a Mon Sep 17 00:00:00 2001 From: Christian Tornqvist Date: Wed, 24 Feb 2016 16:33:19 -0500 Subject: [PATCH 04/27] 8150490: Update OS detection code to recognize Windows Server 2016 Reviewed-by: mgronlun, alanb, dholmes --- jdk/src/java.base/windows/native/libjava/java_props_md.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/src/java.base/windows/native/libjava/java_props_md.c b/jdk/src/java.base/windows/native/libjava/java_props_md.c index 135976483b6..382a35a571e 100644 --- a/jdk/src/java.base/windows/native/libjava/java_props_md.c +++ b/jdk/src/java.base/windows/native/libjava/java_props_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, 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 @@ -469,7 +469,9 @@ GetJavaProperties(JNIEnv* env) * Windows Server 2008 R2 6 1 (!VER_NT_WORKSTATION) * Windows 8 6 2 (VER_NT_WORKSTATION) * Windows Server 2012 6 2 (!VER_NT_WORKSTATION) + * Windows Server 2012 R2 6 3 (!VER_NT_WORKSTATION) * Windows 10 10 0 (VER_NT_WORKSTATION) + * Windows Server 2016 10 0 (!VER_NT_WORKSTATION) * * This mapping will presumably be augmented as new Windows * versions are released. @@ -543,6 +545,7 @@ GetJavaProperties(JNIEnv* env) } } else { switch (minorVersion) { + case 0: sprops.os_name = "Windows Server 2016"; break; default: sprops.os_name = "Windows NT (unknown)"; } } From b9e4cabc43b60bda1413055ad382c368055bfcc5 Mon Sep 17 00:00:00 2001 From: Cheleswer Sahu Date: Fri, 26 Feb 2016 16:19:04 +0530 Subject: [PATCH 05/27] 8130425: libjvm crash due to stack overflow in executables with 32k tbss/tdata Reviewed-by: kevinw, dholmes --- .../java.base/share/classes/java/lang/ProcessHandleImpl.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java index e5fcb94d1b9..91fa5623174 100644 --- a/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java @@ -81,9 +81,8 @@ final class ProcessHandleImpl implements ProcessHandle { ThreadGroup systemThreadGroup = tg; ThreadFactory threadFactory = grimReaper -> { - // Our thread stack requirement is quite modest. - Thread t = new Thread(systemThreadGroup, grimReaper, - "process reaper", 32768); + long stackSize = Boolean.getBoolean("jdk.lang.processReaperUseDefaultStackSize") ? 0 : 32768; + Thread t = new Thread(systemThreadGroup, grimReaper, "process reaper", stackSize); t.setDaemon(true); // A small attempt (probably futile) to avoid priority inversion t.setPriority(Thread.MAX_PRIORITY); From dc8f45fc7dad5c788afc1f8317aa27ef3546df55 Mon Sep 17 00:00:00 2001 From: Zoltan Majo Date: Mon, 29 Feb 2016 07:58:45 +0100 Subject: [PATCH 06/27] 8148940: java/lang/ref/FinalizeOverride.java can time out due to frequent safepointing Reduce the freqency of triggering GCs by sleeping between GCs. Reviewed-by: thartmann, shade --- jdk/test/java/lang/ref/FinalizeOverride.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/jdk/test/java/lang/ref/FinalizeOverride.java b/jdk/test/java/lang/ref/FinalizeOverride.java index eeb86fe4ab2..7701f5844ea 100644 --- a/jdk/test/java/lang/ref/FinalizeOverride.java +++ b/jdk/test/java/lang/ref/FinalizeOverride.java @@ -29,7 +29,7 @@ import java.nio.file.Paths; import java.util.concurrent.atomic.AtomicInteger; /* @test - * @bug 8027351 + * @bug 8027351 8148940 * @summary Basic test of the finalize method */ @@ -63,6 +63,19 @@ public class FinalizeOverride { while (finalizedCount.get() != (count+1)) { System.gc(); System.runFinalization(); + // Running System.gc() and System.runFinalization() in a + // tight loop can trigger frequent safepointing that slows + // down the VM and, as a result, the test. (With the + // HotSpot VM, the effect of frequent safepointing is + // especially noticeable if the test is run with the + // -Xcomp flag.) Sleeping for a second after every + // garbage collection and finalization cycle gives the VM + // time to make progress. + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + System.out.println("Main thread interrupted, continuing execution."); + } } if (privateFinalizeInvoked) { From 85ee898a02cff9cec1d4636ba198085db1694d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Tue, 1 Mar 2016 23:54:05 +0100 Subject: [PATCH 07/27] 8143235: Remove libjfr mapfile Reviewed-by: jbachorik, egahlin --- jdk/make/mapfiles/libjfr/mapfile-vers | 45 ------------------- .../classes/build/tools/module/boot.modules | 1 + 2 files changed, 1 insertion(+), 45 deletions(-) delete mode 100644 jdk/make/mapfiles/libjfr/mapfile-vers diff --git a/jdk/make/mapfiles/libjfr/mapfile-vers b/jdk/make/mapfiles/libjfr/mapfile-vers deleted file mode 100644 index 0bb2cbcb8bc..00000000000 --- a/jdk/make/mapfiles/libjfr/mapfile-vers +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. -# ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. -# - -# Define library interface. - -SUNWprivate_1.1 { - global: - Java_oracle_jrockit_jfr_Process_getpid; - Java_oracle_jrockit_jfr_Timing_counterTime; - Java_oracle_jrockit_jfr_Timing_init; - Java_oracle_jrockit_jfr_Logger_output0; - Java_oracle_jrockit_jfr_JFR_isCommercialFeaturesUnlocked; - Java_oracle_jrockit_jfr_JFR_isStarted; - Java_oracle_jrockit_jfr_JFR_isSupportedInVM; - Java_oracle_jrockit_jfr_JFR_startFlightRecorder; - Java_oracle_jrockit_jfr_JFR_isDisabledOnCommandLine; - Java_oracle_jrockit_jfr_JFR_isEnabled; - Java_oracle_jrockit_jfr_VMJFR_options; - Java_oracle_jrockit_jfr_VMJFR_init; - Java_oracle_jrockit_jfr_VMJFR_addConstPool; - Java_oracle_jrockit_jfr_VMJFR_removeConstPool; - Java_oracle_jrockit_jfr_VMJFR_storeConstPool; - Java_oracle_jrockit_jfr_VMJFR_classID0; - Java_oracle_jrockit_jfr_VMJFR_stackTraceID; - Java_oracle_jrockit_jfr_VMJFR_threadID; - Java_oracle_jrockit_jfr_VMJFR_rotate; - Java_oracle_jrockit_jfr_VMJFR_shutdown; - Java_oracle_jrockit_jfr_VMJFR_start; - Java_oracle_jrockit_jfr_VMJFR_stop; - Java_oracle_jrockit_jfr_VMJFR_buffer; - Java_oracle_jrockit_jfr_VMJFR_flush; - Java_oracle_jrockit_jfr_VMJFR_write; - Java_oracle_jrockit_jfr_VMJFR_add; - Java_oracle_jrockit_jfr_VMJFR_remove; - Java_oracle_jrockit_jfr_VMJFR_setThreshold; - Java_oracle_jrockit_jfr_VMJFR_setPeriod; - Java_oracle_jrockit_jfr_VMJFR_getPeriod; - Java_oracle_jrockit_jfr_VMJFR_descriptors; - Java_oracle_jrockit_jfr_VMJFR_retransformClasses0; - JNI_OnLoad; - local: - *; -}; diff --git a/jdk/make/src/classes/build/tools/module/boot.modules b/jdk/make/src/classes/build/tools/module/boot.modules index a22b4af52b9..5bac3ea896c 100644 --- a/jdk/make/src/classes/build/tools/module/boot.modules +++ b/jdk/make/src/classes/build/tools/module/boot.modules @@ -27,6 +27,7 @@ jdk.vm.cds jdk.vm.ci jdk.management jdk.management.cmm +jdk.management.jfr jdk.management.resource jdk.naming.rmi jdk.sctp From 29383473b186a5afe2144e6944e86b85dea4cb7e Mon Sep 17 00:00:00 2001 From: Rachel Protacio Date: Wed, 2 Mar 2016 14:52:35 -0500 Subject: [PATCH 08/27] 8145098: JNI GetVersion should return JNI_VERSION_9 Updated JNI_VERSION for current version to be JNI_VERSION_9 Reviewed-by: hseigel, gtriantafill, dholmes, alanb --- jdk/src/java.base/share/native/include/jni.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/src/java.base/share/native/include/jni.h b/jdk/src/java.base/share/native/include/jni.h index 2e83cb7e06e..c09658a1fa7 100644 --- a/jdk/src/java.base/share/native/include/jni.h +++ b/jdk/src/java.base/share/native/include/jni.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -1952,6 +1952,7 @@ JNI_OnUnload(JavaVM *vm, void *reserved); #define JNI_VERSION_1_4 0x00010004 #define JNI_VERSION_1_6 0x00010006 #define JNI_VERSION_1_8 0x00010008 +#define JNI_VERSION_9 0x00090000 #ifdef __cplusplus } /* extern "C" */ From 41988936d3f33e2526cc00fa6f97bfd86de7c915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Wed, 2 Mar 2016 21:39:03 +0100 Subject: [PATCH 09/27] 8151053: com/sun/jdi/StepTest.java fails in 2016-03-01 JDK9-hs-rt nightly Reviewed-by: dcubed, egahlin --- jdk/test/com/sun/jdi/TestScaffold.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/test/com/sun/jdi/TestScaffold.java b/jdk/test/com/sun/jdi/TestScaffold.java index 079733509e0..f221221a1de 100644 --- a/jdk/test/com/sun/jdi/TestScaffold.java +++ b/jdk/test/com/sun/jdi/TestScaffold.java @@ -752,6 +752,7 @@ abstract public class TestScaffold extends TargetAdapter { sr.addClassExclusionFilter("com.oracle.*"); sr.addClassExclusionFilter("oracle.*"); sr.addClassExclusionFilter("jdk.internal.*"); + sr.addClassExclusionFilter("jdk.jfr.*"); sr.addCountFilter(1); sr.enable(); StepEvent retEvent = (StepEvent)waitForRequestedEvent(sr); From 20ebb13fb50590c35fee37e72c6543b9ecfe9914 Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Thu, 3 Mar 2016 08:58:00 +0100 Subject: [PATCH 10/27] 8151024: Remove TCKJapaneseChronology.java from the problem list Remove TCKJapaneseChronology.java from the problem list after JDK-8134979 was fixed. Reviewed-by: vlivanov --- jdk/test/ProblemList.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 8e1c6a6a1e1..5296f830828 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -334,9 +334,6 @@ javax/imageio/plugins/tiff/WriteToSequenceAfterAbort.java generic-all # jdk_time -# 8134979 -java/time/tck/java/time/chrono/TCKJapaneseChronology.java generic-all - ############################################################################ # jdk_tools From b9210004c4679729da0c166c24024c5baec0339d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Thu, 3 Mar 2016 12:34:55 +0100 Subject: [PATCH 11/27] 8151100: Test java/lang/instrument/NativeMethodPrefixAgent.java can't attempt to do CheckIntrinsics Reviewed-by: sspitsyn, ddmitriev, egahlin --- jdk/test/java/lang/instrument/NativeMethodPrefixAgent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/java/lang/instrument/NativeMethodPrefixAgent.java b/jdk/test/java/lang/instrument/NativeMethodPrefixAgent.java index 8c209c1b87e..4522d8b1055 100644 --- a/jdk/test/java/lang/instrument/NativeMethodPrefixAgent.java +++ b/jdk/test/java/lang/instrument/NativeMethodPrefixAgent.java @@ -31,7 +31,7 @@ * java.management * java.instrument * @run shell/timeout=240 MakeJAR2.sh NativeMethodPrefixAgent NativeMethodPrefixApp 'Can-Retransform-Classes: true' 'Can-Set-Native-Method-Prefix: true' - * @run main/othervm -javaagent:NativeMethodPrefixAgent.jar NativeMethodPrefixApp + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:-CheckIntrinsics -javaagent:NativeMethodPrefixAgent.jar NativeMethodPrefixApp */ import java.lang.instrument.*; From 832b46f2fa45890f2d079a7b91d2ffb08125beff Mon Sep 17 00:00:00 2001 From: Andreas Eriksson Date: Thu, 3 Mar 2016 18:05:48 +0100 Subject: [PATCH 12/27] 8151064: com/sun/jdi/RedefineAddPrivateMethod.sh fails intermittently Reviewed-by: dsamersoff, sspitsyn --- jdk/test/com/sun/jdi/RedefineAddPrivateMethod.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jdk/test/com/sun/jdi/RedefineAddPrivateMethod.sh b/jdk/test/com/sun/jdi/RedefineAddPrivateMethod.sh index bb9eefd8968..d91f74ab85c 100644 --- a/jdk/test/com/sun/jdi/RedefineAddPrivateMethod.sh +++ b/jdk/test/com/sun/jdi/RedefineAddPrivateMethod.sh @@ -35,7 +35,8 @@ createJavaFile() cat < $1.java.1 public class $1 { static public void main(String[] args) { - // @1 breakpoint @2 breakpoint + System.out.println("@1 breakpoint"); + System.out.println("@2 breakpoint"); } // @1 uncomment private static void test() {} @@ -50,7 +51,8 @@ dojdbCmds() runToBkpt @1 redefineClass @1 setBkpts @2 - cmd allowExit cont + runToBkpt @2 + cmd exitJdb } From 8041d8453e9f8f707e239cf485a8fb677df24b5f Mon Sep 17 00:00:00 2001 From: Felix Yang Date: Tue, 8 Mar 2016 09:33:31 +0800 Subject: [PATCH 13/27] 8151352: jdk/test/sample fails with "effective library path is outside the test suite" Reviewed-by: darcy --- jdk/test/sample/TEST.properties | 1 + jdk/test/sample/chatserver/ChatTest.java | 9 ++++++--- jdk/test/sample/mergesort/MergeSortTest.java | 9 ++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 jdk/test/sample/TEST.properties diff --git a/jdk/test/sample/TEST.properties b/jdk/test/sample/TEST.properties new file mode 100644 index 00000000000..8e5f78afde3 --- /dev/null +++ b/jdk/test/sample/TEST.properties @@ -0,0 +1 @@ +external.lib.roots = ../../ diff --git a/jdk/test/sample/chatserver/ChatTest.java b/jdk/test/sample/chatserver/ChatTest.java index 654819b9fa5..dcfe4d3dd6c 100644 --- a/jdk/test/sample/chatserver/ChatTest.java +++ b/jdk/test/sample/chatserver/ChatTest.java @@ -25,9 +25,9 @@ /* @test * @summary Test chat server chatserver test * - * @library ../../../src/sample/share/nio/chatserver + * @library /src/sample/share/nio/chatserver * @build ChatTest ChatServer Client ClientReader DataReader MessageReader NameReader - * @run main ChatTest + * @run testng ChatTest */ import java.io.*; @@ -38,10 +38,13 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.CyclicBarrier; +import org.testng.annotations.Test; + public class ChatTest { public static int listeningPort = 0; - public static void main(String[] args) throws Throwable { + @Test + public static void doTest() throws Throwable { testStartStop(); testPortOpen(); testAsksForName(); diff --git a/jdk/test/sample/mergesort/MergeSortTest.java b/jdk/test/sample/mergesort/MergeSortTest.java index e38a0e03413..fb082c21a56 100644 --- a/jdk/test/sample/mergesort/MergeSortTest.java +++ b/jdk/test/sample/mergesort/MergeSortTest.java @@ -25,14 +25,16 @@ /* @test * @summary Test MergeSort * - * @library ../../../src/sample/share/forkjoin/mergesort + * @library /src/sample/share/forkjoin/mergesort * @build MergeSortTest MergeDemo MergeSort - * @run main MergeSortTest + * @run testng MergeSortTest */ import java.util.Arrays; import java.util.Random; +import org.testng.annotations.Test; + public class MergeSortTest { private Random random; private MergeSort target; @@ -42,7 +44,8 @@ public class MergeSortTest { this.target = target; } - public static void main(String[] args) { + @Test + public static void doTest() { MergeSortTest test = new MergeSortTest(new Random(), new MergeSort(Runtime.getRuntime().availableProcessors() * 4)); test.run(); } From 34313c01e33f7825b3fc6db450ced4b9fd66f0f8 Mon Sep 17 00:00:00 2001 From: Hamlin Li Date: Tue, 8 Mar 2016 11:01:38 +0000 Subject: [PATCH 14/27] 8143610: (dc) java/nio/channels/DatagramChannel/AdaptDatagramSocket.java failed intermittently due to SocketTimeoutException Reviewed-by: alanb --- .../nio/channels/DatagramChannel/AdaptDatagramSocket.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java b/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java index b8ec1c1060b..8b23f14f960 100644 --- a/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java +++ b/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, 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 @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313882 4981129 + * @bug 4313882 4981129 8143610 * @summary Unit test for datagram-socket-channel adaptors * @library .. * @key randomness @@ -137,7 +137,7 @@ public class AdaptDatagramSocket { echoServer.getPort()); test(address, 0, false, false); test(address, 0, false, true); - test(address, 15000, false, false); + test(address, Integer.MAX_VALUE, false, false); } try (TestServers.UdpDiscardServer discardServer = TestServers.UdpDiscardServer.startNewServer()) { From bd69ca08d2ec1b6c77a8389f986d05458cc8672a Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Tue, 8 Mar 2016 12:11:07 +0000 Subject: [PATCH 15/27] 8151384: Improve String.CASE_INSENSITIVE_ORDER and remove sun.misc.ASCIICaseInsensitiveComparator Reviewed-by: shade, sherman --- .../share/classes/java/lang/String.java | 28 +----- .../share/classes/java/lang/StringLatin1.java | 42 ++++++++ .../share/classes/java/lang/StringUTF16.java | 44 +++++++++ .../classes/java/nio/charset/Charset.java | 3 +- .../classes/java/util/jar/Attributes.java | 6 +- .../misc/ASCIICaseInsensitiveComparator.java | 99 ------------------- .../nio/cs/ext/AbstractCharsetProvider.java | 9 +- 7 files changed, 99 insertions(+), 132 deletions(-) delete mode 100644 jdk/src/java.base/share/classes/sun/misc/ASCIICaseInsensitiveComparator.java diff --git a/jdk/src/java.base/share/classes/java/lang/String.java b/jdk/src/java.base/share/classes/java/lang/String.java index 86ec043d5b1..85916e672d9 100644 --- a/jdk/src/java.base/share/classes/java/lang/String.java +++ b/jdk/src/java.base/share/classes/java/lang/String.java @@ -1222,30 +1222,12 @@ public final class String public int compare(String s1, String s2) { byte v1[] = s1.value; byte v2[] = s2.value; - int n1 = s1.length(); - int n2 = s2.length(); - boolean s1IsLatin1 = s1.isLatin1(); - boolean s2IsLatin1 = s2.isLatin1(); - int min = Math.min(n1, n2); - for (int i = 0; i < min; i++) { - char c1 = s1IsLatin1 ? StringLatin1.getChar(v1, i) - : StringUTF16.getChar(v1, i); - char c2 = s2IsLatin1 ? StringLatin1.getChar(v2, i) - : StringUTF16.getChar(v2, i); - if (c1 != c2) { - c1 = Character.toUpperCase(c1); - c2 = Character.toUpperCase(c2); - if (c1 != c2) { - c1 = Character.toLowerCase(c1); - c2 = Character.toLowerCase(c2); - if (c1 != c2) { - // No overflow because of numeric promotion - return c1 - c2; - } - } - } + if (s1.coder() == s2.coder()) { + return s1.isLatin1() ? StringLatin1.compareToCI(v1, v2) + : StringUTF16.compareToCI(v1, v2); } - return n1 - n2; + return s1.isLatin1() ? StringLatin1.compareToCI_UTF16(v1, v2) + : StringUTF16.compareToCI_Latin1(v1, v2); } /** Replaces the de-serialized object. */ diff --git a/jdk/src/java.base/share/classes/java/lang/StringLatin1.java b/jdk/src/java.base/share/classes/java/lang/StringLatin1.java index 8e8016d833e..c491f4833e1 100644 --- a/jdk/src/java.base/share/classes/java/lang/StringLatin1.java +++ b/jdk/src/java.base/share/classes/java/lang/StringLatin1.java @@ -128,6 +128,48 @@ final class StringLatin1 { return len1 - len2; } + public static int compareToCI(byte[] value, byte[] other) { + int len1 = value.length; + int len2 = other.length; + int lim = Math.min(len1, len2); + for (int k = 0; k < lim; k++) { + if (value[k] != other[k]) { + char c1 = (char) CharacterDataLatin1.instance.toUpperCase(getChar(value, k)); + char c2 = (char) CharacterDataLatin1.instance.toUpperCase(getChar(other, k)); + if (c1 != c2) { + c1 = (char) CharacterDataLatin1.instance.toLowerCase(c1); + c2 = (char) CharacterDataLatin1.instance.toLowerCase(c2); + if (c1 != c2) { + return c1 - c2; + } + } + } + } + return len1 - len2; + } + + public static int compareToCI_UTF16(byte[] value, byte[] other) { + int len1 = length(value); + int len2 = StringUTF16.length(other); + int lim = Math.min(len1, len2); + for (int k = 0; k < lim; k++) { + char c1 = getChar(value, k); + char c2 = StringUTF16.getChar(other, k); + if (c1 != c2) { + c1 = Character.toUpperCase(c1); + c2 = Character.toUpperCase(c2); + if (c1 != c2) { + c1 = Character.toLowerCase(c1); + c2 = Character.toLowerCase(c2); + if (c1 != c2) { + return c1 - c2; + } + } + } + } + return len1 - len2; + } + public static int hashCode(byte[] value) { int h = 0; for (byte v : value) { diff --git a/jdk/src/java.base/share/classes/java/lang/StringUTF16.java b/jdk/src/java.base/share/classes/java/lang/StringUTF16.java index 937f642ce8d..fe0c964b290 100644 --- a/jdk/src/java.base/share/classes/java/lang/StringUTF16.java +++ b/jdk/src/java.base/share/classes/java/lang/StringUTF16.java @@ -270,6 +270,50 @@ final class StringUTF16 { return len1 - len2; } + public static int compareToCI(byte[] value, byte[] other) { + int len1 = length(value); + int len2 = length(other); + int lim = Math.min(len1, len2); + for (int k = 0; k < lim; k++) { + char c1 = getChar(value, k); + char c2 = getChar(other, k); + if (c1 != c2) { + c1 = Character.toUpperCase(c1); + c2 = Character.toUpperCase(c2); + if (c1 != c2) { + c1 = Character.toLowerCase(c1); + c2 = Character.toLowerCase(c2); + if (c1 != c2) { + return c1 - c2; + } + } + } + } + return len1 - len2; + } + + public static int compareToCI_Latin1(byte[] value, byte[] other) { + int len1 = length(value); + int len2 = StringLatin1.length(other); + int lim = Math.min(len1, len2); + for (int k = 0; k < lim; k++) { + char c1 = getChar(value, k); + char c2 = StringLatin1.getChar(other, k); + if (c1 != c2) { + c1 = Character.toUpperCase(c1); + c2 = Character.toUpperCase(c2); + if (c1 != c2) { + c1 = Character.toLowerCase(c1); + c2 = Character.toLowerCase(c2); + if (c1 != c2) { + return c1 - c2; + } + } + } + } + return len1 - len2; + } + public static int hashCode(byte[] value) { int h = 0; int length = value.length >> 1; diff --git a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java index de85b2f525c..78ee33e764a 100644 --- a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java +++ b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java @@ -44,7 +44,6 @@ import java.util.ServiceConfigurationError; import java.util.SortedMap; import java.util.TreeMap; import jdk.internal.misc.VM; -import sun.misc.ASCIICaseInsensitiveComparator; import sun.nio.cs.StandardCharsets; import sun.nio.cs.ThreadLocalCoders; import sun.security.action.GetPropertyAction; @@ -579,7 +578,7 @@ public abstract class Charset public SortedMap run() { TreeMap m = new TreeMap<>( - ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER); + String.CASE_INSENSITIVE_ORDER); put(standardProvider.charsets(), m); CharsetProvider[] ecps = ExtendedProviderHolder.extendedProviders; for (CharsetProvider ecp :ecps) { diff --git a/jdk/src/java.base/share/classes/java/util/jar/Attributes.java b/jdk/src/java.base/share/classes/java/util/jar/Attributes.java index b99755b4bb6..342c85ea2fd 100644 --- a/jdk/src/java.base/share/classes/java/util/jar/Attributes.java +++ b/jdk/src/java.base/share/classes/java/util/jar/Attributes.java @@ -34,9 +34,9 @@ import java.util.Set; import java.util.Collection; import java.util.AbstractSet; import java.util.Iterator; +import java.util.Locale; import sun.util.logging.PlatformLogger; import java.util.Comparator; -import sun.misc.ASCIICaseInsensitiveComparator; /** * The Attributes class maps Manifest attribute names to associated string @@ -501,7 +501,7 @@ public class Attributes implements Map, Cloneable { */ public boolean equals(Object o) { if (o instanceof Name) { - Comparator c = ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER; + Comparator c = String.CASE_INSENSITIVE_ORDER; return c.compare(name, ((Name)o).name) == 0; } else { return false; @@ -513,7 +513,7 @@ public class Attributes implements Map, Cloneable { */ public int hashCode() { if (hashCode == -1) { - hashCode = ASCIICaseInsensitiveComparator.lowerCaseHashCode(name); + hashCode = name.toLowerCase(Locale.ROOT).hashCode(); } return hashCode; } diff --git a/jdk/src/java.base/share/classes/sun/misc/ASCIICaseInsensitiveComparator.java b/jdk/src/java.base/share/classes/sun/misc/ASCIICaseInsensitiveComparator.java deleted file mode 100644 index 9fdc6b53b54..00000000000 --- a/jdk/src/java.base/share/classes/sun/misc/ASCIICaseInsensitiveComparator.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2002, 2004, 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.util.Comparator; - -/** Implements a locale and case insensitive comparator suitable for - strings that are known to only contain ASCII characters. Some - tables internal to the JDK contain only ASCII data and are using - the "generalized" java.lang.String case-insensitive comparator - which converts each character to both upper and lower case. */ - -public class ASCIICaseInsensitiveComparator implements Comparator { - public static final Comparator CASE_INSENSITIVE_ORDER = - new ASCIICaseInsensitiveComparator(); - - public int compare(String s1, String s2) { - int n1=s1.length(), n2=s2.length(); - int minLen = n1 < n2 ? n1 : n2; - for (int i=0; i < minLen; i++) { - char c1 = s1.charAt(i); - char c2 = s2.charAt(i); - assert c1 <= '\u007F' && c2 <= '\u007F'; - if (c1 != c2) { - c1 = (char)toLower(c1); - c2 = (char)toLower(c2); - if (c1 != c2) { - return c1 - c2; - } - } - } - return n1 - n2; - } - - /** - * A case insensitive hash code method to go with the case insensitive - * compare() method. - * - * Returns a hash code for this ASCII string as if it were lower case. - * - * returns same answer as:

- * s.toLowerCase(Locale.US).hashCode();

- * but does not allocate memory (it does NOT have the special - * case Turkish rules). - * - * @param s a String to compute the hashcode on. - * @return a hash code value for this object. - */ - public static int lowerCaseHashCode(String s) { - int h = 0; - int len = s.length(); - - for (int i = 0; i < len; i++) { - h = 31*h + toLower(s.charAt(i)); - } - - return h; - } - - /* If java.util.regex.ASCII ever becomes public or sun.*, use its code instead:*/ - static boolean isLower(int ch) { - return ((ch-'a')|('z'-ch)) >= 0; - } - - static boolean isUpper(int ch) { - return ((ch-'A')|('Z'-ch)) >= 0; - } - - static int toLower(int ch) { - return isUpper(ch) ? (ch + 0x20) : ch; - } - - static int toUpper(int ch) { - return isLower(ch) ? (ch - 0x20) : ch; - } -} diff --git a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/AbstractCharsetProvider.java b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/AbstractCharsetProvider.java index 972d6593573..1c60443415b 100644 --- a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/AbstractCharsetProvider.java +++ b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/AbstractCharsetProvider.java @@ -33,7 +33,6 @@ import java.util.TreeMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; -import sun.misc.ASCIICaseInsensitiveComparator; /** @@ -49,22 +48,22 @@ public class AbstractCharsetProvider /* Maps canonical names to class names */ private Map classMap - = new TreeMap<>(ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER); + = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); /* Maps alias names to canonical names */ private Map aliasMap - = new TreeMap<>(ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER); + = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); /* Maps canonical names to alias-name arrays */ private Map aliasNameMap - = new TreeMap<>(ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER); + = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); /* Maps canonical names to soft references that hold cached instances */ private Map> cache - = new TreeMap<>(ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER); + = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); private String packagePrefix; From 7d85e0638fba8325daee77bc5e70793bfa82930d Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Tue, 8 Mar 2016 11:36:42 -0800 Subject: [PATCH 16/27] 8148187: Remove OS X-specific com.apple.concurrent package Removed jdk.deploy.osx module (including com.apple.concurrent) Reviewed-by: alanb, erikj, mchung --- jdk/make/lib/Lib-java.desktop.gmk | 1 + ...jdk.deploy.osx.gmk => LibosxLibraries.gmk} | 5 +- .../classes/build/tools/module/boot.modules | 1 - .../macosx/native/libosx/CFileManager.m | 0 .../com/apple/concurrent/Dispatch.java | 141 -------------- .../LibDispatchConcurrentQueue.java | 44 ----- .../concurrent/LibDispatchMainQueue.java | 53 ------ .../apple/concurrent/LibDispatchNative.java | 48 ----- .../apple/concurrent/LibDispatchQueue.java | 32 ---- .../LibDispatchRetainedResource.java | 43 ----- .../concurrent/LibDispatchSerialQueue.java | 100 ---------- .../classes/com/apple/concurrent/package.html | 7 - .../macosx/native/libosx/Dispatch.m | 174 ------------------ 13 files changed, 2 insertions(+), 647 deletions(-) rename jdk/make/lib/{Lib-jdk.deploy.osx.gmk => LibosxLibraries.gmk} (94%) rename jdk/src/{jdk.deploy.osx => java.desktop}/macosx/native/libosx/CFileManager.m (100%) delete mode 100644 jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/Dispatch.java delete mode 100644 jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchConcurrentQueue.java delete mode 100644 jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchMainQueue.java delete mode 100644 jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchNative.java delete mode 100644 jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchQueue.java delete mode 100644 jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchRetainedResource.java delete mode 100644 jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchSerialQueue.java delete mode 100644 jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/package.html delete mode 100644 jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m diff --git a/jdk/make/lib/Lib-java.desktop.gmk b/jdk/make/lib/Lib-java.desktop.gmk index c8bc8195854..5433fe96acb 100644 --- a/jdk/make/lib/Lib-java.desktop.gmk +++ b/jdk/make/lib/Lib-java.desktop.gmk @@ -29,6 +29,7 @@ include LibCommon.gmk $(eval $(call FillCacheFind, $(wildcard $(JDK_TOPDIR)/src/java.desktop/*/native \ $(JDK_TOPDIR)/src/*/java.desktop/*/native))) +include LibosxLibraries.gmk include PlatformLibraries.gmk include Awt2dLibraries.gmk include SoundLibraries.gmk diff --git a/jdk/make/lib/Lib-jdk.deploy.osx.gmk b/jdk/make/lib/LibosxLibraries.gmk similarity index 94% rename from jdk/make/lib/Lib-jdk.deploy.osx.gmk rename to jdk/make/lib/LibosxLibraries.gmk index 881a387e14d..91ab6457cb4 100644 --- a/jdk/make/lib/Lib-jdk.deploy.osx.gmk +++ b/jdk/make/lib/LibosxLibraries.gmk @@ -23,18 +23,15 @@ # questions. # -include LibCommon.gmk - ifeq ($(OPENJDK_TARGET_OS), macosx) ################################################################################ - LIBOSX_DIRS := $(JDK_TOPDIR)/src/jdk.deploy.osx/macosx/native/libosx + LIBOSX_DIRS := $(JDK_TOPDIR)/src/java.desktop/macosx/native/libosx LIBOSX_CFLAGS := -I$(LIBOSX_DIRS) \ -I$(JDK_TOPDIR)/src/java.desktop/macosx/native/libosxapp \ $(LIBJAVA_HEADER_FLAGS) \ -I$(SUPPORT_OUTPUTDIR)/headers/java.desktop \ - -I$(SUPPORT_OUTPUTDIR)/headers/jdk.deploy.osx \ # $(eval $(call SetupNativeCompilation,BUILD_LIBOSX, \ diff --git a/jdk/make/src/classes/build/tools/module/boot.modules b/jdk/make/src/classes/build/tools/module/boot.modules index c774b5a0300..948362f0a51 100644 --- a/jdk/make/src/classes/build/tools/module/boot.modules +++ b/jdk/make/src/classes/build/tools/module/boot.modules @@ -19,7 +19,6 @@ java.xml java.xml.crypto jdk.charsets jdk.deploy -jdk.deploy.osx jdk.httpserver jdk.jfr jdk.jsobject diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libosx/CFileManager.m b/jdk/src/java.desktop/macosx/native/libosx/CFileManager.m similarity index 100% rename from jdk/src/jdk.deploy.osx/macosx/native/libosx/CFileManager.m rename to jdk/src/java.desktop/macosx/native/libosx/CFileManager.m diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/Dispatch.java b/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/Dispatch.java deleted file mode 100644 index e983504a626..00000000000 --- a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/Dispatch.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 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 com.apple.concurrent; - -import java.util.concurrent.*; - -/** - * Factory for {@link Executor}s and {@link ExecutorService}s backed by - * libdispatch. - * - * Access is controlled through the Dispatch.getInstance() method, because - * performed tasks occur on threads owned by libdispatch. These threads are - * not owned by any particular AppContext or have any specific context - * classloader installed. - * - * @since Java for Mac OS X 10.6 Update 2 - */ -public final class Dispatch { - /** - * The priorities of the three default asynchronous queues. - */ - public enum Priority { - LOW(-2), NORMAL(0), HIGH(2); // values from - - final int nativePriority; - Priority(final int nativePriority) { this.nativePriority = nativePriority; } - }; - - final static Dispatch instance = new Dispatch(); - - /** - * Factory method returns an instnace of Dispatch if supported by the - * underlying operating system, and if the caller's security manager - * permits "canInvokeInSystemThreadGroup". - * - * @return a factory instance of Dispatch, or null if not available - */ - public static Dispatch getInstance() { - checkSecurity(); - if (!LibDispatchNative.nativeIsDispatchSupported()) return null; - - return instance; - } - - private static void checkSecurity() { - final SecurityManager security = System.getSecurityManager(); - if (security != null) security.checkPermission(new RuntimePermission("canInvokeInSystemThreadGroup")); - } - - private Dispatch() { } - - /** - * Creates an {@link Executor} that performs tasks asynchronously. The {@link Executor} - * cannot be shutdown, and enqueued {@link Runnable}s cannot be canceled. Passing null - * returns the {@link Priority.NORMAL} {@link Executor}. - * - * @param priority - the priority of the returned {@link Executor} - * @return an asynchronous {@link Executor} - */ - public Executor getAsyncExecutor(Priority priority) { - if (priority == null) priority = Priority.NORMAL; - final long nativeQueue = LibDispatchNative.nativeCreateConcurrentQueue(priority.nativePriority); - if (nativeQueue == 0L) return null; - return new LibDispatchConcurrentQueue(nativeQueue); - } - - int queueIndex = 0; - /** - * Creates an {@link ExecutorService} that performs tasks synchronously in FIFO order. - * Useful to protect a resource against concurrent modification, in lieu of a lock. - * Passing null returns an {@link ExecutorService} with a uniquely labeled queue. - * - * @param label - a label to name the queue, shown in several debugging tools - * @return a synchronous {@link ExecutorService} - */ - public ExecutorService createSerialExecutor(String label) { - if (label == null) label = ""; - if (label.length() > 256) label = label.substring(0, 256); - String queueName = "com.apple.java.concurrent."; - if ("".equals(label)) { - synchronized (this) { - queueName += queueIndex++; - } - } else { - queueName += label; - } - - final long nativeQueue = LibDispatchNative.nativeCreateSerialQueue(queueName); - if (nativeQueue == 0) return null; - return new LibDispatchSerialQueue(nativeQueue); - } - - Executor nonBlockingMainQueue = null; - /** - * Returns an {@link Executor} that performs the provided Runnables on the main queue of the process. - * Runnables submitted to this {@link Executor} will not run until the AWT is started or another native toolkit is running a CFRunLoop or NSRunLoop on the main thread. - * - * Submitting a Runnable to this {@link Executor} does not wait for the Runnable to complete. - * @return an asynchronous {@link Executor} that is backed by the main queue - */ - public synchronized Executor getNonBlockingMainQueueExecutor() { - if (nonBlockingMainQueue != null) return nonBlockingMainQueue; - return nonBlockingMainQueue = new LibDispatchMainQueue.ASync(); - } - - Executor blockingMainQueue = null; - /** - * Returns an {@link Executor} that performs the provided Runnables on the main queue of the process. - * Runnables submitted to this {@link Executor} will not run until the AWT is started or another native toolkit is running a CFRunLoop or NSRunLoop on the main thread. - * - * Submitting a Runnable to this {@link Executor} will block until the Runnable has completed. - * @return an {@link Executor} that is backed by the main queue - */ - public synchronized Executor getBlockingMainQueueExecutor() { - if (blockingMainQueue != null) return blockingMainQueue; - return blockingMainQueue = new LibDispatchMainQueue.Sync(); - } -} diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchConcurrentQueue.java b/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchConcurrentQueue.java deleted file mode 100644 index af055aedb57..00000000000 --- a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchConcurrentQueue.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 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 com.apple.concurrent; - -import java.util.concurrent.Executor; - -class LibDispatchConcurrentQueue extends LibDispatchQueue implements Executor { - LibDispatchConcurrentQueue(final long queuePtr) { - super(queuePtr); - } - - @Override - public void execute(final Runnable task) { - LibDispatchNative.nativeExecuteAsync(ptr, task); - } - - @Override - protected synchronized void dispose() { - // should not dispose the default concurrent queues - } -} diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchMainQueue.java b/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchMainQueue.java deleted file mode 100644 index 1e05192986c..00000000000 --- a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchMainQueue.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 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 com.apple.concurrent; - -import java.util.concurrent.Executor; - -abstract class LibDispatchMainQueue extends LibDispatchQueue implements Executor { - public LibDispatchMainQueue() { - super(LibDispatchNative.nativeGetMainQueue()); - } - - @Override - protected synchronized void dispose() { - // should not dispose the main queue - } - - static class Sync extends LibDispatchMainQueue { - @Override - public void execute(final Runnable task) { - LibDispatchNative.nativeExecuteSync(ptr, task); - } - } - - static class ASync extends LibDispatchMainQueue { - @Override - public void execute(final Runnable task) { - LibDispatchNative.nativeExecuteAsync(ptr, task); - } - } -} diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchNative.java b/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchNative.java deleted file mode 100644 index 9b89ac546e3..00000000000 --- a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchNative.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 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 com.apple.concurrent; - -final class LibDispatchNative { - static { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Void run() { - System.loadLibrary("osx"); - return null; - } - }); - } - - static native boolean nativeIsDispatchSupported(); - static native long nativeGetMainQueue(); - static native long nativeCreateConcurrentQueue(int priority); - static native long nativeCreateSerialQueue(String name); - static native void nativeReleaseQueue(long nativeQueue); - static native void nativeExecuteAsync(long nativeQueue, Runnable task); - static native void nativeExecuteSync(long nativeQueue, Runnable task); - - private LibDispatchNative() { } -} diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchQueue.java b/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchQueue.java deleted file mode 100644 index f464f698541..00000000000 --- a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchQueue.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 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 com.apple.concurrent; - -class LibDispatchQueue extends LibDispatchRetainedResource { - LibDispatchQueue(final long queuePtr) { - super(queuePtr); - } -} diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchRetainedResource.java b/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchRetainedResource.java deleted file mode 100644 index 9d6b59543b0..00000000000 --- a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchRetainedResource.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 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 com.apple.concurrent; - -class LibDispatchRetainedResource { - protected long ptr; - - protected LibDispatchRetainedResource(final long ptr) { - this.ptr = ptr; - } - - protected synchronized void dispose() { - if (ptr != 0) LibDispatchNative.nativeReleaseQueue(ptr); - ptr = 0; - } - - protected void finalize() throws Throwable { - dispose(); - } -} diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchSerialQueue.java b/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchSerialQueue.java deleted file mode 100644 index bb22566aef0..00000000000 --- a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/LibDispatchSerialQueue.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 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 com.apple.concurrent; - -import java.util.List; -import java.util.concurrent.*; - -class LibDispatchSerialQueue extends AbstractExecutorService { - static final int RUNNING = 0; - static final int SHUTDOWN = 1; -// static final int STOP = 2; // not supported by GCD - static final int TERMINATED = 3; - - final Object lock = new Object(); - LibDispatchQueue nativeQueueWrapper; - volatile int runState; - - LibDispatchSerialQueue(final long queuePtr) { - nativeQueueWrapper = new LibDispatchQueue(queuePtr); - } - - @Override - public void execute(final Runnable task) { - if (nativeQueueWrapper == null) return; - LibDispatchNative.nativeExecuteAsync(nativeQueueWrapper.ptr, task); - } - - @Override - public boolean isShutdown() { - return runState != RUNNING; - } - - @Override - public boolean isTerminated() { - return runState == TERMINATED; - } - - @Override - public void shutdown() { - synchronized (lock) { - if (runState != RUNNING) return; - - runState = SHUTDOWN; - execute(new Runnable() { - public void run() { - synchronized (lock) { - runState = TERMINATED; - lock.notifyAll(); // for the benefit of awaitTermination() - } - } - }); - nativeQueueWrapper = null; - } - } - - @Override - public List shutdownNow() { - shutdown(); - return null; - } - - @Override - public boolean awaitTermination(final long timeout, final TimeUnit unit) throws InterruptedException { - if (runState == TERMINATED) return true; - - final long millis = unit.toMillis(timeout); - if (millis <= 0) return false; - - synchronized (lock) { - if (runState == TERMINATED) return true; - lock.wait(timeout); - if (runState == TERMINATED) return true; - } - - return false; - } -} diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/package.html b/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/package.html deleted file mode 100644 index 003a7a239f3..00000000000 --- a/jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/package.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - -Apple-specific implementations of the java.util.concurrent.* API based on libdispatch. - - diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m b/jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m deleted file mode 100644 index cdeac0d435d..00000000000 --- a/jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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 - * 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. - */ - -/* - * Must include this before JavaNativeFoundation.h to get jni.h from build - */ -#include "jni.h" -#include "jni_util.h" - -#import "com_apple_concurrent_LibDispatchNative.h" - -#import -#import - -/* - * Declare library specific JNI_Onload entry if static build - */ -DEF_STATIC_JNI_OnLoad - -/* - * Class: com_apple_concurrent_LibDispatchNative - * Method: nativeIsDispatchSupported - * Signature: ()Z - */ -JNIEXPORT jboolean JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeIsDispatchSupported -(JNIEnv *env, jclass clazz) -{ - return JNI_TRUE; -} - - -/* - * Class: com_apple_concurrent_LibDispatchNative - * Method: nativeGetMainQueue - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeGetMainQueue -(JNIEnv *env, jclass clazz) -{ - dispatch_queue_t queue = dispatch_get_main_queue(); - return ptr_to_jlong(queue); -} - - -/* - * Class: com_apple_concurrent_LibDispatchNative - * Method: nativeCreateConcurrentQueue - * Signature: (I)J - */ -JNIEXPORT jlong JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeCreateConcurrentQueue -(JNIEnv *env, jclass clazz, jint priority) -{ - dispatch_queue_t queue = dispatch_get_global_queue((long)priority, 0); - return ptr_to_jlong(queue); -} - - -/* - * Class: com_apple_concurrent_LibDispatchNative - * Method: nativeCreateSerialQueue - * Signature: (Ljava/lang/String;)J - */ -JNIEXPORT jlong JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeCreateSerialQueue -(JNIEnv *env, jclass clazz, jstring name) -{ - if (name == NULL) return 0L; - - jboolean isCopy; - const char *queue_name = (*env)->GetStringUTFChars(env, name, &isCopy); - dispatch_queue_t queue = dispatch_queue_create(queue_name, NULL); - (*env)->ReleaseStringUTFChars(env, name, queue_name); - - return ptr_to_jlong(queue); -} - - -/* - * Class: com_apple_concurrent_LibDispatchNative - * Method: nativeReleaseQueue - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeReleaseQueue -(JNIEnv *env, jclass clazz, jlong nativeQueue) -{ - if (nativeQueue == 0L) return; - dispatch_release((dispatch_queue_t)jlong_to_ptr(nativeQueue)); -} - - -static JNF_CLASS_CACHE(jc_Runnable, "java/lang/Runnable"); -static JNF_MEMBER_CACHE(jm_run, jc_Runnable, "run", "()V"); - -static void perform_dispatch(JNIEnv *env, jlong nativeQueue, jobject runnable, void (*dispatch_fxn)(dispatch_queue_t, dispatch_block_t)) -{ -JNF_COCOA_ENTER(env); - dispatch_queue_t queue = (dispatch_queue_t)jlong_to_ptr(nativeQueue); - if (queue == NULL) return; // shouldn't happen - - // create a global-ref around the Runnable, so it can be safely passed to the dispatch thread - JNFJObjectWrapper *wrappedRunnable = [[JNFJObjectWrapper alloc] initWithJObject:runnable withEnv:env]; - - dispatch_fxn(queue, ^{ - // attach the dispatch thread to the JVM if necessary, and get an env - JNFThreadContext ctx = JNFThreadDetachOnThreadDeath | JNFThreadSetSystemClassLoaderOnAttach | JNFThreadAttachAsDaemon; - JNIEnv *blockEnv = JNFObtainEnv(&ctx); - - JNF_COCOA_ENTER(blockEnv); - - // call the user's runnable - JNFCallObjectMethod(blockEnv, [wrappedRunnable jObject], jm_run); - - // explicitly clear object while we have an env (it's cheaper that way) - [wrappedRunnable setJObject:NULL withEnv:blockEnv]; - - JNF_COCOA_EXIT(blockEnv); - - // let the env go, but leave the thread attached as a daemon - JNFReleaseEnv(blockEnv, &ctx); - }); - - // release this thread's interest in the Runnable, the block - // will have retained the it's own interest above - [wrappedRunnable release]; - -JNF_COCOA_EXIT(env); -} - - -/* - * Class: com_apple_concurrent_LibDispatchNative - * Method: nativeExecuteAsync - * Signature: (JLjava/lang/Runnable;)V - */ -JNIEXPORT void JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeExecuteAsync -(JNIEnv *env, jclass clazz, jlong nativeQueue, jobject runnable) -{ - // enqueues and returns - perform_dispatch(env, nativeQueue, runnable, dispatch_async); -} - - -/* - * Class: com_apple_concurrent_LibDispatchNative - * Method: nativeExecuteSync - * Signature: (JLjava/lang/Runnable;)V - */ -JNIEXPORT void JNICALL Java_com_apple_concurrent_LibDispatchNative_nativeExecuteSync -(JNIEnv *env, jclass clazz, jlong nativeQueue, jobject runnable) -{ - // blocks until the Runnable completes - perform_dispatch(env, nativeQueue, runnable, dispatch_sync); -} From 025fa588dc68ce37fa09d10f6820ff23beb0e6ae Mon Sep 17 00:00:00 2001 From: Amy Lu Date: Wed, 9 Mar 2016 11:35:21 +0800 Subject: [PATCH 17/27] 8151260: Mark URLPermission/URLTest.java and ipv6tests/TcpTest.java as intermittently failing Reviewed-by: chegar --- jdk/test/java/net/URLPermission/URLTest.java | 3 ++- jdk/test/java/net/ipv6tests/TcpTest.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/jdk/test/java/net/URLPermission/URLTest.java b/jdk/test/java/net/URLPermission/URLTest.java index 266fdfd0a89..710e8f59cf7 100644 --- a/jdk/test/java/net/URLPermission/URLTest.java +++ b/jdk/test/java/net/URLPermission/URLTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, 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,6 +27,7 @@ import java.net.URLPermission; * * @test * @bug 8010464 + * @key intermittent * @library /lib/testlibrary/ * @build jdk.testlibrary.SimpleSSLContext * @run main/othervm/java.security.policy=policy.1 URLTest one diff --git a/jdk/test/java/net/ipv6tests/TcpTest.java b/jdk/test/java/net/ipv6tests/TcpTest.java index 63008acddba..f538831506c 100644 --- a/jdk/test/java/net/ipv6tests/TcpTest.java +++ b/jdk/test/java/net/ipv6tests/TcpTest.java @@ -24,6 +24,7 @@ /* * @test * @bug 4868820 + * @key intermittent * @summary IPv6 support for Windows XP and 2003 server */ From a3aa84871979660affad8386f6e09a720699fda3 Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Wed, 9 Mar 2016 12:11:31 +0000 Subject: [PATCH 18/27] 8151441: Completion result in httpclient Exchange.java lost Reviewed-by: chegar --- .../share/classes/java/net/http/Exchange.java | 28 ++--- .../java/net/httpclient/ShortRequestBody.java | 103 ++++++++++++++++++ 2 files changed, 117 insertions(+), 14 deletions(-) create mode 100644 jdk/test/java/net/httpclient/ShortRequestBody.java diff --git a/jdk/src/java.httpclient/share/classes/java/net/http/Exchange.java b/jdk/src/java.httpclient/share/classes/java/net/http/Exchange.java index 597b4c0b6a1..9201d22160a 100644 --- a/jdk/src/java.httpclient/share/classes/java/net/http/Exchange.java +++ b/jdk/src/java.httpclient/share/classes/java/net/http/Exchange.java @@ -214,21 +214,21 @@ class Exchange { .sendHeadersAsync() .thenCompose((Void v) -> { // send body and get response at same time - exchImpl.sendBodyAsync(); - return exchImpl.getResponseAsync(null); + return exchImpl.sendBodyAsync() + .thenCompose(exchImpl::getResponseAsync); + }) + .thenCompose((HttpResponseImpl r1) -> { + int rcode = r1.statusCode(); + CompletableFuture cf = + checkForUpgradeAsync(r1, exchImpl); + if (cf != null) { + return cf; + } else { + Exchange.this.response = r1; + logResponse(r1); + return CompletableFuture.completedFuture(r1); + } }) - .thenCompose((HttpResponseImpl r1) -> { - int rcode = r1.statusCode(); - CompletableFuture cf = - checkForUpgradeAsync(r1, exchImpl); - if (cf != null) { - return cf; - } else { - Exchange.this.response = r1; - logResponse(r1); - return CompletableFuture.completedFuture(r1); - } - }) .thenApply((HttpResponseImpl response) -> { this.response = response; logResponse(response); diff --git a/jdk/test/java/net/httpclient/ShortRequestBody.java b/jdk/test/java/net/httpclient/ShortRequestBody.java new file mode 100644 index 00000000000..12a0b6dca51 --- /dev/null +++ b/jdk/test/java/net/httpclient/ShortRequestBody.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, 2016, 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.*; +import java.net.http.*; +import java.net.*; +import java.util.concurrent.*; +import java.nio.ByteBuffer; +import java.util.function.LongConsumer; + +/** + * @test + * @bug 8151441 + * @run main/othervm/timeout=10 ShortRequestBody + */ + +/** + * Exception was not being thrown + */ +public class ShortRequestBody { + + static Server server; + static String reqbody = "Hello world"; + + static String response = "HTTP/1.1 200 OK\r\nContent-length: 0\r\n\r\n"; + + static class RequestBody implements HttpRequest.BodyProcessor { + public long onRequestStart(HttpRequest hr, LongConsumer flowController) { + return reqbody.length() + 1; // wrong! + } + + public boolean onRequestBodyChunk(ByteBuffer buf) throws IOException { + byte[] b = reqbody.getBytes(); + buf.put(b); + return true; + } + } + + static void close(Closeable c) { + try { + if (c == null) + return; + c.close(); + } catch (IOException e) {} + } + + public static void main(String[] args) throws Exception { + ServerSocket server = new ServerSocket(0); + int port = server.getLocalPort(); + URI uri = new URI("http://127.0.0.1:" + port + "/"); + + HttpRequest request; + HttpResponse r; + Socket s = null; + CompletableFuture cf1; + try { + cf1 = HttpRequest.create(uri) + .body(new RequestBody()) + .GET() + .responseAsync(); + + s = server.accept(); + s.getInputStream().readAllBytes(); + try (OutputStream os = s.getOutputStream()) { + os.write(response.getBytes()); + } catch (IOException ee) { + } + + try { + r = cf1.get(3, TimeUnit.SECONDS); + throw new RuntimeException("Failed"); + } catch (TimeoutException e0) { + throw new RuntimeException("Failed timeout"); + } catch (ExecutionException e) { + System.err.println("OK"); + } + } finally { + HttpClient.getDefault().executorService().shutdownNow(); + close(s); + close(server); + } + } +} From b9616807fc1b2a8c79d70c9ea6fd96dbc8b89032 Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Wed, 9 Mar 2016 13:37:30 +0000 Subject: [PATCH 19/27] 8151299: Http client SelectorManager overwriting read and write events Reviewed-by: chegar --- .../classes/java/net/http/HttpClientImpl.java | 130 +++++++---- .../net/httpclient/whitebox/TEST.properties | 3 + .../whitebox/java/net/http/SelectorTest.java | 208 ++++++++++++++++++ 3 files changed, 300 insertions(+), 41 deletions(-) create mode 100644 jdk/test/java/net/httpclient/whitebox/TEST.properties create mode 100644 jdk/test/java/net/httpclient/whitebox/java/net/http/SelectorTest.java diff --git a/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java b/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java index e7e53bd6346..fd1ab0b012d 100644 --- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java +++ b/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java @@ -30,19 +30,17 @@ import java.net.ProxySelector; import java.net.URI; import static java.net.http.Utils.BUFSIZE; import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import static java.nio.channels.SelectionKey.OP_CONNECT; import static java.nio.channels.SelectionKey.OP_READ; import static java.nio.channels.SelectionKey.OP_WRITE; import java.nio.channels.Selector; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; +import java.util.*; +import java.util.stream.Stream; import java.util.concurrent.ExecutorService; import java.security.NoSuchAlgorithmException; -import java.util.ListIterator; -import java.util.Optional; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import javax.net.ssl.SSLContext; @@ -72,12 +70,6 @@ class HttpClientImpl extends HttpClient implements BufferHandler { private static final ThreadFactory defaultFactory = Executors.defaultThreadFactory(); private final LinkedList timeouts; - //@Override - void debugPrint() { - selmgr.debugPrint(); - client2.debugPrint(); - } - public static HttpClientImpl create(HttpClientBuilderImpl builder) { HttpClientImpl impl = new HttpClientImpl(builder); impl.start(); @@ -173,19 +165,15 @@ class HttpClientImpl extends HttpClient implements BufferHandler { // Main loop for this client's selector class SelectorManager extends Thread { - final Selector selector; boolean closed; final List readyList; final List registrations; - List debugList; - SelectorManager() throws IOException { readyList = new LinkedList<>(); registrations = new LinkedList<>(); - debugList = new LinkedList<>(); selector = Selector.open(); } @@ -216,13 +204,6 @@ class HttpClientImpl extends HttpClient implements BufferHandler { return c; } - synchronized void debugPrint() { - System.err.println("Selecting on:"); - for (AsyncEvent e : debugList) { - System.err.println(opvals(e.interestOps())); - } - } - String opvals(int i) { StringBuilder sb = new StringBuilder(); if ((i & OP_READ) != 0) @@ -239,14 +220,18 @@ class HttpClientImpl extends HttpClient implements BufferHandler { try { while (true) { synchronized (this) { - debugList = copy(registrations); for (AsyncEvent exchange : registrations) { SelectableChannel c = exchange.channel(); try { c.configureBlocking(false); - c.register(selector, - exchange.interestOps(), - exchange); + SelectionKey key = c.keyFor(selector); + SelectorAttachment sa; + if (key == null) { + sa = new SelectorAttachment(c, selector); + } else { + sa = (SelectorAttachment)key.attachment(); + } + sa.register(exchange); } catch (IOException e) { Log.logError("HttpClientImpl: " + e); c.close(); @@ -266,11 +251,10 @@ class HttpClientImpl extends HttpClient implements BufferHandler { Set keys = selector.selectedKeys(); for (SelectionKey key : keys) { - if (key.isReadable() || key.isConnectable() || key.isWritable()) { - key.cancel(); - AsyncEvent exchange = (AsyncEvent) key.attachment(); - readyList.add(exchange); - } + SelectorAttachment sa = (SelectorAttachment)key.attachment(); + int eventsOccurred = key.readyOps(); + sa.events(eventsOccurred).forEach(readyList::add); + sa.resetInterestOps(eventsOccurred); } selector.selectNow(); // complete cancellation selector.selectedKeys().clear(); @@ -305,6 +289,80 @@ class HttpClientImpl extends HttpClient implements BufferHandler { } } + /** + * Tracks multiple user level registrations associated with one NIO + * registration (SelectionKey). In this implementation, registrations + * are one-off and when an event is posted the registration is cancelled + * until explicitly registered again. + * + *

No external synchronization required as this class is only used + * by the SelectorManager thread. One of these objects required per + * connection. + */ + private static class SelectorAttachment { + private final SelectableChannel chan; + private final Selector selector; + private final ArrayList pending; + private int interestops; + + SelectorAttachment(SelectableChannel chan, Selector selector) { + this.pending = new ArrayList<>(); + this.chan = chan; + this.selector = selector; + } + + void register(AsyncEvent e) throws ClosedChannelException { + int newops = e.interestOps(); + boolean reRegister = (interestops & newops) != newops; + interestops |= newops; + pending.add(e); + if (reRegister) { + // first time registration happens here also + chan.register(selector, interestops, this); + } + } + + int interestOps() { + return interestops; + } + + /** + * Returns a Stream containing only events that are + * registered with the given {@code interestop}. + */ + Stream events(int interestop) { + return pending.stream() + .filter(ev -> (ev.interestOps() & interestop) != 0); + } + + /** + * Removes any events with the given {@code interestop}, and if no + * events remaining, cancels the associated SelectionKey. + */ + void resetInterestOps(int interestop) { + int newops = 0; + + Iterator itr = pending.iterator(); + while (itr.hasNext()) { + AsyncEvent event = itr.next(); + int evops = event.interestOps(); + if ((evops & interestop) != 0) { + itr.remove(); + } else { + newops |= evops; + } + } + + interestops = newops; + SelectionKey key = chan.keyFor(selector); + if (newops == 0) { + key.cancel(); + } else { + key.interestOps(newops); + } + } + } + /** * Creates a HttpRequest associated with this group. * @@ -425,18 +483,9 @@ class HttpClientImpl extends HttpClient implements BufferHandler { } } iter.add(event); - //debugPrintList("register"); selmgr.wakeupSelector(); } - void debugPrintList(String s) { - System.err.printf("%s: {", s); - for (TimeoutEvent e : timeouts) { - System.err.printf("(%d,%d) ", e.delta, e.timeval); - } - System.err.println("}"); - } - synchronized void signalTimeouts(long then) { if (timeouts.isEmpty()) { return; @@ -462,7 +511,6 @@ class HttpClientImpl extends HttpClient implements BufferHandler { break; } } - //debugPrintList("signalTimeouts"); } synchronized void cancelTimer(TimeoutEvent event) { diff --git a/jdk/test/java/net/httpclient/whitebox/TEST.properties b/jdk/test/java/net/httpclient/whitebox/TEST.properties new file mode 100644 index 00000000000..1d784754199 --- /dev/null +++ b/jdk/test/java/net/httpclient/whitebox/TEST.properties @@ -0,0 +1,3 @@ +TestNG.dirs = . + +bootclasspath.dirs = /java/net/httpclient diff --git a/jdk/test/java/net/httpclient/whitebox/java/net/http/SelectorTest.java b/jdk/test/java/net/httpclient/whitebox/java/net/http/SelectorTest.java new file mode 100644 index 00000000000..74ef4ff2991 --- /dev/null +++ b/jdk/test/java/net/httpclient/whitebox/java/net/http/SelectorTest.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2015, 2016, 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 8151299 + * @summary Http client SelectorManager overwriting read and write events + */ +package java.net.http; + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.nio.ByteBuffer; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; +import static java.lang.System.out; +import static java.nio.charset.StandardCharsets.US_ASCII; +import static java.util.concurrent.TimeUnit.SECONDS; + +import org.testng.annotations.Test; + +/** + * Whitebox test of selector mechanics. Currently only a simple test + * setting one read and one write event is done. It checks that the + * write event occurs first, followed by the read event and then no + * further events occur despite the conditions actually still existing. + */ +@Test +public class SelectorTest { + + AtomicInteger counter = new AtomicInteger(); + volatile boolean error; + static final CountDownLatch finishingGate = new CountDownLatch(1); + + String readSomeBytes(RawChannel chan) { + try { + ByteBuffer buf = ByteBuffer.allocate(1024); + int t = chan.read(buf); + if (t <= 0) { + out.printf("chan read returned %d\n", t); + return null; + } + byte[] bb = new byte[t]; + buf.get(bb); + return new String(bb, US_ASCII); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + } + + @Test(timeOut = 10000) + public void test() throws Exception { + + try (ServerSocket server = new ServerSocket(0)) { + int port = server.getLocalPort(); + + out.println("Listening on port " + server.getLocalPort()); + + TestServer t = new TestServer(server); + t.start(); + out.println("Started server thread"); + + final RawChannel chan = getARawChannel(port); + + chan.registerEvent(new RawChannel.NonBlockingEvent() { + @Override + public int interestOps() { + return SelectionKey.OP_READ; + } + + @Override + public void handle() { + readSomeBytes(chan); + out.printf("OP_READ\n"); + if (counter.get() != 1) { + out.printf("OP_READ error counter = %d\n", counter); + error = true; + } + } + }); + + chan.registerEvent(new RawChannel.NonBlockingEvent() { + @Override + public int interestOps() { + return SelectionKey.OP_WRITE; + } + + @Override + public void handle() { + out.printf("OP_WRITE\n"); + if (counter.get() != 0) { + out.printf("OP_WRITE error counter = %d\n", counter); + error = true; + } else { + ByteBuffer bb = ByteBuffer.wrap(TestServer.INPUT); + counter.incrementAndGet(); + try { + chan.write(bb); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + } + + }); + out.println("Events registered. Waiting"); + finishingGate.await(30, SECONDS); + if (error) + throw new RuntimeException("Error"); + else + out.println("No error"); + } + } + + static RawChannel getARawChannel(int port) throws Exception { + URI uri = URI.create("http://127.0.0.1:" + port + "/"); + out.println("client connecting to " + uri.toString()); + HttpRequest req = HttpRequest.create(uri).GET(); + HttpResponse r = req.response(); + r.body(HttpResponse.ignoreBody()); + return ((HttpResponseImpl) r).rawChannel(); + } + + static class TestServer extends Thread { + static final byte[] INPUT = "Hello world".getBytes(US_ASCII); + static final byte[] OUTPUT = "Goodbye world".getBytes(US_ASCII); + static final String FIRST_RESPONSE = "HTTP/1.1 200 OK\r\nContent-length: 0\r\n\r\n"; + final ServerSocket server; + + TestServer(ServerSocket server) throws IOException { + this.server = server; + } + + public void run() { + try (Socket s = server.accept(); + InputStream is = s.getInputStream(); + OutputStream os = s.getOutputStream()) { + + out.println("Got connection"); + readRequest(is); + os.write(FIRST_RESPONSE.getBytes()); + read(is); + write(os); + Thread.sleep(1000); + // send some more data, and make sure WRITE op does not get called + write(os); + out.println("TestServer exiting"); + SelectorTest.finishingGate.countDown(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + // consumes the HTTP request + static void readRequest(InputStream is) throws IOException { + out.println("starting readRequest"); + byte[] buf = new byte[1024]; + String s = ""; + while (true) { + int n = is.read(buf); + if (n <= 0) + throw new IOException("Error"); + s = s + new String(buf, 0, n); + if (s.indexOf("\r\n\r\n") != -1) + break; + } + out.println("returning from readRequest"); + } + + static void read(InputStream is) throws IOException { + out.println("starting read"); + for (int i = 0; i < INPUT.length; i++) { + int c = is.read(); + if (c == -1) + throw new IOException("closed"); + if (INPUT[i] != (byte) c) + throw new IOException("Error. Expected:" + INPUT[i] + ", got:" + c); + } + out.println("returning from read"); + } + + static void write(OutputStream os) throws IOException { + out.println("doing write"); + os.write(OUTPUT); + } + } +} From 020a27b202898b2c8ac2addf1149a1faf1657148 Mon Sep 17 00:00:00 2001 From: Peter Levart Date: Wed, 9 Mar 2016 21:17:06 +0100 Subject: [PATCH 20/27] 8149925: We don't need jdk.internal.ref.Cleaner any more - part1 1st part of removing legacy jdk.internal.ref.Cleaner Reviewed-by: chegar, mchung --- .../java/lang/invoke/MethodHandleNatives.java | 12 +++--- .../share/classes/java/lang/ref/Cleaner.java | 12 ++++-- .../jdk/internal/misc/InnocuousThread.java | 8 +++- .../classes/jdk/internal/ref/CleanerImpl.java | 41 ++++++++++++++----- .../classes/sun/nio/ch/IOVecWrapper.java | 4 +- .../share/classes/sun/nio/ch/Util.java | 1 - .../classes/sun/nio/fs/NativeBuffer.java | 12 +++--- .../classes/sun/nio/fs/NativeBuffers.java | 4 +- .../sun/nio/fs/WindowsWatchService.java | 2 +- 9 files changed, 64 insertions(+), 32 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java index e9bb8046246..57ad668b903 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -30,7 +30,7 @@ import java.lang.reflect.Field; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; -import jdk.internal.ref.Cleaner; +import jdk.internal.ref.CleanerFactory; /** * The JVM interface for the method handles package is all here. @@ -68,10 +68,12 @@ class MethodHandleNatives { 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); + // CallSite instance is tracked by a Cleanable which clears native + // structures allocated for CallSite context. Though the CallSite can + // become unreachable, its Context is retained by the Cleanable instance + // (which is referenced from Cleaner instance which is referenced from + // CleanerFactory class) until cleanup is performed. + CleanerFactory.cleaner().register(cs, newContext); return newContext; } diff --git a/jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java b/jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java index bee049ec8fe..63bd43c53c1 100644 --- a/jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java +++ b/jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java @@ -25,10 +25,11 @@ package java.lang.ref; +import jdk.internal.ref.CleanerImpl; + import java.util.Objects; import java.util.concurrent.ThreadFactory; - -import jdk.internal.ref.CleanerImpl; +import java.util.function.Function; /** * {@code Cleaner} manages a set of object references and corresponding cleaning actions. @@ -135,7 +136,12 @@ public final class Cleaner { final CleanerImpl impl; static { - CleanerImpl.setCleanerImplAccess((Cleaner c) -> c.impl); + CleanerImpl.setCleanerImplAccess(new Function() { + @Override + public CleanerImpl apply(Cleaner cleaner) { + return cleaner.impl; + } + }); } /** diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java b/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java index 8c5b8833834..0891f2a125f 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java @@ -128,8 +128,12 @@ public final class InnocuousThread extends Thread { } final ThreadGroup root = group; INNOCUOUSTHREADGROUP = AccessController.doPrivileged( - (PrivilegedAction) () -> - { return new ThreadGroup(root, "InnocuousThreadGroup"); }); + new PrivilegedAction() { + @Override + public ThreadGroup run() { + return new ThreadGroup(root, "InnocuousThreadGroup"); + } + }); } catch (Exception e) { throw new Error(e); } diff --git a/jdk/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java b/jdk/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java index 6d99648eac2..787382326f7 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java +++ b/jdk/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java @@ -31,6 +31,7 @@ import java.lang.ref.ReferenceQueue; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import jdk.internal.misc.InnocuousThread; @@ -39,7 +40,7 @@ import jdk.internal.misc.InnocuousThread; * CleanerImpl manages a set of object references and corresponding cleaning actions. * CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}. */ -public final class CleanerImpl { +public final class CleanerImpl implements Runnable { /** * An object to access the CleanerImpl from a Cleaner; set by Cleaner init. @@ -103,7 +104,7 @@ public final class CleanerImpl { } // schedule a nop cleaning action for the cleaner, so the associated thread // will continue to run at least until the cleaner is reclaimable. - new PhantomCleanableRef(cleaner, cleaner, () -> {}); + new CleanerCleanable(cleaner); if (threadFactory == null) { threadFactory = CleanerImpl.InnocuousThreadFactory.factory(); @@ -112,7 +113,7 @@ public final class CleanerImpl { // now that there's at least one cleaning action, for the cleaner, // we can start the associated thread, which runs until // all cleaning actions have been run. - Thread thread = threadFactory.newThread(this::run); + Thread thread = threadFactory.newThread(this); thread.setDaemon(true); thread.start(); } @@ -128,7 +129,8 @@ public final class CleanerImpl { * If the thread is a ManagedLocalsThread, the threadlocals * are erased before each cleanup */ - private void run() { + @Override + public void run() { Thread t = Thread.currentThread(); InnocuousThread mlThread = (t instanceof InnocuousThread) ? (InnocuousThread) t @@ -147,10 +149,9 @@ public final class CleanerImpl { if (ref != null) { ref.clean(); } - } catch (InterruptedException i) { - continue; // ignore the interruption } catch (Throwable e) { // ignore exceptions from the cleanup action + // (including interruption of cleanup thread) } } } @@ -320,14 +321,32 @@ public final class CleanerImpl { return factory; } + final AtomicInteger cleanerThreadNumber = new AtomicInteger(); + public Thread newThread(Runnable r) { - return AccessController.doPrivileged((PrivilegedAction) () -> { - Thread t = new InnocuousThread(r); - t.setPriority(Thread.MAX_PRIORITY - 2); - t.setName("Cleaner-" + t.getId()); - return t; + return AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Thread run() { + Thread t = new InnocuousThread(r); + t.setPriority(Thread.MAX_PRIORITY - 2); + t.setName("Cleaner-" + cleanerThreadNumber.getAndIncrement()); + return t; + } }); } } + /** + * A PhantomCleanable implementation for tracking the Cleaner itself. + */ + static final class CleanerCleanable extends PhantomCleanable { + CleanerCleanable(Cleaner cleaner) { + super(cleaner, cleaner); + } + + @Override + protected void performCleanup() { + // no action + } + } } diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java b/jdk/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java index d2c03a34fea..3c43c5a6777 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java @@ -26,7 +26,7 @@ package sun.nio.ch; import java.nio.ByteBuffer; -import jdk.internal.ref.Cleaner; +import jdk.internal.ref.CleanerFactory; /** @@ -101,7 +101,7 @@ class IOVecWrapper { } if (wrapper == null) { wrapper = new IOVecWrapper(size); - Cleaner.create(wrapper, new Deallocator(wrapper.vecArray)); + CleanerFactory.cleaner().register(wrapper, new Deallocator(wrapper.vecArray)); cached.set(wrapper); } return wrapper; diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java index a580b82c4d0..af89eca4544 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java @@ -33,7 +33,6 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.util.*; import jdk.internal.misc.Unsafe; -import jdk.internal.ref.Cleaner; import sun.security.action.GetPropertyAction; diff --git a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java index 91efac348e8..7daf8ccfe16 100644 --- a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java +++ b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java @@ -26,7 +26,9 @@ package sun.nio.fs; import jdk.internal.misc.Unsafe; -import jdk.internal.ref.Cleaner; +import jdk.internal.ref.CleanerFactory; + +import java.lang.ref.Cleaner; /** * A light-weight buffer in native memory. @@ -37,7 +39,7 @@ class NativeBuffer { private final long address; private final int size; - private final Cleaner cleaner; + private final Cleaner.Cleanable cleanable; // optional "owner" to avoid copying // (only safe for use by thread-local caches) @@ -56,7 +58,7 @@ class NativeBuffer { NativeBuffer(int size) { this.address = unsafe.allocateMemory(size); this.size = size; - this.cleaner = Cleaner.create(this, new Deallocator(address)); + this.cleanable = CleanerFactory.cleaner().register(this, new Deallocator(address)); } void release() { @@ -71,8 +73,8 @@ class NativeBuffer { return size; } - Cleaner cleaner() { - return cleaner; + void free() { + cleanable.clean(); } // not synchronized; only safe for use by thread-local caches diff --git a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java index 728d96eb2b3..4f0aa5c9071 100644 --- a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java +++ b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java @@ -107,14 +107,14 @@ class NativeBuffers { for (int i=0; i Date: Thu, 10 Mar 2016 09:35:59 -0500 Subject: [PATCH 21/27] 8043329: Wrong variable used in java.util.Collections javadoc code Reviewed-by: lancea, rriggs --- jdk/src/java.base/share/classes/java/util/Collections.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/java.base/share/classes/java/util/Collections.java b/jdk/src/java.base/share/classes/java/util/Collections.java index 73047bff5d1..0eb9da0f644 100644 --- a/jdk/src/java.base/share/classes/java/util/Collections.java +++ b/jdk/src/java.base/share/classes/java/util/Collections.java @@ -2728,7 +2728,7 @@ public class Collections { * Set s2 = m2.keySet(); // Needn't be in synchronized block * ... * synchronized (m) { // Synchronizing on m, not m2 or s2! - * Iterator i = s.iterator(); // Must be in synchronized block + * Iterator i = s2.iterator(); // Must be in synchronized block * while (i.hasNext()) * foo(i.next()); * } From 94509dadd14a4f18355d25d0b7f593fa9159475f Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 10 Mar 2016 09:28:15 -0800 Subject: [PATCH 22/27] Added tag jdk-9+109 for changeset 652d06266511 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index ad3f50825db..8d4f94f1f2c 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -351,3 +351,4 @@ eee1ced1d8e78293f2a004af818ca474387dbebf jdk-9+103 6e9ecae50b4e0d37483fb2719202eea5dca026a4 jdk-9+106 8701b2bb1d2e1b9abc2a9be0933993c7150a9dbe jdk-9+107 42794e648cfe9fd67461dcbe8b7594241a84bcff jdk-9+108 +1c7bad0798900fe58f4db01ae7ffdc84f5baee8c jdk-9+109 From 28ad9686826e55fa5e7418bd220dc666262b615d Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Thu, 10 Mar 2016 11:52:54 -0800 Subject: [PATCH 23/27] 8151660: Revert NativeBuffer.java to use jdk.internal.ref.Cleaner Reviewed-by: rriggs --- .../share/classes/sun/nio/fs/NativeBuffer.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java index 7daf8ccfe16..1a215d11bf1 100644 --- a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java +++ b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java @@ -26,9 +26,7 @@ package sun.nio.fs; import jdk.internal.misc.Unsafe; -import jdk.internal.ref.CleanerFactory; - -import java.lang.ref.Cleaner; +import jdk.internal.ref.Cleaner; /** * A light-weight buffer in native memory. @@ -39,7 +37,7 @@ class NativeBuffer { private final long address; private final int size; - private final Cleaner.Cleanable cleanable; + private final Cleaner cleaner; // optional "owner" to avoid copying // (only safe for use by thread-local caches) @@ -58,7 +56,7 @@ class NativeBuffer { NativeBuffer(int size) { this.address = unsafe.allocateMemory(size); this.size = size; - this.cleanable = CleanerFactory.cleaner().register(this, new Deallocator(address)); + this.cleaner = Cleaner.create(this, new Deallocator(address)); } void release() { @@ -74,7 +72,7 @@ class NativeBuffer { } void free() { - cleanable.clean(); + cleaner.clean(); } // not synchronized; only safe for use by thread-local caches From 9566de29293818419aa29e305132770fe33aa07f Mon Sep 17 00:00:00 2001 From: Abhijit Roy Date: Fri, 11 Mar 2016 18:35:26 +0530 Subject: [PATCH 24/27] 8151065: Typo in javax.naming.CompoundName Reviewed-by: vinnie, prappo --- .../java.naming/share/classes/javax/naming/CompoundName.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/java.naming/share/classes/javax/naming/CompoundName.java b/jdk/src/java.naming/share/classes/javax/naming/CompoundName.java index a7f43a095e3..aa4b4eb252c 100644 --- a/jdk/src/java.naming/share/classes/javax/naming/CompoundName.java +++ b/jdk/src/java.naming/share/classes/javax/naming/CompoundName.java @@ -82,7 +82,7 @@ import java.util.Properties; * attribute-value-assertions when specifying multiple attribute/value * pairs. (e.g. "," in age=65,gender=male). *

jndi.syntax.separator.typeval - *
If present, specifies the string that separators attribute + *
If present, specifies the string that separates attribute * from value (e.g. "=" in "age=65") * * These properties are interpreted according to the following rules: From 781cae322ee663b62e229f6a837d6db8200aaaa6 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Fri, 11 Mar 2016 10:06:12 -0800 Subject: [PATCH 25/27] 8151679: Mark SignatureOffsets.java as intermittently failing Reviewed-by: xuelei --- jdk/test/sun/security/mscapi/SignatureOffsets.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/test/sun/security/mscapi/SignatureOffsets.java b/jdk/test/sun/security/mscapi/SignatureOffsets.java index 4c710396840..128cc00ca04 100644 --- a/jdk/test/sun/security/mscapi/SignatureOffsets.java +++ b/jdk/test/sun/security/mscapi/SignatureOffsets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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 @@ -28,7 +28,7 @@ import java.security.SignatureException; /* * @test * @bug 8050374 - * @key randomness + * @key randomness intermittent * @summary This test validates signature verification * Signature.verify(byte[], int, int). The test uses RandomFactory to * get random set of clear text data to sign. After the signature From 2fc3f9915c507fa9019bc971d568ebc46b378e6c Mon Sep 17 00:00:00 2001 From: Abhijit Roy Date: Fri, 11 Mar 2016 12:53:10 -0500 Subject: [PATCH 26/27] 8151063: Typo in java.lang.invoke.StringConcatFactory javadoc Reviewed-by: prappo, rriggs --- .../share/classes/java/lang/invoke/StringConcatFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java index 5fb5277e798..9a4cecdc561 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java @@ -91,7 +91,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*; * can call with more than 255 slots. This limits the number of static and * dynamic arguments one can pass to bootstrap method. Since there are potential * concatenation strategies that use {@code MethodHandle} combinators, we need - * to reserve a few empty slots on the parameter lists to to capture the + * to reserve a few empty slots on the parameter lists to capture the * temporal results. This is why bootstrap methods in this factory do not accept * more than 200 argument slots. Users requiring more than 200 argument slots in * concatenation are expected to split the large concatenation in smaller From 59eca614db537db2488b79c2eb8613b4fd615a27 Mon Sep 17 00:00:00 2001 From: Jamil Nimeh Date: Fri, 11 Mar 2016 10:54:42 -0800 Subject: [PATCH 27/27] 8132942: ServerHandshaker should not throw SSLHandshakeException when CertificateStatus constructor is called with invalid arguments Performs argument checking on inputs to the CertificateStatus constructor in order to eliminate the need for exception processing. Also pulls stapling processing logic out to its own method. Reviewed-by: xuelei --- .../sun/security/ssl/HandshakeMessage.java | 10 +- .../sun/security/ssl/ServerHandshaker.java | 239 ++++++++++-------- 2 files changed, 141 insertions(+), 108 deletions(-) diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java index 86c72bac38a..b49723aa462 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -700,7 +700,7 @@ static final class CertificateStatus extends HandshakeMessage * OCSP response data is provided. */ CertificateStatus(StatusRequestType type, X509Certificate[] chain, - Map responses) throws SSLException { + Map responses) { statusType = type; encodedResponsesLen = 0; encodedResponses = new ArrayList<>(chain.length); @@ -715,7 +715,7 @@ static final class CertificateStatus extends HandshakeMessage encodedResponses.add(respDER); encodedResponsesLen = 3 + respDER.length; } else { - throw new SSLHandshakeException("Zero-length or null " + + throw new IllegalArgumentException("Zero-length or null " + "OCSP Response"); } } else if (statusType == StatusRequestType.OCSP_MULTI) { @@ -732,8 +732,8 @@ static final class CertificateStatus extends HandshakeMessage } } } else { - throw new SSLHandshakeException("Unsupported StatusResponseType: " + - statusType); + throw new IllegalArgumentException( + "Unsupported StatusResponseType: " + statusType); } } diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java b/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java index eb3484c6c4b..a4c119faf25 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java @@ -36,7 +36,6 @@ import java.security.spec.ECParameterSpec; import java.math.BigInteger; import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.*; import sun.security.action.GetLongAction; @@ -67,7 +66,6 @@ final class ServerHandshaker extends Handshaker { // our authentication info private X509Certificate[] certs; - private Map responseMap; private PrivateKey privateKey; private Object serviceCreds; @@ -118,7 +116,6 @@ final class ServerHandshaker extends Handshaker { LegacyAlgorithmConstraints.PROPERTY_TLS_LEGACY_ALGS, new SSLAlgorithmDecomposer()); - private boolean staplingActive = false; private long statusRespTimeout; static { @@ -578,16 +575,6 @@ final class ServerHandshaker extends Handshaker { } } - // Check if the client has asserted the status_request[_v2] extension(s) - CertStatusReqExtension statReqExt = (CertStatusReqExtension) - mesg.extensions.get(ExtensionType.EXT_STATUS_REQUEST); - CertStatusReqListV2Extension statReqExtV2 = - (CertStatusReqListV2Extension)mesg.extensions.get( - ExtensionType.EXT_STATUS_REQUEST_V2); - // Keep stapling active if at least one of the extensions has been set - staplingActive = sslContext.isStaplingEnabled(false) && - (statReqExt != null || statReqExtV2 != null); - /* * FIRST, construct the ServerHello using the options and priorities * from the ClientHello. Update the (pending) cipher spec as we do @@ -883,79 +870,17 @@ final class ServerHandshaker extends Handshaker { m1.extensions.add(maxFragLenExt); } - StatusRequestType statReqType = null; - StatusRequest statReqData = null; - if (staplingActive && !resumingSession) { - ExtensionType statusRespExt = ExtensionType.EXT_STATUS_REQUEST; - - // Determine which type of stapling we are doing and assert the - // proper extension in the server hello. - // Favor status_request_v2 over status_request and ocsp_multi - // over ocsp. - // If multiple ocsp or ocsp_multi types exist, select the first - // instance of a given type - if (statReqExtV2 != null) { // RFC 6961 stapling - statusRespExt = ExtensionType.EXT_STATUS_REQUEST_V2; - List reqItems = - statReqExtV2.getRequestItems(); - int ocspIdx = -1; - int ocspMultiIdx = -1; - for (int pos = 0; pos < reqItems.size(); pos++) { - CertStatusReqItemV2 item = reqItems.get(pos); - if (ocspIdx < 0 && item.getType() == - StatusRequestType.OCSP) { - ocspIdx = pos; - } else if (ocspMultiIdx < 0 && item.getType() == - StatusRequestType.OCSP_MULTI) { - ocspMultiIdx = pos; - } - } - if (ocspMultiIdx >= 0) { - statReqType = reqItems.get(ocspMultiIdx).getType(); - statReqData = reqItems.get(ocspMultiIdx).getRequest(); - } else if (ocspIdx >= 0) { - statReqType = reqItems.get(ocspIdx).getType(); - statReqData = reqItems.get(ocspIdx).getRequest(); - } else { - // Some unknown type. We will not do stapling for - // this connection since we cannot understand the - // requested type. - staplingActive = false; - } - } else { // RFC 6066 stapling - statReqType = StatusRequestType.OCSP; - statReqData = statReqExt.getRequest(); - } - - if (statReqType != null && statReqData != null) { - StatusResponseManager statRespMgr = - sslContext.getStatusResponseManager(); - if (statRespMgr != null) { - responseMap = statRespMgr.get(statReqType, statReqData, - certs, statusRespTimeout, TimeUnit.MILLISECONDS); - if (!responseMap.isEmpty()) { - // We now can safely assert status_request[_v2] in our - // ServerHello, and know for certain that we can provide - // responses back to this client for this connection. - if (statusRespExt == ExtensionType.EXT_STATUS_REQUEST) { - m1.extensions.add(new CertStatusReqExtension()); - } else if (statusRespExt == - ExtensionType.EXT_STATUS_REQUEST_V2) { - m1.extensions.add( - new CertStatusReqListV2Extension()); - } - } - } else { - // This should not happen if stapling is active, but - // if lazy initialization of the StatusResponseManager - // doesn't occur we should turn off stapling. - if (debug != null && Debug.isOn("handshake")) { - System.out.println("Warning: lazy initialization " + - "of the StatusResponseManager failed. " + - "Stapling has been disabled."); - staplingActive = false; - } - } + StaplingParameters staplingParams = processStapling(mesg); + if (staplingParams != null) { + // We now can safely assert status_request[_v2] in our + // ServerHello, and know for certain that we can provide + // responses back to this client for this connection. + if (staplingParams.statusRespExt == + ExtensionType.EXT_STATUS_REQUEST) { + m1.extensions.add(new CertStatusReqExtension()); + } else if (staplingParams.statusRespExt == + ExtensionType.EXT_STATUS_REQUEST_V2) { + m1.extensions.add(new CertStatusReqListV2Extension()); } } @@ -1031,24 +956,15 @@ final class ServerHandshaker extends Handshaker { * supports status stapling and there is at least one response to * return to the client. */ - if (staplingActive && !responseMap.isEmpty()) { - try { - CertificateStatus csMsg = new CertificateStatus(statReqType, - certs, responseMap); - if (debug != null && Debug.isOn("handshake")) { - csMsg.print(System.out); - } - csMsg.write(output); - handshakeState.update(csMsg, resumingSession); - responseMap = null; - } catch (SSLException ssle) { - // We don't want the exception to be fatal, we just won't - // send the message if we fail on construction. - if (debug != null && Debug.isOn("handshake")) { - System.out.println("Failed during CertificateStatus " + - "construction: " + ssle); - } + if (staplingParams != null) { + CertificateStatus csMsg = new CertificateStatus( + staplingParams.statReqType, certs, + staplingParams.responseMap); + if (debug != null && Debug.isOn("handshake")) { + csMsg.print(System.out); } + csMsg.write(output); + handshakeState.update(csMsg, resumingSession); } /* @@ -2078,4 +1994,121 @@ final class ServerHandshaker extends Handshaker { session.setPeerCertificates(peerCerts); } + + private StaplingParameters processStapling(ClientHello mesg) { + StaplingParameters params = null; + ExtensionType ext; + StatusRequestType type = null; + StatusRequest req = null; + Map responses; + + // If this feature has not been enabled, then no more processing + // is necessary. Also we will only staple if we're doing a full + // handshake. + if (!sslContext.isStaplingEnabled(false) || resumingSession) { + return null; + } + + // Check if the client has asserted the status_request[_v2] extension(s) + CertStatusReqExtension statReqExt = (CertStatusReqExtension) + mesg.extensions.get(ExtensionType.EXT_STATUS_REQUEST); + CertStatusReqListV2Extension statReqExtV2 = + (CertStatusReqListV2Extension)mesg.extensions.get( + ExtensionType.EXT_STATUS_REQUEST_V2); + // Keep processing only if either status_request or status_request_v2 + // has been sent in the ClientHello. + if (statReqExt == null && statReqExtV2 == null) { + return null; + } + + // Determine which type of stapling we are doing and assert the + // proper extension in the server hello. + // Favor status_request_v2 over status_request and ocsp_multi + // over ocsp. + // If multiple ocsp or ocsp_multi types exist, select the first + // instance of a given type + ext = ExtensionType.EXT_STATUS_REQUEST; + if (statReqExtV2 != null) { // RFC 6961 stapling + ext = ExtensionType.EXT_STATUS_REQUEST_V2; + List reqItems = + statReqExtV2.getRequestItems(); + int ocspIdx = -1; + int ocspMultiIdx = -1; + for (int pos = 0; pos < reqItems.size(); pos++) { + CertStatusReqItemV2 item = reqItems.get(pos); + if (ocspIdx < 0 && item.getType() == + StatusRequestType.OCSP) { + ocspIdx = pos; + } else if (ocspMultiIdx < 0 && item.getType() == + StatusRequestType.OCSP_MULTI) { + ocspMultiIdx = pos; + } + } + if (ocspMultiIdx >= 0) { + type = reqItems.get(ocspMultiIdx).getType(); + req = reqItems.get(ocspMultiIdx).getRequest(); + } else if (ocspIdx >= 0) { + type = reqItems.get(ocspIdx).getType(); + req = reqItems.get(ocspIdx).getRequest(); + } + } else { // RFC 6066 stapling + type = StatusRequestType.OCSP; + req = statReqExt.getRequest(); + } + + // If, after walking through the extensions we were unable to + // find a suitable StatusRequest, then stapling is disabled. + // Both statReqType and statReqData must have been set to continue. + if (type == null || req == null) { + return null; + } + + // Get the OCSP responses from the StatusResponseManager + StatusResponseManager statRespMgr = + sslContext.getStatusResponseManager(); + if (statRespMgr != null) { + responses = statRespMgr.get(type, req, certs, statusRespTimeout, + TimeUnit.MILLISECONDS); + if (!responses.isEmpty()) { + // If this RFC 6066-style stapling (SSL cert only) then the + // response cannot be zero length + if (type == StatusRequestType.OCSP) { + byte[] respDER = responses.get(certs[0]); + if (respDER == null || respDER.length <= 0) { + return null; + } + } + params = new StaplingParameters(ext, type, req, responses); + } + } else { + // This should not happen, but if lazy initialization of the + // StatusResponseManager doesn't occur we should turn off stapling. + if (debug != null && Debug.isOn("handshake")) { + System.out.println("Warning: lazy initialization " + + "of the StatusResponseManager failed. " + + "Stapling has been disabled."); + } + } + + return params; + } + + /** + * Inner class used to hold stapling parameters needed by the handshaker + * when stapling is active. + */ + private class StaplingParameters { + private final ExtensionType statusRespExt; + private final StatusRequestType statReqType; + private final StatusRequest statReqData; + private final Map responseMap; + + StaplingParameters(ExtensionType ext, StatusRequestType type, + StatusRequest req, Map responses) { + statusRespExt = ext; + statReqType = type; + statReqData = req; + responseMap = responses; + } + } }