aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java')
-rw-r--r--src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java122
1 files changed, 0 insertions, 122 deletions
diff --git a/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java b/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java
deleted file mode 100644
index 4d3df509..00000000
--- a/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package jdk.nashorn.internal.objects;
-
-import static jdk.nashorn.internal.lookup.Lookup.MH;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import jdk.nashorn.internal.codegen.CompilationException;
-import jdk.nashorn.internal.codegen.Compiler;
-import jdk.nashorn.internal.codegen.FunctionSignature;
-import jdk.nashorn.internal.codegen.types.Type;
-import jdk.nashorn.internal.ir.FunctionNode;
-import jdk.nashorn.internal.runtime.CodeInstaller;
-import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.ScriptEnvironment;
-import jdk.nashorn.internal.runtime.ScriptFunction;
-import jdk.nashorn.internal.runtime.ScriptFunctionData;
-import jdk.nashorn.internal.runtime.ScriptObject;
-
-/**
- * A trampoline is a promise to compile a {@link ScriptFunction} later. It just looks like
- * the call to the script function, but when invoked it will compile the script function
- * (in a new compile unit) and invoke it
- */
-public final class ScriptFunctionTrampolineImpl extends ScriptFunctionImpl {
-
- private CodeInstaller<ScriptEnvironment> installer;
-
- /** Function node to lazily recompile when trampoline is hit */
- private FunctionNode functionNode;
-
- /**
- * Constructor
- *
- * @param installer opaque code installer from context
- * @param functionNode function node to lazily compile when trampoline is hit
- * @param data {@link ScriptFunctionData} for function
- * @param scope scope
- * @param allocator allocator
- */
- public ScriptFunctionTrampolineImpl(final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode, final ScriptFunctionData data, final ScriptObject scope, final MethodHandle allocator) {
- super(null, data, scope, allocator);
-
- this.installer = installer;
- this.functionNode = functionNode;
-
- data.setMethodHandles(makeTrampoline(), allocator);
- }
-
- private final MethodHandle makeTrampoline() {
- final MethodType mt =
- new FunctionSignature(
- true,
- functionNode.needsCallee(),
- Type.OBJECT,
- functionNode.getParameters().size()).
- getMethodType();
-
- return
- MH.bindTo(
- MH.asCollector(
- findOwnMH(
- "trampoline",
- Object.class,
- Object[].class),
- Object[].class,
- mt.parameterCount()),
- this);
- }
-
- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
- return MH.findVirtual(MethodHandles.lookup(), ScriptFunctionTrampolineImpl.class, name, MH.type(rtype, types));
- }
-
- @Override
- protected ScriptFunction makeBoundFunction(final ScriptFunctionData data) {
- //prevent trampoline recompilation cycle if a function is bound before use
- compile();
- return super.makeBoundFunction(data);
- }
-
- private MethodHandle compile() throws CompilationException {
- final Compiler compiler = new Compiler(installer, functionNode);
-
- compiler.compile();
-
- final Class<?> clazz = compiler.install();
- /* compute function signature for lazy method. this can be done first after compilation, as only then do we know
- * the final state about callees, scopes and specialized parameter types */
- final FunctionSignature signature = new FunctionSignature(true, functionNode.needsCallee(), Type.OBJECT, functionNode.getParameters().size());
- final MethodType mt = signature.getMethodType();
-
- MethodHandle mh = MH.findStatic(MethodHandles.publicLookup(), clazz, functionNode.getName(), mt);
- if (functionNode.needsCallee()) {
- mh = MH.bindTo(mh, this);
- }
-
- // now the invoker method looks like the one our superclass is expecting
- resetInvoker(mh);
-
- return mh;
- }
-
- @SuppressWarnings("unused")
- private Object trampoline(final Object... args) throws CompilationException {
- Compiler.LOG.info(">>> TRAMPOLINE: Hitting trampoline for '" + functionNode.getName() + "'");
- MethodHandle mh = compile();
-
- Compiler.LOG.info("<<< COMPILED TO: " + mh);
- // spread the array to invididual args of the correct type
- mh = MH.asSpreader(mh, Object[].class, mh.type().parameterCount());
-
- try {
- //invoke the real method the trampoline points to. this only happens once
- return mh.invoke(args);
- } catch (final RuntimeException | Error e) {
- throw e;
- } catch (final Throwable t) {
- throw new RuntimeException(t);
- }
- }
-}