Adds some StringInterner references to reduce overall memory usage
under compile report (soyc). On A large code base, I witnessed a
reduction from 369M to 301M of heap when running the compileReport.
Review at http://gwt-code-reviews.appspot.com/1108801
Review by: conroy@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9236 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCastableTypeMap.java b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCastableTypeMap.java
index 0313d5d..0ded30e 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCastableTypeMap.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCastableTypeMap.java
@@ -22,10 +22,12 @@
* The standard implementation of {@link CastableTypeMap}.
*/
public class StandardCastableTypeMap implements CastableTypeMap {
+ // Save some memory by defining this constant string.
+ private static final String EMPTY_JSON_REF = "{}";
final String jsonData;
public StandardCastableTypeMap(String jsonData) {
- this.jsonData = jsonData;
+ this.jsonData = jsonData.equals(EMPTY_JSON_REF) ? EMPTY_JSON_REF : jsonData;
}
public String toJs() {
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/impl/DependencyRecorder.java b/dev/core/src/com/google/gwt/core/ext/soyc/impl/DependencyRecorder.java
index 17040a7..fcd2393 100644
--- a/dev/core/src/com/google/gwt/core/ext/soyc/impl/DependencyRecorder.java
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/impl/DependencyRecorder.java
@@ -19,8 +19,8 @@
import com.google.gwt.dev.jjs.InternalCompilerException;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JProgram;
-import com.google.gwt.dev.jjs.impl.ControlFlowAnalyzer;
import com.google.gwt.dev.jjs.impl.CodeSplitter.MultipleDependencyGraphRecorder;
+import com.google.gwt.dev.jjs.impl.ControlFlowAnalyzer;
import com.google.gwt.util.tools.Utility;
import java.io.IOException;
@@ -121,7 +121,7 @@
}
printPost();
- writer.write(builder.toString());
+ flushOutput();
Utility.close(writer);
} catch (Throwable e) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index 245561c..e795adb 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -24,9 +24,9 @@
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.CompilationMetricsArtifact;
import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.ModuleMetricsArtifact;
import com.google.gwt.core.ext.linker.PrecompilationMetricsArtifact;
-import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.StatementRanges;
import com.google.gwt.core.ext.linker.SymbolData;
import com.google.gwt.core.ext.linker.SyntheticArtifact;
@@ -308,7 +308,7 @@
// (7) Generate a JavaScript code DOM from the Java type declarations
jprogram.typeOracle.recomputeAfterOptimizations();
- JavaToJavaScriptMap map = GenerateJavaScriptAST.exec(jprogram, jsProgram,
+ JavaToJavaScriptMap jjsmap = GenerateJavaScriptAST.exec(jprogram, jsProgram,
options.getOutput(), symbolTable, propertyOracles);
// (8) Normalize the JS AST.
@@ -317,7 +317,7 @@
// Resolve all unresolved JsNameRefs.
JsSymbolResolver.exec(jsProgram);
// Move all function definitions to a top-level scope, to reduce weirdness
- EvalFunctionsAtTopScope.exec(jsProgram, map);
+ EvalFunctionsAtTopScope.exec(jsProgram, jjsmap);
// (9) Optimize the JS AST.
if (optimizationLevel > OptionOptimize.OPTIMIZE_LEVEL_DRAFT) {
@@ -340,7 +340,7 @@
SyntheticArtifact dependencies = null;
if (options.isRunAsyncEnabled()) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- CodeSplitter.exec(logger, jprogram, jsProgram, map,
+ CodeSplitter.exec(logger, jprogram, jsProgram, jjsmap,
chooseDependencyRecorder(options.isSoycEnabled(), baos));
if (baos.size() == 0 && options.isSoycEnabled()) {
recordNonSplitDependencies(jprogram, baos);
@@ -423,7 +423,7 @@
new SizeBreakdown[js.length] : null;
List<Map<Range, SourceInfo>> sourceInfoMaps = options.isSoycExtra() ?
new ArrayList<Map<Range, SourceInfo>>() : null;
- generateJavaScriptCode(options, jsProgram, map, js, ranges,
+ generateJavaScriptCode(options, jsProgram, jjsmap, js, ranges,
sizeBreakdowns, sourceInfoMaps, splitBlocks);
PermutationResult toReturn = new PermutationResultImpl(js, permutation,
@@ -441,7 +441,7 @@
unifiedAst.getPrecompilationMetrics(), compilationMetrics));
}
toReturn.addArtifacts(makeSoycArtifacts(logger, permutationId, jprogram,
- js, sizeBreakdowns, sourceInfoMaps, dependencies, map, obfuscateMap,
+ js, sizeBreakdowns, sourceInfoMaps, dependencies, jjsmap, obfuscateMap,
unifiedAst.getModuleMetrics(), unifiedAst.getPrecompilationMetrics(),
compilationMetrics));
@@ -1153,6 +1153,7 @@
PrecompilationMetricsArtifact precompilationMetricsArtifact,
CompilationMetricsArtifact compilationMetrics) throws IOException,
UnableToCompleteException {
+ Memory.maybeDumpMemory("makeSoycArtifactsStart");
List<SyntheticArtifact> soycArtifacts = new ArrayList<SyntheticArtifact>();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -1215,6 +1216,7 @@
if (dependencies != null) {
dashboard.readDependencies(openWithGunzip(dependencies));
}
+ Memory.maybeDumpMemory("soycReadDependenciesEnd");
} catch (ParserConfigurationException e) {
throw new InternalCompilerException(
"Error reading compile report information that was just generated",
diff --git a/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java b/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java
index f06dba8..5e666d7 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java
@@ -16,13 +16,14 @@
package com.google.gwt.dev.jjs;
import com.google.gwt.dev.jjs.Correlation.Axis;
+import com.google.gwt.dev.util.StringInterner;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.Map.Entry;
+import java.util.Set;
/**
* Describes where a SourceInfo's node came from. This class currently includes
@@ -118,7 +119,7 @@
private final int startLine;
private SourceOrigin(String location, int startLine) {
- this.fileName = location;
+ this.fileName = StringInterner.get().intern(location);
this.startLine = startLine;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index 2ad8a9a..bc2288c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -135,8 +135,9 @@
import com.google.gwt.dev.js.ast.JsUnaryOperation;
import com.google.gwt.dev.js.ast.JsUnaryOperator;
import com.google.gwt.dev.js.ast.JsVars;
-import com.google.gwt.dev.js.ast.JsWhile;
import com.google.gwt.dev.js.ast.JsVars.JsVar;
+import com.google.gwt.dev.js.ast.JsWhile;
+import com.google.gwt.dev.util.StringInterner;
import com.google.gwt.dev.util.collect.IdentityHashSet;
import com.google.gwt.dev.util.collect.Maps;
@@ -150,10 +151,10 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
-import java.util.Map.Entry;
/**
* Creates a JavaScript AST from a <code>JProgram</code> node.
@@ -482,7 +483,7 @@
}
sb.append(')');
sb.append(method.getOriginalReturnType().getJsniSignatureName());
- methodSig = sb.toString();
+ methodSig = StringInterner.get().intern(sb.toString());
} else {
methodSig = null;
}
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsName.java b/dev/core/src/com/google/gwt/dev/js/ast/JsName.java
index a087d15..0cb1461 100644
--- a/dev/core/src/com/google/gwt/dev/js/ast/JsName.java
+++ b/dev/core/src/com/google/gwt/dev/js/ast/JsName.java
@@ -24,7 +24,6 @@
* An abstract base class for named JavaScript objects.
*/
public class JsName implements Serializable {
-
private final JsScope enclosing;
private final String ident;
private boolean isObfuscatable;
@@ -76,7 +75,7 @@
}
public void setShortIdent(String shortIdent) {
- this.shortIdent = shortIdent;
+ this.shortIdent = StringInterner.get().intern(shortIdent);
}
/**
@@ -91,5 +90,4 @@
public String toString() {
return ident;
}
-
}
diff --git a/dev/core/src/com/google/gwt/dev/util/Memory.java b/dev/core/src/com/google/gwt/dev/util/Memory.java
index 912e0d6..420130f 100644
--- a/dev/core/src/com/google/gwt/dev/util/Memory.java
+++ b/dev/core/src/com/google/gwt/dev/util/Memory.java
@@ -81,7 +81,8 @@
}
String dumpFile = System.getProperty(PROPERTY_DUMP_HEAP);
if (dumpFile != null) {
- dumpFile = info + "-" + dumpFile;
+ String procName = ManagementFactory.getRuntimeMXBean().getName();
+ dumpFile = info + "-" + procName + dumpFile;
new File(dumpFile).delete();
try {
Class<?> beanClass = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
diff --git a/dev/core/src/com/google/gwt/soyc/SoycDashboard.java b/dev/core/src/com/google/gwt/soyc/SoycDashboard.java
index 22c992a..492204e 100644
--- a/dev/core/src/com/google/gwt/soyc/SoycDashboard.java
+++ b/dev/core/src/com/google/gwt/soyc/SoycDashboard.java
@@ -19,6 +19,7 @@
import com.google.gwt.core.ext.linker.CompilationMetricsArtifact;
import com.google.gwt.core.ext.linker.ModuleMetricsArtifact;
import com.google.gwt.core.ext.linker.PrecompilationMetricsArtifact;
+import com.google.gwt.dev.util.StringInterner;
import com.google.gwt.soyc.MakeTopLevelHtmlForPerm.DependencyLinker;
import com.google.gwt.soyc.MakeTopLevelHtmlForPerm.NullDependencyLinker;
import com.google.gwt.soyc.io.FileSystemOutputDirectory;
@@ -40,10 +41,10 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Scanner;
import java.util.TreeMap;
import java.util.TreeSet;
-import java.util.Map.Entry;
import java.util.zip.GZIPInputStream;
import javax.xml.parsers.ParserConfigurationException;
@@ -212,9 +213,9 @@
&& (attributes.getValue("name") != null)) {
String name = attributes.getValue("name");
dependencies = new TreeMap<String, String>();
- allDependencies.put(name, dependencies);
+ allDependencies.put(StringInterner.get().intern(name), dependencies);
if (attributes.getValue("extends") != null) {
- graphExtends = attributes.getValue("extends");
+ graphExtends = StringInterner.get().intern(attributes.getValue("extends"));
if (!allDependencies.containsKey(graphExtends)) {
throw new FormatException("Graph " + name
+ " extends an unknown graph " + graphExtends);
@@ -224,12 +225,13 @@
}
} else if ((strippedName.compareTo("method") == 0)
&& (attributes.getValue("name") != null)) {
- curMethod = attributes.getValue("name");
+ curMethod = StringInterner.get().intern(attributes.getValue("name"));
} else if ((strippedName.compareTo("called") == 0)
&& (attributes.getValue("by") != null)) {
String curDepMethod = attributes.getValue("by");
if (!dependencies.containsKey(curMethod)) {
- dependencies.put(curMethod, curDepMethod);
+ dependencies.put(StringInterner.get().intern(curMethod),
+ StringInterner.get().intern(curDepMethod));
}
}
}
@@ -519,7 +521,7 @@
int idx = className.indexOf(':');
className = className.substring(0, idx);
}
-
+ className = StringInterner.get().intern(className);
// derive the package name from the class
String packageName;
if (!globalInformation.getClassToPackage().containsKey(className)) {
@@ -529,6 +531,7 @@
} else {
packageName = globalInformation.getClassToPackage().get(className);
}
+
if (!globalInformation.getPackageToClasses().containsKey(packageName)) {
TreeSet<String> insertSet = new TreeSet<String>();
insertSet.add(className);
@@ -569,6 +572,8 @@
private void recordSize(String refType, String ref, int size,
GlobalInformation globalInformation) {
+ refType = StringInterner.get().intern(refType);
+ ref = StringInterner.get().intern(ref);
for (SizeBreakdown breakdown : breakdownsForFragment(fragment)) {
accountForSize(breakdown, refType, ref, size, globalInformation);
}