Author: [email protected]
Date: Wed Apr  1 12:11:09 2009
New Revision: 5147

Added:
    trunk/dev/core/src/com/google/gwt/dev/util/Memory.java
Modified:
    trunk/dev/core/src/com/google/gwt/dev/Compiler.java
    trunk/dev/core/src/com/google/gwt/dev/Precompile.java
    trunk/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java
    trunk/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
     
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/SourceGenerationVisitor.java
     
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java

Log:
Added infrastructure to profile compiler memory usage.
- reporting memory usage at various points
- dumping the heap at various points
- logging changes to the Java AST

Also remove the printing of a JMethod's thrown exceptions; this will soon  
go away entirely.

Review by: spoon

Modified: trunk/dev/core/src/com/google/gwt/dev/Compiler.java
==============================================================================
--- trunk/dev/core/src/com/google/gwt/dev/Compiler.java (original)
+++ trunk/dev/core/src/com/google/gwt/dev/Compiler.java Wed Apr  1 12:11:09  
2009
@@ -27,6 +27,7 @@
  import com.google.gwt.dev.shell.CheckForUpdates;
  import com.google.gwt.dev.shell.CheckForUpdates.UpdateResult;
  import com.google.gwt.dev.util.FileBackedObject;
+import com.google.gwt.dev.util.Memory;
  import com.google.gwt.dev.util.PerfLogger;
  import com.google.gwt.dev.util.Util;
  import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
@@ -119,6 +120,12 @@
    }

    public static void main(String[] args) {
+    Memory.initialize();
+    if (System.getProperty("gwt.jjs.dumpAst") != null) {
+      System.out.println("Will dump AST to: "
+          + System.getProperty("gwt.jjs.dumpAst"));
+    }
+
      /*
       * NOTE: main always exits with a call to System.exit to terminate any
       * non-daemon threads that were started in Generators. Typically, this  
is to

Modified: trunk/dev/core/src/com/google/gwt/dev/Precompile.java
==============================================================================
--- trunk/dev/core/src/com/google/gwt/dev/Precompile.java       (original)
+++ trunk/dev/core/src/com/google/gwt/dev/Precompile.java       Wed Apr  1  
12:11:09 2009
@@ -40,6 +40,7 @@
  import com.google.gwt.dev.shell.CheckForUpdates;
  import com.google.gwt.dev.shell.StandardRebindOracle;
  import com.google.gwt.dev.shell.CheckForUpdates.UpdateResult;
+import com.google.gwt.dev.util.Memory;
  import com.google.gwt.dev.util.PerfLogger;
  import com.google.gwt.dev.util.Util;
  import com.google.gwt.dev.util.arg.ArgHandlerDisableAggressiveOptimization;
@@ -316,6 +317,12 @@
     * Performs a command-line precompile.
     */
    public static void main(String[] args) {
+    Memory.initialize();
+    if (System.getProperty("gwt.jjs.dumpAst") != null) {
+      System.out.println("Will dump AST to: "
+          + System.getProperty("gwt.jjs.dumpAst"));
+    }
+
      /*
       * NOTE: main always exits with a call to System.exit to terminate any
       * non-daemon threads that were started in Generators. Typically, this  
is to

Modified:  
trunk/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java
==============================================================================
--- trunk/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java      
 
(original)
+++ trunk/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java      
 
Wed Apr  1 12:11:09 2009
@@ -27,6 +27,7 @@
  import com.google.gwt.dev.jjs.impl.FragmentLoaderCreator;
  import com.google.gwt.dev.util.Empty;
  import com.google.gwt.dev.util.JsniRef;
+import com.google.gwt.dev.util.Memory;

  import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
  import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
@@ -120,6 +121,7 @@
       */
      CompilationUnitDeclaration[] cuds = compile(logger,
          icus.toArray(new ICompilationUnit[icus.size()]));
+    Memory.maybeDumpMemory("WebModeCompiler");
      return cuds;
    }


Modified:  
trunk/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
==============================================================================
--- trunk/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java     
 
(original)
+++ trunk/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java     
 
Wed Apr  1 12:11:09 2009
@@ -72,6 +72,7 @@
  import com.google.gwt.dev.jjs.impl.ReplaceRebinds;
  import com.google.gwt.dev.jjs.impl.ReplaceRunAsyncs;
  import com.google.gwt.dev.jjs.impl.ResolveRebinds;
+import com.google.gwt.dev.jjs.impl.SourceGenerationVisitor;
  import com.google.gwt.dev.jjs.impl.TypeMap;
  import com.google.gwt.dev.jjs.impl.TypeTightener;
  import com.google.gwt.dev.js.EvalFunctionsAtTopScope;
@@ -91,9 +92,12 @@
  import com.google.gwt.dev.js.ast.JsName;
  import com.google.gwt.dev.js.ast.JsProgram;
  import com.google.gwt.dev.js.ast.JsStatement;
+import com.google.gwt.dev.util.AbstractTextOutput;
  import com.google.gwt.dev.util.DefaultTextOutput;
  import com.google.gwt.dev.util.Empty;
+import com.google.gwt.dev.util.Memory;
  import com.google.gwt.dev.util.PerfLogger;
+import com.google.gwt.dev.util.TextOutput;

  import org.eclipse.jdt.core.compiler.IProblem;
  import org.eclipse.jdt.internal.compiler.CompilationResult;
@@ -101,6 +105,9 @@
  import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;

  import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashMap;
@@ -346,6 +353,8 @@
      allRootTypes.addAll(JProgram.INDEX_TYPES_SET);
      allRootTypes.add(FragmentLoaderCreator.ASYNC_FRAGMENT_LOADER);

+    Memory.maybeDumpMemory("CompStateBuilt");
+
      // Compile the source and get the compiler so we can get the parse tree
      //
      CompilationUnitDeclaration[] goldenCuds =  
compilerFrontEnd.getCompilationUnitDeclarations(
@@ -383,11 +392,15 @@
        // GenerateJavaAST can uncover semantic JSNI errors; report & abort
        checkForErrors(logger, goldenCuds, true);

+      Memory.maybeDumpMemory("AstBuilt");
+
        // Allow GC
        goldenCuds = null;
        typeMap = null;
        allTypeDeclarations = null;

+      maybeDumpAST(jprogram);
+
        // (3) Perform Java AST normalizations.

        FixAssignmentToUnbox.exec(jprogram);
@@ -457,6 +470,8 @@
          throw new InterruptedException();
        }

+      maybeDumpAST(jprogram);
+
        // Recompute clinits each time, they can become empty.
        jprogram.typeOracle.recomputeAfterOptimizations();
        didChange = false;
@@ -803,5 +818,27 @@
      }

      return toReturn;
