Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.jruby.util;
  
  import java.util.Map;
A Simple cache which maintains a collection of classes that can potentially be shared among multiple runtimes (or whole JVM).
 
 public class ClassCache<T> {
 
     private static final Logger LOG = LoggerFactory.getLogger("ClassCache");
 
     private final AtomicInteger classLoadCount = new AtomicInteger(0);
     private final AtomicInteger classReuseCount = new AtomicInteger(0);
     private final ReferenceQueue referenceQueue = new ReferenceQueue();
     private final Map<ObjectKeyedClassReferencecache =
         new ConcurrentHashMap<ObjectKeyedClassReference>();
     private final ClassLoader classLoader;
     private final int max;
    
    
The ClassLoader this class cache will use for any classes generated through it. It is assumed that the classloader provided will be a parent loader of any runtime using it.

Parameters:
classLoader to use to generate shared classes
 
     public ClassCache(ClassLoader classLoaderint max) {
         assert classLoader != null : "Null classloader provided for ClassCache";
         this. = classLoader;
         this. = max;
     }
     
     public ClassCache(ClassLoader classLoader) {
         this(classLoader, -1);
     }
     
     public interface ClassGenerator {
         void generate();
         byte[] bytecode();
         String name();
     }
     
     private static class KeyedClassReference<T> extends WeakReference<Class<T>> {
         private final Object key;
         
         public KeyedClassReference(Object keyClass<T> referentReferenceQueue<Class<T>> referenceQueue) {
             super(referentreferenceQueue);
             
             this. = key;
         }
         
         public Object getKey() {
             return ;
         }
     }
     
     public static class OneShotClassLoader extends ClassLoader implements ClassDefiningClassLoader {
         private final static ProtectionDomain DEFAULT_DOMAIN = 
             JRubyClassLoader.class.getProtectionDomain();
         
         public OneShotClassLoader(ClassLoader parent) {
             super(parent);
         }
 
         public Class<?> defineClass(String namebyte[] bytes) {
             return super.defineClass(namebytes, 0, bytes.length);
          }
     }
     
     
     public ClassLoader getClassLoader() {
         return ;
     }
 
     public int getMax() {
         return ;
     }
     
     public Class<T> cacheClassByKey(Object keyClassGenerator classGenerator
         throws ClassNotFoundException {
         Class<T> contents = null;
         if (.) {
             WeakReference<Class<T>> weakRef = .get(key);
             if (weakRef != nullcontents = weakRef.get();
 
             if (weakRef == null || contents == null) {
                 if (isFull()) return null;
 
                 contents = defineClass(classGenerator);
 
                 cleanup();
 
                .put(keynew KeyedClassReference(keycontents));
            } else {
                .incrementAndGet();
            }
        } else {
            contents = defineClass(classGenerator);
        }
        
        return contents;
    }
    protected Class<T> defineClass(ClassGenerator classGenerator) {
        // attempt to load from classloaders
        String className = classGenerator.name();
        Class contents = null;
        try {
            contents = getClassLoader().loadClass(className);
            if (.) {
                .debug("found jitted code in classloader: {}"className);
            }
        } catch (ClassNotFoundException cnfe) {
            if (.) {
                .debug("no jitted code in classloader for method {} at class: {}"classGeneratorclassName);
            }
            // proceed to define in-memory
        }
        OneShotClassLoader oneShotCL = new OneShotClassLoader(getClassLoader());
        classGenerator.generate();
        contents = oneShotCL.defineClass(classGenerator.name(), classGenerator.bytecode());
        return contents;
    }
    
    public void flush() {
        .clear();
    }
    
    public boolean isFull() {
        cleanup();
        return  > 0 && .size() >= ;
    }
    
    public int getClassLoadCount() {
        return .get();
    }
    
    public int getLiveClassCount() {
        cleanup();
        return .size();
    }
    
    public int getClassReuseCount() {
        return .get();
    }
    
    private void cleanup() {
        KeyedClassReference reference;
        while ((reference = (KeyedClassReference).poll()) != null) {
            .remove(reference.getKey());
        }
    }
New to GrepCode? Check out our FAQ X