Revision: 9472
Author: [email protected]
Date: Tue Dec 21 05:37:31 2010
Log: Generator Result Caching implementation for RPC

Review at http://gwt-code-reviews.appspot.com/1235801

http://code.google.com/p/google-web-toolkit/source/detail?r=9472

Modified:
 /trunk/user/src/com/google/gwt/rpc/rebind/RpcProxyCreator.java
 /trunk/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
/trunk/user/src/com/google/gwt/user/rebind/rpc/ServiceInterfaceProxyGenerator.java
 /trunk/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java

=======================================
--- /trunk/user/src/com/google/gwt/rpc/rebind/RpcProxyCreator.java Thu Dec 2 04:45:53 2010 +++ /trunk/user/src/com/google/gwt/rpc/rebind/RpcProxyCreator.java Tue Dec 21 05:37:31 2010
@@ -19,7 +19,7 @@
 import com.google.gwt.core.client.impl.ArtificialRescue;
 import com.google.gwt.core.client.impl.Impl;
 import com.google.gwt.core.client.impl.ArtificialRescue.Rescue;
-import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.GeneratorContextExt;
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.JArrayType;
@@ -118,7 +118,7 @@
   }

   @Override
- protected void generateTypeHandlers(TreeLogger logger, GeneratorContext ctx, + protected void generateTypeHandlers(TreeLogger logger, GeneratorContextExt ctx,
       SerializableTypeOracle serializationSto,
       SerializableTypeOracle deserializationSto)
       throws UnableToCompleteException {
@@ -271,7 +271,7 @@

   @Override
   protected String writeSerializationPolicyFile(TreeLogger logger,
-      GeneratorContext ctx, SerializableTypeOracle serializationSto,
+      GeneratorContextExt ctx, SerializableTypeOracle serializationSto,
       SerializableTypeOracle deserializationSto)
       throws UnableToCompleteException {

=======================================
--- /trunk/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java Tue Dec 14 13:56:04 2010 +++ /trunk/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java Tue Dec 21 05:37:31 2010
@@ -19,7 +19,7 @@
 import com.google.gwt.core.client.impl.Impl;
 import com.google.gwt.core.ext.BadPropertyValueException;
 import com.google.gwt.core.ext.ConfigurationProperty;
-import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.GeneratorContextExt;
 import com.google.gwt.core.ext.PropertyOracle;
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
@@ -248,7 +248,7 @@
    *
    * @throws UnableToCompleteException
    */
-  public String create(TreeLogger logger, GeneratorContext context)
+  public String create(TreeLogger logger, GeneratorContextExt context)
       throws UnableToCompleteException {
     TypeOracle typeOracle = context.getTypeOracle();

@@ -690,7 +690,7 @@
   }

   protected void generateTypeHandlers(TreeLogger logger,
- GeneratorContext context, SerializableTypeOracle typesSentFromBrowser, + GeneratorContextExt context, SerializableTypeOracle typesSentFromBrowser,
       SerializableTypeOracle typesSentToBrowser)
       throws UnableToCompleteException {
Event event = SpeedTracerLogger.start(CompilerEventType.GENERATOR_RPC_TYPE_SERIALIZER);
@@ -729,7 +729,7 @@
   }

   protected String writeSerializationPolicyFile(TreeLogger logger,
-      GeneratorContext ctx, SerializableTypeOracle serializationSto,
+      GeneratorContextExt ctx, SerializableTypeOracle serializationSto,
       SerializableTypeOracle deserializationSto)
       throws UnableToCompleteException {
     try {
@@ -830,7 +830,7 @@
   }

   private void emitPolicyFileArtifact(TreeLogger logger,
-      GeneratorContext context, String partialPath)
+      GeneratorContextExt context, String partialPath)
       throws UnableToCompleteException {
     try {
       String qualifiedSourceName = serviceIntf.getQualifiedSourceName();
@@ -881,7 +881,7 @@
     return ResponseReader.OBJECT;
   }

- private SourceWriter getSourceWriter(TreeLogger logger, GeneratorContext ctx, + private SourceWriter getSourceWriter(TreeLogger logger, GeneratorContextExt ctx,
       JClassType serviceAsync) {
     JPackage serviceIntfPkg = serviceAsync.getPackage();
String packageName = serviceIntfPkg == null ? "" : serviceIntfPkg.getName();
=======================================
--- /trunk/user/src/com/google/gwt/user/rebind/rpc/ServiceInterfaceProxyGenerator.java Mon Jul 6 16:17:17 2009 +++ /trunk/user/src/com/google/gwt/user/rebind/rpc/ServiceInterfaceProxyGenerator.java Tue Dec 21 05:37:31 2010
@@ -15,23 +15,25 @@
  */
 package com.google.gwt.user.rebind.rpc;

-import com.google.gwt.core.ext.Generator;
-import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.GeneratorContextExt;
+import com.google.gwt.core.ext.GeneratorExt;
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.JClassType;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.dev.javac.rebind.RebindResult;
+import com.google.gwt.dev.javac.rebind.RebindStatus;

 /**
  * Generator for producing the asynchronous version of a
* {...@link com.google.gwt.user.client.rpc.RemoteService RemoteService} interface.
  */
-public class ServiceInterfaceProxyGenerator extends Generator {
+public class ServiceInterfaceProxyGenerator extends GeneratorExt {

   @Override
-  public String generate(TreeLogger logger, GeneratorContext ctx,
+ public RebindResult generateIncrementally(TreeLogger logger, GeneratorContextExt ctx,
       String requestedClass) throws UnableToCompleteException {
-
+
     TypeOracle typeOracle = ctx.getTypeOracle();
     assert (typeOracle != null);

@@ -54,7 +56,16 @@
         "Generating client proxy for remote service interface '"
             + remoteService.getQualifiedSourceName() + "'", null);

-    return proxyCreator.create(proxyLogger, ctx);
+    String returnTypeName = proxyCreator.create(proxyLogger, ctx);
+
+    /*
+ * Return with RebindStatus.USE_PARTIAL_CACHED, since we are implementing an + * incremental scheme, which allows us to use a mixture of previously cached + * and newly generated compilation units and artifacts. For example, the + * field serializers only need to be generated fresh if their source type
+     * has changed (or if no previously cached version exists).
+     */
+ return new RebindResult(RebindStatus.USE_PARTIAL_CACHED, returnTypeName);
   }

   protected ProxyCreator createProxyCreator(JClassType remoteService) {
=======================================
--- /trunk/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java Thu Dec 16 11:33:51 2010 +++ /trunk/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java Tue Dec 21 05:37:31 2010
@@ -21,7 +21,7 @@
 import com.google.gwt.core.client.JsArrayString;
 import com.google.gwt.core.ext.BadPropertyValueException;
 import com.google.gwt.core.ext.ConfigurationProperty;
-import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.GeneratorContextExt;
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.JClassType;
@@ -29,6 +29,7 @@
 import com.google.gwt.core.ext.typeinfo.JParameterizedType;
 import com.google.gwt.core.ext.typeinfo.JType;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.dev.javac.rebind.CachedRebindResult;
 import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
@@ -99,7 +100,7 @@
     }
   }

-  private final GeneratorContext context;
+  private final GeneratorContextExt context;

   private final SerializableTypeOracle deserializationOracle;

@@ -121,7 +122,7 @@

   public TypeSerializerCreator(TreeLogger logger,
       SerializableTypeOracle serializationOracle,
- SerializableTypeOracle deserializationOracle, GeneratorContext context, + SerializableTypeOracle deserializationOracle, GeneratorContextExt context,
       String typeSerializerClassName, String typeSerializerSimpleName)
       throws UnableToCompleteException {
     this.context = context;
@@ -202,44 +203,52 @@

     return typeSerializerClassName;
   }
-
+
   /*
    * Create a field serializer for a type if it does not have a custom
    * serializer.
    */
- private void createFieldSerializer(TreeLogger logger, GeneratorContext ctx, + private void createFieldSerializer(TreeLogger logger, GeneratorContextExt ctx,
       JType type) {
Event event = SpeedTracerLogger.start(CompilerEventType.GENERATOR_RPC_FIELD_SERIALIZER);
-    assert (type != null);
- assert (serializationOracle.isSerializable(type) || deserializationOracle.isSerializable(type));
-
-    JParameterizedType parameterizedType = type.isParameterized();
-    if (parameterizedType != null) {
-      createFieldSerializer(logger, ctx, parameterizedType.getRawType());
-      return;
-    }
-
-    /*
- * Only a JClassType can reach this point in the code. JPrimitives have been - * removed because their serialization is built in, interfaces have been - * removed because they are not an instantiable type and parameterized types
-     * have been broken down into their raw types.
-     */
-    assert (type.isClass() != null || type.isArray() != null);
-
- JClassType customFieldSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer(
-        typeOracle, type);
-    FieldSerializerCreator creator = new FieldSerializerCreator(typeOracle,
-        serializationOracle, deserializationOracle, (JClassType) type,
-        customFieldSerializer);
-    creator.realize(logger, ctx);
-    event.end();
+    try {
+      assert (type != null);
+ assert (serializationOracle.isSerializable(type) || deserializationOracle.isSerializable(type));
+
+      JParameterizedType parameterizedType = type.isParameterized();
+      if (parameterizedType != null) {
+        createFieldSerializer(logger, ctx, parameterizedType.getRawType());
+        return;
+      }
+
+      /*
+ * Only a JClassType can reach this point in the code. JPrimitives have been + * removed because their serialization is built in, interfaces have been + * removed because they are not an instantiable type and parameterized types
+       * have been broken down into their raw types.
+       */
+      assert (type.isClass() != null || type.isArray() != null);
+
+ if (findCacheableFieldSerializerAndMarkForReuseIfAvailable(ctx, type)) {
+        // skip generation of field serializer
+        return;
+      }
+
+ JClassType customFieldSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer(
+          typeOracle, type);
+ FieldSerializerCreator creator = new FieldSerializerCreator(typeOracle,
+          serializationOracle, deserializationOracle, (JClassType) type,
+          customFieldSerializer);
+      creator.realize(logger, ctx);
+    } finally {
+      event.end();
+    }
   }

   /*
    * Create all of the necessary field serializers.
    */
- private void createFieldSerializers(TreeLogger logger, GeneratorContext ctx) { + private void createFieldSerializers(TreeLogger logger, GeneratorContextExt ctx) {
     JType[] types = getSerializableTypes();
     int typeCount = types.length;
     for (int typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
@@ -249,7 +258,51 @@
       createFieldSerializer(logger, ctx, type);
     }
   }
-
+
+  /*
+   * check whether we can use a previously generated version of a
+   * FieldSerializer.  If so, mark it for reuse, and return true.
+   * Otherwise return false.
+   */
+  private boolean findCacheableFieldSerializerAndMarkForReuseIfAvailable(
+      GeneratorContextExt ctx, JType type) {
+
+    CachedRebindResult lastResult = ctx.getCachedGeneratorResult();
+    if (lastResult == null || !ctx.isGeneratorResultCachingEnabled()) {
+      return false;
+    }
+
+    String fieldSerializerName =
+      SerializationUtils.getStandardSerializerName((JClassType) type);
+
+    if (type instanceof JClassType) {
+      // check that it is available for reuse
+      if (!lastResult.isTypeCached(fieldSerializerName)) {
+        return false;
+      }
+    } else {
+      return false;
+    }
+
+    try {
+      /*
+       * TODO(jbrosenberg): Change this check to use getVersion() from
+       * TypeOracle, once that is available.
+       */
+      long lastModified = ctx.getSourceLastModifiedTime((JClassType) type);
+
+      if (lastModified != 0L &&
+          lastModified < lastResult.getTimeGenerated()) {
+
+        // use cached version
+        return ctx.reuseTypeFromCacheIfAvailable(fieldSerializerName);
+      }
+    } catch (RuntimeException ex) {
+      // could get an exception checking modified time
+    }
+
+    return false;
+  }
   private String[] getPackageAndClassName(String fullClassName) {
     String className = fullClassName;
     String packageName = "";
@@ -265,7 +318,7 @@
     return serializableTypes;
   }

- private SourceWriter getSourceWriter(TreeLogger logger, GeneratorContext ctx) { + private SourceWriter getSourceWriter(TreeLogger logger, GeneratorContextExt ctx) {
     String name[] = getPackageAndClassName(typeSerializerClassName);
     String packageName = name[0];
     String className = name[1];

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to