Improve hosted mode performance by caching frequently referenced values.

Patch by: jat
Review by: scottb


git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.6@4382 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
index 6b7d755..3acd448 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
@@ -27,14 +27,22 @@
     HasMetaData {
 
   /**
+   * Cached set of supertypes for this type (including itself).  If null,
+   * the set has not been calculated yet.
+   */
+  private Set<JClassType> flattenedSupertypes;
+  
+  /**
    * Returns all of the superclasses and superinterfaces for a given type
    * including the type itself.
    */
   protected static Set<JClassType> getFlattenedSuperTypeHierarchy(
       JClassType type) {
-    Set<JClassType> typesSeen = new HashSet<JClassType>();
-    getFlattenedSuperTypeHierarchyRecursive(type, typesSeen);
-    return typesSeen;
+    if (type.flattenedSupertypes == null) {
+      type.flattenedSupertypes = new HashSet<JClassType>();
+      getFlattenedSuperTypeHierarchyRecursive(type, type.flattenedSupertypes);
+    }
+    return type.flattenedSupertypes;
   }
 
   /**
@@ -309,13 +317,13 @@
     // Superclass
     JClassType superclass = type.getSuperclass();
     if (superclass != null) {
-      getFlattenedSuperTypeHierarchyRecursive(superclass, typesSeen);
+      typesSeen.addAll(getFlattenedSuperTypeHierarchy(superclass));
     }
 
     // Check the interfaces
     JClassType[] intfs = type.getImplementedInterfaces();
     for (JClassType intf : intfs) {
-      getFlattenedSuperTypeHierarchyRecursive(intf, typesSeen);
+      typesSeen.addAll(getFlattenedSuperTypeHierarchy(intf));
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
index 75e8e2e..424a3ca 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
@@ -22,6 +22,7 @@
 import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -167,7 +168,11 @@
     }
   }
 
-  private final Set<JRealClassType> allTypes = new HashSet<JRealClassType>();
+  /**
+   * A map of fully-qualify source names (ie, use "." rather than "$" for nested
+   * classes) to JRealClassTypes.
+   */
+  private final Map<String, JRealClassType> allTypes = new HashMap<String, JRealClassType>();
 
   private final Map<JType, JArrayType> arrayTypes = new IdentityHashMap<JType, JArrayType>();
 
@@ -210,33 +215,16 @@
   }
 
   /**
-   * Finds a class or interface given its fully-qualified name. For nested
+   * Finds a class or interface given its fully-qualified name.
+   *
+   * @param name fully-qualified class/interface name -  for nested
    * classes, use its source name rather than its binary name (that is, use a
-   * "." rather than a "$").
+   * "." rather than a "$")
    * 
    * @return <code>null</code> if the type is not found
    */
   public JClassType findType(String name) {
-    // Try the dotted pieces, right to left.
-    //
-    int i = name.length() - 1;
-    while (i >= 0) {
-      int dot = name.lastIndexOf('.', i);
-      String pkgName = "";
-      String typeName = name;
-      if (dot != -1) {
-        pkgName = name.substring(0, dot);
-        typeName = name.substring(dot + 1);
-        i = dot - 1;
-      } else {
-        i = -1;
-      }
-      JClassType result = findType(pkgName, typeName);
-      if (result != null) {
-        return result;
-      }
-    }
-    return null;
+    return allTypes.get(name);
   }
 
   /**
@@ -482,7 +470,8 @@
    * @return an array of types, possibly of zero length
    */
   public JClassType[] getTypes() {
-    return allTypes.toArray(NO_JCLASSES);
+    Collection<JRealClassType> values = allTypes.values();
+    return values.toArray(new JClassType[values.size()]);
   }
 
   public JWildcardType getWildcardType(JWildcardType.BoundType boundType,
@@ -611,7 +600,8 @@
   }
 
   void addNewType(JRealClassType newType) {
-    allTypes.add(newType);
+    String fqcn = newType.getQualifiedSourceName();
+    allTypes.put(fqcn, newType);
     recentTypes.add(newType);
   }
 
@@ -990,9 +980,9 @@
    */
   private void removeTypes(Set<JRealClassType> invalidTypes) {
     for (Iterator<JRealClassType> iter = invalidTypes.iterator(); iter.hasNext();) {
-      JClassType classType = iter.next();
-
-      allTypes.remove(classType);
+      JRealClassType classType = iter.next();
+      String fqcn = classType.getQualifiedSourceName();
+      allTypes.remove(fqcn);
 
       JPackage pkg = classType.getPackage();
       if (pkg != null) {
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
index 666b1e6..6076260 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
@@ -52,6 +52,7 @@
 
   private Set<ZipFileResource> allZipFileResources;
   private Set<AbstractResource> cachedAnswers;
+  private String cachedLocation;
   private PathPrefixSet lastPrefixSet;
   private final ZipFile zipFile;
 
@@ -80,7 +81,10 @@
 
   @Override
   public String getLocation() {
-    return new File(zipFile.getName()).toURI().toString();
+    if (cachedLocation == null) {
+      cachedLocation = new File(zipFile.getName()).toURI().toString();
+    }
+    return cachedLocation;
   }
 
   public ZipFile getZipFile() {