1/*
2 * Copyright (c) 2000, 2012, 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
25package sun.jvm.hotspot.oops;
26
27import java.io.*;
28
29import sun.jvm.hotspot.runtime.*;
30import sun.jvm.hotspot.utilities.*;
31
32// Super class for all fields in an object
33public class Field {
34
35  Field(FieldIdentifier id, long offset, boolean isVMField) {
36    this.offset    = offset;
37    this.id        = id;
38    this.isVMField = isVMField;
39  }
40
41  /** Constructor for fields that are named in an InstanceKlass's
42      fields array (i.e., named, non-VM fields) */
43  Field(InstanceKlass holder, int fieldIndex) {
44    this.holder = holder;
45    this.fieldIndex = fieldIndex;
46
47    offset               = holder.getFieldOffset(fieldIndex);
48    genericSignature     = holder.getFieldGenericSignature(fieldIndex);
49
50    Symbol name          = holder.getFieldName(fieldIndex);
51    id          = new NamedFieldIdentifier(name.asString());
52
53    signature            = holder.getFieldSignature(fieldIndex);
54    fieldType   = new FieldType(signature);
55
56    short access         = holder.getFieldAccessFlags(fieldIndex);
57    accessFlags = new AccessFlags(access);
58  }
59
60  private long            offset;
61  private FieldIdentifier id;
62  private boolean         isVMField;
63  // Java fields only
64  private InstanceKlass   holder;
65  private FieldType       fieldType;
66  private Symbol          signature;
67  private Symbol          genericSignature;
68  private AccessFlags     accessFlags;
69  private int             fieldIndex;
70
71  /** Returns the byte offset of the field within the object or klass */
72  public long getOffset() { return offset; }
73
74  /** Returns the identifier of the field */
75  public FieldIdentifier getID() { return id; }
76
77  /** Indicates whether this is a VM field */
78  public boolean isVMField() { return isVMField; }
79
80  /** Indicates whether this is a named field */
81  public boolean isNamedField() { return (id instanceof NamedFieldIdentifier); }
82
83  public void printOn(PrintStream tty) {
84    getID().printOn(tty);
85    tty.print(" {" + getOffset() + "} :");
86  }
87
88  /** (Named, non-VM fields only) Returns the InstanceKlass containing
89      this (static or non-static) field. */
90  public InstanceKlass getFieldHolder() {
91    return holder;
92  }
93
94  /** (Named, non-VM fields only) Returns the index in the fields
95      TypeArray for this field. Equivalent to the "index" in the VM's
96      fieldDescriptors. */
97  public int getFieldIndex() {
98    return fieldIndex;
99  }
100
101  /** (Named, non-VM fields only) Retrieves the access flags. */
102  public long getAccessFlags() { return accessFlags.getValue(); }
103  public AccessFlags getAccessFlagsObj() { return accessFlags; }
104
105  /** (Named, non-VM fields only) Returns the type of this field. */
106  public FieldType getFieldType() { return fieldType; }
107
108  /** (Named, non-VM fields only) Returns the signature of this
109      field. */
110  public Symbol getSignature() { return signature; }
111  public Symbol getGenericSignature() { return genericSignature; }
112
113  public boolean hasInitialValue()           { return holder.getFieldInitialValueIndex(fieldIndex) != 0;    }
114
115  //
116  // Following acccessors are for named, non-VM fields only
117  //
118  public boolean isPublic()                  { return accessFlags.isPublic(); }
119  public boolean isPrivate()                 { return accessFlags.isPrivate(); }
120  public boolean isProtected()               { return accessFlags.isProtected(); }
121  public boolean isPackagePrivate()          { return !isPublic() && !isPrivate() && !isProtected(); }
122
123  public boolean isStatic()                  { return accessFlags.isStatic(); }
124  public boolean isFinal()                   { return accessFlags.isFinal(); }
125  public boolean isVolatile()                { return accessFlags.isVolatile(); }
126  public boolean isTransient()               { return accessFlags.isTransient(); }
127
128  public boolean isSynthetic()               { return accessFlags.isSynthetic(); }
129  public boolean isEnumConstant()            { return accessFlags.isEnum();      }
130
131  public boolean equals(Object obj) {
132     if (obj == null) {
133        return false;
134     }
135
136     if (! (obj instanceof Field)) {
137        return false;
138     }
139
140     Field other = (Field) obj;
141     return this.getFieldHolder().equals(other.getFieldHolder()) &&
142            this.getID().equals(other.getID());
143  }
144
145  public int hashCode() {
146     return getFieldHolder().hashCode() ^ getID().hashCode();
147  }
148}
149