Author: sco...@google.com Date: Thu Apr 9 08:42:18 2009 New Revision: 5203
Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/CompilationResult.java trunk/dev/core/src/com/google/gwt/core/ext/linker/SyntheticArtifact.java trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationResult.java trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java trunk/dev/core/src/com/google/gwt/dev/util/DiskCache.java trunk/dev/core/src/com/google/gwt/dev/util/Util.java Log: Make Link run faster and use less heap by caching big objects to disk. Review by: bobv Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/CompilationResult.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/ext/linker/CompilationResult.java (original) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/CompilationResult.java Thu Apr 9 08:42:18 2009 @@ -65,11 +65,7 @@ @Override public final int hashCode() { - int hash = 17; - for (String js : getJavaScript()) { - hash = hash * 37 + js.hashCode(); - } - return hash; + return getStrongName().hashCode(); } @Override Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/SyntheticArtifact.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/ext/linker/SyntheticArtifact.java (original) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/SyntheticArtifact.java Thu Apr 9 08:42:18 2009 @@ -18,52 +18,37 @@ import com.google.gwt.core.ext.Linker; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.UnableToCompleteException; -import com.google.gwt.dev.util.Util; +import com.google.gwt.dev.util.DiskCache; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; +import java.io.ByteArrayInputStream; import java.io.InputStream; /** * Artifacts created by {...@link AbstractLinker}. */ public class SyntheticArtifact extends EmittedArtifact { - private final File backing; + private static final DiskCache diskCache = new DiskCache(); + private final long lastModified; + private final long token; SyntheticArtifact(TreeLogger logger, Class<? extends Linker> linkerType, - String partialPath, byte[] data) throws UnableToCompleteException { + String partialPath, byte[] data) { this(logger, linkerType, partialPath, data, System.currentTimeMillis()); } - SyntheticArtifact(TreeLogger logger, Class<? extends Linker> linkerType, String partialPath, - byte[] data, long lastModified) throws UnableToCompleteException { + SyntheticArtifact(TreeLogger logger, Class<? extends Linker> linkerType, + String partialPath, byte[] data, long lastModified) { super(linkerType, partialPath); assert data != null; - - try { - backing = File.createTempFile("synthetic", ".artifact"); - backing.deleteOnExit(); - Util.writeBytesToFile(TreeLogger.NULL, backing, data); - } catch (IOException e) { - logger.log(TreeLogger.ERROR, "Unable to write backing file for artifact " - + partialPath, e); - throw new UnableToCompleteException(); - } this.lastModified = lastModified; + this.token = diskCache.writeByteArray(data); } @Override public InputStream getContents(TreeLogger logger) throws UnableToCompleteException { - try { - return new FileInputStream(backing); - } catch (IOException e) { - logger.log(TreeLogger.ERROR, "Unable to read backing file for artifact " - + getPartialPath(), e); - throw new UnableToCompleteException(); - } + return new ByteArrayInputStream(diskCache.readByteArray(token)); } @Override Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationResult.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationResult.java (original) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationResult.java Thu Apr 9 08:42:18 2009 @@ -15,16 +15,12 @@ */ package com.google.gwt.core.ext.linker.impl; -import com.google.gwt.core.ext.TreeLogger; -import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.core.ext.linker.CompilationResult; import com.google.gwt.core.ext.linker.SelectionProperty; import com.google.gwt.core.ext.linker.SymbolData; -import com.google.gwt.dev.PermutationResult; -import com.google.gwt.dev.util.FileBackedObject; +import com.google.gwt.dev.util.DiskCache; import java.io.Serializable; -import java.lang.ref.SoftReference; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; @@ -71,22 +67,23 @@ */ public static final Comparator<SortedMap<SelectionProperty, String>> MAP_COMPARATOR = new MapComparator(); - private transient SoftReference<String[]> js; + private static final DiskCache diskCache = new DiskCache(); - private final FileBackedObject<PermutationResult> resultFile; - - private transient SoftReference<SortedMap<SymbolData, String>> symbolMap; + private final long jsToken; private final SortedSet<SortedMap<SelectionProperty, String>> propertyValues = new TreeSet<SortedMap<SelectionProperty, String>>( MAP_COMPARATOR); + private final String strongName; - public StandardCompilationResult(String[] js, String strongName, - FileBackedObject<PermutationResult> resultFile) { + private final long symbolMapToken; + + public StandardCompilationResult(String strongName, String[] js, + SortedMap<SymbolData, String> symbolMap) { super(StandardLinkerContext.class); - this.js = new SoftReference<String[]>(js); this.strongName = strongName; - this.resultFile = resultFile; + jsToken = diskCache.writeObject(js); + symbolMapToken = diskCache.writeObject(symbolMap); } /** @@ -102,18 +99,7 @@ @Override public String[] getJavaScript() { - String[] toReturn = null; - if (js != null) { - toReturn = js.get(); - } - - if (toReturn == null) { - PermutationResult result = loadPermutationResult(); - toReturn = result.getJs(); - js = new SoftReference<String[]>(toReturn); - } - - return toReturn; + return diskCache.readObject(jsToken, String[].class); } @Override @@ -127,27 +113,8 @@ } @Override + @SuppressWarnings("unchecked") public SortedMap<SymbolData, String> getSymbolMap() { - SortedMap<SymbolData, String> toReturn = null; - if (symbolMap != null) { - toReturn = symbolMap.get(); - } - - if (toReturn == null) { - PermutationResult result = loadPermutationResult(); - toReturn = result.getSymbolMap(); - symbolMap = new SoftReference<SortedMap<SymbolData, String>>(toReturn); - } - - return toReturn; - } - - private PermutationResult loadPermutationResult() { - try { - return resultFile.newInstance(TreeLogger.NULL); - } catch (UnableToCompleteException e) { - throw new RuntimeException( - "Unexpectedly unable to read PermutationResult"); - } + return diskCache.readObject(symbolMapToken, SortedMap.class); } } Modified: trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java (original) +++ trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java Thu Apr 9 08:42:18 2009 @@ -269,10 +269,13 @@ FileBackedObject<PermutationResult> resultFile) throws UnableToCompleteException { PermutationResult permutationResult = resultFile.newInstance(logger); - String strongName = Util.computeStrongName(Util.getBytes(permutationResult.getJs())); + + String[] js = permutationResult.getJs(); + String strongName = Util.computeStrongName(Util.getBytes(js)); StandardCompilationResult result = resultsByStrongName.get(strongName); if (result == null) { - result = new StandardCompilationResult(null, strongName, resultFile); + result = new StandardCompilationResult(strongName, js, + permutationResult.getSymbolMap()); resultsByStrongName.put(result.getStrongName(), result); artifacts.add(result); Modified: trunk/dev/core/src/com/google/gwt/dev/util/DiskCache.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/dev/util/DiskCache.java (original) +++ trunk/dev/core/src/com/google/gwt/dev/util/DiskCache.java Thu Apr 9 08:42:18 2009 @@ -15,6 +15,8 @@ */ package com.google.gwt.dev.util; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; @@ -97,6 +99,17 @@ } } + public <T> T readObject(long token, Class<T> type) { + try { + byte[] bytes = readByteArray(token); + ByteArrayInputStream in = new ByteArrayInputStream(bytes); + return Util.readStreamAsObject(in, type); + } catch (ClassNotFoundException e) { + throw new RuntimeException( + "Unexpected exception deserializing from disk cache", e); + } + } + /** * Read a String from disk. * @@ -123,6 +136,17 @@ return position; } catch (IOException e) { throw new RuntimeException("Unable to write to byte cache", e); + } + } + + public long writeObject(Object object) { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Util.writeObjectToStream(out, object); + return writeByteArray(out.toByteArray()); + } catch (IOException e) { + throw new RuntimeException("Unexpected IOException on in-memory stream", + e); } } Modified: trunk/dev/core/src/com/google/gwt/dev/util/Util.java ============================================================================== --- trunk/dev/core/src/com/google/gwt/dev/util/Util.java (original) +++ trunk/dev/core/src/com/google/gwt/dev/util/Util.java Thu Apr 9 08:42:18 2009 @@ -658,7 +658,7 @@ } } - public static <T extends Serializable> T readStreamAsObject( + public static <T> T readStreamAsObject( InputStream inputStream, Class<T> type) throws ClassNotFoundException { ObjectInputStream objectInputStream = null; try { @@ -1087,7 +1087,7 @@ * Serializes an object and writes it to a file. */ public static void writeObjectAsFile(TreeLogger logger, File file, - Serializable... objects) throws UnableToCompleteException { + Object... objects) throws UnableToCompleteException { FileOutputStream stream = null; try { file.getParentFile().mkdirs(); @@ -1105,11 +1105,11 @@ /** * Serializes an object and writes it to a stream. */ - public static void writeObjectToStream(OutputStream stream, - Serializable... objects) throws IOException { + public static void writeObjectToStream(OutputStream stream, Object... objects) + throws IOException { ObjectOutputStream objectStream = null; objectStream = new ObjectOutputStream(stream); - for (Serializable object : objects) { + for (Object object : objects) { objectStream.writeObject(object); } objectStream.flush(); --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---