1.1 --- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Mon Sep 29 14:39:58 2014 -0700 1.2 +++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Thu Oct 02 16:30:49 2014 +0200 1.3 @@ -26,6 +26,7 @@ 1.4 package jdk.nashorn.internal.runtime; 1.5 1.6 import static jdk.nashorn.internal.lookup.Lookup.MH; 1.7 + 1.8 import java.io.IOException; 1.9 import java.lang.invoke.MethodHandle; 1.10 import java.lang.invoke.MethodHandles; 1.11 @@ -268,7 +269,7 @@ 1.12 if (this.source == null && this.installer == null) { 1.13 this.source = src; 1.14 this.installer = inst; 1.15 - } else if (this.source != src || this.installer != inst) { 1.16 + } else if (this.source != src || !this.installer.isCompatibleWith(inst)) { 1.17 // Existing values must be same as those passed as parameters 1.18 throw new IllegalArgumentException(); 1.19 } 1.20 @@ -407,6 +408,17 @@ 1.21 return getCompiler(fn, actualCallSiteType, newLocals(runtimeScope), null, null); 1.22 } 1.23 1.24 + /** 1.25 + * Returns a code installer for installing new code. If we're using either optimistic typing or loader-per-compile, 1.26 + * then asks for a code installer with a new class loader; otherwise just uses the current installer. We use 1.27 + * a new class loader with optimistic typing so that deoptimized code can get reclaimed by GC. 1.28 + * @return a code installer for installing new code. 1.29 + */ 1.30 + private CodeInstaller<ScriptEnvironment> getInstallerForNewCode() { 1.31 + final ScriptEnvironment env = installer.getOwner(); 1.32 + return env._optimistic_types || env._loader_per_compile ? installer.withNewLoader() : installer; 1.33 + } 1.34 + 1.35 Compiler getCompiler(final FunctionNode functionNode, final MethodType actualCallSiteType, 1.36 final ScriptObject runtimeScope, final Map<Integer, Type> invalidatedProgramPoints, 1.37 final int[] continuationEntryPoints) { 1.38 @@ -417,7 +429,7 @@ 1.39 return new Compiler( 1.40 context, 1.41 context.getEnv(), 1.42 - installer, 1.43 + getInstallerForNewCode(), 1.44 functionNode.getSource(), // source 1.45 context.getErrorManager(), 1.46 isStrict() | functionNode.isStrict(), // is strict 1.47 @@ -463,11 +475,12 @@ 1.48 final TypeMap typeMap = typeMap(actualCallSiteType); 1.49 final Type[] paramTypes = typeMap == null ? null : typeMap.getParameterTypes(functionNodeId); 1.50 cacheKey = CodeStore.getCacheKey(functionNodeId, paramTypes); 1.51 - final StoredScript script = installer.loadScript(source, cacheKey); 1.52 + final CodeInstaller<ScriptEnvironment> newInstaller = getInstallerForNewCode(); 1.53 + final StoredScript script = newInstaller.loadScript(source, cacheKey); 1.54 1.55 if (script != null) { 1.56 Compiler.updateCompilationId(script.getCompilationId()); 1.57 - return install(script); 1.58 + return installStoredScript(script, newInstaller); 1.59 } 1.60 } 1.61 1.62 @@ -481,15 +494,7 @@ 1.63 return new FunctionInitializer(compiledFn, compiler.getInvalidatedProgramPoints()); 1.64 } 1.65 1.66 - 1.67 - /** 1.68 - * Install this script using the given {@code installer}. 1.69 - * 1.70 - * @param script the compiled script 1.71 - * @return the function initializer 1.72 - */ 1.73 - private FunctionInitializer install(final StoredScript script) { 1.74 - 1.75 + private static Map<String, Class<?>> installStoredScriptClasses(final StoredScript script, final CodeInstaller<ScriptEnvironment> installer) { 1.76 final Map<String, Class<?>> installedClasses = new HashMap<>(); 1.77 final Map<String, byte[]> classBytes = script.getClassBytes(); 1.78 final String mainClassName = script.getMainClassName(); 1.79 @@ -509,6 +514,17 @@ 1.80 1.81 installedClasses.put(className, installer.install(className, bytecode)); 1.82 } 1.83 + return installedClasses; 1.84 + } 1.85 + 1.86 + /** 1.87 + * Install this script using the given {@code installer}. 1.88 + * 1.89 + * @param script the compiled script 1.90 + * @return the function initializer 1.91 + */ 1.92 + private FunctionInitializer installStoredScript(final StoredScript script, final CodeInstaller<ScriptEnvironment> newInstaller) { 1.93 + final Map<String, Class<?>> installedClasses = installStoredScriptClasses(script, newInstaller); 1.94 1.95 final Map<Integer, FunctionInitializer> initializers = script.getInitializers(); 1.96 assert initializers != null; 1.97 @@ -523,7 +539,7 @@ 1.98 } 1.99 } 1.100 1.101 - installer.initialize(installedClasses.values(), source, constants); 1.102 + newInstaller.initialize(installedClasses.values(), source, constants); 1.103 initializer.setCode(installedClasses.get(initializer.getClassName())); 1.104 return initializer; 1.105 }