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