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 */
013package org.jikesrvm.objectmodel;
014
015import org.jikesrvm.VM;
016import org.jikesrvm.classloader.RVMClass;
017import org.jikesrvm.classloader.RVMType;
018import org.jikesrvm.compilers.common.CodeArray;
019import org.vmmagic.Intrinsic;
020import org.vmmagic.pragma.Inline;
021import org.vmmagic.pragma.Interruptible;
022import org.vmmagic.pragma.NonMoving;
023import org.vmmagic.pragma.Uninterruptible;
024import org.vmmagic.pragma.UninterruptibleNoWarn;
025
026/**
027 * This class represents an instance of an interface table.
028 */
029@NonMoving
030public 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  private ITable(int size) {
038    this.data = new Object[size];
039  }
040
041  /**
042   * Creates a new ITable of the specified size.
043   *
044   * @param size The size of the ITable
045   * @return The created ITable instance.
046   */
047  public static ITable allocate(int size) {
048    if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);
049    return new ITable(size);
050  }
051
052  @Override
053  public Object[] getBacking() {
054    if (VM.VerifyAssertions) VM._assert(!VM.runningVM);
055    return data;
056  }
057
058  /**
059   * Gets an entry in the ITable.
060   *
061   * @param index The index of the entry to get
062   * @return The value of that entry
063   */
064  @Override
065  @Intrinsic
066  @Uninterruptible
067  public Object get(int index) {
068    if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);
069    return data[index];
070  }
071
072  /**
073   * Does this ITable correspond to the given interface?
074   *
075   * @param I The interface
076   * @return True if this ITable is for the given interface
077   */
078  @Inline
079  @Uninterruptible
080  public boolean isFor(RVMType I) {
081    return get(0) == I;
082  }
083
084  /**
085   * @return The interface class for this ITable
086   */
087  @Inline
088  @Interruptible
089  public RVMClass getInterfaceClass() {
090    return (RVMClass)get(0);
091  }
092
093
094  /**
095   * Gets the code array at the given index.
096   *
097   * @param index The index
098   * @return The code array
099   */
100  @Inline
101  @Interruptible
102  public CodeArray getCode(int index) {
103    if (VM.VerifyAssertions) VM._assert(index < length());
104    return (CodeArray)get(index);
105  }
106  /**
107   * Sets an entry in this ITable.
108   *
109   * @param index The index of the entry to set
110   * @param value The value to set the entry to.
111   */
112  @Override
113  @Intrinsic
114  @UninterruptibleNoWarn("Interruptible code not reachable at runtime")
115  public void set(int index, Object value) {
116    if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);
117    data[index] = value;
118  }
119
120  /**
121   * Return the length of the ITable
122   */
123  @Override
124  @Intrinsic
125  @Uninterruptible
126  public int length() {
127    if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);
128    return data.length;
129  }
130}