[jboss-cvs] JBossAS SVN: r62376 - in projects/aop/trunk/aop/src/main/org/jboss/aop: annotation and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Apr 17 06:36:50 EDT 2007


Author: kabir.khan at jboss.com
Date: 2007-04-17 06:36:49 -0400 (Tue, 17 Apr 2007)
New Revision: 62376

Modified:
   projects/aop/trunk/aop/src/main/org/jboss/aop/Advisor.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/ClassAdvisor.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/ClassContainer.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/annotation/AnnotationRepository.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/proxy/container/ClassProxyContainer.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/util/UnmodifiableEmptyCollections.java
Log:
[JBAOP-378] Lazy initialize some of the Advisor and AnnotationRepository maps. Weirdly, lazy initializing the throwaway Advisor.methodInterceptors map has a drastic negative influence on perfomance...

Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/Advisor.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/Advisor.java	2007-04-16 21:47:26 UTC (rev 62375)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/Advisor.java	2007-04-17 10:36:49 UTC (rev 62376)
@@ -37,6 +37,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import javassist.CtClass;
 import javassist.CtConstructor;
@@ -68,6 +69,7 @@
 import org.jboss.aop.metadata.MethodMetaData;
 import org.jboss.aop.metadata.SimpleMetaData;
 import org.jboss.aop.pointcut.PointcutMethodMatch;
+import org.jboss.aop.util.UnmodifiableEmptyCollections;
 import org.jboss.metadata.spi.MetaData;
 import org.jboss.metadata.spi.signature.MethodSignature;
 import org.jboss.util.NestedRuntimeException;
@@ -120,29 +122,33 @@
       }
    }
 
+   /** Read/Write lock to be used when lazy creating the collections */
+   protected ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
 
    protected HashSet adviceBindings = new HashSet();
-   protected ArrayList interfaceIntroductions = new ArrayList();
-   protected ArrayList classMetaDataBindings = new ArrayList();
+   protected ArrayList interfaceIntroductions = UnmodifiableEmptyCollections.EMPTY_ARRAYLIST;
+   protected ArrayList classMetaDataBindings = UnmodifiableEmptyCollections.EMPTY_ARRAYLIST;
    protected SimpleMetaData defaultMetaData = new SimpleMetaData();
    protected MethodMetaData methodMetaData = new MethodMetaData();
    protected FieldMetaData fieldMetaData = new FieldMetaData();
    protected SimpleMetaData classMetaData = new SimpleMetaData();
    protected ConstructorMetaData constructorMetaData = new ConstructorMetaData();
-   protected HashMap classAnnotations = new HashMap();
+   //Does not seem to be used
+   //protected HashMap classAnnotations = UnmodifiableEmptyCollections.EMPTY_HASHMAP;
    protected AnnotationRepository annotations = new AnnotationRepository();
    protected boolean doesHaveAspects = false;
 
    protected String name;
    protected ConcurrentReaderHashMap aspects = new ConcurrentReaderHashMap();
    protected HashMap adviceInterceptors = new HashMap();
-   protected CopyOnWriteArraySet perInstanceAspectDefinitions = new CopyOnWriteArraySet();
-   protected ConcurrentReaderHashMap perInstanceJoinpointAspectDefinitions = new ConcurrentReaderHashMap();
+   protected CopyOnWriteArraySet perInstanceAspectDefinitions = UnmodifiableEmptyCollections.EMPTY_COPYONWRITE_ARRAYSET;
+   protected ConcurrentReaderHashMap perInstanceJoinpointAspectDefinitions = UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP;
 
    static Class cl = java.lang.String.class;
-   protected TLongObjectHashMap advisedMethods = new TLongObjectHashMap();
+   protected TLongObjectHashMap advisedMethods = UnmodifiableEmptyCollections.EMPTY_TLONG_OBJECT_HASHMAP;
    // The method signatures are sorted at transformation and load time to
    // make sure the tables line up.
