src/jdk/nashorn/internal/codegen/Compiler.java
Print this page
*** 60,71 ****
--- 60,74 ----
import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
import jdk.nashorn.internal.ir.TemporarySymbols;
import jdk.nashorn.internal.ir.debug.ClassHistogramElement;
import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator;
+ import jdk.nashorn.internal.runtime.CodeCache;
import jdk.nashorn.internal.runtime.CodeInstaller;
import jdk.nashorn.internal.runtime.DebugLogger;
+ import jdk.nashorn.internal.runtime.PersistentCodeCache;
+ import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.Timing;
import jdk.nashorn.internal.runtime.options.Options;
*** 403,419 ****
}
return newFunctionNode;
}
! private Class<?> install(final String className, final byte[] code) {
LOG.fine("Installing class ", className);
final Class<?> clazz = installer.install(Compiler.binaryName(className), code);
try {
- final Object[] constants = getConstantData().toArray();
// Need doPrivileged because these fields are private
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
//use reflection to write source and constants table to installed classes
--- 406,421 ----
}
return newFunctionNode;
}
! private Class<?> install(final String className, final byte[] code, final Object[] constants) {
LOG.fine("Installing class ", className);
final Class<?> clazz = installer.install(Compiler.binaryName(className), code);
try {
// Need doPrivileged because these fields are private
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
//use reflection to write source and constants table to installed classes
*** 442,455 ****
final long t0 = Timing.isEnabled() ? System.currentTimeMillis() : 0L;
assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " has no bytecode and cannot be installed";
final Map<String, Class<?>> installedClasses = new HashMap<>();
final String rootClassName = firstCompileUnitName();
final byte[] rootByteCode = bytecode.get(rootClassName);
! final Class<?> rootClass = install(rootClassName, rootByteCode);
int length = rootByteCode.length;
installedClasses.put(rootClassName, rootClass);
--- 444,467 ----
final long t0 = Timing.isEnabled() ? System.currentTimeMillis() : 0L;
assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " has no bytecode and cannot be installed";
final Map<String, Class<?>> installedClasses = new HashMap<>();
+ final Object[] constants = getConstantData().toArray();
final String rootClassName = firstCompileUnitName();
final byte[] rootByteCode = bytecode.get(rootClassName);
! final Class<?> rootClass = install(rootClassName, rootByteCode, constants);
!
! final CodeCache codeCache = installer.getCodeCache();
! if (!isLazy() && codeCache != null) {
! try {
! codeCache.putScript(source, rootClassName, bytecode, constants);
! } catch (Exception e) {
! throw new RuntimeException(e);
! }
! }
int length = rootByteCode.length;
installedClasses.put(rootClassName, rootClass);
*** 459,469 ****
continue;
}
final byte[] code = entry.getValue();
length += code.length;
! installedClasses.put(className, install(className, code));
}
for (final CompileUnit unit : compileUnits) {
unit.setCode(installedClasses.get(unit.getUnitClassName()));
}
--- 471,481 ----
continue;
}
final byte[] code = entry.getValue();
length += code.length;
! installedClasses.put(className, install(className, code, constants));
}
for (final CompileUnit unit : compileUnits) {
unit.setCode(installedClasses.get(unit.getUnitClassName()));
}
*** 497,506 ****
--- 509,554 ----
}
return rootClass;
}
+ /**
+ * Install a previously compiled class from the code cache.
+ *
+ * @param cachedScript cached script containing class bytes and constants
+ * @return main script class
+ */
+ public Class<?> install(final PersistentCodeCache.CachedScript cachedScript) {
+ this.source = cachedScript.getSource();
+
+ final Map<String, Class<?>> installedClasses = new HashMap<>();
+ final Object[] constants = cachedScript.getConstants();
+
+ final String rootClassName = cachedScript.getMainClassName();
+ final byte[] rootByteCode = cachedScript.getClassBytes().get(rootClassName);
+ final Class<?> rootClass = install(rootClassName, rootByteCode, constants);
+
+ installedClasses.put(rootClassName, rootClass);
+
+ for (final Entry<String, byte[]> entry : cachedScript.getClassBytes().entrySet()) {
+ final String className = entry.getKey();
+ if (className.equals(rootClassName)) {
+ continue;
+ }
+ final byte[] code = entry.getValue();
+
+ installedClasses.put(className, install(className, code, constants));
+ }
+ for (Object constant : constants) {
+ if (constant instanceof RecompilableScriptFunctionData) {
+ ((RecompilableScriptFunctionData) constant).setCodeAndSource(installedClasses, source);
+ }
+ }
+
+ return rootClass;
+ }
+
Set<CompileUnit> getCompileUnits() {
return compileUnits;
}
boolean getStrictMode() {