# HG changeset patch # User Andrew John Hughes # Date 1378229749 -3600 # Node ID c93101925a2ef36db9cb90865b6716707386ae74 # Parent 1efdc95c9ae0d65ee82a1715b118c2ca69883b81 Add dependencies of 8013196 and remove SharedSecrets fragment of 8013196 which causes a TCK regression. 2013-08-05 Andrew John Hughes * Makefile.am: (ICEDTEA_PATCHES): Add new patches. * patches/openjdk/6636331-appcontext_concurrentmodificationexception.patch, * patches/openjdk/6636370-appcontext_simplification.patch, * patches/openjdk/7196533-timezone_bottleneck.patch: Backport additional patches which relate to changes in 8013196. * patches/openjdk/8013196-TimeZone_getDefault_throws_exception.patch: Drop SharedSecrets changes which cause a TCK regression. diff -r 1efdc95c9ae0 -r c93101925a2e ChangeLog --- a/ChangeLog Tue Sep 03 18:10:04 2013 +0100 +++ b/ChangeLog Tue Sep 03 18:35:49 2013 +0100 @@ -1,3 +1,14 @@ +2013-08-05 Andrew John Hughes + + * Makefile.am: + (ICEDTEA_PATCHES): Add new patches. + * patches/openjdk/6636331-appcontext_concurrentmodificationexception.patch, + * patches/openjdk/6636370-appcontext_simplification.patch, + * patches/openjdk/7196533-timezone_bottleneck.patch: + Backport additional patches which relate to changes in 8013196. + * patches/openjdk/8013196-TimeZone_getDefault_throws_exception.patch: + Drop SharedSecrets changes which cause a TCK regression. + 2013-05-28 Xerxes RĂ„nby PR1188: ASM Interpreter and Thumb2 JIT javac miscompile diff -r 1efdc95c9ae0 -r c93101925a2e Makefile.am --- a/Makefile.am Tue Sep 03 18:10:04 2013 +0100 +++ b/Makefile.am Tue Sep 03 18:35:49 2013 +0100 @@ -653,7 +653,10 @@ patches/openjdk/8002225-tzdata2012i.patch \ patches/openjdk/8009987-tzdata2013b.patch \ patches/openjdk/6840152-jvm_crashes_with_heavyweight_monitors.patch \ - patches/openjdk/7022999-fastlocking_compiler1_only.patch + patches/openjdk/7022999-fastlocking_compiler1_only.patch \ + patches/openjdk/7196533-timezone_bottleneck.patch \ + patches/openjdk/6636370-appcontext_simplification.patch \ + patches/openjdk/6636331-appcontext_concurrentmodificationexception.patch if WITH_RHINO ICEDTEA_PATCHES += \ diff -r 1efdc95c9ae0 -r c93101925a2e patches/openjdk/6636331-appcontext_concurrentmodificationexception.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6636331-appcontext_concurrentmodificationexception.patch Tue Sep 03 18:35:49 2013 +0100 @@ -0,0 +1,24 @@ +# HG changeset patch +# User son +# Date 1205416264 -10800 +# Thu Mar 13 16:51:04 2008 +0300 +# Node ID c9ee9428aea9baa8e32691db1e14744002c70def +# Parent bbd8e20d50523bbd89d10204e4f337a844f3cef1 +6636331: ConcurrentModificationException in AppContext code +Summary: Added synchronization to AppContext.getAppContexts() +Reviewed-by: art + +diff --git a/src/share/classes/sun/awt/AppContext.java b/src/share/classes/sun/awt/AppContext.java +--- openjdk/jdk/src/share/classes/sun/awt/AppContext.java ++++ openjdk/jdk/src/share/classes/sun/awt/AppContext.java +@@ -146,7 +146,9 @@ + * Returns a set containing all AppContexts. + */ + public static Set getAppContexts() { +- return new HashSet(threadGroup2appContext.values()); ++ synchronized (threadGroup2appContext) { ++ return new HashSet(threadGroup2appContext.values()); ++ } + } + + /* The main "system" AppContext, used by everything not otherwise diff -r 1efdc95c9ae0 -r c93101925a2e patches/openjdk/6636370-appcontext_simplification.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6636370-appcontext_simplification.patch Tue Sep 03 18:35:49 2013 +0100 @@ -0,0 +1,178 @@ +diff -Nru openjdk.orig/jdk/src/share/classes/sun/awt/AppContext.java openjdk/jdk/src/share/classes/sun/awt/AppContext.java +--- openjdk.orig/jdk/src/share/classes/sun/awt/AppContext.java 2013-08-05 16:49:37.120128300 +0100 ++++ openjdk/jdk/src/share/classes/sun/awt/AppContext.java 2013-08-05 17:02:51.304664462 +0100 +@@ -151,7 +151,7 @@ + contained in another AppContext. It is implicitly created for + standalone apps only (i.e. not applets) + */ +- private static AppContext mainAppContext = null; ++ private static volatile AppContext mainAppContext = null; + + /* + * The hash map associated with this AppContext. A private delegate +@@ -223,14 +223,15 @@ + threadGroup2appContext.put(threadGroup, this); + + this.contextClassLoader = +- (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { +- public Object run() { ++ AccessController.doPrivileged(new PrivilegedAction() { ++ public ClassLoader run() { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + +- private static MostRecentThreadAppContext mostRecentThreadAppContext = null; ++ private static final ThreadLocal threadAppContext = ++ new ThreadLocal(); + + private final static void initMainAppContext() { + // On the main Thread, we get the ThreadGroup, make a corresponding +@@ -270,30 +271,18 @@ + return mainAppContext; + } + +- final Thread currentThread = Thread.currentThread(); ++ AppContext appContext = threadAppContext.get(); + +- AppContext appContext = null; +- +- // Note: this most recent Thread/AppContext caching is thread-hot. +- // A simple test using SwingSet found that 96.8% of lookups +- // were matched using the most recent Thread/AppContext. By +- // instantiating a simple MostRecentThreadAppContext object on +- // cache misses, the cache hits can be processed without +- // synchronization. +- +- MostRecentThreadAppContext recent = mostRecentThreadAppContext; +- if ((recent != null) && (recent.thread == currentThread)) { +- appContext = recent.appContext; // Cache hit +- } else { +- appContext = (AppContext)AccessController.doPrivileged( +- new PrivilegedAction() { +- public Object run() { +- // Get the current ThreadGroup, and look for it and its +- // parents in the hash from ThreadGroup to AppContext -- +- // it should be found, because we use createNewContext() +- // when new AppContext objects are created. +- ThreadGroup currentThreadGroup = currentThread.getThreadGroup(); +- ThreadGroup threadGroup = currentThreadGroup; ++ if (null == appContext) { ++ appContext = AccessController.doPrivileged(new PrivilegedAction() ++ { ++ public AppContext run() { ++ // Get the current ThreadGroup, and look for it and its ++ // parents in the hash from ThreadGroup to AppContext -- ++ // it should be found, because we use createNewContext() ++ // when new AppContext objects are created. ++ ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup(); ++ ThreadGroup threadGroup = currentThreadGroup; + + // Special case: we implicitly create the main app context + // if no contexts have been created yet. This covers standalone apps +@@ -308,28 +297,29 @@ + } + } + +- AppContext context = threadGroup2appContext.get(threadGroup); +- while (context == null) { +- threadGroup = threadGroup.getParent(); +- if (threadGroup == null) { +- return null; ++ AppContext context = threadGroup2appContext.get(threadGroup); ++ while (context == null) { ++ threadGroup = threadGroup.getParent(); ++ if (threadGroup == null) { ++ return null; ++ } ++ context = threadGroup2appContext.get(threadGroup); ++ } ++ ++ // In case we did anything in the above while loop, we add ++ // all the intermediate ThreadGroups to threadGroup2appContext ++ // so we won't spin again. ++ for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) { ++ threadGroup2appContext.put(tg, context); ++ } ++ ++ // Now we're done, so we cache the latest key/value pair. ++ threadAppContext.set(context); ++ ++ ++ return context; + } +- context = threadGroup2appContext.get(threadGroup); +- } +- // In case we did anything in the above while loop, we add +- // all the intermediate ThreadGroups to threadGroup2appContext +- // so we won't spin again. +- for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) { +- threadGroup2appContext.put(tg, context); +- } +- +- // Now we're done, so we cache the latest key/value pair. +- mostRecentThreadAppContext = +- new MostRecentThreadAppContext(currentThread, context); +- +- return context; +- } +- }); ++ }); + } + + return appContext; +@@ -473,7 +463,7 @@ + // Threads in the ThreadGroup to exit. + + long startTime = System.currentTimeMillis(); +- long endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT; ++ long endTime = startTime + THREAD_INTERRUPT_TIMEOUT; + while ((this.threadGroup.activeCount() > 0) && + (System.currentTimeMillis() < endTime)) { + try { +@@ -488,7 +478,7 @@ + // Threads in the ThreadGroup to die. + + startTime = System.currentTimeMillis(); +- endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT; ++ endTime = startTime + THREAD_INTERRUPT_TIMEOUT; + while ((this.threadGroup.activeCount() > 0) && + (System.currentTimeMillis() < endTime)) { + try { +@@ -507,10 +497,7 @@ + } + threadGroup2appContext.remove(this.threadGroup); + +- MostRecentThreadAppContext recent = mostRecentThreadAppContext; +- if ((recent != null) && (recent.appContext == this)) +- mostRecentThreadAppContext = null; +- // If the "most recent" points to this, clear it for GC ++ threadAppContext.set(null); + + // Finally, we destroy the ThreadGroup entirely. + try { +@@ -693,6 +680,7 @@ + * Returns a string representation of this AppContext. + * @since 1.2 + */ ++ @Override + public String toString() { + return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]"; + } +@@ -842,15 +830,6 @@ + } + } + +-final class MostRecentThreadAppContext { +- final Thread thread; +- final AppContext appContext; +- MostRecentThreadAppContext(Thread key, AppContext value) { +- thread = key; +- appContext = value; +- } +-} +- + final class MostRecentKeyValue { + Object key; + Object value; diff -r 1efdc95c9ae0 -r c93101925a2e patches/openjdk/7196533-timezone_bottleneck.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/7196533-timezone_bottleneck.patch Tue Sep 03 18:35:49 2013 +0100 @@ -0,0 +1,66 @@ +diff -Nru openjdk.orig/jdk/src/share/classes/java/util/TimeZone.java openjdk/jdk/src/share/classes/java/util/TimeZone.java +--- openjdk.orig/jdk/src/share/classes/java/util/TimeZone.java 2012-10-26 19:25:53.000000000 +0100 ++++ openjdk/jdk/src/share/classes/java/util/TimeZone.java 2013-08-05 14:46:18.022264343 +0100 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it +@@ -646,9 +646,15 @@ + * Returns the default TimeZone in an AppContext if any AppContext + * has ever used. null is returned if any AppContext hasn't been + * used or if the AppContext doesn't have the default TimeZone. ++ * ++ * Note that javaAWTAccess may be null if sun.awt.AppContext class hasn't ++ * been loaded. If so, it implies that AWTSecurityManager is not our ++ * SecurityManager and we can use a local static variable. ++ * This works around a build time issue. + */ +- private synchronized static TimeZone getDefaultInAppContext() { +- javaAWTAccess = SharedSecrets.getJavaAWTAccess(); ++ private static TimeZone getDefaultInAppContext() { ++ // JavaAWTAccess provides access implementation-private methods without using reflection. ++ JavaAWTAccess javaAWTAccess = SharedSecrets.getJavaAWTAccess(); + if (javaAWTAccess == null) { + return mainAppContextDefault; + } else { +@@ -670,9 +676,15 @@ + * tz. null is handled special: do nothing if any AppContext + * hasn't been used, remove the default TimeZone in the + * AppContext otherwise. ++ * ++ * Note that javaAWTAccess may be null if sun.awt.AppContext class hasn't ++ * been loaded. If so, it implies that AWTSecurityManager is not our ++ * SecurityManager and we can use a local static variable. ++ * This works around a build time issue. + */ +- private synchronized static void setDefaultInAppContext(TimeZone tz) { +- javaAWTAccess = SharedSecrets.getJavaAWTAccess(); ++ private static void setDefaultInAppContext(TimeZone tz) { ++ // JavaAWTAccess provides access implementation-private methods without using reflection. ++ JavaAWTAccess javaAWTAccess = SharedSecrets.getJavaAWTAccess(); + if (javaAWTAccess == null) { + mainAppContextDefault = tz; + } else { +@@ -736,18 +748,8 @@ + static final String GMT_ID = "GMT"; + private static final int GMT_ID_LENGTH = 3; + +- /* +- * Provides access implementation-private methods without using reflection +- * +- * Note that javaAWTAccess may be null if sun.awt.AppContext class hasn't +- * been loaded. If so, it implies that AWTSecurityManager is not our +- * SecurityManager and we can use a local static variable. +- * This works around a build time issue. +- */ +- private static JavaAWTAccess javaAWTAccess; +- + // a static TimeZone we can reference if no AppContext is in place +- private static TimeZone mainAppContextDefault; ++ private static volatile TimeZone mainAppContextDefault; + + + /** diff -r 1efdc95c9ae0 -r c93101925a2e patches/openjdk/8013196-TimeZone_getDefault_throws_exception.patch --- a/patches/openjdk/8013196-TimeZone_getDefault_throws_exception.patch Tue Sep 03 18:10:04 2013 +0100 +++ b/patches/openjdk/8013196-TimeZone_getDefault_throws_exception.patch Tue Sep 03 18:35:49 2013 +0100 @@ -37,22 +37,3 @@ } public boolean isMainAppContext() { return (numAppContexts.get() == 1 && mainAppContext != null); ---- openjdk/jdk/src/share/classes/sun/misc/SharedSecrets.java -+++ openjdk/jdk/src/share/classes/sun/misc/SharedSecrets.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -174,6 +174,9 @@ - public static JavaAWTAccess getJavaAWTAccess() { - // this may return null in which case calling code needs to - // provision for. -+ if (javaAWTAccess == null || javaAWTAccess.getContext() == null) { -+ return null; -+ } - return javaAWTAccess; - } - }