jdk/src/share/classes/java/lang/invoke/Invokers.java
changeset 9752 88ab34b6da6d
parent 9646 5ebbe5ab084f
child 10419 12c063b39232
equal deleted inserted replaced
9731:d0f7a3e441c4 9752:88ab34b6da6d
    44     /*lazy*/ MethodHandle erasedInvokerWithDrops;  // for InvokeGeneric
    44     /*lazy*/ MethodHandle erasedInvokerWithDrops;  // for InvokeGeneric
    45 
    45 
    46     // general invoker for the outgoing call
    46     // general invoker for the outgoing call
    47     private /*lazy*/ MethodHandle generalInvoker;
    47     private /*lazy*/ MethodHandle generalInvoker;
    48 
    48 
    49     // general invoker for the outgoing call; accepts a single Object[]
    49     // general invoker for the outgoing call, uses varargs
       
    50     private /*lazy*/ MethodHandle varargsInvoker;
       
    51 
       
    52     // general invoker for the outgoing call; accepts a trailing Object[]
    50     private final /*lazy*/ MethodHandle[] spreadInvokers;
    53     private final /*lazy*/ MethodHandle[] spreadInvokers;
    51 
    54 
    52     // invoker for an unbound callsite
    55     // invoker for an unbound callsite
    53     private /*lazy*/ MethodHandle uninitializedCallSite;
    56     private /*lazy*/ MethodHandle uninitializedCallSite;
    54 
    57 
    65     }
    68     }
    66 
    69 
    67     /*non-public*/ MethodHandle exactInvoker() {
    70     /*non-public*/ MethodHandle exactInvoker() {
    68         MethodHandle invoker = exactInvoker;
    71         MethodHandle invoker = exactInvoker;
    69         if (invoker != null)  return invoker;
    72         if (invoker != null)  return invoker;
    70         try {
    73         invoker = lookupInvoker("invokeExact");
    71             invoker = IMPL_LOOKUP.findVirtual(MethodHandle.class, "invokeExact", targetType);
       
    72         } catch (ReflectiveOperationException ex) {
       
    73             throw new InternalError("JVM cannot find invoker for "+targetType);
       
    74         }
       
    75         assert(invokerType(targetType) == invoker.type());
       
    76         exactInvoker = invoker;
    74         exactInvoker = invoker;
    77         return invoker;
    75         return invoker;
    78     }
    76     }
    79 
    77 
    80     /*non-public*/ MethodHandle generalInvoker() {
    78     /*non-public*/ MethodHandle generalInvoker() {
    81         MethodHandle invoker1 = exactInvoker();
       
    82         MethodHandle invoker = generalInvoker;
    79         MethodHandle invoker = generalInvoker;
    83         if (invoker != null)  return invoker;
    80         if (invoker != null)  return invoker;
    84         MethodType generalType = targetType.generic();
    81         invoker = lookupInvoker("invoke");
    85         invoker = invoker1.asType(invokerType(generalType));
       
    86         generalInvoker = invoker;
    82         generalInvoker = invoker;
    87         return invoker;
    83         return invoker;
    88     }
    84     }
    89 
    85 
       
    86     private MethodHandle lookupInvoker(String name) {
       
    87         MethodHandle invoker;
       
    88         try {
       
    89             invoker = IMPL_LOOKUP.findVirtual(MethodHandle.class, name, targetType);
       
    90         } catch (ReflectiveOperationException ex) {
       
    91             throw new InternalError("JVM cannot find invoker for "+targetType);
       
    92         }
       
    93         assert(invokerType(targetType) == invoker.type());
       
    94         assert(!invoker.isVarargsCollector());
       
    95         return invoker;
       
    96     }
       
    97 
    90     /*non-public*/ MethodHandle erasedInvoker() {
    98     /*non-public*/ MethodHandle erasedInvoker() {
    91         MethodHandle invoker1 = exactInvoker();
    99         MethodHandle xinvoker = exactInvoker();
    92         MethodHandle invoker = erasedInvoker;
   100         MethodHandle invoker = erasedInvoker;
    93         if (invoker != null)  return invoker;
   101         if (invoker != null)  return invoker;
    94         MethodType erasedType = targetType.erase();
   102         MethodType erasedType = targetType.erase();
    95         if (erasedType == targetType.generic())
   103         invoker = xinvoker.asType(invokerType(erasedType));
    96             invoker = generalInvoker();
       
    97         else
       
    98             invoker = invoker1.asType(invokerType(erasedType));
       
    99         erasedInvoker = invoker;
   104         erasedInvoker = invoker;
   100         return invoker;
   105         return invoker;
   101     }
   106     }
   102 
   107 
   103     /*non-public*/ MethodHandle spreadInvoker(int objectArgCount) {
   108     /*non-public*/ MethodHandle spreadInvoker(int leadingArgCount) {
   104         MethodHandle vaInvoker = spreadInvokers[objectArgCount];
   109         MethodHandle vaInvoker = spreadInvokers[leadingArgCount];
   105         if (vaInvoker != null)  return vaInvoker;
   110         if (vaInvoker != null)  return vaInvoker;
   106         MethodHandle gInvoker = generalInvoker();
   111         MethodHandle gInvoker = generalInvoker();
   107         vaInvoker = gInvoker.asSpreader(Object[].class, targetType.parameterCount() - objectArgCount);
   112         int spreadArgCount = targetType.parameterCount() - leadingArgCount;
   108         spreadInvokers[objectArgCount] = vaInvoker;
   113         vaInvoker = gInvoker.asSpreader(Object[].class, spreadArgCount);
       
   114         spreadInvokers[leadingArgCount] = vaInvoker;
       
   115         return vaInvoker;
       
   116     }
       
   117 
       
   118     /*non-public*/ MethodHandle varargsInvoker() {
       
   119         MethodHandle vaInvoker = varargsInvoker;
       
   120         if (vaInvoker != null)  return vaInvoker;
       
   121         vaInvoker = spreadInvoker(0).asType(invokerType(MethodType.genericMethodType(0, true)));
       
   122         varargsInvoker = vaInvoker;
   109         return vaInvoker;
   123         return vaInvoker;
   110     }
   124     }
   111 
   125 
   112     private static MethodHandle THROW_UCS = null;
   126     private static MethodHandle THROW_UCS = null;
   113 
   127