1 19 20 package edu.umd.cs.findbugs.ba; 21 22 import java.util.Collection ; 23 import java.util.HashSet ; 24 25 import edu.umd.cs.findbugs.ba.vna.ValueNumber; 26 import edu.umd.cs.findbugs.ba.vna.ValueNumberAnalysis; 27 import edu.umd.cs.findbugs.ba.vna.ValueNumberFactory; 28 import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame; 29 30 38 public final class LockSet { 39 42 public static final int TOP = -1; 43 44 48 public static final int BOTTOM = -2; 49 50 private static final int INVALID = -1; 51 private static final int DEFAULT_CAPACITY = 8; 52 53 59 private int[] array; 60 61 64 private int defaultLockCount; 65 66 71 public LockSet() { 72 this.array = new int[DEFAULT_CAPACITY]; 73 this.defaultLockCount = TOP; 74 clear(); 75 } 76 77 83 public int getLockCount(int valueNumber) { 84 int index = findIndex(valueNumber); 85 if (index < 0) 86 return defaultLockCount; 87 else 88 return array[index + 1]; 89 } 90 91 public boolean isTop() { 92 return defaultLockCount == TOP; 93 } 94 100 public void setLockCount(int valueNumber, int lockCount) { 101 int index = findIndex(valueNumber); 102 if (index < 0) { 103 addEntry(index, valueNumber, lockCount); 104 } else { 105 array[index + 1] = lockCount; 106 } 107 } 108 109 114 public void setDefaultLockCount(int defaultLockCount) { 115 this.defaultLockCount = defaultLockCount; 116 } 117 118 121 public int getNumLockedObjects() { 122 int result = 0; 123 for (int i = 0; i < array.length; i += 2) { 124 if (array[i] == INVALID) 125 break; 126 if (array[i + 1] > 0) 127 ++result; 128 } 129 return result; 130 } 131 132 137 public void copyFrom(LockSet other) { 138 if (other.array.length != array.length) { 139 array = new int[other.array.length]; 140 } 141 System.arraycopy(other.array, 0, array, 0, array.length); 142 this.defaultLockCount = other.defaultLockCount; 143 } 144 145 148 public void clear() { 149 for (int i = 0; i < array.length; i += 2) { 150 array[i] = INVALID; 151 } 152 } 153 154 160 public void meetWith(LockSet other) { 161 for (int i = 0; i < array.length; i += 2) { 162 int valueNumber = array[i]; 163 if (valueNumber < 0) 164 break; 165 166 int mine = array[i + 1]; 167 int his = other.getLockCount(valueNumber); 168 array[i + 1] = mergeValues(mine, his); 169 } 170 171 for (int i = 0; i < other.array.length; i += 2) { 172 int valueNumber = other.array[i]; 173 if (valueNumber < 0) 174 break; 175 176 int mine = getLockCount(valueNumber); 177 int his = other.array[i + 1]; 178 setLockCount(valueNumber, mergeValues(mine, his)); 179 } 180 181 setDefaultLockCount(0); 182 } 183 184 189 public boolean sameAs(LockSet other) { 190 return this.identicalSubset(other) && other.identicalSubset(this); 191 } 192 193 199 public boolean containsReturnValue(ValueNumberFactory factory) { 200 for (int i = 0; i < array.length; i += 2) { 201 int valueNumber = array[i]; 202 if (valueNumber < 0) 203 break; 204 int lockCount = array[i + 1]; 205 if (lockCount > 0 && factory.forNumber(valueNumber).hasFlag(ValueNumber.RETURN_VALUE)) 206 return true; 207 } 208 return false; 209 } 210 211 219 public void intersectWith(LockSet other) { 220 for (int i = 0; i < array.length; i += 2) { 221 int valueNumber = array[i]; 222 if (valueNumber < 0) 223 break; 224 int myLockCount = array[i + 1]; 225 if (myLockCount <= 0) 226 continue; 227 int otherLockCount = other.getLockCount(valueNumber); 228 if (otherLockCount <= 0) { 229 230 array[i + 1] = 0; 231 } 232 } 233 } 234 235 242 public boolean isEmpty() { 243 for (int i = 0; i < array.length; i += 2) { 244 int valueNumber = array[i]; 245 if (valueNumber < 0) 246 return true; 247 int myLockCount = array[i + 1]; 248 if (myLockCount > 0) 249 return false; 250 } 251 return true; 252 } 253 254 private boolean identicalSubset(LockSet other) { 255 for (int i = 0; i < array.length; i += 2) { 256 int valueNumber = array[i]; 257 if (valueNumber < 0) 258 break; 259 int mine = array[i + 1]; 260 int his = other.getLockCount(valueNumber); 261 if (mine != his) 262 return false; 263 } 265 return true; 266 } 267 268 private static int mergeValues(int a, int b) { 269 if (a == TOP) 270 return b; 271 else if (b == TOP) 272 return a; 273 else if (a == BOTTOM || b == BOTTOM) 274 return BOTTOM; 275 else if (a == b) 276 return a; 277 else 278 return BOTTOM; 279 } 280 281 private int findIndex(int valueNumber) { 282 for (int i = 0; i < array.length; i += 2) { 283 int value = array[i]; 284 if (value < 0) 285 return -(i + 1); else if (value == valueNumber) 287 return i; } 289 return -(array.length + 1); } 291 292 private void addEntry(int index, int valueNumber, int lockCount) { 293 index = -(index + 1); 294 int origCapacity = array.length; 295 if (index == origCapacity) { 296 298 int[] data = new int[origCapacity * 2]; 300 301 System.arraycopy(array, 0, data, 0, origCapacity); 303 304 for (int i = index + 2; i < data.length; i += 2) { 308 data[i] = INVALID; 309 } 310 311 array = data; 313 } 314 315 array[index] = valueNumber; 316 array[index + 1] = lockCount; 317 } 318 319 @Override 320 public String toString() { 321 StringBuffer buf = new StringBuffer (); 322 buf.append('['); 323 boolean first = true; 324 if (defaultLockCount == 0) { 325 buf.append("default=0"); 326 first = false; 327 } 328 for (int i = 0; i < array.length; i += 2) { 329 int valueNumber = array[i]; 330 if (valueNumber < 0) 331 continue; 332 int lockCount = array[i + 1]; 333 if (lockCount == 0) 334 continue; 335 if (first) 336 first = false; 337 else 338 buf.append(','); 339 buf.append(valueNumber); 340 buf.append('='); 341 if (lockCount == TOP) 342 buf.append("TOP"); 343 else if (lockCount == BOTTOM) 344 buf.append("BOTTOM"); 345 else 346 buf.append(lockCount); 347 } 348 buf.append(']'); 349 return buf.toString(); 350 } 351 352 356 public Collection <ValueNumber> getLockedValueNumbers(ValueNumberFrame frame) { 357 if (frame == null) throw new IllegalArgumentException ("Null Frame"); 358 HashSet <ValueNumber> result = new HashSet <ValueNumber>(); 359 for(ValueNumber v : frame.allSlots()) 360 if (v != null && getLockCount(v.getNumber()) > 0) 361 result.add(v); 362 return result; 363 } 364 365 366 390 } 391 392 | Popular Tags |