1 11 package org.eclipse.jdt.internal.compiler.flow; 12 13 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; 14 15 26 public class NullInfoRegistry extends UnconditionalFlowInfo { 27 30 32 40 public NullInfoRegistry(UnconditionalFlowInfo upstream) { 41 this.maxFieldCount = upstream.maxFieldCount; 42 if ((upstream.tagBits & NULL_FLAG_MASK) != 0) { 43 long u1, u2, u3, u4, nu2, nu3, nu4; 44 this.nullBit2 = (u1 = upstream.nullBit1) 45 & (u2 = upstream.nullBit2) 46 & (nu3 = ~(u3 = upstream.nullBit3)) 47 & (nu4 = ~(u4 = upstream.nullBit4)); 48 this.nullBit3 = u1 & (nu2 = ~u2) & u3 & nu4; 49 this.nullBit4 = u1 & nu2 &nu3 & u4; 50 if ((this.nullBit2 | this.nullBit3 | this.nullBit4) != 0) { 51 this.tagBits |= NULL_FLAG_MASK; 52 } 53 if (upstream.extra != null) { 54 this.extra = new long[extraLength][]; 55 int length = upstream.extra[2].length; 56 for (int i = 2; i < extraLength; i++) { 57 this.extra[i] = new long[length]; 58 } 59 for (int i = 0; i < length; i++) { 60 this.extra[2 + 1][i] = (u1 = upstream.extra[1 + 1][i]) 61 & (u2 = upstream.extra[2 + 1][i]) 62 & (nu3 = ~(u3 = upstream.extra[3 + 1][i])) 63 & (nu4 = ~(u4 = upstream.extra[4 + 1][i])); 64 this.extra[3 + 1][i] = u1 & (nu2 = ~u2) & u3 & nu4; 65 this.extra[4 + 1][i] = u1 & nu2 &nu3 & u4; 66 if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { 67 this.tagBits |= NULL_FLAG_MASK; 68 } 69 } 70 } 71 } 72 } 73 74 80 public NullInfoRegistry add(NullInfoRegistry other) { 81 if ((other.tagBits & NULL_FLAG_MASK) == 0) { 82 return this; 83 } 84 this.tagBits |= NULL_FLAG_MASK; 85 this.nullBit1 |= other.nullBit1; 86 this.nullBit2 |= other.nullBit2; 87 this.nullBit3 |= other.nullBit3; 88 this.nullBit4 |= other.nullBit4; 89 if (other.extra != null) { 90 if (this.extra == null) { 91 this.extra = new long[extraLength][]; 92 for (int i = 2, length = other.extra[2].length; i < extraLength; i++) { 93 System.arraycopy(other.extra[i], 0, 94 (this.extra[i] = new long[length]), 0, length); 95 } 96 } else { 97 int length = this.extra[2].length, otherLength = other.extra[2].length; 98 if (otherLength > length) { 99 for (int i = 2; i < extraLength; i++) { 100 System.arraycopy(this.extra[i], 0, 101 (this.extra[i] = new long[otherLength]), 0, length); 102 System.arraycopy(other.extra[i], length, 103 this.extra[i], length, otherLength - length); 104 } 105 } else if (otherLength < length) { 106 length = otherLength; 107 } 108 for (int i = 2; i < extraLength; i++) { 109 for (int j = 0; j < length; j++) { 110 this.extra[i][j] |= other.extra[i][j]; 111 } 112 } 113 } 114 } 115 return this; 116 } 117 118 public void markAsComparedEqualToNonNull(LocalVariableBinding local) { 119 if (this != DEAD_END) { 121 this.tagBits |= NULL_FLAG_MASK; 122 int position; 123 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { this.nullBit1 |= (1L << position); 127 if (coverageTestFlag && coverageTestId == 290) { 128 this.nullBit1 = 0; 129 } 130 } 131 else { 132 int vectorIndex = (position / BitCacheSize) - 1; 134 if (this.extra == null) { 135 int length = vectorIndex + 1; 136 this.extra = new long[extraLength][]; 137 for (int j = 2; j < extraLength; j++) { 138 this.extra[j] = new long[length]; 139 } 140 } 141 else { 142 int oldLength; if (vectorIndex >= (oldLength = this.extra[2].length)) { 144 for (int j = 2; j < extraLength; j++) { 145 System.arraycopy(this.extra[j], 0, 146 (this.extra[j] = new long[vectorIndex + 1]), 0, 147 oldLength); 148 } 149 } 150 } 151 this.extra[2][vectorIndex] |= (1L << (position % BitCacheSize)); 152 if (coverageTestFlag && coverageTestId == 300) { 153 this.extra[5][vectorIndex] = ~0; 154 } 155 } 156 } 157 } 158 159 public void markAsDefinitelyNonNull(LocalVariableBinding local) { 160 if (this != DEAD_END) { 162 this.tagBits |= NULL_FLAG_MASK; 163 int position; 164 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { this.nullBit3 |= (1L << position); 168 if (coverageTestFlag && coverageTestId == 290) { 169 this.nullBit1 = 0; 170 } 171 } 172 else { 173 int vectorIndex = (position / BitCacheSize) - 1; 175 if (this.extra == null) { 176 int length = vectorIndex + 1; 177 this.extra = new long[extraLength][]; 178 for (int j = 2; j < extraLength; j++) { 179 this.extra[j] = new long[length]; 180 } 181 } 182 else { 183 int oldLength; if (vectorIndex >= (oldLength = this.extra[2].length)) { 185 for (int j = 2; j < extraLength; j++) { 186 System.arraycopy(this.extra[j], 0, 187 (this.extra[j] = new long[vectorIndex + 1]), 0, 188 oldLength); 189 } 190 } 191 } 192 this.extra[4][vectorIndex] |= (1L << (position % BitCacheSize)); 193 if (coverageTestFlag && coverageTestId == 300) { 194 this.extra[5][vectorIndex] = ~0; 195 } 196 } 197 } 198 } 199 public void markAsDefinitelyNull(LocalVariableBinding local) { 202 if (this != DEAD_END) { 204 this.tagBits |= NULL_FLAG_MASK; 205 int position; 206 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { this.nullBit2 |= (1L << position); 210 if (coverageTestFlag && coverageTestId == 290) { 211 this.nullBit1 = 0; 212 } 213 } 214 else { 215 int vectorIndex = (position / BitCacheSize) - 1; 217 if (this.extra == null) { 218 int length = vectorIndex + 1; 219 this.extra = new long[extraLength][]; 220 for (int j = 2; j < extraLength; j++) { 221 this.extra[j] = new long[length]; 222 } 223 } 224 else { 225 int oldLength; if (vectorIndex >= (oldLength = this.extra[2].length)) { 227 for (int j = 2; j < extraLength; j++) { 228 System.arraycopy(this.extra[j], 0, 229 (this.extra[j] = new long[vectorIndex + 1]), 0, 230 oldLength); 231 } 232 } 233 } 234 this.extra[3][vectorIndex] |= (1L << (position % BitCacheSize)); 235 if (coverageTestFlag && coverageTestId == 300) { 236 this.extra[5][vectorIndex] = ~0; 237 } 238 } 239 } 240 } 241 242 public void markAsDefinitelyUnknown(LocalVariableBinding local) { 243 if (this != DEAD_END) { 245 this.tagBits |= NULL_FLAG_MASK; 246 int position; 247 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { this.nullBit4 |= (1L << position); 251 if (coverageTestFlag && coverageTestId == 290) { 252 this.nullBit1 = 0; 253 } 254 } 255 else { 256 int vectorIndex = (position / BitCacheSize) - 1; 258 if (this.extra == null) { 259 int length = vectorIndex + 1; 260 this.extra = new long[extraLength][]; 261 for (int j = 2; j < extraLength; j++) { 262 this.extra[j] = new long[length]; 263 } 264 } 265 else { 266 int oldLength; if (vectorIndex >= (oldLength = this.extra[2].length)) { 268 for (int j = 2; j < extraLength; j++) { 269 System.arraycopy(this.extra[j], 0, 270 (this.extra[j] = new long[vectorIndex + 1]), 0, 271 oldLength); 272 } 273 } 274 } 275 this.extra[5][vectorIndex] |= (1L << (position % BitCacheSize)); 276 if (coverageTestFlag && coverageTestId == 300) { 277 this.extra[5][vectorIndex] = ~0; 278 } 279 } 280 } 281 } 282 283 293 public UnconditionalFlowInfo mitigateNullInfoOf(FlowInfo flowInfo) { 294 if ((this.tagBits & NULL_FLAG_MASK) == 0) { 295 return flowInfo.unconditionalInits(); 296 } 297 long m, m1, nm1, m2, nm2, m3, a2, a3, a4, s1, s2, ns2, s3, ns3, s4, ns4; 298 boolean newCopy = false; 299 UnconditionalFlowInfo source = flowInfo.unconditionalInits(); 300 m1 = (s1 = source.nullBit1) & (s3 = source.nullBit3) 302 & (s4 = source.nullBit4) 303 & ((a2 = this.nullBit2) | (a4 = this.nullBit4)); 305 m2 = s1 & (s2 = this.nullBit2) & (s3 ^ s4) 307 & ((a3 = this.nullBit3) | a4); 309 m3 = s1 & (s2 & (ns3 = ~s3) & (ns4 = ~s4) & (a3 | a4) 314 | (ns2 = ~s2) & s3 & ns4 & (a2 | a4) 315 | ns2 & ns3 & s4 & (a2 | a3)); 316 if ((m = (m1 | m2 | m3)) != 0) { 317 newCopy = true; 318 source = source.unconditionalCopy(); 319 source.nullBit1 &= ~m; 320 source.nullBit2 &= (nm1 = ~m1) & ((nm2 = ~m2) | a4); 321 source.nullBit3 &= (nm1 | a2) & nm2; 322 source.nullBit4 &= nm1 & nm2; 323 } 324 if (this.extra != null && source.extra != null) { 325 int length = this.extra[2].length, sourceLength = source.extra[0].length; 326 if (sourceLength < length) { 327 length = sourceLength; 328 } 329 for (int i = 0; i < length; i++) { 330 m1 = (s1 = source.extra[1 + 1][i]) & (s3 = source.extra[3 + 1][i]) 331 & (s4 = source.extra[4 + 1][i]) 332 & ((a2 = this.extra[2 + 1][i]) | (a4 = this.extra[4 + 1][i])); 333 m2 = s1 & (s2 = this.extra[2 + 1][i]) & (s3 ^ s4) 334 & ((a3 = this.extra[3 + 1][i]) | a4); 335 m3 = s1 & (s2 & (ns3 = ~s3) & (ns4 = ~s4) & (a3 | a4) 336 | (ns2 = ~s2) & s3 & ns4 & (a2 | a4) 337 | ns2 & ns3 & s4 & (a2 | a3)); 338 if ((m = (m1 | m2 | m3)) != 0) { 339 if (! newCopy) { 340 newCopy = true; 341 source = source.unconditionalCopy(); 342 } 343 source.extra[1 + 1][i] &= ~m; 344 source.extra[2 + 1][i] &= (nm1 = ~m1) & ((nm2 = ~m2) | a4); 345 source.extra[3 + 1][i] &= (nm1 | a2) & nm2; 346 source.extra[4 + 1][i] &= nm1 & nm2; 347 } 348 } 349 } 350 return source; 351 } 352 353 public String toString(){ 354 if (this.extra == null) { 355 return "NullInfoRegistry<" + this.nullBit1 + this.nullBit2 + this.nullBit3 + this.nullBit4 357 + ">"; } 359 else { 360 String nullS = "NullInfoRegistry<[" + this.nullBit1 + this.nullBit2 + this.nullBit3 + this.nullBit4; 362 int i, ceil; 363 for (i = 0, ceil = this.extra[0].length > 3 ? 364 3 : 365 this.extra[0].length; 366 i < ceil; i++) { 367 nullS += "," + this.extra[2][i] + this.extra[3][i] + this.extra[4][i] + this.extra[5][i]; 369 } 370 if (ceil < this.extra[0].length) { 371 nullS += ",..."; } 373 return nullS + "]>"; } 375 } 376 } 377 378 | Popular Tags |