Pin modules in DevMode/DevModeBase until they are actually invoked.
Keep an effective-to-physical name mapping around in ModuleDefLoader
if a module needs to be reloaded after a GC.
Review by: jat, scottb
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6996 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 f2015bc..96fd661 100644
--- a/dev/core/src/com/google/gwt/dev/DevMode.java
+++ b/dev/core/src/com/google/gwt/dev/DevMode.java
@@ -325,6 +325,9 @@
TreeLogger moduleBranch = branch.branch(TreeLogger.INFO, moduleName);
try {
ModuleDef module = loadModule(moduleBranch, moduleName, false);
+ // Create a hard reference to the module to avoid gc-ing it until we
+ // actually load the module from the browser.
+ startupModules.put(module.getName(), module);
Util.recursiveDelete(options.getShellBaseWorkDir(module), false);
validateServletTags(moduleBranch, servletValidator, module, webXml);
TreeLogger loadLogger = moduleBranch.branch(TreeLogger.DEBUG,
diff --git a/dev/core/src/com/google/gwt/dev/DevModeBase.java b/dev/core/src/com/google/gwt/dev/DevModeBase.java
index 8725416..c5782e7 100644
--- a/dev/core/src/com/google/gwt/dev/DevModeBase.java
+++ b/dev/core/src/com/google/gwt/dev/DevModeBase.java
@@ -55,6 +55,7 @@
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
@@ -96,6 +97,8 @@
// Try to find an existing loaded version of the module def.
ModuleDef moduleDef = loadModule(logger, moduleName, true);
assert (moduleDef != null);
+ // Release the hard reference to the module if it is present.
+ startupModules.remove(moduleDef.getName());
ShellModuleSpaceHost host = doCreateShellModuleSpaceHost(logger,
moduleDef.getCompilationState(logger), moduleDef);
@@ -354,6 +357,8 @@
}
}
+ protected static final Map<String, ModuleDef> startupModules = new HashMap<String, ModuleDef>();
+
/**
* Handles the -whitelist command line flag.
*/
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
index 8455bff..72862ae 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
@@ -28,6 +28,7 @@
import java.io.Reader;
import java.net.URISyntaxException;
import java.net.URL;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -60,11 +61,17 @@
/**
* Keep soft references to loaded modules so the VM can gc them when memory is
- * tight.
+ * tight. The module's physical name is used as a key.
*/
@SuppressWarnings("unchecked")
private static final Map<String, ModuleDef> loadedModules = new ReferenceMap(
AbstractReferenceMap.HARD, AbstractReferenceMap.SOFT);
+
+ /**
+ * A mapping from effective to physical module names.
+ */
+ private static final Map<String, String> moduleEffectiveNameToPhysicalName =
+ new HashMap<String, String>();
/**
* Creates a module in memory that is not associated with a
@@ -96,7 +103,8 @@
}
/**
- * Loads a new module from the class path.
+ * Loads a new module from the class path. Equivalent to
+ * {@link #loadFromClassPath(logger, moduleName, false)}.
*
* @param logger logs the process
* @param moduleName the module to load
@@ -107,7 +115,7 @@
throws UnableToCompleteException {
return loadFromClassPath(logger, moduleName, false);
}
-
+
/**
* Loads a new module from the class path.
*
@@ -119,6 +127,12 @@
*/
public static ModuleDef loadFromClassPath(TreeLogger logger,
String moduleName, boolean refresh) throws UnableToCompleteException {
+ // Look up the module's physical name; if null, we are either encountering
+ // the module for the first time, or else the name is already physical
+ String physicalName = moduleEffectiveNameToPhysicalName.get(moduleName);
+ if (physicalName != null) {
+ moduleName = physicalName;
+ }
ModuleDef moduleDef = tryGetLoadedModule(logger, moduleName, refresh);
if (moduleDef != null) {
return moduleDef;
@@ -275,8 +289,8 @@
// Add the "physical" module name: com.google.Module
loadedModules.put(moduleName, moduleDef);
- // Add the module's effective name: some.other.Module
- loadedModules.put(moduleDef.getName(), moduleDef);
+ // Add a mapping from the module's effective name to its physical name
+ moduleEffectiveNameToPhysicalName.put(moduleDef.getName(), moduleName);
return moduleDef;
}
}