+  }
+
+  private static void maybeDumpAST(JProgram jprogram) {
+    String dumpFile = System.getProperty("gwt.jjs.dumpAst");
+    if (dumpFile != null) {
+      try {
+        FileOutputStream os = new FileOutputStream(dumpFile, true);
+        final PrintWriter pw = new PrintWriter(os);
+        TextOutput out = new AbstractTextOutput(false) {
+          {
+            setPrintWriter(pw);
+          }
+        };
+        SourceGenerationVisitor v = new SourceGenerationVisitor(out);
+        v.accept(jprogram);
+        pw.flush();
+        pw.close();
+      } catch (IOException e) {
+        System.out.println("Could not dump AST");
+        e.printStackTrace();
+      }
+    }
    }
  }

Modified:  
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/SourceGenerationVisitor.java
==============================================================================
---  
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/SourceGenerationVisitor.java     
 
(original)
+++  
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/SourceGenerationVisitor.java     
 
Wed Apr  1 12:11:09 2009
@@ -20,7 +20,6 @@
  import com.google.gwt.dev.jjs.ast.JField;
  import com.google.gwt.dev.jjs.ast.JInterfaceType;
  import com.google.gwt.dev.jjs.ast.JMethod;
-import com.google.gwt.dev.jjs.ast.JMethodBody;
  import com.google.gwt.dev.jjs.ast.JProgram;
  import com.google.gwt.dev.jjs.ast.JReferenceType;
  import com.google.gwt.dev.util.TextOutput;
@@ -43,11 +42,6 @@
   */
  public class SourceGenerationVisitor extends ToStringGenerationVisitor {

-  private static boolean isEmptyInitializer(JMethod x) {
-    return isInitializer(x)
-        && (((JMethodBody) x.getBody()).getStatements().size() == 0);
-  }
-
    public SourceGenerationVisitor(TextOutput textOutput) {
      super(textOutput);
    }
@@ -70,11 +64,9 @@
      }
      for (int i = 0; i < x.methods.size(); ++i) {
        JMethod it = x.methods.get(i);
-      if (!isEmptyInitializer(it)) {
-        accept(it);
-        newline();
-        newline();
-      }
+      accept(it);
+      newline();
+      newline();
      }

      closeBlock();

Modified:  
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
==============================================================================
---  
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java   
 
(original)
+++  
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java   
 
Wed Apr  1 12:11:09 2009
@@ -141,10 +141,6 @@
    protected static final char[] CHARS_TRY = "try ".toCharArray();
    protected static final char[] CHARS_WHILE = "while ".toCharArray();

-  protected static boolean isInitializer(JMethod x) {
-    return x.getName().equals("$clinit") || x.getName().equals("$init");
-  }
-
    private boolean needSemi = true;

    private boolean suppressType = false;
