nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
changeset 24738 be2026c9717c
parent 24731 ab0c8fc915ae
child 24740 26791be09688
equal deleted inserted replaced
24736:4e7eba3d014b 24738:be2026c9717c
    70      * more specific type for sorting
    70      * more specific type for sorting
    71      */
    71      */
    72     private MethodHandle invoker;
    72     private MethodHandle invoker;
    73     private MethodHandle constructor;
    73     private MethodHandle constructor;
    74     private OptimismInfo optimismInfo;
    74     private OptimismInfo optimismInfo;
       
    75     private int flags; // from FunctionNode
    75 
    76 
    76     CompiledFunction(final MethodHandle invoker) {
    77     CompiledFunction(final MethodHandle invoker) {
    77         this.invoker = invoker;
    78         this.invoker = invoker;
    78     }
    79     }
    79 
    80 
    85     CompiledFunction(final MethodHandle invoker, final MethodHandle constructor) {
    86     CompiledFunction(final MethodHandle invoker, final MethodHandle constructor) {
    86         this(invoker);
    87         this(invoker);
    87         this.constructor = constructor;
    88         this.constructor = constructor;
    88     }
    89     }
    89 
    90 
    90     CompiledFunction(final MethodHandle invoker, final RecompilableScriptFunctionData functionData, final boolean isOptimistic) {
    91     CompiledFunction(final MethodHandle invoker, final RecompilableScriptFunctionData functionData, final int flags) {
    91         this(invoker);
    92         this(invoker);
    92         if(isOptimistic) {
    93         this.flags = flags;
       
    94         if ((flags & FunctionNode.IS_OPTIMISTIC) != 0) {
    93             optimismInfo = new OptimismInfo(functionData);
    95             optimismInfo = new OptimismInfo(functionData);
    94         } else {
    96         } else {
    95             optimismInfo = null;
    97             optimismInfo = null;
    96         }
    98         }
       
    99     }
       
   100 
       
   101     int getFlags() {
       
   102         return flags;
       
   103     }
       
   104 
       
   105     boolean isVarArg() {
       
   106         return isVarArgsType(invoker.type());
    97     }
   107     }
    98 
   108 
    99     @Override
   109     @Override
   100     public String toString() {
   110     public String toString() {
   101         return "<callSiteType=" + invoker.type() + " invoker=" + invoker + " ctor=" + constructor + " weight=" + weight() + ">";
   111         return "<callSiteType=" + invoker.type() + " invoker=" + invoker + " ctor=" + constructor + " weight=" + weight() + ">";
   125      * non-null, and that you can relink the call site it is set into as a target if the switch point is invalidated. In
   135      * non-null, and that you can relink the call site it is set into as a target if the switch point is invalidated. In
   126      * all other cases, use {@link #createComposableConstructor()}.
   136      * all other cases, use {@link #createComposableConstructor()}.
   127      * @return a direct constructor method handle for this function.
   137      * @return a direct constructor method handle for this function.
   128      */
   138      */
   129     MethodHandle getConstructor() {
   139     MethodHandle getConstructor() {
   130         if(constructor == null) {
   140         if (constructor == null) {
   131             constructor = createConstructorFromInvoker(createInvokerForPessimisticCaller());
   141             constructor = createConstructorFromInvoker(createInvokerForPessimisticCaller());
   132         }
   142         }
   133 
   143 
   134         return constructor;
   144         return constructor;
       
   145     }
       
   146 
       
   147     MethodHandle getInvoker() {
       
   148         return invoker;
   135     }
   149     }
   136 
   150 
   137     /**
   151     /**
   138      * Creates a version of the invoker intended for a pessimistic caller (return type is Object, no caller optimistic
   152      * Creates a version of the invoker intended for a pessimistic caller (return type is Object, no caller optimistic
   139      * program point available).
   153      * program point available).
   246         weight += type.parameterCount(); //more params outweigh few parameters
   260         weight += type.parameterCount(); //more params outweigh few parameters
   247 
   261 
   248         return weight;
   262         return weight;
   249     }
   263     }
   250 
   264 
   251     private static boolean isVarArgsType(final MethodType type) {
   265     static boolean isVarArgsType(final MethodType type) {
   252         assert type.parameterCount() >= 1 : type;
   266         assert type.parameterCount() >= 1 : type;
   253         return type.parameterType(type.parameterCount() - 1) == Object[].class;
   267         return type.parameterType(type.parameterCount() - 1) == Object[].class;
   254     }
   268     }
   255 
   269 
   256     static boolean moreGenericThan(final MethodType mt0, final MethodType mt1) {
   270     static boolean moreGenericThan(final MethodType mt0, final MethodType mt1) {
   403         final int fixParamCount = paramTypes.length - (isVarArg ? 1 : 0);
   417         final int fixParamCount = paramTypes.length - (isVarArg ? 1 : 0);
   404         if(i < fixParamCount) {
   418         if(i < fixParamCount) {
   405             return paramTypes[i];
   419             return paramTypes[i];
   406         }
   420         }
   407         assert isVarArg;
   421         assert isVarArg;
   408         return ((ArrayType)(paramTypes[paramTypes.length - 1])).getElementType();
   422         return ((ArrayType)paramTypes[paramTypes.length - 1]).getElementType();
   409     }
   423     }
   410 
   424 
   411     boolean matchesCallSite(final MethodType callSiteType) {
   425     boolean matchesCallSite(final MethodType callSiteType, final boolean pickVarArg) {
   412         if(!ScriptEnvironment.globalOptimistic()) {
   426         if (!ScriptEnvironment.globalOptimistic()) {
   413             // Without optimistic recompilation, always choose the first eagerly compiled version.
   427             // Without optimistic recompilation, always choose the first eagerly compiled version.
   414             return true;
   428             return true;
   415         }
   429         }
   416 
   430 
   417         final MethodType type = type();
   431         final MethodType type  = type();
   418         final int fnParamCount = getParamCount(type);
   432         final int fnParamCount = getParamCount(type);
   419         final boolean isVarArg = fnParamCount == Integer.MAX_VALUE;
   433         final boolean isVarArg = fnParamCount == Integer.MAX_VALUE;
   420         if(isVarArg) {
   434         if (isVarArg) {
   421             return true;
   435             return pickVarArg;
   422         }
   436         }
   423 
   437 
   424         final int csParamCount = getParamCount(callSiteType);
   438         final int csParamCount = getParamCount(callSiteType);
   425         final boolean csIsVarArg = csParamCount == Integer.MAX_VALUE;
   439         final boolean csIsVarArg = csParamCount == Integer.MAX_VALUE;
   426         final int thisThisIndex = needsCallee() ? 1 : 0; // Index of "this" parameter in this function's type
   440         final int thisThisIndex = needsCallee() ? 1 : 0; // Index of "this" parameter in this function's type
   616         FunctionNode recompile(final MethodType callSiteType, final RewriteException e) {
   630         FunctionNode recompile(final MethodType callSiteType, final RewriteException e) {
   617             final Type retType = e.getReturnType();
   631             final Type retType = e.getReturnType();
   618             final Type previousFailedType = invalidatedProgramPoints.put(e.getProgramPoint(), retType);
   632             final Type previousFailedType = invalidatedProgramPoints.put(e.getProgramPoint(), retType);
   619             if (previousFailedType != null && !previousFailedType.narrowerThan(retType)) {
   633             if (previousFailedType != null && !previousFailedType.narrowerThan(retType)) {
   620                 final StackTraceElement[] stack = e.getStackTrace();
   634                 final StackTraceElement[] stack = e.getStackTrace();
   621                 final String functionId = stack.length == 0 ? data.getName() : (stack[0].getClassName() + "." + stack[0].getMethodName());
   635                 final String functionId = stack.length == 0 ? data.getName() : stack[0].getClassName() + "." + stack[0].getMethodName();
   622                 LOG.info("RewriteException for an already invalidated program point ", e.getProgramPoint(), " in ", functionId, ". This is okay for a recursive function invocation, but a bug otherwise.");
   636                 LOG.info("RewriteException for an already invalidated program point ", e.getProgramPoint(), " in ", functionId, ". This is okay for a recursive function invocation, but a bug otherwise.");
   623                 return null;
   637                 return null;
   624             }
   638             }
   625             SwitchPoint.invalidateAll(new SwitchPoint[] { optimisticAssumptions });
   639             SwitchPoint.invalidateAll(new SwitchPoint[] { optimisticAssumptions });
   626             return data.compile(callSiteType, invalidatedProgramPoints, e.getRuntimeScope(), "Deoptimizing recompilation");
   640             return data.compile(callSiteType, invalidatedProgramPoints, e.getRuntimeScope(), "Deoptimizing recompilation");