00001 package gov.nasa.arc.ase.jpf.jvm;
00002
00003 import gov.nasa.arc.ase.util.HashData;
00004 import java.util.BitSet;
00005
00006
00007
00008
00009
00010 public abstract class Area implements Storable {
00011
00012
00013
00014 protected ElementInfo[] elements;
00015
00016
00017
00018
00019
00020 private int nElements;
00021
00022
00023
00024
00025 private int lastElement;
00026
00027
00028
00029
00030 public KernelState ks;
00031
00032
00033
00034
00035 public boolean isStatic;
00036
00037
00038
00039
00040 public BitSet hasChanged;
00041
00042
00043
00044
00045 public boolean anyChanged;
00046
00047
00048
00049
00050 public int[] data;
00051
00052
00053
00054
00055
00056
00057
00058
00059 private static final int delta = 2;
00060 protected Area(Area a) {
00061 int l = a.elements.length;
00062 elements = new ElementInfo[l];
00063 for(int i = 0; i < l; i++)
00064 if(a.elements[i] != null) {
00065 elements[i] = (ElementInfo)a.elements[i].clone();
00066 elements[i].area = this;
00067 elements[i].index = i;
00068 } else
00069 elements[i] = null;
00070
00071 nElements = a.nElements;
00072 lastElement = a.lastElement;
00073 ks = null;
00074 isStatic = a.isStatic;
00075 hasChanged = (BitSet)a.hasChanged.clone();
00076 anyChanged = a.anyChanged;
00077 l = a.data.length;
00078 data = new int[l];
00079 System.arraycopy(a.data, 0, data, 0, l);
00080 }
00081
00082
00083 public Area(KernelState ks, boolean s) {
00084 this.ks = ks;
00085 elements = new ElementInfo[0];
00086 nElements = 0;
00087 lastElement = -1;
00088 isStatic = s;
00089 hasChanged = new BitSet();
00090 anyChanged = false;
00091 data = new int[0];
00092 }
00093 protected void add(int index, ElementInfo e) {
00094 e.area = this;
00095 e.index = index;
00096
00097 if(index >= elements.length) {
00098 ElementInfo[] n = new ElementInfo[index+10];
00099 System.arraycopy(elements, 0, n, 0, elements.length);
00100 elements = n;
00101 }
00102
00103 if(index > lastElement) lastElement = index;
00104
00105 elements[index] = e;
00106 nElements++;
00107 hasChanged.set(index);
00108 anyChanged = true;
00109 ks.data = null;
00110 }
00111 public void backtrackTo(ArrayOffset storing, Object backtrack) {
00112 Object[] b = (Object[])backtrack;
00113
00114 int length = storing.get();
00115 int l = elements.length;
00116
00117 int s = length * delta;
00118
00119 if(data.length != s+1) data = new int[s+1];
00120
00121 if(s > 0)
00122 System.arraycopy(storing.data, storing.offset, data, 1, s);
00123
00124 anyChanged = false;
00125 hasChanged = new BitSet();
00126 data[0] = length;
00127
00128 lastElement = length-1;
00129
00130 if(length != l) {
00131 if(l > length) l = length;
00132
00133 ElementInfo[] n = new ElementInfo[length];
00134 System.arraycopy(elements, 0, n, 0, l);
00135
00136 elements = n;
00137 }
00138
00139 for(int i = 0; i < length; i++) {
00140 ElementInfo e = elements[i];
00141
00142 if(storing.peek() != 0) {
00143 if(e == null) {
00144 e = elements[i] = new ElementInfo();
00145 e.area = this;
00146 e.index = i;
00147 }
00148
00149 e.backtrackTo(storing, b[i]);
00150 } else {
00151 elements[i] = null;
00152
00153 storing.get();
00154 storing.get();
00155
00156
00157
00158 }
00159 }
00160 }
00161 public int count() {
00162 return nElements;
00163 }
00164 public ElementInfo get(int index) {
00165 return elements[index];
00166 }
00167 public Object getBacktrackData() {
00168 int length = elements.length;
00169 Object[] data = new Object[length];
00170
00171
00172
00173
00174
00175
00176
00177
00178 return data;
00179 }
00180 public int[] getStoringData() {
00181 if(!anyChanged) return data;
00182
00183 int length = lastElement+1;
00184 int size = length * delta;
00185 int s = data.length-1;
00186
00187 if(s != size) {
00188 if(s > size) s = size;
00189
00190 int[] n = new int[size+1];
00191 if(s > 0)
00192 System.arraycopy(data, 1, n, 1, s);
00193 data = n;
00194 }
00195 data[0] = length;
00196
00197 for(int i = 0, j = 1; i < length; i++, j += delta) {
00198 if(hasChanged.get(i)) {
00199 if(elements[i] != null) {
00200 int[] eData = elements[i].getStoringData();
00201 System.arraycopy(eData, 0, data, j, delta);
00202 } else {
00203 data[j] = 0;
00204 data[j+1] = 0;
00205
00206
00207
00208 }
00209 } else {
00210 if(elements[i] == null) {
00211 data[j] = 0;
00212 data[j+1] = 0;
00213
00214
00215
00216 }
00217 }
00218 }
00219
00220 anyChanged = false;
00221 hasChanged = new BitSet();
00222
00223 return data;
00224 }
00225 public void hash(HashData hd) {
00226 int length = elements.length;
00227
00228 for(int i = 0; i < length; i++)
00229 if(elements[i] != null)
00230 elements[i].hash(hd);
00231 }
00232 public int hashCode() {
00233 HashData hd = new HashData();
00234
00235 hash(hd);
00236
00237 return hd.getValue();
00238 }
00239 protected void remove(int index) {
00240 elements[index].area = null;
00241 elements[index].index = -1;
00242 elements[index] = null;
00243 nElements--;
00244
00245 hasChanged.set(index);
00246 anyChanged = true;
00247
00248 if(lastElement == index)
00249 while(lastElement >= 0 && elements[lastElement] == null)
00250 lastElement--;
00251 ks.data = null;
00252 }
00253 public void removeAll() {
00254 int l = elements.length;
00255
00256 for(int i = 0; i < l; i++)
00257 if(elements[i] != null)
00258 remove(i);
00259 }
00260 }