Path: blob/master/jcl/src/java.base/share/classes/java/lang/invoke/InterfaceHandle.java
12521 views
/*[INCLUDE-IF Sidecar17 & !OPENJDK_METHODHANDLES]*/1/*******************************************************************************2* Copyright (c) 2009, 2021 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* distribution and is available at https://www.eclipse.org/legal/epl-2.0/7* or the Apache License, Version 2.0 which accompanies this distribution and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*20* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception21*******************************************************************************/22package java.lang.invoke;2324import java.lang.reflect.Method;2526import static java.lang.invoke.MethodHandleResolver.getJ9ClassFromClass;2728/*29* InterfaceHandle is a MethodHandle that does interface dispatch30* on the receiver.31* <p>32* The vmSlot holds the itable index for the correct method.33* The type is the same as the method's except with the interface class prepended34*/35final class InterfaceHandle extends IndirectHandle {3637/*[IF ]*/38// Support natives defined in the JIT dll39/*[ENDIF]*/40static native void registerNatives();41static {42registerNatives();43}4445InterfaceHandle(Class<?> referenceClass, String methodName, MethodType type) throws NoSuchMethodException, IllegalAccessException {46super(indirectMethodType(type, referenceClass), referenceClass, methodName, KIND_INTERFACE);47assert referenceClass.isInterface();48this.defc = finishMethodInitialization(null, type);49}505152InterfaceHandle(Method method) throws IllegalAccessException {53super(indirectMethodType(method), method.getDeclaringClass(), method.getName(), KIND_INTERFACE, method.getModifiers());5455if (!referenceClass.isInterface()) {56throw new IllegalArgumentException();57}5859boolean succeed = setVMSlotAndRawModifiersFromMethod(this, referenceClass, method, this.kind, specialCaller);60if (!succeed) {61throw new IllegalAccessException();62}63}6465public InterfaceHandle(InterfaceHandle originalHandle, MethodType newType) {66super(originalHandle, newType);67}6869/// {{{ JIT support70protected final long vtableOffset(Object receiver) {71/*[IF]*/72/* Must be 'referenceClass' rather than 'type().parameterType(0)' or73* 'defc' so that the itable index matches the defining interface at74* handle creation time, otherwise handles on interfaces methods defined75* in parent interfaces will crash76*/77/*[ENDIF]*/78Class<?> interfaceClass = referenceClass;79if (interfaceClass.isInstance(receiver)) {80long interfaceJ9Class = getJ9ClassFromClass(interfaceClass);81long receiverJ9Class = getJ9ClassFromClass(receiver.getClass());82int result = convertITableIndexToVTableIndex(interfaceJ9Class, (int)vmSlot, receiverJ9Class) << VTABLE_ENTRY_SHIFT;83if (result < 0) {84throw new IllegalAccessError();85}86return result;87} else {88throw new IncompatibleClassChangeError();89}90}9192protected static native int convertITableIndexToVTableIndex(long interfaceClass, int itableIndex, long receiverClass);9394// Thunks9596private static final ThunkTable _thunkTable = new ThunkTable();97protected final ThunkTable thunkTable(){ return _thunkTable; }9899@FrameIteratorSkip100private final void invokeExact_thunkArchetype_V(Object receiver, int argPlaceholder) {101ComputedCalls.dispatchVirtual_V(jittedMethodAddress(receiver), vtableIndexArgument(receiver), receiver, argPlaceholder);102}103104@FrameIteratorSkip105private final int invokeExact_thunkArchetype_I(Object receiver, int argPlaceholder) {106return ComputedCalls.dispatchVirtual_I(jittedMethodAddress(receiver), vtableIndexArgument(receiver), receiver, argPlaceholder);107}108109@FrameIteratorSkip110private final long invokeExact_thunkArchetype_J(Object receiver, int argPlaceholder) {111return ComputedCalls.dispatchVirtual_J(jittedMethodAddress(receiver), vtableIndexArgument(receiver), receiver, argPlaceholder);112}113114@FrameIteratorSkip115private final float invokeExact_thunkArchetype_F(Object receiver, int argPlaceholder) {116return ComputedCalls.dispatchVirtual_F(jittedMethodAddress(receiver), vtableIndexArgument(receiver), receiver, argPlaceholder);117}118119@FrameIteratorSkip120private final double invokeExact_thunkArchetype_D(Object receiver, int argPlaceholder) {121return ComputedCalls.dispatchVirtual_D(jittedMethodAddress(receiver), vtableIndexArgument(receiver), receiver, argPlaceholder);122}123124@FrameIteratorSkip125private final Object invokeExact_thunkArchetype_L(Object receiver, int argPlaceholder) {126return ComputedCalls.dispatchVirtual_L(jittedMethodAddress(receiver), vtableIndexArgument(receiver), receiver, argPlaceholder);127}128129/// }}} JIT support130131@Override132MethodHandle cloneWithNewType(MethodType newType) {133return new InterfaceHandle(this, newType);134}135136final void compareWith(MethodHandle right, Comparator c) {137if (right instanceof InterfaceHandle) {138((InterfaceHandle)right).compareWithInterface(this, c);139} else {140c.fail();141}142}143144final void compareWithInterface(InterfaceHandle left, Comparator c) {145super.compareWithIndirect(left, c);146}147}148149150151