src/jdk/nashorn/internal/runtime/Context.java
Print this page
@@ -149,20 +149,28 @@
@Override
public long getUniqueEvalId() {
return context.getUniqueEvalId();
}
+
+ @Override
+ public CodeCache getCodeCache() {
+ return context.codeCache;
+ }
}
/** Is Context global debug mode enabled ? */
public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug");
private static final ThreadLocal<Global> currentGlobal = new ThreadLocal<>();
- // class cache
+ // cache for loaded classes
private ClassCache classCache;
+ // persistent code cache
+ private CodeCache codeCache;
+
/**
* Get the current global scope
* @return the current global scope
*/
public static Global getGlobal() {
@@ -366,10 +374,23 @@
final int cacheSize = env._class_cache_size;
if (cacheSize > 0) {
classCache = new ClassCache(cacheSize);
}
+ if (env._persistent_cache) {
+ if (env._lazy_compilation || env._specialize_calls != null) {
+ getErr().println("Can not use persistent class caching with lazy compilation or call specialization.");
+ } else {
+ try {
+ final String cacheDir = Options.getStringProperty("nashorn.persistent.code.cache", "nashorn_code_cache");
+ codeCache = new PersistentCodeCache(cacheDir);
+ } catch (IOException e) {
+ throw new RuntimeException("Error initializing code cache", e);
+ }
+ }
+ }
+
// print version info if asked.
if (env._version) {
getErr().println("nashorn " + Version.version());
}
@@ -930,11 +951,25 @@
if (script != null) {
Compiler.LOG.fine("Code cache hit for ", source, " avoiding recompile.");
return script;
}
- final FunctionNode functionNode = new Parser(env, source, errMan, strict).parse();
+ PersistentCodeCache.CachedScript cachedScript = null;
+ FunctionNode functionNode = null;
+
+ if (!env._parse_only && codeCache != null) {
+ try {
+ cachedScript = codeCache.getScript(source);
+ } catch (IOException | ClassNotFoundException e) {
+ Compiler.LOG.warning("Error loading ", source, " from cache: ", e);
+ // Fall back to normal compilation
+ }
+ }
+
+ if (cachedScript == null) {
+ functionNode = new Parser(env, source, errMan, strict).parse();
+
if (errors.hasErrors()) {
return null;
}
if (env._print_ast) {
@@ -942,10 +977,11 @@
}
if (env._print_parse) {
getErr().println(new PrintVisitor(functionNode));
}
+ }
if (env._parse_only) {
return null;
}
@@ -954,14 +990,18 @@
final CodeSource cs = new CodeSource(url, (CodeSigner[])null);
final CodeInstaller<ScriptEnvironment> installer = new ContextCodeInstaller(this, loader, cs);
final Compiler compiler = new Compiler(installer, strict);
+ if (functionNode != null) {
final FunctionNode newFunctionNode = compiler.compile(functionNode);
script = compiler.install(newFunctionNode);
- cacheClass(source, script);
+ } else {
+ script = compiler.install(cachedScript);
+ }
+ cacheClass(source, script);
return script;
}
private ScriptLoader createNewLoader() {
return AccessController.doPrivileged(