Reviewers: Dan Rice,

Message:
Review requested.

Description:
Many types in a production-mode app often have identical field names.
This patch updates the web-mode payload to reuse setter functions within
the payload.

Please review this at http://gwt-code-reviews.appspot.com/130825

Affected files:
  M user/src/com/google/gwt/rpc/server/WebModePayloadSink.java


Index: user/src/com/google/gwt/rpc/server/WebModePayloadSink.java
diff --git a/user/src/com/google/gwt/rpc/server/WebModePayloadSink.java b/user/src/com/google/gwt/rpc/server/WebModePayloadSink.java index a93e308d3b2a77bfcb2ba8803e47f3c4a1c4ed8d..f18a52ec5facdf4e7c5ae6cba9691400ff8d7af4 100644
--- a/user/src/com/google/gwt/rpc/server/WebModePayloadSink.java
+++ b/user/src/com/google/gwt/rpc/server/WebModePayloadSink.java
@@ -103,8 +103,15 @@ public class WebModePayloadSink extends CommandSink {
       return true;
     }
   }
+
   private class PayloadVisitor extends RpcCommandVisitor {
private final Map<Class<?>, byte[]> constructorFunctions = new IdentityHashMap<Class<?>, byte[]>();
+    /**
+ * If two types have the same field ids that need to be set, we can get away + * with using the same field setter function. This is reasonably common in
+     * obfuscated mode since field names are aggressively reused.
+     */
+ private final Map<String, byte[]> constructorFunctionsByFieldIds = new HashMap<String, byte[]>(); private final Map<RpcCommand, ByteBuffer> commandBuffers = new IdentityHashMap<RpcCommand, ByteBuffer>();
     private ByteBuffer currentBuffer;
     private final Stack<RpcCommand> stack = new Stack<RpcCommand>();
@@ -601,11 +608,29 @@ public class WebModePayloadSink extends CommandSink {
         return functionName;
       }

+      String byFieldIdsKey;
+      {
+        // Create a key that looks like a:b:c:
+        StringBuilder sb = new StringBuilder();
+        for (SetCommand setter : x.getSetters()) {
+          sb.append(clientOracle.getFieldId(setter.getFieldDeclClass(),
+              setter.getField()));
+          sb.append(":");
+        }
+        byFieldIdsKey = sb.toString();
+      }
+      functionName = constructorFunctionsByFieldIds.get(byFieldIdsKey);
+      if (functionName != null) {
+        constructorFunctions.put(targetClass, functionName);
+        return functionName;
+      }
+
       String seedName = clientOracle.getSeedName(targetClass);
       assert seedName != null : "TypeOverride failed to rescue "
           + targetClass.getName();
       functionName = getBytes(clientOracle.createUnusedIdent(seedName));
       constructorFunctions.put(targetClass, functionName);
+      constructorFunctionsByFieldIds.put(byFieldIdsKey, functionName);
       byte[][] idents = new byte[x.getSetters().size() + 1][];
       for (int i = 0, j = idents.length; i < j; i++) {
         idents[i] = getBytes("_" + i);


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

Reply via email to