# HG changeset patch # User lana # Date 1452801859 28800 # Node ID 55680f011e48f77f8cc4aaa92be5c01f1fa2508a # Parent 06adfd8db1739cf09f9b6b6958c463fba593fe47# Parent 13e8054a06d9657a7f7f15f3e858320f539dc15b Merge diff -r 06adfd8db173 -r 55680f011e48 jdk/make/gendata/GendataBreakIterator.gmk --- a/jdk/make/gendata/GendataBreakIterator.gmk Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/make/gendata/GendataBreakIterator.gmk Thu Jan 14 12:04:19 2016 -0800 @@ -48,7 +48,6 @@ $(eval $(call SetupJavaCompilation,BUILD_BREAKITERATOR, \ SETUP := GENERATE_OLDBYTECODE, \ SRC := $(TEXT_SRCDIR), \ - INCLUDES := $(TEXT_PKG), \ INCLUDE_FILES := $(TEXT_SOURCES), \ BIN := $(BREAK_ITERATOR_CLASSES))) diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/java/lang/ClassLoader.java --- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu Jan 14 12:04:19 2016 -0800 @@ -50,6 +50,8 @@ import java.util.Hashtable; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; + +import jdk.internal.perf.PerfCounter; import sun.misc.Resource; import sun.misc.URLClassPath; import sun.reflect.CallerSensitive; @@ -423,9 +425,9 @@ c = findClass(name); // this is the defining class loader; record the stats - sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); - sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); - sun.misc.PerfCounter.getFindClasses().increment(); + PerfCounter.getParentDelegationTime().addTime(t1 - t0); + PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); + PerfCounter.getFindClasses().increment(); } } if (resolve) { diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java --- a/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java Thu Jan 14 12:04:19 2016 -0800 @@ -61,6 +61,9 @@ * local variable array is an {@link PrimitiveValue} object; * otherwise, the element is an {@code Object}. * + *

