# HG changeset patch # User prr # Date 1512411166 28800 # Node ID f27aad5782dacbdf2f4667a8cc70df165affb6e9 # Parent 40afd72303e96e3494c46e90b8320c456a01b26d# Parent ee64cb4455a9bbc2548d0b7f98b8eee2110b44aa Merge diff -r 40afd72303e9 -r f27aad5782da make/RunTests.gmk --- a/make/RunTests.gmk Mon Dec 04 09:38:34 2017 -0800 +++ b/make/RunTests.gmk Mon Dec 04 10:12:46 2017 -0800 @@ -68,6 +68,7 @@ TEST_RESULTS_DIR := $(OUTPUTDIR)/test-results TEST_SUPPORT_DIR := $(OUTPUTDIR)/test-support TEST_SUMMARY := $(TEST_RESULTS_DIR)/test-summary.txt +TEST_LAST_IDS := $(TEST_SUPPORT_DIR)/test-last-ids.txt ifeq ($(CUSTOM_ROOT), ) JTREG_TOPDIR := $(TOPDIR) @@ -228,7 +229,8 @@ $(if $(findstring :, $(TEST_NAME)), \ $(if $(filter :%, $(TEST_NAME)), \ $(eval TEST_GROUP := $(patsubst :%, %, $(TEST_NAME))) \ - $(eval TEST_ROOTS := $(JTREG_TESTROOTS)) \ + $(eval TEST_ROOTS := $(foreach test_root, $(JTREG_TESTROOTS), \ + $(call CleanupJtregPath, $(test_root)))) \ , \ $(eval TEST_PATH := $(word 1, $(subst :, $(SPACE), $(TEST_NAME)))) \ $(eval TEST_GROUP := $(word 2, $(subst :, $(SPACE), $(TEST_NAME)))) \ @@ -316,6 +318,7 @@ define SetupRunGtestTestBody $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1 $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1 + $1_EXITCODE := $$($1_TEST_RESULTS_DIR)/exitcode.txt $1_TEST_NAME := $$(strip $$(patsubst gtest:%, %, $$($1_TEST))) ifneq ($$($1_TEST_NAME), all) @@ -332,10 +335,13 @@ $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR)) $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/gtest, \ $$(FIXPATH) $$(TEST_IMAGE_DIR)/hotspot/gtest/server/gtestLauncher \ - -jdk $(JDK_IMAGE_DIR) $$($1_GTEST_FILTER) \ - --gtest_output=xml:$$($1_TEST_RESULTS_DIR)/gtest.xml \ - $$($1_GTEST_REPEAT) $$(GTEST_OPTIONS) $$(GTEST_VM_OPTIONS) \ - > >($(TEE) $$($1_TEST_RESULTS_DIR)/gtest.txt) || true ) + -jdk $(JDK_IMAGE_DIR) $$($1_GTEST_FILTER) \ + --gtest_output=xml:$$($1_TEST_RESULTS_DIR)/gtest.xml \ + $$($1_GTEST_REPEAT) $$(GTEST_OPTIONS) $$(GTEST_VM_OPTIONS) \ + > >($(TEE) $$($1_TEST_RESULTS_DIR)/gtest.txt) \ + && $$(ECHO) $$$$? > $$($1_EXITCODE) \ + || $$(ECHO) $$$$? > $$($1_EXITCODE) \ + ) $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/gtest.txt @@ -343,7 +349,7 @@ $$(call LogWarn, Finished running test '$$($1_TEST)') $$(call LogWarn, Test report is stored in $$(strip \ $$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR)))) - $$(if $$(wildcard $$($1_RESULT_FILE)), \ + $$(if $$(wildcard $$($1_RESULT_FILE)), \ $$(eval $1_TOTAL := $$(shell $$(AWK) '/==========.* tests? from .* \ test cases? ran/ { print $$$$2 }' $$($1_RESULT_FILE))) \ $$(if $$($1_TOTAL), , $$(eval $1_TOTAL := 0)) \ @@ -398,6 +404,7 @@ define SetupRunJtregTestBody $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1 $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1 + $1_EXITCODE := $$($1_TEST_RESULTS_DIR)/exitcode.txt $1_TEST_NAME := $$(strip $$(patsubst jtreg:%, %, $$($1_TEST))) @@ -505,7 +512,10 @@ -workDir:$$($1_TEST_SUPPORT_DIR) \ $$(JTREG_OPTIONS) \ $$(JTREG_FAILURE_HANDLER_OPTIONS) \ - $$($1_TEST_NAME) || true ) + $$($1_TEST_NAME) \ + && $$(ECHO) $$$$? > $$($1_EXITCODE) \ + || $$(ECHO) $$$$? > $$($1_EXITCODE) \ + ) $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/text/stats.txt @@ -513,7 +523,7 @@ $$(call LogWarn, Finished running test '$$($1_TEST)') $$(call LogWarn, Test report is stored in $$(strip \ $$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR)))) - $$(if $$(wildcard $$($1_RESULT_FILE)), \ + $$(if $$(wildcard $$($1_RESULT_FILE)), \ $$(eval $1_PASSED := $$(shell $$(AWK) '{ gsub(/[,;]/, ""); \ for (i=1; i<=NF; i++) { if ($$$$i == "passed:") \ print $$$$(i+1) } }' $$($1_RESULT_FILE))) \ @@ -555,7 +565,7 @@ # Now process each test to run and setup a proper make rule $(foreach test, $(TESTS_TO_RUN), \ $(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \ - $(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \ + $(TR) -cs '[a-z][A-Z][0-9]\n' '[_*1000]')) \ $(eval ALL_TEST_IDS += $(TEST_ID)) \ $(if $(call UseCustomTestHandler, $(test)), \ $(eval $(call SetupRunCustomTest, $(TEST_ID), \ @@ -592,6 +602,8 @@ # Create and print a table of the result of all tests run $(RM) $(TEST_SUMMARY).old 2> /dev/null $(MV) $(TEST_SUMMARY) $(TEST_SUMMARY).old 2> /dev/null || true + $(RM) $(TEST_LAST_IDS).old 2> /dev/null + $(MV) $(TEST_LAST_IDS) $(TEST_LAST_IDS).old 2> /dev/null || true $(ECHO) >> $(TEST_SUMMARY) ============================== $(ECHO) >> $(TEST_SUMMARY) Test summary $(ECHO) >> $(TEST_SUMMARY) ============================== @@ -599,8 +611,9 @@ TEST TOTAL PASS FAIL ERROR " " $(foreach test, $(TESTS_TO_RUN), \ $(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \ - $(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \ - $(eval NAME_PATTERN := $(shell $(ECHO) $(test) | $(TR) -c \\n _)) \ + $(TR) -cs '[a-z][A-Z][0-9]\n' '[_*1000]')) \ + $(ECHO) >> $(TEST_LAST_IDS) $(TEST_ID) $(NEWLINE) \ + $(eval NAME_PATTERN := $(shell $(ECHO) $(test) | $(TR) -c '\n' '[_*1000]')) \ $(if $(filter __________________________________________________%, $(NAME_PATTERN)), \ $(eval TEST_NAME := ) \ $(PRINTF) >> $(TEST_SUMMARY) "%2s %-49s\n" " " "$(test)" $(NEWLINE) \ diff -r 40afd72303e9 -r f27aad5782da make/autoconf/generated-configure.sh --- a/make/autoconf/generated-configure.sh Mon Dec 04 09:38:34 2017 -0800 +++ b/make/autoconf/generated-configure.sh Mon Dec 04 10:12:46 2017 -0800 @@ -5159,7 +5159,7 @@ #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1512085548 +DATE_WHEN_GENERATED=1512410983 ############################################################################### # @@ -66263,23 +66263,6 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for which libpng to use" >&5 -$as_echo_n "checking for which libpng to use... " >&6; } - - # default is bundled - DEFAULT_LIBPNG=bundled - # if user didn't specify, use DEFAULT_LIBPNG - if test "x${with_libpng}" = "x"; then - with_libpng=${DEFAULT_LIBPNG} - fi - - if test "x${with_libpng}" = "xbundled"; then - USE_EXTERNAL_LIBPNG=false - PNG_CFLAGS="" - PNG_LIBS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5 -$as_echo "bundled" >&6; } - elif test "x${with_libpng}" = "xsystem"; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PNG" >&5 @@ -66347,6 +66330,23 @@ $as_echo "yes" >&6; } LIBPNG_FOUND=yes fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for which libpng to use" >&5 +$as_echo_n "checking for which libpng to use... " >&6; } + + # default is bundled + DEFAULT_LIBPNG=bundled + # if user didn't specify, use DEFAULT_LIBPNG + if test "x${with_libpng}" = "x"; then + with_libpng=${DEFAULT_LIBPNG} + fi + + if test "x${with_libpng}" = "xbundled"; then + USE_EXTERNAL_LIBPNG=false + PNG_CFLAGS="" + PNG_LIBS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5 +$as_echo "bundled" >&6; } + elif test "x${with_libpng}" = "xsystem"; then if test "x${LIBPNG_FOUND}" = "xyes"; then # PKG_CHECK_MODULES will set PNG_CFLAGS and PNG_LIBS USE_EXTERNAL_LIBPNG=true @@ -66444,6 +66444,40 @@ USE_EXTERNAL_LIBZ=true { $as_echo "$as_me:${as_lineno-$LINENO}: result: system" >&5 $as_echo "system" >&6; } + + if test "x$USE_EXTERNAL_LIBPNG" != "xtrue"; then + # If we use bundled libpng, we must verify that we have a proper zlib. + # For instance zlib-ng has had issues with inflateValidate(). + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for system zlib functionality" >&5 +$as_echo_n "checking for system zlib functionality... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include "zlib.h" +int +main () +{ + + #if ZLIB_VERNUM >= 0x1281 + inflateValidate(NULL, 0); + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not ok" >&5 +$as_echo "not ok" >&6; } + as_fn_error $? "System zlib not working correctly" "$LINENO" 5 + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: system not found" >&5 $as_echo "system not found" >&6; } diff -r 40afd72303e9 -r f27aad5782da make/autoconf/lib-bundled.m4 --- a/make/autoconf/lib-bundled.m4 Mon Dec 04 09:38:34 2017 -0800 +++ b/make/autoconf/lib-bundled.m4 Mon Dec 04 10:12:46 2017 -0800 @@ -113,6 +113,7 @@ AC_ARG_WITH(libpng, [AS_HELP_STRING([--with-libpng], [use libpng from build system or OpenJDK source (system, bundled) @<:@bundled@:>@])]) + PKG_CHECK_MODULES(PNG, libpng, [LIBPNG_FOUND=yes], [LIBPNG_FOUND=no]) AC_MSG_CHECKING([for which libpng to use]) # default is bundled @@ -128,7 +129,6 @@ PNG_LIBS="" AC_MSG_RESULT([bundled]) elif test "x${with_libpng}" = "xsystem"; then - PKG_CHECK_MODULES(PNG, libpng, [LIBPNG_FOUND=yes], [LIBPNG_FOUND=no]) if test "x${LIBPNG_FOUND}" = "xyes"; then # PKG_CHECK_MODULES will set PNG_CFLAGS and PNG_LIBS USE_EXTERNAL_LIBPNG=true @@ -183,6 +183,24 @@ if test "x${ZLIB_FOUND}" = "xyes"; then USE_EXTERNAL_LIBZ=true AC_MSG_RESULT([system]) + + if test "x$USE_EXTERNAL_LIBPNG" != "xtrue"; then + # If we use bundled libpng, we must verify that we have a proper zlib. + # For instance zlib-ng has had issues with inflateValidate(). + AC_MSG_CHECKING([for system zlib functionality]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([#include "zlib.h"], [ + #if ZLIB_VERNUM >= 0x1281 + inflateValidate(NULL, 0); + #endif + ])], + [AC_MSG_RESULT([ok])], + [ + AC_MSG_RESULT([not ok]) + AC_MSG_ERROR([System zlib not working correctly]) + ] + ) + fi else AC_MSG_RESULT([system not found]) AC_MSG_ERROR([--with-zlib=system specified, but no zlib found!]) diff -r 40afd72303e9 -r f27aad5782da make/autoconf/spec.gmk.in --- a/make/autoconf/spec.gmk.in Mon Dec 04 09:38:34 2017 -0800 +++ b/make/autoconf/spec.gmk.in Mon Dec 04 10:12:46 2017 -0800 @@ -293,6 +293,7 @@ FREETYPE_CFLAGS:=@FREETYPE_CFLAGS@ FREETYPE_BUNDLE_LIB_PATH=@FREETYPE_BUNDLE_LIB_PATH@ FREETYPE_LICENSE=@FREETYPE_LICENSE@ +FONTCONFIG_CFLAGS:=@FONTCONFIG_CFLAGS@ CUPS_CFLAGS:=@CUPS_CFLAGS@ ALSA_LIBS:=@ALSA_LIBS@ ALSA_CFLAGS:=@ALSA_CFLAGS@ diff -r 40afd72303e9 -r f27aad5782da src/hotspot/cpu/aarch64/vm_version_aarch64.cpp --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp Mon Dec 04 09:38:34 2017 -0800 +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp Mon Dec 04 10:12:46 2017 -0800 @@ -148,6 +148,16 @@ PrefetchCopyIntervalInBytes = 32760; } + if (AllocatePrefetchDistance !=-1 && (AllocatePrefetchDistance & 7)) { + warning("AllocatePrefetchDistance must be multiple of 8"); + AllocatePrefetchDistance &= ~7; + } + + if (AllocatePrefetchStepSize & 7) { + warning("AllocatePrefetchStepSize must be multiple of 8"); + AllocatePrefetchStepSize &= ~7; + } + if (SoftwarePrefetchHintDistance != -1 && (SoftwarePrefetchHintDistance & 7)) { warning("SoftwarePrefetchHintDistance must be -1, or a multiple of 8"); diff -r 40afd72303e9 -r f27aad5782da src/java.base/share/classes/java/lang/Class.java --- a/src/java.base/share/classes/java/lang/Class.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/share/classes/java/lang/Class.java Mon Dec 04 10:12:46 2017 -0800 @@ -53,12 +53,11 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.StringJoiner; import jdk.internal.HotSpotIntrinsicCandidate; @@ -1771,7 +1770,7 @@ if (sm != null) { checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true); } - return copyFields(privateGetPublicFields(null)); + return copyFields(privateGetPublicFields()); } @@ -3026,7 +3025,7 @@ // Returns an array of "root" fields. These Field objects must NOT // be propagated to the outside world, but must instead be copied // via ReflectionFactory.copyField. - private Field[] privateGetPublicFields(Set> traversedInterfaces) { + private Field[] privateGetPublicFields() { Field[] res; ReflectionData rd = reflectionData(); if (rd != null) { @@ -3034,35 +3033,25 @@ if (res != null) return res; } - // No cached value available; compute value recursively. - // Traverse in correct order for getField(). - List fields = new ArrayList<>(); - if (traversedInterfaces == null) { - traversedInterfaces = new HashSet<>(); - } + // Use a linked hash set to ensure order is preserved and + // fields from common super interfaces are not duplicated + LinkedHashSet fields = new LinkedHashSet<>(); // Local fields - Field[] tmp = privateGetDeclaredFields(true); - addAll(fields, tmp); + addAll(fields, privateGetDeclaredFields(true)); // Direct superinterfaces, recursively - for (Class c : getInterfaces()) { - if (!traversedInterfaces.contains(c)) { - traversedInterfaces.add(c); - addAll(fields, c.privateGetPublicFields(traversedInterfaces)); - } + for (Class si : getInterfaces()) { + addAll(fields, si.privateGetPublicFields()); } // Direct superclass, recursively - if (!isInterface()) { - Class c = getSuperclass(); - if (c != null) { - addAll(fields, c.privateGetPublicFields(traversedInterfaces)); - } + Class sc = getSuperclass(); + if (sc != null) { + addAll(fields, sc.privateGetPublicFields()); } - res = new Field[fields.size()]; - fields.toArray(res); + res = fields.toArray(new Field[0]); if (rd != null) { rd.publicFields = res; } diff -r 40afd72303e9 -r f27aad5782da src/java.base/share/classes/java/lang/System.java --- a/src/java.base/share/classes/java/lang/System.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/share/classes/java/lang/System.java Mon Dec 04 10:12:46 2017 -0800 @@ -63,8 +63,8 @@ import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; import jdk.internal.HotSpotIntrinsicCandidate; -import jdk.internal.misc.JavaLangAccess;; -import jdk.internal.misc.SharedSecrets;; +import jdk.internal.misc.JavaLangAccess; +import jdk.internal.misc.SharedSecrets; import jdk.internal.misc.VM; import jdk.internal.logger.LoggerFinderLoader; import jdk.internal.logger.LazyLoggers; diff -r 40afd72303e9 -r f27aad5782da src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java --- a/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Mon Dec 04 10:12:46 2017 -0800 @@ -38,11 +38,15 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.concurrent.locks.LockSupport; import java.util.function.BiConsumer; import java.util.function.BiPredicate; import java.util.function.Consumer; +import static java.util.concurrent.Flow.Publisher; +import static java.util.concurrent.Flow.Subscriber; +import static java.util.concurrent.Flow.Subscription; /** * A {@link Flow.Publisher} that asynchronously issues submitted @@ -74,6 +78,14 @@ * Flow#defaultBufferSize()} may provide a useful starting point for * choosing a capacity based on expected rates, resources, and usages. * + *

A single SubmissionPublisher may be shared among multiple + * sources. Actions in a source thread prior to publishing an item or + * issuing a signal + * happen-before actions subsequent to the corresponding + * access by each subscriber. But reported estimates of lag and demand + * are designed for use in monitoring, not for synchronization + * control, and may reflect stale or inaccurate views of progress. + * *

