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       * Create 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      /**
056       * Return the backing array (for boot image writing)
057       */
058      public Object[] getBacking() {
059        if (VM.VerifyAssertions) VM._assert(!VM.runningVM);
060        return data;
061      }
062    
063      /**
064       * Get an ITable entry.
065       *
066       * @param index The index of the entry to get
067       * @return The value of that entry
068       */
069      @Intrinsic
070      @Uninterruptible
071      public Object get(int index) {
072        if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);
073        return data[index];
074      }
075    
076      /**
077       * Does this ITable correspond to the given interface?
078       *
079       * @param I The interface
080       * @return True if this ITable is for the given interface
081       */
082      @Inline
083      @Uninterruptible
084      public boolean isFor(RVMType I) {
085        return get(0) == I;
086      }
087    
088      /**
089       * @return The interface class for this ITable
090       */
091      @Inline
092      @Interruptible
093      public RVMClass getInterfaceClass() {
094        return (RVMClass)get(0);
095      }
096    
097    
098      /**
099       * Get the code array at the given index.
100       *
101       * @param index The index
102       * @return The code array
103       */
104      @Inline
105      @Interruptible
106      public CodeArray getCode(int index) {
107        if (VM.VerifyAssertions) VM._assert(index < length());
108        return (CodeArray)get(index);
109      }
110      /**
111       * Set an ITable entry.
112       *
113       * @param index The index of the entry to set
114       * @param value The value to set the entry to.
115       */
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      @Intrinsic
127      @Uninterruptible
128      public int length() {
129        if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);
130        return data.length;
131      }
132    }