Fix incorrect IncompatibleClassChangeError in ClassInfo.getDefaultMethod (#7)
[jpf-core.git] / src / main / gov / nasa / jpf / vm / StaticElementInfo.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package gov.nasa.jpf.vm;
19
20 import gov.nasa.jpf.JPFException;
21 import gov.nasa.jpf.util.HashData;
22
23 /**
24  * A specialized version of ElementInfo that is used for static fields. Each
25  * registered ClassInfo instance has its own StaticElementInfo instance
26  */
27 public final class StaticElementInfo extends ElementInfo {
28
29   // this is kind of dangerous - make sure these flags are still unused in ElementInfo
30   static final int ATTR_COR_CHANGED    = 0x100000;
31   static final int ATTR_STATUS_CHANGED = 0x200000;
32
33   static final int ATTR_ANY_CHANGED = ElementInfo.ATTR_ANY_CHANGED | ATTR_COR_CHANGED | ATTR_STATUS_CHANGED;
34   
35   protected int classObjectRef = MJIEnv.NULL;
36   protected int status = ClassInfo.UNINITIALIZED;
37
38   
39   public StaticElementInfo () {
40   }
41
42   public StaticElementInfo (int id, ClassInfo ci, Fields f, Monitor m, ThreadInfo ti, ElementInfo eiClsObj) {
43     super(id, ci, f, m, ti);
44
45     // startup classes don't have a class object yet
46     if (eiClsObj != null) {
47       classObjectRef = eiClsObj.getObjectRef();
48     }
49
50     ti.getScheduler().initializeClassSharedness(ti, this);
51   }
52   
53   @Override
54   public ElementInfo getModifiableInstance() {
55     if (!isFrozen()) {
56       return this;
57     } else {
58       Statics statics = ci.getStatics();
59       return statics.getModifiable( objRef);
60     }
61   }
62   
63   @Override
64   public boolean isObject(){
65     return false;
66   }
67
68   @Override
69   public boolean isArray(){
70     return false;
71   }
72   
73   @Override
74   public boolean hasFinalizer() {
75     return false;
76   }
77   
78   @Override
79   protected int getNumberOfFieldsOrElements(){
80     // static fields can't be arrays, those are always heap objects
81     return ci.getNumberOfStaticFields();
82   }
83
84   @Override
85   public boolean hasChanged() {
86     return (attributes & ATTR_ANY_CHANGED) != 0;
87   }
88
89   @Override
90   public void markUnchanged() {
91     attributes &= ~ATTR_ANY_CHANGED;
92   }
93   
94   @Override
95   public void hash(HashData hd) {
96     super.hash(hd);
97     hd.add(classObjectRef);
98     hd.add(status);
99   }
100
101   @Override
102   public boolean equals(Object o) {
103     if (super.equals(o) && o instanceof StaticElementInfo) {
104       StaticElementInfo other = (StaticElementInfo) o;
105
106       if (classObjectRef != other.classObjectRef) {
107         return false;
108       }
109       if (status != other.status) {
110         return false;
111       }
112
113       return true;
114
115     } else {
116       return false;
117     }
118   }
119
120
121   /**
122   public boolean isShared() {
123     // static fields are always thread global
124     return true;
125   }
126   **/
127
128   public int getStatus() {
129     return status;
130   }
131   
132   void setStatus (int newStatus) {
133     checkIsModifiable();
134     
135     if (status != newStatus) {
136       status = newStatus;
137       attributes |= ATTR_STATUS_CHANGED;
138     }
139   }
140
141   
142   @Override
143   protected FieldInfo getDeclaredFieldInfo (String clsBase, String fname) {
144     ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsBase); // <2do> should use CL argument
145     FieldInfo fi = ci.getDeclaredStaticField(fname);
146     
147     if (fi == null) {
148       throw new JPFException("class " + ci.getName() +
149                                          " has no static field " + fname);
150     }
151     return fi;
152   }
153
154   @Override
155   public FieldInfo getFieldInfo (String fname) {
156     ClassInfo ci = getClassInfo();
157     return ci.getStaticField(fname);
158   }
159   
160   protected void checkFieldInfo (FieldInfo fi) {
161     if (getClassInfo() != fi.getClassInfo()) {
162       throw new JPFException("wrong static FieldInfo : " + fi.getName()
163           + " , no such field in class " + getClassInfo().getName());
164     }
165   }
166
167   @Override
168   public int getNumberOfFields () {
169     return getClassInfo().getNumberOfStaticFields();
170   }
171   
172   @Override
173   public FieldInfo getFieldInfo (int fieldIndex) {
174     return getClassInfo().getStaticField(fieldIndex);
175   }
176     
177   /**
178    * gc mark all objects stored in static reference fields
179    */
180   void markStaticRoot (Heap heap) {
181     ClassInfo ci = getClassInfo();
182     int n = ci.getNumberOfStaticFields();
183     
184     for (int i=0; i<n; i++) {
185       FieldInfo fi = ci.getStaticField(i);
186       if (fi.isReference()) {
187         int objref = fields.getIntValue(fi.getStorageOffset());
188         heap.markStaticRoot(objref);
189       }
190     }
191     
192     // don't forget the class object itself (which is not a field)
193     heap.markStaticRoot(classObjectRef);
194   }
195       
196   public int getClassObjectRef () {
197     return classObjectRef;
198   }
199   
200   public void setClassObjectRef(int r) {
201     checkIsModifiable();
202     
203     classObjectRef = r;
204     attributes |= ATTR_COR_CHANGED;
205   }
206
207   @Override
208   public String toString() {
209     return getClassInfo().getName(); // don't append objRef (useless and misleading for statics)
210   }
211
212   protected ElementInfo getReferencedElementInfo (FieldInfo fi){
213     assert fi.isReference();
214     Heap heap = VM.getVM().getHeap();
215     return heap.get(getIntField(fi));
216   }
217
218 }
219