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.classloader; 014 015import static org.jikesrvm.classloader.ClassLoaderConstants.ACC_PRIVATE; 016import static org.jikesrvm.classloader.ClassLoaderConstants.ACC_PROTECTED; 017import static org.jikesrvm.classloader.ClassLoaderConstants.ACC_PUBLIC; 018 019import org.jikesrvm.VM; 020import org.vmmagic.pragma.Uninterruptible; 021import org.vmmagic.unboxed.Offset; 022 023/** 024 * A field or method of a java class. 025 */ 026public abstract class RVMMember extends AnnotatedElement { 027 028 /** Initial value for a field offset - indicates field not laid out. */ 029 private static final int NO_OFFSET = Short.MIN_VALUE + 1; 030 031 /** 032 * The class that declared this member, available by calling 033 * getDeclaringClass once the class is loaded. 034 */ 035 private final TypeReference declaringClass; 036 037 /** 038 * The canonical MemberReference for this member 039 */ 040 protected final MemberReference memRef; 041 042 /** 043 * The modifiers associated with this member. 044 */ 045 protected final short modifiers; 046 047 /** 048 * The signature is a string representing the generic type for this 049 * field or method declaration, may be null 050 */ 051 private final Atom signature; 052 053 /** 054 * The member's jtoc/obj/tib offset in bytes. 055 * Set by {@link RVMClass#resolve()} 056 */ 057 protected int offset; 058 059 /** 060 * NOTE: Only {@link RVMClass} is allowed to create an instance of a RVMMember. 061 * 062 * @param declaringClass the TypeReference object of the class that declared this member 063 * @param memRef the canonical memberReference for this member. 064 * @param modifiers modifiers associated with this member. 065 * @param signature generic type of this member 066 * @param annotations array of runtime visible annotations 067 */ 068 protected RVMMember(TypeReference declaringClass, MemberReference memRef, short modifiers, Atom signature, 069 RVMAnnotation[] annotations) { 070 super(annotations); 071 this.declaringClass = declaringClass; 072 this.memRef = memRef; 073 this.modifiers = modifiers; 074 this.signature = signature; 075 this.offset = NO_OFFSET; // invalid value. Set to valid value during RVMClass.resolve() 076 } 077 078 //--------------------------------------------------------------------// 079 // Section 1. // 080 // The following are available after class loading. // 081 //--------------------------------------------------------------------// 082 083 /** 084 * @return the class that declared this field or method. Not available before 085 * the class is loaded. 086 */ 087 @Uninterruptible 088 public final RVMClass getDeclaringClass() { 089 return declaringClass.peekType().asClass(); 090 } 091 092 /** 093 * @return canonical member reference for this member. 094 */ 095 @Uninterruptible 096 public final MemberReference getMemberRef() { 097 return memRef; 098 } 099 100 /** 101 * @return name of this member. 102 */ 103 @Uninterruptible 104 public final Atom getName() { 105 return memRef.getName(); 106 } 107 108 /** 109 * @return Descriptor for this member. 110 * something like "I" for a field or "(I)V" for a method. 111 */ 112 @Uninterruptible 113 public final Atom getDescriptor() { 114 return memRef.getDescriptor(); 115 } 116 117 /** 118 * @return generic type for member 119 */ 120 public final Atom getSignature() { 121 return signature; 122 } 123 124 /** 125 * Gets a unique id for this member. 126 * The id is the id of the canonical MemberReference for this member 127 * and thus may be used to find the member by first finding the member reference. 128 * 129 * @return id of the canonical member reference for this member 130 */ 131 @Uninterruptible 132 public final int getId() { 133 return memRef.getId(); 134 } 135 136 /* 137 * Define hashcode in terms of Atom.hashCode to enable 138 * consistent hash codes during bootImage writing and run-time. 139 */ 140 @Override 141 public int hashCode() { 142 return memRef.hashCode(); 143 } 144 145 @Override 146 public final String toString() { 147 return declaringClass + "." + getName() + " " + getDescriptor(); 148 } 149 150 /** 151 * @return {@code true} if the member is usable from classes outside its 152 * package? 153 */ 154 public final boolean isPublic() { 155 return (modifiers & ACC_PUBLIC) != 0; 156 } 157 158 /** 159 * @return {@code true} if the member is usable only from this class 160 */ 161 public final boolean isPrivate() { 162 return (modifiers & ACC_PRIVATE) != 0; 163 } 164 165 /** 166 * @return {@code true} if the member is usable from subclasses 167 */ 168 public final boolean isProtected() { 169 return (modifiers & ACC_PROTECTED) != 0; 170 } 171 172 /** 173 * @return the member's modifiers 174 * @see ClassLoaderConstants 175 */ 176 public final int getModifiers() { 177 return modifiers; 178 } 179 180 /** 181 * Has the field been laid out in the object yet ? 182 * 183 * @return {@code true} if the field has been assigned an offset, {@code false} if not 184 */ 185 public final boolean hasOffset() { 186 return !(offset == NO_OFFSET); 187 } 188 189 //------------------------------------------------------------------// 190 // Section 2. // 191 // The following are available after the declaring class has been // 192 // "resolved". // 193 //------------------------------------------------------------------// 194 195 /** 196 * Offset of this field or method, in bytes. 197 * <ul> 198 * <li> For a static field: offset of field from start of jtoc 199 * <li> For a static method: offset of code object reference from start of jtoc 200 * <li> For a non-static field: offset of field from start of object 201 * <li> For a non-static method: offset of code object reference from start of tib 202 * </ul> 203 * 204 * @return offset in bytes as described above 205 */ 206 @Uninterruptible 207 public final Offset getOffset() { 208 if (VM.VerifyAssertions) VM._assert(declaringClass != null); 209 if (VM.VerifyAssertions) VM._assert(declaringClass.isLoaded()); 210 if (VM.VerifyAssertions) VM._assert(offset != NO_OFFSET); 211 return Offset.fromIntSignExtend(offset); 212 } 213 214 /** 215 * Only meant to be used by ObjectModel.layoutInstanceFields. 216 * TODO: refactor system so this functionality is in the classloader package 217 * and this method doesn't have to be final. 218 * 219 * @param off new offset for this member 220 */ 221 public final void setOffset(Offset off) { 222 offset = off.toInt(); 223 } 224} 225