1 /* 2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.oops; 26 27 import java.io.*; 28 29 import sun.jvm.hotspot.runtime.*; 30 31 // Super class for all fields in an object 32 public class Field { 33 34 Field(FieldIdentifier id, long offset, boolean isVMField) { 35 this.offset = offset; 36 this.id = id; 37 this.isVMField = isVMField; 38 } 39 40 /** Constructor for fields that are named in an InstanceKlass's 41 fields array (i.e., named, non-VM fields) */ 42 Field(InstanceKlass holder, int fieldArrayIndex) { 43 this.holder = holder; 44 this.fieldArrayIndex = fieldArrayIndex; 45 46 ConstantPool cp = holder.getConstants(); 47 TypeArray fields = holder.getFields(); 48 short access = fields.getShortAt(fieldArrayIndex + InstanceKlass.ACCESS_FLAGS_OFFSET); 49 short nameIndex = fields.getShortAt(fieldArrayIndex + InstanceKlass.NAME_INDEX_OFFSET); 50 short signatureIndex = fields.getShortAt(fieldArrayIndex + InstanceKlass.SIGNATURE_INDEX_OFFSET); 51 initialValueIndex = fields.getShortAt(fieldArrayIndex + InstanceKlass.INITVAL_INDEX_OFFSET); 52 offset = VM.getVM().buildIntFromShorts(fields.getShortAt(fieldArrayIndex + InstanceKlass.LOW_OFFSET), 53 fields.getShortAt(fieldArrayIndex + InstanceKlass.HIGH_OFFSET)); 54 short genericSignatureIndex = fields.getShortAt(fieldArrayIndex + InstanceKlass.GENERIC_SIGNATURE_INDEX_OFFSET); 55 Symbol name = cp.getSymbolAt(nameIndex); 56 id = new NamedFieldIdentifier(name.asString()); 57 signature = cp.getSymbolAt(signatureIndex); 58 if (genericSignatureIndex != 0) { 59 genericSignature = cp.getSymbolAt(genericSignatureIndex); 60 } else { 61 genericSignature = null; 62 } 63 64 fieldType = new FieldType(signature); 65 accessFlags = new AccessFlags(access); 66 } 67 68 private long offset; 69 private FieldIdentifier id; 70 private boolean isVMField; 71 // Java fields only 72 private InstanceKlass holder; 73 private FieldType fieldType; 74 private Symbol signature; 75 private Symbol genericSignature; 76 private AccessFlags accessFlags; 77 private int fieldArrayIndex; 78 private int initialValueIndex; 79 80 /** Returns the byte offset of the field within the object or klass */ 81 public long getOffset() { return offset; } 82 83 /** Returns the identifier of the field */ 84 public FieldIdentifier getID() { return id; } 85 86 /** Indicates whether this is a VM field */ 87 public boolean isVMField() { return isVMField; } 88 89 /** Indicates whether this is a named field */ 90 public boolean isNamedField() { return (id instanceof NamedFieldIdentifier); } 91 92 public void printOn(PrintStream tty) { 93 getID().printOn(tty); 94 tty.print(" {" + getOffset() + "} :"); 95 } 96 97 /** (Named, non-VM fields only) Returns the InstanceKlass containing 98 this (static or non-static) field. */ 99 public InstanceKlass getFieldHolder() { 100 return holder; 101 } 102 103 /** (Named, non-VM fields only) Returns the index in the fields 104 TypeArray for this field. Equivalent to the "index" in the VM's 105 fieldDescriptors. */ 106 public int getFieldArrayIndex() { 107 return fieldArrayIndex; 108 } 109 110 /** (Named, non-VM fields only) Retrieves the access flags. */ 111 public long getAccessFlags() { return accessFlags.getValue(); } 112 public AccessFlags getAccessFlagsObj() { return accessFlags; } 113 114 /** (Named, non-VM fields only) Returns the type of this field. */ 115 public FieldType getFieldType() { return fieldType; } 116 117 /** (Named, non-VM fields only) Returns the signature of this 118 field. */ 119 public Symbol getSignature() { return signature; } 120 public Symbol getGenericSignature() { return genericSignature; } 121 122 // 123 // Following acccessors are for named, non-VM fields only 124 // 125 public boolean isPublic() { return accessFlags.isPublic(); } 126 public boolean isPrivate() { return accessFlags.isPrivate(); } 127 public boolean isProtected() { return accessFlags.isProtected(); } 128 public boolean isPackagePrivate() { return !isPublic() && !isPrivate() && !isProtected(); } 129 130 public boolean isStatic() { return accessFlags.isStatic(); } 131 public boolean isFinal() { return accessFlags.isFinal(); } 132 public boolean isVolatile() { return accessFlags.isVolatile(); } 133 public boolean isTransient() { return accessFlags.isTransient(); } 134 135 public boolean isSynthetic() { return accessFlags.isSynthetic(); } 136 public boolean isEnumConstant() { return accessFlags.isEnum(); } 137 138 public boolean hasInitialValue() { return initialValueIndex != 0; } 139 140 public boolean equals(Object obj) { 141 if (obj == null) { 142 return false; 143 } 144 145 if (! (obj instanceof Field)) { 146 return false; 147 } 148 149 Field other = (Field) obj; 150 return this.getFieldHolder().equals(other.getFieldHolder()) && 151 this.getID().equals(other.getID()); 152 } 153 154 public int hashCode() { 155 return getFieldHolder().hashCode() ^ getID().hashCode(); 156 } 157 }