Author: [email protected]
Date: Mon Apr 20 10:27:32 2009
New Revision: 5262

Modified:
    releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
    releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
    releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JReferenceType.java

Log:
Reduces the amount of stack required to serialize the Java AST (by an order  
of magnitude).

Issue: 3510
Review by: bobv

Modified: releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
==============================================================================
--- releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java    
(original)
+++ releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java   Mon  
Apr 20 10:27:32 2009
@@ -18,6 +18,9 @@
  import com.google.gwt.dev.jjs.InternalCompilerException;
  import com.google.gwt.dev.jjs.SourceInfo;

+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Set;
@@ -46,7 +49,12 @@

    public final ArrayList<JParameter> params = new ArrayList<JParameter>();
    public final ArrayList<JClassType> thrownExceptions = new  
ArrayList<JClassType>();
-  private JAbstractMethodBody body = null;
+
+  /**
+   * Special serialization treatment.
+   */
+  private transient JAbstractMethodBody body = null;
+
    private final JReferenceType enclosingType;
    private final boolean isAbstract;
    private boolean isFinal;
@@ -75,13 +83,13 @@
    }

    public void freezeParamTypes() {
-    List<JType> paramTypes =  new ArrayList<JType>();
+    List<JType> paramTypes = new ArrayList<JType>();
      for (JParameter param : params) {
        paramTypes.add(param.getType());
      }
      setOriginalParamTypes(paramTypes);
    }
-
+
    public JAbstractMethodBody getBody() {
      return body;
    }
@@ -150,7 +158,6 @@
        throw new InternalCompilerException("Param types already frozen");
      }
      originalParamTypes = paramTypes;
-

      // Determine if we should trace this method.
      if (enclosingType != null) {
@@ -202,5 +209,25 @@
          trace(title, after);
        }
      }
+  }
+
+  /**
+   * See {...@link #writeBody(ObjectOutputStream)}.
+   *
+   * @see #writeBody(ObjectOutputStream)
+   */
+  void readBody(ObjectInputStream stream) throws IOException,
+      ClassNotFoundException {
+    body = (JAbstractMethodBody) stream.readObject();
+  }
+
+  /**
+   * After all types, fields, and methods are written to the stream, this  
method
+   * writes method bodies to the stream.
+   *
+   * @see JProgram#writeObject(ObjectOutputStream)
+   */
+  void writeBody(ObjectOutputStream stream) throws IOException {
+    stream.writeObject(body);
    }
  }

Modified: releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
==============================================================================
--- releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java   
(original)
+++ releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java  Mon  
Apr 20 10:27:32 2009
@@ -22,6 +22,9 @@
  import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
  import com.google.gwt.dev.jjs.ast.js.JsonObject;

+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.Arrays;
@@ -161,7 +164,10 @@
    private final Set<JArrayType> allArrayTypes = new TreeSet<JArrayType>(
        ARRAYTYPE_COMPARATOR);

-  private final List<JReferenceType> allTypes = new  
ArrayList<JReferenceType>();
+  /**
+   * Special serialization treatment.
+   */
+  private transient List<JReferenceType> allTypes = new  
ArrayList<JReferenceType>();

    private final Map<JType, JClassLiteral> classLiterals = new  
IdentityHashMap<JType, JClassLiteral>();

@@ -992,4 +998,59 @@
      return count;
    }