Publication methods support different policies about what to do * when buffers are saturated. Method {@link #submit(Object) submit} * blocks until resources are available. This is simplest, but least @@ -158,19 +170,27 @@ * @author Doug Lea * @since 9 */ -public class SubmissionPublisher implements Flow.Publisher, +public class SubmissionPublisher implements Publisher, AutoCloseable { /* * Most mechanics are handled by BufferedSubscription. This class * mainly tracks subscribers and ensures sequentiality, by using - * built-in synchronization locks across public methods. (Using + * built-in synchronization locks across public methods. Using * built-in locks works well in the most typical case in which - * only one thread submits items). + * only one thread submits items. We extend this idea in + * submission methods by detecting single-ownership to reduce + * producer-consumer synchronization strength. */ /** The largest possible power of two array size. */ static final int BUFFER_CAPACITY_LIMIT = 1 << 30; + /** + * Initial buffer capacity used when maxBufferCapacity is + * greater. Must be a power of two. + */ + static final int INITIAL_CAPACITY = 32; + /** Round capacity to power of 2, at most limit. */ static final int roundCapacity(int cap) { int n = cap - 1; @@ -206,7 +226,7 @@ * but we expect that subscribing is much less common than * publishing. Unsubscribing occurs only during traversal loops, * when BufferedSubscription methods return negative values - * signifying that they have been disabled. To reduce + * signifying that they have been closed. To reduce * head-of-line blocking, submit and offer methods first call * BufferedSubscription.offer on each subscriber, and place * saturated ones in retries list (using nextRetry field), and @@ -216,12 +236,16 @@ /** Run status, updated only within locks */ volatile boolean closed; + /** Set true on first call to subscribe, to initialize possible owner */ + boolean subscribed; + /** The first caller thread to subscribe, or null if thread ever changed */ + Thread owner; /** If non-null, the exception in closeExceptionally */ volatile Throwable closedException; // Parameters for constructing BufferedSubscriptions final Executor executor; - final BiConsumer, ? super Throwable> onNextHandler; + final BiConsumer, ? super Throwable> onNextHandler; final int maxBufferCapacity; /** @@ -245,7 +269,7 @@ * positive */ public SubmissionPublisher(Executor executor, int maxBufferCapacity, - BiConsumer, ? super Throwable> handler) { + BiConsumer, ? super Throwable> handler) { if (executor == null) throw new NullPointerException(); if (maxBufferCapacity <= 0) @@ -311,12 +335,19 @@ * @param subscriber the subscriber * @throws NullPointerException if subscriber is null */ - public void subscribe(Flow.Subscriber subscriber) { + public void subscribe(Subscriber subscriber) { if (subscriber == null) throw new NullPointerException(); + int max = maxBufferCapacity; // allocate initial array + Object[] array = new Object[max < INITIAL_CAPACITY ? + max : INITIAL_CAPACITY]; BufferedSubscription subscription = - new BufferedSubscription(subscriber, executor, - onNextHandler, maxBufferCapacity); + new BufferedSubscription(subscriber, executor, onNextHandler, + array, max); synchronized (this) { + if (!subscribed) { + subscribed = true; + owner = Thread.currentThread(); + } for (BufferedSubscription b = clients, pred = null;;) { if (b == null) { Throwable ex; @@ -332,7 +363,7 @@ break; } BufferedSubscription next = b.next; - if (b.isDisabled()) { // remove + if (b.isClosed()) { // remove b.next = null; // detach if (pred == null) clients = next; @@ -351,6 +382,107 @@ } /** + * Common implementation for all three forms of submit and offer. + * Acts as submit if nanos == Long.MAX_VALUE, else offer. + */ + private int doOffer(T item, long nanos, + BiPredicate, ? super T> onDrop) { + if (item == null) throw new NullPointerException(); + int lag = 0; + boolean complete, unowned; + synchronized (this) { + Thread t = Thread.currentThread(), o; + BufferedSubscription b = clients; + if ((unowned = ((o = owner) != t)) && o != null) + owner = null; // disable bias + if (b == null) + complete = closed; + else { + complete = false; + boolean cleanMe = false; + BufferedSubscription retries = null, rtail = null, next; + do { + next = b.next; + int stat = b.offer(item, unowned); + if (stat == 0) { // saturated; add to retry list + b.nextRetry = null; // avoid garbage on exceptions + if (rtail == null) + retries = b; + else + rtail.nextRetry = b; + rtail = b; + } + else if (stat < 0) // closed + cleanMe = true; // remove later + else if (stat > lag) + lag = stat; + } while ((b = next) != null); + + if (retries != null || cleanMe) + lag = retryOffer(item, nanos, onDrop, retries, lag, cleanMe); + } + } + if (complete) + throw new IllegalStateException("Closed"); + else + return lag; + } + + /** + * Helps, (timed) waits for, and/or drops buffers on list; returns + * lag or negative drops (for use in offer). + */ + private int retryOffer(T item, long nanos, + BiPredicate, ? super T> onDrop, + BufferedSubscription retries, int lag, + boolean cleanMe) { + for (BufferedSubscription r = retries; r != null;) { + BufferedSubscription nextRetry = r.nextRetry; + r.nextRetry = null; + if (nanos > 0L) + r.awaitSpace(nanos); + int stat = r.retryOffer(item); + if (stat == 0 && onDrop != null && onDrop.test(r.subscriber, item)) + stat = r.retryOffer(item); + if (stat == 0) + lag = (lag >= 0) ? -1 : lag - 1; + else if (stat < 0) + cleanMe = true; + else if (lag >= 0 && stat > lag) + lag = stat; + r = nextRetry; + } + if (cleanMe) + cleanAndCount(); + return lag; + } + + /** + * Returns current list count after removing closed subscribers. + * Call only while holding lock. Used mainly by retryOffer for + * cleanup. + */ + private int cleanAndCount() { + int count = 0; + BufferedSubscription pred = null, next; + for (BufferedSubscription b = clients; b != null; b = next) { + next = b.next; + if (b.isClosed()) { + b.next = null; + if (pred == null) + clients = next; + else + pred.next = next; + } + else { + pred = b; + ++count; + } + } + return count; + } + + /** * Publishes the given item to each current subscriber by * asynchronously invoking its {@link Flow.Subscriber#onNext(Object) * onNext} method, blocking uninterruptibly while resources for any @@ -373,55 +505,7 @@ * @throws RejectedExecutionException if thrown by Executor */ public int submit(T item) { - if (item == null) throw new NullPointerException(); - int lag = 0; - boolean complete; - synchronized (this) { - complete = closed; - BufferedSubscription b = clients; - if (!complete) { - BufferedSubscription pred = null, r = null, rtail = null; - while (b != null) { - BufferedSubscription next = b.next; - int stat = b.offer(item); - if (stat < 0) { // disabled - b.next = null; - if (pred == null) - clients = next; - else - pred.next = next; - } - else { - if (stat > lag) - lag = stat; - else if (stat == 0) { // place on retry list - b.nextRetry = null; - if (rtail == null) - r = b; - else - rtail.nextRetry = b; - rtail = b; - } - pred = b; - } - b = next; - } - while (r != null) { - BufferedSubscription nextRetry = r.nextRetry; - r.nextRetry = null; - int stat = r.submit(item); - if (stat > lag) - lag = stat; - else if (stat < 0 && clients == r) - clients = r.next; // postpone internal unsubscribes - r = nextRetry; - } - } - } - if (complete) - throw new IllegalStateException("Closed"); - else - return lag; + return doOffer(item, Long.MAX_VALUE, null); } /** @@ -462,8 +546,8 @@ * @throws RejectedExecutionException if thrown by Executor */ public int offer(T item, - BiPredicate, ? super T> onDrop) { - return doOffer(0L, item, onDrop); + BiPredicate, ? super T> onDrop) { + return doOffer(item, 0L, onDrop); } /** @@ -510,71 +594,11 @@ * @throws RejectedExecutionException if thrown by Executor */ public int offer(T item, long timeout, TimeUnit unit, - BiPredicate, ? super T> onDrop) { - return doOffer(unit.toNanos(timeout), item, onDrop); - } - - /** Common implementation for both forms of offer */ - final int doOffer(long nanos, T item, - BiPredicate, ? super T> onDrop) { - if (item == null) throw new NullPointerException(); - int lag = 0, drops = 0; - boolean complete; - synchronized (this) { - complete = closed; - BufferedSubscription b = clients; - if (!complete) { - BufferedSubscription pred = null, r = null, rtail = null; - while (b != null) { - BufferedSubscription next = b.next; - int stat = b.offer(item); - if (stat < 0) { - b.next = null; - if (pred == null) - clients = next; - else - pred.next = next; - } - else { - if (stat > lag) - lag = stat; - else if (stat == 0) { - b.nextRetry = null; - if (rtail == null) - r = b; - else - rtail.nextRetry = b; - rtail = b; - } - else if (stat > lag) - lag = stat; - pred = b; - } - b = next; - } - while (r != null) { - BufferedSubscription nextRetry = r.nextRetry; - r.nextRetry = null; - int stat = (nanos > 0L) - ? r.timedOffer(item, nanos) - : r.offer(item); - if (stat == 0 && onDrop != null && - onDrop.test(r.subscriber, item)) - stat = r.offer(item); - if (stat == 0) - ++drops; - else if (stat > lag) - lag = stat; - else if (stat < 0 && clients == r) - clients = r.next; - r = nextRetry; - } - } - } - if (complete) - throw new IllegalStateException("Closed"); - else - return (drops > 0) ? -drops : lag; + BiPredicate, ? super T> onDrop) { + long nanos = unit.toNanos(timeout); + // distinguishes from untimed (only wrt interrupt policy) + if (nanos == Long.MAX_VALUE) --nanos; + return doOffer(item, nanos, onDrop); } /** @@ -591,6 +615,7 @@ // no need to re-check closed here b = clients; clients = null; + owner = null; closed = true; } while (b != null) { @@ -621,8 +646,9 @@ synchronized (this) { b = clients; if (!closed) { // don't clobber racing close + closedException = error; clients = null; - closedException = error; + owner = null; closed = true; } } @@ -662,18 +688,16 @@ */ public boolean hasSubscribers() { boolean nonEmpty = false; - if (!closed) { - synchronized (this) { - for (BufferedSubscription b = clients; b != null;) { - BufferedSubscription next = b.next; - if (b.isDisabled()) { - b.next = null; - b = clients = next; - } - else { - nonEmpty = true; - break; - } + synchronized (this) { + for (BufferedSubscription b = clients; b != null;) { + BufferedSubscription next = b.next; + if (b.isClosed()) { + b.next = null; + b = clients = next; + } + else { + nonEmpty = true; + break; } } } @@ -686,27 +710,9 @@ * @return the number of current subscribers */ public int getNumberOfSubscribers() { - int count = 0; - if (!closed) { - synchronized (this) { - BufferedSubscription pred = null, next; - for (BufferedSubscription b = clients; b != null; b = next) { - next = b.next; - if (b.isDisabled()) { - b.next = null; - if (pred == null) - clients = next; - else - pred.next = next; - } - else { - pred = b; - ++count; - } - } - } + synchronized (this) { + return cleanAndCount(); } - return count; } /** @@ -734,13 +740,13 @@ * * @return list of current subscribers */ - public List> getSubscribers() { - ArrayList> subs = new ArrayList<>(); + public List> getSubscribers() { + ArrayList> subs = new ArrayList<>(); synchronized (this) { BufferedSubscription pred = null, next; for (BufferedSubscription b = clients; b != null; b = next) { next = b.next; - if (b.isDisabled()) { + if (b.isClosed()) { b.next = null; if (pred == null) clients = next; @@ -761,14 +767,14 @@ * @return true if currently subscribed * @throws NullPointerException if subscriber is null */ - public boolean isSubscribed(Flow.Subscriber subscriber) { + public boolean isSubscribed(Subscriber subscriber) { if (subscriber == null) throw new NullPointerException(); if (!closed) { synchronized (this) { BufferedSubscription pred = null, next; for (BufferedSubscription b = clients; b != null; b = next) { next = b.next; - if (b.isDisabled()) { + if (b.isClosed()) { b.next = null; if (pred == null) clients = next; @@ -872,16 +878,15 @@ } /** Subscriber for method consume */ - private static final class ConsumerSubscriber - implements Flow.Subscriber { + static final class ConsumerSubscriber implements Subscriber { final CompletableFuture status; final Consumer consumer; - Flow.Subscription subscription; + Subscription subscription; ConsumerSubscriber(CompletableFuture status, Consumer consumer) { this.status = status; this.consumer = consumer; } - public final void onSubscribe(Flow.Subscription subscription) { + public final void onSubscribe(Subscription subscription) { this.subscription = subscription; status.whenComplete((v, e) -> subscription.cancel()); if (!status.isDone()) @@ -925,634 +930,534 @@ } /** - * A bounded (ring) buffer with integrated control to start a - * consumer task whenever items are available. The buffer - * algorithm is similar to one used inside ForkJoinPool (see its - * internal documentation for details) specialized for the case of - * at most one concurrent producer and consumer, and power of two - * buffer sizes. This allows methods to operate without locks even - * while supporting resizing, blocking, task-triggering, and - * garbage-free buffers (nulling out elements when consumed), - * although supporting these does impose a bit of overhead - * compared to plain fixed-size ring buffers. - * - * The publisher guarantees a single producer via its lock. We - * ensure in this class that there is at most one consumer. The - * request and cancel methods must be fully thread-safe but are - * coded to exploit the most common case in which they are only - * called by consumers (usually within onNext). + * A resizable array-based ring buffer with integrated control to + * start a consumer task whenever items are available. The buffer + * algorithm is specialized for the case of at most one concurrent + * producer and consumer, and power of two buffer sizes. It relies + * primarily on atomic operations (CAS or getAndSet) at the next + * array slot to put or take an element, at the "tail" and "head" + * indices written only by the producer and consumer respectively. * - * Execution control is managed using the ACTIVE ctl bit. We - * ensure that a task is active when consumable items (and - * usually, SUBSCRIBE, ERROR or COMPLETE signals) are present and - * there is demand (unfilled requests). This is complicated on - * the creation side by the possibility of exceptions when trying - * to execute tasks. These eventually force DISABLED state, but - * sometimes not directly. On the task side, termination (clearing - * ACTIVE) that would otherwise race with producers or request() - * calls uses the CONSUME keep-alive bit to force a recheck. + * We ensure internally that there is at most one active consumer + * task at any given time. The publisher guarantees a single + * producer via its lock. Sync among producers and consumers + * relies on volatile fields "ctl", "demand", and "waiting" (along + * with element access). Other variables are accessed in plain + * mode, relying on outer ordering and exclusion, and/or enclosing + * them within other volatile accesses. Some atomic operations are + * avoided by tracking single threaded ownership by producers (in + * the style of biased locking). * - * The ctl field also manages run state. When DISABLED, no further - * updates are possible. Disabling may be preceded by setting - * ERROR or COMPLETE (or both -- ERROR has precedence), in which - * case the associated Subscriber methods are invoked, possibly - * synchronously if there is no active consumer task (including - * cases where execute() failed). The cancel() method is supported - * by treating as ERROR but suppressing onError signal. + * Execution control and protocol state are managed using field + * "ctl". Methods to subscribe, close, request, and cancel set + * ctl bits (mostly using atomic boolean method getAndBitwiseOr), + * and ensure that a task is running. (The corresponding consumer + * side actions are in method consume.) To avoid starting a new + * task on each action, ctl also includes a keep-alive bit + * (ACTIVE) that is refreshed if needed on producer actions. + * (Maintaining agreement about keep-alives requires most atomic + * updates to be full SC/Volatile strength, which is still much + * cheaper than using one task per item.) Error signals + * additionally null out items and/or fields to reduce termination + * latency. The cancel() method is supported by treating as ERROR + * but suppressing onError signal. * * Support for blocking also exploits the fact that there is only * one possible waiter. ManagedBlocker-compatible control fields * are placed in this class itself rather than in wait-nodes. - * Blocking control relies on the "waiter" field. Producers set - * the field before trying to block, but must then recheck (via - * offer) before parking. Signalling then just unparks and clears - * waiter field. If the producer and/or consumer are using a - * ForkJoinPool, the producer attempts to help run consumer tasks - * via ForkJoinPool.helpAsyncBlocker before blocking. + * Blocking control relies on the "waiting" and "waiter" + * fields. Producers set them before trying to block. Signalling + * unparks and clears fields. If the producer and/or consumer are + * using a ForkJoinPool, the producer attempts to help run + * consumer tasks via ForkJoinPool.helpAsyncBlocker before + * blocking. * - * This class uses @Contended and heuristic field declaration - * ordering to reduce false-sharing-based memory contention among - * instances of BufferedSubscription, but it does not currently - * attempt to avoid memory contention among buffers. This field - * and element packing can hurt performance especially when each - * publisher has only one client operating at a high rate. - * Addressing this may require allocating substantially more space - * than users expect. + * Usages of this class may encounter any of several forms of + * memory contention. We try to ameliorate across them without + * unduly impacting footprints in low-contention usages where it + * isn't needed. Buffer arrays start out small and grow only as + * needed. The class uses @Contended and heuristic field + * declaration ordering to reduce false-sharing memory contention + * across instances of BufferedSubscription (as in, multiple + * subscribers per publisher). We additionally segregate some + * fields that would otherwise nearly always encounter cache line + * contention among producers and consumers. To reduce contention + * across time (vs space), consumers only periodically update + * other fields (see method takeItems), at the expense of possibly + * staler reporting of lags and demand (bounded at 12.5% == 1/8 + * capacity) and possibly more atomic operations. + * + * Other forms of imbalance and slowdowns can occur during startup + * when producer and consumer methods are compiled and/or memory + * is allocated at different rates. This is ameliorated by + * artificially subdividing some consumer methods, including + * isolation of all subscriber callbacks. This code also includes + * typical power-of-two array screening idioms to avoid compilers + * generating traps, along with the usual SSA-based inline + * assignment coding style. Also, all methods and fields have + * default visibility to simplify usage by callers. */ @SuppressWarnings("serial") @jdk.internal.vm.annotation.Contended - private static final class BufferedSubscription - implements Flow.Subscription, ForkJoinPool.ManagedBlocker { - // Order-sensitive field declarations - long timeout; // > 0 if timed wait - volatile long demand; // # unfilled requests - int maxCapacity; // reduced on OOME - int putStat; // offer result for ManagedBlocker + static final class BufferedSubscription + implements Subscription, ForkJoinPool.ManagedBlocker { + long timeout; // Long.MAX_VALUE if untimed wait + int head; // next position to take + int tail; // next position to put + final int maxCapacity; // max buffer size volatile int ctl; // atomic run state flags - volatile int head; // next position to take - int tail; // next position to put - Object[] array; // buffer: null if disabled - Flow.Subscriber subscriber; // null if disabled - Executor executor; // null if disabled - BiConsumer, ? super Throwable> onNextHandler; - volatile Throwable pendingError; // holds until onError issued - volatile Thread waiter; // blocked producer thread - T putItem; // for offer within ManagedBlocker + Object[] array; // buffer + final Subscriber subscriber; + final BiConsumer, ? super Throwable> onNextHandler; + Executor executor; // null on error + Thread waiter; // blocked producer thread + Throwable pendingError; // holds until onError issued BufferedSubscription next; // used only by publisher BufferedSubscription nextRetry; // used only by publisher - // ctl values - static final int ACTIVE = 0x01; // consumer task active - static final int CONSUME = 0x02; // keep-alive for consumer task - static final int DISABLED = 0x04; // final state - static final int ERROR = 0x08; // signal onError then disable - static final int SUBSCRIBE = 0x10; // signal onSubscribe - static final int COMPLETE = 0x20; // signal onComplete when done + @jdk.internal.vm.annotation.Contended("c") // segregate + volatile long demand; // # unfilled requests + @jdk.internal.vm.annotation.Contended("c") + volatile int waiting; // nonzero if producer blocked + + // ctl bit values + static final int CLOSED = 0x01; // if set, other bits ignored + static final int ACTIVE = 0x02; // keep-alive for consumer task + static final int REQS = 0x04; // (possibly) nonzero demand + static final int ERROR = 0x08; // issues onError when noticed + static final int COMPLETE = 0x10; // issues onComplete when done + static final int RUN = 0x20; // task is or will be running + static final int OPEN = 0x40; // true after subscribe static final long INTERRUPTED = -1L; // timeout vs interrupt sentinel - /** - * Initial buffer capacity used when maxBufferCapacity is - * greater. Must be a power of two. - */ - static final int DEFAULT_INITIAL_CAP = 32; - - BufferedSubscription(Flow.Subscriber subscriber, + BufferedSubscription(Subscriber subscriber, Executor executor, - BiConsumer, + BiConsumer, ? super Throwable> onNextHandler, + Object[] array, int maxBufferCapacity) { this.subscriber = subscriber; this.executor = executor; this.onNextHandler = onNextHandler; + this.array = array; this.maxCapacity = maxBufferCapacity; - this.array = new Object[maxBufferCapacity < DEFAULT_INITIAL_CAP ? - (maxBufferCapacity < 2 ? // at least 2 slots - 2 : maxBufferCapacity) : - DEFAULT_INITIAL_CAP]; + } + + // Wrappers for some VarHandle methods + + final boolean weakCasCtl(int cmp, int val) { + return CTL.weakCompareAndSet(this, cmp, val); } - final boolean isDisabled() { - return ctl == DISABLED; + final int getAndBitwiseOrCtl(int bits) { + return (int)CTL.getAndBitwiseOr(this, bits); } + final long subtractDemand(int k) { + long n = (long)(-k); + return n + (long)DEMAND.getAndAdd(this, n); + } + + final boolean casDemand(long cmp, long val) { + return DEMAND.compareAndSet(this, cmp, val); + } + + // Utilities used by SubmissionPublisher + /** - * Returns estimated number of buffered items, or -1 if - * disabled. - */ - final int estimateLag() { - int n; - return (ctl == DISABLED) ? -1 : ((n = tail - head) > 0) ? n : 0; - } - - /** - * Tries to add item and start consumer task if necessary. - * @return -1 if disabled, 0 if dropped, else estimated lag + * Returns true if closed (consumer task may still be running). */ - final int offer(T item) { - int h = head, t = tail, cap, size, stat; - Object[] a = array; - if (a != null && (cap = a.length) > 0 && cap >= (size = t + 1 - h)) { - a[(cap - 1) & t] = item; // relaxed writes OK - tail = t + 1; - stat = size; - } - else - stat = growAndAdd(a, item); - return (stat > 0 && - (ctl & (ACTIVE | CONSUME)) != (ACTIVE | CONSUME)) ? - startOnOffer(stat) : stat; + final boolean isClosed() { + return (ctl & CLOSED) != 0; } /** - * Tries to create or expand buffer, then adds item if possible. + * Returns estimated number of buffered items, or negative if + * closed. + */ + final int estimateLag() { + int c = ctl, n = tail - head; + return ((c & CLOSED) != 0) ? -1 : (n < 0) ? 0 : n; + } + + // Methods for submitting items + + /** + * Tries to add item and start consumer task if necessary. + * @return negative if closed, 0 if saturated, else estimated lag */ - private int growAndAdd(Object[] a, T item) { - boolean alloc; - int cap, stat; - if ((ctl & (ERROR | DISABLED)) != 0) { - cap = 0; - stat = -1; - alloc = false; - } - else if (a == null || (cap = a.length) <= 0) { - cap = 0; - stat = 1; - alloc = true; - } - else { - VarHandle.fullFence(); // recheck - int h = head, t = tail, size = t + 1 - h; - if (cap >= size) { - a[(cap - 1) & t] = item; + final int offer(T item, boolean unowned) { + Object[] a; + int stat = 0, cap = ((a = array) == null) ? 0 : a.length; + int t = tail, i = t & (cap - 1), n = t + 1 - head; + if (cap > 0) { + boolean added; + if (n >= cap && cap < maxCapacity) // resize + added = growAndoffer(item, a, t); + else if (n >= cap || unowned) // need volatile CAS + added = QA.compareAndSet(a, i, null, item); + else { // can use release mode + QA.setRelease(a, i, item); + added = true; + } + if (added) { tail = t + 1; - stat = size; - alloc = false; - } - else if (cap >= maxCapacity) { - stat = 0; // cannot grow - alloc = false; - } - else { - stat = cap + 1; - alloc = true; + stat = n; } } - if (alloc) { - int newCap = (cap > 0) ? cap << 1 : 1; - if (newCap <= cap) - stat = 0; - else { - Object[] newArray = null; - try { - newArray = new Object[newCap]; - } catch (Throwable ex) { // try to cope with OOME - } - if (newArray == null) { - if (cap > 0) - maxCapacity = cap; // avoid continuous failure - stat = 0; - } - else { - array = newArray; - int t = tail; - int newMask = newCap - 1; - if (a != null && cap > 0) { - int mask = cap - 1; - for (int j = head; j != t; ++j) { - int k = j & mask; - Object x = QA.getAcquire(a, k); - if (x != null && // races with consumer - QA.compareAndSet(a, k, x, null)) - newArray[j & newMask] = x; - } - } - newArray[t & newMask] = item; - tail = t + 1; - } + return startOnOffer(stat); + } + + /** + * Tries to expand buffer and add item, returning true on + * success. Currently fails only if out of memory. + */ + final boolean growAndoffer(T item, Object[] a, int t) { + int cap = 0, newCap = 0; + Object[] newArray = null; + if (a != null && (cap = a.length) > 0 && (newCap = cap << 1) > 0) { + try { + newArray = new Object[newCap]; + } catch (OutOfMemoryError ex) { } } + if (newArray == null) + return false; + else { // take and move items + int newMask = newCap - 1; + newArray[t-- & newMask] = item; + for (int mask = cap - 1, k = mask; k >= 0; --k) { + Object x = QA.getAndSet(a, t & mask, null); + if (x == null) + break; // already consumed + else + newArray[t-- & newMask] = x; + } + array = newArray; + VarHandle.releaseFence(); // release array and slots + return true; + } + } + + /** + * Version of offer for retries (no resize or bias) + */ + final int retryOffer(T item) { + Object[] a; + int stat = 0, t = tail, h = head, cap; + if ((a = array) != null && (cap = a.length) > 0 && + QA.compareAndSet(a, (cap - 1) & t, null, item)) + stat = (tail = t + 1) - h; + return startOnOffer(stat); + } + + /** + * Tries to start consumer task after offer. + * @return negative if now closed, else argument + */ + final int startOnOffer(int stat) { + int c; // start or keep alive if requests exist and not active + if (((c = ctl) & (REQS | ACTIVE)) == REQS && + ((c = getAndBitwiseOrCtl(RUN | ACTIVE)) & (RUN | CLOSED)) == 0) + tryStart(); + else if ((c & CLOSED) != 0) + stat = -1; return stat; } /** - * Spins/helps/blocks while offer returns 0. Called only if - * initial offer return 0. - */ - final int submit(T item) { - int stat; - if ((stat = offer(item)) == 0) { - putItem = item; - timeout = 0L; - putStat = 0; - ForkJoinPool.helpAsyncBlocker(executor, this); - if ((stat = putStat) == 0) { - try { - ForkJoinPool.managedBlock(this); - } catch (InterruptedException ie) { - timeout = INTERRUPTED; - } - stat = putStat; - } - if (timeout < 0L) - Thread.currentThread().interrupt(); - } - return stat; - } - - /** - * Timeout version; similar to submit. - */ - final int timedOffer(T item, long nanos) { - int stat; - if ((stat = offer(item)) == 0 && (timeout = nanos) > 0L) { - putItem = item; - putStat = 0; - ForkJoinPool.helpAsyncBlocker(executor, this); - if ((stat = putStat) == 0) { - try { - ForkJoinPool.managedBlock(this); - } catch (InterruptedException ie) { - timeout = INTERRUPTED; - } - stat = putStat; - } - if (timeout < 0L) - Thread.currentThread().interrupt(); - } - return stat; - } - - /** - * Tries to start consumer task after offer. - * @return -1 if now disabled, else argument + * Tries to start consumer task. Sets error state on failure. */ - private int startOnOffer(int stat) { - for (;;) { - Executor e; int c; - if ((c = ctl) == DISABLED || (e = executor) == null) { - stat = -1; - break; - } - else if ((c & ACTIVE) != 0) { // ensure keep-alive - if ((c & CONSUME) != 0 || - CTL.compareAndSet(this, c, c | CONSUME)) - break; - } - else if (demand == 0L || tail == head) - break; - else if (CTL.compareAndSet(this, c, c | (ACTIVE | CONSUME))) { - try { - e.execute(new ConsumerTask(this)); - break; - } catch (RuntimeException | Error ex) { // back out - do {} while (((c = ctl) & DISABLED) == 0 && - (c & ACTIVE) != 0 && - !CTL.weakCompareAndSet - (this, c, c & ~ACTIVE)); - throw ex; - } - } - } - return stat; - } - - private void signalWaiter(Thread w) { - waiter = null; - LockSupport.unpark(w); // release producer - } - - /** - * Nulls out most fields, mainly to avoid garbage retention - * until publisher unsubscribes, but also to help cleanly stop - * upon error by nulling required components. - */ - private void detach() { - Thread w = waiter; - executor = null; - subscriber = null; - pendingError = null; - signalWaiter(w); - } - - /** - * Issues error signal, asynchronously if a task is running, - * else synchronously. - */ - final void onError(Throwable ex) { - for (int c;;) { - if (((c = ctl) & (ERROR | DISABLED)) != 0) - break; - else if ((c & ACTIVE) != 0) { - pendingError = ex; - if (CTL.compareAndSet(this, c, c | ERROR)) - break; // cause consumer task to exit - } - else if (CTL.compareAndSet(this, c, DISABLED)) { - Flow.Subscriber s = subscriber; - if (s != null && ex != null) { - try { - s.onError(ex); - } catch (Throwable ignore) { - } - } - detach(); - break; - } + final void tryStart() { + try { + Executor e; + ConsumerTask task = new ConsumerTask(this); + if ((e = executor) != null) // skip if disabled on error + e.execute(task); + } catch (RuntimeException | Error ex) { + getAndBitwiseOrCtl(ERROR | CLOSED); + throw ex; } } + // Signals to consumer tasks + /** - * Tries to start consumer task upon a signal or request; - * disables on failure. + * Sets the given control bits, starting task if not running or closed. + * @param bits state bits, assumed to include RUN but not CLOSED */ - private void startOrDisable() { - Executor e; - if ((e = executor) != null) { // skip if already disabled - try { - e.execute(new ConsumerTask(this)); - } catch (Throwable ex) { // back out and force signal - for (int c;;) { - if ((c = ctl) == DISABLED || (c & ACTIVE) == 0) - break; - if (CTL.compareAndSet(this, c, c & ~ACTIVE)) { - onError(ex); - break; - } - } - } - } + final void startOnSignal(int bits) { + if ((ctl & bits) != bits && + (getAndBitwiseOrCtl(bits) & (RUN | CLOSED)) == 0) + tryStart(); + } + + final void onSubscribe() { + startOnSignal(RUN | ACTIVE); } final void onComplete() { - for (int c;;) { - if ((c = ctl) == DISABLED) - break; - if (CTL.compareAndSet(this, c, - c | (ACTIVE | CONSUME | COMPLETE))) { - if ((c & ACTIVE) == 0) - startOrDisable(); - break; - } - } + startOnSignal(RUN | ACTIVE | COMPLETE); } - final void onSubscribe() { - for (int c;;) { - if ((c = ctl) == DISABLED) - break; - if (CTL.compareAndSet(this, c, - c | (ACTIVE | CONSUME | SUBSCRIBE))) { - if ((c & ACTIVE) == 0) - startOrDisable(); - break; - } + final void onError(Throwable ex) { + int c; Object[] a; // to null out buffer on async error + if (ex != null) + pendingError = ex; // races are OK + if (((c = getAndBitwiseOrCtl(ERROR | RUN | ACTIVE)) & CLOSED) == 0) { + if ((c & RUN) == 0) + tryStart(); + else if ((a = array) != null) + Arrays.fill(a, null); } } - /** - * Causes consumer task to exit if active (without reporting - * onError unless there is already a pending error), and - * disables. - */ - public void cancel() { - for (int c;;) { - if ((c = ctl) == DISABLED) - break; - else if ((c & ACTIVE) != 0) { - if (CTL.compareAndSet(this, c, - c | (CONSUME | ERROR))) - break; - } - else if (CTL.compareAndSet(this, c, DISABLED)) { - detach(); - break; - } - } + public final void cancel() { + onError(null); } - /** - * Adds to demand and possibly starts task. - */ - public void request(long n) { + public final void request(long n) { if (n > 0L) { for (;;) { - long prev = demand, d; - if ((d = prev + n) < prev) // saturate - d = Long.MAX_VALUE; - if (DEMAND.compareAndSet(this, prev, d)) { - for (int c, h;;) { - if ((c = ctl) == DISABLED) - break; - else if ((c & ACTIVE) != 0) { - if ((c & CONSUME) != 0 || - CTL.compareAndSet(this, c, c | CONSUME)) - break; - } - else if ((h = head) != tail) { - if (CTL.compareAndSet(this, c, - c | (ACTIVE|CONSUME))) { - startOrDisable(); - break; - } - } - else if (head == h && tail == h) - break; // else stale - if (demand == 0L) - break; - } + long p = demand, d = p + n; // saturate + if (casDemand(p, d < p ? Long.MAX_VALUE : d)) break; - } } + startOnSignal(RUN | ACTIVE | REQS); } else onError(new IllegalArgumentException( "non-positive subscription request")); } - public final boolean isReleasable() { // for ManagedBlocker - T item = putItem; - if (item != null) { - if ((putStat = offer(item)) == 0) - return false; - putItem = null; - } - return true; - } - - public final boolean block() { // for ManagedBlocker - T item = putItem; - if (item != null) { - putItem = null; - long nanos = timeout; - long deadline = (nanos > 0L) ? System.nanoTime() + nanos : 0L; - while ((putStat = offer(item)) == 0) { - if (Thread.interrupted()) { - timeout = INTERRUPTED; - if (nanos > 0L) - break; - } - else if (nanos > 0L && - (nanos = deadline - System.nanoTime()) <= 0L) - break; - else if (waiter == null) - waiter = Thread.currentThread(); - else { - if (nanos > 0L) - LockSupport.parkNanos(this, nanos); - else - LockSupport.park(this); - waiter = null; - } - } - } - waiter = null; - return true; - } + // Consumer task actions /** - * Consumer loop, called from ConsumerTask, or indirectly - * when helping during submit. + * Consumer loop, called from ConsumerTask, or indirectly when + * helping during submit. */ final void consume() { - Flow.Subscriber s; - int h = head; - if ((s = subscriber) != null) { // else disabled - for (;;) { - long d = demand; - int c; Object[] a; int n, i; Object x; Thread w; - if (((c = ctl) & (ERROR | SUBSCRIBE | DISABLED)) != 0) { - if (!checkControl(s, c)) - break; - } - else if ((a = array) == null || h == tail || - (n = a.length) == 0 || - (x = QA.getAcquire(a, i = (n - 1) & h)) == null) { - if (!checkEmpty(s, c)) - break; + Subscriber s; + if ((s = subscriber) != null) { // hoist checks + subscribeOnOpen(s); + long d = demand; + for (int h = head, t = tail;;) { + int c, taken; boolean empty; + if (((c = ctl) & ERROR) != 0) { + closeOnError(s, null); + break; } - else if (d == 0L) { - if (!checkDemand(c)) - break; + else if ((taken = takeItems(s, d, h)) > 0) { + head = h += taken; + d = subtractDemand(taken); + } + else if ((empty = (t == h)) && (c & COMPLETE) != 0) { + closeOnComplete(s); // end of stream + break; } - else if (((c & CONSUME) != 0 || - CTL.compareAndSet(this, c, c | CONSUME)) && - QA.compareAndSet(a, i, x, null)) { - HEAD.setRelease(this, ++h); - DEMAND.getAndAdd(this, -1L); - if ((w = waiter) != null) - signalWaiter(w); - try { - @SuppressWarnings("unchecked") T y = (T) x; - s.onNext(y); - } catch (Throwable ex) { - handleOnNext(s, ex); - } + else if ((d = demand) == 0L && (c & REQS) != 0) + weakCasCtl(c, c & ~REQS); // exhausted demand + else if (d != 0L && (c & REQS) == 0) + weakCasCtl(c, c | REQS); // new demand + else if (t == (t = tail) && (empty || d == 0L)) { + int bit = ((c & ACTIVE) != 0) ? ACTIVE : RUN; + if (weakCasCtl(c, c & ~bit) && bit == RUN) + break; // un-keep-alive or exit } } } } /** - * Responds to control events in consume(). + * Consumes some items until unavailable or bound or error. + * + * @param s subscriber + * @param d current demand + * @param h current head + * @return number taken */ - private boolean checkControl(Flow.Subscriber s, int c) { - boolean stat = true; - if ((c & SUBSCRIBE) != 0) { - if (CTL.compareAndSet(this, c, c & ~SUBSCRIBE)) { - try { - if (s != null) - s.onSubscribe(this); - } catch (Throwable ex) { - onError(ex); - } + final int takeItems(Subscriber s, long d, int h) { + Object[] a; + int k = 0, cap; + if ((a = array) != null && (cap = a.length) > 0) { + int m = cap - 1, b = (m >>> 3) + 1; // min(1, cap/8) + int n = (d < (long)b) ? (int)d : b; + for (; k < n; ++h, ++k) { + Object x = QA.getAndSet(a, h & m, null); + if (waiting != 0) + signalWaiter(); + if (x == null) + break; + else if (!consumeNext(s, x)) + break; } } - else if ((c & ERROR) != 0) { - Throwable ex = pendingError; - ctl = DISABLED; // no need for CAS - if (ex != null) { // null if errorless cancel - try { - if (s != null) - s.onError(ex); - } catch (Throwable ignore) { - } - } - } - else { - detach(); - stat = false; - } - return stat; + return k; } - /** - * Responds to apparent emptiness in consume(). - */ - private boolean checkEmpty(Flow.Subscriber s, int c) { - boolean stat = true; - if (head == tail) { - if ((c & CONSUME) != 0) - CTL.compareAndSet(this, c, c & ~CONSUME); - else if ((c & COMPLETE) != 0) { - if (CTL.compareAndSet(this, c, DISABLED)) { - try { - if (s != null) - s.onComplete(); - } catch (Throwable ignore) { - } - } - } - else if (CTL.compareAndSet(this, c, c & ~ACTIVE)) - stat = false; + final boolean consumeNext(Subscriber s, Object x) { + try { + @SuppressWarnings("unchecked") T y = (T) x; + if (s != null) + s.onNext(y); + return true; + } catch (Throwable ex) { + handleOnNext(s, ex); + return false; } - return stat; - } - - /** - * Responds to apparent zero demand in consume(). - */ - private boolean checkDemand(int c) { - boolean stat = true; - if (demand == 0L) { - if ((c & CONSUME) != 0) - CTL.compareAndSet(this, c, c & ~CONSUME); - else if (CTL.compareAndSet(this, c, c & ~ACTIVE)) - stat = false; - } - return stat; } /** * Processes exception in Subscriber.onNext. */ - private void handleOnNext(Flow.Subscriber s, Throwable ex) { - BiConsumer, ? super Throwable> h; - if ((h = onNextHandler) != null) { - try { + final void handleOnNext(Subscriber s, Throwable ex) { + BiConsumer, ? super Throwable> h; + try { + if ((h = onNextHandler) != null) h.accept(s, ex); - } catch (Throwable ignore) { + } catch (Throwable ignore) { + } + closeOnError(s, ex); + } + + /** + * Issues subscriber.onSubscribe if this is first signal. + */ + final void subscribeOnOpen(Subscriber s) { + if ((ctl & OPEN) == 0 && (getAndBitwiseOrCtl(OPEN) & OPEN) == 0) + consumeSubscribe(s); + } + + final void consumeSubscribe(Subscriber s) { + try { + if (s != null) // ignore if disabled + s.onSubscribe(this); + } catch (Throwable ex) { + closeOnError(s, ex); + } + } + + /** + * Issues subscriber.onComplete unless already closed. + */ + final void closeOnComplete(Subscriber s) { + if ((getAndBitwiseOrCtl(CLOSED) & CLOSED) == 0) + consumeComplete(s); + } + + final void consumeComplete(Subscriber s) { + try { + if (s != null) + s.onComplete(); + } catch (Throwable ignore) { + } + } + + /** + * Issues subscriber.onError, and unblocks producer if needed. + */ + final void closeOnError(Subscriber s, Throwable ex) { + if ((getAndBitwiseOrCtl(ERROR | CLOSED) & CLOSED) == 0) { + if (ex == null) + ex = pendingError; + pendingError = null; // detach + executor = null; // suppress racing start calls + signalWaiter(); + consumeError(s, ex); + } + } + + final void consumeError(Subscriber s, Throwable ex) { + try { + if (ex != null && s != null) + s.onError(ex); + } catch (Throwable ignore) { + } + } + + // Blocking support + + /** + * Unblocks waiting producer. + */ + final void signalWaiter() { + Thread w; + waiting = 0; + if ((w = waiter) != null) + LockSupport.unpark(w); + } + + /** + * Returns true if closed or space available. + * For ManagedBlocker. + */ + public final boolean isReleasable() { + Object[] a; int cap; + return ((ctl & CLOSED) != 0 || + ((a = array) != null && (cap = a.length) > 0 && + QA.getAcquire(a, (cap - 1) & tail) == null)); + } + + /** + * Helps or blocks until timeout, closed, or space available. + */ + final void awaitSpace(long nanos) { + if (!isReleasable()) { + ForkJoinPool.helpAsyncBlocker(executor, this); + if (!isReleasable()) { + timeout = nanos; + try { + ForkJoinPool.managedBlock(this); + } catch (InterruptedException ie) { + timeout = INTERRUPTED; + } + if (timeout == INTERRUPTED) + Thread.currentThread().interrupt(); } } - onError(ex); + } + + /** + * Blocks until closed, space available or timeout. + * For ManagedBlocker. + */ + public final boolean block() { + long nanos = timeout; + boolean timed = (nanos < Long.MAX_VALUE); + long deadline = timed ? System.nanoTime() + nanos : 0L; + while (!isReleasable()) { + if (Thread.interrupted()) { + timeout = INTERRUPTED; + if (timed) + break; + } + else if (timed && (nanos = deadline - System.nanoTime()) <= 0L) + break; + else if (waiter == null) + waiter = Thread.currentThread(); + else if (waiting == 0) + waiting = 1; + else if (timed) + LockSupport.parkNanos(this, nanos); + else + LockSupport.park(this); + } + waiter = null; + waiting = 0; + return true; } // VarHandle mechanics - private static final VarHandle CTL; - private static final VarHandle TAIL; - private static final VarHandle HEAD; - private static final VarHandle DEMAND; - private static final VarHandle QA; + static final VarHandle CTL; + static final VarHandle DEMAND; + static final VarHandle QA; static { try { MethodHandles.Lookup l = MethodHandles.lookup(); CTL = l.findVarHandle(BufferedSubscription.class, "ctl", int.class); - TAIL = l.findVarHandle(BufferedSubscription.class, "tail", - int.class); - HEAD = l.findVarHandle(BufferedSubscription.class, "head", - int.class); DEMAND = l.findVarHandle(BufferedSubscription.class, "demand", long.class); QA = MethodHandles.arrayElementVarHandle(Object[].class); diff -r 40afd72303e9 -r f27aad5782da src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Mon Dec 04 10:12:46 2017 -0800 @@ -422,8 +422,8 @@ * @return {@code true} if interrupted while waiting */ final boolean acquireQueued(final Node node, long arg) { + boolean interrupted = false; try { - boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { @@ -431,12 +431,13 @@ p.next = null; // help GC return interrupted; } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - interrupted = true; + if (shouldParkAfterFailedAcquire(p, node)) + interrupted |= parkAndCheckInterrupt(); } } catch (Throwable t) { cancelAcquire(node); + if (interrupted) + selfInterrupt(); throw t; } } @@ -510,8 +511,8 @@ */ private void doAcquireShared(long arg) { final Node node = addWaiter(Node.SHARED); + boolean interrupted = false; try { - boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head) { @@ -519,18 +520,18 @@ if (r >= 0) { setHeadAndPropagate(node, r); p.next = null; // help GC - if (interrupted) - selfInterrupt(); return; } } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - interrupted = true; + if (shouldParkAfterFailedAcquire(p, node)) + interrupted |= parkAndCheckInterrupt(); } } catch (Throwable t) { cancelAcquire(node); throw t; + } finally { + if (interrupted) + selfInterrupt(); } } diff -r 40afd72303e9 -r f27aad5782da src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Mon Dec 04 10:12:46 2017 -0800 @@ -505,7 +505,7 @@ * * @return the predecessor of this node */ - final Node predecessor() throws NullPointerException { + final Node predecessor() { Node p = prev; if (p == null) throw new NullPointerException(); @@ -902,8 +902,8 @@ * @return {@code true} if interrupted while waiting */ final boolean acquireQueued(final Node node, int arg) { + boolean interrupted = false; try { - boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { @@ -911,12 +911,13 @@ p.next = null; // help GC return interrupted; } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - interrupted = true; + if (shouldParkAfterFailedAcquire(p, node)) + interrupted |= parkAndCheckInterrupt(); } } catch (Throwable t) { cancelAcquire(node); + if (interrupted) + selfInterrupt(); throw t; } } @@ -990,8 +991,8 @@ */ private void doAcquireShared(int arg) { final Node node = addWaiter(Node.SHARED); + boolean interrupted = false; try { - boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head) { @@ -999,18 +1000,18 @@ if (r >= 0) { setHeadAndPropagate(node, r); p.next = null; // help GC - if (interrupted) - selfInterrupt(); return; } } - if (shouldParkAfterFailedAcquire(p, node) && - parkAndCheckInterrupt()) - interrupted = true; + if (shouldParkAfterFailedAcquire(p, node)) + interrupted |= parkAndCheckInterrupt(); } } catch (Throwable t) { cancelAcquire(node); throw t; + } finally { + if (interrupted) + selfInterrupt(); } } diff -r 40afd72303e9 -r f27aad5782da src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java --- a/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Mon Dec 04 10:12:46 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, 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 @@ -33,7 +33,7 @@ import java.nio.channels.FileChannel; import java.nio.channels.SeekableByteChannel; import java.nio.file.*; -import java.nio.file.DirectoryStream.Filter;; +import java.nio.file.DirectoryStream.Filter; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributeView; import java.nio.file.attribute.FileAttribute; diff -r 40afd72303e9 -r f27aad5782da src/java.base/share/classes/sun/security/tools/keytool/Main.java --- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java Mon Dec 04 10:12:46 2017 -0800 @@ -2746,12 +2746,12 @@ if (rfc) { dumpCert(cert, out); } else { - out.println("Certificate #" + i++); + out.println("Certificate #" + i); out.println("===================================="); printX509Cert((X509Certificate)cert, out); out.println(); } - checkWeak(oneInMany(rb.getString("the.certificate"), i, chain.size()), cert); + checkWeak(oneInMany(rb.getString("the.certificate"), i++, chain.size()), cert); } catch (Exception e) { if (debug) { e.printStackTrace(); diff -r 40afd72303e9 -r f27aad5782da src/java.base/share/native/libzip/Deflater.c --- a/src/java.base/share/native/libzip/Deflater.c Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/share/native/libzip/Deflater.c Mon Dec 04 10:12:46 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -164,17 +164,14 @@ res = deflateParams(strm, level, strategy); (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - switch (res) { case Z_OK: (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE); + case Z_BUF_ERROR: this_off += this_len - strm->avail_in; (*env)->SetIntField(env, this, offID, this_off); (*env)->SetIntField(env, this, lenID, strm->avail_in); return (jint) (len - strm->avail_out); - case Z_BUF_ERROR: - (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE); - return 0; default: JNU_ThrowInternalError(env, strm->msg); return 0; @@ -203,19 +200,17 @@ res = deflate(strm, finish ? Z_FINISH : flush); (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - switch (res) { case Z_STREAM_END: (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); /* fall through */ case Z_OK: + case Z_BUF_ERROR: this_off += this_len - strm->avail_in; (*env)->SetIntField(env, this, offID, this_off); (*env)->SetIntField(env, this, lenID, strm->avail_in); return len - strm->avail_out; - case Z_BUF_ERROR: - return 0; - default: + default: JNU_ThrowInternalError(env, strm->msg); return 0; } diff -r 40afd72303e9 -r f27aad5782da src/java.base/share/native/libzip/zlib/deflate.c --- a/src/java.base/share/native/libzip/zlib/deflate.c Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/share/native/libzip/zlib/deflate.c Mon Dec 04 10:12:46 2017 -0800 @@ -505,8 +505,6 @@ s->pending = 0; s->pending_out = s->pending_buf; - s->high_water = 0; /* reset to its inital value 0 */ - if (s->wrap < 0) { s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ } @@ -520,7 +518,7 @@ s->wrap == 2 ? crc32(0L, Z_NULL, 0) : #endif adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; + s->last_flush = -2; _tr_init(s); @@ -613,7 +611,7 @@ func = configuration_table[s->level].func; if ((strategy != s->strategy || func != configuration_table[level].func) && - s->high_water) { + s->last_flush != -2) { /* Flush the last buffer: */ int err = deflate(strm, Z_BLOCK); if (err == Z_STREAM_ERROR) diff -r 40afd72303e9 -r f27aad5782da src/java.base/share/native/libzip/zlib/patches/ChangeLog_java --- a/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java Mon Dec 04 10:12:46 2017 -0800 @@ -93,4 +93,6 @@ s->status = #ifdef GZIP +(7) deflate.c undo (6), replaced withe the official zlib repo fix see#305/#f969409 + diff -r 40afd72303e9 -r f27aad5782da src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java --- a/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Mon Dec 04 10:12:46 2017 -0800 @@ -45,41 +45,33 @@ ExtendedSocketOptions.getInstance(); protected void setOption(SocketOption name, T value) throws IOException { - if (!extendedOptions.isOptionSupported(name)) { - if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) { - super.setOption(name, value); + if (isClosed()) { + throw new SocketException("Socket closed"); + } + if (supportedOptions().contains(name)) { + if (extendedOptions.isOptionSupported(name)) { + extendedOptions.setOption(fd, name, value); } else { - if (supportedOptions().contains(name)) { - super.setOption(name, value); - } else { - throw new UnsupportedOperationException("unsupported option"); - } + super.setOption(name, value); } } else { - if (isClosed()) { - throw new SocketException("Socket closed"); - } - extendedOptions.setOption(fd, name, value); + throw new UnsupportedOperationException("unsupported option"); } } @SuppressWarnings("unchecked") protected T getOption(SocketOption name) throws IOException { - if (!extendedOptions.isOptionSupported(name)) { - if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) { - return super.getOption(name); + if (isClosed()) { + throw new SocketException("Socket closed"); + } + if (supportedOptions().contains(name)) { + if (extendedOptions.isOptionSupported(name)) { + return (T) extendedOptions.getOption(fd, name); } else { - if (supportedOptions().contains(name)) { - return super.getOption(name); - } else { - throw new UnsupportedOperationException("unsupported option"); - } + return super.getOption(name); } } else { - if (isClosed()) { - throw new SocketException("Socket closed"); - } - return (T) extendedOptions.getOption(fd, name); + throw new UnsupportedOperationException("unsupported option"); } } diff -r 40afd72303e9 -r f27aad5782da src/java.base/unix/classes/java/net/PlainSocketImpl.java --- a/src/java.base/unix/classes/java/net/PlainSocketImpl.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.base/unix/classes/java/net/PlainSocketImpl.java Mon Dec 04 10:12:46 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2017, 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 @@ -58,58 +58,57 @@ ExtendedSocketOptions.getInstance(); protected void setOption(SocketOption name, T value) throws IOException { - if (!extendedOptions.isOptionSupported(name)) { - if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) { - super.setOption(name, value); + if (isClosedOrPending()) { + throw new SocketException("Socket closed"); + } + if (supportedOptions().contains(name)) { + if (extendedOptions.isOptionSupported(name)) { + extendedOptions.setOption(fd, name, value); } else { - if (supportedOptions().contains(name)) { - super.setOption(name, value); - } else { - throw new UnsupportedOperationException("unsupported option"); - } + super.setOption(name, value); } } else { - if (getSocket() == null) { - throw new UnsupportedOperationException("unsupported option"); - } - if (isClosedOrPending()) { - throw new SocketException("Socket closed"); - } - extendedOptions.setOption(fd, name, value); + throw new UnsupportedOperationException("unsupported option"); } } @SuppressWarnings("unchecked") protected T getOption(SocketOption name) throws IOException { - if (!extendedOptions.isOptionSupported(name)) { - if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) { - return super.getOption(name); + if (isClosedOrPending()) { + throw new SocketException("Socket closed"); + } + if (supportedOptions().contains(name)) { + if (extendedOptions.isOptionSupported(name)) { + return (T) extendedOptions.getOption(fd, name); } else { - if (supportedOptions().contains(name)) { - return super.getOption(name); - } else { - throw new UnsupportedOperationException("unsupported option"); - } + return super.getOption(name); } } else { - if (getSocket() == null) { - throw new UnsupportedOperationException("unsupported option"); - } - if (isClosedOrPending()) { - throw new SocketException("Socket closed"); - } - return (T) extendedOptions.getOption(fd, name); + throw new UnsupportedOperationException("unsupported option"); } } protected Set> supportedOptions() { HashSet> options = new HashSet<>(super.supportedOptions()); - if (getSocket() != null) { - options.addAll(extendedOptions.options()); - } + addExtSocketOptions(extendedOptions.options(), options); return options; } + private void addExtSocketOptions(Set> extOptions, + Set> options) { + extOptions.forEach((option) -> { + if (option.name().equals("SO_FLOW_SLA")) { + // SO_FLOW_SLA is Solaris specific option which is not applicable + // for ServerSockets. + // getSocket() will always return null for server socket + if (getSocket() != null) { + options.add(option); + } + } else { + options.add(option); + } + }); + } protected void socketSetOption(int opt, boolean b, Object val) throws SocketException { if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) { diff -r 40afd72303e9 -r f27aad5782da src/java.desktop/share/classes/sun/awt/FontDescriptor.java --- a/src/java.desktop/share/classes/sun/awt/FontDescriptor.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.desktop/share/classes/sun/awt/FontDescriptor.java Mon Dec 04 10:12:46 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, 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,7 +26,7 @@ import java.io.ByteArrayOutputStream; import java.io.OutputStreamWriter; -import java.io.IOException;; +import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; diff -r 40afd72303e9 -r f27aad5782da src/java.security.jgss/share/native/libj2gss/GSSLibStub.c --- a/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c Mon Dec 04 09:38:34 2017 -0800 +++ b/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c Mon Dec 04 10:12:46 2017 -0800 @@ -1410,7 +1410,6 @@ checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_getMic]"); return NULL; } - contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); qop = (gss_qop_t) jqop; initGSSBuffer(env, jmsg, &msg); if ((*env)->ExceptionCheck(env)) { diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Mon Dec 04 10:12:46 2017 -0800 @@ -115,7 +115,7 @@ values = EnumSet.noneOf(LintCategory.class); Source source = Source.instance(context); - if (source.compareTo(Source.JDK1_9) >= 0) { + if (source.compareTo(Source.JDK9) >= 0) { values.add(LintCategory.DEP_ANN); } values.add(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC); diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java Mon Dec 04 10:12:46 2017 -0800 @@ -31,7 +31,12 @@ import static javax.lang.model.SourceVersion.*; import com.sun.tools.javac.jvm.Target; +import com.sun.tools.javac.resources.CompilerProperties.Errors; +import com.sun.tools.javac.resources.CompilerProperties.Fragments; import com.sun.tools.javac.util.*; +import com.sun.tools.javac.util.JCDiagnostic.Error; +import com.sun.tools.javac.util.JCDiagnostic.Fragment; + import static com.sun.tools.javac.main.Option.*; /** The source language version accepted. @@ -59,22 +64,22 @@ /** 1.5 introduced generics, attributes, foreach, boxing, static import, * covariant return, enums, varargs, et al. */ - JDK1_5("1.5"), + JDK5("5"), /** 1.6 reports encoding problems as errors instead of warnings. */ - JDK1_6("1.6"), + JDK6("6"), /** 1.7 introduced try-with-resources, multi-catch, string switch, etc. */ - JDK1_7("1.7"), + JDK7("7"), /** 1.8 lambda expressions and default methods. */ - JDK1_8("1.8"), + JDK8("8"), /** 1.9 modularity. */ - JDK1_9("1.9"), + JDK9("9"), /** 1.10 covers the to be determined language features that will be added in JDK 10. */ - JDK1_10("1.10"); + JDK10("10"); private static final Context.Key sourceKey = new Context.Key<>(); @@ -97,19 +102,19 @@ for (Source s : values()) { tab.put(s.name, s); } - tab.put("5", JDK1_5); // Make 5 an alias for 1.5 - tab.put("6", JDK1_6); // Make 6 an alias for 1.6 - tab.put("7", JDK1_7); // Make 7 an alias for 1.7 - tab.put("8", JDK1_8); // Make 8 an alias for 1.8 - tab.put("9", JDK1_9); // Make 9 an alias for 1.9 - tab.put("10", JDK1_10); // Make 10 an alias for 1.10 + tab.put("1.5", JDK5); // Make 5 an alias for 1.5 + tab.put("1.6", JDK6); // Make 6 an alias for 1.6 + tab.put("1.7", JDK7); // Make 7 an alias for 1.7 + tab.put("1.8", JDK8); // Make 8 an alias for 1.8 + tab.put("1.9", JDK9); // Make 9 an alias for 1.9 + tab.put("1.10", JDK10); // Make 10 an alias for 1.10 } private Source(String name) { this.name = name; } - public static final Source MIN = Source.JDK1_6; + public static final Source MIN = Source.JDK6; private static final Source MAX = values()[values().length - 1]; @@ -120,114 +125,108 @@ } public Target requiredTarget() { - if (this.compareTo(JDK1_10) >= 0) return Target.JDK1_10; - if (this.compareTo(JDK1_9) >= 0) return Target.JDK1_9; - if (this.compareTo(JDK1_8) >= 0) return Target.JDK1_8; - if (this.compareTo(JDK1_7) >= 0) return Target.JDK1_7; - if (this.compareTo(JDK1_6) >= 0) return Target.JDK1_6; - if (this.compareTo(JDK1_5) >= 0) return Target.JDK1_5; + if (this.compareTo(JDK10) >= 0) return Target.JDK1_10; + if (this.compareTo(JDK9) >= 0) return Target.JDK1_9; + if (this.compareTo(JDK8) >= 0) return Target.JDK1_8; + if (this.compareTo(JDK7) >= 0) return Target.JDK1_7; + if (this.compareTo(JDK6) >= 0) return Target.JDK1_6; + if (this.compareTo(JDK5) >= 0) return Target.JDK1_5; if (this.compareTo(JDK1_4) >= 0) return Target.JDK1_4; return Target.JDK1_1; } - public boolean allowDiamond() { - return compareTo(JDK1_7) >= 0; - } - public boolean allowMulticatch() { - return compareTo(JDK1_7) >= 0; - } - public boolean allowImprovedRethrowAnalysis() { - return compareTo(JDK1_7) >= 0; - } - public boolean allowImprovedCatchAnalysis() { - return compareTo(JDK1_7) >= 0; - } - public boolean allowModules() { - return compareTo(JDK1_9) >= 0; - } - public boolean allowTryWithResources() { - return compareTo(JDK1_7) >= 0; - } - public boolean allowEffectivelyFinalVariablesInTryWithResources() { - return compareTo(JDK1_9) >= 0; - } - public boolean allowBinaryLiterals() { - return compareTo(JDK1_7) >= 0; - } - public boolean allowUnderscoresInLiterals() { - return compareTo(JDK1_7) >= 0; - } - public boolean allowStringsInSwitch() { - return compareTo(JDK1_7) >= 0; - } - public boolean allowDeprecationOnImport() { - return compareTo(JDK1_9) < 0; - } - public boolean allowSimplifiedVarargs() { - return compareTo(JDK1_7) >= 0; - } - public boolean allowObjectToPrimitiveCast() { - return compareTo(JDK1_7) >= 0; - } - public boolean enforceThisDotInit() { - return compareTo(JDK1_7) >= 0; - } - public boolean allowPoly() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowLambda() { - return compareTo(JDK1_8) >= 0; + /** + * Models a feature of the Java programming language. Each feature can be associated with a + * minimum source level, a maximum source level and a diagnostic fragment describing the feature, + * which is used to generate error messages of the kind {@code feature XYZ not supported in source N}. + */ + public enum Feature { + + DIAMOND(JDK7, Fragments.FeatureDiamond, DiagKind.NORMAL), + MULTICATCH(JDK7, Fragments.FeatureMulticatch, DiagKind.PLURAL), + IMPROVED_RETHROW_ANALYSIS(JDK7), + IMPROVED_CATCH_ANALYSIS(JDK7), + MODULES(JDK9, Fragments.FeatureModules, DiagKind.PLURAL), + TRY_WITH_RESOURCES(JDK7, Fragments.FeatureTryWithResources, DiagKind.NORMAL), + EFFECTIVELY_FINAL_VARIABLES_IN_TRY_WITH_RESOURCES(JDK9, Fragments.FeatureVarInTryWithResources, DiagKind.PLURAL), + BINARY_LITERALS(JDK7, Fragments.FeatureBinaryLit, DiagKind.PLURAL), + UNDERSCORES_IN_LITERALS(JDK7, Fragments.FeatureUnderscoreLit, DiagKind.PLURAL), + STRINGS_IN_SWITCH(JDK7, Fragments.FeatureStringSwitch, DiagKind.PLURAL), + DEPRECATION_ON_IMPORT(MIN, JDK9), + SIMPLIFIED_VARARGS(JDK7), + OBJECT_TO_PRIMITIVE_CAST(JDK7), + ENFORCE_THIS_DOT_INIT(JDK7), + POLY(JDK8), + LAMBDA(JDK8, Fragments.FeatureLambda, DiagKind.PLURAL), + METHOD_REFERENCES(JDK8, Fragments.FeatureMethodReferences, DiagKind.PLURAL), + DEFAULT_METHODS(JDK8, Fragments.FeatureDefaultMethods, DiagKind.PLURAL), + STATIC_INTERFACE_METHODS(JDK8, Fragments.FeatureStaticIntfMethods, DiagKind.PLURAL), + STATIC_INTERFACE_METHODS_INVOKE(JDK8, Fragments.FeatureStaticIntfMethodInvoke, DiagKind.PLURAL), + STRICT_METHOD_CLASH_CHECK(JDK8), + EFFECTIVELY_FINAL_IN_INNER_CLASSES(JDK8), + TYPE_ANNOTATIONS(JDK8, Fragments.FeatureTypeAnnotations, DiagKind.PLURAL), + ANNOTATIONS_AFTER_TYPE_PARAMS(JDK8, Fragments.FeatureAnnotationsAfterTypeParams, DiagKind.PLURAL), + REPEATED_ANNOTATIONS(JDK8, Fragments.FeatureRepeatableAnnotations, DiagKind.PLURAL), + INTERSECTION_TYPES_IN_CAST(JDK8, Fragments.FeatureIntersectionTypesInCast, DiagKind.PLURAL), + GRAPH_INFERENCE(JDK8), + FUNCTIONAL_INTERFACE_MOST_SPECIFIC(JDK8), + POST_APPLICABILITY_VARARGS_ACCESS_CHECK(JDK8), + MAP_CAPTURES_TO_BOUNDS(MIN, JDK7), + PRIVATE_SAFE_VARARGS(JDK9), + DIAMOND_WITH_ANONYMOUS_CLASS_CREATION(JDK9, Fragments.FeatureDiamondAndAnonClass, DiagKind.NORMAL), + UNDERSCORE_IDENTIFIER(MIN, JDK8), + PRIVATE_INTERFACE_METHODS(JDK9, Fragments.FeaturePrivateIntfMethods, DiagKind.PLURAL), + LOCAL_VARIABLE_TYPE_INFERENCE(JDK10); + + enum DiagKind { + NORMAL, + PLURAL; + } + + private final Source minLevel; + private final Source maxLevel; + private final Fragment optFragment; + private final DiagKind optKind; + + Feature(Source minLevel) { + this(minLevel, null, null); + } + + Feature(Source minLevel, Fragment optFragment, DiagKind optKind) { + this(minLevel, MAX, optFragment, optKind); + } + + Feature(Source minLevel, Source maxLevel) { + this(minLevel, maxLevel, null, null); + } + + Feature(Source minLevel, Source maxLevel, Fragment optFragment, DiagKind optKind) { + this.minLevel = minLevel; + this.maxLevel = maxLevel; + this.optFragment = optFragment; + this.optKind = optKind; + } + + public boolean allowedInSource(Source source) { + return source.compareTo(minLevel) >= 0 && + source.compareTo(maxLevel) <= 0; + } + + public Fragment fragment(String sourceName) { + Assert.checkNonNull(optFragment); + return optKind == DiagKind.NORMAL ? + Fragments.FeatureNotSupportedInSource(optFragment, sourceName, minLevel.name) : + Fragments.FeatureNotSupportedInSourcePlural(optFragment, sourceName, minLevel.name); + } + + public Error error(String sourceName) { + Assert.checkNonNull(optFragment); + return optKind == DiagKind.NORMAL ? + Errors.FeatureNotSupportedInSource(optFragment, sourceName, minLevel.name) : + Errors.FeatureNotSupportedInSourcePlural(optFragment, sourceName, minLevel.name); + } } - public boolean allowMethodReferences() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowDefaultMethods() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowStaticInterfaceMethods() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowStrictMethodClashCheck() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowEffectivelyFinalInInnerClasses() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowTypeAnnotations() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowAnnotationsAfterTypeParams() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowRepeatedAnnotations() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowIntersectionTypesInCast() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowGraphInference() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowFunctionalInterfaceMostSpecific() { - return compareTo(JDK1_8) >= 0; - } - public boolean allowPostApplicabilityVarargsAccessCheck() { - return compareTo(JDK1_8) >= 0; - } - public boolean mapCapturesToBounds() { - return compareTo(JDK1_8) < 0; - } - public boolean allowPrivateSafeVarargs() { - return compareTo(JDK1_9) >= 0; - } - public boolean allowDiamondWithAnonymousClassCreation() { - return compareTo(JDK1_9) >= 0; - } - public boolean allowUnderscoreIdentifier() { - return compareTo(JDK1_8) <= 0; - } - public boolean allowPrivateInterfaceMethods() { return compareTo(JDK1_9) >= 0; } - public boolean allowLocalVariableTypeInference() { return compareTo(JDK1_10) >= 0; } + public static SourceVersion toSourceVersion(Source source) { switch(source) { case JDK1_2: @@ -236,17 +235,17 @@ return RELEASE_3; case JDK1_4: return RELEASE_4; - case JDK1_5: + case JDK5: return RELEASE_5; - case JDK1_6: + case JDK6: return RELEASE_6; - case JDK1_7: + case JDK7: return RELEASE_7; - case JDK1_8: + case JDK8: return RELEASE_8; - case JDK1_9: + case JDK9: return RELEASE_9; - case JDK1_10: + case JDK10: return RELEASE_10; default: return null; diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Mon Dec 04 10:12:46 2017 -0800 @@ -35,6 +35,7 @@ import javax.lang.model.element.ElementVisitor; import com.sun.tools.javac.code.Scope.WriteableScope; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.Completer; import com.sun.tools.javac.code.Symbol.CompletionFailure; @@ -468,7 +469,7 @@ scope.enter(errSymbol); Source source = Source.instance(context); - if (source.allowModules()) { + if (Feature.MODULES.allowedInSource(source)) { java_base = enterModule(names.java_base); //avoid completing java.base during the Symtab initialization java_base.completer = Completer.NULL_COMPLETER; diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Mon Dec 04 10:12:46 2017 -0800 @@ -41,6 +41,7 @@ import com.sun.tools.javac.code.Attribute.RetentionPolicy; import com.sun.tools.javac.code.Lint.LintCategory; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; import com.sun.tools.javac.code.TypeMetadata.Entry.Kind; import com.sun.tools.javac.comp.AttrContext; @@ -113,9 +114,9 @@ syms = Symtab.instance(context); names = Names.instance(context); Source source = Source.instance(context); - allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast(); - allowDefaultMethods = source.allowDefaultMethods(); - mapCapturesToBounds = source.mapCapturesToBounds(); + allowObjectToPrimitiveCast = Feature.OBJECT_TO_PRIMITIVE_CAST.allowedInSource(source); + allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source); + mapCapturesToBounds = Feature.MAP_CAPTURES_TO_BOUNDS.allowedInSource(source); chk = Check.instance(context); enter = Enter.instance(context); capturedName = names.fromString(""); diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Mon Dec 04 10:12:46 2017 -0800 @@ -29,6 +29,7 @@ import com.sun.source.tree.LambdaExpressionTree; import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext; @@ -128,7 +129,7 @@ String findOpt = options.get("find"); //parse modes Source source = Source.instance(context); - allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation(); + allowDiamondWithAnonymousClassCreation = Feature.DIAMOND_WITH_ANONYMOUS_CLASS_CREATION.allowedInSource(source); analyzerModes = AnalyzerMode.getAnalyzerModes(findOpt, source); } @@ -137,17 +138,17 @@ * the {@code -XDfind} option. */ enum AnalyzerMode { - DIAMOND("diamond", Source::allowDiamond), - LAMBDA("lambda", Source::allowLambda), - METHOD("method", Source::allowGraphInference), - LOCAL("local", Source::allowLocalVariableTypeInference); + DIAMOND("diamond", Feature.DIAMOND), + LAMBDA("lambda", Feature.LAMBDA), + METHOD("method", Feature.GRAPH_INFERENCE), + LOCAL("local", Feature.LOCAL_VARIABLE_TYPE_INFERENCE); final String opt; - final Predicate sourceFilter; + final Feature feature; - AnalyzerMode(String opt, Predicate sourceFilter) { + AnalyzerMode(String opt, Feature feature) { this.opt = opt; - this.sourceFilter = sourceFilter; + this.feature = feature; } /** @@ -168,7 +169,7 @@ for (AnalyzerMode mode : values()) { if (modes.contains(mode.opt)) { res.add(mode); - } else if (modes.contains("-" + mode.opt) || !mode.sourceFilter.test(source)) { + } else if (modes.contains("-" + mode.opt) || !mode.feature.allowedInSource(source)) { res.remove(mode); } } diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Mon Dec 04 10:12:46 2017 -0800 @@ -30,10 +30,12 @@ import com.sun.tools.javac.code.Attribute.TypeCompound; import com.sun.tools.javac.code.Kinds.KindSelector; import com.sun.tools.javac.code.Scope.WriteableScope; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.TypeMetadata.Entry.Kind; import com.sun.tools.javac.comp.Check.CheckContext; import com.sun.tools.javac.resources.CompilerProperties.Errors; +import com.sun.tools.javac.resources.CompilerProperties.Fragments; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.TreeInfo; @@ -121,7 +123,7 @@ theUnfinishedDefaultValue = new Attribute.Error(syms.errType); Source source = Source.instance(context); - allowRepeatedAnnos = source.allowRepeatedAnnotations(); + allowRepeatedAnnos = Feature.REPEATED_ANNOTATIONS.allowedInSource(source); sourceName = source.name; blockCount = 1; @@ -344,7 +346,7 @@ if (annotated.containsKey(a.type.tsym)) { if (!allowRepeatedAnnos) { - log.error(DiagnosticFlag.SOURCE_LEVEL, a.pos(), Errors.RepeatableAnnotationsNotSupportedInSource(sourceName)); + log.error(DiagnosticFlag.SOURCE_LEVEL, a.pos(), Feature.REPEATED_ANNOTATIONS.error(sourceName)); } ListBuffer l = annotated.get(a.type.tsym); l = l.append(c); diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Mon Dec 04 10:12:46 2017 -0800 @@ -38,6 +38,7 @@ import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Scope.WriteableScope; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.TypeMetadata.Annotations; @@ -150,12 +151,12 @@ Options options = Options.instance(context); Source source = Source.instance(context); - allowStringsInSwitch = source.allowStringsInSwitch(); - allowPoly = source.allowPoly(); - allowTypeAnnos = source.allowTypeAnnotations(); - allowLambda = source.allowLambda(); - allowDefaultMethods = source.allowDefaultMethods(); - allowStaticInterfaceMethods = source.allowStaticInterfaceMethods(); + allowStringsInSwitch = Feature.STRINGS_IN_SWITCH.allowedInSource(source); + allowPoly = Feature.POLY.allowedInSource(source); + allowTypeAnnos = Feature.TYPE_ANNOTATIONS.allowedInSource(source); + allowLambda = Feature.LAMBDA.allowedInSource(source); + allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source); + allowStaticInterfaceMethods = Feature.STATIC_INTERFACE_METHODS.allowedInSource(source); sourceName = source.name; useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning"); @@ -1392,7 +1393,7 @@ boolean enumSwitch = (seltype.tsym.flags() & Flags.ENUM) != 0; boolean stringSwitch = types.isSameType(seltype, syms.stringType); if (stringSwitch && !allowStringsInSwitch) { - log.error(DiagnosticFlag.SOURCE_LEVEL, tree.selector.pos(), Errors.StringSwitchNotSupportedInSource(sourceName)); + log.error(DiagnosticFlag.SOURCE_LEVEL, tree.selector.pos(), Feature.STRINGS_IN_SWITCH.error(sourceName)); } if (!enumSwitch && !stringSwitch) seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType); @@ -3667,7 +3668,7 @@ } if (!allowStaticInterfaceMethods && sitesym.isInterface() && sym.isStatic() && sym.kind == MTH) { - log.error(DiagnosticFlag.SOURCE_LEVEL, tree.pos(), Errors.StaticIntfMethodInvokeNotSupportedInSource(sourceName)); + log.error(DiagnosticFlag.SOURCE_LEVEL, tree.pos(), Feature.STATIC_INTERFACE_METHODS_INVOKE.error(sourceName)); } } else if (sym.kind != ERR && (sym.flags() & STATIC) != 0 && diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Mon Dec 04 10:12:46 2017 -0800 @@ -33,6 +33,7 @@ import com.sun.tools.javac.code.Attribute.Compound; import com.sun.tools.javac.code.Directive.ExportsDirective; import com.sun.tools.javac.code.Directive.RequiresDirective; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata; import com.sun.tools.javac.jvm.*; import com.sun.tools.javac.resources.CompilerProperties.Errors; @@ -127,11 +128,6 @@ fileManager = context.get(JavaFileManager.class); source = Source.instance(context); - allowSimplifiedVarargs = source.allowSimplifiedVarargs(); - allowDefaultMethods = source.allowDefaultMethods(); - allowStrictMethodClashCheck = source.allowStrictMethodClashCheck(); - allowPrivateSafeVarargs = source.allowPrivateSafeVarargs(); - allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation(); warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers"); Target target = Target.instance(context); @@ -156,26 +152,6 @@ deferredLintHandler = DeferredLintHandler.instance(context); } - /** Switch: simplified varargs enabled? - */ - boolean allowSimplifiedVarargs; - - /** Switch: default methods enabled? - */ - boolean allowDefaultMethods; - - /** Switch: should unrelated return types trigger a method clash? - */ - boolean allowStrictMethodClashCheck; - - /** Switch: can the @SafeVarargs annotation be applied to private methods? - */ - boolean allowPrivateSafeVarargs; - - /** Switch: can diamond inference be used in anonymous instance creation ? - */ - boolean allowDiamondWithAnonymousClassCreation; - /** Character for synthetic names */ char syntheticNameChar; @@ -256,7 +232,7 @@ * @param pos Position to be used for error reporting. */ void warnUnsafeVararg(DiagnosticPosition pos, String key, Object... args) { - if (lint.isEnabled(LintCategory.VARARGS) && allowSimplifiedVarargs) + if (lint.isEnabled(LintCategory.VARARGS) && Feature.SIMPLIFIED_VARARGS.allowedInSource(source)) log.warning(LintCategory.VARARGS, pos, key, args); } @@ -814,9 +790,9 @@ t.isErroneous()) { return checkClassType(tree.clazz.pos(), t, true); } else { - if (tree.def != null && !allowDiamondWithAnonymousClassCreation) { + if (tree.def != null && !Feature.DIAMOND_WITH_ANONYMOUS_CLASS_CREATION.allowedInSource(source)) { log.error(DiagnosticFlag.SOURCE_LEVEL, tree.clazz.pos(), - Errors.CantApplyDiamond1(t, Fragments.DiamondAndAnonClassNotSupportedInSource(source.name))); + Errors.CantApplyDiamond1(t, Feature.DIAMOND_WITH_ANONYMOUS_CLASS_CREATION.fragment(source.name))); } if (t.tsym.type.getTypeArguments().isEmpty()) { log.error(tree.clazz.pos(), @@ -906,7 +882,7 @@ void checkVarargsMethodDecl(Env env, JCMethodDecl tree) { MethodSymbol m = tree.sym; - if (!allowSimplifiedVarargs) return; + if (!Feature.SIMPLIFIED_VARARGS.allowedInSource(source)) return; boolean hasTrustMeAnno = m.attribute(syms.trustMeType.tsym) != null; Type varargElemType = null; if (m.isVarArgs()) { @@ -914,7 +890,7 @@ } if (hasTrustMeAnno && !isTrustMeAllowedOnMethod(m)) { if (varargElemType != null) { - JCDiagnostic msg = allowPrivateSafeVarargs ? + JCDiagnostic msg = Feature.PRIVATE_SAFE_VARARGS.allowedInSource(source) ? diags.fragment(Fragments.VarargsTrustmeOnVirtualVarargs(m)) : diags.fragment(Fragments.VarargsTrustmeOnVirtualVarargsFinalOnly(m)); log.error(tree, @@ -942,7 +918,7 @@ return (s.flags() & VARARGS) != 0 && (s.isConstructor() || (s.flags() & (STATIC | FINAL | - (allowPrivateSafeVarargs ? PRIVATE : 0) )) != 0); + (Feature.PRIVATE_SAFE_VARARGS.allowedInSource(source) ? PRIVATE : 0) )) != 0); } Type checkLocalVarType(DiagnosticPosition pos, Type t, Name name) { @@ -1019,7 +995,7 @@ if (useVarargs) { Type argtype = owntype.getParameterTypes().last(); if (!types.isReifiable(argtype) && - (!allowSimplifiedVarargs || + (!Feature.SIMPLIFIED_VARARGS.allowedInSource(source) || sym.baseSymbol().attribute(syms.trustMeType.tsym) == null || !isTrustMeAllowedOnMethod(sym))) { warnUnchecked(env.tree.pos(), @@ -2489,7 +2465,7 @@ if (m2 == m1) continue; //if (i) the signature of 'sym' is not a subsignature of m1 (seen as //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error - if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) && + if (!types.isSubSignature(sym.type, types.memberType(site, m2), Feature.STRICT_METHOD_CLASH_CHECK.allowedInSource(source)) && types.hasSameArgs(m2.erasure(types), m1.erasure(types))) { sym.flags_field |= CLASH; if (m1 == sym) { @@ -2534,7 +2510,7 @@ for (Symbol s : types.membersClosure(site, true).getSymbolsByName(sym.name, cf)) { //if (i) the signature of 'sym' is not a subsignature of m1 (seen as //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error - if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) { + if (!types.isSubSignature(sym.type, types.memberType(site, s), Feature.STRICT_METHOD_CLASH_CHECK.allowedInSource(source))) { if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) { log.error(pos, Errors.NameClashSameErasureNoHide(sym, sym.location(), s, s.location())); @@ -2634,7 +2610,7 @@ void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site, MethodSymbol msym1, MethodSymbol msym2) { if (msym1 != msym2 && - allowDefaultMethods && + Feature.DEFAULT_METHODS.allowedInSource(source) && lint.isEnabled(LintCategory.OVERLOADS) && (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 && (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) { diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Mon Dec 04 10:12:46 2017 -0800 @@ -32,6 +32,7 @@ import com.sun.source.tree.LambdaExpressionTree.BodyKind; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Scope.WriteableScope; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.resources.CompilerProperties.Warnings; import com.sun.tools.javac.tree.*; @@ -291,10 +292,10 @@ rs = Resolve.instance(context); diags = JCDiagnostic.Factory.instance(context); Source source = Source.instance(context); - allowImprovedRethrowAnalysis = source.allowImprovedRethrowAnalysis(); - allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis(); - allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses(); - enforceThisDotInit = source.enforceThisDotInit(); + allowImprovedRethrowAnalysis = Feature.IMPROVED_RETHROW_ANALYSIS.allowedInSource(source); + allowImprovedCatchAnalysis = Feature.IMPROVED_CATCH_ANALYSIS.allowedInSource(source); + allowEffectivelyFinalInInnerClasses = Feature.EFFECTIVELY_FINAL_IN_INNER_CLASSES.allowedInSource(source); + enforceThisDotInit = Feature.ENFORCE_THIS_DOT_INIT.allowedInSource(source); } /** diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Mon Dec 04 10:12:46 2017 -0800 @@ -25,6 +25,7 @@ package com.sun.tools.javac.comp; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Type.UndetVar.UndetVarListener; import com.sun.tools.javac.code.Types.TypeMapping; import com.sun.tools.javac.comp.Attr.CheckMode; @@ -116,7 +117,8 @@ log = Log.instance(context); inferenceException = new InferenceException(diags); Options options = Options.instance(context); - allowGraphInference = Source.instance(context).allowGraphInference() + Source source = Source.instance(context); + allowGraphInference = Feature.GRAPH_INFERENCE.allowedInSource(source) && options.isUnset("useLegacyInference"); dependenciesFolder = options.get("debug.dumpInferenceGraphsTo"); pendingGraphs = List.nil(); diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Mon Dec 04 10:12:46 2017 -0800 @@ -66,6 +66,7 @@ import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.ModuleFinder; import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.Completer; @@ -185,7 +186,7 @@ types = Types.instance(context); fileManager = context.get(JavaFileManager.class); source = Source.instance(context); - allowModules = source.allowModules(); + allowModules = Feature.MODULES.allowedInSource(source); Options options = Options.instance(context); allowAccessIntoSystem = options.isUnset(Option.RELEASE); diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Dec 04 10:12:46 2017 -0800 @@ -28,6 +28,7 @@ import com.sun.tools.javac.api.Formattable.LocalizedString; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Scope.WriteableScope; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.comp.Attr.ResultInfo; @@ -137,15 +138,15 @@ verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options); Target target = Target.instance(context); allowMethodHandles = target.hasMethodHandles(); - allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific(); - allowLocalVariableTypeInference = source.allowLocalVariableTypeInference(); + allowFunctionalInterfaceMostSpecific = Feature.FUNCTIONAL_INTERFACE_MOST_SPECIFIC.allowedInSource(source); + allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source); checkVarargsAccessAfterResolution = - source.allowPostApplicabilityVarargsAccessCheck(); + Feature.POST_APPLICABILITY_VARARGS_ACCESS_CHECK.allowedInSource(source); polymorphicSignatureScope = WriteableScope.create(syms.noSymbol); inapplicableMethodException = new InapplicableMethodException(diags); - allowModules = source.allowModules(); + allowModules = Feature.MODULES.allowedInSource(source); } /** error symbols, which are returned when resolution fails diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java Mon Dec 04 10:12:46 2017 -0800 @@ -29,6 +29,7 @@ import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Attribute.TypeCompound; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.tree.*; @@ -94,8 +95,8 @@ make = TreeMaker.instance(context); resolve = Resolve.instance(context); Source source = Source.instance(context); - allowInterfaceBridges = source.allowDefaultMethods(); - allowGraphInference = source.allowGraphInference(); + allowInterfaceBridges = Feature.DEFAULT_METHODS.allowedInSource(source); + allowGraphInference = Feature.GRAPH_INFERENCE.allowedInSource(source); annotate = Annotate.instance(context); attr = Attr.instance(context); } diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Mon Dec 04 10:12:46 2017 -0800 @@ -37,6 +37,7 @@ import com.sun.tools.javac.code.Scope.NamedImportScope; import com.sun.tools.javac.code.Scope.StarImportScope; import com.sun.tools.javac.code.Scope.WriteableScope; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.util.*; @@ -137,8 +138,8 @@ typeEnvs = TypeEnvs.instance(context); dependencies = Dependencies.instance(context); Source source = Source.instance(context); - allowTypeAnnos = source.allowTypeAnnotations(); - allowDeprecationOnImport = source.allowDeprecationOnImport(); + allowTypeAnnos = Feature.TYPE_ANNOTATIONS.allowedInSource(source); + allowDeprecationOnImport = Feature.DEPRECATION_ON_IMPORT.allowedInSource(source); } /** Switch: support type annotations. diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Mon Dec 04 10:12:46 2017 -0800 @@ -42,6 +42,7 @@ import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.comp.Annotate; import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter; import com.sun.tools.javac.code.*; @@ -246,8 +247,8 @@ verbose = options.isSet(Option.VERBOSE); Source source = Source.instance(context); - allowSimplifiedVarargs = source.allowSimplifiedVarargs(); - allowModules = source.allowModules(); + allowSimplifiedVarargs = Feature.SIMPLIFIED_VARARGS.allowedInSource(source); + allowModules = Feature.MODULES.allowedInSource(source); saveParameterNames = options.isSet(PARAMETERS); diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Mon Dec 04 10:12:46 2017 -0800 @@ -54,6 +54,7 @@ import com.sun.tools.doclint.DocLint; import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.file.BaseFileManager; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.jvm.Profile; diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Mon Dec 04 10:12:46 2017 -0800 @@ -52,6 +52,7 @@ import com.sun.tools.javac.api.MultiTaskListener; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Lint.LintCategory; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.CompletionFailure; import com.sun.tools.javac.code.Symbol.PackageSymbol; @@ -684,7 +685,7 @@ if (sep == -1) { msym = modules.getDefaultModule(); typeName = name; - } else if (source.allowModules()) { + } else if (Feature.MODULES.allowedInSource(source)) { Name modName = names.fromString(name.substring(0, sep)); msym = moduleFinder.findModule(modName); @@ -1544,7 +1545,7 @@ env.tree = transTypes.translateTopLevelClass(env.tree, localMake); compileStates.put(env, CompileState.TRANSTYPES); - if (source.allowLambda() && scanner.hasLambdas) { + if (Feature.LAMBDA.allowedInSource(source) && scanner.hasLambdas) { if (shouldStop(CompileState.UNLAMBDA)) return; diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Mon Dec 04 10:12:46 2017 -0800 @@ -51,6 +51,7 @@ import com.sun.tools.javac.code.Directive.RequiresDirective; import com.sun.tools.javac.code.Directive.RequiresFlag; import com.sun.tools.javac.code.Scope.WriteableScope; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Enter; @@ -114,7 +115,7 @@ javacTaskImpl = t instanceof JavacTaskImpl ? (JavacTaskImpl) t : null; log = Log.instance(context); Source source = Source.instance(context); - allowModules = source.allowModules(); + allowModules = Feature.MODULES.allowedInSource(source); } @Override @DefinedBy(Api.LANGUAGE_MODEL) diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Mon Dec 04 10:12:46 2017 -0800 @@ -26,8 +26,11 @@ package com.sun.tools.javac.parser; import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; +import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.util.*; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import java.nio.CharBuffer; @@ -46,14 +49,6 @@ private static final boolean scannerDebug = false; - /** Allow binary literals. - */ - private boolean allowBinaryLiterals; - - /** Allow underscores in literals. - */ - private boolean allowUnderscoresInLiterals; - /** The source language setting. */ private Source source; @@ -121,14 +116,24 @@ this.tokens = fac.tokens; this.source = fac.source; this.reader = reader; - this.allowBinaryLiterals = source.allowBinaryLiterals(); - this.allowUnderscoresInLiterals = source.allowUnderscoresInLiterals(); + } + + private void checkSourceLevel(int pos, Feature feature) { + if (!feature.allowedInSource(source)) { + lexError(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name)); + } } /** Report an error at the given position using the provided arguments. */ - protected void lexError(int pos, String key, Object... args) { - log.error(pos, key, args); + protected void lexError(int pos, JCDiagnostic.Error key) { + log.error(pos, key); + tk = TokenKind.ERROR; + errPos = pos; + } + + protected void lexError(DiagnosticFlag flags, int pos, JCDiagnostic.Error key) { + log.error(flags, pos, key); tk = TokenKind.ERROR; errPos = pos; } @@ -175,7 +180,7 @@ case '\\': reader.putChar('\\', true); break; default: - lexError(reader.bp, "illegal.esc.char"); + lexError(reader.bp, Errors.IllegalEscChar); } } } else if (reader.bp != reader.buflen) { @@ -190,17 +195,14 @@ if (reader.ch != '_') { reader.putChar(false); } else { - if (!allowUnderscoresInLiterals) { - lexError(pos, "unsupported.underscore.lit", source.name); - allowUnderscoresInLiterals = true; - } + checkSourceLevel(pos, Feature.UNDERSCORES_IN_LITERALS); } saveCh = reader.ch; savePos = reader.bp; reader.scanChar(); } while (reader.digit(pos, digitRadix) >= 0 || reader.ch == '_'); if (saveCh == '_') - lexError(savePos, "illegal.underscore"); + lexError(savePos, Errors.IllegalUnderscore); } /** Read fractional part of hexadecimal floating point number. @@ -216,11 +218,11 @@ if (reader.digit(pos, 10) >= 0) { scanDigits(pos, 10); if (!hexFloatsWork) - lexError(pos, "unsupported.cross.fp.lit"); + lexError(pos, Errors.UnsupportedCrossFpLit); } else - lexError(pos, "malformed.fp.lit"); + lexError(pos, Errors.MalformedFpLit); } else { - lexError(pos, "malformed.fp.lit"); + lexError(pos, Errors.MalformedFpLit); } if (reader.ch == 'f' || reader.ch == 'F') { reader.putChar(true); @@ -254,7 +256,7 @@ scanDigits(pos, 10); return; } - lexError(pos, "malformed.fp.lit"); + lexError(pos, Errors.MalformedFpLit); reader.sp = sp1; } } @@ -287,14 +289,14 @@ scanDigits(pos, 16); } if (!seendigit) - lexError(pos, "invalid.hex.number"); + lexError(pos, Errors.InvalidHexNumber); else scanHexExponentAndSuffix(pos); } private void skipIllegalUnderscores() { if (reader.ch == '_') { - lexError(reader.bp, "illegal.underscore"); + lexError(reader.bp, Errors.IllegalUnderscore); while (reader.ch == '_') reader.scanChar(); } @@ -329,10 +331,10 @@ if (!seenValidDigit) { switch (radix) { case 2: - lexError(pos, "invalid.binary.number"); + lexError(pos, Errors.InvalidBinaryNumber); break; case 16: - lexError(pos, "invalid.hex.number"); + lexError(pos, Errors.InvalidHexNumber); break; } } @@ -504,10 +506,7 @@ skipIllegalUnderscores(); scanNumber(pos, 16); } else if (reader.ch == 'b' || reader.ch == 'B') { - if (!allowBinaryLiterals) { - lexError(pos, "unsupported.binary.lit", source.name); - allowBinaryLiterals = true; - } + checkSourceLevel(pos, Feature.BINARY_LITERALS); reader.scanChar(); skipIllegalUnderscores(); scanNumber(pos, 2); @@ -519,7 +518,7 @@ reader.scanChar(); } while (reader.ch == '_'); if (reader.digit(pos, 10) < 0) { - lexError(savePos, "illegal.underscore"); + lexError(savePos, Errors.IllegalUnderscore); } } scanNumber(pos, 8); @@ -542,7 +541,7 @@ reader.putChar('.'); tk = TokenKind.ELLIPSIS; } else { - lexError(savePos, "illegal.dot"); + lexError(savePos, Errors.IllegalDot); } } else { tk = TokenKind.DOT; @@ -600,7 +599,7 @@ comments = addComment(comments, processComment(pos, reader.bp, style)); break; } else { - lexError(pos, "unclosed.comment"); + lexError(pos, Errors.UnclosedComment); break loop; } } else if (reader.ch == '=') { @@ -613,17 +612,17 @@ case '\'': reader.scanChar(); if (reader.ch == '\'') { - lexError(pos, "empty.char.lit"); + lexError(pos, Errors.EmptyCharLit); reader.scanChar(); } else { if (reader.ch == CR || reader.ch == LF) - lexError(pos, "illegal.line.end.in.char.lit"); + lexError(pos, Errors.IllegalLineEndInCharLit); scanLitChar(pos); if (reader.ch == '\'') { reader.scanChar(); tk = TokenKind.CHARLITERAL; } else { - lexError(pos, "unclosed.char.lit"); + lexError(pos, Errors.UnclosedCharLit); } } break loop; @@ -635,7 +634,7 @@ tk = TokenKind.STRINGLITERAL; reader.scanChar(); } else { - lexError(pos, "unclosed.str.lit"); + lexError(pos, Errors.UnclosedStrLit); } break loop; default: @@ -676,7 +675,7 @@ String.format("%s", reader.ch) : String.format("\\u%04x", (int)reader.ch); } - lexError(pos, "illegal.char", arg); + lexError(pos, Errors.IllegalChar(arg)); reader.scanChar(); } } diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Dec 04 10:12:46 2017 -0800 @@ -26,12 +26,15 @@ package com.sun.tools.javac.parser; import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; import com.sun.source.tree.MemberReferenceTree.ReferenceMode; import com.sun.source.tree.ModuleTree.ModuleKind; import com.sun.tools.javac.code.*; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.parser.Tokens.*; import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import com.sun.tools.javac.resources.CompilerProperties; @@ -41,6 +44,7 @@ import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; +import com.sun.tools.javac.util.JCDiagnostic.Error; import com.sun.tools.javac.util.List; import static com.sun.tools.javac.parser.Tokens.TokenKind.*; @@ -163,23 +167,7 @@ this.log = fac.log; this.names = fac.names; this.source = fac.source; - this.allowTWR = source.allowTryWithResources(); - this.allowEffectivelyFinalVariablesInTWR = - source.allowEffectivelyFinalVariablesInTryWithResources(); - this.allowDiamond = source.allowDiamond(); - this.allowMulticatch = source.allowMulticatch(); this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true); - this.allowLambda = source.allowLambda(); - this.allowMethodReferences = source.allowMethodReferences(); - this.allowDefaultMethods = source.allowDefaultMethods(); - this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods(); - this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast(); - this.allowTypeAnnotations = source.allowTypeAnnotations(); - this.allowModules = source.allowModules(); - this.allowAnnotationsAfterTypeParams = source.allowAnnotationsAfterTypeParams(); - this.allowUnderscoreIdentifier = source.allowUnderscoreIdentifier(); - this.allowPrivateInterfaceMethods = source.allowPrivateInterfaceMethods(); - this.allowLocalVariableTypeInference = source.allowLocalVariableTypeInference(); this.keepDocComments = keepDocComments; this.parseModuleInfo = parseModuleInfo; docComments = newDocCommentTable(keepDocComments, fac); @@ -198,54 +186,10 @@ return keepDocComments ? new LazyDocCommentTable(fac) : null; } - /** Switch: Should diamond operator be recognized? - */ - boolean allowDiamond; - - /** Switch: Should multicatch clause be accepted? - */ - boolean allowMulticatch; - - /** Switch: should we recognize try-with-resources? - */ - boolean allowTWR; - - /** Switch: should we allow (effectively) final variables as resources in try-with-resources? - */ - boolean allowEffectivelyFinalVariablesInTWR; - /** Switch: should we fold strings? */ boolean allowStringFolding; - /** Switch: should we recognize lambda expressions? - */ - boolean allowLambda; - - /** Switch: should we allow method/constructor references? - */ - boolean allowMethodReferences; - - /** Switch: should we recognize modules? - */ - boolean allowModules; - - /** Switch: should we allow default methods in interfaces? - */ - boolean allowDefaultMethods; - - /** Switch: should we allow static methods in interfaces? - */ - boolean allowStaticInterfaceMethods; - - /** Switch: should we allow private (instance) methods in interfaces? - */ - boolean allowPrivateInterfaceMethods; - - /** Switch: should we allow intersection types in cast? - */ - boolean allowIntersectionTypesInCast; - /** Switch: should we keep docComments? */ boolean keepDocComments; @@ -254,27 +198,11 @@ */ boolean keepLineMap; - /** Switch: should we recognize type annotations? - */ - boolean allowTypeAnnotations; - - /** Switch: should we allow annotations after the method type parameters? - */ - boolean allowAnnotationsAfterTypeParams; - - /** Switch: should we allow '_' as an identifier? - */ - boolean allowUnderscoreIdentifier; - /** Switch: is "this" allowed as an identifier? * This is needed to parse receiver types. */ boolean allowThisIdent; - /** Switch: is local variable inference allowed? - */ - boolean allowLocalVariableTypeInference; - /** The type of the method receiver, as specified by a first "this" parameter. */ JCVariableDecl receiverParam; @@ -628,7 +556,7 @@ } else if (token.kind == THIS) { if (allowThisIdent) { // Make sure we're using a supported source version. - checkTypeAnnotations(); + checkSourceLevel(Feature.TYPE_ANNOTATIONS); Name name = token.name(); nextToken(); return name; @@ -638,7 +566,7 @@ return names.error; } } else if (token.kind == UNDERSCORE) { - if (allowUnderscoreIdentifier) { + if (Feature.UNDERSCORE_IDENTIFIER.allowedInSource(source)) { warning(token.pos, "underscore.as.identifier"); } else { error(token.pos, "underscore.as.identifier"); @@ -1170,7 +1098,7 @@ int pos1 = pos; List targets = List.of(t = parseType()); while (token.kind == AMP) { - checkIntersectionTypesInCast(); + checkSourceLevel(Feature.INTERSECTION_TYPES_IN_CAST); accept(AMP); targets = targets.prepend(parseType()); } @@ -1771,7 +1699,7 @@ } JCExpression lambdaExpressionOrStatementRest(List args, int pos) { - checkLambda(); + checkSourceLevel(Feature.LAMBDA); accept(ARROW); return token.kind == LBRACE ? @@ -1890,7 +1818,7 @@ if (token.kind == LT) { nextToken(); if (token.kind == GT && diamondAllowed) { - checkDiamond(); + checkSourceLevel(Feature.DIAMOND); mode |= DIAMOND; nextToken(); return List.nil(); @@ -2065,7 +1993,7 @@ } JCExpression memberReferenceSuffix(int pos1, JCExpression t) { - checkMethodReferences(); + checkSourceLevel(Feature.METHOD_REFERENCES); mode = EXPR; List typeArgs = null; if (token.kind == LT) { @@ -2568,7 +2496,7 @@ nextToken(); List resources = List.nil(); if (token.kind == LPAREN) { - checkTryWithResources(); + checkSourceLevel(Feature.TRY_WITH_RESOURCES); nextToken(); resources = resources(); accept(RPAREN); @@ -2584,7 +2512,7 @@ } } else { if (resources.isEmpty()) { - if (allowTWR) { + if (Feature.TRY_WITH_RESOURCES.allowedInSource(source)) { error(pos, "try.without.catch.finally.or.resource.decls"); } else { error(pos, "try.without.catch.or.finally"); @@ -2701,7 +2629,7 @@ ListBuffer catchTypes = new ListBuffer<>(); catchTypes.add(parseType()); while (token.kind == BAR) { - checkMulticatch(); + checkSourceLevel(Feature.MULTICATCH); nextToken(); // Instead of qualident this is now parseType. // But would that allow too much, e.g. arrays or generics? @@ -2870,7 +2798,7 @@ case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break; case STRICTFP : flag = Flags.STRICTFP; break; case MONKEYS_AT : flag = Flags.ANNOTATION; break; - case DEFAULT : checkDefaultMethods(); flag = Flags.DEFAULT; break; + case DEFAULT : checkSourceLevel(Feature.DEFAULT_METHODS); flag = Flags.DEFAULT; break; case ERROR : flag = 0; nextToken(); break; default: break loop; } @@ -2914,7 +2842,7 @@ JCAnnotation annotation(int pos, Tag kind) { // accept(AT); // AT consumed by caller if (kind == Tag.TYPE_ANNOTATION) { - checkTypeAnnotations(); + checkSourceLevel(Feature.TYPE_ANNOTATIONS); } JCTree ident = qualident(false); List fieldValues = annotationFieldValuesOpt(); @@ -3028,7 +2956,7 @@ boolean localDecl) { JCVariableDecl head = variableDeclaratorRest(pos, mods, type, name, reqInit, dc, localDecl); - boolean implicit = allowLocalVariableTypeInference && head.vartype == null; + boolean implicit = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && head.vartype == null; vdefs.append(head); while (token.kind == COMMA) { if (implicit) { @@ -3066,7 +2994,7 @@ else if (reqInit) syntaxError(token.pos, "expected", EQ); JCTree elemType = TreeInfo.innermostType(type, true); int startPos = Position.NOPOS; - if (allowLocalVariableTypeInference && elemType.hasTag(IDENT)) { + if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && elemType.hasTag(IDENT)) { Name typeName = ((JCIdent)elemType).name; if (isRestrictedLocalVarTypeName(typeName)) { if (type.hasTag(TYPEARRAY)) { @@ -3100,7 +3028,7 @@ } boolean isRestrictedLocalVarTypeName(Name name) { - return allowLocalVariableTypeInference && name == names.var; + return Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && name == names.var; } /** VariableDeclaratorId = Ident BracketsOpt @@ -3176,7 +3104,7 @@ JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL)); return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true); } else { - checkVariableInTryWithResources(startPos); + checkSourceLevel(Feature.EFFECTIVELY_FINAL_VARIABLES_IN_TRY_WITH_RESOURCES); if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) { log.error(t.pos(), Errors.TryWithResourcesExprNeedsVar); } @@ -3278,10 +3206,7 @@ JCModuleDecl moduleDecl(JCModifiers mods, ModuleKind kind, Comment dc) { int pos = token.pos; - if (!allowModules) { - log.error(pos, Errors.ModulesNotSupportedInSource(source.name)); - allowModules = true; - } + checkSourceLevel(Feature.MODULES); nextToken(); JCExpression name = qualident(false); @@ -3700,7 +3625,7 @@ List annosAfterParams = annotationsOpt(Tag.ANNOTATION); if (annosAfterParams.nonEmpty()) { - checkAnnotationsAfterTypeParams(annosAfterParams.head.pos); + checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS); mods.annotations = mods.annotations.appendList(annosAfterParams); if (mods.pos == Position.NOPOS) mods.pos = mods.annotations.head.pos; @@ -3768,10 +3693,10 @@ Comment dc) { if (isInterface) { if ((mods.flags & Flags.STATIC) != 0) { - checkStaticInterfaceMethods(); + checkSourceLevel(Feature.STATIC_INTERFACE_METHODS); } if ((mods.flags & Flags.PRIVATE) != 0) { - checkPrivateInterfaceMethods(); + checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS); } } JCVariableDecl prevReceiverParam = this.receiverParam; @@ -4226,64 +4151,13 @@ } } - void checkDiamond() { - if (!allowDiamond) { - log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.DiamondNotSupportedInSource(source.name)); - } - } - void checkMulticatch() { - if (!allowMulticatch) { - log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.MulticatchNotSupportedInSource(source.name)); - } - } - void checkTryWithResources() { - if (!allowTWR) { - log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.TryWithResourcesNotSupportedInSource(source.name)); - } - } - void checkVariableInTryWithResources(int startPos) { - if (!allowEffectivelyFinalVariablesInTWR) { - log.error(DiagnosticFlag.SOURCE_LEVEL, startPos, Errors.VarInTryWithResourcesNotSupportedInSource(source.name)); - } - } - void checkLambda() { - if (!allowLambda) { - log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.LambdaNotSupportedInSource(source.name)); - } + void checkSourceLevel(Feature feature) { + checkSourceLevel(token.pos, feature); } - void checkMethodReferences() { - if (!allowMethodReferences) { - log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.MethodReferencesNotSupportedInSource(source.name)); - } - } - void checkDefaultMethods() { - if (!allowDefaultMethods) { - log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.DefaultMethodsNotSupportedInSource(source.name)); - } - } - void checkIntersectionTypesInCast() { - if (!allowIntersectionTypesInCast) { - log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.IntersectionTypesInCastNotSupportedInSource(source.name)); - } - } - void checkStaticInterfaceMethods() { - if (!allowStaticInterfaceMethods) { - log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.StaticIntfMethodsNotSupportedInSource(source.name)); - } - } - void checkTypeAnnotations() { - if (!allowTypeAnnotations) { - log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.TypeAnnotationsNotSupportedInSource(source.name)); - } - } - void checkPrivateInterfaceMethods() { - if (!allowPrivateInterfaceMethods) { - log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, CompilerProperties.Errors.PrivateIntfMethodsNotSupportedInSource(source.name)); - } - } - protected void checkAnnotationsAfterTypeParams(int pos) { - if (!allowAnnotationsAfterTypeParams) { - log.error(DiagnosticFlag.SOURCE_LEVEL, pos, Errors.AnnotationsAfterTypeParamsNotSupportedInSource(source.name)); + + protected void checkSourceLevel(int pos, Feature feature) { + if (!feature.allowedInSource(source)) { + log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name)); } } diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Mon Dec 04 10:12:46 2017 -0800 @@ -53,6 +53,7 @@ import com.sun.tools.javac.api.MultiTaskListener; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Scope.WriteableScope; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.ClassType; import com.sun.tools.javac.code.Types; @@ -116,7 +117,6 @@ private final boolean fatalErrors; private final boolean werror; private final boolean showResolveErrors; - private final boolean allowModules; private final JavacFiler filer; private final JavacMessager messager; @@ -233,8 +233,6 @@ initialCompleter = ClassFinder.instance(context).getCompleter(); chk = Check.instance(context); initProcessorLoader(); - - allowModules = source.allowModules(); } public void setProcessors(Iterable processors) { @@ -770,7 +768,7 @@ if (psi.processorIterator.hasNext()) { ProcessorState ps = new ProcessorState(psi.processorIterator.next(), - log, source, allowModules, + log, source, Feature.MODULES.allowedInSource(source), JavacProcessingEnvironment.this); psi.procStateList.add(ps); return ps; @@ -837,7 +835,7 @@ for(TypeElement a : annotationsPresent) { ModuleElement mod = elementUtils.getModuleOf(a); - String moduleSpec = allowModules && mod != null ? mod.getQualifiedName() + "/" : ""; + String moduleSpec = Feature.MODULES.allowedInSource(source) && mod != null ? mod.getQualifiedName() + "/" : ""; unmatchedAnnotations.put(moduleSpec + a.getQualifiedName().toString(), a); } diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Dec 04 10:12:46 2017 -0800 @@ -2601,38 +2601,87 @@ ({3}) ######################################## -# Diagnostics for language feature changes +# Diagnostics for language feature changes. +# Such diagnostics have a common template which can be customized by using a feature +# diagnostic fragment (one of those given below). ######################################## -# 0: string -compiler.err.modules.not.supported.in.source=\ - modules are not supported in -source {0}\n\ - (use -source 9 or higher to enable modules) - -# 0: string -compiler.misc.diamond.and.anon.class.not.supported.in.source=\ - cannot use ''<>'' with anonymous inner classes in -source {0}\n\ - (use -source 9 or higher to enable ''<>'' with anonymous inner classes) - -# 0: string -compiler.err.unsupported.binary.lit=\ - binary literals are not supported in -source {0}\n\ - (use -source 7 or higher to enable binary literals) - -# 0: string -compiler.err.unsupported.underscore.lit=\ - underscores in literals are not supported in -source {0}\n\ - (use -source 7 or higher to enable underscores in literals) - -# 0: string -compiler.err.try.with.resources.not.supported.in.source=\ - try-with-resources is not supported in -source {0}\n\ - (use -source 7 or higher to enable try-with-resources) - -# 0: string -compiler.err.var.in.try.with.resources.not.supported.in.source=\ - variables in try-with-resources not supported in -source {0}\n\ - (use -source 9 or higher to enable variables in try-with-resources) +# 0: message segment (feature), 1: string (found version), 2: string (expected version) +compiler.err.feature.not.supported.in.source=\ + {0} is not supported in -source {1}\n\ + (use -source {2} or higher to enable {0}) + +# 0: message segment (feature), 1: string (found version), 2: string (expected version) +compiler.err.feature.not.supported.in.source.plural=\ + {0} are not supported in -source {1}\n\ + (use -source {2} or higher to enable {0}) + +# 0: message segment (feature), 1: string (found version), 2: string (expected version) +compiler.misc.feature.not.supported.in.source=\ + {0} is not supported in -source {1}\n\ + (use -source {2} or higher to enable {0}) + +# 0: message segment (feature), 1: string (found version), 2: string (expected version) +compiler.misc.feature.not.supported.in.source.plural=\ + {0} are not supported in -source {1}\n\ + (use -source {2} or higher to enable {0}) + +compiler.misc.feature.modules=\ + modules + +compiler.misc.feature.diamond.and.anon.class=\ + ''<>'' with anonymous inner classes + +compiler.misc.feature.binary.lit=\ + binary literals + +compiler.misc.feature.underscore.lit=\ + underscores in literals + +compiler.misc.feature.try.with.resources=\ + try-with-resources + +compiler.misc.feature.var.in.try.with.resources=\ + variables in try-with-resources + +compiler.misc.feature.type.annotations=\ + type annotations + +compiler.misc.feature.annotations.after.type.params=\ + annotations after method type parameters + +compiler.misc.feature.repeatable.annotations=\ + repeated annotations + +compiler.misc.feature.diamond=\ + diamond operator + +compiler.misc.feature.multicatch=\ + multi-catch statements + +compiler.misc.feature.string.switch=\ + strings in switch + +compiler.misc.feature.lambda=\ + lambda expressions + +compiler.misc.feature.method.references=\ + method references + +compiler.misc.feature.default.methods=\ + default methods + +compiler.misc.feature.intersection.types.in.cast=\ + intersection types + +compiler.misc.feature.static.intf.methods=\ + static interface methods + +compiler.misc.feature.static.intf.method.invoke=\ + static interface method invocations + +compiler.misc.feature.private.intf.methods=\ + private interface methods compiler.warn.underscore.as.identifier=\ as of release 9, ''_'' is a keyword, and may not be used as an identifier @@ -2694,71 +2743,6 @@ compiler.err.no.annotations.on.dot.class=\ no annotations are allowed in the type of a class literal -# 0: string -compiler.err.type.annotations.not.supported.in.source=\ - type annotations are not supported in -source {0}\n\ -(use -source 8 or higher to enable type annotations) - -# 0: string -compiler.err.annotations.after.type.params.not.supported.in.source=\ - annotations after method type parameters are not supported in -source {0}\n\ -(use -source 8 or higher to enable annotations after method type parameters) - -# 0: string -compiler.err.repeatable.annotations.not.supported.in.source=\ - repeated annotations are not supported in -source {0}\n\ -(use -source 8 or higher to enable repeated annotations) - -# 0: string -compiler.err.diamond.not.supported.in.source=\ - diamond operator is not supported in -source {0}\n\ - (use -source 7 or higher to enable diamond operator) - -# 0: string -compiler.err.multicatch.not.supported.in.source=\ - multi-catch statement is not supported in -source {0}\n\ - (use -source 7 or higher to enable multi-catch statement) - -# 0: string -compiler.err.string.switch.not.supported.in.source=\ - strings in switch are not supported in -source {0}\n\ - (use -source 7 or higher to enable strings in switch) - -# 0: string -compiler.err.lambda.not.supported.in.source=\ - lambda expressions are not supported in -source {0}\n\ - (use -source 8 or higher to enable lambda expressions) - -# 0: string -compiler.err.method.references.not.supported.in.source=\ - method references are not supported in -source {0}\n\ - (use -source 8 or higher to enable method references) - -# 0: string -compiler.err.default.methods.not.supported.in.source=\ - default methods are not supported in -source {0}\n\ - (use -source 8 or higher to enable default methods) - -# 0: string -compiler.err.intersection.types.in.cast.not.supported.in.source=\ - intersection types in cast are not supported in -source {0}\n\ - (use -source 8 or higher to enable intersection types in cast) - -# 0: string -compiler.err.static.intf.methods.not.supported.in.source=\ - static interface methods are not supported in -source {0}\n\ - (use -source 8 or higher to enable static interface methods) - -# 0: string -compiler.err.static.intf.method.invoke.not.supported.in.source=\ - static interface method invocations are not supported in -source {0}\n\ - (use -source 8 or higher to enable static interface method invocations) - -# 0: string -compiler.err.private.intf.methods.not.supported.in.source=\ - private interface methods are not supported in -source {0}\n\ - (use -source 9 or higher to enable private interface methods) - ######################################## # Diagnostics for verbose resolution # used by Resolve (debug only) diff -r 40afd72303e9 -r f27aad5782da src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Mon Dec 04 10:12:46 2017 -0800 @@ -426,7 +426,7 @@ /** A set of "not-supported-in-source-X" errors produced so far. This is used to only generate * one such error per file. */ - protected Set> recordedSourceLevelErrors = new HashSet<>(); + protected Set>> recordedSourceLevelErrors = new HashSet<>(); public boolean hasDiagnosticListener() { return diagListener != null; @@ -521,13 +521,29 @@ if (!d.isFlagSet(DiagnosticFlag.SOURCE_LEVEL)) return true; - Pair coords = new Pair<>(file, d.getCode()); + Pair> coords = new Pair<>(file, getCode(d)); boolean shouldReport = !recordedSourceLevelErrors.contains(coords); if (shouldReport) recordedSourceLevelErrors.add(coords); return shouldReport; } + //where + private List getCode(JCDiagnostic d) { + ListBuffer buf = new ListBuffer<>(); + getCodeRecursive(buf, d); + return buf.toList(); + } + + private void getCodeRecursive(ListBuffer buf, JCDiagnostic d) { + buf.add(d.getCode()); + for (Object o : d.getArgs()) { + if (o instanceof JCDiagnostic) { + getCodeRecursive(buf, (JCDiagnostic)o); + } + } + } + /** Prompt user after an error. */ public void prompt() { diff -r 40afd72303e9 -r f27aad5782da src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java --- a/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java Mon Dec 04 10:12:46 2017 -0800 @@ -34,6 +34,7 @@ import javax.tools.StandardJavaFileManager; import com.sun.javadoc.*; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; @@ -388,7 +389,7 @@ } public boolean isFunctionalInterface(AnnotationDesc annotationDesc) { - return env.source.allowLambda() + return Feature.LAMBDA.allowedInSource(env.source) && annotationDesc.annotationType().qualifiedName().equals( env.syms.functionalInterfaceType.toString()); } diff -r 40afd72303e9 -r f27aad5782da src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Mon Dec 04 10:12:46 2017 -0800 @@ -55,6 +55,7 @@ import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Scope; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol; @@ -187,7 +188,7 @@ // TODO: we need ElementUtils.getPackage to cope with input strings // to return the proper unnamedPackage for all supported releases. PackageElement getUnnamedPackage() { - return (toolEnv.source.allowModules()) + return (Feature.MODULES.allowedInSource(toolEnv.source)) ? toolEnv.syms.unnamedModule.unnamedPackage : toolEnv.syms.noModule.unnamedPackage; } diff -r 40afd72303e9 -r f27aad5782da src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Mon Dec 04 10:12:46 2017 -0800 @@ -55,6 +55,7 @@ import com.sun.tools.javac.code.Kinds.Kind; import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.CompletionFailure; @@ -222,7 +223,7 @@ else locs.add(StandardLocation.CLASS_PATH); } - if (source.allowModules() && toolEnv.fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH)) + if (Feature.MODULES.allowedInSource(source) && toolEnv.fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH)) locs.add(StandardLocation.PATCH_MODULE_PATH); this.locations = Collections.unmodifiableList(locs); diff -r 40afd72303e9 -r f27aad5782da src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java --- a/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java Mon Dec 04 10:12:46 2017 -0800 @@ -34,6 +34,7 @@ import com.sun.tools.javac.util.JCDiagnostic; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; +import com.sun.tools.javac.util.JCDiagnostic.Error; import com.sun.tools.javac.util.Log; import java.io.PrintWriter; import java.io.StringWriter; @@ -78,7 +79,7 @@ Context context = new Context(); Log log = CaLog.createLog(context); context.put(Log.class, log); - context.put(Source.class, Source.JDK1_9); + context.put(Source.class, Source.JDK9); scannerFactory = ScannerFactory.instance(context); } @@ -138,6 +139,11 @@ } @Override + public void error(int pos, Error errorKey) { + die(); + } + + @Override public void error(int pos, String key, Object... args) { die(); } diff -r 40afd72303e9 -r f27aad5782da src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java --- a/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java Mon Dec 04 09:38:34 2017 -0800 +++ b/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java Mon Dec 04 10:12:46 2017 -0800 @@ -25,6 +25,7 @@ package jdk.jshell; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.parser.JavacParser; import com.sun.tools.javac.parser.ParserFactory; @@ -191,7 +192,7 @@ List annosAfterParams = annotationsOpt(Tag.ANNOTATION); if (annosAfterParams.nonEmpty()) { - checkAnnotationsAfterTypeParams(annosAfterParams.head.pos); + checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS); mods.annotations = mods.annotations.appendList(annosAfterParams); if (mods.pos == Position.NOPOS) { mods.pos = mods.annotations.head.pos; diff -r 40afd72303e9 -r f27aad5782da test/jdk/java/lang/reflect/StaticFieldsOnInterface.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/StaticFieldsOnInterface.java Mon Dec 04 10:12:46 2017 -0800 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8186961 + * @run main/othervm StaticFieldsOnInterface C + * @run main/othervm StaticFieldsOnInterface D + * @run main/othervm StaticFieldsOnInterface Y + */ + +public class StaticFieldsOnInterface { + /* + A + / \ + B C + \ / + D + + Interface A has a public field + Ensure B, C, D only report exactly one public field + + A + / + X A + |/ + Y + + Ensure class Y, extending class X, reports exactly one public field + */ + + public interface A { + public static final int CONSTANT = 42; + } + + public interface B extends A { + } + + public interface C extends A { + } + + public interface D extends B, C { + } + + static class X implements A {} + static class Y extends X implements A {} + + public static void main(String[] args) throws Exception { + char first = 'C'; + if (args.length > 0) { + first = args[0].charAt(0); + } + + assertOneField(A.class); + // D first + if (first == 'D') { + assertOneField(D.class); + assertOneField(C.class); + } + // C first + else if (first == 'C') { + assertOneField(C.class); + assertOneField(D.class); + } + else { + assertOneField(Y.class); + } + } + + static void assertOneField(Class c) { + int nfs = c.getFields().length; + if (nfs != 1) { + throw new AssertionError(String.format( + "Class %s does not have exactly one field: %d", c.getName(), nfs)); + } + } +} diff -r 40afd72303e9 -r f27aad5782da test/jdk/java/net/SocketOption/UnsupportedOptionsTest.java --- a/test/jdk/java/net/SocketOption/UnsupportedOptionsTest.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/jdk/java/net/SocketOption/UnsupportedOptionsTest.java Mon Dec 04 10:12:46 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, 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 @@ -57,6 +57,8 @@ Class c = Class.forName("jdk.net.ExtendedSocketOptions"); Field field = c.getField("SO_FLOW_SLA"); socketOptions.add((SocketOption)field.get(null)); + field = c.getField("TCP_QUICKACK"); + socketOptions.add((SocketOption)field.get(null)); } catch (ClassNotFoundException e) { // ignore, jdk.net module not present } catch (ReflectiveOperationException e) { diff -r 40afd72303e9 -r f27aad5782da test/jdk/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java --- a/test/jdk/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/jdk/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java Mon Dec 04 10:12:46 2017 -0800 @@ -39,6 +39,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.locks.AbstractQueuedLongSynchronizer; import java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject; @@ -1283,4 +1284,57 @@ sync.release(); } + /** + * Tests scenario for + * JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw + */ + public void testInterruptedFailingAcquire() throws InterruptedException { + final RuntimeException ex = new RuntimeException(); + + // A synchronizer only offering a choice of failure modes + class Sync extends AbstractQueuedLongSynchronizer { + boolean pleaseThrow; + @Override protected boolean tryAcquire(long ignored) { + if (pleaseThrow) throw ex; + return false; + } + @Override protected long tryAcquireShared(long ignored) { + if (pleaseThrow) throw ex; + return -1; + } + @Override protected boolean tryRelease(long ignored) { + return true; + } + @Override protected boolean tryReleaseShared(long ignored) { + return true; + } + } + + final Sync s = new Sync(); + + final Thread thread = newStartedThread(new CheckedRunnable() { + public void realRun() { + try { + if (ThreadLocalRandom.current().nextBoolean()) + s.acquire(1); + else + s.acquireShared(1); + shouldThrow(); + } catch (Throwable t) { + assertSame(ex, t); + assertTrue(Thread.interrupted()); + } + }}); + waitForThreadToEnterWaitState(thread); + assertSame(thread, s.getFirstQueuedThread()); + assertTrue(s.hasQueuedPredecessors()); + assertTrue(s.hasQueuedThreads()); + assertEquals(1, s.getQueueLength()); + + s.pleaseThrow = true; + thread.interrupt(); + s.release(1); + awaitTermination(thread); + } + } diff -r 40afd72303e9 -r f27aad5782da test/jdk/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java --- a/test/jdk/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/jdk/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java Mon Dec 04 10:12:46 2017 -0800 @@ -36,9 +36,11 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.locks.AbstractQueuedSynchronizer; import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject; @@ -1286,4 +1288,105 @@ sync.release(); } + /** + * Disabled demo test for (unfixed as of 2017-11) + * JDK-8191483: AbstractQueuedSynchronizer cancel/cancel race + * ant -Djsr166.tckTestClass=AbstractQueuedSynchronizerTest -Djsr166.methodFilter=testCancelCancelRace -Djsr166.runsPerTest=100 tck + */ + public void DISABLED_testCancelCancelRace() throws InterruptedException { + class Sync extends AbstractQueuedSynchronizer { + protected boolean tryAcquire(int acquires) { + return !hasQueuedPredecessors() && compareAndSetState(0, 1); + } + protected boolean tryRelease(int releases) { + return compareAndSetState(1, 0); + } + } + + Sync s = new Sync(); + s.acquire(1); // acquire to force other threads to enqueue + + // try to trigger double cancel race with two background threads + ArrayList threads = new ArrayList<>(); + Runnable failedAcquire = () -> { + try { + s.acquireInterruptibly(1); + shouldThrow(); + } catch (InterruptedException expected) {} + }; + for (int i = 0; i < 2; i++) { + Thread thread = new Thread(failedAcquire); + thread.start(); + threads.add(thread); + } + Thread.sleep(100); + for (Thread thread : threads) thread.interrupt(); + for (Thread thread : threads) awaitTermination(thread); + + s.release(1); + + // no one holds lock now, we should be able to acquire + if (!s.tryAcquire(1)) + throw new RuntimeException( + String.format( + "Broken: hasQueuedPredecessors=%s hasQueuedThreads=%s queueLength=%d firstQueuedThread=%s", + s.hasQueuedPredecessors(), + s.hasQueuedThreads(), + s.getQueueLength(), + s.getFirstQueuedThread())); + } + + /** + * Tests scenario for + * JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw + */ + public void testInterruptedFailingAcquire() throws InterruptedException { + final RuntimeException ex = new RuntimeException(); + + // A synchronizer only offering a choice of failure modes + class Sync extends AbstractQueuedSynchronizer { + boolean pleaseThrow; + @Override protected boolean tryAcquire(int ignored) { + if (pleaseThrow) throw ex; + return false; + } + @Override protected int tryAcquireShared(int ignored) { + if (pleaseThrow) throw ex; + return -1; + } + @Override protected boolean tryRelease(int ignored) { + return true; + } + @Override protected boolean tryReleaseShared(int ignored) { + return true; + } + } + + final Sync s = new Sync(); + + final Thread thread = newStartedThread(new CheckedRunnable() { + public void realRun() { + try { + if (ThreadLocalRandom.current().nextBoolean()) + s.acquire(1); + else + s.acquireShared(1); + shouldThrow(); + } catch (Throwable t) { + assertSame(ex, t); + assertTrue(Thread.interrupted()); + } + }}); + waitForThreadToEnterWaitState(thread); + assertSame(thread, s.getFirstQueuedThread()); + assertTrue(s.hasQueuedPredecessors()); + assertTrue(s.hasQueuedThreads()); + assertEquals(1, s.getQueueLength()); + + s.pleaseThrow = true; + thread.interrupt(); + s.release(1); + awaitTermination(thread); + } + } diff -r 40afd72303e9 -r f27aad5782da test/jdk/java/util/concurrent/tck/StampedLockTest.java --- a/test/jdk/java/util/concurrent/tck/StampedLockTest.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/jdk/java/util/concurrent/tck/StampedLockTest.java Mon Dec 04 10:12:46 2017 -0800 @@ -614,7 +614,7 @@ long s = lock.readLock(); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() { - threadAssertEquals(0L, lock.tryWriteLock()); + assertEquals(0L, lock.tryWriteLock()); }}); awaitTermination(t); diff -r 40afd72303e9 -r f27aad5782da test/jdk/java/util/concurrent/tck/SubmissionPublisherTest.java --- a/test/jdk/java/util/concurrent/tck/SubmissionPublisherTest.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/jdk/java/util/concurrent/tck/SubmissionPublisherTest.java Mon Dec 04 10:12:46 2017 -0800 @@ -33,6 +33,7 @@ */ import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.Flow; @@ -429,7 +430,8 @@ * Cancelling a subscription eventually causes no more onNexts to be issued */ public void testCancel() { - SubmissionPublisher p = basicPublisher(); + SubmissionPublisher p = + new SubmissionPublisher(basicExecutor, 4); // must be < 20 TestSubscriber s1 = new TestSubscriber(); TestSubscriber s2 = new TestSubscriber(); p.subscribe(s1); @@ -666,7 +668,6 @@ p.subscribe(s1); p.subscribe(s2); for (int i = 1; i <= 20; ++i) { - assertTrue(p.estimateMinimumDemand() <= 1); assertTrue(p.submit(i) >= 0); } p.close(); @@ -1005,4 +1006,31 @@ assertTrue(count.get() < n); } + /** + * Tests scenario for + * JDK-8187947: A race condition in SubmissionPublisher + * cvs update -D '2017-11-25' src/main/java/util/concurrent/SubmissionPublisher.java && ant -Djsr166.expensiveTests=true -Djsr166.tckTestClass=SubmissionPublisherTest -Djsr166.methodFilter=testMissedSignal tck; cvs update -A src/main/java/util/concurrent/SubmissionPublisher.java + */ + public void testMissedSignal_8187947() throws Exception { + final int N = expensiveTests ? (1 << 20) : (1 << 10); + final CountDownLatch finished = new CountDownLatch(1); + final SubmissionPublisher pub = new SubmissionPublisher<>(); + class Sub implements Subscriber { + int received; + public void onSubscribe(Subscription s) { + s.request(N); + } + public void onNext(Boolean item) { + if (++received == N) + finished.countDown(); + else + CompletableFuture.runAsync(() -> pub.submit(Boolean.TRUE)); + } + public void onError(Throwable t) { throw new AssertionError(t); } + public void onComplete() {} + } + pub.subscribe(new Sub()); + CompletableFuture.runAsync(() -> pub.submit(Boolean.TRUE)); + await(finished); + } } diff -r 40afd72303e9 -r f27aad5782da test/jdk/java/util/zip/InflateIn_DeflateOut.java --- a/test/jdk/java/util/zip/InflateIn_DeflateOut.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/jdk/java/util/zip/InflateIn_DeflateOut.java Mon Dec 04 10:12:46 2017 -0800 @@ -23,8 +23,9 @@ /** * @test - * @bug 4206909 4813885 - * @summary Test basic functionality of DeflaterOutputStream/InflaterInputStream and GZIPOutputStream/GZIPInputStream, including flush + * @bug 4206909 4813885 8191918 + * @summary Test basic functionality of DeflaterOutputStream/InflaterInputStream + * and GZIPOutputStream/GZIPInputStream, including flush * @key randomness */ @@ -147,6 +148,36 @@ check(Arrays.equals(data, buf)); } + private static void TestFlushableGZIPOutputStream() throws Throwable { + var random = new Random(new Date().getTime()); + + var byteOutStream = new ByteArrayOutputStream(); + var output = new FlushableGZIPOutputStream(byteOutStream); + + var data = new byte[random.nextInt(1024 * 1024)]; + var buf = new byte[data.length]; + random.nextBytes(data); + + output.write(data); + for (int i=0; i 0) { + out.write(buf, 0, len); + } + } while (len != 0); + } + +} diff -r 40afd72303e9 -r f27aad5782da test/jdk/jdk/net/Sockets/ExtOptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/jdk/net/Sockets/ExtOptionTest.java Mon Dec 04 10:12:46 2017 -0800 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* + * @test + * @bug 8190843 + * @summary can not set/get extendedOptions to ServerSocket + * @modules jdk.net + * @run main ExtOptionTest + */ +import java.io.IOException; +import java.net.ServerSocket; + +import static jdk.net.ExtendedSocketOptions.TCP_QUICKACK; +import static jdk.net.ExtendedSocketOptions.SO_FLOW_SLA; + +public class ExtOptionTest { + + private static final String OS = "Linux"; + + public static void main(String args[]) throws IOException { + var operSys = System.getProperty("os.name"); + try (ServerSocket ss = new ServerSocket(0)) { + // currently TCP_QUICKACK is available only on Linux. + if (operSys.equals(OS)) { + ss.setOption(TCP_QUICKACK, true); + if (!ss.getOption(TCP_QUICKACK)) { + throw new RuntimeException("Test failed, TCP_QUICKACK should" + + " have been set"); + } + } else if (operSys.equals("SunOS")) { + if (ss.supportedOptions().contains(SO_FLOW_SLA)) { + throw new RuntimeException("Test failed, SO_FLOW_SLA is not " + + "applicable for ServerSocket"); + } + } else { + if (ss.supportedOptions().contains(TCP_QUICKACK)) { + ss.setOption(TCP_QUICKACK, true); + if (!ss.getOption(TCP_QUICKACK)) { + throw new RuntimeException("Test failed, TCP_QUICKACK should" + + " have been set"); + } + } + } + } + } +} diff -r 40afd72303e9 -r f27aad5782da test/langtools/jdk/jshell/CompilerOptionsTest.java --- a/test/langtools/jdk/jshell/CompilerOptionsTest.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/jdk/jshell/CompilerOptionsTest.java Mon Dec 04 10:12:46 2017 -0800 @@ -51,6 +51,6 @@ public void testSourceVersion() { assertEval("import java.util.function.*;", added(VALID)); assertDeclareFail("Function f = x -> x*2;", - new ExpectedDiagnostic("compiler.err.lambda.not.supported.in.source", 32, 32, 32, -1, -1, Diagnostic.Kind.ERROR)); + new ExpectedDiagnostic("compiler.err.feature.not.supported.in.source.plural", 32, 32, 32, -1, -1, Diagnostic.Kind.ERROR)); } } diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/6302184/HiddenOptionsShouldUseGivenEncodingTest.java --- a/test/langtools/tools/javac/6302184/HiddenOptionsShouldUseGivenEncodingTest.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/6302184/HiddenOptionsShouldUseGivenEncodingTest.java Mon Dec 04 10:12:46 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, 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 @@ -29,28 +29,62 @@ * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * @build toolbox.ToolBox - * @run compile -encoding iso-8859-1 -XD-printsource T6302184.java + * @build toolbox.ToolBox toolbox.JavacTask * @run main HiddenOptionsShouldUseGivenEncodingTest */ +import java.nio.charset.Charset; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Arrays; import java.util.List; +import toolbox.JavacTask; import toolbox.ToolBox; // Original test: test/tools/javac/6302184/T6302184.sh public class HiddenOptionsShouldUseGivenEncodingTest { public static void main(String[] args) throws Exception { + String encoding = "iso-8859-1"; + Path src = Paths.get("src"); + Files.createDirectories(src); + Files.write(src.resolve("T6302184.java"), source, Charset.forName(encoding)); + Files.write(src.resolve("T6302184.out"), expect, Charset.forName(encoding)); + + Path out = Paths.get("out"); + Files.createDirectories(out); + ToolBox tb = new ToolBox(); - String encoding = "iso-8859-1"; - Path path1 = Paths.get(ToolBox.testClasses, "T6302184.java"); + new JavacTask(tb) + .outdir("out") + .options("-encoding", encoding, "-XD-printsource") + .files(src.resolve("T6302184.java")) + .run(); + + Path path1 = Paths.get("out").resolve("T6302184.java"); List file1 = tb.readAllLines(path1, encoding); - Path path2 = Paths.get(ToolBox.testSrc, "T6302184.out"); + Path path2 = src.resolve("T6302184.out"); List file2 = tb.readAllLines(path2, encoding); tb.checkEqual(file1, file2); } + static List source = Arrays.asList( + "class T6302184 {", + " int \u00c0\u00c1\u00c2\u00c3\u00c4\u00c5 = 1;", + "}" + ); + + static List expect = Arrays.asList( + "", + "class T6302184 {", + " ", + " T6302184() {", + " super();", + " }", + " int \u00c0\u00c1\u00c2\u00c3\u00c4\u00c5 = 1;", + "}" + ); + } diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/6302184/T6302184.java --- a/test/langtools/tools/javac/6302184/T6302184.java Mon Dec 04 09:38:34 2017 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * 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. - * - * 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. - */ - -/** - * This is a test that uses ISO 8859 encoding. - */ -class T6302184 { - int ÀÁÂÃÄÅ = 1; -} diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/6302184/T6302184.out --- a/test/langtools/tools/javac/6302184/T6302184.out Mon Dec 04 09:38:34 2017 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ - -/** - * This is a test that uses ISO 8859 encoding. - */ -class T6302184 { - - T6302184() { - super(); - } - int ÀÁÂÃÄÅ = 1; -} diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/StringsInSwitch/BadlyTypedLabel1_6.out --- a/test/langtools/tools/javac/StringsInSwitch/BadlyTypedLabel1_6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/StringsInSwitch/BadlyTypedLabel1_6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,7 +1,7 @@ -- compiler.warn.source.no.bootclasspath: 1.6 -- compiler.warn.option.obsolete.source: 1.6 +- compiler.warn.source.no.bootclasspath: 6 +- compiler.warn.option.obsolete.source: 6 - compiler.warn.option.obsolete.suppression -BadlyTypedLabel1.java:10:15: compiler.err.string.switch.not.supported.in.source: 1.6 +BadlyTypedLabel1.java:10:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7 BadlyTypedLabel1.java:13:14: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.String) 2 errors 3 warnings diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/StringsInSwitch/BadlyTypedLabel2_6.out --- a/test/langtools/tools/javac/StringsInSwitch/BadlyTypedLabel2_6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/StringsInSwitch/BadlyTypedLabel2_6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,7 +1,7 @@ -- compiler.warn.source.no.bootclasspath: 1.6 -- compiler.warn.option.obsolete.source: 1.6 +- compiler.warn.source.no.bootclasspath: 6 +- compiler.warn.option.obsolete.source: 6 - compiler.warn.option.obsolete.suppression -BadlyTypedLabel2.java:12:15: compiler.err.string.switch.not.supported.in.source: 1.6 +BadlyTypedLabel2.java:12:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7 BadlyTypedLabel2.java:15:14: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.math.RoundingMode, java.lang.String) 2 errors 3 warnings diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/StringsInSwitch/NonConstantLabel6.out --- a/test/langtools/tools/javac/StringsInSwitch/NonConstantLabel6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/StringsInSwitch/NonConstantLabel6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,7 +1,7 @@ -- compiler.warn.source.no.bootclasspath: 1.6 -- compiler.warn.option.obsolete.source: 1.6 +- compiler.warn.source.no.bootclasspath: 6 +- compiler.warn.option.obsolete.source: 6 - compiler.warn.option.obsolete.suppression -NonConstantLabel.java:11:15: compiler.err.string.switch.not.supported.in.source: 1.6 +NonConstantLabel.java:11:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7 NonConstantLabel.java:14:14: compiler.err.string.const.req 2 errors 3 warnings diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/StringsInSwitch/OneCaseSwitches.out --- a/test/langtools/tools/javac/StringsInSwitch/OneCaseSwitches.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/StringsInSwitch/OneCaseSwitches.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,6 +1,6 @@ -- compiler.warn.source.no.bootclasspath: 1.6 -- compiler.warn.option.obsolete.source: 1.6 +- compiler.warn.source.no.bootclasspath: 6 +- compiler.warn.option.obsolete.source: 6 - compiler.warn.option.obsolete.suppression -OneCaseSwitches.java:23:15: compiler.err.string.switch.not.supported.in.source: 1.6 +OneCaseSwitches.java:23:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7 1 error -3 warnings \ No newline at end of file +3 warnings diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/StringsInSwitch/RSCL1_6.out --- a/test/langtools/tools/javac/StringsInSwitch/RSCL1_6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/StringsInSwitch/RSCL1_6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,7 +1,7 @@ -- compiler.warn.source.no.bootclasspath: 1.6 -- compiler.warn.option.obsolete.source: 1.6 +- compiler.warn.source.no.bootclasspath: 6 +- compiler.warn.option.obsolete.source: 6 - compiler.warn.option.obsolete.suppression -RepeatedStringCaseLabels1.java:10:15: compiler.err.string.switch.not.supported.in.source: 1.6 +RepeatedStringCaseLabels1.java:10:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7 RepeatedStringCaseLabels1.java:13:9: compiler.err.duplicate.case.label 2 errors 3 warnings diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/StringsInSwitch/RSCL2_6.out --- a/test/langtools/tools/javac/StringsInSwitch/RSCL2_6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/StringsInSwitch/RSCL2_6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,7 +1,7 @@ -- compiler.warn.source.no.bootclasspath: 1.6 -- compiler.warn.option.obsolete.source: 1.6 +- compiler.warn.source.no.bootclasspath: 6 +- compiler.warn.option.obsolete.source: 6 - compiler.warn.option.obsolete.suppression -RepeatedStringCaseLabels2.java:11:15: compiler.err.string.switch.not.supported.in.source: 1.6 +RepeatedStringCaseLabels2.java:11:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7 RepeatedStringCaseLabels2.java:14:9: compiler.err.duplicate.case.label 2 errors 3 warnings diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/TryWithResources/BadTwr6.out --- a/test/langtools/tools/javac/TryWithResources/BadTwr6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/TryWithResources/BadTwr6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,6 +1,6 @@ -- compiler.warn.source.no.bootclasspath: 1.6 -- compiler.warn.option.obsolete.source: 1.6 +- compiler.warn.source.no.bootclasspath: 6 +- compiler.warn.option.obsolete.source: 6 - compiler.warn.option.obsolete.suppression -BadTwr.java:13:12: compiler.err.try.with.resources.not.supported.in.source: 1.6 +BadTwr.java:13:12: compiler.err.feature.not.supported.in.source: (compiler.misc.feature.try.with.resources), 6, 7 1 error 3 warnings diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/TryWithResources/BadTwrSyntax6.out --- a/test/langtools/tools/javac/TryWithResources/BadTwrSyntax6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/TryWithResources/BadTwrSyntax6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,7 +1,7 @@ -- compiler.warn.source.no.bootclasspath: 1.6 -- compiler.warn.option.obsolete.source: 1.6 +- compiler.warn.source.no.bootclasspath: 6 +- compiler.warn.option.obsolete.source: 6 - compiler.warn.option.obsolete.suppression -BadTwrSyntax.java:14:12: compiler.err.try.with.resources.not.supported.in.source: 1.6 +BadTwrSyntax.java:14:12: compiler.err.feature.not.supported.in.source: (compiler.misc.feature.try.with.resources), 6, 7 BadTwrSyntax.java:14:43: compiler.err.illegal.start.of.expr 2 errors 3 warnings diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/TryWithResources/TwrForVariable1.out --- a/test/langtools/tools/javac/TryWithResources/TwrForVariable1.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/TryWithResources/TwrForVariable1.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,2 +1,2 @@ -TwrForVariable1.java:13:14: compiler.err.var.in.try.with.resources.not.supported.in.source: 1.8 +TwrForVariable1.java:13:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.var.in.try.with.resources), 8, 9 1 error diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/TryWithResources/TwrOnNonResource6.out --- a/test/langtools/tools/javac/TryWithResources/TwrOnNonResource6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/TryWithResources/TwrOnNonResource6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,6 +1,6 @@ -- compiler.warn.source.no.bootclasspath: 1.6 -- compiler.warn.option.obsolete.source: 1.6 +- compiler.warn.source.no.bootclasspath: 6 +- compiler.warn.option.obsolete.source: 6 - compiler.warn.option.obsolete.suppression -TwrOnNonResource.java:12:12: compiler.err.try.with.resources.not.supported.in.source: 1.6 +TwrOnNonResource.java:12:12: compiler.err.feature.not.supported.in.source: (compiler.misc.feature.try.with.resources), 6, 7 1 error 3 warnings diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/TryWithResources/WeirdTwr.out --- a/test/langtools/tools/javac/TryWithResources/WeirdTwr.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/TryWithResources/WeirdTwr.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,6 +1,6 @@ -- compiler.warn.source.no.bootclasspath: 1.6 -- compiler.warn.option.obsolete.source: 1.6 +- compiler.warn.source.no.bootclasspath: 6 +- compiler.warn.option.obsolete.source: 6 - compiler.warn.option.obsolete.suppression -WeirdTwr.java:14:12: compiler.err.try.with.resources.not.supported.in.source: 1.6 +WeirdTwr.java:14:12: compiler.err.feature.not.supported.in.source: (compiler.misc.feature.try.with.resources), 6, 7 1 error 3 warnings diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/annotations/repeatingAnnotations/WrongVersion6.out --- a/test/langtools/tools/javac/annotations/repeatingAnnotations/WrongVersion6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/annotations/repeatingAnnotations/WrongVersion6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,2 +1,2 @@ -WrongVersion.java:12:9: compiler.err.repeatable.annotations.not.supported.in.source: 1.6 +WrongVersion.java:12:9: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.repeatable.annotations), 6, 8 1 error diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/annotations/repeatingAnnotations/WrongVersion7.out --- a/test/langtools/tools/javac/annotations/repeatingAnnotations/WrongVersion7.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/annotations/repeatingAnnotations/WrongVersion7.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,2 +1,2 @@ -WrongVersion.java:12:9: compiler.err.repeatable.annotations.not.supported.in.source: 1.7 +WrongVersion.java:12:9: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.repeatable.annotations), 7, 8 1 error diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out --- a/test/langtools/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,2 +1,2 @@ -AnnotationVersion.java:12:27: compiler.err.type.annotations.not.supported.in.source: 1.6 +AnnotationVersion.java:12:27: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.type.annotations), 6, 8 1 error diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out --- a/test/langtools/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,2 +1,2 @@ -AnnotationVersion.java:12:27: compiler.err.type.annotations.not.supported.in.source: 1.7 +AnnotationVersion.java:12:27: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.type.annotations), 7, 8 1 error diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/annotations/typeAnnotations/failures/CheckErrorsForSource7.java --- a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CheckErrorsForSource7.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CheckErrorsForSource7.java Mon Dec 04 10:12:46 2017 -0800 @@ -135,7 +135,7 @@ boolean found = false; for (Diagnostic d : errors.getDiagnostics()) { - if (d.getKind() == Diagnostic.Kind.ERROR && EXPECTED_ERRORS.contains(d.getCode())) { + if (d.getKind() == Diagnostic.Kind.ERROR && EXPECTED_ERROR.equals(d.getCode())) { if (found) { throw new IllegalStateException("More than one expected error found."); } @@ -149,10 +149,7 @@ } } - static final Set EXPECTED_ERRORS = new HashSet<>(Arrays.asList( - "compiler.err.type.annotations.not.supported.in.source", - "compiler.err.annotations.after.type.params.not.supported.in.source" - )); + static final String EXPECTED_ERROR = "compiler.err.feature.not.supported.in.source.plural"; class TestFO extends SimpleJavaFileObject { private final String content; diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/conditional/Conditional.out --- a/test/langtools/tools/javac/conditional/Conditional.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/conditional/Conditional.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,4 +1,4 @@ -- compiler.warn.source.no.bootclasspath: 1.7 +- compiler.warn.source.no.bootclasspath: 7 Conditional.java:16:38: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.util.List, java.util.List) 1 error 1 warning diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/defaultMethods/static/StaticInvokeQualified6.out --- a/test/langtools/tools/javac/defaultMethods/static/StaticInvokeQualified6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/defaultMethods/static/StaticInvokeQualified6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,2 +1,2 @@ -StaticInvokeQualified.java:11:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6 +StaticInvokeQualified.java:11:32: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.static.intf.method.invoke), 6, 8 1 error diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/defaultMethods/static/StaticInvokeQualified7.out --- a/test/langtools/tools/javac/defaultMethods/static/StaticInvokeQualified7.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/defaultMethods/static/StaticInvokeQualified7.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,2 +1,2 @@ -StaticInvokeQualified.java:11:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7 +StaticInvokeQualified.java:11:32: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.static.intf.method.invoke), 7, 8 1 error diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/defaultMethods/static/StaticInvokeSimple6.out --- a/test/langtools/tools/javac/defaultMethods/static/StaticInvokeSimple6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/defaultMethods/static/StaticInvokeSimple6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,2 +1,2 @@ -StaticInvokeSimple.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6 +StaticInvokeSimple.java:12:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.static.intf.method.invoke), 6, 8 1 error diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/defaultMethods/static/StaticInvokeSimple7.out --- a/test/langtools/tools/javac/defaultMethods/static/StaticInvokeSimple7.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/defaultMethods/static/StaticInvokeSimple7.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,2 +1,2 @@ -StaticInvokeSimple.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7 -1 error \ No newline at end of file +StaticInvokeSimple.java:12:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.static.intf.method.invoke), 7, 8 +1 error diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/depDocComment/SuppressDeprecation8.out --- a/test/langtools/tools/javac/depDocComment/SuppressDeprecation8.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/depDocComment/SuppressDeprecation8.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,4 +1,4 @@ -- compiler.warn.source.no.bootclasspath: 1.8 +- compiler.warn.source.no.bootclasspath: 8 SuppressDeprecation.java:83:10: compiler.warn.has.been.deprecated: g(), T SuppressDeprecation.java:84:14: compiler.warn.has.been.deprecated: g(), T SuppressDeprecation.java:85:9: compiler.warn.has.been.deprecated: var, T diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples.not-yet.txt --- a/test/langtools/tools/javac/diags/examples.not-yet.txt Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples.not-yet.txt Mon Dec 04 10:12:46 2017 -0800 @@ -61,6 +61,7 @@ compiler.misc.fatal.err.cant.locate.field # Resolve, from Lower compiler.misc.fatal.err.cant.locate.meth # Resolve, from Lower compiler.misc.fatal.err.cant.close # JavaCompiler +compiler.misc.feature.not.supported.in.source.plural # cannot happen (for now) compiler.misc.file.does.not.contain.package compiler.misc.illegal.start.of.class.file compiler.misc.inferred.do.not.conform.to.lower.bounds # cannot happen? diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/AnnotationsAfterTypeParamsNotSupportedInSource.java --- a/test/langtools/tools/javac/diags/examples/AnnotationsAfterTypeParamsNotSupportedInSource.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/AnnotationsAfterTypeParamsNotSupportedInSource.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.annotations.after.type.params.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.annotations.after.type.params // key: compiler.warn.source.no.bootclasspath // options: -source 7 diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/DefaultMethodNotSupported.java --- a/test/langtools/tools/javac/diags/examples/DefaultMethodNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/DefaultMethodNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.default.methods.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.default.methods // options: -source 7 -Xlint:-options interface DefaultMethodNotSupported { diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/DiamondAndAnonClass.java --- a/test/langtools/tools/javac/diags/examples/DiamondAndAnonClass.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/DiamondAndAnonClass.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.misc.diamond.and.anon.class.not.supported.in.source +// key: compiler.misc.feature.not.supported.in.source +// key: compiler.misc.feature.diamond.and.anon.class // key: compiler.err.cant.apply.diamond.1 // key: compiler.warn.source.no.bootclasspath // options: -source 8 diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/DiamondNotSupported.java --- a/test/langtools/tools/javac/diags/examples/DiamondNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/DiamondNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.diamond.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source +// key: compiler.misc.feature.diamond // options: -source 6 -Xlint:-options import java.util.*; diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/IntersectionTypesInCastNotSupported.java --- a/test/langtools/tools/javac/diags/examples/IntersectionTypesInCastNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/IntersectionTypesInCastNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.intersection.types.in.cast.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.intersection.types.in.cast // options: -source 7 -Xlint:-options interface IntersectionTypesInCastNotSupported { diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/LambdaNotSupported.java --- a/test/langtools/tools/javac/diags/examples/LambdaNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/LambdaNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.lambda.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.lambda // options: -source 7 -Xlint:-options class LambdaNotSupported { diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/MethodReferencesNotSupported.java --- a/test/langtools/tools/javac/diags/examples/MethodReferencesNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/MethodReferencesNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.method.references.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.method.references // options: -source 7 -Xlint:-options class MethodReferencesNotSupported { diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/ModulesNotSupportedInSource/module-info.java --- a/test/langtools/tools/javac/diags/examples/ModulesNotSupportedInSource/module-info.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/ModulesNotSupportedInSource/module-info.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.modules.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.modules // key: compiler.warn.source.no.bootclasspath // options: -source 8 -Xlint:-path diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/MulticatchNotSupported.java --- a/test/langtools/tools/javac/diags/examples/MulticatchNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/MulticatchNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.multicatch.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.multicatch // options: -source 1.6 -Xlint:-options class MulticatchNotSupported { diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/PrivateInterfaceMethodsNotSupported.java --- a/test/langtools/tools/javac/diags/examples/PrivateInterfaceMethodsNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/PrivateInterfaceMethodsNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.private.intf.methods.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.private.intf.methods // key: compiler.warn.source.no.bootclasspath // options: -source 8 diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/RepeatableAnnotationsNotSupported.java --- a/test/langtools/tools/javac/diags/examples/RepeatableAnnotationsNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/RepeatableAnnotationsNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.repeatable.annotations.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.repeatable.annotations // key: compiler.warn.source.no.bootclasspath // options: -source 7 diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/StaticIntfMethodInvokeNotSupported.java --- a/test/langtools/tools/javac/diags/examples/StaticIntfMethodInvokeNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/StaticIntfMethodInvokeNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.static.intf.method.invoke.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.static.intf.method.invoke // options: -source 7 -Xlint:-options import java.util.stream.Stream; diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/StaticIntfMethodNotSupported.java --- a/test/langtools/tools/javac/diags/examples/StaticIntfMethodNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/StaticIntfMethodNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.static.intf.methods.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.static.intf.methods // options: -source 7 -Xlint:-options -XDallowStaticInterfaceMethods interface StaticIntfMethodNotSupported { diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/StringSwitchNotSupported.java --- a/test/langtools/tools/javac/diags/examples/StringSwitchNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/StringSwitchNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.string.switch.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.string.switch // options: -source 6 -Xlint:-options class StringSwitchNotSupported { diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/TryResourceNotSupported.java --- a/test/langtools/tools/javac/diags/examples/TryResourceNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/TryResourceNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.try.with.resources.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source +// key: compiler.misc.feature.try.with.resources // options: -source 1.6 -Xlint:-options import java.io.*; diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/TypeAnnotationsNotSupported.java --- a/test/langtools/tools/javac/diags/examples/TypeAnnotationsNotSupported.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/TypeAnnotationsNotSupported.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.type.annotations.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.type.annotations // key: compiler.warn.source.no.bootclasspath // options: -source 7 diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/UnsupportedBinaryLiteral.java --- a/test/langtools/tools/javac/diags/examples/UnsupportedBinaryLiteral.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/UnsupportedBinaryLiteral.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.unsupported.binary.lit +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.binary.lit // options: -source 6 -Xlint:-options class UnsupportedBinaryLiteral { diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/UnsupportedUnderscoreLiteral.java --- a/test/langtools/tools/javac/diags/examples/UnsupportedUnderscoreLiteral.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/UnsupportedUnderscoreLiteral.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.unsupported.underscore.lit +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.underscore.lit // options: -source 6 -Xlint:-options class UnsupportedUnderscoreLiteral { diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/diags/examples/VarInTryWithResourcesNotSupportedInSource.java --- a/test/langtools/tools/javac/diags/examples/VarInTryWithResourcesNotSupportedInSource.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/diags/examples/VarInTryWithResourcesNotSupportedInSource.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,7 +21,8 @@ * questions. */ -// key: compiler.err.var.in.try.with.resources.not.supported.in.source +// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.misc.feature.var.in.try.with.resources // key: compiler.warn.source.no.bootclasspath // options: -source 8 diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/generics/diamond/neg/Neg09a.out --- a/test/langtools/tools/javac/generics/diamond/neg/Neg09a.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/generics/diamond/neg/Neg09a.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,4 +1,4 @@ -- compiler.warn.source.no.bootclasspath: 1.8 -Neg09a.java:15:34: compiler.err.cant.apply.diamond.1: Neg09a.Member, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8) +- compiler.warn.source.no.bootclasspath: 8 +Neg09a.java:15:34: compiler.err.cant.apply.diamond.1: Neg09a.Member, (compiler.misc.feature.not.supported.in.source: (compiler.misc.feature.diamond.and.anon.class), 8, 9) 1 error 1 warning diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/generics/diamond/neg/Neg09b.out --- a/test/langtools/tools/javac/generics/diamond/neg/Neg09b.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/generics/diamond/neg/Neg09b.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,4 +1,4 @@ -- compiler.warn.source.no.bootclasspath: 1.8 -Neg09b.java:16:34: compiler.err.cant.apply.diamond.1: Neg09b.Nested, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8) +- compiler.warn.source.no.bootclasspath: 8 +Neg09b.java:16:34: compiler.err.cant.apply.diamond.1: Neg09b.Nested, (compiler.misc.feature.not.supported.in.source: (compiler.misc.feature.diamond.and.anon.class), 8, 9) 1 error 1 warning diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/generics/diamond/neg/Neg09c.out --- a/test/langtools/tools/javac/generics/diamond/neg/Neg09c.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/generics/diamond/neg/Neg09c.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,4 +1,4 @@ -- compiler.warn.source.no.bootclasspath: 1.8 -Neg09c.java:15:39: compiler.err.cant.apply.diamond.1: Neg09c.Member, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8) +- compiler.warn.source.no.bootclasspath: 8 +Neg09c.java:15:39: compiler.err.cant.apply.diamond.1: Neg09c.Member, (compiler.misc.feature.not.supported.in.source: (compiler.misc.feature.diamond.and.anon.class), 8, 9) 1 error 1 warning diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/generics/diamond/neg/Neg09d.out --- a/test/langtools/tools/javac/generics/diamond/neg/Neg09d.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/generics/diamond/neg/Neg09d.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,4 +1,4 @@ -- compiler.warn.source.no.bootclasspath: 1.8 +- compiler.warn.source.no.bootclasspath: 8 Neg09d.java:16:33: compiler.err.doesnt.exist: Neg09 1 error 1 warning diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/generics/inference/6278587/T6278587Neg.out --- a/test/langtools/tools/javac/generics/inference/6278587/T6278587Neg.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/generics/inference/6278587/T6278587Neg.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,4 +1,4 @@ -- compiler.warn.source.no.bootclasspath: 1.7 +- compiler.warn.source.no.bootclasspath: 7 T6278587Neg.java:18:10: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.lower.bounds: T, T6278587Neg.C) 1 error 1 warning diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/generics/odersky/BadTest4.out --- a/test/langtools/tools/javac/generics/odersky/BadTest4.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/generics/odersky/BadTest4.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,4 +1,4 @@ -- compiler.warn.source.no.bootclasspath: 1.7 +- compiler.warn.source.no.bootclasspath: 7 BadTest4.java:38:17: compiler.err.cant.apply.symbol: kindname.method, f, A,B, java.lang.Integer,java.lang.Number, kindname.class, BadTest4.Main, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Number, java.lang.Integer) 1 error 1 warning diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/lambda/SourceLevelTest.out --- a/test/langtools/tools/javac/lambda/SourceLevelTest.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/lambda/SourceLevelTest.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,6 +1,6 @@ -- compiler.warn.source.no.bootclasspath: 1.7 -SourceLevelTest.java:11:9: compiler.err.default.methods.not.supported.in.source: 1.7 -SourceLevelTest.java:18:17: compiler.err.lambda.not.supported.in.source: 1.7 -SourceLevelTest.java:19:20: compiler.err.method.references.not.supported.in.source: 1.7 +- compiler.warn.source.no.bootclasspath: 7 +SourceLevelTest.java:11:9: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.default.methods), 7, 8 +SourceLevelTest.java:18:17: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.lambda), 7, 8 +SourceLevelTest.java:19:20: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.method.references), 7, 8 3 errors 1 warning diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/literals/BadBinaryLiterals.6.out --- a/test/langtools/tools/javac/literals/BadBinaryLiterals.6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/literals/BadBinaryLiterals.6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,8 +1,6 @@ -BadBinaryLiterals.java:10:17: compiler.err.unsupported.binary.lit: 1.6 +BadBinaryLiterals.java:10:17: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.binary.lit), 6, 7 BadBinaryLiterals.java:11:24: compiler.err.expected: ';' -BadBinaryLiterals.java:13:21: compiler.err.int.number.too.large: 111111111111111111111111111111111 -BadBinaryLiterals.java:15:21: compiler.err.int.number.too.large: 11111111111111111111111111111111111111111111111111111111111111111 BadBinaryLiterals.java:16:27: compiler.err.expected: ';' BadBinaryLiterals.java:17:27: compiler.err.expected: ';' BadBinaryLiterals.java:17:30: compiler.err.expected: token.identifier -7 errors +5 errors diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/literals/BadUnderscoreLiterals.6.out --- a/test/langtools/tools/javac/literals/BadUnderscoreLiterals.6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/literals/BadUnderscoreLiterals.6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,7 +1,7 @@ -BadUnderscoreLiterals.java:11:17: compiler.err.unsupported.underscore.lit: 1.6 +BadUnderscoreLiterals.java:11:17: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.underscore.lit), 6, 7 BadUnderscoreLiterals.java:15:15: compiler.err.illegal.underscore BadUnderscoreLiterals.java:19:19: compiler.err.illegal.underscore -BadUnderscoreLiterals.java:22:14: compiler.err.unsupported.binary.lit: 1.6 +BadUnderscoreLiterals.java:22:14: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.binary.lit), 6, 7 BadUnderscoreLiterals.java:22:16: compiler.err.illegal.underscore BadUnderscoreLiterals.java:23:17: compiler.err.illegal.underscore BadUnderscoreLiterals.java:26:16: compiler.err.illegal.underscore diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/options/T6900037.out --- a/test/langtools/tools/javac/options/T6900037.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/options/T6900037.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,4 +1,4 @@ -- compiler.warn.source.no.bootclasspath: 1.8 +- compiler.warn.source.no.bootclasspath: 8 - compiler.err.warnings.and.werror 1 error 1 warning diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/parser/extend/TrialParser.java --- a/test/langtools/tools/javac/parser/extend/TrialParser.java Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/parser/extend/TrialParser.java Mon Dec 04 10:12:46 2017 -0800 @@ -21,6 +21,7 @@ * questions. */ +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.parser.JavacParser; import com.sun.tools.javac.parser.ParserFactory; @@ -186,7 +187,7 @@ List annosAfterParams = annotationsOpt(Tag.ANNOTATION); if (annosAfterParams.nonEmpty()) { - checkAnnotationsAfterTypeParams(annosAfterParams.head.pos); + checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS); mods.annotations = mods.annotations.appendList(annosAfterParams); if (mods.pos == Position.NOPOS) { mods.pos = mods.annotations.head.pos; diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/processing/warnings/gold_sv_warn_5_6.out --- a/test/langtools/tools/javac/processing/warnings/gold_sv_warn_5_6.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/processing/warnings/gold_sv_warn_5_6.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,2 +1,2 @@ -- compiler.warn.proc.processor.incompatible.source.version: RELEASE_5, TestSourceVersionWarnings, 1.6 +- compiler.warn.proc.processor.incompatible.source.version: RELEASE_5, TestSourceVersionWarnings, 6 1 warning diff -r 40afd72303e9 -r f27aad5782da test/langtools/tools/javac/varargs/6313164/T6313164Source7.out --- a/test/langtools/tools/javac/varargs/6313164/T6313164Source7.out Mon Dec 04 09:38:34 2017 -0800 +++ b/test/langtools/tools/javac/varargs/6313164/T6313164Source7.out Mon Dec 04 10:12:46 2017 -0800 @@ -1,4 +1,4 @@ -- compiler.warn.source.no.bootclasspath: 1.7 +- compiler.warn.source.no.bootclasspath: 7 T6313164.java:14:10: compiler.err.cant.apply.symbol: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) T6313164.java:19:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) T6313164.java:20:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)