Matthew Dempsky has submitted this change and it was merged.

Change subject: Segment the code generation in loadMethodsJava and loadSignaturesJava
......................................................................


Segment the code generation in loadMethodsJava and loadSignaturesJava

Change-Id: I3ef33f32ba67a849c679eb90351507f89ffc1d5c
Review-Link: https://gwt-review.googlesource.com/#/c/2731/
---
M user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
1 file changed, 121 insertions(+), 21 deletions(-)

Approvals:
  Matthew Dempsky: Looks good to me, approved
  Leeroy Jenkins: Verified



diff --git a/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java b/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
index 753d5f0..7079db5 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
@@ -47,6 +47,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.IdentityHashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -81,6 +82,16 @@
private static final String GWT_CREATEMETHODMAP_SHARD_SIZE = "gwt.typecreator.shard.size";

   private static int shardSize = -1;
+
+  /**
+ * The maximum number of bytes that should be used in the source code of a method body. + * The absolute maximum limit is 64k (or it will fail to compile) however 8k is the limit + * for the JIT compiler (HotSpot) and methods over this limit will run slower. We will leave a 1k
+   * buffer and set the limit at 7k.
+   */
+  private static final int MAX_BYTES_PER_METHOD = 7168;
+ private static final String LOAD_METHODS_JAVA_HELPER_PREFIX = "populateLoadMethodsJavaMap"; + private static final String LOAD_SIGNATURES_JAVA_HELPER_PREFIX = "populateLoadSignaturesJavaMap";

private static void computeShardSize(TreeLogger logger) throws UnableToCompleteException {
     String shardSizeProperty =
@@ -422,25 +433,20 @@

   /**
    * Writes a method to produce a map of type string -> class name of
-   * {@link TypeHandler} for Java.
+ * {@link TypeHandler} for Java. We are forced to use repeated helper methods to populate the map
+   * because of the limit on Java method size.
    *
    * <pre>
    * private static Map&lt;String, String&gt; loadMethodsJava() {
* Map&lt;String, String&gt; result = new HashMap&lt;String, String&gt;();
-   *   result.put(
-   *       &quot;java.lang.String/2004016611&quot;,
- * &quot;com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer&quot;
+   *   populateLoadMethodsJavaMap0(result);
+   *   populateLoadMethodsJavaMap1(result);
    *   ...
    *   return result;
    * }
    * </pre>
    */
   private void writeLoadMethodsJava() {
-    srcWriter.println("@SuppressWarnings(\"deprecation\")");
- srcWriter.println("private static Map<String, String> loadMethodsJava() {");
-    srcWriter.indent();
- srcWriter.println("Map<String, String> result = new HashMap<String, String>();");
-
     List<JType> filteredTypes = new ArrayList<JType>();
     JType[] types = getSerializableTypes();
     int n = types.length;
@@ -452,14 +458,62 @@
       }
     }