+   //Common sense suggests that this should be lazily initialised for generated advisors, profiling shows that is a major performance hit...
    protected TLongObjectHashMap methodInterceptors = new TLongObjectHashMap();
    protected AspectManager manager;
    protected Class clazz = null;
@@ -644,6 +650,7 @@
 
    public synchronized void addInterfaceIntroduction(InterfaceIntroduction pointcut)
    {
+      initInterfaceIntroductionsList();      
       interfaceIntroductions.add(pointcut);
    }
 
@@ -666,6 +673,7 @@
 
    public void addPerInstanceAspect(AspectDefinition def)
    {
+      initPerInstanceAspectDefinitionsSet();
       perInstanceAspectDefinitions.add(def);
       def.registerAdvisor(this);
    }
@@ -688,6 +696,7 @@
       if (joinpoints == null)
       {
          joinpoints = new CopyOnWriteArraySet();
+         initPerInstanceJoinpointAspectDefinitionsMap();
          perInstanceJoinpointAspectDefinitions.put(def, joinpoints);
          def.registerAdvisor(this);
       }
@@ -1176,4 +1185,115 @@
          }
       }
    }
+   
+   /**
+    * Lock for write
+    */
+   protected void lockWrite()
+   {
+      lock.writeLock().lock();
+   }
+
+   /**
+    * Unlock for write
+    */
+   protected void unlockWrite()
+   {
+      lock.writeLock().unlock();
+   }
+
+   protected void initInterfaceIntroductionsList()
+   {
+      if (interfaceIntroductions == UnmodifiableEmptyCollections.EMPTY_ARRAYLIST)
+      {
+         lockWrite();
+         try
+         {
+            if (interfaceIntroductions == UnmodifiableEmptyCollections.EMPTY_ARRAYLIST)
+            {
+               interfaceIntroductions = new ArrayList();
+            }
+         }
+         finally
+         {
+            unlockWrite();
+         }
+      }
+   }
+   
+   protected void initClassMetaDataBindingsList()
+   {
+      if (classMetaDataBindings == UnmodifiableEmptyCollections.EMPTY_ARRAYLIST)
+      {
+         lockWrite();
+         try
+         {
+            if (classMetaDataBindings == UnmodifiableEmptyCollections.EMPTY_ARRAYLIST)
+            {
+               classMetaDataBindings = new ArrayList();
+            }
+         }
+         finally
+         {
+            unlockWrite();
+         }
+      }
+   }
+   
+   protected void initPerInstanceAspectDefinitionsSet()
+   {
+      if (perInstanceAspectDefinitions == UnmodifiableEmptyCollections.EMPTY_COPYONWRITE_ARRAYSET)
+      {
+         lockWrite();
+         try
+         {
+            if (perInstanceAspectDefinitions == UnmodifiableEmptyCollections.EMPTY_COPYONWRITE_ARRAYSET)
+            {
+               perInstanceAspectDefinitions = new CopyOnWriteArraySet();
+            }
+         }
+         finally
+         {
+            unlockWrite();
+         }
+      }
+   }
+   
+   protected void initPerInstanceJoinpointAspectDefinitionsMap()
+   {
+      if (perInstanceJoinpointAspectDefinitions == UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP)
+      {
+         lockWrite();
+         try
+         {
+            if (perInstanceJoinpointAspectDefinitions == UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP)
+            {
+               perInstanceJoinpointAspectDefinitions = new ConcurrentReaderHashMap();
+            }
+         }
+         finally
+         {
+            unlockWrite();
+         }
+      }
+   }
+
+   protected void initAdvisedMethodsMap()
+   {
+      if (advisedMethods == UnmodifiableEmptyCollections.EMPTY_TLONG_OBJECT_HASHMAP)
+      {
+         lockWrite();
+         try
+         {
+            if (advisedMethods == UnmodifiableEmptyCollections.EMPTY_TLONG_OBJECT_HASHMAP)
+            {
+               advisedMethods = new TLongObjectHashMap();
+            }
+         }
+         finally
+         {
+            unlockWrite();
+         }
+      }
+   }
 }
