154
155 //// Implementation methods.
156 @Override
157 @ForceInline
158 MemberName internalMemberName() {
159 return member;
160 }
161
162 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
163
164 /**
165 * Create a LF which can invoke the given method.
166 * Cache and share this structure among all methods with
167 * the same basicType and refKind.
168 */
169 private static LambdaForm preparedLambdaForm(MemberName m, Class<?> callerClass) {
170 assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead
171 MethodType mtype = m.getInvocationType().basicType();
172 assert(!m.isMethodHandleInvoke()) : m;
173 int which;
174 switch (m.getReferenceKind()) {
175 case REF_invokeVirtual: which = LF_INVVIRTUAL; break;
176 case REF_invokeStatic: which = LF_INVSTATIC; break;
177 case REF_invokeSpecial: which = LF_INVSPECIAL; break;
178 case REF_invokeInterface: which = LF_INVINTERFACE; break;
179 case REF_newInvokeSpecial: which = LF_NEWINVSPECIAL; break;
180 default: throw new InternalError(m.toString());
181 }
182 if (which == LF_INVSTATIC && shouldBeInitialized(m)) {
183 // precompute the barrier-free version:
184 preparedLambdaForm(mtype, which);
185 which = LF_INVSTATIC_INIT;
186 }
187 if (which == LF_INVSPECIAL && callerClass != null && callerClass.isInterface()) {
188 which = LF_INVSPECIAL_IFC;
189 }
190 LambdaForm lform = preparedLambdaForm(mtype, which);
191 maybeCompile(lform, m);
192 assert(lform.methodType().dropParameterTypes(0, 1)
193 .equals(m.getInvocationType().basicType()))
194 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
195 return lform;
196 }
197
198 private static LambdaForm preparedLambdaForm(MemberName m) {
199 return preparedLambdaForm(m, null);
200 }
201
202 private static LambdaForm preparedLambdaForm(MethodType mtype, int which) {
203 LambdaForm lform = mtype.form().cachedLambdaForm(which);
204 if (lform != null) return lform;
205 lform = makePreparedLambdaForm(mtype, which);
206 return mtype.form().setCachedLambdaForm(which, lform);
207 }
|
154
155 //// Implementation methods.
156 @Override
157 @ForceInline
158 MemberName internalMemberName() {
159 return member;
160 }
161
162 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
163
164 /**
165 * Create a LF which can invoke the given method.
166 * Cache and share this structure among all methods with
167 * the same basicType and refKind.
168 */
169 private static LambdaForm preparedLambdaForm(MemberName m, Class<?> callerClass) {
170 assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead
171 MethodType mtype = m.getInvocationType().basicType();
172 assert(!m.isMethodHandleInvoke()) : m;
173 int which;
174 // MemberName.getReferenceKind may be different to the 'kind' passed to
175 // DMH.make. Specifically private/final methods that use a direct call
176 // have been adapted to REF_invokeSpecial, even though the actual
177 // invocation mode may be invokevirtual or invokeinterface.
178 switch (m.getReferenceKind()) {
179 case REF_invokeVirtual: which = LF_INVVIRTUAL; break;
180 case REF_invokeStatic: which = LF_INVSTATIC; break;
181 case REF_invokeSpecial: which = LF_INVSPECIAL; break;
182 case REF_invokeInterface: which = LF_INVINTERFACE; break;
183 case REF_newInvokeSpecial: which = LF_NEWINVSPECIAL; break;
184 default: throw new InternalError(m.toString());
185 }
186 if (which == LF_INVSTATIC && shouldBeInitialized(m)) {
187 // precompute the barrier-free version:
188 preparedLambdaForm(mtype, which);
189 which = LF_INVSTATIC_INIT;
190 }
191 // Direct calls involving interfaces require additional specialization to add
192 // in a receiver typecheck. For true invokespecial we need to inspect the callerClass
193 // for being an interface (which implies REFC is also an interface). For invokeinterface
194 // we always need the check. If the declaring class is an interface, and the method is not
195 // static, then this must be an invokeinterface.
196 if (which == LF_INVSPECIAL && ((callerClass != null && callerClass.isInterface()) ||
197 (!m.isStatic() && m.getDeclaringClass().isInterface()))) {
198 which = LF_INVSPECIAL_IFC;
199 }
200 LambdaForm lform = preparedLambdaForm(mtype, which);
201 maybeCompile(lform, m);
202 assert(lform.methodType().dropParameterTypes(0, 1)
203 .equals(m.getInvocationType().basicType()))
204 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
205 return lform;
206 }
207
208 private static LambdaForm preparedLambdaForm(MemberName m) {
209 return preparedLambdaForm(m, null);
210 }
211
212 private static LambdaForm preparedLambdaForm(MethodType mtype, int which) {
213 LambdaForm lform = mtype.form().cachedLambdaForm(which);
214 if (lform != null) return lform;
215 lform = makePreparedLambdaForm(mtype, which);
216 return mtype.form().setCachedLambdaForm(which, lform);
217 }
|