Search in sources :

Example 1 with ITable

use of org.jikesrvm.objectmodel.ITable in project JikesRVM by JikesRVM.

the class InterfaceInvocation method installITable.

private static void installITable(RVMClass C, RVMClass I) {
    TIB tib = C.getTypeInformationBlock();
    ITableArray iTables = tib.getITableArray();
    if (iTables == null) {
        iTables = MemoryManager.newITableArray(2);
        tib.setITableArray(iTables);
    } else {
        for (int i = 0; i < iTables.length(); i++) {
            if (iTables.get(i).isFor(I)) {
                // some other thread just built the iTable
                return;
            }
        }
        ITableArray tmp = MemoryManager.newITableArray(iTables.length() + 1);
        for (int i = 0; i < iTables.length(); i++) {
            tmp.set(i, iTables.get(i));
        }
        iTables = tmp;
        tib.setITableArray(iTables);
    }
    if (VM.VerifyAssertions)
        VM._assert(iTables.get(iTables.length() - 1) == null);
    ITable iTable = buildITable(C, I);
    iTables.set(iTables.length() - 1, iTable);
    // iTables[0] is a move to front cache; fill it here so we can
    // assume it always contains some iTable.
    iTables.set(0, iTable);
}
Also used : ITableArray(org.jikesrvm.objectmodel.ITableArray) ITable(org.jikesrvm.objectmodel.ITable) TIB(org.jikesrvm.objectmodel.TIB) Entrypoint(org.vmmagic.pragma.Entrypoint)

Example 2 with ITable

use of org.jikesrvm.objectmodel.ITable in project JikesRVM by JikesRVM.

the class InterfaceInvocation method updateTIBEntry.

/**
 * If there is an an IMT or ITable entry that contains
 * compiled code for the argument method, then update it to
 * contain the current compiled code for the method.
 *
 * @param klass the RVMClass who's IMT/ITable is being reset
 * @param m the method that needs to be updated.
 */
public static void updateTIBEntry(RVMClass klass, RVMMethod m) {
    TIB tib = klass.getTypeInformationBlock();
    if (VM.BuildForIMTInterfaceInvocation) {
        RVMMethod[] map = klass.noIMTConflictMap;
        if (map != null) {
            for (int i = 0; i < IMT_METHOD_SLOTS; i++) {
                if (map[i] == m) {
                    IMT imt = tib.getImt();
                    imt.set(i, m.getCurrentEntryCodeArray());
                    // all done -- a method is in at most 1 IMT slot
                    return;
                }
            }
        }
    } else if (VM.BuildForITableInterfaceInvocation) {
        if (tib.getITableArray() != null) {
            ITableArray iTables = tib.getITableArray();
            Atom name = m.getName();
            Atom desc = m.getDescriptor();
            for (int i = 0; i < iTables.length(); i++) {
                ITable iTable = iTables.get(i);
                if (iTable != null) {
                    RVMClass I = iTable.getInterfaceClass();
                    RVMMethod[] interfaceMethods = I.getDeclaredMethods();
                    for (RVMMethod im : interfaceMethods) {
                        if (im.getName() == name && im.getDescriptor() == desc) {
                            iTable.set(getITableIndex(I, name, desc), m.getCurrentEntryCodeArray());
                        }
                    }
                }
            }
        }
    }
}
Also used : IMT(org.jikesrvm.objectmodel.IMT) ITableArray(org.jikesrvm.objectmodel.ITableArray) ITable(org.jikesrvm.objectmodel.ITable) TIB(org.jikesrvm.objectmodel.TIB) Entrypoint(org.vmmagic.pragma.Entrypoint)

Example 3 with ITable

use of org.jikesrvm.objectmodel.ITable in project JikesRVM by JikesRVM.

the class InterfaceInvocation method buildITable.

private static ITable buildITable(RVMClass C, RVMClass I) {
    RVMMethod[] interfaceMethods = I.getDeclaredMethods();
    TIB tib = C.getTypeInformationBlock();
    ITable iTable = MemoryManager.newITable(interfaceMethods.length + 1);
    iTable.set(0, I);
    for (RVMMethod im : interfaceMethods) {
        if (im.isClassInitializer())
            continue;
        if (VM.VerifyAssertions)
            VM._assert(im.isPublic() && im.isAbstract());
        RVMMethod vm = C.findVirtualMethod(im.getName(), im.getDescriptor());
        // Since the methods in question take no arguments, we can get away with this.
        if (vm == null || vm.isAbstract()) {
            vm = Entrypoints.raiseAbstractMethodError;
        } else if (!vm.isPublic()) {
            vm = Entrypoints.raiseIllegalAccessError;
        }
        if (vm.isStatic()) {
            vm.compile();
            iTable.set(getITableIndex(I, im.getName(), im.getDescriptor()), vm.getCurrentEntryCodeArray());
        } else {
            iTable.set(getITableIndex(I, im.getName(), im.getDescriptor()), tib.getVirtualMethod(vm.getOffset()));
        }
    }
    return iTable;
}
Also used : ITable(org.jikesrvm.objectmodel.ITable) TIB(org.jikesrvm.objectmodel.TIB)

