/interpreter/tags/at_build150307/src/edu/vub/at/objects/symbiosis/JMethodCache.java
Java | 119 lines | 49 code | 11 blank | 59 comment | 9 complexity | 9983109c70e7e6389f4dd8504d9f2409 MD5 | raw file
1/** 2 * AmbientTalk/2 Project 3 * JMethodCache.java created on 9-dec-2006 at 17:14:55 4 * (c) Programming Technology Lab, 2006 - 2007 5 * Authors: Tom Van Cutsem & Stijn Mostinckx 6 * 7 * Permission is hereby granted, free of charge, to any person 8 * obtaining a copy of this software and associated documentation 9 * files (the "Software"), to deal in the Software without 10 * restriction, including without limitation the rights to use, 11 * copy, modify, merge, publish, distribute, sublicense, and/or 12 * sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following 14 * conditions: 15 * 16 * The above copyright notice and this permission notice shall be 17 * included in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 * OTHER DEALINGS IN THE SOFTWARE. 27 */ 28package edu.vub.at.objects.symbiosis; 29 30import java.lang.ref.SoftReference; 31import java.util.Collections; 32import java.util.Hashtable; 33import java.util.Map; 34 35/** 36 * A singleton object that represents a method cache. It is used to speed up 37 * the symbiosis with Java. Every time a JavaMethod is successfully created from 38 * an array of java.lang.reflect.Method objects, it is stored in the cache. 39 * The cache uses weak references such that JavaMethod instances can be safely recollected 40 * when they are no longer used. Note that this caching scheme only works because: 41 * - Java classes are unmodifyable at runtime 42 * - JavaMethod objects are constant, so may be safely shared between different actors 43 * 44 * The method cache is implemented as a hash map, mapping pairs 45 * [ java.lang.Class class, java.lang.String methodname, boolean isStatic ] => soft ref to JavaMethod 46 * 47 * If a JavaMethod has been garbage collected, its entry is removed from the cache. 48 * Soft references rather than weak references are used to point to the JavaMethod entries. 49 * Soft references are like weak references, but normally only get reclaimed when the 50 * JVM runs low on memory. Hence, they are much more suitable for caching. 51 * 52 * The cache is synchronized to ensure proper synchronization between different actors. 53 * 54 * @author tvcutsem 55 */ 56public final class JMethodCache { 57 58 public static final JMethodCache _INSTANCE_ = new JMethodCache(); 59 60 private final Map cache_; 61 62 private JMethodCache() { 63 cache_ = Collections.synchronizedMap(new Hashtable()); 64 } 65 66 /** 67 * Add a JavaMethod instance to the cache. 68 */ 69 public void put(Class cls, String methName, boolean isStatic, JavaMethod entry) { 70 cache_.put(new CacheKey(cls, methName, isStatic), new SoftReference(entry)); 71 } 72 73 /** 74 * Retrieve a JavaMethod entry from the cache. 75 * @return the entry, or null if the cache does not contain the entry 76 */ 77 public JavaMethod get(Class cls, String methName, boolean isStatic) { 78 CacheKey key = new CacheKey(cls, methName, isStatic); 79 SoftReference ref = (SoftReference) cache_.get(key); 80 if (ref == null) { 81 return null; // cache miss 82 } else { 83 JavaMethod entry = (JavaMethod) ref.get(); 84 if (entry != null) { 85 // cache hit 86 return entry; 87 } else { 88 // entry was garbage-collected, clean up the mapping 89 cache_.remove(key); 90 return null; // cache miss 91 } 92 } 93 } 94 95 private static class CacheKey { 96 private final Class class_; 97 private final String methodName_; 98 private final boolean isStatic_; 99 public CacheKey(Class c, String mname, boolean isStatic) { 100 class_ = c; 101 methodName_ = mname; 102 isStatic_ = isStatic; 103 } 104 105 public boolean equals(Object other) { 106 // no check on type of other for performance reasons: 107 // these CacheKeys are not compared to anything else 108 CacheKey otherKey = (CacheKey) other; 109 return ((class_.equals(otherKey.class_)) 110 && (methodName_.equals(otherKey.methodName_)) 111 && (isStatic_ == otherKey.isStatic_)); 112 } 113 114 public int hashCode() { 115 return (class_.hashCode() | methodName_.hashCode()) << ((isStatic_) ? 1 : 0); 116 } 117 } 118 119}