-    for (JType type : filteredTypes) {
-      String typeString = typeStrings.get(type);
- assert typeString != null : "Missing type signature for " + type.getQualifiedSourceName();
-      srcWriter.println("result.put(\"" + typeString + "\", \""
- + SerializationUtils.getStandardSerializerName((JClassType) type) + "\");");
+    // Write out as many helper methods as necessary.
+    Iterator<JType> filteredTypesIter = filteredTypes.iterator();
+    int numHelpers = 0;
+    while (filteredTypesIter.hasNext()) {
+ writeLoadMethodsJavaHelper(filteredTypesIter, Integer.toString(numHelpers));
+      numHelpers++;
+    }
+
+    srcWriter.println("@SuppressWarnings(\"deprecation\")");
+ srcWriter.println("private static Map<String, String> loadMethodsJava() {");
+    srcWriter.indent();
+ srcWriter.println("Map<String, String> result = new HashMap<String, String>();");
+
+    // Call all the helper methods to populate the map.
+    for (int helperNum = 0; helperNum < numHelpers; helperNum++) {
+ srcWriter.println(LOAD_METHODS_JAVA_HELPER_PREFIX + Integer.toString(helperNum) +
+          "(result);");
     }

     srcWriter.println("return result;");
+    srcWriter.outdent();
+    srcWriter.println("}");
+    srcWriter.println();
+  }
+
+  /**
+ * Writes a helper method to add the type signatures for the specified types to the result map. + * Adds as many of the types as possible by destructively modifying the iterator but may
+   * finish with elements still left.
+   *
+   * <pre>
+ * private static void populateLoadMethodsJavaMap#(Map&lt;String, String&gt; result) {
+   *   result.put(
+   *       &quot;java.lang.String/2004016611&quot;,
+ * &quot;com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer&quot);
+   *   ...
+   * }
+   * </pre>
+   */
+ private void writeLoadMethodsJavaHelper(Iterator<JType> iter, String methodSuffix) { + srcWriter.println("private static void " + LOAD_METHODS_JAVA_HELPER_PREFIX + methodSuffix);
+    srcWriter.println("(Map<String, String> result) {");
+    srcWriter.indent();
+
+    int totalBytesEstimate = 0;
+    while (iter.hasNext() && totalBytesEstimate < MAX_BYTES_PER_METHOD) {
+      JType type = iter.next();
+      String typeString = typeStrings.get(type);
+ assert typeString != null : "Missing type signature for " + type.getQualifiedSourceName();
+
+      String line = "result.put(\"" + typeString + "\", \""
+ + SerializationUtils.getStandardSerializerName((JClassType) type) + "\");";
+      totalBytesEstimate += line.getBytes().length;
+      srcWriter.println(line);
+    }
+
     srcWriter.outdent();
     srcWriter.println("}");
     srcWriter.println();
@@ -536,25 +590,69 @@

   /**
* Writes a method to produce a map of class name to type string for Java.
-   *
+   *
    * <pre>
* private static Map&lt;String&lt;?&gt;, String&gt; loadSignaturesJava() { * Map&lt;String&lt;?&gt;, String&gt; result = new HashMap&lt;String&lt;?&gt;, String&gt;();
-   *   result.put(
- * com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer.concreteType(),
-   *       &quot;java.lang.String/2004016611&quot;);
+   *   populateLoadSignaturesJavaMap0(result);
+   *   populateLoadSignaturesJavaMap1(result);
    *   ...
    *   return result;
    * }
    * </pre>
    */
   private void writeLoadSignaturesJava() {
+
+    List<JType> allTypes = Arrays.asList(getSerializableTypes());
+    Iterator<JType> allTypesIter = allTypes.iterator();
+
+    // Write out as many helper methods as necessary.
+    int numHelpers = 0;
+    while (allTypesIter.hasNext()) {
+ writeLoadSignaturesJavaHelper(allTypesIter, Integer.toString(numHelpers));
+      numHelpers++;
+    }
+
     srcWriter.println("@SuppressWarnings(\"deprecation\")");
srcWriter.println("private static Map<String, String> loadSignaturesJava() {");
     srcWriter.indent();
srcWriter.println("Map<String, String> result = new HashMap<String, String>();");

-    for (JType type : getSerializableTypes()) {
+    // Call all the helper methods to populate the map.
+    for (int helperNum = 0; helperNum < numHelpers; helperNum++) {
+      srcWriter.println(LOAD_SIGNATURES_JAVA_HELPER_PREFIX +
+          Integer.toString(helperNum) + "(result);");
+    }
+
+    srcWriter.println("return result;");
+    srcWriter.outdent();
+    srcWriter.println("}");
+    srcWriter.println();
+  }
+
+  /**
+ * Writes a helper method to produce a map of class name to type string for Java. Adds as many of + * the signatures as possible by destructively modifying the iterator but may finish with elements
+   * still left.
+   *
+   * <pre>
+ * private static void populateLoadSignaturesJavaMap#(Map&lt;String&lt;?&gt;, String&gt; result) {
+   *   result.put(
+ * com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer.concreteType(),
+   *       &quot;java.lang.String/2004016611&quot;);
+   *   ...
+   * }
+   * </pre>
+   */
+ private void writeLoadSignaturesJavaHelper(Iterator<JType> iter, String methodSuffix) { + srcWriter.println("private static void " + LOAD_SIGNATURES_JAVA_HELPER_PREFIX +
+        methodSuffix);
+    srcWriter.println("(Map<String, String> result) {");
+    srcWriter.indent();
+
+    int totalBytesEstimate = 0;
+    while (iter.hasNext() && totalBytesEstimate < MAX_BYTES_PER_METHOD) {
+      JType type = iter.next();
       String typeString = typeStrings.get(type);

       if (!serializationOracle.maybeInstantiated(type)
@@ -572,10 +670,11 @@
         typeRef = '"' + SerializationUtils.getRpcTypeName(type) + '"';
       }

- srcWriter.println("result.put(" + typeRef + ", \"" + typeString + "\");");
+      String line = "result.put(" + typeRef + ", \"" + typeString + "\");";
+      totalBytesEstimate += line.getBytes().length;
+      srcWriter.println(line);
     }

-    srcWriter.println("return result;");
     srcWriter.outdent();
     srcWriter.println("}");
     srcWriter.println();
@@ -755,3 +854,4 @@
     srcWriter.outdent();
   }
 }
+

--
To view, visit https://gwt-review.googlesource.com/2731
To unsubscribe, visit https://gwt-review.googlesource.com/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I3ef33f32ba67a849c679eb90351507f89ffc1d5c
Gerrit-PatchSet: 2
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Oliver King <[email protected]>
Gerrit-Reviewer: Brian Slesinsky <[email protected]>
Gerrit-Reviewer: Leeroy Jenkins <[email protected]>
Gerrit-Reviewer: Matthew Dempsky <[email protected]>
Gerrit-Reviewer: Oliver King <[email protected]>

--
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors
--- You received this message because you are subscribed to the Google Groups "Google Web Toolkit Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to