Fix Bug 414554 - ClassCache should use WeakHashMap

This commit is contained in:
nboyd%atg.com 2008-01-29 14:34:32 +00:00
Родитель d5c5d75bb1
Коммит 657e75be5e
3 изменённых файлов: 41 добавлений и 28 удалений

Просмотреть файл

@ -23,6 +23,7 @@
*
* Contributor(s):
* Igor Bukanov, igor@fastmail.fm
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
@ -38,7 +39,8 @@
package org.mozilla.javascript;
import java.util.Hashtable;
import java.util.Map;
import java.util.WeakHashMap;
/**
* Cache of generated classes and data structures to access Java runtime
@ -51,17 +53,14 @@ import java.util.Hashtable;
public class ClassCache
{
private static final Object AKEY = new Object();
private volatile boolean cachingIsEnabled = true;
Hashtable classTable = new Hashtable();
Hashtable javaAdapterGeneratedClasses = new Hashtable();
ScriptableObject scope;
private Hashtable interfaceAdapterCache;
private WeakHashMap<Class<?>,JavaMembers> classTable
= new WeakHashMap<Class<?>,JavaMembers>();
private WeakHashMap<Class<?>,JavaMembers> javaAdapterGeneratedClasses
= new WeakHashMap<Class<?>,JavaMembers>();
private WeakHashMap<JavaAdapter.JavaAdapterSignature,Class<?>> classAdapterCache
= new WeakHashMap<JavaAdapter.JavaAdapterSignature,Class<?>>();
private WeakHashMap<Class<?>,Object> interfaceAdapterCache;
private int generatedClassSerial;
/**
@ -93,7 +92,7 @@ public class ClassCache
* The ClassCache object can only be associated with the given scope once.
*
* @param topScope scope to associate this ClassCache object with.
* @return true if no prevous ClassCache objects were embedded into
* @return true if no previous ClassCache objects were embedded into
* the scope and this ClassCache were successfully associated
* or false otherwise.
*
@ -105,8 +104,7 @@ public class ClassCache
// Can only associate cache with top level scope
throw new IllegalArgumentException();
}
if(this == topScope.associateValue(AKEY, this)) {
scope = topScope;
if (this == topScope.associateValue(AKEY, this)) {
return true;
}
return false;
@ -117,8 +115,9 @@ public class ClassCache
*/
public synchronized void clearCaches()
{
classTable = new Hashtable();
javaAdapterGeneratedClasses = new Hashtable();
classTable.clear();
javaAdapterGeneratedClasses.clear();
classAdapterCache.clear();
interfaceAdapterCache = null;
}
@ -157,7 +156,19 @@ public class ClassCache
clearCaches();
cachingIsEnabled = enabled;
}
/**
* @return a map from classes to associated JavaMembers objects
*/
Map<Class<?>,JavaMembers> getClassCacheMap() {
return classTable;
}
Map<JavaAdapter.JavaAdapterSignature,Class<?>> getInterfaceAdapterCacheMap()
{
return classAdapterCache;
}
/**
* @deprecated
* The method always returns false.
@ -172,8 +183,8 @@ public class ClassCache
* @deprecated
* The method does nothing.
* Invoker optimization is no longer used by Rhino.
* On modern JDK like 1.4 or 1.5 the disadvatages of the optimization
* like incresed memory usage or longer initialization time overweight
* On modern JDK like 1.4 or 1.5 the disadvantages of the optimization
* like increased memory usage or longer initialization time overweight
* small speed increase that can be gained using generated proxy class
* to replace reflection.
*/
@ -190,10 +201,10 @@ public class ClassCache
return ++generatedClassSerial;
}
Object getInterfaceAdapter(Class cl)
Object getInterfaceAdapter(Class<?> cl)
{
Object result;
Hashtable cache = interfaceAdapterCache;
WeakHashMap<Class<?>,Object> cache = interfaceAdapterCache;
if (cache == null) {
result = null;
} else {
@ -202,11 +213,11 @@ public class ClassCache
return result;
}
synchronized void cacheInterfaceAdapter(Class cl, Object iadapter)
synchronized void cacheInterfaceAdapter(Class<?> cl, Object iadapter)
{
if (cachingIsEnabled) {
if (interfaceAdapterCache == null) {
interfaceAdapterCache = new Hashtable();
interfaceAdapterCache = new WeakHashMap<Class<?>,Object>();
}
interfaceAdapterCache.put(cl, iadapter);
}

Просмотреть файл

@ -302,12 +302,13 @@ public final class JavaAdapter implements IdFunctionCall
Class[] interfaces, Scriptable obj)
{
ClassCache cache = ClassCache.get(scope);
Hashtable generated = cache.javaAdapterGeneratedClasses;
Map<JavaAdapterSignature,Class<?>> generated
= cache.getInterfaceAdapterCacheMap();
ObjToIntMap names = getObjectFunctionNames(obj);
JavaAdapterSignature sig;
sig = new JavaAdapterSignature(superClass, interfaces, names);
Class adapterClass = (Class) generated.get(sig);
Class<?> adapterClass = generated.get(sig);
if (adapterClass == null) {
String adapterName = "adapter"
+ cache.newClassSerialNumber();

Просмотреть файл

@ -807,17 +807,18 @@ class JavaMembers
Class staticType, boolean includeProtected)
{
JavaMembers members;
scope = ScriptableObject.getTopLevelScope(scope);
ClassCache cache = ClassCache.get(scope);
Hashtable ct = cache.classTable;
Map<Class<?>,JavaMembers> ct = cache.getClassCacheMap();
Class cl = dynamicType;
for (;;) {
members = (JavaMembers)ct.get(cl);
members = ct.get(cl);
if (members != null) {
return members;
}
try {
members = new JavaMembers(cache.scope, cl, includeProtected);
members = new JavaMembers(scope, cl, includeProtected);
break;
} catch (SecurityException e) {
// Reflection may fail for objects that are in a restricted