src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java

changeset 1030
7eba45a08557
parent 1029
70597fd25c61
child 1057
ef1e5e03e03e
     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      }

mercurial