@@ -583,17 +579,7 @@

    @Override
    public boolean visit(JMethod x, Context ctx) {
-    // special: transcribe clinit and init as if they were initializer  
blocks
-    if (isInitializer(x)) {
-      if (x.isStatic()) {
-        print(CHARS_STATIC);
-      }
-      if (!shouldPrintMethodBody()) {
-        print("{...}");
-      }
-    } else {
-      printMethodHeader(x);
-    }
+    printMethodHeader(x);

      if (x.isAbstract() || !shouldPrintMethodBody()) {
        semi();
@@ -1028,18 +1014,6 @@

      // Parameters
      printParameterList(x);
-
-    if (x.thrownExceptions.size() > 0) {
-      print(CHARS_THROWS);
-      Iterator<JClassType> iter = x.thrownExceptions.iterator();
-      if (iter.hasNext()) {
-        printTypeName(iter.next());
-      }
-      while (iter.hasNext()) {
-        print(CHARS_COMMA);
-        printTypeName(iter.next());
-      }
-    }
    }

    protected void printName(HasName x) {

Added: trunk/dev/core/src/com/google/gwt/dev/util/Memory.java
==============================================================================
--- (empty file)
+++ trunk/dev/core/src/com/google/gwt/dev/util/Memory.java      Wed Apr  1  
12:11:09 2009
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may  
not
+ * use this file except in compliance with the License. You may obtain a  
copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,  
WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations  
under
+ * the License.
+ */
+package com.google.gwt.dev.util;
+
+import java.io.File;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+
+/**
+ * Utility methods for dealing with VM memory.
+ */
+public class Memory {
+
+  /**
+   * Number of times to call System.gc() before measuring the memory
+   * usage/dumping the heap. This value was arrived at through  
trial-and-error
+   * on the Sun JVM; memory usage seems to stabilize after 3 to 4 runs. We  
think
+   * the reason it requires multiple runs is due to the generational  
aspect of
+   * garbage collection.
+   */
+  private static final int NUM_GC_COLLECTIONS = 4;
+
+  /**
+   * Set this system property to a filename suffix to dump heaps into.
+   */
+  private static final String PROPERTY_DUMP_HEAP = "gwt.memory.dumpHeap";
+
+  /**
+   * Set this system property to dump memory usage at various points.
+   */
+  private static final String PROPERTY_DUMP_MEMORY = "gwt.memory.usage";
+
+  /**
+   * Time to start measuring since the last memory measurement/dump, or
+   * application startup.
+   */
+  private static long startTime;
+
+  public static void initialize() {
+    if (System.getProperty(PROPERTY_DUMP_MEMORY) != null) {
+      System.out.println("Will print mem usage");
+    }
+    if (System.getProperty(PROPERTY_DUMP_HEAP) != null) {
+      System.out.println("Will dump heap into: *-"
+          + System.getProperty(PROPERTY_DUMP_HEAP));
+    }
+    startTime = System.currentTimeMillis();
+  }
+
+  public static void main(String[] args) {
+    initialize();
+    System.setProperty(PROPERTY_DUMP_MEMORY, "");
+    maybeDumpMemory("test");
+  }
+
+  public static void maybeDumpMemory(String info) {
+    long elapsed = System.currentTimeMillis() - startTime;
+    if (System.getProperty(PROPERTY_DUMP_MEMORY) != null) {
+      for (int i = 0; i < NUM_GC_COLLECTIONS; ++i) {
+        System.gc();
+      }
+      long heap =  
ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed();
+      long nonHeap =  
ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getUsed();
+      String infoString = String.format("[%.18s]", info);
+      System.out.println(String.format(
+          "%-20s %10d heap, %10d nonheap, %10d total, %10.2fs", infoString,
+          heap, nonHeap, heap + nonHeap, (double) elapsed / 1000));
+    }
+    String dumpFile = System.getProperty(PROPERTY_DUMP_HEAP);
+    if (dumpFile != null) {
+      dumpFile = info + "-" + dumpFile;
+      new File(dumpFile).delete();
+      try {
+        Class<?> beanClass =  
Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
+        Object bean = ManagementFactory.newPlatformMXBeanProxy(
+            ManagementFactory.getPlatformMBeanServer(),
+            "com.sun.management:type=HotSpotDiagnostic", beanClass);
+        Method dumpHeapMethod = beanClass.getDeclaredMethod("dumpHeap",
+            String.class, Boolean.TYPE);
+        dumpHeapMethod.invoke(bean, dumpFile, true);
+        System.out.println("(" + info + ") dumped heap into: " + dumpFile);
+      } catch (Throwable e) {
+        System.err.println("Unable to dump heap");
+        e.printStackTrace();
+      }
+    }
+    // Reset for next call
+    startTime = System.currentTimeMillis();
+  }
+}

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

Reply via email to