Example 4 with ITable

use of org.jikesrvm.objectmodel.ITable in project JikesRVM by JikesRVM.

the class InterfaceInvocation method findITable.

/**
 * Return a reference to the itable for a given class, interface pair
 * We might not have created the iTable yet, in which case we will do that and then return it.
 *
 * @param tib the TIB for the class
 * @param id interface id of the interface sought (NOT dictionary id!!)
 * @return iTable for desired interface
 */
@Entrypoint
public static ITable findITable(TIB tib, int id) throws IncompatibleClassChangeError {
    ITableArray iTables = tib.getITableArray();
    // Search for the right ITable
    RVMType I = RVMClass.getInterface(id);
    if (iTables != null) {
        // check the cache at slot 0
        ITable iTable = iTables.get(0);
        if (iTable.isFor(I)) {
            // cache hit :)
            return iTable;
        }
        // Have to search the 'real' entries for the iTable
        for (int i = 1; i < iTables.length(); i++) {
            iTable = iTables.get(i);
            if (iTable.isFor(I)) {
                // found it; update cache
                iTables.set(0, iTable);
                return iTable;
            }
        }
    }
    // Didn't find the itable, so we don't yet know if
    // the class implements the interface. :(((
    // Therefore, we need to establish that and then
    // look for the iTable again.
    RVMClass C = (RVMClass) tib.getType();
    if (!RuntimeEntrypoints.isAssignableWith(I, C))
        throw new IncompatibleClassChangeError();
    synchronized (C) {
        installITable(C, (RVMClass) I);
    }
    ITable iTable = findITable(tib, id);
    if (VM.VerifyAssertions)
        VM._assert(iTable != null);
    return iTable;
}
Also used : ITableArray(org.jikesrvm.objectmodel.ITableArray) ITable(org.jikesrvm.objectmodel.ITable) Entrypoint(org.vmmagic.pragma.Entrypoint) Entrypoint(org.vmmagic.pragma.Entrypoint)

Example 5 with ITable

use of org.jikesrvm.objectmodel.ITable in project JikesRVM by JikesRVM.

the class InterfaceInvocation method invokeInterface.

/*
   * PART I: runtime routines to implement the invokeinterface bytecode.
   *         these routines are called from the generated code
   *         as part of the interface invocation sequence.
   */
/**
 * Resolve an interface method call.
 * This routine is never called by the IMT-based dispatching code.
 * It is only called for directly indexed ITables when the table
 * index was unknown at compile time (i.e. the target Interface was not loaded).
 *
 * @param target object to which interface method is to be applied
 * @param mid id of the MemberReference for the target interface method.
 * @return machine code corresponding to desired interface method
 */
@Entrypoint
public static CodeArray invokeInterface(Object target, int mid) throws IncompatibleClassChangeError {
    MethodReference mref = MemberReference.getMemberRef(mid).asMethodReference();
    RVMMethod sought = mref.resolveInterfaceMethod();
    RVMClass I = sought.getDeclaringClass();
    RVMClass C = Magic.getObjectType(target).asClass();
    if (VM.BuildForITableInterfaceInvocation) {
        TIB tib = C.getTypeInformationBlock();
        ITable iTable = findITable(tib, I.getInterfaceId());
        return iTable.getCode(getITableIndex(I, mref.getName(), mref.getDescriptor()));
    } else {
        if (!RuntimeEntrypoints.isAssignableWith(I, C))
            throw new IncompatibleClassChangeError();
        RVMMethod found = C.findVirtualMethod(sought.getName(), sought.getDescriptor());
        if (found == null)
            throw new IncompatibleClassChangeError();
        return found.getCurrentEntryCodeArray();
    }
}
Also used : ITable(org.jikesrvm.objectmodel.ITable) TIB(org.jikesrvm.objectmodel.TIB) Entrypoint(org.vmmagic.pragma.Entrypoint)

Aggregations

ITable (org.jikesrvm.objectmodel.ITable)5 TIB (org.jikesrvm.objectmodel.TIB)4 Entrypoint (org.vmmagic.pragma.Entrypoint)4 ITableArray (org.jikesrvm.objectmodel.ITableArray)3 IMT (org.jikesrvm.objectmodel.IMT)1