Pre-initialize ResourceOracleImpl's classpaths in parallel with other startup tasks. http://gwt-code-reviews.appspot.com/1265801/show Review by: conroy@google.com git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9512 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/DevMode.java b/dev/core/src/com/google/gwt/dev/DevMode.java index 8bcdcca..4bc6b14 100644 --- a/dev/core/src/com/google/gwt/dev/DevMode.java +++ b/dev/core/src/com/google/gwt/dev/DevMode.java
@@ -23,6 +23,7 @@ import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility; import com.google.gwt.core.ext.linker.impl.StandardLinkerContext; import com.google.gwt.dev.cfg.ModuleDef; +import com.google.gwt.dev.resource.impl.ResourceOracleImpl; import com.google.gwt.dev.shell.jetty.JettyLauncher; import com.google.gwt.dev.ui.RestartServerCallback; import com.google.gwt.dev.ui.RestartServerEvent; @@ -411,6 +412,21 @@ } @Override + protected boolean doStartup() { + // Background scan the classpath to warm the cache. + Thread scanThread = new Thread(new Runnable() { + public void run() { + ResourceOracleImpl.preload(getTopLogger()); + } + }); + scanThread.setDaemon(true); + scanThread.setPriority((Thread.MIN_PRIORITY + Thread.NORM_PRIORITY) / 2); + scanThread.start(); + + return super.doStartup(); + } + + @Override protected int doStartUpServer() { // Create the war directory if it doesn't exist File warDir = options.getWarDir();
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java b/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java index 31b5b44..d6dcb5b 100644 --- a/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java +++ b/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
@@ -172,6 +172,30 @@ } /** + * Preinitializes the classpath from the thread default {@link ClassLoader}. + */ + public static void preload(TreeLogger logger) { + preload(logger, Thread.currentThread().getContextClassLoader()); + } + + /** + * Preinitializes the classpath for a given {@link ClassLoader}. + */ + public static void preload(TreeLogger logger, ClassLoader classLoader) { + Event resourceOracle = SpeedTracerLogger.start( + CompilerEventType.RESOURCE_ORACLE, "phase", "preload"); + List<ClassPathEntry> entries = getAllClassPathEntries(logger, classLoader); + for (ClassPathEntry entry : entries) { + // We only handle pre-indexing jars, the file system could change. + if (entry instanceof ZipFileClassPathEntry) { + ZipFileClassPathEntry zpe = (ZipFileClassPathEntry) entry; + zpe.index(logger); + } + } + resourceOracle.end(); + } + + /** * Rescans the associated paths to recompute the available resources. * * TODO(conroy,scottb): This synchronization could be improved upon to allow
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java index 5194594..be2fc8f 100644 --- a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java +++ b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
@@ -90,11 +90,7 @@ @Override public Map<AbstractResource, PathPrefix> findApplicableResources( TreeLogger logger, PathPrefixSet pathPrefixSet) { - // Never re-index. - if (allZipFileResources == null) { - allZipFileResources = buildIndex(logger); - } - + index(logger); ZipFileSnapshot snapshot = cachedSnapshots.get(pathPrefixSet); if (snapshot == null || snapshot.prefixSetSize != pathPrefixSet.getSize()) { snapshot = new ZipFileSnapshot(pathPrefixSet.getSize(), @@ -113,6 +109,13 @@ return zipFile; } + synchronized void index(TreeLogger logger) { + // Never re-index. + if (allZipFileResources == null) { + allZipFileResources = buildIndex(logger); + } + } + private Set<ZipFileResource> buildIndex(TreeLogger logger) { logger = Messages.BUILDING_INDEX.branch(logger, zipFile.getName(), null);