1 11 package org.eclipse.jdt.internal.compiler.flow; 12 13 import org.eclipse.jdt.internal.compiler.ast.ASTNode; 14 import org.eclipse.jdt.internal.compiler.impl.Constant; 15 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; 16 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; 17 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 18 import org.eclipse.jdt.internal.compiler.lookup.TagBits; 19 20 25 public class UnconditionalFlowInfo extends FlowInfo { 26 31 public static class AssertionFailedException extends RuntimeException { 32 private static final long serialVersionUID = 1827352841030089703L; 33 34 public AssertionFailedException(String message) { 35 super(message); 36 } 37 } 38 39 public final static boolean coverageTestFlag = false; 43 public static int coverageTestId; 45 46 public long definiteInits; 48 public long potentialInits; 49 50 public long 52 nullBit1, 53 nullBit2, 54 nullBit3, 55 nullBit4; 56 74 75 public static final int extraLength = 6; 77 public long extra[][]; 78 83 public int maxFieldCount; 85 public static final int BitCacheSize = 64; 88 public FlowInfo addInitializationsFrom(FlowInfo inits) { 89 if (this == DEAD_END) 90 return this; 91 if (inits == DEAD_END) 92 return this; 93 UnconditionalFlowInfo otherInits = inits.unconditionalInits(); 94 95 this.definiteInits |= otherInits.definiteInits; 97 this.potentialInits |= otherInits.potentialInits; 99 boolean thisHadNulls = (this.tagBits & NULL_FLAG_MASK) != 0, 101 otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0; 102 long 103 a1, a2, a3, a4, 104 na1, na2, na3, na4, 105 b1, b2, b3, b4, 106 nb1, nb2, nb3, nb4; 107 if (otherHasNulls) { 108 if (!thisHadNulls) { 109 this.nullBit1 = otherInits.nullBit1; 110 this.nullBit2 = otherInits.nullBit2; 111 this.nullBit3 = otherInits.nullBit3; 112 this.nullBit4 = otherInits.nullBit4; 113 if (coverageTestFlag && coverageTestId == 1) { 114 this.nullBit4 = ~0; 115 } 116 } 117 else { 118 this.nullBit1 = (b1 = otherInits.nullBit1) 119 | (a1 = this.nullBit1) & ((a3 = this.nullBit3) 120 & (a4 = this.nullBit4) & (nb2 = ~(b2 = otherInits.nullBit2)) 121 & (nb4 = ~(b4 = otherInits.nullBit4)) 122 | ((na4 = ~a4) | (na3 = ~a3)) 123 & ((na2 = ~(a2 = this.nullBit2)) & nb2 124 | a2 & (nb3 = ~(b3 = otherInits.nullBit3)) & nb4)); 125 this.nullBit2 = b2 & (nb4 | nb3) 126 | na3 & na4 & b2 127 | a2 & (nb3 & nb4 128 | (nb1 = ~b1) & (na3 | (na1 = ~a1)) 129 | a1 & b2); 130 this.nullBit3 = b3 & (nb1 & (b2 | a2 | na1) 131 | b1 & (b4 | nb2 | a1 & a3) 132 | na1 & na2 & na4) 133 | a3 & nb2 & nb4 134 | nb1 & ((na2 & a4 | na1) & a3 135 | a1 & na2 & na4 & b2); 136 this.nullBit4 = nb1 & (a4 & (na3 & nb3 | (a3 | na2) & nb2) 137 | a1 & (a3 & nb2 & b4 138 | a2 & b2 & (b4 | a3 & na4 & nb3))) 139 | b1 & (a3 & a4 & b4 140 | na2 & na4 & nb3 & b4 141 | a2 & ((b3 | a4) & b4 142 | na3 & a4 & b2 & b3) 143 | na1 & (b4 | (a4 | a2) & b2 & b3)) 144 | (na1 & (na3 & nb3 | na2 & nb2) 145 | a1 & (nb2 & nb3 | a2 & a3)) & b4; 146 if (coverageTestFlag && coverageTestId == 2) { 147 this.nullBit4 = ~0; 148 } 149 } 150 this.tagBits |= NULL_FLAG_MASK; } 152 if (this.extra != null || otherInits.extra != null) { 154 int mergeLimit = 0, copyLimit = 0; 155 if (this.extra != null) { 156 if (otherInits.extra != null) { 157 int length, otherLength; 159 if ((length = this.extra[0].length) < 160 (otherLength = otherInits.extra[0].length)) { 161 for (int j = 0; j < extraLength; j++) { 163 System.arraycopy(this.extra[j], 0, 164 (this.extra[j] = new long[otherLength]), 0, length); 165 } 166 mergeLimit = length; 167 copyLimit = otherLength; 168 if (coverageTestFlag && coverageTestId == 3) { 169 throw new AssertionFailedException("COVERAGE 3"); } 171 } else { 172 mergeLimit = otherLength; 174 if (coverageTestFlag && coverageTestId == 4) { 175 throw new AssertionFailedException("COVERAGE 4"); } 177 } 178 } 179 } else if (otherInits.extra != null) { 180 int otherLength; 183 this.extra = new long[extraLength][]; 184 System.arraycopy(otherInits.extra[0], 0, 185 (this.extra[0] = new long[otherLength = 186 otherInits.extra[0].length]), 0, otherLength); 187 System.arraycopy(otherInits.extra[1], 0, 188 (this.extra[1] = new long[otherLength]), 0, otherLength); 189 if (otherHasNulls) { 190 for (int j = 2; j < extraLength; j++) { 191 System.arraycopy(otherInits.extra[j], 0, 192 (this.extra[j] = new long[otherLength]), 0, otherLength); 193 } 194 if (coverageTestFlag && coverageTestId == 5) { 195 this.extra[5][otherLength - 1] = ~0; 196 } 197 } 198 else { 199 for (int j = 2; j < extraLength; j++) { 200 this.extra[j] = new long[otherLength]; 201 } 202 if (coverageTestFlag && coverageTestId == 6) { 203 throw new AssertionFailedException("COVERAGE 6"); } 205 } 206 } 207 int i; 208 for (i = 0; i < mergeLimit; i++) { 210 this.extra[0][i] |= otherInits.extra[0][i]; 211 this.extra[1][i] |= otherInits.extra[1][i]; 212 } 213 for (; i < copyLimit; i++) { 214 this.extra[0][i] = otherInits.extra[0][i]; 215 this.extra[1][i] = otherInits.extra[1][i]; 216 } 217 if (!thisHadNulls) { 219 if (copyLimit < mergeLimit) { 220 copyLimit = mergeLimit; 221 } 222 mergeLimit = 0; 223 } 224 if (!otherHasNulls) { 225 copyLimit = 0; 226 mergeLimit = 0; 227 } 228 for (i = 0; i < mergeLimit; i++) { 229 this.extra[1 + 1][i] = (b1 = otherInits.extra[1 + 1][i]) 230 | (a1 = this.extra[1 + 1][i]) & ((a3 = this.extra[3 + 1][i]) 231 & (a4 = this.extra[4 + 1][i]) & (nb2 = ~(b2 = otherInits.extra[2 + 1][i])) 232 & (nb4 = ~(b4 = otherInits.extra[4 + 1][i])) 233 | ((na4 = ~a4) | (na3 = ~a3)) 234 & ((na2 = ~(a2 = this.extra[2 + 1][i])) & nb2 235 | a2 & (nb3 = ~(b3 = otherInits.extra[3 + 1][i])) & nb4)); 236 this.extra[2 + 1][i] = b2 & (nb4 | nb3) 237 | na3 & na4 & b2 238 | a2 & (nb3 & nb4 239 | (nb1 = ~b1) & (na3 | (na1 = ~a1)) 240 | a1 & b2); 241 this.extra[3 + 1][i] = b3 & (nb1 & (b2 | a2 | na1) 242 | b1 & (b4 | nb2 | a1 & a3) 243 | na1 & na2 & na4) 244 | a3 & nb2 & nb4 245 | nb1 & ((na2 & a4 | na1) & a3 246 | a1 & na2 & na4 & b2); 247 this.extra[4 + 1][i] = nb1 & (a4 & (na3 & nb3 | (a3 | na2) & nb2) 248 | a1 & (a3 & nb2 & b4 249 | a2 & b2 & (b4 | a3 & na4 & nb3))) 250 | b1 & (a3 & a4 & b4 251 | na2 & na4 & nb3 & b4 252 | a2 & ((b3 | a4) & b4 253 | na3 & a4 & b2 & b3) 254 | na1 & (b4 | (a4 | a2) & b2 & b3)) 255 | (na1 & (na3 & nb3 | na2 & nb2) 256 | a1 & (nb2 & nb3 | a2 & a3)) & b4; 257 if (coverageTestFlag && coverageTestId == 7) { 258 this.extra[5][i] = ~0; 259 } 260 } 261 for (; i < copyLimit; i++) { 262 for (int j = 2; j < extraLength; j++) { 263 this.extra[j][i] = otherInits.extra[j][i]; 264 } 265 if (coverageTestFlag && coverageTestId == 8) { 266 this.extra[5][i] = ~0; 267 } 268 } 269 } 270 return this; 271 } 272 273 public FlowInfo addPotentialInitializationsFrom(FlowInfo inits) { 274 if (this == DEAD_END){ 275 return this; 276 } 277 if (inits == DEAD_END){ 278 return this; 279 } 280 UnconditionalFlowInfo otherInits = inits.unconditionalInits(); 281 this.potentialInits |= otherInits.potentialInits; 283 if (this.extra != null) { 285 if (otherInits.extra != null) { 286 int i = 0, length, otherLength; 288 if ((length = this.extra[0].length) < (otherLength = otherInits.extra[0].length)) { 289 for (int j = 0; j < extraLength; j++) { 291 System.arraycopy(this.extra[j], 0, 292 (this.extra[j] = new long[otherLength]), 0, length); 293 } 294 for (; i < length; i++) { 295 this.extra[1][i] |= otherInits.extra[1][i]; 296 } 297 for (; i < otherLength; i++) { 298 this.extra[1][i] = otherInits.extra[1][i]; 299 } 300 } 301 else { 302 for (; i < otherLength; i++) { 304 this.extra[1][i] |= otherInits.extra[1][i]; 305 } 306 } 307 } 308 } 309 else if (otherInits.extra != null) { 310 int otherLength = otherInits.extra[0].length; 312 this.extra = new long[extraLength][]; 313 for (int j = 0; j < extraLength; j++) { 314 this.extra[j] = new long[otherLength]; 315 } 316 System.arraycopy(otherInits.extra[1], 0, this.extra[1], 0, 317 otherLength); 318 } 319 this.addPotentialNullInfoFrom(otherInits); 320 return this; 321 } 322 323 334 public UnconditionalFlowInfo addPotentialNullInfoFrom( 335 UnconditionalFlowInfo otherInits) { 336 if ((this.tagBits & UNREACHABLE) != 0 || 337 (otherInits.tagBits & UNREACHABLE) != 0 || 338 (otherInits.tagBits & NULL_FLAG_MASK) == 0) { 339 return this; 340 } 341 boolean thisHadNulls = (this.tagBits & NULL_FLAG_MASK) != 0, 343 thisHasNulls = false; 344 long a1, a2, a3, a4, 345 na1, na2, na3, na4, 346 b1, b2, b3, b4, 347 nb1, nb2, nb3, nb4; 348 if (thisHadNulls) { 349 this.nullBit1 = (a1 = this.nullBit1) 350 & ((a3 = this.nullBit3) & (a4 = this.nullBit4) 351 & ((nb2 = ~(b2 = otherInits.nullBit2)) 352 & (nb4 = ~(b4 = otherInits.nullBit4)) 353 | (b1 = otherInits.nullBit1) & (b3 = otherInits.nullBit3)) 354 | (na2 = ~(a2 = this.nullBit2)) 355 & (b1 & b3 | ((na4 = ~a4) | (na3 = ~a3)) & nb2) 356 | a2 & ((na4 | na3) & ((nb3 = ~b3) & nb4 | b1 & b2))); 357 this.nullBit2 = b2 & (nb3 | (nb1 = ~b1)) 358 | a2 & (nb3 & nb4 | b2 | na3 | (na1 = ~a1)); 359 this.nullBit3 = b3 & (nb1 & b2 360 | a2 & (nb2 | a3) 361 | na1 & nb2 362 | a1 & na2 & na4 & b1) 363 | a3 & (nb2 & nb4 | na2 & a4 | na1) 364 | a1 & na2 & na4 & b2; 365 this.nullBit4 = na3 & (nb1 & nb3 & b4 366 | a4 & (nb3 | b1 & b2)) 367 | nb2 & (na3 & b1 & nb3 | na2 & (nb1 & b4 | b1 & nb3 | a4)) 368 | a3 & (a4 & (nb2 | b1 & b3) 369 | a1 & a2 & (nb1 & b4 | na4 & (b2 | b1) & nb3)); 370 if (coverageTestFlag && coverageTestId == 9) { 371 this.nullBit4 = ~0; 372 } 373 if ((this.nullBit2 | this.nullBit3 | this.nullBit4) != 0) { thisHasNulls = true; 375 } 376 } else { 377 this.nullBit1 = 0; 378 this.nullBit2 = (b2 = otherInits.nullBit2) 379 & ((nb3 = ~(b3 = otherInits.nullBit3)) | 380 (nb1 = ~(b1 = otherInits.nullBit1))); 381 this.nullBit3 = b3 & (nb1 | (nb2 = ~b2)); 382 this.nullBit4 = ~b1 & ~b3 & (b4 = otherInits.nullBit4) | ~b2 & (b1 & ~b3 | ~b1 & b4); 383 if (coverageTestFlag && coverageTestId == 10) { 384 this.nullBit4 = ~0; 385 } 386 if ((this.nullBit2 | this.nullBit3 | this.nullBit4) != 0) { thisHasNulls = true; 388 } 389 } 390 if (otherInits.extra != null) { 392 int mergeLimit = 0, copyLimit = otherInits.extra[0].length; 393 if (this.extra == null) { 394 this.extra = new long[extraLength][]; 395 for (int j = 0; j < extraLength; j++) { 396 this.extra[j] = new long[copyLimit]; 397 } 398 if (coverageTestFlag && coverageTestId == 11) { 399 throw new AssertionFailedException("COVERAGE 11"); } 401 } else { 402 mergeLimit = copyLimit; 403 if (mergeLimit > this.extra[0].length) { 404 mergeLimit = this.extra[0].length; 405 for (int j = 0; j < extraLength; j++) { 406 System.arraycopy(this.extra[j], 0, 407 this.extra[j] = new long[copyLimit], 0, 408 mergeLimit); 409 } 410 if (! thisHadNulls) { 411 mergeLimit = 0; 412 if (coverageTestFlag && coverageTestId == 12) { 414 throw new AssertionFailedException("COVERAGE 12"); } 416 } 417 } 418 } 419 int i; 421 for (i = 0 ; i < mergeLimit ; i++) { 422 this.extra[1 + 1][i] = (a1 = this.extra[1 + 1][i]) 423 & ((a3 = this.extra[3 + 1][i]) & (a4 = this.extra[4 + 1][i]) 424 & ((nb2 = ~(b2 = otherInits.extra[2 + 1][i])) 425 & (nb4 = ~(b4 = otherInits.extra[4 + 1][i])) 426 | (b1 = otherInits.extra[1 + 1][i]) & (b3 = otherInits.extra[3 + 1][i])) 427 | (na2 = ~(a2 = this.extra[2 + 1][i])) 428 & (b1 & b3 | ((na4 = ~a4) | (na3 = ~a3)) & nb2) 429 | a2 & ((na4 | na3) & ((nb3 = ~b3) & nb4 | b1 & b2))); 430 this.extra[2 + 1][i] = b2 & (nb3 | (nb1 = ~b1)) 431 | a2 & (nb3 & nb4 | b2 | na3 | (na1 = ~a1)); 432 this.extra[3 + 1][i] = b3 & (nb1 & b2 433 | a2 & (nb2 | a3) 434 | na1 & nb2 435 | a1 & na2 & na4 & b1) 436 | a3 & (nb2 & nb4 | na2 & a4 | na1) 437 | a1 & na2 & na4 & b2; 438 this.extra[4 + 1][i] = na3 & (nb1 & nb3 & b4 439 | a4 & (nb3 | b1 & b2)) 440 | nb2 & (na3 & b1 & nb3 | na2 & (nb1 & b4 | b1 & nb3 | a4)) 441 | a3 & (a4 & (nb2 | b1 & b3) 442 | a1 & a2 & (nb1 & b4 | na4 & (b2 | b1) & nb3)); 443 if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { thisHasNulls = true; 445 } 446 if (coverageTestFlag && coverageTestId == 13) { 447 this.nullBit4 = ~0; 448 } 449 } 450 for (; i < copyLimit; i++) { 451 this.extra[1 + 1][i] = 0; 452 this.extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i]) 453 & ((nb3 = ~(b3 = otherInits.extra[3 + 1][i])) | 454 (nb1 = ~(b1 = otherInits.extra[1 + 1][i]))); 455 this.extra[3 + 1][i] = b3 & (nb1 | (nb2 = ~b2)); 456 this.extra[4 + 1][i] = ~b1 & ~b3 & (b4 = otherInits.extra[4 + 1][i]) | ~b2 & (b1 & ~b3 | ~b1 & b4); 457 if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { thisHasNulls = true; 459 } 460 if (coverageTestFlag && coverageTestId == 14) { 461 this.extra[5][i] = ~0; 462 } 463 } 464 } 465 if (thisHasNulls) { 466 this.tagBits |= NULL_FLAG_MASK; 467 } 468 else { 469 this.tagBits &= NULL_FLAG_MASK; 470 } 471 return this; 472 } 473 474 final public boolean cannotBeDefinitelyNullOrNonNull(LocalVariableBinding local) { 475 if ((this.tagBits & NULL_FLAG_MASK) == 0 || 476 (local.type.tagBits & TagBits.IsBaseType) != 0) { 477 return false; 478 } 479 int position; 480 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { 481 return ( 483 (~this.nullBit1 484 & (this.nullBit2 & this.nullBit3 | this.nullBit4) 485 | ~this.nullBit2 & ~this.nullBit3 & this.nullBit4) 486 & (1L << position)) != 0; 487 } 488 if (this.extra == null) { 490 return false; } 492 int vectorIndex; 493 if ((vectorIndex = (position / BitCacheSize) - 1) >= 494 this.extra[0].length) { 495 return false; } 497 long a2, a3, a4; 498 return ( 499 (~this.extra[2][vectorIndex] 500 & ((a2 = this.extra[3][vectorIndex]) & (a3 = this.extra[4][vectorIndex]) | (a4 = this.extra[5][vectorIndex])) 501 | ~a2 & ~a3 & a4) 502 & (1L << (position % BitCacheSize))) != 0; 503 } 504 505 final public boolean cannotBeNull(LocalVariableBinding local) { 506 if ((this.tagBits & NULL_FLAG_MASK) == 0 || 507 (local.type.tagBits & TagBits.IsBaseType) != 0) { 508 return false; 509 } 510 int position; 511 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { 512 return (this.nullBit1 & this.nullBit3 514 & ((this.nullBit2 & this.nullBit4) | ~this.nullBit2) 515 & (1L << position)) != 0; 516 } 517 if (this.extra == null) { 519 return false; } 521 int vectorIndex; 522 if ((vectorIndex = (position / BitCacheSize) - 1) >= 523 this.extra[0].length) { 524 return false; } 526 return (this.extra[2][vectorIndex] & this.extra[4][vectorIndex] 527 & ((this.extra[3][vectorIndex] & this.extra[5][vectorIndex]) | 528 ~this.extra[3][vectorIndex]) 529 & (1L << (position % BitCacheSize))) != 0; 530 } 531 532 final public boolean canOnlyBeNull(LocalVariableBinding local) { 533 if ((this.tagBits & NULL_FLAG_MASK) == 0 || 534 (local.type.tagBits & TagBits.IsBaseType) != 0) { 535 return false; 536 } 537 int position; 538 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { 539 return (this.nullBit1 & this.nullBit2 541 & (~this.nullBit3 | ~this.nullBit4) 542 & (1L << position)) != 0; 543 } 544 if (this.extra == null) { 546 return false; } 548 int vectorIndex; 549 if ((vectorIndex = (position / BitCacheSize) - 1) >= 550 this.extra[0].length) { 551 return false; } 553 return (this.extra[2][vectorIndex] & this.extra[3][vectorIndex] 554 & (~this.extra[4][vectorIndex] | ~this.extra[5][vectorIndex]) 555 & (1L << (position % BitCacheSize))) != 0; 556 } 557 558 public FlowInfo copy() { 559 if (this == DEAD_END) { 561 return this; 562 } 563 UnconditionalFlowInfo copy = new UnconditionalFlowInfo(); 564 copy.definiteInits = this.definiteInits; 566 copy.potentialInits = this.potentialInits; 567 boolean hasNullInfo = (this.tagBits & NULL_FLAG_MASK) != 0; 568 if (hasNullInfo) { 569 copy.nullBit1 = this.nullBit1; 570 copy.nullBit2 = this.nullBit2; 571 copy.nullBit3 = this.nullBit3; 572 copy.nullBit4 = this.nullBit4; 573 } 574 copy.tagBits = this.tagBits; 575 copy.maxFieldCount = this.maxFieldCount; 576 if (this.extra != null) { 577 int length; 578 copy.extra = new long[extraLength][]; 579 System.arraycopy(this.extra[0], 0, 580 (copy.extra[0] = new long[length = this.extra[0].length]), 0, 581 length); 582 System.arraycopy(this.extra[1], 0, 583 (copy.extra[1] = new long[length]), 0, length); 584 if (hasNullInfo) { 585 for (int j = 2; j < extraLength; j++) { 586 System.arraycopy(this.extra[j], 0, 587 (copy.extra[j] = new long[length]), 0, length); 588 } 589 } 590 else { 591 for (int j = 2; j < extraLength; j++) { 592 copy.extra[j] = new long[length]; 593 } 594 } 595 } 596 return copy; 597 } 598 599 604 public UnconditionalFlowInfo discardInitializationInfo() { 605 if (this == DEAD_END) { 606 return this; 607 } 608 this.definiteInits = 609 this.potentialInits = 0; 610 if (this.extra != null) { 611 for (int i = 0, length = this.extra[0].length; i < length; i++) { 612 this.extra[0][i] = this.extra[1][i] = 0; 613 } 614 } 615 return this; 616 } 617 618 622 public UnconditionalFlowInfo discardNonFieldInitializations() { 623 int limit = this.maxFieldCount; 624 if (limit < BitCacheSize) { 625 long mask = (1L << limit)-1; 626 this.definiteInits &= mask; 627 this.potentialInits &= mask; 628 this.nullBit1 &= mask; 629 this.nullBit2 &= mask; 630 this.nullBit3 &= mask; 631 this.nullBit4 &= mask; 632 } 633 if (this.extra == null) { 635 return this; } 637 int vectorIndex, length = this.extra[0].length; 638 if ((vectorIndex = (limit / BitCacheSize) - 1) >= length) { 639 return this; } 641 if (vectorIndex >= 0) { 642 long mask = (1L << (limit % BitCacheSize))-1; 644 for (int j = 0; j < extraLength; j++) { 645 this.extra[j][vectorIndex] &= mask; 646 } 647 } 648 for (int i = vectorIndex + 1; i < length; i++) { 649 for (int j = 0; j < extraLength; j++) { 650 this.extra[j][i] = 0; 651 } 652 } 653 return this; 654 } 655 656 public FlowInfo initsWhenFalse() { 657 return this; 658 } 659 660 public FlowInfo initsWhenTrue() { 661 return this; 662 } 663 664 669 final private boolean isDefinitelyAssigned(int position) { 670 if (position < BitCacheSize) { 671 return (this.definiteInits & (1L << position)) != 0; 673 } 674 if (this.extra == null) 676 return false; int vectorIndex; 678 if ((vectorIndex = (position / BitCacheSize) - 1) 679 >= this.extra[0].length) { 680 return false; } 682 return ((this.extra[0][vectorIndex]) & 683 (1L << (position % BitCacheSize))) != 0; 684 } 685 686 final public boolean isDefinitelyAssigned(FieldBinding field) { 687 if ((this.tagBits & UNREACHABLE) != 0) { 690 return true; 691 } 692 return isDefinitelyAssigned(field.id); 693 } 694 695 final public boolean isDefinitelyAssigned(LocalVariableBinding local) { 696 if ((this.tagBits & UNREACHABLE) != 0 && (local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0) { 698 return true; 699 } 700 return isDefinitelyAssigned(local.id + this.maxFieldCount); 701 } 702 703 final public boolean isDefinitelyNonNull(LocalVariableBinding local) { 704 if ((this.tagBits & UNREACHABLE) != 0 || 706 (this.tagBits & NULL_FLAG_MASK) == 0) { 707 return false; 708 } 709 if ((local.type.tagBits & TagBits.IsBaseType) != 0 || 710 local.constant() != Constant.NotAConstant) { return true; 712 } 713 int position = local.id + this.maxFieldCount; 714 if (position < BitCacheSize) { return ((this.nullBit1 & this.nullBit3 & (~this.nullBit2 | this.nullBit4)) 716 & (1L << position)) != 0; 717 } 718 if (this.extra == null) { 720 return false; } 722 int vectorIndex; 723 if ((vectorIndex = (position / BitCacheSize) - 1) 724 >= this.extra[0].length) { 725 return false; } 727 return ((this.extra[2][vectorIndex] & this.extra[4][vectorIndex] 728 & (~this.extra[3][vectorIndex] | this.extra[5][vectorIndex])) 729 & (1L << (position % BitCacheSize))) != 0; 730 } 731 732 final public boolean isDefinitelyNull(LocalVariableBinding local) { 733 if ((this.tagBits & UNREACHABLE) != 0 || 735 (this.tagBits & NULL_FLAG_MASK) == 0 || 736 (local.type.tagBits & TagBits.IsBaseType) != 0) { 737 return false; 738 } 739 int position = local.id + this.maxFieldCount; 740 if (position < BitCacheSize) { return ((this.nullBit1 & this.nullBit2 742 & (~this.nullBit3 | ~this.nullBit4)) 743 & (1L << position)) != 0; 744 } 745 if (this.extra == null) { 747 return false; } 749 int vectorIndex; 750 if ((vectorIndex = (position / BitCacheSize) - 1) >= 751 this.extra[0].length) { 752 return false; } 754 return ((this.extra[2][vectorIndex] & this.extra[3][vectorIndex] 755 & (~this.extra[4][vectorIndex] | ~this.extra[5][vectorIndex])) 756 & (1L << (position % BitCacheSize))) != 0; 757 } 758 759 final public boolean isDefinitelyUnknown(LocalVariableBinding local) { 760 if ((this.tagBits & UNREACHABLE) != 0 || 762 (this.tagBits & NULL_FLAG_MASK) == 0) { 763 return false; 764 } 765 int position = local.id + this.maxFieldCount; 766 if (position < BitCacheSize) { return ((this.nullBit1 & this.nullBit4 768 & ~this.nullBit2 & ~this.nullBit3) & (1L << position)) != 0; 769 } 770 if (this.extra == null) { 772 return false; } 774 int vectorIndex; 775 if ((vectorIndex = (position / BitCacheSize) - 1) >= 776 this.extra[0].length) { 777 return false; } 779 return ((this.extra[2][vectorIndex] & this.extra[5][vectorIndex] 780 & ~this.extra[3][vectorIndex] & ~this.extra[4][vectorIndex]) 781 & (1L << (position % BitCacheSize))) != 0; 782 } 783 784 787 final private boolean isPotentiallyAssigned(int position) { 788 if (position < BitCacheSize) { 790 return (this.potentialInits & (1L << position)) != 0; 792 } 793 if (this.extra == null) { 795 return false; } 797 int vectorIndex; 798 if ((vectorIndex = (position / BitCacheSize) - 1) 799 >= this.extra[0].length) { 800 return false; } 802 return ((this.extra[1][vectorIndex]) & 803 (1L << (position % BitCacheSize))) != 0; 804 } 805 806 final public boolean isPotentiallyAssigned(FieldBinding field) { 807 return isPotentiallyAssigned(field.id); 808 } 809 810 final public boolean isPotentiallyAssigned(LocalVariableBinding local) { 811 if (local.constant() != Constant.NotAConstant) { 813 return true; 814 } 815 return isPotentiallyAssigned(local.id + this.maxFieldCount); 816 } 817 818 final public boolean isPotentiallyNonNull(LocalVariableBinding local) { 819 if ((this.tagBits & NULL_FLAG_MASK) == 0 || 820 (local.type.tagBits & TagBits.IsBaseType) != 0) { 821 return false; 822 } 823 int position; 824 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { 825 return ((this.nullBit3 & (~this.nullBit1 | ~this.nullBit2)) 827 & (1L << position)) != 0; 828 } 829 if (this.extra == null) { 831 return false; } 833 int vectorIndex; 834 if ((vectorIndex = (position / BitCacheSize) - 1) >= 835 this.extra[0].length) { 836 return false; } 838 return ((this.extra[4][vectorIndex] 839 & (~this.extra[2][vectorIndex] | ~this.extra[3][vectorIndex])) 840 & (1L << (position % BitCacheSize))) != 0; 841 } 842 843 final public boolean isPotentiallyNull(LocalVariableBinding local) { 844 if ((this.tagBits & NULL_FLAG_MASK) == 0 || 845 (local.type.tagBits & TagBits.IsBaseType) != 0) { 846 return false; 847 } 848 int position; 849 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { 850 return ((this.nullBit2 & (~this.nullBit1 | ~this.nullBit3)) 852 & (1L << position)) != 0; 853 } 854 if (this.extra == null) { 856 return false; } 858 int vectorIndex; 859 if ((vectorIndex = (position / BitCacheSize) - 1) >= 860 this.extra[0].length) { 861 return false; } 863 return ((this.extra[3][vectorIndex] 864 & (~this.extra[2][vectorIndex] | ~this.extra[4][vectorIndex])) 865 & (1L << (position % BitCacheSize))) != 0; 866 } 867 868 final public boolean isPotentiallyUnknown(LocalVariableBinding local) { 869 if ((this.tagBits & UNREACHABLE) != 0 || 871 (this.tagBits & NULL_FLAG_MASK) == 0) { 872 return false; 873 } 874 int position = local.id + this.maxFieldCount; 875 if (position < BitCacheSize) { return (this.nullBit4 877 & (~this.nullBit1 | ~this.nullBit2 & ~this.nullBit3) 878 & (1L << position)) != 0; 879 } 880 if (this.extra == null) { 882 return false; } 884 int vectorIndex; 885 if ((vectorIndex = (position / BitCacheSize) - 1) >= 886 this.extra[0].length) { 887 return false; } 889 return (this.extra[5][vectorIndex] 890 & (~this.extra[2][vectorIndex] 891 | ~this.extra[3][vectorIndex] & ~this.extra[4][vectorIndex]) 892 & (1L << (position % BitCacheSize))) != 0; 893 } 894 895 final public boolean isProtectedNonNull(LocalVariableBinding local) { 896 if ((this.tagBits & NULL_FLAG_MASK) == 0 || 897 (local.type.tagBits & TagBits.IsBaseType) != 0) { 898 return false; 899 } 900 int position; 901 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { 902 return (this.nullBit1 & this.nullBit3 & this.nullBit4 & (1L << position)) != 0; 904 } 905 if (this.extra == null) { 907 return false; } 909 int vectorIndex; 910 if ((vectorIndex = (position / BitCacheSize) - 1) >= 911 this.extra[0].length) { 912 return false; } 914 return (this.extra[2][vectorIndex] 915 & this.extra[4][vectorIndex] 916 & this.extra[5][vectorIndex] 917 & (1L << (position % BitCacheSize))) != 0; 918 } 919 920 final public boolean isProtectedNull(LocalVariableBinding local) { 921 if ((this.tagBits & NULL_FLAG_MASK) == 0 || 922 (local.type.tagBits & TagBits.IsBaseType) != 0) { 923 return false; 924 } 925 int position; 926 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { 927 return (this.nullBit1 & this.nullBit2 929 & (this.nullBit3 ^ this.nullBit4) 930 & (1L << position)) != 0; 931 } 932 if (this.extra == null) { 934 return false; } 936 int vectorIndex; 937 if ((vectorIndex = (position / BitCacheSize) - 1) >= 938 this.extra[0].length) { 939 return false; } 941 return (this.extra[2][vectorIndex] & this.extra[3][vectorIndex] 942 & (this.extra[4][vectorIndex] ^ this.extra[5][vectorIndex]) 943 & (1L << (position % BitCacheSize))) != 0; 944 } 945 946 public void markAsComparedEqualToNonNull(LocalVariableBinding local) { 947 if (this != DEAD_END) { 949 this.tagBits |= NULL_FLAG_MASK; 950 int position; 951 long mask; 952 long a1, a2, a3, a4, na2; 953 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { 955 if (((mask = 1L << position) 957 & (a1 = this.nullBit1) 958 & (na2 = ~(a2 = this.nullBit2)) 959 & ~(a3 = this.nullBit3) 960 & (a4 = this.nullBit4)) 961 != 0) { 962 this.nullBit4 &= ~mask; 963 } else if ((mask & a1 & na2 & a3) == 0) { 964 this.nullBit4 |= mask; 965 if ((mask & a1) == 0) { 966 if ((mask & a2 & (a3 ^ a4)) != 0) { 967 this.nullBit2 &= ~mask; 968 } 969 else if ((mask & (a2 | a3 | a4)) == 0) { 970 this.nullBit2 |= mask; 971 } 972 } 973 } 974 this.nullBit1 |= mask; 975 this.nullBit3 |= mask; 976 if (coverageTestFlag && coverageTestId == 15) { 977 this.nullBit4 = ~0; 978 } 979 } 980 else { 981 int vectorIndex = (position / BitCacheSize) - 1; 983 if (this.extra == null) { 984 int length = vectorIndex + 1; 985 this.extra = new long[extraLength][]; 986 for (int j = 0; j < extraLength; j++) { 987 this.extra[j] = new long[length]; 988 } 989 if (coverageTestFlag && coverageTestId == 16) { 990 throw new AssertionFailedException("COVERAGE 16"); } 992 } 993 else { 994 int oldLength; 995 if (vectorIndex >= (oldLength = this.extra[0].length)) { 996 int newLength = vectorIndex + 1; 997 for (int j = 0; j < extraLength; j++) { 998 System.arraycopy(this.extra[j], 0, 999 (this.extra[j] = new long[newLength]), 0, 1000 oldLength); 1001 } 1002 if (coverageTestFlag && coverageTestId == 17) { 1003 throw new AssertionFailedException("COVERAGE 17"); } 1005 } 1006 } 1007 if (((mask = 1L << (position % BitCacheSize)) 1009 & (a1 = this.extra[1 + 1][vectorIndex]) 1010 & (na2 = ~(a2 = this.extra[2 + 1][vectorIndex])) 1011 & ~(a3 = this.extra[3 + 1][vectorIndex]) 1012 & (a4 = this.extra[4 + 1][vectorIndex])) 1013 != 0) { 1014 this.extra[4 + 1][vectorIndex] &= ~mask; 1015 } else if ((mask & a1 & na2 & a3) == 0) { 1016 this.extra[4 + 1][vectorIndex] |= mask; 1017 if ((mask & a1) == 0) { 1018 if ((mask & a2 & (a3 ^ a4)) != 0) { 1019 this.extra[2 + 1][vectorIndex] &= ~mask; 1020 } 1021 else if ((mask & (a2 | a3 | a4)) == 0) { 1022 this.extra[2 + 1][vectorIndex] |= mask; 1023 } 1024 } 1025 } 1026 this.extra[1 + 1][vectorIndex] |= mask; 1027 this.extra[3 + 1][vectorIndex] |= mask; 1028 if (coverageTestFlag && coverageTestId == 18) { 1029 this.extra[5][vectorIndex] = ~0; 1030 } 1031 } 1032 } 1033} 1034 1035public void markAsComparedEqualToNull(LocalVariableBinding local) { 1036 if (this != DEAD_END) { 1038 this.tagBits |= NULL_FLAG_MASK; 1039 int position; 1040 long mask; 1041 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { 1043 if (((mask = 1L << position) & this.nullBit1) != 0) { 1045 if ((mask 1046 & (~this.nullBit2 | this.nullBit3 1047 | ~this.nullBit4)) != 0) { 1048 this.nullBit4 &= ~mask; 1049 } 1050 } else if ((mask & this.nullBit4) != 0) { 1051 this.nullBit3 &= ~mask; 1052 } else { 1053 if ((mask & this.nullBit2) != 0) { 1054 this.nullBit3 &= ~mask; 1055 this.nullBit4 |= mask; 1056 } else { 1057 this.nullBit3 |= mask; 1058 } 1059 } 1060 this.nullBit1 |= mask; 1061 this.nullBit2 |= mask; 1062 if (coverageTestFlag && coverageTestId == 19) { 1063 this.nullBit4 = ~0; 1064 } 1065 } 1066 else { 1067 int vectorIndex = (position / BitCacheSize) - 1; 1069 mask = 1L << (position % BitCacheSize); 1070 if (this.extra == null) { 1071 int length = vectorIndex + 1; 1072 this.extra = new long[extraLength][]; 1073 for (int j = 0; j < extraLength; j++) { 1074 this.extra[j] = new long[length ]; 1075 } 1076 if (coverageTestFlag && coverageTestId == 20) { 1077 throw new AssertionFailedException("COVERAGE 20"); } 1079 } 1080 else { 1081 int oldLength; 1082 if (vectorIndex >= (oldLength = this.extra[0].length)) { 1083 int newLength = vectorIndex + 1; 1084 for (int j = 0; j < extraLength; j++) { 1085 System.arraycopy(this.extra[j], 0, 1086 (this.extra[j] = new long[newLength]), 0, 1087 oldLength); 1088 } 1089 if (coverageTestFlag && coverageTestId == 21) { 1090 throw new AssertionFailedException("COVERAGE 21"); } 1092 } 1093 } 1094 if ((mask & this.extra[1 + 1][vectorIndex]) != 0) { 1095 if ((mask 1096 & (~this.extra[2 + 1][vectorIndex] | this.extra[3 + 1][vectorIndex] 1097 | ~this.extra[4 + 1][vectorIndex])) != 0) { 1098 this.extra[4 + 1][vectorIndex] &= ~mask; 1099 } 1100 } else if ((mask & this.extra[4 + 1][vectorIndex]) != 0) { 1101 this.extra[3 + 1][vectorIndex] &= ~mask; 1102 } else { 1103 if ((mask & this.extra[2 + 1][vectorIndex]) != 0) { 1104 this.extra[3 + 1][vectorIndex] &= ~mask; 1105 this.extra[4 + 1][vectorIndex] |= mask; 1106 } else { 1107 this.extra[3 + 1][vectorIndex] |= mask; 1108 } 1109 } 1110 this.extra[1 + 1][vectorIndex] |= mask; 1111 this.extra[2 + 1][vectorIndex] |= mask; 1112 } 1113 } 1114} 1115 1116 1119final private void markAsDefinitelyAssigned(int position) { 1120 1121 if (this != DEAD_END) { 1122 if (position < BitCacheSize) { 1124 long mask; 1126 this.definiteInits |= (mask = 1L << position); 1127 this.potentialInits |= mask; 1128 } 1129 else { 1130 int vectorIndex = (position / BitCacheSize) - 1; 1132 if (this.extra == null) { 1133 int length = vectorIndex + 1; 1134 this.extra = new long[extraLength][]; 1135 for (int j = 0; j < extraLength; j++) { 1136 this.extra[j] = new long[length]; 1137 } 1138 } 1139 else { 1140 int oldLength; if (vectorIndex >= (oldLength = this.extra[0].length)) { 1142 for (int j = 0; j < extraLength; j++) { 1143 System.arraycopy(this.extra[j], 0, 1144 (this.extra[j] = new long[vectorIndex + 1]), 0, 1145 oldLength); 1146 } 1147 } 1148 } 1149 long mask; 1150 this.extra[0][vectorIndex] |= 1151 (mask = 1L << (position % BitCacheSize)); 1152 this.extra[1][vectorIndex] |= mask; 1153 } 1154 } 1155} 1156 1157public void markAsDefinitelyAssigned(FieldBinding field) { 1158 if (this != DEAD_END) 1159 markAsDefinitelyAssigned(field.id); 1160} 1161 1162public void markAsDefinitelyAssigned(LocalVariableBinding local) { 1163 if (this != DEAD_END) 1164 markAsDefinitelyAssigned(local.id + this.maxFieldCount); 1165} 1166 1167public void markAsDefinitelyNonNull(LocalVariableBinding local) { 1168 if (this != DEAD_END) { 1170 this.tagBits |= NULL_FLAG_MASK; 1171 long mask; 1172 int position; 1173 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { this.nullBit1 |= (mask = 1L << position); 1177 this.nullBit3 |= mask; 1178 this.nullBit2 &= (mask = ~mask); 1180 this.nullBit4 &= mask; 1181 if (coverageTestFlag && coverageTestId == 22) { 1182 this.nullBit1 = 0; 1183 } 1184 } 1185 else { 1186 int vectorIndex ; 1188 this.extra[2][vectorIndex = (position / BitCacheSize) - 1] 1189 |= (mask = 1L << (position % BitCacheSize)); 1190 this.extra[4][vectorIndex] |= mask; 1191 this.extra[3][vectorIndex] &= (mask = ~mask); 1192 this.extra[5][vectorIndex] &= mask; 1193 if (coverageTestFlag && coverageTestId == 23) { 1194 this.extra[2][vectorIndex] = 0; 1195 } 1196 } 1197 } 1198} 1199 1200public void markAsDefinitelyNull(LocalVariableBinding local) { 1201 if (this != DEAD_END) { 1203 this.tagBits |= NULL_FLAG_MASK; 1204 long mask; 1205 int position; 1206 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { this.nullBit1 |= (mask = 1L << position); 1210 this.nullBit2 |= mask; 1211 this.nullBit3 &= (mask = ~mask); 1213 this.nullBit4 &= mask; 1214 if (coverageTestFlag && coverageTestId == 24) { 1215 this.nullBit4 = ~0; 1216 } 1217 } 1218 else { 1219 int vectorIndex ; 1221 this.extra[2][vectorIndex = (position / BitCacheSize) - 1] 1222 |= (mask = 1L << (position % BitCacheSize)); 1223 this.extra[3][vectorIndex] |= mask; 1224 this.extra[4][vectorIndex] &= (mask = ~mask); 1225 this.extra[5][vectorIndex] &= mask; 1226 if (coverageTestFlag && coverageTestId == 25) { 1227 this.extra[5][vectorIndex] = ~0; 1228 } 1229 } 1230 } 1231} 1232 1233 1237public void markAsDefinitelyUnknown(LocalVariableBinding local) { 1240 if (this != DEAD_END) { 1242 this.tagBits |= NULL_FLAG_MASK; 1243 long mask; 1244 int position; 1245 if ((position = local.id + this.maxFieldCount) < BitCacheSize) { 1247 this.nullBit1 |= (mask = 1L << position); 1250 this.nullBit4 |= mask; 1251 this.nullBit2 &= (mask = ~mask); 1253 this.nullBit3 &= mask; 1254 if (coverageTestFlag && coverageTestId == 26) { 1255 this.nullBit4 = 0; 1256 } 1257 } 1258 else { 1259 int vectorIndex ; 1261 this.extra[2][vectorIndex = (position / BitCacheSize) - 1] 1262 |= (mask = 1L << (position % BitCacheSize)); 1263 this.extra[5][vectorIndex] |= mask; 1264 this.extra[3][vectorIndex] &= (mask = ~mask); 1265 this.extra[4][vectorIndex] &= mask; 1266 if (coverageTestFlag && coverageTestId == 27) { 1267 this.extra[5][vectorIndex] = 0; 1268 } 1269 } 1270 } 1271} 1272 1273public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) { 1274 if ((otherInits.tagBits & UNREACHABLE) != 0 && this != DEAD_END) { 1275 if (coverageTestFlag && coverageTestId == 28) { 1276 throw new AssertionFailedException("COVERAGE 28"); } 1278 return this; 1279 } 1280 if ((this.tagBits & UNREACHABLE) != 0) { 1281 if (coverageTestFlag && coverageTestId == 29) { 1282 throw new AssertionFailedException("COVERAGE 29"); } 1284 return (UnconditionalFlowInfo) otherInits.copy(); } 1286 1287 this.definiteInits &= otherInits.definiteInits; 1289 this.potentialInits |= otherInits.potentialInits; 1291 1292 boolean 1294 thisHasNulls = (this.tagBits & NULL_FLAG_MASK) != 0, 1295 otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0, 1296 thisHadNulls = thisHasNulls; 1297 long 1298 a1, a2, a3, a4, 1299 na1, na2, na3, na4, 1300 nb1, nb2, nb3, nb4, 1301 b1, b2, b3, b4; 1302 if (thisHadNulls) { 1303 if (otherHasNulls) { 1304 this.nullBit1 = (a2 = this.nullBit2) & (a3 = this.nullBit3) 1305 & (a4 = this.nullBit4) & (b1 = otherInits.nullBit1) 1306 & (nb2 = ~(b2 = otherInits.nullBit2)) 1307 | (a1 = this.nullBit1) & (b1 & (a3 & a4 & (b3 = otherInits.nullBit3) 1308 & (b4 = otherInits.nullBit4) 1309 | (na2 = ~a2) & nb2 1310 & ((nb4 = ~b4) | (na4 = ~a4) 1311 | (na3 = ~a3) & (nb3 = ~b3)) 1312 | a2 & b2 & ((na4 | na3) & (nb4 | nb3))) 1313 | na2 & b2 & b3 & b4); 1314 this.nullBit2 = b2 & (nb3 | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & nb4) 1315 | a2 & (b2 | na4 & b3 & (b4 | nb1) | na3 | na1); 1316 this.nullBit3 = b3 & (nb2 & b4 | nb1 | a3 & (na4 & nb4 | a4 & b4)) 1317 | a3 & (na2 & a4 | na1) 1318 | (a2 | na1) & b1 & nb2 & nb4 1319 | a1 & na2 & na4 & (b2 | nb1); 1320 this.nullBit4 = na3 & (nb1 & nb3 & b4 1321 | b1 & (nb2 & nb3 | a4 & b2 & nb4) 1322 | na1 & a4 & (nb3 | b1 & b2)) 1323 | a3 & a4 & (b3 & b4 | b1 & nb2) 1324 | na2 & (nb1 & b4 | b1 & nb3 | na1 & a4) & nb2 1325 | a1 & (na3 & (nb3 & b4 1326 | b1 & b2 & b3 & nb4 1327 | na2 & (nb3 | nb2)) 1328 | na2 & b3 & b4 1329 | a2 & (nb1 & b4 | a3 & na4 & b1) & nb3); 1330 if (coverageTestFlag && coverageTestId == 30) { 1331 this.nullBit4 = ~0; 1332 } 1333 } else { a1 = this.nullBit1; 1335 this.nullBit1 = 0; 1336 this.nullBit2 = (a2 = this.nullBit2) & (na3 = ~(a3 = this.nullBit3) | (na1 = ~a1)); 1337 this.nullBit3 = a3 & ((na2 = ~a2) & (a4 = this.nullBit4) | na1) | a1 & na2 & ~a4; 1338 this.nullBit4 = (na3 | na2) & na1 & a4 | a1 & na3 & na2; 1339 if (coverageTestFlag && coverageTestId == 31) { 1340 this.nullBit4 = ~0; 1341 } 1342 } 1343 } else if (otherHasNulls) { this.nullBit1 = 0; 1345 this.nullBit2 = (b2 = otherInits.nullBit2) & (nb3 = ~(b3 = otherInits.nullBit3) | (nb1 = ~(b1 = otherInits.nullBit1))); 1346 this.nullBit3 = b3 & ((nb2 = ~b2) & (b4 = otherInits.nullBit4) | nb1) | b1 & nb2 & ~b4; 1347 this.nullBit4 = (nb3 | nb2) & nb1 & b4 | b1 & nb3 & nb2; 1348 if (coverageTestFlag && coverageTestId == 32) { 1349 this.nullBit4 = ~0; 1350 } 1351 thisHasNulls = 1352 this.nullBit2 != 0 || 1354 this.nullBit3 != 0 || 1355 this.nullBit4 != 0; 1356 } 1357 1358 if (this.extra != null || otherInits.extra != null) { 1360 int mergeLimit = 0, copyLimit = 0, resetLimit = 0; 1361 int i; 1362 if (this.extra != null) { 1363 if (otherInits.extra != null) { 1364 int length, otherLength; 1366 if ((length = this.extra[0].length) < 1367 (otherLength = otherInits.extra[0].length)) { 1368 for (int j = 0; j < extraLength; j++) { 1370 System.arraycopy(this.extra[j], 0, 1371 (this.extra[j] = new long[otherLength]), 0, length); 1372 } 1373 mergeLimit = length; 1374 copyLimit = otherLength; 1375 if (coverageTestFlag && coverageTestId == 33) { 1376 throw new AssertionFailedException("COVERAGE 33"); } 1378 } 1379 else { 1380 mergeLimit = otherLength; 1382 resetLimit = length; 1383 if (coverageTestFlag && coverageTestId == 34) { 1384 throw new AssertionFailedException("COVERAGE 34"); } 1386 } 1387 } 1388 else { 1389 resetLimit = this.extra[0].length; 1390 if (coverageTestFlag && coverageTestId == 35) { 1391 throw new AssertionFailedException("COVERAGE 35"); } 1393 } 1394 } 1395 else if (otherInits.extra != null) { 1396 int otherLength = otherInits.extra[0].length; 1398 this.extra = new long[extraLength][]; 1399 for (int j = 0; j < extraLength; j++) { 1400 this.extra[j] = new long[otherLength]; 1401 } 1402 System.arraycopy(otherInits.extra[1], 0, 1403 this.extra[1], 0, otherLength); 1404 copyLimit = otherLength; 1405 if (coverageTestFlag && coverageTestId == 36) { 1406 throw new AssertionFailedException("COVERAGE 36"); } 1408 } 1409 for (i = 0; i < mergeLimit; i++) { 1412 this.extra[0][i] &= otherInits.extra[0][i]; 1413 this.extra[1][i] |= otherInits.extra[1][i]; 1414 } 1415 for (; i < copyLimit; i++) { 1416 this.extra[1][i] = otherInits.extra[1][i]; 1417 } 1418 for (; i < resetLimit; i++) { 1419 this.extra[0][i] = 0; 1420 } 1421 if (!otherHasNulls) { 1423 if (resetLimit < mergeLimit) { 1424 resetLimit = mergeLimit; 1425 } 1426 copyLimit = 0; mergeLimit = 0; 1428 } 1429 if (!thisHadNulls) { 1430 resetLimit = 0; } 1432 for (i = 0; i < mergeLimit; i++) { 1434 this.extra[1 + 1][i] = (a2 = this.extra[2 + 1][i]) & (a3 = this.extra[3 + 1][i]) 1435 & (a4 = this.extra[4 + 1][i]) & (b1 = otherInits.extra[1 + 1][i]) 1436 & (nb2 = ~(b2 = otherInits.extra[2 + 1][i])) 1437 | (a1 = this.extra[1 + 1][i]) & (b1 & (a3 & a4 & (b3 = otherInits.extra[3 + 1][i]) 1438 & (b4 = otherInits.extra[4 + 1][i]) 1439 | (na2 = ~a2) & nb2 1440 & ((nb4 = ~b4) | (na4 = ~a4) 1441 | (na3 = ~a3) & (nb3 = ~b3)) 1442 | a2 & b2 & ((na4 | na3) & (nb4 | nb3))) 1443 | na2 & b2 & b3 & b4); 1444 this.extra[2 + 1][i] = b2 & (nb3 | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & nb4) 1445 | a2 & (b2 | na4 & b3 & (b4 | nb1) | na3 | na1); 1446 this.extra[3 + 1][i] = b3 & (nb2 & b4 | nb1 | a3 & (na4 & nb4 | a4 & b4)) 1447 | a3 & (na2 & a4 | na1) 1448 | (a2 | na1) & b1 & nb2 & nb4 1449 | a1 & na2 & na4 & (b2 | nb1); 1450 this.extra[4 + 1][i] = na3 & (nb1 & nb3 & b4 1451 | b1 & (nb2 & nb3 | a4 & b2 & nb4) 1452 | na1 & a4 & (nb3 | b1 & b2)) 1453 | a3 & a4 & (b3 & b4 | b1 & nb2) 1454 | na2 & (nb1 & b4 | b1 & nb3 | na1 & a4) & nb2 1455 | a1 & (na3 & (nb3 & b4 1456 | b1 & b2 & b3 & nb4 1457 | na2 & (nb3 | nb2)) 1458 | na2 & b3 & b4 1459 | a2 & (nb1 & b4 | a3 & na4 & b1) & nb3); 1460 thisHasNulls = thisHasNulls || 1461 this.extra[3][i] != 0 || 1462 this.extra[4][i] != 0 || 1463 this.extra[5][i] != 0 ; 1464 if (coverageTestFlag && coverageTestId == 37) { 1465 this.extra[5][i] = ~0; 1466 } 1467 } 1468 for (; i < copyLimit; i++) { 1469 this.extra[1 + 1][i] = 0; 1470 this.extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i]) & (nb3 = ~(b3 = otherInits.extra[3 + 1][i]) | (nb1 = ~(b1 = otherInits.extra[1 + 1][i]))); 1471 this.extra[3 + 1][i] = b3 & ((nb2 = ~b2) & (b4 = otherInits.extra[4 + 1][i]) | nb1) | b1 & nb2 & ~b4; 1472 this.extra[4 + 1][i] = (nb3 | nb2) & nb1 & b4 | b1 & nb3 & nb2; 1473 thisHasNulls = thisHasNulls || 1474 this.extra[3][i] != 0 || 1475 this.extra[4][i] != 0 || 1476 this.extra[5][i] != 0; 1477 if (coverageTestFlag && coverageTestId == 38) { 1478 this.extra[5][i] = ~0; 1479 } 1480 } 1481 for (; i < resetLimit; i++) { 1482 a1 = this.extra[1 + 1][i]; 1483 this.extra[1 + 1][i] = 0; 1484 this.extra[2 + 1][i] = (a2 = this.extra[2 + 1][i]) & (na3 = ~(a3 = this.extra[3 + 1][i]) | (na1 = ~a1)); 1485 this.extra[3 + 1][i] = a3 & ((na2 = ~a2) & (a4 = this.extra[4 + 1][i]) | na1) | a1 & na2 & ~a4; 1486 this.extra[4 + 1][i] = (na3 | na2) & na1 & a4 | a1 & na3 & na2; 1487 thisHasNulls = thisHasNulls || 1488 this.extra[3][i] != 0 || 1489 this.extra[4][i] != 0 || 1490 this.extra[5][i] != 0; 1491 if (coverageTestFlag && coverageTestId == 39) { 1492 this.extra[5][i] = ~0; 1493 } 1494 } 1495 } 1496 if (thisHasNulls) { 1497 this.tagBits |= NULL_FLAG_MASK; 1498 } 1499 else { 1500 this.tagBits &= ~NULL_FLAG_MASK; 1501 } 1502 return this; 1503} 1504 1505 1508static int numberOfEnclosingFields(ReferenceBinding type){ 1509 int count = 0; 1510 type = type.enclosingType(); 1511 while(type != null) { 1512 count += type.fieldCount(); 1513 type = type.enclosingType(); 1514 } 1515 return count; 1516} 1517 1518public UnconditionalFlowInfo nullInfoLessUnconditionalCopy() { 1519 if (this == DEAD_END) { 1520 return this; 1521 } 1522 UnconditionalFlowInfo copy = new UnconditionalFlowInfo(); 1523 copy.definiteInits = this.definiteInits; 1524 copy.potentialInits = this.potentialInits; 1525 copy.tagBits = this.tagBits & ~NULL_FLAG_MASK; 1526 copy.maxFieldCount = this.maxFieldCount; 1527 if (this.extra != null) { 1528 int length; 1529 copy.extra = new long[extraLength][]; 1530 System.arraycopy(this.extra[0], 0, 1531 (copy.extra[0] = 1532 new long[length = this.extra[0].length]), 0, length); 1533 System.arraycopy(this.extra[1], 0, 1534 (copy.extra[1] = new long[length]), 0, length); 1535 for (int j = 2; j < extraLength; j++) { 1536 copy.extra[j] = new long[length]; 1537 } 1538 } 1539 return copy; 1540} 1541 1542public FlowInfo safeInitsWhenTrue() { 1543 return copy(); 1544} 1545 1546public FlowInfo setReachMode(int reachMode) { 1547 if (reachMode == REACHABLE && this != DEAD_END) { this.tagBits &= ~UNREACHABLE; 1549 } 1550 else { 1551 if ((this.tagBits & UNREACHABLE) == 0) { 1552 this.potentialInits = 0; 1555 if (this.extra != null) { 1556 for (int i = 0, length = this.extra[0].length; 1557 i < length; i++) { 1558 this.extra[1][i] = 0; 1559 } 1560 } 1561 } 1562 this.tagBits |= UNREACHABLE; 1563 } 1564 return this; 1565} 1566 1567public String toString(){ 1568 if (this == DEAD_END){ 1570 return "FlowInfo.DEAD_END"; } 1572 if ((this.tagBits & NULL_FLAG_MASK) != 0) { 1573 if (this.extra == null) { 1574 return "FlowInfo<def: " + this.definiteInits +", pot: " + this.potentialInits + ", reachable:" + ((this.tagBits & UNREACHABLE) == 0) +", null: " + this.nullBit1 + this.nullBit2 + this.nullBit3 + this.nullBit4 1579 +">"; } 1581 else { 1582 String def = "FlowInfo<def:[" + this.definiteInits, pot = "], pot:[" + this.potentialInits, nullS = ", null:[" + this.nullBit1 + this.nullBit2 + this.nullBit3 + this.nullBit4; 1586 int i, ceil; 1587 for (i = 0, ceil = this.extra[0].length > 3 ? 1588 3 : 1589 this.extra[0].length; 1590 i < ceil; i++) { 1591 def += "," + this.extra[0][i]; pot += "," + this.extra[1][i]; nullS += "," + this.extra[2][i] + this.extra[3][i] + this.extra[4][i] + this.extra[5][i]; 1595 } 1596 if (ceil < this.extra[0].length) { 1597 def += ",..."; pot += ",..."; nullS += ",..."; } 1601 return def + pot 1602 + "], reachable:" + ((this.tagBits & UNREACHABLE) == 0) + nullS 1604 + "]>"; } 1606 } 1607 else { 1608 if (this.extra == null) { 1609 return "FlowInfo<def: " + this.definiteInits +", pot: " + this.potentialInits + ", reachable:" + ((this.tagBits & UNREACHABLE) == 0) +", no null info>"; } 1614 else { 1615 String def = "FlowInfo<def:[" + this.definiteInits, pot = "], pot:[" + this.potentialInits; int i, ceil; 1618 for (i = 0, ceil = this.extra[0].length > 3 ? 1619 3 : 1620 this.extra[0].length; 1621 i < ceil; i++) { 1622 def += "," + this.extra[0][i]; pot += "," + this.extra[1][i]; } 1625 if (ceil < this.extra[0].length) { 1626 def += ",..."; pot += ",..."; } 1629 return def + pot 1630 + "], reachable:" + ((this.tagBits & UNREACHABLE) == 0) + ", no null info>"; } 1633 } 1634} 1635 1636public UnconditionalFlowInfo unconditionalCopy() { 1637 return (UnconditionalFlowInfo) copy(); 1638} 1639 1640public UnconditionalFlowInfo unconditionalFieldLessCopy() { 1641 UnconditionalFlowInfo copy = new UnconditionalFlowInfo(); 1643 copy.tagBits = this.tagBits; 1644 copy.maxFieldCount = this.maxFieldCount; 1645 int limit = this.maxFieldCount; 1646 if (limit < BitCacheSize) { 1647 long mask; 1648 copy.definiteInits = this.definiteInits & (mask = ~((1L << limit)-1)); 1649 copy.potentialInits = this.potentialInits & mask; 1650 copy.nullBit1 = this.nullBit1 & mask; 1651 copy.nullBit2 = this.nullBit2 & mask; 1652 copy.nullBit3 = this.nullBit3 & mask; 1653 copy.nullBit4 = this.nullBit4 & mask; 1654 } 1655 if (this.extra == null) { 1657 return copy; } 1659 int vectorIndex, length, copyStart; 1660 if ((vectorIndex = (limit / BitCacheSize) - 1) >= 1661 (length = this.extra[0].length)) { 1662 return copy; } 1664 long mask; 1665 copy.extra = new long[extraLength][]; 1666 if ((copyStart = vectorIndex + 1) < length) { 1667 int copyLength = length - copyStart; 1668 for (int j = 0; j < extraLength; j++) { 1669 System.arraycopy(this.extra[j], copyStart, 1670 (copy.extra[j] = new long[length]), copyStart, 1671 copyLength); 1672 } 1673 } 1674 else if (vectorIndex >= 0) { 1675 for (int j = 0; j < extraLength; j++) { 1676 copy.extra[j] = new long[length]; 1677 } 1678 } 1679 if (vectorIndex >= 0) { 1680 mask = ~((1L << (limit % BitCacheSize))-1); 1681 for (int j = 0; j < extraLength; j++) { 1682 copy.extra[j][vectorIndex] = 1683 this.extra[j][vectorIndex] & mask; 1684 } 1685 } 1686 return copy; 1687} 1688 1689public UnconditionalFlowInfo unconditionalInits() { 1690 return this; 1692} 1693 1694public UnconditionalFlowInfo unconditionalInitsWithoutSideEffect() { 1695 return this; 1696} 1697} 1698 1699 | Popular Tags |