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 }