24 */ |
24 */ |
25 |
25 |
26 package jdk.nashorn.internal.runtime; |
26 package jdk.nashorn.internal.runtime; |
27 |
27 |
28 import static jdk.nashorn.internal.lookup.Lookup.MH; |
28 import static jdk.nashorn.internal.lookup.Lookup.MH; |
29 |
|
30 import java.io.IOException; |
29 import java.io.IOException; |
31 import java.lang.invoke.MethodHandle; |
30 import java.lang.invoke.MethodHandle; |
32 import java.lang.invoke.MethodHandles; |
31 import java.lang.invoke.MethodHandles; |
33 import java.lang.invoke.MethodType; |
32 import java.lang.invoke.MethodType; |
34 import java.util.Collection; |
33 import java.util.Collection; |
618 return f.clearFlag(null, FunctionNode.IS_DECLARED); |
617 return f.clearFlag(null, FunctionNode.IS_DECLARED); |
619 } |
618 } |
620 return f; |
619 return f; |
621 } |
620 } |
622 |
621 |
623 MethodHandle lookup(final FunctionInitializer fnInit) { |
622 private void logLookup(final boolean shouldLog, final MethodType targetType) { |
|
623 if (shouldLog && log.isEnabled()) { |
|
624 log.info("Looking up ", DebugLogger.quote(functionName), " type=", targetType); |
|
625 } |
|
626 } |
|
627 |
|
628 private MethodHandle lookup(final FunctionInitializer fnInit, final boolean shouldLog) { |
624 final MethodType type = fnInit.getMethodType(); |
629 final MethodType type = fnInit.getMethodType(); |
|
630 logLookup(shouldLog, type); |
625 return lookupCodeMethod(fnInit.getCode(), type); |
631 return lookupCodeMethod(fnInit.getCode(), type); |
626 } |
632 } |
627 |
633 |
628 MethodHandle lookup(final FunctionNode fn) { |
634 MethodHandle lookup(final FunctionNode fn) { |
629 final MethodType type = new FunctionSignature(fn).getMethodType(); |
635 final MethodType type = new FunctionSignature(fn).getMethodType(); |
|
636 logLookup(true, type); |
630 return lookupCodeMethod(fn.getCompileUnit().getCode(), type); |
637 return lookupCodeMethod(fn.getCompileUnit().getCode(), type); |
631 } |
638 } |
632 |
639 |
633 MethodHandle lookupCodeMethod(final Class<?> codeClass, final MethodType targetType) { |
640 MethodHandle lookupCodeMethod(final Class<?> codeClass, final MethodType targetType) { |
634 if (log.isEnabled()) { |
|
635 log.info("Looking up ", DebugLogger.quote(functionName), " type=", targetType); |
|
636 } |
|
637 return MH.findStatic(LOOKUP, codeClass, functionName, targetType); |
641 return MH.findStatic(LOOKUP, codeClass, functionName, targetType); |
638 } |
642 } |
639 |
643 |
640 /** |
644 /** |
641 * Initializes this function data with the eagerly generated version of the code. This method can only be invoked |
645 * Initializes this function data with the eagerly generated version of the code. This method can only be invoked |
647 public void initializeCode(final FunctionInitializer initializer) { |
651 public void initializeCode(final FunctionInitializer initializer) { |
648 // Since the method is public, we double-check that we aren't invoked with an inappropriate compile unit. |
652 // Since the method is public, we double-check that we aren't invoked with an inappropriate compile unit. |
649 if(!code.isEmpty()) { |
653 if(!code.isEmpty()) { |
650 throw new IllegalStateException(name); |
654 throw new IllegalStateException(name); |
651 } |
655 } |
652 addCode(lookup(initializer), null, null, initializer.getFlags()); |
656 addCode(lookup(initializer, true), null, null, initializer.getFlags()); |
653 } |
657 } |
654 |
658 |
655 private CompiledFunction addCode(final MethodHandle target, final Map<Integer, Type> invalidatedProgramPoints, |
659 private CompiledFunction addCode(final MethodHandle target, final Map<Integer, Type> invalidatedProgramPoints, |
656 final MethodType callSiteType, final int fnFlags) { |
660 final MethodType callSiteType, final int fnFlags) { |
657 final CompiledFunction cfn = new CompiledFunction(target, this, invalidatedProgramPoints, callSiteType, fnFlags); |
661 final CompiledFunction cfn = new CompiledFunction(target, this, invalidatedProgramPoints, callSiteType, fnFlags); |
669 * @param callSiteType the call site type |
673 * @param callSiteType the call site type |
670 * @return the compiled function object, with its type matching that of the call site type. |
674 * @return the compiled function object, with its type matching that of the call site type. |
671 */ |
675 */ |
672 private CompiledFunction addCode(final FunctionInitializer fnInit, final MethodType callSiteType) { |
676 private CompiledFunction addCode(final FunctionInitializer fnInit, final MethodType callSiteType) { |
673 if (isVariableArity()) { |
677 if (isVariableArity()) { |
674 return addCode(lookup(fnInit), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags()); |
678 return addCode(lookup(fnInit, true), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags()); |
675 } |
679 } |
676 |
680 |
677 final MethodHandle handle = lookup(fnInit); |
681 final MethodHandle handle = lookup(fnInit, true); |
678 final MethodType fromType = handle.type(); |
682 final MethodType fromType = handle.type(); |
679 MethodType toType = needsCallee(fromType) ? callSiteType.changeParameterType(0, ScriptFunction.class) : callSiteType.dropParameterTypes(0, 1); |
683 MethodType toType = needsCallee(fromType) ? callSiteType.changeParameterType(0, ScriptFunction.class) : callSiteType.dropParameterTypes(0, 1); |
680 toType = toType.changeReturnType(fromType.returnType()); |
684 toType = toType.changeReturnType(fromType.returnType()); |
681 |
685 |
682 final int toCount = toType.parameterCount(); |
686 final int toCount = toType.parameterCount(); |
697 toType = toType.appendParameterTypes(fromType.parameterList().subList(toCount, fromCount)); |
701 toType = toType.appendParameterTypes(fromType.parameterList().subList(toCount, fromCount)); |
698 } else if (fromCount < toCount) { |
702 } else if (fromCount < toCount) { |
699 toType = toType.dropParameterTypes(fromCount, toCount); |
703 toType = toType.dropParameterTypes(fromCount, toCount); |
700 } |
704 } |
701 |
705 |
702 return addCode(lookup(fnInit).asType(toType), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags()); |
706 return addCode(lookup(fnInit, false).asType(toType), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags()); |
703 } |
707 } |
704 |
708 |
705 /** |
709 /** |
706 * Returns the return type of a function specialization for particular parameter types.<br> |
710 * Returns the return type of a function specialization for particular parameter types.<br> |
707 * <b>Be aware that the way this is implemented, it forces full materialization (compilation and installation) of |
711 * <b>Be aware that the way this is implemented, it forces full materialization (compilation and installation) of |