Reviewers: jat, scottb,
Description:
If a GC occurs during startup, the AbstractReferenceMap that maps from
the module name to its ModuleDef in ModuleDefLoader can be cleared.
When we attempt to reload the module, we cannot because we only have the
module's "effective name" (i.e., a short, lower-case name), whereas we
need its physical name (i.e., a fully-qualified class name) to perform
the load. This patch creates a separate effective-to-physical name
mapping so even if we lose the ModuleDef we retain the ability to reload
it based on the effective name.
Please review this at
http://gwt-code-reviews.appspot.com/103801
Affected files:
dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
Index: dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
===================================================================
--- dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java (revision 6955)
+++ dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java (working copy)
@@ -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
@@ -119,6 +126,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 +288,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 maping from the module's effective name to its physical name
+ moduleEffectiveNameToPhysicalName.put(moduleDef.getName(), moduleName);
return moduleDef;
}
}