1 package gov.nasa.jpf.jvm; 20 import java.util.List ; 21 import gov.nasa.jpf.util.Debug; 22 import java.util.BitSet ; 23 24 37 38 public class StatisticFieldLockInfo extends FieldLockInfo { 39 final static int CHECK_THRESHOLD = 5; 40 41 int[] lset; 42 int checkLevel; 43 44 static String printLocks (int[] lockSet) { 46 DynamicArea heap = DynamicArea.getHeap(); 47 48 if ((lockSet == null) || (lockSet.length == 0)) { 49 return "{}"; 50 } else { 51 StringBuffer sb = new StringBuffer (); 52 sb.append("{"); 53 for (int i=0; i<lockSet.length;) { 54 int ref = lockSet[i]; 55 if (ref != -1) { 56 ElementInfo ei = heap.get(ref); 57 if (ei != null) { 58 sb.append(ei); 59 } else { 60 sb.append("?@"); 61 sb.append(lockSet[i]); 62 } 63 } 64 i++; 65 if (i<lockSet.length) sb.append(','); 66 } 67 sb.append("}"); 68 return sb.toString(); 69 } 70 } 71 72 void lockAssumptionFailed (ElementInfo ei, FieldInfo fi, ThreadInfo ti) { 73 String src = ti.getMethod().getClassInfo().getSourceFileName(); 74 int line = ti.getLine(); 75 76 Debug.println(Debug.ERROR,"MESSAGE: unprotected field access of: " + 77 ei + "." + fi.getName() + " in thread:" 78 + " \"" + ti.getName() + "\" " + src+ ":" + line); 79 Debug.println(Debug.ERROR," sync-detection assumed to be protected by: " 80 + printLocks(lset)); 81 Debug.println(Debug.ERROR," found to be protected by: " 82 + printLocks(ti.getLockedObjectReferences())); 83 Debug.println(Debug.ERROR," >>> re-run without '-sync-detection' <<<"); 84 } 85 86 96 static ElementInfo strongProtectionCandidate (ElementInfo ei, FieldInfo fi, ThreadInfo ti) { 97 List currentLocks = ti.getLockedObjects(); 98 int n = currentLocks.size(); 99 100 if (fi.isStatic()) { ClassInfo ci = fi.getClassInfo(); 102 int cref = ci.getClassObjectRef(); 103 104 for (int i=0; i<n; i++) { 105 ElementInfo e = (ElementInfo)currentLocks.get(i); if (e.getIndex() == cref) { 107 Debug.print(Debug.MESSAGE, "sync-detection: "); 108 Debug.print(Debug.MESSAGE, ei); 109 Debug.print(Debug.MESSAGE, " assumed to be synced on class object: "); 110 Debug.println(Debug.MESSAGE, e); 111 return e; 112 } 113 } 114 115 } else { for (int i=0; i<n; i++) { 117 ElementInfo e = (ElementInfo)currentLocks.get(i); int eidx = e.getIndex(); 119 120 if (ei == e) { 122 Debug.print(Debug.MESSAGE, "sync-detection: "); 123 Debug.print(Debug.MESSAGE, ei); 124 Debug.println(Debug.MESSAGE, " assumed to be synced on itself"); 125 return e; 126 } 127 128 if (e.hasRefField(ei.getIndex())) { 130 Debug.print(Debug.MESSAGE, "sync-detection: "); 131 Debug.print(Debug.MESSAGE, ei); 132 Debug.print(Debug.MESSAGE, " assumed to be synced on object wrapper: "); 133 Debug.println(Debug.MESSAGE, e); 134 return e; 135 } 136 137 if (ei.hasRefField(eidx)) { 139 Debug.print(Debug.MESSAGE, "sync-detection: "); 140 Debug.print(Debug.MESSAGE, ei); 141 Debug.print(Debug.MESSAGE, " assumed to be synced on sibling: "); 142 Debug.println(Debug.MESSAGE, e); 143 return e; 144 } 145 } 146 } 147 148 return null; 149 } 150 151 public FieldLockInfo checkProtection (ElementInfo ei, FieldInfo fi, ThreadInfo ti) { 152 List currentLocks = ti.getLockedObjects(); 153 int n = currentLocks.size(); 154 155 checkLevel++; 156 if (checkLevel == 1) { if (n == 0) { 158 return empty; 160 } else { 161 ElementInfo lcei = strongProtectionCandidate(ei,fi,ti); 162 if (lcei != null) { 163 checkLevel = CHECK_THRESHOLD; 166 } 167 168 if (n == 1) { 169 return new StatisticFieldLockInfo1(ei, fi, ti, checkLevel); 171 } 172 173 lset = new int[n]; 174 for (int i=0; i<n; i++) { 175 ElementInfo lei = (ElementInfo) currentLocks.get(i); 176 lset[i] = lei.getIndex(); 177 } 178 } 179 180 } else { if (n == 0) { 182 lockAssumptionFailed(ei, fi, ti); 183 return empty; 184 } else { 185 int i, j; 186 BitSet active = new BitSet (lset.length); 187 188 for (i=0; i<n; i++) { 189 ElementInfo lei = (ElementInfo)currentLocks.get(i); 190 int leidx = lei.getIndex(); 191 192 for (j=0; j<lset.length; j++) { 196 if (lset[j] == leidx) { 197 active.set(j); 198 } 199 } 200 201 int nActive = active.size(); 202 if (nActive == 0) { 203 lockAssumptionFailed(ei, fi, ti); 204 return empty; 205 } else { 206 for (j=0; j<lset.length; j++) { 207 if (!active.get(j)) { 208 lset[j] = -1; 209 } 210 } 211 } 212 } 213 } 214 } 215 216 return this; 217 } 218 219 public boolean isProtected () { 220 return (checkLevel >= CHECK_THRESHOLD); 222 } 223 } 224 225 229 class StatisticFieldLockInfo1 extends FieldLockInfo { 230 int lock; 231 boolean active; 232 int checkLevel; 233 234 StatisticFieldLockInfo1 (ElementInfo ei, FieldInfo fi, ThreadInfo ti, int nChecks) { 235 List currentLocks = ti.getLockedObjects(); 236 237 lock = ((ElementInfo)currentLocks.get(0)).getIndex(); 238 active = true; 239 this.checkLevel = nChecks; 240 } 241 242 void lockAssumptionFailed (ElementInfo ei, FieldInfo fi, ThreadInfo ti) { 243 String src = ti.getMethod().getClassInfo().getSourceFileName(); 244 int line = ti.getLine(); 245 246 Debug.println(Debug.ERROR,"Warning: unprotected field access of: " + 247 ei + "." + fi.getName() + " in thread:" 248 + " \"" + ti.getName() + "\" " + src+ ":" + line); 249 Debug.println(Debug.ERROR," sync-detection assumed to be protected by: " 250 + DynamicArea.getHeap().get(lock)); 251 Debug.println(Debug.ERROR," found to be protected by: " 252 + StatisticFieldLockInfo.printLocks(ti.getLockedObjectReferences())); 253 Debug.println(Debug.ERROR," >>> re-run without '-sync-detection' <<<"); 254 } 255 256 public FieldLockInfo checkProtection (ElementInfo ei, FieldInfo fi, ThreadInfo ti) { 257 List currentLocks = ti.getLockedObjects(); 258 int n = currentLocks.size(); 259 260 checkLevel++; 261 active = false; 262 for (int i=0; i<n; i++) { 263 ElementInfo lei = (ElementInfo)currentLocks.get(i); 264 if (lei.getIndex() == lock) { 265 active = true; 266 break; 267 } 268 } 269 270 if (!active) { 271 if (checkLevel > StatisticFieldLockInfo.CHECK_THRESHOLD) { 272 lockAssumptionFailed(ei, fi, ti); 273 } 274 return empty; 275 } 276 277 return this; 278 } 279 280 public boolean isProtected () { 281 return (checkLevel >= StatisticFieldLockInfo.CHECK_THRESHOLD); 283 } 284 } 285 | Popular Tags |