summaryrefslogtreecommitdiff
path: root/java/openjdk6/files/icedtea/openjdk/5102804-memory_leak.patch
diff options
context:
space:
mode:
Diffstat (limited to 'java/openjdk6/files/icedtea/openjdk/5102804-memory_leak.patch')
-rw-r--r--java/openjdk6/files/icedtea/openjdk/5102804-memory_leak.patch429
1 files changed, 0 insertions, 429 deletions
diff --git a/java/openjdk6/files/icedtea/openjdk/5102804-memory_leak.patch b/java/openjdk6/files/icedtea/openjdk/5102804-memory_leak.patch
deleted file mode 100644
index 01dd35c1bee2..000000000000
--- a/java/openjdk6/files/icedtea/openjdk/5102804-memory_leak.patch
+++ /dev/null
@@ -1,429 +0,0 @@
-# HG changeset patch
-# User andrew
-# Date 1365704033 -3600
-# Node ID 06255d9f82761abc74c30f31fda00968ffef4bc3
-# Parent a939f541de9af5ccb78225c27cd46cd7dc6bcf87
-5102804: Memory leak in Introspector.getBeanInfo(Class) for custom BeanInfo: Class param (includes WeakCache from 6397609)
-Reviewed-by: peterz
-
-diff --git a/src/share/classes/com/sun/beans/WeakCache.java b/src/share/classes/com/sun/beans/WeakCache.java
-new file mode 100644
---- /dev/null
-+++ jdk/src/share/classes/com/sun/beans/WeakCache.java
-@@ -0,0 +1,91 @@
-+/*
-+ * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
-+ * particular file as subject to the "Classpath" exception as provided
-+ * by Sun in the LICENSE file that accompanied this code.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-+ * CA 95054 USA or visit www.sun.com if you need additional information or
-+ * have any questions.
-+ */
-+package com.sun.beans;
-+
-+import java.lang.ref.Reference;
-+import java.lang.ref.WeakReference;
-+
-+import java.util.Map;
-+import java.util.WeakHashMap;
-+
-+/**
-+ * A hashtable-based cache with weak keys and weak values.
-+ * An entry in the map will be automatically removed
-+ * when its key is no longer in the ordinary use.
-+ * A value will be automatically removed as well
-+ * when it is no longer in the ordinary use.
-+ *
-+ * @since 1.7
-+ *
-+ * @author Sergey A. Malenkov
-+ */
-+public final class WeakCache<K, V> {
-+ private final Map<K, Reference<V>> map = new WeakHashMap<K, Reference<V>>();
-+
-+ /**
-+ * Returns a value to which the specified {@code key} is mapped,
-+ * or {@code null} if this map contains no mapping for the {@code key}.
-+ *
-+ * @param key the key whose associated value is returned
-+ * @return a value to which the specified {@code key} is mapped
-+ */
-+ public V get(K key) {
-+ Reference<V> reference = this.map.get(key);
-+ if (reference == null) {
-+ return null;
-+ }
-+ V value = reference.get();
-+ if (value == null) {
-+ this.map.remove(key);
-+ }
-+ return value;
-+ }
-+
-+ /**
-+ * Associates the specified {@code value} with the specified {@code key}.
-+ * Removes the mapping for the specified {@code key} from this cache
-+ * if it is present and the specified {@code value} is {@code null}.
-+ * If the cache previously contained a mapping for the {@code key},
-+ * the old value is replaced by the specified {@code value}.
-+ *
-+ * @param key the key with which the specified value is associated
-+ * @param value the value to be associated with the specified key
-+ */
-+ public void put(K key, V value) {
-+ if (value != null) {
-+ this.map.put(key, new WeakReference<V>(value));
-+ }
-+ else {
-+ this.map.remove(key);
-+ }
-+ }
-+
-+ /**
-+ * Removes all of the mappings from this cache.
-+ */
-+ public void clear() {
-+ this.map.clear();
-+ }
-+}
-diff --git a/src/share/classes/java/beans/Introspector.java b/src/share/classes/java/beans/Introspector.java
---- jdk/src/share/classes/java/beans/Introspector.java
-+++ jdk/src/share/classes/java/beans/Introspector.java
-@@ -25,25 +25,18 @@
-
- package java.beans;
-
-+import com.sun.beans.WeakCache;
- import com.sun.beans.finder.ClassFinder;
-
--import java.lang.ref.Reference;
--import java.lang.ref.SoftReference;
--
- import java.lang.reflect.Method;
- import java.lang.reflect.Modifier;
-
--import java.security.AccessController;
--import java.security.PrivilegedAction;
--
--import java.util.Collections;
- import java.util.Map;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.EventListener;
- import java.util.List;
--import java.util.WeakHashMap;
- import java.util.TreeMap;
- import sun.awt.AppContext;
- import sun.reflect.misc.ReflectUtil;
-@@ -110,8 +103,8 @@
- public final static int IGNORE_ALL_BEANINFO = 3;
-
- // Static Caches to speed up introspection.
-- private static Map declaredMethodCache =
-- Collections.synchronizedMap(new WeakHashMap());
-+ private static WeakCache<Class<?>, Method[]> declaredMethodCache =
-+ new WeakCache<Class<?>, Method[]>();
-
- private static final Object BEANINFO_CACHE = new Object();
-
-@@ -177,20 +170,21 @@
- if (!ReflectUtil.isPackageAccessible(beanClass)) {
- return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
- }
-- Map<Class<?>, BeanInfo> map;
- synchronized (BEANINFO_CACHE) {
-- map = (Map<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE);
-- if (map == null) {
-- map = Collections.synchronizedMap(new WeakHashMap<Class<?>, BeanInfo>());
-- AppContext.getAppContext().put(BEANINFO_CACHE, map);
-+ WeakCache<Class<?>, BeanInfo> beanInfoCache =
-+ (WeakCache<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE);
-+
-+ if (beanInfoCache == null) {
-+ beanInfoCache = new WeakCache<Class<?>, BeanInfo>();
-+ AppContext.getAppContext().put(BEANINFO_CACHE, beanInfoCache);
- }
-+ BeanInfo beanInfo = beanInfoCache.get(beanClass);
-+ if (beanInfo == null) {
-+ beanInfo = (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
-+ beanInfoCache.put(beanClass, beanInfo);
-+ }
-+ return beanInfo;
- }
-- BeanInfo bi = map.get(beanClass);
-- if (bi == null) {
-- bi = (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
-- map.put(beanClass, bi);
-- }
-- return bi;
- }
-
- /**
-@@ -337,11 +331,13 @@
- */
-
- public static void flushCaches() {
-- Map map = (Map) AppContext.getAppContext().get(BEANINFO_CACHE);
-- if (map != null) {
-- map.clear();
-+ synchronized (BEANINFO_CACHE) {
-+ WeakCache beanInfoCache = (WeakCache) AppContext.getAppContext().get(BEANINFO_CACHE);
-+ if (beanInfoCache != null) {
-+ beanInfoCache.clear();
-+ }
-+ declaredMethodCache.clear();
- }
-- declaredMethodCache.clear();
- }
-
- /**
-@@ -363,11 +359,13 @@
- if (clz == null) {
- throw new NullPointerException();
- }
-- Map map = (Map) AppContext.getAppContext().get(BEANINFO_CACHE);
-- if (map != null) {
-- map.remove(clz);
-+ synchronized (BEANINFO_CACHE) {
-+ WeakCache beanInfoCache = (WeakCache) AppContext.getAppContext().get(BEANINFO_CACHE);
-+ if (beanInfoCache != null) {
-+ beanInfoCache.put(clz, null);
-+ }
-+ declaredMethodCache.put(clz, null);
- }
-- declaredMethodCache.remove(clz);
- }
-
- //======================================================================
-@@ -1306,41 +1304,26 @@
- /*
- * Internal method to return *public* methods within a class.
- */
-- private static synchronized Method[] getPublicDeclaredMethods(Class clz) {
-+ private static Method[] getPublicDeclaredMethods(Class clz) {
- // Looking up Class.getDeclaredMethods is relatively expensive,
- // so we cache the results.
-- Method[] result = null;
- if (!ReflectUtil.isPackageAccessible(clz)) {
- return new Method[0];
- }
-- final Class fclz = clz;
-- Reference ref = (Reference)declaredMethodCache.get(fclz);
-- if (ref != null) {
-- result = (Method[])ref.get();
-- if (result != null) {
-- return result;
-+ synchronized (BEANINFO_CACHE) {
-+ Method[] result = declaredMethodCache.get(clz);
-+ if (result == null) {
-+ result = clz.getMethods();
-+ for (int i = 0; i < result.length; i++) {
-+ Method method = result[i];
-+ if (!method.getDeclaringClass().equals(clz)) {
-+ result[i] = null;
-+ }
-+ }
-+ declaredMethodCache.put(clz, result);
- }
-+ return result;
- }
--
-- // We have to raise privilege for getDeclaredMethods
-- result = (Method[]) AccessController.doPrivileged(new PrivilegedAction() {
-- public Object run() {
-- return fclz.getDeclaredMethods();
-- }
-- });
--
--
-- // Null out any non-public methods.
-- for (int i = 0; i < result.length; i++) {
-- Method method = result[i];
-- int mods = method.getModifiers();
-- if (!Modifier.isPublic(mods)) {
-- result[i] = null;
-- }
-- }
-- // Add it to the cache.
-- declaredMethodCache.put(fclz, new SoftReference(result));
-- return result;
- }
-
- //======================================================================
-diff --git a/test/java/beans/Introspector/Test5102804.java b/test/java/beans/Introspector/Test5102804.java
-new file mode 100644
---- /dev/null
-+++ jdk/test/java/beans/Introspector/Test5102804.java
-@@ -0,0 +1,155 @@
-+/*
-+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-+ * CA 95054 USA or visit www.sun.com if you need additional information or
-+ * have any questions.
-+ */
-+
-+/*
-+ * @test
-+ * @bug 5102804
-+ * @summary Tests memory leak
-+ * @author Sergey Malenkov
-+ */
-+
-+import java.beans.BeanInfo;
-+import java.beans.IntrospectionException;
-+import java.beans.Introspector;
-+import java.beans.PropertyDescriptor;
-+import java.beans.SimpleBeanInfo;
-+import java.lang.ref.Reference;
-+import java.lang.ref.WeakReference;
-+import java.net.URL;
-+import java.net.URLClassLoader;
-+
-+public class Test5102804 {
-+ private static final String BEAN_NAME = "Test5102804$Example";
-+ private static final String BEAN_INFO_NAME = BEAN_NAME + "BeanInfo";
-+
-+ public static void main(String[] args) {
-+ if (!isCollectible(getReference()))
-+ throw new Error("Reference is not collected");
-+ }
-+
-+ private static Reference getReference() {
-+ try {
-+ ClassLoader loader = new Loader();
-+ Class type = Class.forName(BEAN_NAME, true, loader);
-+ if (!type.getClassLoader().equals(loader)) {
-+ throw new Error("Wrong class loader");
-+ }
-+ BeanInfo info = Introspector.getBeanInfo(type);
-+ if (0 != info.getDefaultPropertyIndex()) {
-+ throw new Error("Wrong bean info found");
-+ }
-+ return new WeakReference<Class>(type);
-+ }
-+ catch (IntrospectionException exception) {
-+ throw new Error("Introspection Error", exception);
-+ }
-+ catch (ClassNotFoundException exception) {
-+ throw new Error("Class Not Found", exception);
-+ }
-+ }
-+
-+ private static boolean isCollectible(Reference reference) {
-+ int[] array = new int[10];
-+ while (true) {
-+ try {
-+ array = new int[array.length + array.length / 3];
-+ }
-+ catch (OutOfMemoryError error) {
-+ return null == reference.get();
-+ }
-+ }
-+ }
-+
-+ /**
-+ * Custom class loader to load the Example class by itself.
-+ * Could also load it from a different code source, but this is easier to set up.
-+ */
-+ private static final class Loader extends URLClassLoader {
-+ Loader() {
-+ super(new URL[] {
-+ Test5102804.class.getProtectionDomain().getCodeSource().getLocation()
-+ });
-+ }
-+
-+ @Override
-+ protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
-+ Class c = findLoadedClass(name);
-+ if (c == null) {
-+ if (BEAN_NAME.equals(name) || BEAN_INFO_NAME.equals(name)) {
-+ c = findClass(name);
-+ }
-+ else try {
-+ c = getParent().loadClass(name);
-+ }
-+ catch (ClassNotFoundException exception) {
-+ c = findClass(name);
-+ }
-+ }
-+ if (resolve) {
-+ resolveClass(c);
-+ }
-+ return c;
-+ }
-+ }
-+
-+ /**
-+ * A simple bean to load from the Loader class, not main class loader.
-+ */
-+ public static final class Example {
-+ private int value;
-+
-+ public int getValue() {
-+ return value;
-+ }
-+
-+ public void setValue(int value) {
-+ this.value = value;
-+ }
-+ }
-+
-+ /**
-+ * The BeanInfo for the Example class.
-+ * It is also loaded from the Loader class.
-+ */
-+ public static final class ExampleBeanInfo extends SimpleBeanInfo {
-+ @Override
-+ public int getDefaultPropertyIndex() {
-+ return 0;
-+ }
-+
-+ @Override
-+ public PropertyDescriptor[] getPropertyDescriptors() {
-+ try {
-+ return new PropertyDescriptor[] {
-+ new PropertyDescriptor("value", Class.forName(BEAN_NAME))
-+ };
-+ }
-+ catch (ClassNotFoundException exception) {
-+ return null;
-+ }
-+ catch (IntrospectionException exception) {
-+ return null;
-+ }
-+ }
-+ }
-+}