\ No newline at end of file

Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/ClassAdvisor.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/ClassAdvisor.java	2007-04-16 21:47:26 UTC (rev 62375)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/ClassAdvisor.java	2007-04-17 10:36:49 UTC (rev 62376)
@@ -1042,6 +1042,7 @@
 
    public synchronized void addClassMetaData(ClassMetaDataBinding data)
    {
+      initClassMetaDataBindingsList();
       classMetaDataBindings.add(data);
       if (this.clazz == null) return;  // don't bind till later.
 
@@ -1454,6 +1455,7 @@
    protected void createMethodTables()
    throws Exception
    {
+      initAdvisedMethodsMap();
       populateMethodTables(clazz.getSuperclass());
       addDeclaredMethods(clazz);
    }

Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/ClassContainer.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/ClassContainer.java	2007-04-16 21:47:26 UTC (rev 62375)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/ClassContainer.java	2007-04-17 10:36:49 UTC (rev 62376)
@@ -125,6 +125,7 @@
 
    public void addClassMetaData(ClassMetaDataBinding data)
    {
+      initClassMetaDataBindingsList();
       classMetaDataBindings.add(data);
       if (this.clazz == null) return;  // don't bind till later.
 
@@ -185,6 +186,7 @@
 
    protected void createMethodMap()
    {
+      initAdvisedMethodsMap();
       try
       {
          Method[] declaredMethods = clazz.getMethods();

Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/annotation/AnnotationRepository.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/annotation/AnnotationRepository.java	2007-04-16 21:47:26 UTC (rev 62375)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/annotation/AnnotationRepository.java	2007-04-17 10:36:49 UTC (rev 62376)
@@ -29,8 +29,10 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.jboss.aop.annotation.factory.duplicate.AnnotationCreator;
+import org.jboss.aop.util.UnmodifiableEmptyCollections;
 
 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
 import javassist.CtMember;
@@ -44,10 +46,14 @@
 public class AnnotationRepository
 {
    private static final String CLASS_ANNOTATION = "CLASS";
-   Map annotations = new ConcurrentReaderHashMap();
-   Map classAnnotations = new ConcurrentReaderHashMap();
-   Map disabledAnnotations = new ConcurrentReaderHashMap();
    
+   /** Read/Write lock to be used when lazy creating the collections */
+   protected ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+   Map annotations = UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP;
+   Map classAnnotations = UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP;
+   Map disabledAnnotations = UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP;
+   
    public Map getAnnotations()
    {
 	   return annotations;
@@ -60,11 +66,13 @@
 
    public void addClassAnnotation(String annotation, String value)
    {
+      initClassAnnotationsMap();
       classAnnotations.put(annotation, value);
    }
 
    public void addClassAnnotation(Class annotation, Object value)
    {
+      initClassAnnotationsMap();
       classAnnotations.put(annotation.getName(), value);
    }
 
@@ -126,6 +134,7 @@
       if (annotationList == null)
       {
          annotationList = new ArrayList();
+         initDisabledAnnotationsMap();
          disabledAnnotations.put(m,annotationList);
       }
       annotationList.add(annotation);
@@ -137,6 +146,7 @@
       if (annotationList == null)
       {
          annotationList = new ArrayList();
+         initDisabledAnnotationsMap();
          disabledAnnotations.put(CLASS_ANNOTATION,annotationList);
       }
       annotationList.add(annotation);
@@ -200,6 +210,7 @@
       if (map == null)
       {
          map = new HashMap();
+         initAnnotationsMap();
          annotations.put(m, map);
       }
       map.put(annotation.getName(), value);
@@ -211,6 +222,7 @@
       if (map == null)
       {
          map = new HashMap();
+         initAnnotationsMap();
          annotations.put(m, map);
       }
       map.put(annotation, value);
@@ -249,8 +261,82 @@
       if (set == null)
       {
          set = new HashSet();
+         initAnnotationsMap();
          annotations.put(m, set);
       }
       set.add(annotation);
    }
+
+   /**
+    * Lock for write
+    */
+   protected void lockWrite()
+   {
+      lock.writeLock().lock();
+   }
+
+   /**
+    * Unlock for write
+    */
+   protected void unlockWrite()
+   {
+      lock.writeLock().unlock();
+   }
+
+   protected void initAnnotationsMap()
+   {
+      if (annotations == UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP)
+      {
+         lockWrite();
+         try
+         {
+            if (annotations == UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP)
+            {
+               annotations = new ConcurrentReaderHashMap();;
+            }
+         }
+         finally
+         {
+            unlockWrite();
+         }
+      }
+   }
+
+   protected void initClassAnnotationsMap()
+   {
+      if (classAnnotations == UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP)
+      {
+         lockWrite();
+         try
+         {
+            if (classAnnotations == UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP)
+            {
+               classAnnotations = new ConcurrentReaderHashMap();;
+            }
+         }
+         finally
+         {
+            unlockWrite();
+         }
+      }
+   }
+
+   protected void initDisabledAnnotationsMap()
+   {
+      if (disabledAnnotations == UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP)
+      {
+         lockWrite();
+         try
+         {
+            if (disabledAnnotations == UnmodifiableEmptyCollections.EMPTY_CONCURRENT_READER_HASHMAP)
+            {
+               disabledAnnotations = new ConcurrentReaderHashMap();;
+            }
+         }
+         finally
+         {
+            unlockWrite();
+         }
+      }
+   }
 }

Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/proxy/container/ClassProxyContainer.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/proxy/container/ClassProxyContainer.java	2007-04-16 21:47:26 UTC (rev 62375)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/proxy/container/ClassProxyContainer.java	2007-04-17 10:36:49 UTC (rev 62376)
@@ -83,6 +83,7 @@
 
    protected void createMethodMap()
    {
+      initAdvisedMethodsMap();
       //System.out.println("============================================ Create method map - " + this + " " + clazz.getName());
       try
       {

Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/util/UnmodifiableEmptyCollections.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/util/UnmodifiableEmptyCollections.java	2007-04-16 21:47:26 UTC (rev 62375)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/util/UnmodifiableEmptyCollections.java	2007-04-17 10:36:49 UTC (rev 62376)
@@ -21,6 +21,8 @@
 */ 
 package org.jboss.aop.util;
 
+import gnu.trove.TLongObjectHashMap;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -31,6 +33,7 @@
 import org.jboss.util.collection.WeakValueHashMap;
 
 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
+import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArraySet;
 
 
 /**
@@ -49,6 +52,8 @@
    public static final WeakHashMap EMPTY_WEAK_HASHMAP = new LockedWeakHashMap();
    public static final WeakValueHashMap EMPTY_WEAK_VALUE_HASHMAP = new LockedWeakValueHashMap();
    public static final ArrayList EMPTY_ARRAYLIST = new LockedArrayList();
+   public static final CopyOnWriteArraySet EMPTY_COPYONWRITE_ARRAYSET = new LockedCopyOnWriteArraySet();
+   public static final TLongObjectHashMap EMPTY_TLONG_OBJECT_HASHMAP = new LockedTLongObjectHashMap();
 
    private static class LockedHashMap<K,V> extends HashMap<K,V>
    {
@@ -148,4 +153,32 @@
          throw new UnsupportedOperationException();
       }
    }
+   
+   private static class LockedCopyOnWriteArraySet extends CopyOnWriteArraySet
+   {
+      private static final long serialVersionUID = 1L;
+
+      @Override
+      public boolean add(Object arg0)
+      {
+         return super.add(arg0);
+      }
+
+      @Override
+      public boolean addAll(Collection arg0)
+      {
+         return super.addAll(arg0);
+      }
+   }
+
+   
+   private static class LockedTLongObjectHashMap extends TLongObjectHashMap
+   {
+      private static final long serialVersionUID = 1L;
+      @Override
+      public Object put(long arg0, Object arg1)
+      {
+         throw new UnsupportedOperationException();
+      }
+   }
 }




More information about the jboss-cvs-commits mailing list