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 |