+  /**
+   * See notes in {...@link #writeObject(ObjectOutputStream)}.
+   *
+   * @see #writeObject(ObjectOutputStream)
+   */
+  @SuppressWarnings("unchecked")
+  private void readObject(ObjectInputStream stream) throws IOException,
+      ClassNotFoundException {
+    allTypes = (List<JReferenceType>) stream.readObject();
+    for (JReferenceType type : allTypes) {
+      type.readMembers(stream);
+    }
+    for (JReferenceType type : allTypes) {
+      type.readMethodBodies(stream);
+    }
+    stream.defaultReadObject();
+    for (JMethod method : entryMethods) {
+      method.readBody(stream);
+    }
+  }
+
+  /**
+   * Serializing the Java AST is a multi-step process to avoid blowing out  
the
+   * stack.
+   *
+   * <ol>
+   * <li>Write all declared types in a lightweight manner to establish  
object
+   * identity for types</li>
+   * <li>Write all fields; write all methods in a lightweight manner to
+   * establish object identity for methods</li>
+   * <li>Write all method bodies</li>
+   * <li>Write everything else, which will mostly refer to  
already-serialized
+   * objects.</li>
+   * <li>Write the bodies of the entry methods (unlike all other methods,  
these
+   * are not contained by any type.</li>
+   * </ol>
+   *
+   * The goal of this process to to avoid "running away" with the stack.  
Without
+   * special logic here, lots of things would reference types, method body  
code
+   * would reference both types and other methods, and really, really long
+   * recursion chains would result.
+   */
+  private void writeObject(ObjectOutputStream stream) throws IOException {
+    stream.writeObject(allTypes);
+    for (JReferenceType type : allTypes) {
+      type.writeMembers(stream);
+    }
+    for (JReferenceType type : allTypes) {
+      type.writeMethodBodies(stream);
+    }
+    stream.defaultWriteObject();
+    for (JMethod method : entryMethods) {
+      method.writeBody(stream);
+    }
+  }
  }

Modified:  
releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JReferenceType.java
==============================================================================
---  
releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JReferenceType.java        
 
(original)
+++  
releases/1.6/dev/core/src/com/google/gwt/dev/jjs/ast/JReferenceType.java        
 
Mon Apr 20 10:27:32 2009
@@ -17,6 +17,9 @@

  import com.google.gwt.dev.jjs.SourceInfo;

+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
  import java.util.ArrayList;
  import java.util.List;

@@ -25,11 +28,20 @@
   */
  public abstract class JReferenceType extends JType implements  
CanBeAbstract {

-  public List<JField> fields = new ArrayList<JField>();
-  public List<JMethod> methods = new ArrayList<JMethod>();
    public JClassType extnds;
+
+  /**
+   * Special serialization treatment.
+   */
+  public transient List<JField> fields = new ArrayList<JField>();
+
    public List<JInterfaceType> implments = new ArrayList<JInterfaceType>();

+  /**
+   * Special serialization treatment.
+   */
+  public transient List<JMethod> methods = new ArrayList<JMethod>();
+
    public JReferenceType(JProgram program, SourceInfo info, String name) {
      super(program, info, name, program.getLiteralNull());
    }
@@ -53,4 +65,51 @@
      return name.substring(dotpos + 1);
    }

+  /**
+   * See {...@link #writeMembers(ObjectOutputStream)}.
+   *
+   * @see #writeMembers(ObjectOutputStream)
+   */
+  @SuppressWarnings("unchecked")
+  void readMembers(ObjectInputStream stream) throws IOException,
+      ClassNotFoundException {
+    fields = (List<JField>) stream.readObject();
+    methods = (List<JMethod>) stream.readObject();
+  }
+
+  /**
+   * See {...@link #writeMethodBodies(ObjectOutputStream).
+   *
+   * @see #writeMethodBodies(ObjectOutputStream)
+   */
+  void readMethodBodies(ObjectInputStream stream) throws IOException,
+      ClassNotFoundException {
+    for (JMethod method : methods) {
+      method.readBody(stream);
+    }
+  }
+
+  /**
+   * After all types are written to the stream without transient members,  
this
+   * method actually writes fields and methods to the stream, which  
establishes
+   * type identity for them.
+   *
+   * @see JProgram#writeObject(ObjectOutputStream)
+   */
+  void writeMembers(ObjectOutputStream stream) throws IOException {
+    stream.writeObject(fields);
+    stream.writeObject(methods);
+  }
+
+  /**
+   * After all types, fields, and methods are written to the stream, this  
method
+   * writes method bodies to the stream.
+   *
+   * @see JProgram#writeObject(ObjectOutputStream)
+   */
+  void writeMethodBodies(ObjectOutputStream stream) throws IOException {
+    for (JMethod method : methods) {
+      method.writeBody(stream);
+    }
+  }
  }

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

Reply via email to