The returned array may contain null entries if a local variable is not + * live. + * * @return the local variable array of this stack frame. */ public Object[] getLocals(); diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/java/lang/System.java --- a/jdk/src/java.base/share/classes/java/lang/System.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/System.java Thu Jan 14 12:04:19 2016 -0800 @@ -1535,6 +1535,8 @@ * @return an instance of {@link Logger} that can be used by the calling * class. * @throws NullPointerException if {@code name} is {@code null}. + * + * @since 9 */ @CallerSensitive public static Logger getLogger(String name) { @@ -1572,6 +1574,8 @@ * resource bundle for message localization. * @throws NullPointerException if {@code name} is {@code null} or * {@code bundle} is {@code null}. + * + * @since 9 */ @CallerSensitive public static Logger getLogger(String name, ResourceBundle bundle) { diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Jan 14 12:04:19 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -3120,6 +3120,8 @@ MethodHandle handler) { MethodType ttype = target.type(); MethodType htype = handler.type(); + if (!Throwable.class.isAssignableFrom(exType)) + throw new ClassCastException(exType.getName()); if (htype.parameterCount() < 1 || !htype.parameterType(0).isAssignableFrom(exType)) throw newIllegalArgumentException("handler does not accept exception type "+exType); diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java --- a/jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java Thu Jan 14 12:04:19 2016 -0800 @@ -28,7 +28,7 @@ import java.util.Objects; import java.util.concurrent.ThreadFactory; -import jdk.internal.misc.CleanerImpl; +import jdk.internal.ref.CleanerImpl; /** * {@code Cleaner} manages a set of object references and corresponding cleaning actions. diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/java/net/URI.java --- a/jdk/src/java.base/share/classes/java/net/URI.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/java/net/URI.java Thu Jan 14 12:04:19 2016 -0800 @@ -1146,13 +1146,30 @@ if (part != null) { return part; } - StringBuilder sb = new StringBuilder(); - appendSchemeSpecificPart(sb, null, getAuthority(), getUserInfo(), + + String s = string; + if (s != null) { + // if string is defined, components will have been parsed + int start = 0; + int end = s.length(); + if (scheme != null) { + start = scheme.length() + 1; + } + if (fragment != null) { + end -= fragment.length() + 1; + } + if (path != null && path.length() == end - start) { + part = path; + } else { + part = s.substring(start, end); + } + } else { + StringBuilder sb = new StringBuilder(); + appendSchemeSpecificPart(sb, null, getAuthority(), getUserInfo(), host, port, getPath(), getQuery()); - if (sb.length() == 0) { - return null; + part = sb.toString(); } - return schemeSpecificPart = sb.toString(); + return schemeSpecificPart = part; } /** @@ -3056,7 +3073,6 @@ // void parse(boolean rsa) throws URISyntaxException { requireServerAuthority = rsa; - int ssp; // Start of scheme-specific part int n = input.length(); int p = scan(0, n, "/?#", ":"); if ((p >= 0) && at(p, n, ':')) { @@ -3066,21 +3082,20 @@ checkChars(1, p, L_SCHEME, H_SCHEME, "scheme name"); scheme = input.substring(0, p); p++; // Skip ':' - ssp = p; if (at(p, n, '/')) { p = parseHierarchical(p, n); } else { + // opaque; need to create the schemeSpecificPart int q = scan(p, n, "#"); if (q <= p) failExpecting("scheme-specific part", p); checkChars(p, q, L_URIC, H_URIC, "opaque part"); + schemeSpecificPart = input.substring(p, q); p = q; } } else { - ssp = 0; p = parseHierarchical(0, n); } - schemeSpecificPart = input.substring(ssp, p); if (at(p, n, '#')) { checkChars(p + 1, n, L_URIC, H_URIC, "fragment"); fragment = input.substring(p + 1, n); diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/java/net/URLClassLoader.java --- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Thu Jan 14 12:04:19 2016 -0800 @@ -52,6 +52,7 @@ import jdk.internal.misc.JavaNetAccess; import jdk.internal.misc.SharedSecrets; +import jdk.internal.perf.PerfCounter; import sun.misc.Resource; import sun.misc.URLClassPath; import sun.net.www.ParseUtil; @@ -459,14 +460,14 @@ // Use (direct) ByteBuffer: CodeSigner[] signers = res.getCodeSigners(); CodeSource cs = new CodeSource(url, signers); - sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0); + PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0); return defineClass(name, bb, cs); } else { byte[] b = res.getBytes(); // must read certificates AFTER reading bytes. CodeSigner[] signers = res.getCodeSigners(); CodeSource cs = new CodeSource(url, signers); - sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0); + PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0); return defineClass(name, b, 0, b.length, cs); } } diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/java/security/ProtectionDomain.java --- a/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Thu Jan 14 12:04:19 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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,12 +27,12 @@ import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Map; -import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import jdk.internal.misc.JavaSecurityAccess; import jdk.internal.misc.JavaSecurityProtectionDomainAccess; @@ -472,11 +472,15 @@ * * This class stores ProtectionDomains as weak keys in a ConcurrentHashMap * with additional support for checking and removing weak keys that are no - * longer in use. + * longer in use. There can be cases where the permission collection may + * have a chain of strong references back to the ProtectionDomain, which + * ordinarily would prevent the entry from being removed from the map. To + * address that, we wrap the permission collection in a SoftReference so + * that it can be reclaimed by the garbage collector due to memory demand. */ private static class PDCache implements ProtectionDomainCache { private final ConcurrentHashMap + SoftReference> pdMap = new ConcurrentHashMap<>(); private final ReferenceQueue queue = new ReferenceQueue<>(); @@ -485,15 +489,15 @@ processQueue(queue, pdMap); WeakProtectionDomainKey weakPd = new WeakProtectionDomainKey(pd, queue); - pdMap.putIfAbsent(weakPd, pc); + pdMap.put(weakPd, new SoftReference<>(pc)); } @Override public PermissionCollection get(ProtectionDomain pd) { processQueue(queue, pdMap); - WeakProtectionDomainKey weakPd = - new WeakProtectionDomainKey(pd, queue); - return pdMap.get(weakPd); + WeakProtectionDomainKey weakPd = new WeakProtectionDomainKey(pd); + SoftReference sr = pdMap.get(weakPd); + return (sr == null) ? null : sr.get(); } /** @@ -533,11 +537,20 @@ this((pd == null ? NULL_KEY : pd.key), rq); } + WeakProtectionDomainKey(ProtectionDomain pd) { + this(pd == null ? NULL_KEY : pd.key); + } + private WeakProtectionDomainKey(Key key, ReferenceQueue rq) { super(key, rq); hash = key.hashCode(); } + private WeakProtectionDomainKey(Key key) { + super(key); + hash = key.hashCode(); + } + /** * Returns the identity hash code of the original referent. */ diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/java/time/LocalDate.java --- a/jdk/src/java.base/share/classes/java/time/LocalDate.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/java/time/LocalDate.java Thu Jan 14 12:04:19 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -1369,6 +1369,23 @@ if (daysToAdd == 0) { return this; } + long dom = day + daysToAdd; + if (dom > 0) { + if (dom <= 28) { + return new LocalDate(year, month, (int) dom); + } else if (dom <= 59) { // 59th Jan is 28th Feb, 59th Feb is 31st Mar + long monthLen = lengthOfMonth(); + if (dom <= monthLen) { + return new LocalDate(year, month, (int) dom); + } else if (month < 12) { + return new LocalDate(year, month + 1, (int) (dom - monthLen)); + } else { + YEAR.checkValidValue(year + 1); + return new LocalDate(year + 1, 1, (int) (dom - monthLen)); + } + } + } + long mjDay = Math.addExact(toEpochDay(), daysToAdd); return LocalDate.ofEpochDay(mjDay); } diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/java/util/zip/ZipFile.java --- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java Thu Jan 14 12:04:19 2016 -0800 @@ -54,6 +54,7 @@ import java.util.stream.StreamSupport; import jdk.internal.misc.JavaUtilZipFileAccess; import jdk.internal.misc.SharedSecrets; +import jdk.internal.perf.PerfCounter; import static java.util.zip.ZipConstants.*; import static java.util.zip.ZipConstants64.*; @@ -210,8 +211,8 @@ this.name = name; long t0 = System.nanoTime(); this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0); - sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0); - sun.misc.PerfCounter.getZipFileCount().increment(); + PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0); + PerfCounter.getZipFileCount().increment(); } /** diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java --- a/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java Thu Jan 14 08:08:19 2016 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,788 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. 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 jdk.internal.misc; - -import java.lang.ref.Cleaner; -import java.lang.ref.Cleaner.Cleanable; -import java.lang.ref.PhantomReference; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Objects; -import java.util.concurrent.ThreadFactory; -import java.util.function.Function; - -import sun.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 implements Runnable { - - /** - * An object to access the CleanerImpl from a Cleaner; set by Cleaner init. - */ - private static Function cleanerImplAccess = null; - - /** - * Heads of a CleanableList for each reference type. - */ - final PhantomCleanable phantomCleanableList; - - final WeakCleanable weakCleanableList; - - final SoftCleanable softCleanableList; - - // The ReferenceQueue of pending cleaning actions - final ReferenceQueue queue; - - /** - * Called by Cleaner static initialization to provide the function - * to map from Cleaner to CleanerImpl. - * @param access a function to map from Cleaner to CleanerImpl - */ - public static void setCleanerImplAccess(Function access) { - if (cleanerImplAccess == null) { - cleanerImplAccess = access; - } - } - - /** - * Called to get the CleanerImpl for a Cleaner. - * @param cleaner the cleaner - * @return the corresponding CleanerImpl - */ - private static CleanerImpl getCleanerImpl(Cleaner cleaner) { - return cleanerImplAccess.apply(cleaner); - } - - /** - * Constructor for CleanerImpl. - */ - public CleanerImpl() { - queue = new ReferenceQueue<>(); - phantomCleanableList = new PhantomCleanableRef(this); - weakCleanableList = new WeakCleanableRef(this); - softCleanableList = new SoftCleanableRef(this); - } - - /** - * Starts the Cleaner implementation. - * When started waits for Cleanables to be queued. - * @param service the cleaner - * @param threadFactory the thread factory - */ - public void start(Cleaner service, ThreadFactory threadFactory) { - // schedule a nop cleaning action for the service, so the associated thread - // will continue to run at least until the service is reclaimable. - new PhantomCleanableRef(service, service, () -> {}); - - if (threadFactory == null) { - threadFactory = CleanerImpl.InnocuousThreadFactory.factory(); - } - - // now that there's at least one cleaning action, for the service, - // we can start the associated thread, which runs until - // all cleaning actions have been run. - Thread thread = threadFactory.newThread(this); - thread.setDaemon(true); - thread.start(); - } - - /** - * Process queued Cleanables as long as the cleanable lists are not empty. - * A Cleanable is in one of the lists for each Object and for the Cleaner - * itself. - * Terminates when the Cleaner is no longer reachable and - * has been cleaned and there are no more Cleanable instances - * for which the object is reachable. - *

- * If the thread is a ManagedLocalsThread, the threadlocals - * are erased before each cleanup - */ - public void run() { - Thread t = Thread.currentThread(); - InnocuousThread mlThread = (t instanceof InnocuousThread) - ? (InnocuousThread) t - : null; - while (!phantomCleanableList.isListEmpty() || - !weakCleanableList.isListEmpty() || - !softCleanableList.isListEmpty()) { - if (mlThread != null) { - // Clear the thread locals - mlThread.eraseThreadLocals(); - } - try { - // Wait for a Ref, with a timeout to avoid getting hung - // due to a race with clear/clean - Cleanable ref = (Cleanable) queue.remove(60 * 1000L); - if (ref != null) { - ref.clean(); - } - } catch (InterruptedException i) { - continue; // ignore the interruption - } catch (Throwable e) { - // ignore exceptions from the cleanup action - } - } - } - - /** - * PhantomCleanable subclasses efficiently encapsulate cleanup state and - * the cleaning action. - * Subclasses implement the abstract {@link #performCleanup()} method - * to provide the cleaning action. - * When constructed, the object reference and the {@link Cleanable Cleanable} - * are registered with the {@link Cleaner}. - * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the - * referent becomes phantom reachable. - */ - public static abstract class PhantomCleanable extends PhantomReference - implements Cleaner.Cleanable { - - /** - * Links to previous and next in a doubly-linked list. - */ - PhantomCleanable prev = this, next = this; - - /** - * The CleanerImpl for this Cleanable. - */ - private final CleanerImpl cleanerImpl; - - /** - * Constructs new {@code PhantomCleanable} with - * {@code non-null referent} and {@code non-null cleaner}. - * The {@code cleaner} is not retained; it is only used to - * register the newly constructed {@link Cleaner.Cleanable Cleanable}. - * - * @param referent the referent to track - * @param cleaner the {@code Cleaner} to register with - */ - public PhantomCleanable(T referent, Cleaner cleaner) { - super(Objects.requireNonNull(referent), getCleanerImpl(cleaner).queue); - this.cleanerImpl = getCleanerImpl(cleaner); - insert(); - - // TODO: Replace getClass() with ReachabilityFence when it is available - cleaner.getClass(); - referent.getClass(); - } - - /** - * Construct a new root of the list; not inserted. - */ - PhantomCleanable(CleanerImpl cleanerImpl) { - super(null, null); - this.cleanerImpl = cleanerImpl; - } - - /** - * Insert this PhantomCleanable after the list head. - */ - private void insert() { - final PhantomCleanable list = cleanerImpl.phantomCleanableList; - synchronized (list) { - prev = list; - next = list.next; - next.prev = this; - list.next = this; - } - } - - /** - * Remove this PhantomCleanable from the list. - * - * @return true if Cleanable was removed or false if not because - * it had already been removed before - */ - private boolean remove() { - PhantomCleanable list = cleanerImpl.phantomCleanableList; - synchronized (list) { - if (next != this) { - next.prev = prev; - prev.next = next; - prev = this; - next = this; - return true; - } - return false; - } - } - - /** - * Returns true if the list's next reference refers to itself. - * - * @return true if the list is empty - */ - boolean isListEmpty() { - PhantomCleanable list = cleanerImpl.phantomCleanableList; - synchronized (list) { - return list == list.next; - } - } - - /** - * Unregister this PhantomCleanable and invoke {@link #performCleanup()}, - * ensuring at-most-once semantics. - */ - @Override - public final void clean() { - if (remove()) { - super.clear(); - performCleanup(); - } - } - - /** - * Unregister this PhantomCleanable and clear the reference. - * Due to inherent concurrency, {@link #performCleanup()} may still be invoked. - */ - @Override - public void clear() { - if (remove()) { - super.clear(); - } - } - - /** - * The {@code performCleanup} abstract method is overridden - * to implement the cleaning logic. - * The {@code performCleanup} method should not be called except - * by the {@link #clean} method which ensures at most once semantics. - */ - protected abstract void performCleanup(); - - /** - * This method always throws {@link UnsupportedOperationException}. - * Enqueuing details of {@link Cleaner.Cleanable} - * are a private implementation detail. - * - * @throws UnsupportedOperationException always - */ - @Override - public final boolean isEnqueued() { - throw new UnsupportedOperationException("isEnqueued"); - } - - /** - * This method always throws {@link UnsupportedOperationException}. - * Enqueuing details of {@link Cleaner.Cleanable} - * are a private implementation detail. - * - * @throws UnsupportedOperationException always - */ - @Override - public final boolean enqueue() { - throw new UnsupportedOperationException("enqueue"); - } - } - - /** - * WeakCleanable subclasses efficiently encapsulate cleanup state and - * the cleaning action. - * Subclasses implement the abstract {@link #performCleanup()} method - * to provide the cleaning action. - * When constructed, the object reference and the {@link Cleanable Cleanable} - * are registered with the {@link Cleaner}. - * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the - * referent becomes weakly reachable. - */ - public static abstract class WeakCleanable extends WeakReference - implements Cleaner.Cleanable { - - /** - * Links to previous and next in a doubly-linked list. - */ - WeakCleanable prev = this, next = this; - - /** - * The CleanerImpl for this Cleanable. - */ - private final CleanerImpl cleanerImpl; - - /** - * Constructs new {@code WeakCleanableReference} with - * {@code non-null referent} and {@code non-null cleaner}. - * The {@code cleaner} is not retained by this reference; it is only used - * to register the newly constructed {@link Cleaner.Cleanable Cleanable}. - * - * @param referent the referent to track - * @param cleaner the {@code Cleaner} to register new reference with - */ - public WeakCleanable(T referent, Cleaner cleaner) { - super(Objects.requireNonNull(referent), getCleanerImpl(cleaner).queue); - cleanerImpl = getCleanerImpl(cleaner); - insert(); - - // TODO: Replace getClass() with ReachabilityFence when it is available - cleaner.getClass(); - referent.getClass(); - } - - /** - * Construct a new root of the list; not inserted. - */ - WeakCleanable(CleanerImpl cleanerImpl) { - super(null, null); - this.cleanerImpl = cleanerImpl; - } - - /** - * Insert this WeakCleanableReference after the list head. - */ - private void insert() { - final WeakCleanable list = cleanerImpl.weakCleanableList; - synchronized (list) { - prev = list; - next = list.next; - next.prev = this; - list.next = this; - } - } - - /** - * Remove this WeakCleanableReference from the list. - * - * @return true if Cleanable was removed or false if not because - * it had already been removed before - */ - private boolean remove() { - WeakCleanable list = cleanerImpl.weakCleanableList; - synchronized (list) { - if (next != this) { - next.prev = prev; - prev.next = next; - prev = this; - next = this; - return true; - } - return false; - } - } - - /** - * Returns true if the list's next reference refers to itself. - * - * @return true if the list is empty - */ - boolean isListEmpty() { - WeakCleanable list = cleanerImpl.weakCleanableList; - synchronized (list) { - return list == list.next; - } - } - - /** - * Unregister this WeakCleanable reference and invoke {@link #performCleanup()}, - * ensuring at-most-once semantics. - */ - @Override - public final void clean() { - if (remove()) { - super.clear(); - performCleanup(); - } - } - - /** - * Unregister this WeakCleanable and clear the reference. - * Due to inherent concurrency, {@link #performCleanup()} may still be invoked. - */ - @Override - public void clear() { - if (remove()) { - super.clear(); - } - } - - /** - * The {@code performCleanup} abstract method is overridden - * to implement the cleaning logic. - * The {@code performCleanup} method should not be called except - * by the {@link #clean} method which ensures at most once semantics. - */ - protected abstract void performCleanup(); - - /** - * This method always throws {@link UnsupportedOperationException}. - * Enqueuing details of {@link java.lang.ref.Cleaner.Cleanable} - * are a private implementation detail. - * - * @throws UnsupportedOperationException always - */ - @Override - public final boolean isEnqueued() { - throw new UnsupportedOperationException("isEnqueued"); - } - - /** - * This method always throws {@link UnsupportedOperationException}. - * Enqueuing details of {@link java.lang.ref.Cleaner.Cleanable} - * are a private implementation detail. - * - * @throws UnsupportedOperationException always - */ - @Override - public final boolean enqueue() { - throw new UnsupportedOperationException("enqueue"); - } - } - - /** - * SoftCleanable subclasses efficiently encapsulate cleanup state and - * the cleaning action. - * Subclasses implement the abstract {@link #performCleanup()} method - * to provide the cleaning action. - * When constructed, the object reference and the {@link Cleanable Cleanable} - * are registered with the {@link Cleaner}. - * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the - * referent becomes softly reachable. - */ - public static abstract class SoftCleanable extends SoftReference - implements Cleaner.Cleanable { - - /** - * Links to previous and next in a doubly-linked list. - */ - SoftCleanable prev = this, next = this; - - /** - * The CleanerImpl for this Cleanable. - */ - private final CleanerImpl cleanerImpl; - - /** - * Constructs new {@code SoftCleanableReference} with - * {@code non-null referent} and {@code non-null cleaner}. - * The {@code cleaner} is not retained by this reference; it is only used - * to register the newly constructed {@link Cleaner.Cleanable Cleanable}. - * - * @param referent the referent to track - * @param cleaner the {@code Cleaner} to register with - */ - public SoftCleanable(T referent, Cleaner cleaner) { - super(Objects.requireNonNull(referent), getCleanerImpl(cleaner).queue); - cleanerImpl = getCleanerImpl(cleaner); - insert(); - - // TODO: Replace getClass() with ReachabilityFence when it is available - cleaner.getClass(); - referent.getClass(); - } - - /** - * Construct a new root of the list; not inserted. - */ - SoftCleanable(CleanerImpl cleanerImpl) { - super(null, null); - this.cleanerImpl = cleanerImpl; - } - - /** - * Insert this SoftCleanableReference after the list head. - */ - private void insert() { - final SoftCleanable list = cleanerImpl.softCleanableList; - synchronized (list) { - prev = list; - next = list.next; - next.prev = this; - list.next = this; - } - } - - /** - * Remove this SoftCleanableReference from the list. - * - * @return true if Cleanable was removed or false if not because - * it had already been removed before - */ - private boolean remove() { - SoftCleanable list = cleanerImpl.softCleanableList; - synchronized (list) { - if (next != this) { - next.prev = prev; - prev.next = next; - prev = this; - next = this; - return true; - } - return false; - } - } - - /** - * Returns true if the list's next reference refers to itself. - * - * @return true if the list is empty - */ - boolean isListEmpty() { - SoftCleanable list = cleanerImpl.softCleanableList; - synchronized (list) { - return list == list.next; - } - } - - /** - * Unregister this SoftCleanable reference and invoke {@link #performCleanup()}, - * ensuring at-most-once semantics. - */ - @Override - public final void clean() { - if (remove()) { - super.clear(); - performCleanup(); - } - } - - /** - * Unregister this SoftCleanable and clear the reference. - * Due to inherent concurrency, {@link #performCleanup()} may still be invoked. - */ - @Override - public void clear() { - if (remove()) { - super.clear(); - } - } - - /** - * The {@code performCleanup} abstract method is overridden - * to implement the cleaning logic. - * The {@code performCleanup} method should not be called except - * by the {@link #clean} method which ensures at most once semantics. - */ - protected abstract void performCleanup(); - - /** - * This method always throws {@link UnsupportedOperationException}. - * Enqueuing details of {@link Cleaner.Cleanable} - * are a private implementation detail. - * - * @throws UnsupportedOperationException always - */ - @Override - public final boolean isEnqueued() { - throw new UnsupportedOperationException("isEnqueued"); - } - - /** - * This method always throws {@link UnsupportedOperationException}. - * Enqueuing details of {@link Cleaner.Cleanable} - * are a private implementation detail. - * - * @throws UnsupportedOperationException always - */ - @Override - public final boolean enqueue() { - throw new UnsupportedOperationException("enqueue"); - } - } - - /** - * Perform cleaning on an unreachable PhantomReference. - */ - public static final class PhantomCleanableRef extends PhantomCleanable { - private final Runnable action; - - /** - * Constructor for a phantom cleanable reference. - * @param obj the object to monitor - * @param cleaner the cleaner - * @param action the action Runnable - */ - public PhantomCleanableRef(Object obj, Cleaner cleaner, Runnable action) { - super(obj, cleaner); - this.action = action; - } - - /** - * Constructor used only for root of phantom cleanable list. - * @param cleanerImpl the cleanerImpl - */ - PhantomCleanableRef(CleanerImpl cleanerImpl) { - super(cleanerImpl); - this.action = null; - } - - @Override - protected void performCleanup() { - action.run(); - } - - /** - * Prevent access to referent even when it is still alive. - * - * @throws UnsupportedOperationException always - */ - @Override - public Object get() { - throw new UnsupportedOperationException("get"); - } - - /** - * Direct clearing of the referent is not supported. - * - * @throws UnsupportedOperationException always - */ - @Override - public void clear() { - throw new UnsupportedOperationException("clear"); - } - } - - /** - * Perform cleaning on an unreachable WeakReference. - */ - public static final class WeakCleanableRef extends WeakCleanable { - private final Runnable action; - - /** - * Constructor for a weak cleanable reference. - * @param obj the object to monitor - * @param cleaner the cleaner - * @param action the action Runnable - */ - WeakCleanableRef(Object obj, Cleaner cleaner, Runnable action) { - super(obj, cleaner); - this.action = action; - } - - /** - * Constructor used only for root of weak cleanable list. - * @param cleanerImpl the cleanerImpl - */ - WeakCleanableRef(CleanerImpl cleanerImpl) { - super(cleanerImpl); - this.action = null; - } - - @Override - protected void performCleanup() { - action.run(); - } - - /** - * Prevent access to referent even when it is still alive. - * - * @throws UnsupportedOperationException always - */ - @Override - public Object get() { - throw new UnsupportedOperationException("get"); - } - - /** - * Direct clearing of the referent is not supported. - * - * @throws UnsupportedOperationException always - */ - @Override - public void clear() { - throw new UnsupportedOperationException("clear"); - } - } - - /** - * Perform cleaning on an unreachable SoftReference. - */ - public static final class SoftCleanableRef extends SoftCleanable { - private final Runnable action; - - /** - * Constructor for a soft cleanable reference. - * @param obj the object to monitor - * @param cleaner the cleaner - * @param action the action Runnable - */ - SoftCleanableRef(Object obj, Cleaner cleaner, Runnable action) { - super(obj, cleaner); - this.action = action; - } - - /** - * Constructor used only for root of soft cleanable list. - * @param cleanerImpl the cleanerImpl - */ - SoftCleanableRef(CleanerImpl cleanerImpl) { - super(cleanerImpl); - this.action = null; - } - - @Override - protected void performCleanup() { - action.run(); - } - - /** - * Prevent access to referent even when it is still alive. - * - * @throws UnsupportedOperationException always - */ - @Override - public Object get() { - throw new UnsupportedOperationException("get"); - } - - /** - * Direct clearing of the referent is not supported. - * - * @throws UnsupportedOperationException always - */ - @Override - public void clear() { - throw new UnsupportedOperationException("clear"); - } - - } - - /** - * A ThreadFactory for InnocuousThreads. - * The factory is a singleton. - */ - static final class InnocuousThreadFactory implements ThreadFactory { - final static ThreadFactory factory = new InnocuousThreadFactory(); - - static ThreadFactory factory() { - return factory; - } - - 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; - }); - } - } - -} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/jdk/internal/perf/Perf.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/perf/Perf.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,547 @@ +/* + * Copyright (c) 2002, 2006, 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 jdk.internal.perf; + +import java.nio.ByteBuffer; +import java.security.Permission; +import java.security.PrivilegedAction; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import jdk.internal.ref.CleanerFactory; + +/** + * The Perf class provides the ability to attach to an instrumentation + * buffer maintained by a Java virtual machine. The instrumentation + * buffer may be for the Java virtual machine running the methods of + * this class or it may be for another Java virtual machine on the + * same system. + *

+ * In addition, this class provides methods to create instrumentation + * objects in the instrumentation buffer for the Java virtual machine + * that is running these methods. It also contains methods for acquiring + * the value of a platform specific high resolution clock for time + * stamp and interval measurement purposes. + * + * @author Brian Doherty + * @since 1.4.2 + * @see #getPerf + * @see jdk.internal.perf.Perf.GetPerfAction + * @see java.nio.ByteBuffer + */ +public final class Perf { + + private static Perf instance; + + private static final int PERF_MODE_RO = 0; + private static final int PERF_MODE_RW = 1; + + private Perf() { } // prevent instantiation + + /** + * The GetPerfAction class is a convenience class for acquiring access + * to the singleton Perf instance using the + * AccessController.doPrivileged() method. + *

+ * An instance of this class can be used as the argument to + * AccessController.doPrivileged(PrivilegedAction). + *

Here is a suggested idiom for use of this class: + * + *

{@code
+     * class MyTrustedClass {
+     *   private static final Perf perf =
+     *       AccessController.doPrivileged(new Perf.GetPerfAction());
+     *   ...
+     * }
+     * }
+ *

+ * In the presence of a security manager, the MyTrustedClass + * class in the above example will need to be granted the + * "sun.misc.Perf.getPerf" RuntimePermission + * permission in order to successfully acquire the singleton Perf instance. + *

+ * Please note that the "sun.misc.Perf.getPerf" permission + * is not a JDK specified permission. + * + * @see java.security.AccessController#doPrivileged(PrivilegedAction) + * @see java.lang.RuntimePermission + */ + public static class GetPerfAction implements PrivilegedAction + { + /** + * Run the Perf.getPerf() method in a privileged context. + * + * @see #getPerf + */ + public Perf run() { + return getPerf(); + } + } + + /** + * Return a reference to the singleton Perf instance. + *

+ * The getPerf() method returns the singleton instance of the Perf + * class. The returned object provides the caller with the capability + * for accessing the instrumentation buffer for this or another local + * Java virtual machine. + *

+ * If a security manager is installed, its checkPermission + * method is called with a RuntimePermission with a target + * of "sun.misc.Perf.getPerf". A security exception will result + * if the caller has not been granted this permission. + *

+ * Access to the returned Perf object should be protected + * by its caller and not passed on to untrusted code. This object can + * be used to attach to the instrumentation buffer provided by this Java + * virtual machine or for those of other Java virtual machines running + * on the same system. The instrumentation buffer may contain senstitive + * information. API's built on top of this interface may want to provide + * finer grained access control to the contents of individual + * instrumentation objects contained within the buffer. + *

+ * Please note that the "sun.misc.Perf.getPerf" permission + * is not a JDK specified permission. + * + * @return A reference to the singleton Perf instance. + * @throws SecurityException if a security manager exists and its + * checkPermission method doesn't allow access + * to the "jdk.internal.perf.Perf.getPerf"" target. + * @see java.lang.RuntimePermission + * @see #attach + */ + public static Perf getPerf() + { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + Permission perm = new RuntimePermission("jdk.internal.perf.Perf.getPerf"); + security.checkPermission(perm); + } + + return instance; + } + + /** + * Attach to the instrumentation buffer for the specified Java virtual + * machine. + *

+ * This method will attach to the instrumentation buffer for the + * specified virtual machine. It returns a ByteBuffer object + * that is initialized to access the instrumentation buffer for the + * indicated Java virtual machine. The lvmid parameter is + * a integer value that uniquely identifies the target local Java virtual + * machine. It is typically, but not necessarily, the process id of + * the target Java virtual machine. + *

+ * If the lvmid identifies a Java virtual machine different + * from the one running this method, then the coherency characteristics + * of the buffer are implementation dependent. Implementations that do + * not support named, coherent, shared memory may return a + * ByteBuffer object that contains only a snap shot of the + * data in the instrumentation buffer. Implementations that support named, + * coherent, shared memory, may return a ByteBuffer object + * that will be changing dynamically over time as the target Java virtual + * machine updates its mapping of this buffer. + *

+ * If the lvmid is 0 or equal to the actual lvmid + * for the Java virtual machine running this method, then the returned + * ByteBuffer object will always be coherent and dynamically + * changing. + *

+ * The attach mode specifies the access permissions requested for the + * instrumentation buffer of the target virtual machine. The permitted + * access permissions are: + *

    + *
  • "r" - Read only access. This Java virtual machine has only + * read access to the instrumentation buffer for the target Java + * virtual machine. + *
  • "rw" - Read/Write access. This Java virtual machine has read and + * write access to the instrumentation buffer for the target Java virtual + * machine. This mode is currently not supported and is reserved for + * future enhancements. + *
+ * + * @param lvmid an integer that uniquely identifies the + * target local Java virtual machine. + * @param mode a string indicating the attach mode. + * @return ByteBuffer a direct allocated byte buffer + * @throws IllegalArgumentException The lvmid or mode was invalid. + * @throws IOException An I/O error occurred while trying to acquire + * the instrumentation buffer. + * @throws OutOfMemoryError The instrumentation buffer could not be mapped + * into the virtual machine's address space. + * @see java.nio.ByteBuffer + */ + public ByteBuffer attach(int lvmid, String mode) + throws IllegalArgumentException, IOException + { + if (mode.compareTo("r") == 0) { + return attachImpl(null, lvmid, PERF_MODE_RO); + } + else if (mode.compareTo("rw") == 0) { + return attachImpl(null, lvmid, PERF_MODE_RW); + } + else { + throw new IllegalArgumentException("unknown mode"); + } + } + + /** + * Attach to the instrumentation buffer for the specified Java virtual + * machine owned by the given user. + *

+ * This method behaves just as the attach(int lvmid, String mode) + * method, except that it only searches for Java virtual machines + * owned by the specified user. + * + * @param user A String object containing the + * name of the user that owns the target Java + * virtual machine. + * @param lvmid an integer that uniquely identifies the + * target local Java virtual machine. + * @param mode a string indicating the attach mode. + * @return ByteBuffer a direct allocated byte buffer + * @throws IllegalArgumentException The lvmid or mode was invalid. + * @throws IOException An I/O error occurred while trying to acquire + * the instrumentation buffer. + * @throws OutOfMemoryError The instrumentation buffer could not be mapped + * into the virtual machine's address space. + * @see java.nio.ByteBuffer + */ + public ByteBuffer attach(String user, int lvmid, String mode) + throws IllegalArgumentException, IOException + { + if (mode.compareTo("r") == 0) { + return attachImpl(user, lvmid, PERF_MODE_RO); + } + else if (mode.compareTo("rw") == 0) { + return attachImpl(user, lvmid, PERF_MODE_RW); + } + else { + throw new IllegalArgumentException("unknown mode"); + } + } + + /** + * Call the implementation specific attach method. + *

+ * This method calls into the Java virtual machine to perform the platform + * specific attach method. Buffers returned from this method are + * internally managed as PhantomRefereces to provide for + * guaranteed, secure release of the native resources. + * + * @param user A String object containing the + * name of the user that owns the target Java + * virtual machine. + * @param lvmid an integer that uniquely identifies the + * target local Java virtual machine. + * @param mode a string indicating the attach mode. + * @return ByteBuffer a direct allocated byte buffer + * @throws IllegalArgumentException The lvmid or mode was invalid. + * @throws IOException An I/O error occurred while trying to acquire + * the instrumentation buffer. + * @throws OutOfMemoryError The instrumentation buffer could not be mapped + * into the virtual machine's address space. + */ + private ByteBuffer attachImpl(String user, int lvmid, int mode) + throws IllegalArgumentException, IOException + { + final ByteBuffer b = attach(user, lvmid, mode); + + if (lvmid == 0) { + // The native instrumentation buffer for this Java virtual + // machine is never unmapped. + return b; + } + else { + // This is an instrumentation buffer for another Java virtual + // machine with native resources that need to be managed. We + // create a duplicate of the native ByteBuffer and manage it + // with a Cleaner. When the duplicate becomes phantom reachable, + // the native resources will be released. + + final ByteBuffer dup = b.duplicate(); + + CleanerFactory.cleaner() + .register(dup, new CleanerAction(instance, b)); + return dup; + } + } + + private static class CleanerAction implements Runnable { + private final ByteBuffer bb; + private final Perf perf; + CleanerAction(Perf perf, ByteBuffer bb) { + this.perf = perf; + this.bb = bb; + } + public void run() { + try { + perf.detach(bb); + } catch (Throwable th) { + // avoid crashing the reference handler thread, + // but provide for some diagnosability + assert false : th.toString(); + } + } + } + + /** + * Native method to perform the implementation specific attach mechanism. + *

+ * The implementation of this method may return distinct or identical + * ByteBuffer objects for two distinct calls requesting + * attachment to the same Java virtual machine. + *

+ * For the Sun HotSpot JVM, two distinct calls to attach to the same + * target Java virtual machine will result in two distinct ByteBuffer + * objects returned by this method. This may change in a future release. + * + * @param user A String object containing the + * name of the user that owns the target Java + * virtual machine. + * @param lvmid an integer that uniquely identifies the + * target local Java virtual machine. + * @param mode a string indicating the attach mode. + * @return ByteBuffer a direct allocated byte buffer + * @throws IllegalArgumentException The lvmid or mode was invalid. + * @throws IOException An I/O error occurred while trying to acquire + * the instrumentation buffer. + * @throws OutOfMemoryError The instrumentation buffer could not be mapped + * into the virtual machine's address space. + */ + private native ByteBuffer attach(String user, int lvmid, int mode) + throws IllegalArgumentException, IOException; + + /** + * Native method to perform the implementation specific detach mechanism. + *

+ * If this method is passed a ByteBuffer object that is + * not created by the attach method, then the results of + * this method are undefined, with unpredictable and potentially damaging + * effects to the Java virtual machine. To prevent accidental or malicious + * use of this method, all native ByteBuffer created by the + * attach method are managed internally as PhantomReferences + * and resources are freed by the system. + *

+ * If this method is passed a ByteBuffer object created + * by the attach method with a lvmid for the Java virtual + * machine running this method (lvmid=0, for example), then the detach + * request is silently ignored. + * + * @param bb A direct allocated byte buffer created by the + * attach method. + * @see java.nio.ByteBuffer + * @see #attach + */ + private native void detach(ByteBuffer bb); + + /** + * Create a long scalar entry in the instrumentation buffer + * with the given variability characteristic, units, and initial value. + *

+ * Access to the instrument is provided through the returned + * ByteBuffer object. Typically, this object should be wrapped + * with LongBuffer view object. + * + * @param variability the variability characteristic for this entry. + * @param units the units for this entry. + * @param name the name of this entry. + * @param value the initial value for this entry. + * @return ByteBuffer a direct allocated ByteBuffer object that + * allows write access to a native memory location + * containing a long value. + * + * see sun.misc.perf.Variability + * see sun.misc.perf.Units + * @see java.nio.ByteBuffer + */ + public native ByteBuffer createLong(String name, int variability, + int units, long value); + + /** + * Create a String entry in the instrumentation buffer with + * the given variability characteristic, units, and initial value. + *

+ * The maximum length of the String stored in this string + * instrument is given in by maxLength parameter. Updates + * to this instrument with String values with lengths greater + * than maxLength will be truncated to maxLength. + * The truncated value will be terminated by a null character. + *

+ * The underlying implementation may further limit the length of the + * value, but will continue to preserve the null terminator. + *

+ * Access to the instrument is provided through the returned + * ByteBuffer object. + * + * @param variability the variability characteristic for this entry. + * @param units the units for this entry. + * @param name the name of this entry. + * @param value the initial value for this entry. + * @param maxLength the maximum string length for this string + * instrument. + * @return ByteBuffer a direct allocated ByteBuffer that allows + * write access to a native memory location + * containing a long value. + * + * see sun.misc.perf.Variability + * see sun.misc.perf.Units + * @see java.nio.ByteBuffer + */ + public ByteBuffer createString(String name, int variability, + int units, String value, int maxLength) + { + byte[] v = getBytes(value); + byte[] v1 = new byte[v.length+1]; + System.arraycopy(v, 0, v1, 0, v.length); + v1[v.length] = '\0'; + return createByteArray(name, variability, units, v1, Math.max(v1.length, maxLength)); + } + + /** + * Create a String entry in the instrumentation buffer with + * the given variability characteristic, units, and initial value. + *

+ * The maximum length of the String stored in this string + * instrument is implied by the length of the value parameter. + * Subsequent updates to the value of this instrument will be truncated + * to this implied maximum length. The truncated value will be terminated + * by a null character. + *

+ * The underlying implementation may further limit the length of the + * initial or subsequent value, but will continue to preserve the null + * terminator. + *

+ * Access to the instrument is provided through the returned + * ByteBuffer object. + * + * @param variability the variability characteristic for this entry. + * @param units the units for this entry. + * @param name the name of this entry. + * @param value the initial value for this entry. + * @return ByteBuffer a direct allocated ByteBuffer that allows + * write access to a native memory location + * containing a long value. + * + * see sun.misc.perf.Variability + * see sun.misc.perf.Units + * @see java.nio.ByteBuffer + */ + public ByteBuffer createString(String name, int variability, + int units, String value) + { + byte[] v = getBytes(value); + byte[] v1 = new byte[v.length+1]; + System.arraycopy(v, 0, v1, 0, v.length); + v1[v.length] = '\0'; + return createByteArray(name, variability, units, v1, v1.length); + } + + /** + * Create a byte vector entry in the instrumentation buffer + * with the given variability characteristic, units, and initial value. + *

+ * The maxLength parameter limits the size of the byte + * array instrument such that the initial or subsequent updates beyond + * this length are silently ignored. No special handling of truncated + * updates is provided. + *

+ * The underlying implementation may further limit the length of the + * length of the initial or subsequent value. + *

+ * Access to the instrument is provided through the returned + * ByteBuffer object. + * + * @param variability the variability characteristic for this entry. + * @param units the units for this entry. + * @param name the name of this entry. + * @param value the initial value for this entry. + * @param maxLength the maximum length of this byte array. + * @return ByteBuffer a direct allocated byte buffer that allows + * write access to a native memory location + * containing a long value. + * + * see sun.misc.perf.Variability + * see sun.misc.perf.Units + * @see java.nio.ByteBuffer + */ + public native ByteBuffer createByteArray(String name, int variability, + int units, byte[] value, + int maxLength); + + + /** + * convert string to an array of UTF-8 bytes + */ + private static byte[] getBytes(String s) + { + byte[] bytes = null; + + try { + bytes = s.getBytes("UTF-8"); + } + catch (UnsupportedEncodingException e) { + // ignore, UTF-8 encoding is always known + } + + return bytes; + } + + /** + * Return the value of the High Resolution Counter. + * + * The High Resolution Counter returns the number of ticks since + * since the start of the Java virtual machine. The resolution of + * the counter is machine dependent and can be determined from the + * value return by the {@link #highResFrequency} method. + * + * @return the number of ticks of machine dependent resolution since + * the start of the Java virtual machine. + * + * @see #highResFrequency + * @see java.lang.System#currentTimeMillis() + */ + public native long highResCounter(); + + /** + * Returns the frequency of the High Resolution Counter, in ticks per + * second. + * + * This value can be used to convert the value of the High Resolution + * Counter, as returned from a call to the {@link #highResCounter} method, + * into the number of seconds since the start of the Java virtual machine. + * + * @return the frequency of the High Resolution Counter. + * @see #highResCounter + */ + public native long highResFrequency(); + + private static native void registerNatives(); + + static { + registerNatives(); + instance = new Perf(); + } +} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/jdk/internal/perf/PerfCounter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/perf/PerfCounter.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.perf; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.LongBuffer; +import java.security.AccessController; + +/** + * Performance counter support for internal JRE classes. + * This class defines a fixed list of counters for the platform + * to use as an interim solution until RFE# 6209222 is implemented. + * The perf counters will be created in the jvmstat perf buffer + * that the HotSpot VM creates. The default size is 32K and thus + * the number of counters is bounded. You can alter the size + * with {@code -XX:PerfDataMemorySize=} option. If there is + * insufficient memory in the jvmstat perf buffer, the C heap memory + * will be used and thus the application will continue to run if + * the counters added exceeds the buffer size but the counters + * will be missing. + * + * See HotSpot jvmstat implementation for certain circumstances + * that the jvmstat perf buffer is not supported. + * + */ +public class PerfCounter { + private static final Perf perf = + AccessController.doPrivileged(new Perf.GetPerfAction()); + + // Must match values defined in hotspot/src/share/vm/runtime/perfdata.hpp + private static final int V_Constant = 1; + private static final int V_Monotonic = 2; + private static final int V_Variable = 3; + private static final int U_None = 1; + + private final String name; + private final LongBuffer lb; + + private PerfCounter(String name, int type) { + this.name = name; + ByteBuffer bb = perf.createLong(name, type, U_None, 0L); + bb.order(ByteOrder.nativeOrder()); + this.lb = bb.asLongBuffer(); + } + + static PerfCounter newPerfCounter(String name) { + return new PerfCounter(name, V_Variable); + } + + static PerfCounter newConstantPerfCounter(String name) { + PerfCounter c = new PerfCounter(name, V_Constant); + return c; + } + + /** + * Returns the current value of the perf counter. + */ + public synchronized long get() { + return lb.get(0); + } + + /** + * Sets the value of the perf counter to the given newValue. + */ + public synchronized void set(long newValue) { + lb.put(0, newValue); + } + + /** + * Adds the given value to the perf counter. + */ + public synchronized void add(long value) { + long res = get() + value; + lb.put(0, res); + } + + /** + * Increments the perf counter with 1. + */ + public void increment() { + add(1); + } + + /** + * Adds the given interval to the perf counter. + */ + public void addTime(long interval) { + add(interval); + } + + /** + * Adds the elapsed time from the given start time (ns) to the perf counter. + */ + public void addElapsedTimeFrom(long startTime) { + add(System.nanoTime() - startTime); + } + + @Override + public String toString() { + return name + " = " + get(); + } + + static class CoreCounters { + static final PerfCounter pdt = newPerfCounter("sun.classloader.parentDelegationTime"); + static final PerfCounter lc = newPerfCounter("sun.classloader.findClasses"); + static final PerfCounter lct = newPerfCounter("sun.classloader.findClassTime"); + static final PerfCounter rcbt = newPerfCounter("sun.urlClassLoader.readClassBytesTime"); + static final PerfCounter zfc = newPerfCounter("sun.zip.zipFiles"); + static final PerfCounter zfot = newPerfCounter("sun.zip.zipFile.openTime"); + } + + static class WindowsClientCounters { + static final PerfCounter d3dAvailable = newConstantPerfCounter("sun.java2d.d3d.available"); + } + + /** + * Number of findClass calls + */ + public static PerfCounter getFindClasses() { + return CoreCounters.lc; + } + + /** + * Time (ns) spent in finding classes that includes + * lookup and read class bytes and defineClass + */ + public static PerfCounter getFindClassTime() { + return CoreCounters.lct; + } + + /** + * Time (ns) spent in finding classes + */ + public static PerfCounter getReadClassBytesTime() { + return CoreCounters.rcbt; + } + + /** + * Time (ns) spent in the parent delegation to + * the parent of the defining class loader + */ + public static PerfCounter getParentDelegationTime() { + return CoreCounters.pdt; + } + + /** + * Number of zip files opened. + */ + public static PerfCounter getZipFileCount() { + return CoreCounters.zfc; + } + + /** + * Time (ns) spent in opening the zip files that + * includes building the entries hash table + */ + public static PerfCounter getZipFileOpenTime() { + return CoreCounters.zfot; + } + + /** + * D3D graphic pipeline available + */ + public static PerfCounter getD3DAvailable() { + return WindowsClientCounters.d3dAvailable; + } +} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/jdk/internal/ref/CleanerFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/ref/CleanerFactory.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,48 @@ +/* + * 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. 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 jdk.internal.ref; + +import java.lang.ref.Cleaner; + +/** + * CleanerFactory provides a Cleaner for use within OpenJDK modules. + * The cleaner is created on the first reference to the CleanerFactory. + */ +public final class CleanerFactory { + + /* The common Cleaner. */ + private final static Cleaner commonCleaner = Cleaner.create(); + + /** + * Cleaner for use within OpenJDK modules. + * + * @return a Cleaner for use within OpenJDK modules + */ + public static Cleaner cleaner() { + return commonCleaner; + } + +} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,333 @@ +/* + * 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. 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 jdk.internal.ref; + +import java.lang.ref.Cleaner; +import java.lang.ref.Cleaner.Cleanable; +import java.lang.ref.ReferenceQueue; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.concurrent.ThreadFactory; +import java.util.function.Function; + +import sun.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 { + + /** + * An object to access the CleanerImpl from a Cleaner; set by Cleaner init. + */ + private static Function cleanerImplAccess = null; + + /** + * Heads of a CleanableList for each reference type. + */ + final PhantomCleanable phantomCleanableList; + + final WeakCleanable weakCleanableList; + + final SoftCleanable softCleanableList; + + // The ReferenceQueue of pending cleaning actions + final ReferenceQueue queue; + + /** + * Called by Cleaner static initialization to provide the function + * to map from Cleaner to CleanerImpl. + * @param access a function to map from Cleaner to CleanerImpl + */ + public static void setCleanerImplAccess(Function access) { + if (cleanerImplAccess == null) { + cleanerImplAccess = access; + } else { + throw new InternalError("cleanerImplAccess"); + } + } + + /** + * Called to get the CleanerImpl for a Cleaner. + * @param cleaner the cleaner + * @return the corresponding CleanerImpl + */ + static CleanerImpl getCleanerImpl(Cleaner cleaner) { + return cleanerImplAccess.apply(cleaner); + } + + /** + * Constructor for CleanerImpl. + */ + public CleanerImpl() { + queue = new ReferenceQueue<>(); + phantomCleanableList = new PhantomCleanableRef(); + weakCleanableList = new WeakCleanableRef(); + softCleanableList = new SoftCleanableRef(); + } + + /** + * Starts the Cleaner implementation. + * Ensure this is the CleanerImpl for the Cleaner. + * When started waits for Cleanables to be queued. + * @param cleaner the cleaner + * @param threadFactory the thread factory + */ + public void start(Cleaner cleaner, ThreadFactory threadFactory) { + if (getCleanerImpl(cleaner) != this) { + throw new AssertionError("wrong cleaner"); + } + // 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, () -> {}); + + if (threadFactory == null) { + threadFactory = CleanerImpl.InnocuousThreadFactory.factory(); + } + + // 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.setDaemon(true); + thread.start(); + } + + /** + * Process queued Cleanables as long as the cleanable lists are not empty. + * A Cleanable is in one of the lists for each Object and for the Cleaner + * itself. + * Terminates when the Cleaner is no longer reachable and + * has been cleaned and there are no more Cleanable instances + * for which the object is reachable. + *

+ * If the thread is a ManagedLocalsThread, the threadlocals + * are erased before each cleanup + */ + private void run() { + Thread t = Thread.currentThread(); + InnocuousThread mlThread = (t instanceof InnocuousThread) + ? (InnocuousThread) t + : null; + while (!phantomCleanableList.isListEmpty() || + !weakCleanableList.isListEmpty() || + !softCleanableList.isListEmpty()) { + if (mlThread != null) { + // Clear the thread locals + mlThread.eraseThreadLocals(); + } + try { + // Wait for a Ref, with a timeout to avoid getting hung + // due to a race with clear/clean + Cleanable ref = (Cleanable) queue.remove(60 * 1000L); + if (ref != null) { + ref.clean(); + } + } catch (InterruptedException i) { + continue; // ignore the interruption + } catch (Throwable e) { + // ignore exceptions from the cleanup action + } + } + } + + /** + * Perform cleaning on an unreachable PhantomReference. + */ + public static final class PhantomCleanableRef extends PhantomCleanable { + private final Runnable action; + + /** + * Constructor for a phantom cleanable reference. + * @param obj the object to monitor + * @param cleaner the cleaner + * @param action the action Runnable + */ + public PhantomCleanableRef(Object obj, Cleaner cleaner, Runnable action) { + super(obj, cleaner); + this.action = action; + } + + /** + * Constructor used only for root of phantom cleanable list. + */ + PhantomCleanableRef() { + super(); + this.action = null; + } + + @Override + protected void performCleanup() { + action.run(); + } + + /** + * Prevent access to referent even when it is still alive. + * + * @throws UnsupportedOperationException always + */ + @Override + public Object get() { + throw new UnsupportedOperationException("get"); + } + + /** + * Direct clearing of the referent is not supported. + * + * @throws UnsupportedOperationException always + */ + @Override + public void clear() { + throw new UnsupportedOperationException("clear"); + } + } + + /** + * Perform cleaning on an unreachable WeakReference. + */ + public static final class WeakCleanableRef extends WeakCleanable { + private final Runnable action; + + /** + * Constructor for a weak cleanable reference. + * @param obj the object to monitor + * @param cleaner the cleaner + * @param action the action Runnable + */ + WeakCleanableRef(Object obj, Cleaner cleaner, Runnable action) { + super(obj, cleaner); + this.action = action; + } + + /** + * Constructor used only for root of weak cleanable list. + */ + WeakCleanableRef() { + super(); + this.action = null; + } + + @Override + protected void performCleanup() { + action.run(); + } + + /** + * Prevent access to referent even when it is still alive. + * + * @throws UnsupportedOperationException always + */ + @Override + public Object get() { + throw new UnsupportedOperationException("get"); + } + + /** + * Direct clearing of the referent is not supported. + * + * @throws UnsupportedOperationException always + */ + @Override + public void clear() { + throw new UnsupportedOperationException("clear"); + } + } + + /** + * Perform cleaning on an unreachable SoftReference. + */ + public static final class SoftCleanableRef extends SoftCleanable { + private final Runnable action; + + /** + * Constructor for a soft cleanable reference. + * @param obj the object to monitor + * @param cleaner the cleaner + * @param action the action Runnable + */ + SoftCleanableRef(Object obj, Cleaner cleaner, Runnable action) { + super(obj, cleaner); + this.action = action; + } + + /** + * Constructor used only for root of soft cleanable list. + */ + SoftCleanableRef() { + super(); + this.action = null; + } + + @Override + protected void performCleanup() { + action.run(); + } + + /** + * Prevent access to referent even when it is still alive. + * + * @throws UnsupportedOperationException always + */ + @Override + public Object get() { + throw new UnsupportedOperationException("get"); + } + + /** + * Direct clearing of the referent is not supported. + * + * @throws UnsupportedOperationException always + */ + @Override + public void clear() { + throw new UnsupportedOperationException("clear"); + } + + } + + /** + * A ThreadFactory for InnocuousThreads. + * The factory is a singleton. + */ + static final class InnocuousThreadFactory implements ThreadFactory { + final static ThreadFactory factory = new InnocuousThreadFactory(); + + static ThreadFactory factory() { + return factory; + } + + 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; + }); + } + } + +} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/jdk/internal/ref/PhantomCleanable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/ref/PhantomCleanable.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,178 @@ +/* + * 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. 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 jdk.internal.ref; + +import java.lang.ref.Cleaner; +import java.lang.ref.PhantomReference; +import java.util.Objects; + +/** + * PhantomCleanable subclasses efficiently encapsulate cleanup state and + * the cleaning action. + * Subclasses implement the abstract {@link #performCleanup()} method + * to provide the cleaning action. + * When constructed, the object reference and the {@link Cleaner.Cleanable Cleanable} + * are registered with the {@link Cleaner}. + * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the + * referent becomes phantom reachable. + */ +public abstract class PhantomCleanable extends PhantomReference + implements Cleaner.Cleanable { + + /** + * Links to previous and next in a doubly-linked list. + */ + PhantomCleanable prev = this, next = this; + + /** + * The list of PhantomCleanable; synchronizes insert and remove. + */ + private final PhantomCleanable list; + + /** + * Constructs new {@code PhantomCleanable} with + * {@code non-null referent} and {@code non-null cleaner}. + * The {@code cleaner} is not retained; it is only used to + * register the newly constructed {@link Cleaner.Cleanable Cleanable}. + * + * @param referent the referent to track + * @param cleaner the {@code Cleaner} to register with + */ + public PhantomCleanable(T referent, Cleaner cleaner) { + super(Objects.requireNonNull(referent), CleanerImpl.getCleanerImpl(cleaner).queue); + this.list = CleanerImpl.getCleanerImpl(cleaner).phantomCleanableList; + insert(); + + // TODO: Replace getClass() with ReachabilityFence when it is available + cleaner.getClass(); + referent.getClass(); + } + + /** + * Construct a new root of the list; not inserted. + */ + PhantomCleanable() { + super(null, null); + this.list = this; + } + + /** + * Insert this PhantomCleanable after the list head. + */ + private void insert() { + synchronized (list) { + prev = list; + next = list.next; + next.prev = this; + list.next = this; + } + } + + /** + * Remove this PhantomCleanable from the list. + * + * @return true if Cleanable was removed or false if not because + * it had already been removed before + */ + private boolean remove() { + synchronized (list) { + if (next != this) { + next.prev = prev; + prev.next = next; + prev = this; + next = this; + return true; + } + return false; + } + } + + /** + * Returns true if the list's next reference refers to itself. + * + * @return true if the list is empty + */ + boolean isListEmpty() { + synchronized (list) { + return list == list.next; + } + } + + /** + * Unregister this PhantomCleanable and invoke {@link #performCleanup()}, + * ensuring at-most-once semantics. + */ + @Override + public final void clean() { + if (remove()) { + super.clear(); + performCleanup(); + } + } + + /** + * Unregister this PhantomCleanable and clear the reference. + * Due to inherent concurrency, {@link #performCleanup()} may still be invoked. + */ + @Override + public void clear() { + if (remove()) { + super.clear(); + } + } + + /** + * The {@code performCleanup} abstract method is overridden + * to implement the cleaning logic. + * The {@code performCleanup} method should not be called except + * by the {@link #clean} method which ensures at most once semantics. + */ + protected abstract void performCleanup(); + + /** + * This method always throws {@link UnsupportedOperationException}. + * Enqueuing details of {@link Cleaner.Cleanable} + * are a private implementation detail. + * + * @throws UnsupportedOperationException always + */ + @Override + public final boolean isEnqueued() { + throw new UnsupportedOperationException("isEnqueued"); + } + + /** + * This method always throws {@link UnsupportedOperationException}. + * Enqueuing details of {@link Cleaner.Cleanable} + * are a private implementation detail. + * + * @throws UnsupportedOperationException always + */ + @Override + public final boolean enqueue() { + throw new UnsupportedOperationException("enqueue"); + } +} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/jdk/internal/ref/SoftCleanable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/ref/SoftCleanable.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,178 @@ +/* + * 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. 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 jdk.internal.ref; + +import java.lang.ref.Cleaner; +import java.lang.ref.SoftReference; +import java.util.Objects; + +/** + * SoftCleanable subclasses efficiently encapsulate cleanup state and + * the cleaning action. + * Subclasses implement the abstract {@link #performCleanup()} method + * to provide the cleaning action. + * When constructed, the object reference and the {@link Cleaner.Cleanable Cleanable} + * are registered with the {@link Cleaner}. + * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the + * referent becomes softly reachable. + */ +public abstract class SoftCleanable extends SoftReference + implements Cleaner.Cleanable { + + /** + * Links to previous and next in a doubly-linked list. + */ + SoftCleanable prev = this, next = this; + + /** + * The list of SoftCleanable; synchronizes insert and remove. + */ + private final SoftCleanable list; + + /** + * Constructs new {@code SoftCleanableReference} with + * {@code non-null referent} and {@code non-null cleaner}. + * The {@code cleaner} is not retained by this reference; it is only used + * to register the newly constructed {@link Cleaner.Cleanable Cleanable}. + * + * @param referent the referent to track + * @param cleaner the {@code Cleaner} to register with + */ + public SoftCleanable(T referent, Cleaner cleaner) { + super(Objects.requireNonNull(referent), CleanerImpl.getCleanerImpl(cleaner).queue); + list = CleanerImpl.getCleanerImpl(cleaner).softCleanableList; + insert(); + + // TODO: Replace getClass() with ReachabilityFence when it is available + cleaner.getClass(); + referent.getClass(); + } + + /** + * Construct a new root of the list; not inserted. + */ + SoftCleanable() { + super(null, null); + this.list = this; + } + + /** + * Insert this SoftCleanableReference after the list head. + */ + private void insert() { + synchronized (list) { + prev = list; + next = list.next; + next.prev = this; + list.next = this; + } + } + + /** + * Remove this SoftCleanableReference from the list. + * + * @return true if Cleanable was removed or false if not because + * it had already been removed before + */ + private boolean remove() { + synchronized (list) { + if (next != this) { + next.prev = prev; + prev.next = next; + prev = this; + next = this; + return true; + } + return false; + } + } + + /** + * Returns true if the list's next reference refers to itself. + * + * @return true if the list is empty + */ + boolean isListEmpty() { + synchronized (list) { + return list == list.next; + } + } + + /** + * Unregister this SoftCleanable reference and invoke {@link #performCleanup()}, + * ensuring at-most-once semantics. + */ + @Override + public final void clean() { + if (remove()) { + super.clear(); + performCleanup(); + } + } + + /** + * Unregister this SoftCleanable and clear the reference. + * Due to inherent concurrency, {@link #performCleanup()} may still be invoked. + */ + @Override + public void clear() { + if (remove()) { + super.clear(); + } + } + + /** + * The {@code performCleanup} abstract method is overridden + * to implement the cleaning logic. + * The {@code performCleanup} method should not be called except + * by the {@link #clean} method which ensures at most once semantics. + */ + protected abstract void performCleanup(); + + /** + * This method always throws {@link UnsupportedOperationException}. + * Enqueuing details of {@link Cleaner.Cleanable} + * are a private implementation detail. + * + * @throws UnsupportedOperationException always + */ + @Override + public final boolean isEnqueued() { + throw new UnsupportedOperationException("isEnqueued"); + } + + /** + * This method always throws {@link UnsupportedOperationException}. + * Enqueuing details of {@link Cleaner.Cleanable} + * are a private implementation detail. + * + * @throws UnsupportedOperationException always + */ + @Override + public final boolean enqueue() { + throw new UnsupportedOperationException("enqueue"); + } +} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/jdk/internal/ref/WeakCleanable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/ref/WeakCleanable.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,178 @@ +package jdk.internal.ref; + +/* + * 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. 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. + */ + +import java.lang.ref.Cleaner; +import java.lang.ref.WeakReference; +import java.util.Objects; + +/** + * WeakCleanable subclasses efficiently encapsulate cleanup state and + * the cleaning action. + * Subclasses implement the abstract {@link #performCleanup()} method + * to provide the cleaning action. + * When constructed, the object reference and the {@link Cleaner.Cleanable Cleanable} + * are registered with the {@link Cleaner}. + * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the + * referent becomes weakly reachable. + */ +public abstract class WeakCleanable extends WeakReference + implements Cleaner.Cleanable { + + /** + * Links to previous and next in a doubly-linked list. + */ + WeakCleanable prev = this, next = this; + + /** + * The list of WeakCleanable; synchronizes insert and remove. + */ + private final WeakCleanable list; + + /** + * Constructs new {@code WeakCleanableReference} with + * {@code non-null referent} and {@code non-null cleaner}. + * The {@code cleaner} is not retained by this reference; it is only used + * to register the newly constructed {@link Cleaner.Cleanable Cleanable}. + * + * @param referent the referent to track + * @param cleaner the {@code Cleaner} to register new reference with + */ + public WeakCleanable(T referent, Cleaner cleaner) { + super(Objects.requireNonNull(referent), CleanerImpl.getCleanerImpl(cleaner).queue); + list = CleanerImpl.getCleanerImpl(cleaner).weakCleanableList; + insert(); + + // TODO: Replace getClass() with ReachabilityFence when it is available + cleaner.getClass(); + referent.getClass(); + } + + /** + * Construct a new root of the list; not inserted. + */ + WeakCleanable() { + super(null, null); + this.list = this; + } + + /** + * Insert this WeakCleanableReference after the list head. + */ + private void insert() { + synchronized (list) { + prev = list; + next = list.next; + next.prev = this; + list.next = this; + } + } + + /** + * Remove this WeakCleanableReference from the list. + * + * @return true if Cleanable was removed or false if not because + * it had already been removed before + */ + private boolean remove() { + synchronized (list) { + if (next != this) { + next.prev = prev; + prev.next = next; + prev = this; + next = this; + return true; + } + return false; + } + } + + /** + * Returns true if the list's next reference refers to itself. + * + * @return true if the list is empty + */ + boolean isListEmpty() { + synchronized (list) { + return list == list.next; + } + } + + /** + * Unregister this WeakCleanable reference and invoke {@link #performCleanup()}, + * ensuring at-most-once semantics. + */ + @Override + public final void clean() { + if (remove()) { + super.clear(); + performCleanup(); + } + } + + /** + * Unregister this WeakCleanable and clear the reference. + * Due to inherent concurrency, {@link #performCleanup()} may still be invoked. + */ + @Override + public void clear() { + if (remove()) { + super.clear(); + } + } + + /** + * The {@code performCleanup} abstract method is overridden + * to implement the cleaning logic. + * The {@code performCleanup} method should not be called except + * by the {@link #clean} method which ensures at most once semantics. + */ + protected abstract void performCleanup(); + + /** + * This method always throws {@link UnsupportedOperationException}. + * Enqueuing details of {@link Cleaner.Cleanable} + * are a private implementation detail. + * + * @throws UnsupportedOperationException always + */ + @Override + public final boolean isEnqueued() { + throw new UnsupportedOperationException("isEnqueued"); + } + + /** + * This method always throws {@link UnsupportedOperationException}. + * Enqueuing details of {@link Cleaner.Cleanable} + * are a private implementation detail. + * + * @throws UnsupportedOperationException always + */ + @Override + public final boolean enqueue() { + throw new UnsupportedOperationException("enqueue"); + } +} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/sun/misc/CEFormatException.java --- a/jdk/src/java.base/share/classes/sun/misc/CEFormatException.java Thu Jan 14 08:08:19 2016 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.misc; - -import java.io.IOException; - -public class CEFormatException extends IOException { - static final long serialVersionUID = -7139121221067081482L; - public CEFormatException(String s) { - super(s); - } -} - diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/sun/misc/CEStreamExhausted.java --- a/jdk/src/java.base/share/classes/sun/misc/CEStreamExhausted.java Thu Jan 14 08:08:19 2016 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package sun.misc; - -import java.io.IOException; - -/** This exception is thrown when EOF is reached */ -public class CEStreamExhausted extends IOException { - static final long serialVersionUID = -5889118049525891904L; -} - diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/sun/misc/JarFilter.java --- a/jdk/src/java.base/share/classes/sun/misc/JarFilter.java Thu Jan 14 08:08:19 2016 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.misc; - -import java.io.File; -import java.io.FilenameFilter; - -/** - * This class checks that only jar and zip files are included in the file list. - * This class is used in extension installation support (ExtensionDependency). - * - * @deprecated this class will be removed in a future release. - * @author Michael Colburn - */ -@Deprecated -public class JarFilter implements FilenameFilter { - - public boolean accept(File dir, String name) { - String lower = name.toLowerCase(); - return lower.endsWith(".jar") || lower.endsWith(".zip"); - } -} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/sun/misc/Perf.java --- a/jdk/src/java.base/share/classes/sun/misc/Perf.java Thu Jan 14 08:08:19 2016 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,538 +0,0 @@ -/* - * Copyright (c) 2002, 2006, 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.nio.ByteBuffer; -import java.security.Permission; -import java.security.PrivilegedAction; -import java.io.IOException; -import java.io.UnsupportedEncodingException; - -/** - * The Perf class provides the ability to attach to an instrumentation - * buffer maintained by a Java virtual machine. The instrumentation - * buffer may be for the Java virtual machine running the methods of - * this class or it may be for another Java virtual machine on the - * same system. - *

- * In addition, this class provides methods to create instrumentation - * objects in the instrumentation buffer for the Java virtual machine - * that is running these methods. It also contains methods for acquiring - * the value of a platform specific high resolution clock for time - * stamp and interval measurement purposes. - * - * @author Brian Doherty - * @since 1.4.2 - * @see #getPerf - * @see sun.misc.Perf$GetPerfAction - * @see java.nio.ByteBuffer - */ -public final class Perf { - - private static Perf instance; - - private static final int PERF_MODE_RO = 0; - private static final int PERF_MODE_RW = 1; - - private Perf() { } // prevent instantiation - - /** - * The GetPerfAction class is a convenience class for acquiring access - * to the singleton Perf instance using the - * AccessController.doPrivileged() method. - *

- * An instance of this class can be used as the argument to - * AccessController.doPrivileged(PrivilegedAction). - *

Here is a suggested idiom for use of this class: - * - *

{@code
-     * class MyTrustedClass {
-     *   private static final Perf perf =
-     *       AccessController.doPrivileged(new Perf.GetPerfAction());
-     *   ...
-     * }
-     * }
- *

- * In the presence of a security manager, the MyTrustedClass - * class in the above example will need to be granted the - * "sun.misc.Perf.getPerf" RuntimePermission - * permission in order to successfully acquire the singleton Perf instance. - *

- * Please note that the "sun.misc.Perf.getPerf" permission - * is not a JDK specified permission. - * - * @see java.security.AccessController#doPrivileged(PrivilegedAction) - * @see java.lang.RuntimePermission - */ - public static class GetPerfAction implements PrivilegedAction - { - /** - * Run the Perf.getPerf() method in a privileged context. - * - * @see #getPerf - */ - public Perf run() { - return getPerf(); - } - } - - /** - * Return a reference to the singleton Perf instance. - *

- * The getPerf() method returns the singleton instance of the Perf - * class. The returned object provides the caller with the capability - * for accessing the instrumentation buffer for this or another local - * Java virtual machine. - *

- * If a security manager is installed, its checkPermission - * method is called with a RuntimePermission with a target - * of "sun.misc.Perf.getPerf". A security exception will result - * if the caller has not been granted this permission. - *

- * Access to the returned Perf object should be protected - * by its caller and not passed on to untrusted code. This object can - * be used to attach to the instrumentation buffer provided by this Java - * virtual machine or for those of other Java virtual machines running - * on the same system. The instrumentation buffer may contain senstitive - * information. API's built on top of this interface may want to provide - * finer grained access control to the contents of individual - * instrumentation objects contained within the buffer. - *

- * Please note that the "sun.misc.Perf.getPerf" permission - * is not a JDK specified permission. - * - * @return A reference to the singleton Perf instance. - * @throws AccessControlException if a security manager exists and - * its checkPermission method doesn't allow - * access to the "sun.misc.Perf.getPerf" target. - * @see java.lang.RuntimePermission - * @see #attach - */ - public static Perf getPerf() - { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - Permission perm = new RuntimePermission("sun.misc.Perf.getPerf"); - security.checkPermission(perm); - } - - return instance; - } - - /** - * Attach to the instrumentation buffer for the specified Java virtual - * machine. - *

- * This method will attach to the instrumentation buffer for the - * specified virtual machine. It returns a ByteBuffer object - * that is initialized to access the instrumentation buffer for the - * indicated Java virtual machine. The lvmid parameter is - * a integer value that uniquely identifies the target local Java virtual - * machine. It is typically, but not necessarily, the process id of - * the target Java virtual machine. - *

- * If the lvmid identifies a Java virtual machine different - * from the one running this method, then the coherency characteristics - * of the buffer are implementation dependent. Implementations that do - * not support named, coherent, shared memory may return a - * ByteBuffer object that contains only a snap shot of the - * data in the instrumentation buffer. Implementations that support named, - * coherent, shared memory, may return a ByteBuffer object - * that will be changing dynamically over time as the target Java virtual - * machine updates its mapping of this buffer. - *

- * If the lvmid is 0 or equal to the actual lvmid - * for the Java virtual machine running this method, then the returned - * ByteBuffer object will always be coherent and dynamically - * changing. - *

- * The attach mode specifies the access permissions requested for the - * instrumentation buffer of the target virtual machine. The permitted - * access permissions are: - *

    - *
  • "r" - Read only access. This Java virtual machine has only - * read access to the instrumentation buffer for the target Java - * virtual machine. - *
  • "rw" - Read/Write access. This Java virtual machine has read and - * write access to the instrumentation buffer for the target Java virtual - * machine. This mode is currently not supported and is reserved for - * future enhancements. - *
- * - * @param lvmid an integer that uniquely identifies the - * target local Java virtual machine. - * @param mode a string indicating the attach mode. - * @return ByteBuffer a direct allocated byte buffer - * @throws IllegalArgumentException The lvmid or mode was invalid. - * @throws IOException An I/O error occurred while trying to acquire - * the instrumentation buffer. - * @throws OutOfMemoryError The instrumentation buffer could not be mapped - * into the virtual machine's address space. - * @see java.nio.ByteBuffer - */ - public ByteBuffer attach(int lvmid, String mode) - throws IllegalArgumentException, IOException - { - if (mode.compareTo("r") == 0) { - return attachImpl(null, lvmid, PERF_MODE_RO); - } - else if (mode.compareTo("rw") == 0) { - return attachImpl(null, lvmid, PERF_MODE_RW); - } - else { - throw new IllegalArgumentException("unknown mode"); - } - } - - /** - * Attach to the instrumentation buffer for the specified Java virtual - * machine owned by the given user. - *

- * This method behaves just as the attach(int lvmid, String mode) - * method, except that it only searches for Java virtual machines - * owned by the specified user. - * - * @param user A String object containing the - * name of the user that owns the target Java - * virtual machine. - * @param lvmid an integer that uniquely identifies the - * target local Java virtual machine. - * @param mode a string indicating the attach mode. - * @return ByteBuffer a direct allocated byte buffer - * @throws IllegalArgumentException The lvmid or mode was invalid. - * @throws IOException An I/O error occurred while trying to acquire - * the instrumentation buffer. - * @throws OutOfMemoryError The instrumentation buffer could not be mapped - * into the virtual machine's address space. - * @see java.nio.ByteBuffer - */ - public ByteBuffer attach(String user, int lvmid, String mode) - throws IllegalArgumentException, IOException - { - if (mode.compareTo("r") == 0) { - return attachImpl(user, lvmid, PERF_MODE_RO); - } - else if (mode.compareTo("rw") == 0) { - return attachImpl(user, lvmid, PERF_MODE_RW); - } - else { - throw new IllegalArgumentException("unknown mode"); - } - } - - /** - * Call the implementation specific attach method. - *

- * This method calls into the Java virtual machine to perform the platform - * specific attach method. Buffers returned from this method are - * internally managed as PhantomRefereces to provide for - * guaranteed, secure release of the native resources. - * - * @param user A String object containing the - * name of the user that owns the target Java - * virtual machine. - * @param lvmid an integer that uniquely identifies the - * target local Java virtual machine. - * @param mode a string indicating the attach mode. - * @return ByteBuffer a direct allocated byte buffer - * @throws IllegalArgumentException The lvmid or mode was invalid. - * @throws IOException An I/O error occurred while trying to acquire - * the instrumentation buffer. - * @throws OutOfMemoryError The instrumentation buffer could not be mapped - * into the virtual machine's address space. - */ - private ByteBuffer attachImpl(String user, int lvmid, int mode) - throws IllegalArgumentException, IOException - { - final ByteBuffer b = attach(user, lvmid, mode); - - if (lvmid == 0) { - // The native instrumentation buffer for this Java virtual - // machine is never unmapped. - return b; - } - else { - // This is an instrumentation buffer for another Java virtual - // machine with native resources that need to be managed. We - // create a duplicate of the native ByteBuffer and manage it - // with a Cleaner object (PhantomReference). When the duplicate - // becomes only phantomly reachable, the native resources will - // be released. - - final ByteBuffer dup = b.duplicate(); - Cleaner.create(dup, new Runnable() { - public void run() { - try { - instance.detach(b); - } - catch (Throwable th) { - // avoid crashing the reference handler thread, - // but provide for some diagnosability - assert false : th.toString(); - } - } - }); - return dup; - } - } - - /** - * Native method to perform the implementation specific attach mechanism. - *

- * The implementation of this method may return distinct or identical - * ByteBuffer objects for two distinct calls requesting - * attachment to the same Java virtual machine. - *

- * For the Sun HotSpot JVM, two distinct calls to attach to the same - * target Java virtual machine will result in two distinct ByteBuffer - * objects returned by this method. This may change in a future release. - * - * @param user A String object containing the - * name of the user that owns the target Java - * virtual machine. - * @param lvmid an integer that uniquely identifies the - * target local Java virtual machine. - * @param mode a string indicating the attach mode. - * @return ByteBuffer a direct allocated byte buffer - * @throws IllegalArgumentException The lvmid or mode was invalid. - * @throws IOException An I/O error occurred while trying to acquire - * the instrumentation buffer. - * @throws OutOfMemoryError The instrumentation buffer could not be mapped - * into the virtual machine's address space. - */ - private native ByteBuffer attach(String user, int lvmid, int mode) - throws IllegalArgumentException, IOException; - - /** - * Native method to perform the implementation specific detach mechanism. - *

- * If this method is passed a ByteBuffer object that is - * not created by the attach method, then the results of - * this method are undefined, with unpredictable and potentially damaging - * effects to the Java virtual machine. To prevent accidental or malicious - * use of this method, all native ByteBuffer created by the - * attach method are managed internally as PhantomReferences - * and resources are freed by the system. - *

- * If this method is passed a ByteBuffer object created - * by the attach method with a lvmid for the Java virtual - * machine running this method (lvmid=0, for example), then the detach - * request is silently ignored. - * - * @param ByteBuffer A direct allocated byte buffer created by the - * attach method. - * @see java.nio.ByteBuffer - * @see #attach - */ - private native void detach(ByteBuffer bb); - - /** - * Create a long scalar entry in the instrumentation buffer - * with the given variability characteristic, units, and initial value. - *

- * Access to the instrument is provided through the returned - * ByteBuffer object. Typically, this object should be wrapped - * with LongBuffer view object. - * - * @param variability the variability characteristic for this entry. - * @param units the units for this entry. - * @param name the name of this entry. - * @param value the initial value for this entry. - * @return ByteBuffer a direct allocated ByteBuffer object that - * allows write access to a native memory location - * containing a long value. - * - * see sun.misc.perf.Variability - * see sun.misc.perf.Units - * @see java.nio.ByteBuffer - */ - public native ByteBuffer createLong(String name, int variability, - int units, long value); - - /** - * Create a String entry in the instrumentation buffer with - * the given variability characteristic, units, and initial value. - *

- * The maximum length of the String stored in this string - * instrument is given in by maxLength parameter. Updates - * to this instrument with String values with lengths greater - * than maxLength will be truncated to maxLength. - * The truncated value will be terminated by a null character. - *

- * The underlying implementation may further limit the length of the - * value, but will continue to preserve the null terminator. - *

- * Access to the instrument is provided through the returned - * ByteBuffer object. - * - * @param variability the variability characteristic for this entry. - * @param units the units for this entry. - * @param name the name of this entry. - * @param value the initial value for this entry. - * @param maxLength the maximum string length for this string - * instrument. - * @return ByteBuffer a direct allocated ByteBuffer that allows - * write access to a native memory location - * containing a long value. - * - * see sun.misc.perf.Variability - * see sun.misc.perf.Units - * @see java.nio.ByteBuffer - */ - public ByteBuffer createString(String name, int variability, - int units, String value, int maxLength) - { - byte[] v = getBytes(value); - byte[] v1 = new byte[v.length+1]; - System.arraycopy(v, 0, v1, 0, v.length); - v1[v.length] = '\0'; - return createByteArray(name, variability, units, v1, Math.max(v1.length, maxLength)); - } - - /** - * Create a String entry in the instrumentation buffer with - * the given variability characteristic, units, and initial value. - *

- * The maximum length of the String stored in this string - * instrument is implied by the length of the value parameter. - * Subsequent updates to the value of this instrument will be truncated - * to this implied maximum length. The truncated value will be terminated - * by a null character. - *

- * The underlying implementation may further limit the length of the - * initial or subsequent value, but will continue to preserve the null - * terminator. - *

- * Access to the instrument is provided through the returned - * ByteBuffer object. - * - * @param variability the variability characteristic for this entry. - * @param units the units for this entry. - * @param name the name of this entry. - * @param value the initial value for this entry. - * @return ByteBuffer a direct allocated ByteBuffer that allows - * write access to a native memory location - * containing a long value. - * - * see sun.misc.perf.Variability - * see sun.misc.perf.Units - * @see java.nio.ByteBuffer - */ - public ByteBuffer createString(String name, int variability, - int units, String value) - { - byte[] v = getBytes(value); - byte[] v1 = new byte[v.length+1]; - System.arraycopy(v, 0, v1, 0, v.length); - v1[v.length] = '\0'; - return createByteArray(name, variability, units, v1, v1.length); - } - - /** - * Create a byte vector entry in the instrumentation buffer - * with the given variability characteristic, units, and initial value. - *

- * The maxLength parameter limits the size of the byte - * array instrument such that the initial or subsequent updates beyond - * this length are silently ignored. No special handling of truncated - * updates is provided. - *

- * The underlying implementation may further limit the length of the - * length of the initial or subsequent value. - *

- * Access to the instrument is provided through the returned - * ByteBuffer object. - * - * @param variability the variability characteristic for this entry. - * @param units the units for this entry. - * @param name the name of this entry. - * @param value the initial value for this entry. - * @param maxLength the maximum length of this byte array. - * @return ByteBuffer a direct allocated byte buffer that allows - * write access to a native memory location - * containing a long value. - * - * see sun.misc.perf.Variability - * see sun.misc.perf.Units - * @see java.nio.ByteBuffer - */ - public native ByteBuffer createByteArray(String name, int variability, - int units, byte[] value, - int maxLength); - - - /** - * convert string to an array of UTF-8 bytes - */ - private static byte[] getBytes(String s) - { - byte[] bytes = null; - - try { - bytes = s.getBytes("UTF-8"); - } - catch (UnsupportedEncodingException e) { - // ignore, UTF-8 encoding is always known - } - - return bytes; - } - - /** - * Return the value of the High Resolution Counter. - * - * The High Resolution Counter returns the number of ticks since - * since the start of the Java virtual machine. The resolution of - * the counter is machine dependent and can be determined from the - * value return by the {@link #highResFrequency} method. - * - * @return the number of ticks of machine dependent resolution since - * the start of the Java virtual machine. - * - * @see #highResFrequency - * @see java.lang.System#currentTimeMillis() - */ - public native long highResCounter(); - - /** - * Returns the frequency of the High Resolution Counter, in ticks per - * second. - * - * This value can be used to convert the value of the High Resolution - * Counter, as returned from a call to the {@link #highResCounter} method, - * into the number of seconds since the start of the Java virtual machine. - * - * @return the frequency of the High Resolution Counter. - * @see #highResCounter - */ - public native long highResFrequency(); - - private static native void registerNatives(); - - static { - registerNatives(); - instance = new Perf(); - } -} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/sun/misc/PerfCounter.java --- a/jdk/src/java.base/share/classes/sun/misc/PerfCounter.java Thu Jan 14 08:08:19 2016 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.misc; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.LongBuffer; -import java.security.AccessController; - -/** - * Performance counter support for internal JRE classes. - * This class defines a fixed list of counters for the platform - * to use as an interim solution until RFE# 6209222 is implemented. - * The perf counters will be created in the jvmstat perf buffer - * that the HotSpot VM creates. The default size is 32K and thus - * the number of counters is bounded. You can alter the size - * with {@code -XX:PerfDataMemorySize=} option. If there is - * insufficient memory in the jvmstat perf buffer, the C heap memory - * will be used and thus the application will continue to run if - * the counters added exceeds the buffer size but the counters - * will be missing. - * - * See HotSpot jvmstat implementation for certain circumstances - * that the jvmstat perf buffer is not supported. - * - */ -public class PerfCounter { - private static final Perf perf = - AccessController.doPrivileged(new Perf.GetPerfAction()); - - // Must match values defined in hotspot/src/share/vm/runtime/perfdata.hpp - private static final int V_Constant = 1; - private static final int V_Monotonic = 2; - private static final int V_Variable = 3; - private static final int U_None = 1; - - private final String name; - private final LongBuffer lb; - - private PerfCounter(String name, int type) { - this.name = name; - ByteBuffer bb = perf.createLong(name, type, U_None, 0L); - bb.order(ByteOrder.nativeOrder()); - this.lb = bb.asLongBuffer(); - } - - static PerfCounter newPerfCounter(String name) { - return new PerfCounter(name, V_Variable); - } - - static PerfCounter newConstantPerfCounter(String name) { - PerfCounter c = new PerfCounter(name, V_Constant); - return c; - } - - /** - * Returns the current value of the perf counter. - */ - public synchronized long get() { - return lb.get(0); - } - - /** - * Sets the value of the perf counter to the given newValue. - */ - public synchronized void set(long newValue) { - lb.put(0, newValue); - } - - /** - * Adds the given value to the perf counter. - */ - public synchronized void add(long value) { - long res = get() + value; - lb.put(0, res); - } - - /** - * Increments the perf counter with 1. - */ - public void increment() { - add(1); - } - - /** - * Adds the given interval to the perf counter. - */ - public void addTime(long interval) { - add(interval); - } - - /** - * Adds the elapsed time from the given start time (ns) to the perf counter. - */ - public void addElapsedTimeFrom(long startTime) { - add(System.nanoTime() - startTime); - } - - @Override - public String toString() { - return name + " = " + get(); - } - - static class CoreCounters { - static final PerfCounter pdt = newPerfCounter("sun.classloader.parentDelegationTime"); - static final PerfCounter lc = newPerfCounter("sun.classloader.findClasses"); - static final PerfCounter lct = newPerfCounter("sun.classloader.findClassTime"); - static final PerfCounter rcbt = newPerfCounter("sun.urlClassLoader.readClassBytesTime"); - static final PerfCounter zfc = newPerfCounter("sun.zip.zipFiles"); - static final PerfCounter zfot = newPerfCounter("sun.zip.zipFile.openTime"); - } - - static class WindowsClientCounters { - static final PerfCounter d3dAvailable = newConstantPerfCounter("sun.java2d.d3d.available"); - } - - /** - * Number of findClass calls - */ - public static PerfCounter getFindClasses() { - return CoreCounters.lc; - } - - /** - * Time (ns) spent in finding classes that includes - * lookup and read class bytes and defineClass - */ - public static PerfCounter getFindClassTime() { - return CoreCounters.lct; - } - - /** - * Time (ns) spent in finding classes - */ - public static PerfCounter getReadClassBytesTime() { - return CoreCounters.rcbt; - } - - /** - * Time (ns) spent in the parent delegation to - * the parent of the defining class loader - */ - public static PerfCounter getParentDelegationTime() { - return CoreCounters.pdt; - } - - /** - * Number of zip files opened. - */ - public static PerfCounter getZipFileCount() { - return CoreCounters.zfc; - } - - /** - * Time (ns) spent in opening the zip files that - * includes building the entries hash table - */ - public static PerfCounter getZipFileOpenTime() { - return CoreCounters.zfot; - } - - /** - * D3D graphic pipeline available - */ - public static PerfCounter getD3DAvailable() { - return WindowsClientCounters.d3dAvailable; - } -} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/sun/misc/PerformanceLogger.java --- a/jdk/src/java.base/share/classes/sun/misc/PerformanceLogger.java Thu Jan 14 08:08:19 2016 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,317 +0,0 @@ -/* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - - -package sun.misc; - -import java.util.Vector; -import java.io.FileWriter; -import java.io.File; -import java.io.OutputStreamWriter; -import java.io.Writer; - -/** - * This class is intended to be a central place for the jdk to - * log timing events of interest. There is pre-defined event - * of startTime, as well as a general - * mechanism of setting arbitrary times in an array. - * All unreserved times in the array can be used by callers - * in application-defined situations. The caller is responsible - * for setting and getting all times and for doing whatever - * analysis is interesting; this class is merely a central container - * for those timing values. - * Note that, due to the variables in this class being static, - * use of particular time values by multiple applets will cause - * confusing results. For example, if plugin runs two applets - * simultaneously, the initTime for those applets will collide - * and the results may be undefined. - *

- * To automatically track startup performance in an app or applet, - * use the command-line parameter sun.perflog as follows:
- *

{@code
- *     -Dsun.perflog[=file:]
- * }
- *
- * where simply using the parameter with no value will enable output - * to the console and a value of "{@code file:}" will cause - * that given filename to be created and used for all output. - *

- * By default, times are measured using System.currentTimeMillis(). To use - * System.nanoTime() instead, add the command-line parameter:
- -Dsun.perflog.nano=true - *
- *

- * Warning: Use at your own risk! - * This class is intended for internal testing - * purposes only and may be removed at any time. More - * permanent monitoring and profiling APIs are expected to be - * developed for future releases and this class will cease to - * exist once those APIs are in place. - * @author Chet Haase - */ -public class PerformanceLogger { - - // Timing values of global interest - private static final int START_INDEX = 0; // VM start - private static final int LAST_RESERVED = START_INDEX; - - private static boolean perfLoggingOn = false; - private static boolean useNanoTime = false; - private static Vector times; - private static String logFileName = null; - private static Writer logWriter = null; - private static long baseTime; - - static { - String perfLoggingProp = - java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.perflog")); - if (perfLoggingProp != null) { - perfLoggingOn = true; - - // Check if we should use nanoTime - String perfNanoProp = - java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.perflog.nano")); - if (perfNanoProp != null) { - useNanoTime = true; - } - - // Now, figure out what the user wants to do with the data - if (perfLoggingProp.regionMatches(true, 0, "file:", 0, 5)) { - logFileName = perfLoggingProp.substring(5); - } - if (logFileName != null) { - if (logWriter == null) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Void run() { - try { - File logFile = new File(logFileName); - logFile.createNewFile(); - logWriter = new FileWriter(logFile); - } catch (Exception e) { - System.out.println(e + ": Creating logfile " + - logFileName + - ". Log to console"); - } - return null; - } - }); - } - } - if (logWriter == null) { - logWriter = new OutputStreamWriter(System.out); - } - } - times = new Vector(10); - // Reserve predefined slots - for (int i = 0; i <= LAST_RESERVED; ++i) { - times.add(new TimeData("Time " + i + " not set", 0)); - } - } - - /** - * Returns status of whether logging is enabled or not. This is - * provided as a convenience method so that users do not have to - * perform the same GetPropertyAction check as above to determine whether - * to enable performance logging. - */ - public static boolean loggingEnabled() { - return perfLoggingOn; - } - - - /** - * Internal class used to store time/message data together. - */ - static class TimeData { - String message; - long time; - - TimeData(String message, long time) { - this.message = message; - this.time = time; - } - - String getMessage() { - return message; - } - - long getTime() { - return time; - } - } - - /** - * Return the current time, in millis or nanos as appropriate - */ - private static long getCurrentTime() { - if (useNanoTime) { - return System.nanoTime(); - } else { - return System.currentTimeMillis(); - } - } - - /** - * Sets the start time. Ideally, this is the earliest time available - * during the startup of a Java applet or application. This time is - * later used to analyze the difference between the initial startup - * time and other events in the system (such as an applet's init time). - */ - public static void setStartTime(String message) { - if (loggingEnabled()) { - long nowTime = getCurrentTime(); - setStartTime(message, nowTime); - } - } - - /** - * Sets the base time, output can then - * be displayed as offsets from the base time;. - */ - public static void setBaseTime(long time) { - if (loggingEnabled()) { - baseTime = time; - } - } - - /** - * Sets the start time. - * This version of the method is - * given the time to log, instead of expecting this method to - * get the time itself. This is done in case the time was - * recorded much earlier than this method was called. - */ - public static void setStartTime(String message, long time) { - if (loggingEnabled()) { - times.set(START_INDEX, new TimeData(message, time)); - } - } - - /** - * Gets the start time, which should be the time when - * the java process started, prior to the VM actually being - * loaded. - */ - public static long getStartTime() { - if (loggingEnabled()) { - return times.get(START_INDEX).getTime(); - } else { - return 0; - } - } - - /** - * Sets the value of a given time and returns the index of the - * slot that that time was stored in. - */ - public static int setTime(String message) { - if (loggingEnabled()) { - long nowTime = getCurrentTime(); - return setTime(message, nowTime); - } else { - return 0; - } - } - - /** - * Sets the value of a given time and returns the index of the - * slot that that time was stored in. - * This version of the method is - * given the time to log, instead of expecting this method to - * get the time itself. This is done in case the time was - * recorded much earlier than this method was called. - */ - public static int setTime(String message, long time) { - if (loggingEnabled()) { - // times is already synchronized, but we need to ensure that - // the size used in times.set() is the same used when returning - // the index of that operation. - synchronized (times) { - times.add(new TimeData(message, time)); - return (times.size() - 1); - } - } else { - return 0; - } - } - - /** - * Returns time at given index. - */ - public static long getTimeAtIndex(int index) { - if (loggingEnabled()) { - return times.get(index).getTime(); - } else { - return 0; - } - } - - /** - * Returns message at given index. - */ - public static String getMessageAtIndex(int index) { - if (loggingEnabled()) { - return times.get(index).getMessage(); - } else { - return null; - } - } - - /** - * Outputs all data to parameter-specified Writer object - */ - public static void outputLog(Writer writer) { - if (loggingEnabled()) { - try { - synchronized(times) { - for (int i = 0; i < times.size(); ++i) { - TimeData td = times.get(i); - if (td != null) { - writer.write(i + " " + td.getMessage() + ": " + - (td.getTime() - baseTime) + "\n"); - - } - } - } - writer.flush(); - } catch (Exception e) { - System.out.println(e + ": Writing performance log to " + - writer); - } - } - } - - /** - * Outputs all data to whatever location the user specified - * via sun.perflog command-line parameter. - */ - public static void outputLog() { - outputLog(logWriter); - } -} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java --- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java Thu Jan 14 12:04:19 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -967,12 +967,6 @@ return ""; } - @Override - protected void finalize() throws Throwable { - // This should do nothing. The stream finalizer will - // close the fd. - } - public void setDoNotRetry(boolean value) { // failedOnce is used to determine if a request should be retried. failedOnce = value; diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java Thu Jan 14 12:04:19 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, 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 @@ -108,13 +108,6 @@ return false; } - /* - * close the jar file. - */ - protected void finalize() throws IOException { - close(); - } - /** * Returns the ZipEntry for the given entry name or * null if not found. diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Thu Jan 14 12:04:19 2016 -0800 @@ -2211,7 +2211,7 @@ @Override public synchronized String getHandshakeApplicationProtocol() { - if ((handshaker != null) && !handshaker.started()) { + if ((handshaker != null) && handshaker.started()) { return handshaker.getHandshakeApplicationProtocol(); } return null; diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Thu Jan 14 12:04:19 2016 -0800 @@ -2598,7 +2598,7 @@ @Override public synchronized String getHandshakeApplicationProtocol() { - if ((handshaker != null) && !handshaker.started()) { + if ((handshaker != null) && handshaker.started()) { return handshaker.getHandshakeApplicationProtocol(); } return null; diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Thu Jan 14 12:04:19 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -153,13 +153,11 @@ getSupportedAlgorithms(AlgorithmConstraints constraints) { Collection supported = new ArrayList<>(); - synchronized (priorityMap) { - for (SignatureAndHashAlgorithm sigAlg : priorityMap.values()) { - if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM && - constraints.permits(SIGNATURE_PRIMITIVE_SET, - sigAlg.algorithm, null)) { - supported.add(sigAlg); - } + for (SignatureAndHashAlgorithm sigAlg : priorityMap.values()) { + if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM && + constraints.permits(SIGNATURE_PRIMITIVE_SET, + sigAlg.algorithm, null)) { + supported.add(sigAlg); } } diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/share/conf/security/java.policy --- a/jdk/src/java.base/share/conf/security/java.policy Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/share/conf/security/java.policy Thu Jan 14 12:04:19 2016 -0800 @@ -98,17 +98,6 @@ // default permissions granted to all domains grant { - // Allows any thread to stop itself using the java.lang.Thread.stop() - // method that takes no argument. - // Note that this permission is granted by default only to remain - // backwards compatible. - // It is strongly recommended that you either remove this permission - // from this policy file or further restrict it to code sources - // that you specify, because Thread.stop() is potentially unsafe. - // See the API specification of java.lang.Thread.stop() for more - // information. - permission java.lang.RuntimePermission "stopThread"; - // allows anyone to listen on dynamic ports permission java.net.SocketPermission "localhost:0", "listen"; diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java --- a/jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java Thu Jan 14 12:04:19 2016 -0800 @@ -42,8 +42,10 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; + import jdk.internal.misc.JavaIOFileDescriptorAccess; import jdk.internal.misc.SharedSecrets; +import jdk.internal.ref.CleanerFactory; /* This class is for the exclusive use of ProcessBuilder.start() to * create new processes. @@ -417,6 +419,10 @@ handle = create(cmdstr, envblock, path, stdHandles, redirectErrorStream); + // Register a cleaning function to close the handle + final long local_handle = handle; // local to prevent capture of this + CleanerFactory.cleaner().register(this, () -> closeHandle(local_handle)); + processHandle = ProcessHandleImpl.getInternal(getProcessId0(handle)); java.security.AccessController.doPrivileged( @@ -463,10 +469,6 @@ return stderr_stream; } - protected void finalize() { - closeHandle(handle); - } - private static final int STILL_ACTIVE = getStillActive(); private static native int getStillActive(); diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/windows/native/libjli/java_md.c --- a/jdk/src/java.base/windows/native/libjli/java_md.c Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/windows/native/libjli/java_md.c Thu Jan 14 12:04:19 2016 -0800 @@ -337,6 +337,15 @@ } } + /* Try getting path to JRE from path to JLI.DLL */ + if (GetApplicationHomeFromDll(path, pathsize)) { + JLI_Snprintf(javadll, sizeof(javadll), "%s\\bin\\" JAVA_DLL, path); + if (stat(javadll, &s) == 0) { + JLI_TraceLauncher("JRE path is %s\n", path); + return JNI_TRUE; + } + } + JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL); return JNI_FALSE; @@ -404,17 +413,17 @@ } /* - * If app is "c:\foo\bin\javac", then put "c:\foo" into buf. + * Removes the trailing file name and one sub-folder from a path. + * If buf is "c:\foo\bin\javac", then put "c:\foo" into buf. */ jboolean -GetApplicationHome(char *buf, jint bufsize) +TruncatePath(char *buf) { char *cp; - GetModuleFileName(0, buf, bufsize); *JLI_StrRChr(buf, '\\') = '\0'; /* remove .exe file name */ if ((cp = JLI_StrRChr(buf, '\\')) == 0) { /* This happens if the application is in a drive root, and - * there is no bin directory. */ + * there is no bin directory. */ buf[0] = '\0'; return JNI_FALSE; } @@ -423,6 +432,36 @@ } /* + * Retrieves the path to the JRE home by locating the executable file + * of the current process and then truncating the path to the executable + */ +jboolean +GetApplicationHome(char *buf, jint bufsize) +{ + GetModuleFileName(NULL, buf, bufsize); + return TruncatePath(buf); +} + +/* + * Retrieves the path to the JRE home by locating JLI.DLL and + * then truncating the path to JLI.DLL + */ +jboolean +GetApplicationHomeFromDll(char *buf, jint bufsize) +{ + HMODULE hModule; + DWORD dwFlags = + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT; + + if (GetModuleHandleEx(dwFlags, (LPCSTR)&GetJREPath, &hModule) == 0) { + return JNI_FALSE; + }; + GetModuleFileName(hModule, buf, bufsize); + return TruncatePath(buf); +} + +/* * Support for doing cheap, accurate interval timing. */ static jboolean counterAvailable = JNI_FALSE; diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.base/windows/native/libjli/java_md.h --- a/jdk/src/java.base/windows/native/libjli/java_md.h Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.base/windows/native/libjli/java_md.h Thu Jan 14 12:04:19 2016 -0800 @@ -54,4 +54,7 @@ int UnsetEnv(char *name); +jboolean +GetApplicationHomeFromDll(char *buf, jint bufsize); + #endif /* JAVA_MD_H */ diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java --- a/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java Thu Jan 14 12:04:19 2016 -0800 @@ -43,8 +43,8 @@ import sun.awt.AppContext; import sun.awt.EmbeddedFrame; import sun.awt.SunToolkit; +import sun.awt.util.PerformanceLogger; import sun.misc.ManagedLocalsThread; -import sun.misc.PerformanceLogger; import sun.security.util.SecurityConstants; /** diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.desktop/share/classes/sun/awt/util/PerformanceLogger.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.desktop/share/classes/sun/awt/util/PerformanceLogger.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + + +package sun.awt.util; + +import java.util.Vector; +import java.io.FileWriter; +import java.io.File; +import java.io.OutputStreamWriter; +import java.io.Writer; + +/** + * This class is intended to be a central place for the jdk to + * log timing events of interest. There is pre-defined event + * of startTime, as well as a general + * mechanism of setting arbitrary times in an array. + * All unreserved times in the array can be used by callers + * in application-defined situations. The caller is responsible + * for setting and getting all times and for doing whatever + * analysis is interesting; this class is merely a central container + * for those timing values. + * Note that, due to the variables in this class being static, + * use of particular time values by multiple applets will cause + * confusing results. For example, if plugin runs two applets + * simultaneously, the initTime for those applets will collide + * and the results may be undefined. + *

+ * To automatically track startup performance in an app or applet, + * use the command-line parameter sun.perflog as follows:
+ *

{@code
+ *     -Dsun.perflog[=file:]
+ * }
+ *
+ * where simply using the parameter with no value will enable output + * to the console and a value of "{@code file:}" will cause + * that given filename to be created and used for all output. + *

+ * By default, times are measured using System.currentTimeMillis(). To use + * System.nanoTime() instead, add the command-line parameter:
+ -Dsun.perflog.nano=true + *
+ *

+ * Warning: Use at your own risk! + * This class is intended for internal testing + * purposes only and may be removed at any time. More + * permanent monitoring and profiling APIs are expected to be + * developed for future releases and this class will cease to + * exist once those APIs are in place. + * @author Chet Haase + */ +public class PerformanceLogger { + + // Timing values of global interest + private static final int START_INDEX = 0; // VM start + private static final int LAST_RESERVED = START_INDEX; + + private static boolean perfLoggingOn = false; + private static boolean useNanoTime = false; + private static Vector times; + private static String logFileName = null; + private static Writer logWriter = null; + private static long baseTime; + + static { + String perfLoggingProp = + java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("sun.perflog")); + if (perfLoggingProp != null) { + perfLoggingOn = true; + + // Check if we should use nanoTime + String perfNanoProp = + java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("sun.perflog.nano")); + if (perfNanoProp != null) { + useNanoTime = true; + } + + // Now, figure out what the user wants to do with the data + if (perfLoggingProp.regionMatches(true, 0, "file:", 0, 5)) { + logFileName = perfLoggingProp.substring(5); + } + if (logFileName != null) { + if (logWriter == null) { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + try { + File logFile = new File(logFileName); + logFile.createNewFile(); + logWriter = new FileWriter(logFile); + } catch (Exception e) { + System.out.println(e + ": Creating logfile " + + logFileName + + ". Log to console"); + } + return null; + } + }); + } + } + if (logWriter == null) { + logWriter = new OutputStreamWriter(System.out); + } + } + times = new Vector(10); + // Reserve predefined slots + for (int i = 0; i <= LAST_RESERVED; ++i) { + times.add(new TimeData("Time " + i + " not set", 0)); + } + } + + /** + * Returns status of whether logging is enabled or not. This is + * provided as a convenience method so that users do not have to + * perform the same GetPropertyAction check as above to determine whether + * to enable performance logging. + */ + public static boolean loggingEnabled() { + return perfLoggingOn; + } + + + /** + * Internal class used to store time/message data together. + */ + static class TimeData { + String message; + long time; + + TimeData(String message, long time) { + this.message = message; + this.time = time; + } + + String getMessage() { + return message; + } + + long getTime() { + return time; + } + } + + /** + * Return the current time, in millis or nanos as appropriate + */ + private static long getCurrentTime() { + if (useNanoTime) { + return System.nanoTime(); + } else { + return System.currentTimeMillis(); + } + } + + /** + * Sets the start time. Ideally, this is the earliest time available + * during the startup of a Java applet or application. This time is + * later used to analyze the difference between the initial startup + * time and other events in the system (such as an applet's init time). + */ + public static void setStartTime(String message) { + if (loggingEnabled()) { + long nowTime = getCurrentTime(); + setStartTime(message, nowTime); + } + } + + /** + * Sets the base time, output can then + * be displayed as offsets from the base time;. + */ + public static void setBaseTime(long time) { + if (loggingEnabled()) { + baseTime = time; + } + } + + /** + * Sets the start time. + * This version of the method is + * given the time to log, instead of expecting this method to + * get the time itself. This is done in case the time was + * recorded much earlier than this method was called. + */ + public static void setStartTime(String message, long time) { + if (loggingEnabled()) { + times.set(START_INDEX, new TimeData(message, time)); + } + } + + /** + * Gets the start time, which should be the time when + * the java process started, prior to the VM actually being + * loaded. + */ + public static long getStartTime() { + if (loggingEnabled()) { + return times.get(START_INDEX).getTime(); + } else { + return 0; + } + } + + /** + * Sets the value of a given time and returns the index of the + * slot that that time was stored in. + */ + public static int setTime(String message) { + if (loggingEnabled()) { + long nowTime = getCurrentTime(); + return setTime(message, nowTime); + } else { + return 0; + } + } + + /** + * Sets the value of a given time and returns the index of the + * slot that that time was stored in. + * This version of the method is + * given the time to log, instead of expecting this method to + * get the time itself. This is done in case the time was + * recorded much earlier than this method was called. + */ + public static int setTime(String message, long time) { + if (loggingEnabled()) { + // times is already synchronized, but we need to ensure that + // the size used in times.set() is the same used when returning + // the index of that operation. + synchronized (times) { + times.add(new TimeData(message, time)); + return (times.size() - 1); + } + } else { + return 0; + } + } + + /** + * Returns time at given index. + */ + public static long getTimeAtIndex(int index) { + if (loggingEnabled()) { + return times.get(index).getTime(); + } else { + return 0; + } + } + + /** + * Returns message at given index. + */ + public static String getMessageAtIndex(int index) { + if (loggingEnabled()) { + return times.get(index).getMessage(); + } else { + return null; + } + } + + /** + * Outputs all data to parameter-specified Writer object + */ + public static void outputLog(Writer writer) { + if (loggingEnabled()) { + try { + synchronized(times) { + for (int i = 0; i < times.size(); ++i) { + TimeData td = times.get(i); + if (td != null) { + writer.write(i + " " + td.getMessage() + ": " + + (td.getTime() - baseTime) + "\n"); + + } + } + } + writer.flush(); + } catch (Exception e) { + System.out.println(e + ": Writing performance log to " + + writer); + } + } + } + + /** + * Outputs all data to whatever location the user specified + * via sun.perflog command-line parameter. + */ + public static void outputLog() { + outputLog(logWriter); + } +} diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java --- a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Thu Jan 14 12:04:19 2016 -0800 @@ -88,9 +88,9 @@ import sun.java2d.loops.XORComposite; import sun.awt.ConstrainableGraphics; import sun.awt.SunHints; +import sun.awt.util.PerformanceLogger; import java.util.Map; import java.util.Iterator; -import sun.misc.PerformanceLogger; import java.lang.annotation.Native; import java.awt.image.MultiResolutionImage; diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Thu Jan 14 12:04:19 2016 -0800 @@ -52,6 +52,7 @@ import sun.font.FontConfigManager; import sun.java2d.SunGraphicsEnvironment; import sun.misc.*; +import sun.awt.util.PerformanceLogger; import sun.awt.util.ThreadGroupUtils; import sun.print.PrintJob2D; import sun.security.action.GetPropertyAction; diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java Thu Jan 14 12:04:19 2016 -0800 @@ -67,10 +67,10 @@ import java.util.Map; import java.util.Properties; +import sun.awt.util.PerformanceLogger; import sun.font.FontManager; import sun.font.FontManagerFactory; import sun.font.SunFontManager; -import sun.misc.PerformanceLogger; import sun.util.logging.PlatformLogger; public final class WToolkit extends SunToolkit implements Runnable { diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java --- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java Thu Jan 14 12:04:19 2016 -0800 @@ -38,6 +38,7 @@ import java.awt.peer.WindowPeer; import java.util.ArrayList; +import jdk.internal.perf.PerfCounter; import sun.awt.AWTAccessor; import sun.awt.AWTAccessor.ComponentAccessor; import sun.awt.Win32GraphicsDevice; @@ -69,9 +70,9 @@ if (d3dAvailable) { // we don't use pixel formats for the d3d pipeline pfDisabled = true; - sun.misc.PerfCounter.getD3DAvailable().set(1); + PerfCounter.getD3DAvailable().set(1); } else { - sun.misc.PerfCounter.getD3DAvailable().set(0); + PerfCounter.getD3DAvailable().set(0); } } diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.management/share/classes/sun/management/ConnectorAddressLink.java --- a/jdk/src/java.management/share/classes/sun/management/ConnectorAddressLink.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.management/share/classes/sun/management/ConnectorAddressLink.java Thu Jan 14 12:04:19 2016 -0800 @@ -34,7 +34,7 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; -import sun.misc.Perf; +import jdk.internal.perf.Perf; import sun.management.counter.Units; import sun.management.counter.Counter; import sun.management.counter.perf.PerfInstrumentation; diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.management/share/classes/sun/management/VMManagementImpl.java --- a/jdk/src/java.management/share/classes/sun/management/VMManagementImpl.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.management/share/classes/sun/management/VMManagementImpl.java Thu Jan 14 12:04:19 2016 -0800 @@ -25,7 +25,7 @@ package sun.management; -import sun.misc.Perf; +import jdk.internal.perf.Perf; import sun.management.counter.*; import sun.management.counter.perf.*; import java.nio.ByteBuffer; diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java --- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Thu Jan 14 12:04:19 2016 -0800 @@ -31,12 +31,14 @@ * ScriptEngineFactory is used to describe and instantiate * ScriptEngines. *

- * Each class implementing ScriptEngine has a corresponding factory - * that exposes metadata describing the engine class. + * Each class implementing ScriptEngine has a corresponding + * factory that exposes metadata describing the engine class. *

The ScriptEngineManager - * uses the service provider mechanism described in the Jar File Specification to obtain - * instances of all ScriptEngineFactories available in - * the current ClassLoader. + * uses the service-provider loader mechanism described in the + * {@link java.util.ServiceLoader} class to obtain + * instances of {@code ScriptEngineFactory} instances. + * See {@link ScriptEngineManager#ScriptEngineManager()} and + * {@link ScriptEngineManager#ScriptEngineManager(java.lang.ClassLoader)}. * * @since 1.6 */ diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java --- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java Thu Jan 14 12:04:19 2016 -0800 @@ -33,7 +33,8 @@ * The ScriptEngineManager implements a discovery and instantiation * mechanism for ScriptEngine classes and also maintains a * collection of key/value pairs storing state shared by all engines created - * by the Manager. This class uses the service provider mechanism to enumerate all the + * by the Manager. This class uses the service provider mechanism described in the + * {@link java.util.ServiceLoader} class to enumerate all the * implementations of ScriptEngineFactory.

* The ScriptEngineManager provides a method to return a list of all these factories * as well as utility methods which look up factories on the basis of language name, file extension @@ -64,7 +65,7 @@ /** * This constructor loads the implementations of * ScriptEngineFactory visible to the given - * ClassLoader using the service provider mechanism.

+ * ClassLoader using the service provider mechanism.

* If loader is null, the script engine factories that are * bundled with the platform are loaded.
* diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.scripting/share/classes/javax/script/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.scripting/share/classes/javax/script/package-info.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005, 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. + */ + +/** + +

The scripting API consists of interfaces and classes that define +Java™ Scripting Engines and provides +a framework for their use in Java applications. This API is intended +for use by application programmers who wish to execute programs +written in scripting languages in their Java applications. The +scripting language programs are usually provided by the end-users of +the applications. +

+

The main areas of functionality of javax.script +package include +

+
    +
  1. Script execution: Scripts +are streams of characters used as sources for programs executed by +script engines. Script execution uses +{@link javax.script.ScriptEngine#eval eval} methods of +{@link javax.script.ScriptEngine ScriptEngine} and methods of the +{@link javax.script.Invocable Invocable} interface. +

    +
  2. Binding: This facility +allows Java objects to be exposed to script programs as named +variables. {@link javax.script.Bindings Bindings} and +{@link javax.script.ScriptContext ScriptContext} +classes are used for this purpose. +

    +
  3. Compilation: This +functionality allows the intermediate code generated by the +front-end of a script engine to be stored and executed repeatedly. +This benefits applications that execute the same script multiple +times. These applications can gain efficiency since the engines' +front-ends only need to execute once per script rather than once per +script execution. Note that this functionality is optional and +script engines may choose not to implement it. Callers need to check +for availability of the {@link javax.script.Compilable Compilable} +interface using an instanceof check. +

    +
  4. Invocation: This +functionality allows the reuse of intermediate code generated by a +script engine's front-end. Whereas Compilation allows entire scripts +represented by intermediate code to be re-executed, Invocation +functionality allows individual procedures/methods in the scripts to +be re-executed. As in the case with compilation, not all script +engines are required to provide this facility. Caller has to check +for {@link javax.script.Invocable Invocable} availability. +

    +
  5. Script engine discovery: Applications +written to the Scripting API might have specific requirements on +script engines. Some may require a specific scripting language +and/or version while others may require a specific implementation +engine and/or version. Script engines are packaged in a specified +way so that engines can be discovered at runtime and queried for +attributes. The Engine discovery mechanism is based on the service-provider +loading facility described in the {@link java.util.ServiceLoader} class. +{@link javax.script.ScriptEngineManager ScriptEngineManager} +includes +{@link javax.script.ScriptEngineManager#getEngineFactories getEngineFactories} method to get all +{@link javax.script.ScriptEngineFactory ScriptEngineFactory} instances +discovered using this mechanism. ScriptEngineFactory has +methods to query attributes about script engine. +

    +
+ +@since 1.6 +*/ + +package javax.script; + diff -r 06adfd8db173 -r 55680f011e48 jdk/src/java.scripting/share/classes/javax/script/package.html --- a/jdk/src/java.scripting/share/classes/javax/script/package.html Thu Jan 14 08:08:19 2016 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ - - - - - - - -

The scripting API consists of interfaces and classes that define -Java™ Scripting Engines and provides -a framework for their use in Java applications. This API is intended -for use by application programmers who wish to execute programs -written in scripting languages in their Java applications. The -scripting language programs are usually provided by the end-users of -the applications. -

-

The main areas of functionality of javax.script -package include -

-
    -
  1. Script execution: Scripts - are streams of characters used as sources for programs executed by - script engines. Script execution uses - {@link javax.script.ScriptEngine#eval eval} methods of - {@link javax.script.ScriptEngine ScriptEngine} and methods of the - {@link javax.script.Invocable Invocable} interface. -

    -
  2. Binding: This facility - allows Java objects to be exposed to script programs as named - variables. {@link javax.script.Bindings Bindings} and - {@link javax.script.ScriptContext ScriptContext} - classes are used for this purpose. -

    -
  3. Compilation: This - functionality allows the intermediate code generated by the - front-end of a script engine to be stored and executed repeatedly. - This benefits applications that execute the same script multiple - times. These applications can gain efficiency since the engines' - front-ends only need to execute once per script rather than once per - script execution. Note that this functionality is optional and - script engines may choose not to implement it. Callers need to check - for availability of the {@link javax.script.Compilable Compilable} - interface using an instanceof check. -

    -
  4. Invocation: This - functionality allows the reuse of intermediate code generated by a - script engine's front-end. Whereas Compilation allows entire scripts - represented by intermediate code to be re-executed, Invocation - functionality allows individual procedures/methods in the scripts to - be re-executed. As in the case with compilation, not all script - engines are required to provide this facility. Caller has to check - for {@link javax.script.Invocable Invocable} availability. -

    -
  5. Script engine discovery and Metadata: Applications - written to the Scripting API might have specific requirements on - script engines. Some may require a specific scripting language - and/or version while others may require a specific implementation - engine and/or version. Script engines are packaged in a specified - way so that engines can be discovered at runtime and queried for - attributes. The Engine discovery mechanism is based on the Service - discovery mechanism described in the Jar File Specification. - Script engine implementing classes are packaged in jar files that - include a text resource named - META-INF/services/javax.script.ScriptEngineFactory. This - resource must include a line for each - {@link javax.script.ScriptEngineFactory ScriptEngineFactory} - that is packaged in the jar file. - {@link javax.script.ScriptEngineManager ScriptEngineManager} - includes - {@link javax.script.ScriptEngineManager#getEngineFactories getEngineFactories} method to get all - {@link javax.script.ScriptEngineFactory ScriptEngineFactory} instances - discovered using this mechanism. ScriptEngineFactory has - methods to query attributes about script engine. -

    -
- -@since 1.6 - - - diff -r 06adfd8db173 -r 55680f011e48 jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java Thu Jan 14 12:04:19 2016 -0800 @@ -95,7 +95,7 @@ public void detach() { /* * no default action required because the detach operation for the - * native byte buffer is managed by the sun.misc.Perf class. + * native byte buffer is managed by the Perf class. */ } diff -r 06adfd8db173 -r 55680f011e48 jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java Thu Jan 14 12:04:19 2016 -0800 @@ -25,7 +25,6 @@ package sun.jvmstat.perfdata.monitor; -import sun.misc.Perf; import sun.jvmstat.monitor.*; import java.util.*; import java.io.*; diff -r 06adfd8db173 -r 55680f011e48 jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataBuffer.java --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataBuffer.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataBuffer.java Thu Jan 14 12:04:19 2016 -0800 @@ -25,7 +25,7 @@ package sun.jvmstat.perfdata.monitor.protocol.local; -import sun.misc.Perf; +import jdk.internal.perf.Perf; import sun.jvmstat.monitor.*; import sun.jvmstat.perfdata.monitor.*; import java.util.*; diff -r 06adfd8db173 -r 55680f011e48 jdk/test/ProblemList.txt --- a/jdk/test/ProblemList.txt Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/ProblemList.txt Thu Jan 14 12:04:19 2016 -0800 @@ -1,6 +1,6 @@ ########################################################################### # -# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 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 @@ -299,6 +299,9 @@ # 8074580 sun/security/pkcs11/rsa/TestKeyPairGenerator.java generic-all +# 8146387 +javax/net/ssl/SSLSession/SessionCacheSizeTests.java windows-all,solaris-all + ############################################################################ # jdk_sound diff -r 06adfd8db173 -r 55680f011e48 jdk/test/TEST.groups --- a/jdk/test/TEST.groups Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/TEST.groups Thu Jan 14 12:04:19 2016 -0800 @@ -31,7 +31,6 @@ -java/util/zip/TestLocalTime.java \ :jdk_util \ -java/util/WeakHashMap/GCDuringIteration.java \ - -java/util/concurrent/Phaser/Basic.java \ -java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java sun/nio/cs/ISO8859x.java \ java/nio/Buffer \ @@ -41,7 +40,6 @@ tier2 = \ java/lang/ProcessHandle/TreeTest.java \ java/util/zip/TestLocalTime.java \ - java/util/concurrent/Phaser/Basic.java \ java/util/WeakHashMap/GCDuringIteration.java \ java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \ :jdk_io \ @@ -77,7 +75,6 @@ sun/misc \ sun/reflect \ jdk/lambda \ - jdk/internal/jimage \ vm # All of the java.util package diff -r 06adfd8db173 -r 55680f011e48 jdk/test/java/lang/StackWalker/LocalsAndOperands.java --- a/jdk/test/java/lang/StackWalker/LocalsAndOperands.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/java/lang/StackWalker/LocalsAndOperands.java Thu Jan 14 12:04:19 2016 -0800 @@ -86,29 +86,43 @@ System.out.println("frame: " + f); Object[] locals = (Object[]) getLocals.invoke(f); for (int i = 0; i < locals.length; i++) { - System.out.format("local %d: %s type %s%n", i, locals[i], type(locals[i])); + System.out.format(" local %d: %s type %s\n", i, locals[i], type(locals[i])); + + // check for non-null locals in LocalsAndOperands.test() + if (f.getClassName().equals("LocalsAndOperands") && + f.getMethodName().equals("test")) { + if (locals[i] == null) { + throw new RuntimeException("kept-alive locals should not be null"); + } + } } Object[] operands = (Object[]) getOperands.invoke(f); for (int i = 0; i < operands.length; i++) { - System.out.format("operand %d: %s type %s%n", i, operands[i], type(operands[i])); + System.out.format(" operand %d: %s type %s%n", i, operands[i], + type(operands[i])); } Object[] monitors = (Object[]) getMonitors.invoke(f); for (int i = 0; i < monitors.length; i++) { - System.out.format("monitor %d: %s%n", i, monitors[i]); + System.out.format(" monitor %d: %s%n", i, monitors[i]); } } } else { for (StackFrame f : frames) { - if (liveStackFrameClass.isInstance(f)) + if (liveStackFrameClass.isInstance(f)) { throw new RuntimeException("should not be LiveStackFrame"); + } } } + // Use local variables so they stay alive + System.out.println("Stayin' alive: "+x+" "+c+" "+hi+" "+l+" "+d); } String type(Object o) throws Exception { - if (primitiveValueClass.isInstance(o)) { + if (o == null) { + return "null"; + } else if (primitiveValueClass.isInstance(o)) { char c = (char)primitiveType.invoke(o); return String.valueOf(c); } else { diff -r 06adfd8db173 -r 55680f011e48 jdk/test/java/lang/invoke/8076596/Test8076596.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/invoke/8076596/Test8076596.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,50 @@ +/* + * 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. 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. + */ + +/* @test + * @bug 8076596 + * @run main/othervm/policy=Test8076596.security.policy/secure=Test8076596 -ea -esa Test8076596 + */ + +import java.security.AccessController; +import java.security.PrivilegedAction; + +public class Test8076596 extends SecurityManager { + public Test8076596() { + // 1. Using lambda + AccessController.doPrivileged((PrivilegedAction) () -> null); + // 2. Using inner class + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Void run() { + return null; + } + }); + } + + public static void main(String[] args) { + // empty + } +} diff -r 06adfd8db173 -r 55680f011e48 jdk/test/java/lang/invoke/8076596/Test8076596.security.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/invoke/8076596/Test8076596.security.policy Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,8 @@ +/* + * Security policy used by the Test8076596. + * Must allow file reads so that jtreg itself can run. + */ + +grant { + permission java.io.FilePermission "*", "read"; +}; diff -r 06adfd8db173 -r 55680f011e48 jdk/test/java/lang/invoke/8147078/Test8147078.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/invoke/8147078/Test8147078.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,82 @@ +/* + * 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. 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. + */ + +/* @test + * @bug 8147078 + * @run testng/othervm -ea -esa Test8147078 + */ + +import org.testng.annotations.Test; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + +import static java.lang.invoke.MethodType.methodType; + +import static org.testng.AssertJUnit.*; + +public class Test8147078 { + + static int target(int x) { + throw new RuntimeException("ieps"); + } + + static int handler(String s, int x) { + return 4*x; + } + + static final MethodHandle MH_target; + static final MethodHandle MH_handler; + static final MethodHandle MH_catchException; + + static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); + + static { + try { + Class C = Test8147078.class; + MH_target = LOOKUP.findStatic(C, "target", methodType(int.class, int.class)); + MH_handler = LOOKUP.findStatic(C, "handler", methodType(int.class, String.class, int.class)); + MH_catchException = LOOKUP.findStatic(MethodHandles.class, "catchException", + methodType(MethodHandle.class, MethodHandle.class, Class.class, MethodHandle.class)); + } catch (Exception e) { + throw new ExceptionInInitializerError(e); + } + } + + @Test + public void testNoExceptionType() { + boolean caught = false; + try { + MethodHandle eek = (MethodHandle) MH_catchException.invoke(MH_target, String.class, MH_handler); + } catch (ClassCastException cce) { + assertEquals("java.lang.String", cce.getMessage()); + caught = true; + } catch (Throwable t) { + fail("unexpected exception caught: " + t); + } + assertTrue(caught); + } + +} \ No newline at end of file diff -r 06adfd8db173 -r 55680f011e48 jdk/test/java/lang/invoke/FindClassSecurityManager.java --- a/jdk/test/java/lang/invoke/FindClassSecurityManager.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/java/lang/invoke/FindClassSecurityManager.java Thu Jan 14 12:04:19 2016 -0800 @@ -24,6 +24,7 @@ */ /* @test + * @bug 8139885 * @run main/othervm/policy=findclass.security.policy/secure=java.lang.SecurityManager -ea -esa test.java.lang.invoke.FindClassSecurityManager */ diff -r 06adfd8db173 -r 55680f011e48 jdk/test/java/lang/invoke/T8139885.java --- a/jdk/test/java/lang/invoke/T8139885.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/java/lang/invoke/T8139885.java Thu Jan 14 12:04:19 2016 -0800 @@ -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 @@ -24,6 +24,8 @@ */ /* @test + * @bug 8139885 + * @bug 8143798 * @run testng/othervm -ea -esa test.java.lang.invoke.T8139885 */ diff -r 06adfd8db173 -r 55680f011e48 jdk/test/java/lang/ref/CleanerTest.java --- a/jdk/test/java/lang/ref/CleanerTest.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/java/lang/ref/CleanerTest.java Thu Jan 14 12:04:19 2016 -0800 @@ -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 @@ -34,9 +34,10 @@ import java.util.function.Consumer; import java.util.function.Supplier; -import jdk.internal.misc.CleanerImpl.PhantomCleanable; -import jdk.internal.misc.CleanerImpl.WeakCleanable; -import jdk.internal.misc.CleanerImpl.SoftCleanable; +import jdk.internal.ref.PhantomCleanable; +import jdk.internal.ref.WeakCleanable; +import jdk.internal.ref.SoftCleanable; +import jdk.internal.ref.CleanerFactory; import sun.hotspot.WhiteBox; @@ -48,17 +49,17 @@ * @test * @library /lib/testlibrary /test/lib * @build sun.hotspot.WhiteBox - * @modules java.base/jdk.internal.misc + * @modules java.base/jdk.internal.misc java.base/jdk.internal.ref * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run testng/othervm * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. - * -verbose:gc -Xmx4m CleanerTest + * -verbose:gc CleanerTest */ @Test public class CleanerTest { // A common CleaningService used by the test for notifications - static final Cleaner COMMON = Cleaner.create(); + static final Cleaner COMMON = CleanerFactory.cleaner(); // Access to WhiteBox utilities static final WhiteBox whitebox = WhiteBox.getWhiteBox(); @@ -702,4 +703,17 @@ cleaner = null; } + /** + * Test the Cleaner from the CleanerFactory. + */ + @Test + void testCleanerFactory() { + Cleaner cleaner = CleanerFactory.cleaner(); + + Object obj = new Object(); + CleanableCase s = setupPhantom(cleaner, obj); + obj = null; + Assert.assertTrue(checkCleaned(s.getSemaphore()), + "Object cleaning should have occurred using CleanerFactor.cleaner()"); + } } diff -r 06adfd8db173 -r 55680f011e48 jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.java --- a/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.java Thu Jan 14 12:04:19 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -41,7 +41,11 @@ } catch (Exception ex) { throw new RuntimeException("Setting DatagramSocketImplFactory failed!"); } - new QuoteServerThread().start(); + + QuoteServerThread server = new QuoteServerThread(); + int port = server.getPort(); + System.out.println("Server port is " + port); + server.start(); // get a datagram socket DatagramSocket socket = new DatagramSocket(); @@ -49,7 +53,7 @@ // send request byte[] buf = new byte[256]; InetAddress address = InetAddress.getLocalHost(); - DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); + DatagramPacket packet = new DatagramPacket(buf, buf.length, address, port); socket.send(packet); // get response @@ -67,6 +71,7 @@ class QuoteServerThread extends Thread { protected DatagramSocket socket = null; + private final int port; public QuoteServerThread() throws IOException { this("QuoteServerThread"); @@ -74,7 +79,11 @@ public QuoteServerThread(String name) throws IOException { super(name); - socket = new DatagramSocket(4445); + socket = new DatagramSocket(0); + port = socket.getLocalPort(); + } + public int getPort(){ + return port; } public void run() { @@ -101,3 +110,4 @@ socket.close(); } } + diff -r 06adfd8db173 -r 55680f011e48 jdk/test/java/time/tck/java/time/TCKLocalDate.java --- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java Thu Jan 14 12:04:19 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -1285,12 +1285,36 @@ public void test_plusWeeks_invalidMaxMinusMin() { LocalDate.of(Year.MAX_VALUE, 12, 25).plusWeeks(Long.MIN_VALUE); } + //----------------------------------------------------------------------- + @DataProvider(name="PlusDays") + Object[][] provider_plusDays() { + return new Object[][] { + {LocalDate.of(2007, 7, 15), 1, LocalDate.of(2007, 7, 16)}, + {LocalDate.of(2007, 7, 15), 17, LocalDate.of(2007, 8, 1)}, + {LocalDate.of(2007, 12, 31), 1, LocalDate.of(2008, 1, 1)}, + {LocalDate.of(2007, 1, 1), 58, LocalDate.of(2007, 2, 28)}, + {LocalDate.of(2007, 1, 1), 59, LocalDate.of(2007, 3, 1)}, + {LocalDate.of(2008, 1, 1), 60, LocalDate.of(2008, 3, 1)}, + {LocalDate.of(2007, 2, 1), 27, LocalDate.of(2007, 2, 28)}, + {LocalDate.of(2007, 2, 1), 28, LocalDate.of(2007, 3, 1)}, + {LocalDate.of(2007, 1, 1), 29, LocalDate.of(2007, 1, 30)}, + {LocalDate.of(2007, 1, 1), 30, LocalDate.of(2007, 1, 31)}, + {LocalDate.of(2007, 1, 15), 13, LocalDate.of(2007, 1, 28)}, + {LocalDate.of(2007, 1, 15), 14, LocalDate.of(2007, 1, 29)}, + {LocalDate.of(2007, 1, 15), 15, LocalDate.of(2007, 1, 30)}, + {LocalDate.of(2007, 1, 15), 16, LocalDate.of(2007, 1, 31)}, + {LocalDate.of(2007, 2, 15), 13, LocalDate.of(2007, 2, 28)}, + {LocalDate.of(2007, 2, 15), 14, LocalDate.of(2007, 3, 1)}, + {LocalDate.of(2007, 2, 15), 15, LocalDate.of(2007, 3, 2)}, + {LocalDate.of(2007, 2, 15), 16, LocalDate.of(2007, 3, 3)}, + }; + } - @Test - public void test_plusDays_normal() { - LocalDate t = TEST_2007_07_15.plusDays(1); - assertEquals(t, LocalDate.of(2007, 7, 16)); - } + @Test(dataProvider="PlusDays") + public void test_plusDays_normal(LocalDate input, int amountsToAdd, LocalDate expected) { + LocalDate actual = input.plusDays(amountsToAdd); + assertEquals(actual, expected); + } @Test public void test_plusDays_overMonths() { diff -r 06adfd8db173 -r 55680f011e48 jdk/test/java/util/logging/LogManager/Configuration/updateConfiguration/UpdateConfigurationTest.java --- a/jdk/test/java/util/logging/LogManager/Configuration/updateConfiguration/UpdateConfigurationTest.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/java/util/logging/LogManager/Configuration/updateConfiguration/UpdateConfigurationTest.java Thu Jan 14 12:04:19 2016 -0800 @@ -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 @@ -209,8 +209,9 @@ + barChild.getParent() +"\n\texpected: " + barRef.get()); } Reference ref2; - int max = 3; + int max = 10; barChild = null; + System.gc(); while ((ref2 = queue.poll()) == null) { System.gc(); Thread.sleep(100); @@ -276,24 +277,27 @@ } }); - // Now we need to forget the child, so that loggers are released, - // and so that we can run the test with the next configuration... - - fooChild = null; - System.out.println("Setting fooChild to: " + fooChild); - while ((ref2 = queue.poll()) == null) { - System.gc(); - Thread.sleep(1000); + if (suppressed == null) { + // Now we need to forget the child, so that loggers are released, + // and so that we can run the test with the next configuration... + // No need to do that if failed!=null however, as the first + // ref might not have been cleared yet and failing here would + // hide the original failure. + fooChild = null; + System.out.println("Setting fooChild to: " + fooChild); + while ((ref2 = queue.poll()) == null) { + System.gc(); + Thread.sleep(1000); + } + if (ref2 != fooRef) { + throw new RuntimeException("Unexpected reference: " + + ref2 +"\n\texpected: " + fooRef); + } + if (ref2.get() != null) { + throw new RuntimeException("Referent not cleared: " + ref2.get()); + } + System.out.println("Got fooRef after reset(), fooChild is " + fooChild); } - if (ref2 != fooRef) { - throw new RuntimeException("Unexpected reference: " - + ref2 +"\n\texpected: " + fooRef); - } - if (ref2.get() != null) { - throw new RuntimeException("Referent not cleared: " + ref2.get()); - } - System.out.println("Got fooRef after reset(), fooChild is " + fooChild); - } } if (failed != null) { diff -r 06adfd8db173 -r 55680f011e48 jdk/test/javax/net/ssl/ALPN/MyX509ExtendedKeyManager.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/net/ssl/ALPN/MyX509ExtendedKeyManager.java Thu Jan 14 12:04:19 2016 -0800 @@ -0,0 +1,130 @@ +/* + * 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. + */ + +import java.net.Socket; +import java.security.Principal; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.X509ExtendedKeyManager; + +public class MyX509ExtendedKeyManager extends X509ExtendedKeyManager { + + static final String ERROR = "ERROR"; + X509ExtendedKeyManager akm; + String expectedAP; + + MyX509ExtendedKeyManager(X509ExtendedKeyManager akm) { + this.akm = akm; + } + + public MyX509ExtendedKeyManager( + X509ExtendedKeyManager akm, String expectedAP) { + this.akm = akm; + this.expectedAP = expectedAP; + + } + + @Override + public String[] getClientAliases(String keyType, Principal[] issuers) { + return akm.getClientAliases(keyType, issuers); + } + + @Override + public String chooseClientAlias(String[] keyType, Principal[] issuers, + Socket socket) { + String nap = ((SSLSocket) socket).getHandshakeApplicationProtocol(); + checkALPN(nap); + + return akm.chooseClientAlias(keyType, issuers, socket); + } + + @Override + public String[] getServerAliases(String keyType, Principal[] issuers) { + return akm.getServerAliases(keyType, issuers); + } + + @Override + public String chooseServerAlias(String keyType, Principal[] issuers, + Socket socket) { + String nap = ((SSLSocket) socket).getHandshakeApplicationProtocol(); + checkALPN(nap); + + return akm.chooseServerAlias(keyType, issuers, socket); + } + + @Override + public X509Certificate[] getCertificateChain(String alias) { + return akm.getCertificateChain(alias); + } + + @Override + public PrivateKey getPrivateKey(String alias) { + return akm.getPrivateKey(alias); + } + + @Override + public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, + SSLEngine engine) { + String nap = engine.getHandshakeApplicationProtocol(); + checkALPN(nap); + + return akm.chooseEngineClientAlias(keyType, issuers, engine); + } + + @Override + public String chooseEngineServerAlias(String keyType, Principal[] issuers, + SSLEngine engine) { + String nap = engine.getHandshakeApplicationProtocol(); + checkALPN(nap); + + return akm.chooseEngineServerAlias(keyType, issuers, engine); + } + + private void checkALPN(String ap) { + + if (ERROR.equals(expectedAP)) { + throw new RuntimeException("Should not reach here"); + } + + System.out.println("Expected ALPN value: " + expectedAP + + " Got: " + ap); + + if (ap == null) { + throw new RuntimeException( + "ALPN should be negotiated, but null was received"); + } + if (expectedAP.equals("NONE")) { + if (!ap.isEmpty()) { + throw new RuntimeException("Expected no ALPN value"); + } else { + System.out.println("No ALPN value negotiated, as expected"); + } + } else if (!expectedAP.equals(ap)) { + throw new RuntimeException(expectedAP + + " ALPN value not available on negotiated connection"); + } + + } +} diff -r 06adfd8db173 -r 55680f011e48 jdk/test/javax/net/ssl/ALPN/SSLEngineAlpnTest.java --- a/jdk/test/javax/net/ssl/ALPN/SSLEngineAlpnTest.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/javax/net/ssl/ALPN/SSLEngineAlpnTest.java Thu Jan 14 12:04:19 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -26,8 +26,9 @@ /* * @test - * @bug 8051498 + * @bug 8051498 8145849 * @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension + * @compile MyX509ExtendedKeyManager.java * @run main/othervm SSLEngineAlpnTest h2 h2 h2 * @run main/othervm SSLEngineAlpnTest h2 h2,http/1.1 h2 * @run main/othervm SSLEngineAlpnTest h2,http/1.1 h2,http/1.1 h2 @@ -162,7 +163,7 @@ throw new Exception("Invalid number of test parameters"); } - SSLEngineAlpnTest test = new SSLEngineAlpnTest(); + SSLEngineAlpnTest test = new SSLEngineAlpnTest(args[2]); try { test.runTest(convert(args[0]), convert(args[1]), args[2]); } catch (SSLHandshakeException she) { @@ -179,7 +180,7 @@ /* * Create an initialized SSLContext to use for these tests. */ - public SSLEngineAlpnTest() throws Exception { + public SSLEngineAlpnTest(String expectedAP) throws Exception { KeyStore ks = KeyStore.getInstance("JKS"); KeyStore ts = KeyStore.getInstance("JKS"); @@ -192,12 +193,20 @@ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, passphrase); + KeyManager [] kms = kmf.getKeyManagers(); + if (!(kms[0] instanceof X509ExtendedKeyManager)) { + throw new Exception("kms[0] not X509ExtendedKeyManager"); + } + + kms = new KeyManager[] { new MyX509ExtendedKeyManager( + (X509ExtendedKeyManager) kms[0], expectedAP) }; + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ts); SSLContext sslCtx = SSLContext.getInstance("TLS"); - sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + sslCtx.init(kms, tmf.getTrustManagers(), null); sslc = sslCtx; } @@ -327,6 +336,11 @@ return; } + if (engine.getHandshakeApplicationProtocol() != null) { + throw new Exception ("getHandshakeApplicationProtocol() should " + + "return null after the handshake is completed"); + } + String ap = engine.getApplicationProtocol(); System.out.println("Application Protocol: \"" + ap + "\""); @@ -384,6 +398,12 @@ sslp = clientEngine.getSSLParameters(); sslp.setApplicationProtocols(clientAPs); clientEngine.setSSLParameters(sslp); + + if ((clientEngine.getHandshakeApplicationProtocol() != null) || + (serverEngine.getHandshakeApplicationProtocol() != null)) { + throw new Exception ("getHandshakeApplicationProtocol() should " + + "return null before the handshake starts"); + } } /* diff -r 06adfd8db173 -r 55680f011e48 jdk/test/javax/net/ssl/ALPN/SSLSocketAlpnTest.java --- a/jdk/test/javax/net/ssl/ALPN/SSLSocketAlpnTest.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/javax/net/ssl/ALPN/SSLSocketAlpnTest.java Thu Jan 14 12:04:19 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, 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 @@ -26,8 +26,9 @@ /* * @test - * @bug 8051498 + * @bug 8051498 8145849 * @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension + * @compile MyX509ExtendedKeyManager.java * @run main/othervm SSLSocketAlpnTest h2 h2 h2 * @run main/othervm SSLSocketAlpnTest h2 h2,http/1.1 h2 * @run main/othervm SSLSocketAlpnTest h2,http/1.1 h2,http/1.1 h2 @@ -40,6 +41,8 @@ * @author Brad Wetmore */ import java.io.*; +import java.security.KeyStore; + import javax.net.ssl.*; public class SSLSocketAlpnTest { @@ -65,6 +68,16 @@ static String trustStoreFile = "truststore"; static String passwd = "passphrase"; + static String keyFilename = System.getProperty("test.src", ".") + "/" + + pathToStores + "/" + keyStoreFile; + static String trustFilename = System.getProperty("test.src", ".") + "/" + + pathToStores + "/" + trustStoreFile; + + /* + * SSLContext + */ + SSLContext mySSLContext = null; + /* * Is the server ready to serve? */ @@ -82,7 +95,7 @@ /* * If the client or server is doing some kind of object creation * that the other side depends on, and that thread prematurely - * exits, you may experience a hang. The test harness will + * exits, you may experience a hang. The test harness will * terminate all hung threads after its timeout has expired, * currently 3 minutes by default, but you might try to be * smart about it.... @@ -95,10 +108,11 @@ * to avoid infinite hangs. */ void doServerSide() throws Exception { - SSLServerSocketFactory sslssf - = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); + SSLServerSocketFactory sslssf = mySSLContext.getServerSocketFactory(); SSLServerSocket sslServerSocket = (SSLServerSocket) sslssf.createServerSocket(serverPort); + // for both client/server to call into X509KM + sslServerSocket.setNeedClientAuth(true); serverPort = sslServerSocket.getLocalPort(); @@ -119,20 +133,30 @@ */ String[] suites = sslp.getCipherSuites(); sslp.setCipherSuites(suites); - sslp.setUseCipherSuitesOrder(true); // Set server side order + sslp.setUseCipherSuitesOrder(true); // Set server side order // Set the ALPN selection. sslp.setApplicationProtocols(serverAPs); sslSocket.setSSLParameters(sslp); + if (sslSocket.getHandshakeApplicationProtocol() != null) { + throw new Exception ("getHandshakeApplicationProtocol() should " + + "return null before the handshake starts"); + } + sslSocket.startHandshake(); + if (sslSocket.getHandshakeApplicationProtocol() != null) { + throw new Exception ("getHandshakeApplicationProtocol() should " + + "return null after the handshake is completed"); + } + String ap = sslSocket.getApplicationProtocol(); System.out.println("Application Protocol: \"" + ap + "\""); if (ap == null) { throw new Exception( - "Handshake was completed but null was received"); + "Handshake was completed but null was received"); } if (expectedAP.equals("NONE")) { if (!ap.isEmpty()) { @@ -141,8 +165,8 @@ System.out.println("No ALPN value negotiated, as expected"); } } else if (!expectedAP.equals(ap)) { - throw new Exception(expectedAP + - " ALPN value not available on negotiated connection"); + throw new Exception(expectedAP + + " ALPN value not available on negotiated connection"); } InputStream sslIS = sslSocket.getInputStream(); @@ -170,8 +194,7 @@ Thread.sleep(50); } - SSLSocketFactory sslsf - = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sslsf = mySSLContext.getSocketFactory(); SSLSocket sslSocket = (SSLSocket) sslsf.createSocket("localhost", serverPort); @@ -185,28 +208,35 @@ */ String[] suites = sslp.getCipherSuites(); sslp.setCipherSuites(suites); - sslp.setUseCipherSuitesOrder(true); // Set server side order + sslp.setUseCipherSuitesOrder(true); // Set server side order // Set the ALPN selection. sslp.setApplicationProtocols(clientAPs); sslSocket.setSSLParameters(sslp); + if (sslSocket.getHandshakeApplicationProtocol() != null) { + throw new Exception ("getHandshakeApplicationProtocol() should " + + "return null before the handshake starts"); + } + sslSocket.startHandshake(); + if (sslSocket.getHandshakeApplicationProtocol() != null) { + throw new Exception ("getHandshakeApplicationProtocol() should " + + "return null after the handshake is completed"); + } + /* * Check that the resulting connection meets our defined ALPN * criteria. If we were connecting to a non-JSSE implementation, * the server might have negotiated something we shouldn't accept. - * - * We were expecting H2 from server, let's make sure the - * conditions match. */ String ap = sslSocket.getApplicationProtocol(); System.out.println("Application Protocol: \"" + ap + "\""); if (ap == null) { throw new Exception( - "Handshake was completed but null was received"); + "Handshake was completed but null was received"); } if (expectedAP.equals("NONE")) { if (!ap.isEmpty()) { @@ -215,8 +245,8 @@ System.out.println("No ALPN value negotiated, as expected"); } } else if (!expectedAP.equals(ap)) { - throw new Exception(expectedAP + - " ALPN value not available on negotiated connection"); + throw new Exception(expectedAP + + " ALPN value not available on negotiated connection"); } InputStream sslIS = sslSocket.getInputStream(); @@ -240,17 +270,6 @@ volatile Exception clientException = null; public static void main(String[] args) throws Exception { - String keyFilename - = System.getProperty("test.src", ".") + "/" + pathToStores - + "/" + keyStoreFile; - String trustFilename - = System.getProperty("test.src", ".") + "/" + pathToStores - + "/" + trustStoreFile; - - System.setProperty("javax.net.ssl.keyStore", keyFilename); - System.setProperty("javax.net.ssl.keyStorePassword", passwd); - System.setProperty("javax.net.ssl.trustStore", trustFilename); - System.setProperty("javax.net.ssl.trustStorePassword", passwd); if (debug) { System.setProperty("javax.net.debug", "all"); @@ -280,6 +299,39 @@ System.out.println("Test Passed."); } + SSLContext getSSLContext(String keyFilename, String trustFilename) + throws Exception { + SSLContext ctx = SSLContext.getInstance("TLS"); + + // Keystores + KeyStore keyKS = KeyStore.getInstance("JKS"); + keyKS.load(new FileInputStream(keyFilename), passwd.toCharArray()); + + KeyStore trustKS = KeyStore.getInstance("JKS"); + trustKS.load(new FileInputStream(trustFilename), passwd.toCharArray()); + + // Generate KeyManager and TrustManager + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(keyKS, passwd.toCharArray()); + + KeyManager[] kms = kmf.getKeyManagers(); + if (!(kms[0] instanceof X509ExtendedKeyManager)) { + throw new Exception("kms[0] not X509ExtendedKeyManager"); + } + + kms = new KeyManager[] { new MyX509ExtendedKeyManager( + (X509ExtendedKeyManager) kms[0], expectedAP) }; + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(trustKS); + TrustManager[] tms = tmf.getTrustManagers(); + + // initial SSLContext + ctx.init(kms, tms, null); + + return ctx; + } + /* * Convert a comma-separated list into an array of strings. */ @@ -309,6 +361,7 @@ */ SSLSocketAlpnTest() throws Exception { Exception startException = null; + mySSLContext = getSSLContext(keyFilename, trustFilename); try { if (separateServerThread) { startServer(true); diff -r 06adfd8db173 -r 55680f011e48 jdk/test/javax/net/ssl/SSLSession/SessionCacheSizeTests.java --- a/jdk/test/javax/net/ssl/SSLSession/SessionCacheSizeTests.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/javax/net/ssl/SSLSession/SessionCacheSizeTests.java Thu Jan 14 12:04:19 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, 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 @@ -31,6 +31,7 @@ * @bug 4366807 * @summary Need new APIs to get/set session timeout and session cache size. * @run main/othervm SessionCacheSizeTests + * @key intermittent */ import java.io.*; @@ -108,28 +109,34 @@ void doServerSide(int serverPort, int serverConns) throws Exception { - SSLServerSocket sslServerSocket = - (SSLServerSocket) sslssf.createServerSocket(serverPort); - sslServerSocket.setSoTimeout(45000); // timeout to accept a connection - serverPorts[createdPorts++] = sslServerSocket.getLocalPort(); + try (SSLServerSocket sslServerSocket = + (SSLServerSocket) sslssf.createServerSocket(serverPort)) { + + // timeout to accept a connection + sslServerSocket.setSoTimeout(45000); + + // make sure createdPorts++ is atomic + synchronized(serverPorts) { + serverPorts[createdPorts++] = sslServerSocket.getLocalPort(); - /* - * Signal Client, we're ready for his connect. - */ - if (createdPorts == serverPorts.length) { - serverReady = true; - } - int read = 0; - int nConnections = 0; - /* - * Divide the max connections among the available server ports. - * The use of more than one server port ensures creation of more - * than one session. - */ - SSLSession sessions [] = new SSLSession [serverConns]; - SSLSessionContext sessCtx = sslctx.getServerSessionContext(); + /* + * Signal Client, we're ready for his connect. + */ + if (createdPorts == serverPorts.length) { + serverReady = true; + } + } + int read = 0; + int nConnections = 0; - try { + /* + * Divide the max connections among the available server ports. + * The use of more than one server port ensures creation of more + * than one session. + */ + SSLSession sessions [] = new SSLSession [serverConns]; + SSLSessionContext sessCtx = sslctx.getServerSessionContext(); + while (nConnections < serverConns) { try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) { @@ -143,8 +150,6 @@ nConnections++; } } - } finally { - sslServerSocket.close(); } } @@ -270,8 +275,8 @@ * Using four ports (one per each connection), we are able to create * alteast four sessions. */ - volatile int serverPorts[] = new int[]{0, 0, 0, 0}; - volatile int createdPorts = 0; + int serverPorts[] = new int[]{0, 0, 0, 0}; // MAX_ACTIVE_CONNECTIONS: 4 + int createdPorts = 0; static SSLServerSocketFactory sslssf; static SSLSocketFactory sslsf; static SSLContext sslctx; diff -r 06adfd8db173 -r 55680f011e48 jdk/test/jdk/internal/jimage/JImageReadTest.java --- a/jdk/test/jdk/internal/jimage/JImageReadTest.java Thu Jan 14 08:08:19 2016 -0800 +++ b/jdk/test/jdk/internal/jimage/JImageReadTest.java Thu Jan 14 12:04:19 2016 -0800 @@ -313,7 +313,7 @@ static boolean isMetaName(String name) { return name.startsWith("/modules") || name.startsWith("/packages") - || name.startsWith("META-INF/services") + || name.startsWith("META-INF") || name.equals("bootmodules.jdata"); }