Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ private static final class AnonymousContextCodeInstaller extends ContextCodeInst
private static final MethodHandle DEFINE_ANONYMOUS_CLASS = getDefineAnonymousClass();
private static final String ANONYMOUS_HOST_CLASS_NAME = Compiler.SCRIPTS_PACKAGE.replace('/', '.') + ".AnonymousHost";
private static final byte[] ANONYMOUS_HOST_CLASS_BYTES = getAnonymousHostClassBytes();
static volatile Exception initFailure;

private final Class<?> hostClass;

Expand All @@ -331,8 +332,9 @@ private static MethodHandle getDefineAnonymousClass() {
final Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return mh.bindTo(f.get(null));
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
} catch (Exception e) {
initFailure = e;
return null;
}
});
}
Expand Down Expand Up @@ -1501,8 +1503,9 @@ private synchronized Class<?> compile(final Source source, final ErrorManager er
final URL url = source.getURL();
final CodeSource cs = new CodeSource(url, (CodeSigner[])null);
final CodeInstaller installer;
if (!env.useAnonymousClasses(source.getLength()) || env._persistent_cache || !env._lazy_compilation) {
// Persistent code cache and eager compilation preclude use of VM anonymous classes
if (env._persistent_cache || !env._lazy_compilation || !env.useAnonymousClasses(source.getLength(), () -> AnonymousContextCodeInstaller.initFailure) ) {
// Persistent code cache, eager compilation, or inability to use Unsafe.defineAnonymousClass (typically, JDK 17+)
// preclude use of VM anonymous classes
final ScriptLoader loader = env._loader_per_compile ? createNewLoader() : scriptLoader;
installer = new NamedContextCodeInstaller(this, cs, loader);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.function.Supplier;
import java.util.logging.Level;
import org.openjdk.nashorn.internal.codegen.Namespace;
import org.openjdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
Expand Down Expand Up @@ -225,7 +227,7 @@ public enum FunctionStatementBehavior {
/** Timing */
public final Timing _timing;

/** Whether to use anonymous classes. See {@link #useAnonymousClasses(int)}. */
/** Whether to use anonymous classes. See {@link #useAnonymousClasses(int, Supplier)}. */
private final AnonymousClasses _anonymousClasses;
private enum AnonymousClasses {
AUTO,
Expand Down Expand Up @@ -477,9 +479,16 @@ public boolean isTimingEnabled() {
* @param sourceLength length of source being compiled.
* @return true if anonymous classes should be used
*/
public boolean useAnonymousClasses(final int sourceLength) {
return _anonymousClasses == AnonymousClasses.ON
|| (_anonymousClasses == AnonymousClasses.AUTO && sourceLength <= _anonymous_classes_threshold);
public boolean useAnonymousClasses(final int sourceLength, Supplier<Exception> anonymousInitFailure) {
if (_anonymousClasses == AnonymousClasses.ON) {
Optional.ofNullable(anonymousInitFailure.get()).ifPresent(e -> {
throw new IllegalStateException("Can not use anonymous class loading", e);
});
return true;
}
return _anonymousClasses == AnonymousClasses.AUTO &&
sourceLength <= _anonymous_classes_threshold &&
anonymousInitFailure.get() == null;
}

}