001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.jikesrvm.objectmodel;
014    
015    import org.jikesrvm.VM;
016    import org.jikesrvm.classloader.RVMClass;
017    import org.jikesrvm.classloader.RVMType;
018    import org.jikesrvm.ArchitectureSpecific.CodeArray;
019    import org.vmmagic.Intrinsic;
020    import org.vmmagic.pragma.Inline;
021    import org.vmmagic.pragma.Interruptible;
022    import org.vmmagic.pragma.NonMoving;
023    import org.vmmagic.pragma.Uninterruptible;
024    import org.vmmagic.pragma.UninterruptibleNoWarn;
025    
026    /**
027     * This class represents an instance of an interface table.
028     */
029    @NonMoving
030    public final class ITable implements RuntimeTable<Object> {
031    
032      /**
033       * The backing data used during boot image writing.
034       */
035      private final Object[] data;
036    
037      /**
038       * Private constructor. Can not create instances.
039       */
040      private ITable(int size) {
041        this.data = new Object[size];
042      }
043    
044      /**
045       * Creates a new ITable of the specified size.
046       *
047       * @param size The size of the ITable
048       * @return The created ITable instance.
049       */
050      public static ITable allocate(int size) {
051        if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);
052        return new ITable(size);
053      }
054    
055      @Override
056      public Object[] getBacking() {
057        if (VM.VerifyAssertions) VM._assert(!VM.runningVM);
058        return data;
059      }
060    
061      /**
062       * Gets an entry in the ITable.
063       *
064       * @param index The index of the entry to get
065       * @return The value of that entry
066       */
067      @Override
068      @Intrinsic
069      @Uninterruptible
070      public Object get(int index) {
071        if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);
072        return data[index];
073      }
074    
075      /**
076       * Does this ITable correspond to the given interface?
077       *
078       * @param I The interface
079       * @return True if this ITable is for the given interface
080       */
081      @Inline
082      @Uninterruptible
083      public boolean isFor(RVMType I) {
084        return get(0) == I;
085      }
086    
087      /**
088       * @return The interface class for this ITable
089       */
090      @Inline
091      @Interruptible
092      public RVMClass getInterfaceClass() {
093        return (RVMClass)get(0);
094      }
095    
096    
097      /**
098       * Gets the code array at the given index.
099       *
100       * @param index The index
101       * @return The code array
102       */
103      @Inline
104      @Interruptible
105      public CodeArray getCode(int index) {
106        if (VM.VerifyAssertions) VM._assert(index < length());
107        return (CodeArray)get(index);
108      }
109      /**
110       * Sets an entry in this ITable.
111       *
112       * @param index The index of the entry to set
113       * @param value The value to set the entry to.
114       */
115      @Override
116      @Intrinsic
117      @UninterruptibleNoWarn("Interruptible code not reachable at runtime")
118      public void set(int index, Object value) {
119        if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);
120        data[index] = value;
121      }
122    
123      /**
124       * Return the length of the ITable
125       */
126      @Override
127      @Intrinsic
128      @Uninterruptible
129      public int length() {
130        if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);
131        return data.length;
132      }
133    }