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