00001 package ca.mcgill.sable.soot.jimple;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 import ca.mcgill.sable.util.*;
00079
00080 class ArrayPackedSet implements BoundedFlowSet
00081 {
00082 FlowUniverse map;
00083 int[] bits;
00084
00085 public ArrayPackedSet(FlowUniverse universe)
00086 {
00087
00088
00089
00090
00091 this(universe, new int[universe.getSize() / 32 + (((universe.getSize() % 32) != 0) ? 1 : 0)]);
00092 }
00093 ArrayPackedSet(FlowUniverse map, int[] bits)
00094 {
00095 this.map = map;
00096 this.bits = (int[]) bits.clone();
00097 }
00098 public void add(Object obj, FlowSet destFlow)
00099 {
00100 ArrayPackedSet dest = (ArrayPackedSet) destFlow;
00101
00102 if(this != dest)
00103 copy(dest);
00104
00105 int bitNum = map.getIndexOf(obj);
00106
00107 dest.bits[bitNum / 32] |= 1 << (bitNum % 32);
00108 }
00109 public void clear()
00110 {
00111 for(int i = 0; i < bits.length; i++)
00112 bits[i] = 0;
00113 }
00114 public Object clone()
00115 {
00116 return new ArrayPackedSet(map, bits);
00117 }
00118 public void complement(FlowSet destFlow)
00119 {
00120 ArrayPackedSet dest = (ArrayPackedSet) destFlow;
00121
00122 for(int i = 0; i < bits.length; i++)
00123 dest.bits[i] = ~(this.bits[i]);
00124
00125
00126 if(bits.length >= 1)
00127 {
00128 int lastValidBitCount = map.getSize() % 32;
00129
00130 if(lastValidBitCount != 0)
00131 dest.bits[bits.length - 1] &= ~(0xFFFFFFFF << lastValidBitCount);
00132 }
00133 }
00134 public boolean contains(Object obj)
00135 {
00136 int bitNum = map.getIndexOf(obj);
00137
00138 return (bits[bitNum / 32] & (1 << (bitNum % 32))) != 0;
00139 }
00140 public void copy(FlowSet destFlow)
00141 {
00142 ArrayPackedSet dest = (ArrayPackedSet) destFlow;
00143
00144 for(int i = 0; i < bits.length; i++)
00145 dest.bits[i] = this.bits[i];
00146 }
00147 public void difference(FlowSet otherFlow, FlowSet destFlow)
00148 {
00149 ArrayPackedSet other = (ArrayPackedSet) otherFlow;
00150 ArrayPackedSet dest = (ArrayPackedSet) destFlow;
00151
00152 if(!(other instanceof ArrayPackedSet) || bits.length != other.bits.length)
00153 throw new RuntimeException("Incompatible other set for union");
00154
00155 for(int i = 0; i < bits.length; i++)
00156 dest.bits[i] = this.bits[i] & ~other.bits[i];
00157 }
00158 public boolean equals(Object otherFlow)
00159 {
00160 ArrayPackedSet other = (ArrayPackedSet) otherFlow;
00161
00162 for(int i = 0; i < bits.length; i++)
00163 if(this.bits[i] != other.bits[i])
00164 return false;
00165
00166 return true;
00167 }
00168 public void intersection(FlowSet otherFlow, FlowSet destFlow)
00169 {
00170 ArrayPackedSet other = (ArrayPackedSet) otherFlow;
00171 ArrayPackedSet dest = (ArrayPackedSet) destFlow;
00172
00173 if(!(other instanceof ArrayPackedSet) || bits.length != other.bits.length)
00174 throw new RuntimeException("Incompatible other set for union");
00175
00176 for(int i = 0; i < bits.length; i++)
00177 dest.bits[i] = this.bits[i] & other.bits[i];
00178 }
00179 public boolean isEmpty()
00180 {
00181 for(int i = 0; i < bits.length; i++)
00182 if(bits[i] != 0)
00183 return false;
00184
00185 return true;
00186 }
00187 public void remove(Object obj, FlowSet destFlow)
00188 {
00189 ArrayPackedSet dest = (ArrayPackedSet) destFlow;
00190
00191 if(this != dest)
00192 copy(dest);
00193
00194 int bitNum = map.getIndexOf(obj);
00195
00196 dest.bits[bitNum / 32] &= ~(1 << (bitNum % 32));
00197 }
00198 public int size()
00199 {
00200 int count = 0;
00201
00202 for(int i = 0; i < bits.length; i++)
00203 {
00204 int word = bits[i];
00205
00206 for(int j = 0; j < 32; j++)
00207 if((word & (1 << j)) != 0)
00208 count++;
00209 }
00210
00211 return count;
00212 }
00213 public List toList()
00214 {
00215 List elements = new ArrayList();
00216
00217 for(int i = 0; i < bits.length; i++)
00218 {
00219 int word = bits[i];
00220 int offset = i * 32;
00221
00222 for(int j = 0; j < 32; j++)
00223 if((word & (1 << j)) != 0)
00224 elements.add(map.getObjectOf(offset + j));
00225 }
00226
00227 return elements;
00228 }
00229 public List toList(int low, int high)
00230 {
00231 List elements = new ArrayList();
00232
00233 int startWord = low / 32,
00234 startBit = low % 32;
00235
00236 int endWord = high / 32,
00237 endBit = high % 32;
00238
00239 if(low > high)
00240 return elements;
00241
00242
00243 {
00244 int word = bits[startWord];
00245
00246 int offset = startWord * 32;
00247 int lastBit = (startWord != endWord) ? 32 : (endBit + 1);
00248
00249 for(int j = startBit; j < lastBit; j++)
00250 {
00251 if((word & (1 << j)) != 0)
00252 elements.add(map.getObjectOf(offset + j));
00253 }
00254 }
00255
00256
00257 if(startWord != endWord && startWord + 1 != endWord)
00258 {
00259 for(int i = startWord + 1; i < endWord; i++)
00260 {
00261 int word = bits[i];
00262 int offset = i * 32;
00263
00264 for(int j = 0; j < 32; j++)
00265 {
00266 if((word & (1 << j)) != 0)
00267 elements.add(map.getObjectOf(offset + j));
00268 }
00269 }
00270 }
00271
00272
00273 if(startWord != endWord)
00274 {
00275 int word = bits[endWord];
00276 int offset = endWord * 32;
00277 int lastBit = endBit + 1;
00278
00279 for(int j = 0; j < lastBit; j++)
00280 {
00281 if((word & (1 << j)) != 0)
00282 elements.add(map.getObjectOf(offset + j));
00283 }
00284 }
00285
00286 return elements;
00287 }
00288 public String toString()
00289 {
00290 StringBuffer buffer = new StringBuffer("{");
00291 Iterator it = toList().iterator();
00292
00293
00294 if(it.hasNext())
00295 {
00296 buffer.append(it.next());
00297
00298 while(it.hasNext())
00299 {
00300 buffer.append(", " + it.next());
00301 }
00302 }
00303
00304 buffer.append("}");
00305
00306 return buffer.toString();
00307 }
00308 public void union(FlowSet otherFlow, FlowSet destFlow)
00309 {
00310 ArrayPackedSet other = (ArrayPackedSet) otherFlow;
00311 ArrayPackedSet dest = (ArrayPackedSet) destFlow;
00312
00313 if(!(other instanceof ArrayPackedSet) || bits.length != other.bits.length)
00314 throw new RuntimeException("Incompatible other set for union");
00315
00316 for(int i = 0; i < bits.length; i++)
00317 dest.bits[i] = this.bits[i] | other.bits[i];
00318 }
00319 }