diff options
Diffstat (limited to 'src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java')
-rw-r--r-- | src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java | 122 |
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); - } - } -} |