changeset 2925:c93101925a2e

Add dependencies of 8013196 and remove SharedSecrets fragment of 8013196 which causes a TCK regression. 2013-08-05 Andrew John Hughes <gnu.andrew@redhat.com> * 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.
author Andrew John Hughes <gnu.andrew@redhat.com>
date Tue, 03 Sep 2013 18:35:49 +0100
parents 1efdc95c9ae0
children 44c41a07b14d
files ChangeLog Makefile.am patches/openjdk/6636331-appcontext_concurrentmodificationexception.patch patches/openjdk/6636370-appcontext_simplification.patch patches/openjdk/7196533-timezone_bottleneck.patch patches/openjdk/8013196-TimeZone_getDefault_throws_exception.patch
diffstat 6 files changed, 283 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- 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  <gnu.andrew@redhat.com>
+
+	* 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  <xerxes@zafena.se>
 
 	PR1188: ASM Interpreter and Thumb2 JIT javac miscompile
--- 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 += \
--- /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 <code>AppContext</code>s.
+      */
+     public static Set<AppContext> getAppContexts() {
+-        return new HashSet<AppContext>(threadGroup2appContext.values());
++        synchronized (threadGroup2appContext) {
++            return new HashSet<AppContext>(threadGroup2appContext.values());
++        }
+     }
+ 
+     /* The main "system" AppContext, used by everything not otherwise
--- /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<ClassLoader>() {
++                    public ClassLoader run() {
+                         return Thread.currentThread().getContextClassLoader();
+                     }
+                 });
+     }
+ 
+-    private static MostRecentThreadAppContext mostRecentThreadAppContext = null;
++    private static final ThreadLocal<AppContext> threadAppContext =
++            new ThreadLocal<AppContext>();
+ 
+     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<AppContext>()
++            {
++                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;
--- /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;
+ 
+ 
+     /**
--- 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;
-     }
- }