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 }