Source Code Cross Referenced for UnconditionalFlowInfo.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » compiler » flow » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.compiler.flow 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2006 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.jdt.internal.compiler.flow;
0011:
0012:        import org.eclipse.jdt.internal.compiler.ast.ASTNode;
0013:        import org.eclipse.jdt.internal.compiler.impl.Constant;
0014:        import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
0015:        import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
0016:        import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
0017:        import org.eclipse.jdt.internal.compiler.lookup.TagBits;
0018:
0019:        /**
0020:         * Record initialization status during definite assignment analysis
0021:         *
0022:         * No caching of pre-allocated instances.
0023:         */
0024:        public class UnconditionalFlowInfo extends FlowInfo {
0025:            // Coverage tests
0026:            /**
0027:             * Exception raised when unexpected behavior is detected during coverage
0028:             * tests. 
0029:             */
0030:            public static class AssertionFailedException extends
0031:                    RuntimeException {
0032:                private static final long serialVersionUID = 1827352841030089703L;
0033:
0034:                public AssertionFailedException(String message) {
0035:                    super (message);
0036:                }
0037:            }
0038:
0039:            // Coverage tests need that the code be instrumented. The following flag
0040:            // controls whether the instrumented code is compiled in or not, and whether
0041:            // the coverage tests methods run or not.
0042:            public final static boolean coverageTestFlag = false;
0043:            // never release with the coverageTestFlag set to true
0044:            public static int coverageTestId;
0045:
0046:            // assignment bits - first segment
0047:            public long definiteInits;
0048:            public long potentialInits;
0049:
0050:            // null bits - first segment
0051:            public long nullBit1, nullBit2, nullBit3, nullBit4;
0052:            /*
0053:             nullBit1
0054:             nullBit2...
0055:             0000	start
0056:             0001	pot. unknown
0057:             0010	pot. non null
0058:             0011	pot. nn & pot. un
0059:             0100	pot. null
0060:             0101	pot. n & pot. un
0061:             0110	pot. n & pot. nn
0062:             1001	def. unknown
0063:             1010	def. non null
0064:             1011	pot. nn & prot. nn
0065:             1100	def. null
0066:             1101	pot. n & prot. n
0067:             1110	prot. null
0068:             1111	prot. non null
0069:             */
0070:
0071:            // extra segments
0072:            public static final int extraLength = 6;
0073:            public long extra[][];
0074:            // extra bit fields for larger numbers of fields/variables
0075:            // extra[0] holds definiteInits values, extra[1] potentialInits, etc.
0076:            // lifecycle is extra == null or else all extra[]'s are allocated
0077:            // arrays which have the same size
0078:
0079:            public int maxFieldCount; // limit between fields and locals
0080:
0081:            // Constants
0082:            public static final int BitCacheSize = 64; // 64 bits in a long.
0083:
0084:            public FlowInfo addInitializationsFrom(FlowInfo inits) {
0085:                if (this  == DEAD_END)
0086:                    return this ;
0087:                if (inits == DEAD_END)
0088:                    return this ;
0089:                UnconditionalFlowInfo otherInits = inits.unconditionalInits();
0090:
0091:                // union of definitely assigned variables, 
0092:                this .definiteInits |= otherInits.definiteInits;
0093:                // union of potentially set ones
0094:                this .potentialInits |= otherInits.potentialInits;
0095:                // combine null information
0096:                boolean this HadNulls = (this .tagBits & NULL_FLAG_MASK) != 0, otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0;
0097:                long a1, a2, a3, a4, na1, na2, na3, na4, b1, b2, b3, b4, nb1, nb2, nb3, nb4;
0098:                if (otherHasNulls) {
0099:                    if (!this HadNulls) {
0100:                        this .nullBit1 = otherInits.nullBit1;
0101:                        this .nullBit2 = otherInits.nullBit2;
0102:                        this .nullBit3 = otherInits.nullBit3;
0103:                        this .nullBit4 = otherInits.nullBit4;
0104:                        if (coverageTestFlag && coverageTestId == 1) {
0105:                            this .nullBit4 = ~0;
0106:                        }
0107:                    } else {
0108:                        this .nullBit1 = (b1 = otherInits.nullBit1)
0109:                                | (a1 = this .nullBit1)
0110:                                & ((a3 = this .nullBit3) & (a4 = this .nullBit4)
0111:                                        & (nb2 = ~(b2 = otherInits.nullBit2))
0112:                                        & (nb4 = ~(b4 = otherInits.nullBit4)) | ((na4 = ~a4) | (na3 = ~a3))
0113:                                        & ((na2 = ~(a2 = this .nullBit2)) & nb2 | a2
0114:                                                & (nb3 = ~(b3 = otherInits.nullBit3))
0115:                                                & nb4));
0116:                        this .nullBit2 = b2
0117:                                & (nb4 | nb3)
0118:                                | na3
0119:                                & na4
0120:                                & b2
0121:                                | a2
0122:                                & (nb3 & nb4 | (nb1 = ~b1)
0123:                                        & (na3 | (na1 = ~a1)) | a1 & b2);
0124:                        this .nullBit3 = b3
0125:                                & (nb1 & (b2 | a2 | na1) | b1
0126:                                        & (b4 | nb2 | a1 & a3) | na1 & na2
0127:                                        & na4) | a3 & nb2 & nb4 | nb1
0128:                                & ((na2 & a4 | na1) & a3 | a1 & na2 & na4 & b2);
0129:                        this .nullBit4 = nb1
0130:                                & (a4 & (na3 & nb3 | (a3 | na2) & nb2) | a1
0131:                                        & (a3 & nb2 & b4 | a2 & b2
0132:                                                & (b4 | a3 & na4 & nb3)))
0133:                                | b1
0134:                                & (a3 & a4 & b4 | na2 & na4 & nb3 & b4 | a2
0135:                                        & ((b3 | a4) & b4 | na3 & a4 & b2 & b3) | na1
0136:                                        & (b4 | (a4 | a2) & b2 & b3))
0137:                                | (na1 & (na3 & nb3 | na2 & nb2) | a1
0138:                                        & (nb2 & nb3 | a2 & a3)) & b4;
0139:                        if (coverageTestFlag && coverageTestId == 2) {
0140:                            this .nullBit4 = ~0;
0141:                        }
0142:                    }
0143:                    this .tagBits |= NULL_FLAG_MASK; // in all cases - avoid forgetting extras
0144:                }
0145:                // treating extra storage
0146:                if (this .extra != null || otherInits.extra != null) {
0147:                    int mergeLimit = 0, copyLimit = 0;
0148:                    if (this .extra != null) {
0149:                        if (otherInits.extra != null) {
0150:                            // both sides have extra storage
0151:                            int length, otherLength;
0152:                            if ((length = this .extra[0].length) < (otherLength = otherInits.extra[0].length)) {
0153:                                // current storage is shorter -> grow current
0154:                                for (int j = 0; j < extraLength; j++) {
0155:                                    System
0156:                                            .arraycopy(
0157:                                                    this .extra[j],
0158:                                                    0,
0159:                                                    (this .extra[j] = new long[otherLength]),
0160:                                                    0, length);
0161:                                }
0162:                                mergeLimit = length;
0163:                                copyLimit = otherLength;
0164:                                if (coverageTestFlag && coverageTestId == 3) {
0165:                                    throw new AssertionFailedException(
0166:                                            "COVERAGE 3"); //$NON-NLS-1$
0167:                                }
0168:                            } else {
0169:                                // current storage is longer
0170:                                mergeLimit = otherLength;
0171:                                if (coverageTestFlag && coverageTestId == 4) {
0172:                                    throw new AssertionFailedException(
0173:                                            "COVERAGE 4"); //$NON-NLS-1$
0174:                                }
0175:                            }
0176:                        }
0177:                    } else if (otherInits.extra != null) {
0178:                        // no storage here, but other has extra storage.
0179:                        // shortcut regular copy because array copy is better
0180:                        int otherLength;
0181:                        this .extra = new long[extraLength][];
0182:                        System
0183:                                .arraycopy(
0184:                                        otherInits.extra[0],
0185:                                        0,
0186:                                        (this .extra[0] = new long[otherLength = otherInits.extra[0].length]),
0187:                                        0, otherLength);
0188:                        System.arraycopy(otherInits.extra[1], 0,
0189:                                (this .extra[1] = new long[otherLength]), 0,
0190:                                otherLength);
0191:                        if (otherHasNulls) {
0192:                            for (int j = 2; j < extraLength; j++) {
0193:                                System
0194:                                        .arraycopy(
0195:                                                otherInits.extra[j],
0196:                                                0,
0197:                                                (this .extra[j] = new long[otherLength]),
0198:                                                0, otherLength);
0199:                            }
0200:                            if (coverageTestFlag && coverageTestId == 5) {
0201:                                this .extra[5][otherLength - 1] = ~0;
0202:                            }
0203:                        } else {
0204:                            for (int j = 2; j < extraLength; j++) {
0205:                                this .extra[j] = new long[otherLength];
0206:                            }
0207:                            if (coverageTestFlag && coverageTestId == 6) {
0208:                                throw new AssertionFailedException("COVERAGE 6"); //$NON-NLS-1$
0209:                            }
0210:                        }
0211:                    }
0212:                    int i;
0213:                    // manage definite assignment info
0214:                    for (i = 0; i < mergeLimit; i++) {
0215:                        this .extra[0][i] |= otherInits.extra[0][i];
0216:                        this .extra[1][i] |= otherInits.extra[1][i];
0217:                    }
0218:                    for (; i < copyLimit; i++) {
0219:                        this .extra[0][i] = otherInits.extra[0][i];
0220:                        this .extra[1][i] = otherInits.extra[1][i];
0221:                    }
0222:                    // tweak limits for nulls
0223:                    if (!this HadNulls) {
0224:                        if (copyLimit < mergeLimit) {
0225:                            copyLimit = mergeLimit;
0226:                        }
0227:                        mergeLimit = 0;
0228:                    }
0229:                    if (!otherHasNulls) {
0230:                        copyLimit = 0;
0231:                        mergeLimit = 0;
0232:                    }
0233:                    for (i = 0; i < mergeLimit; i++) {
0234:                        this .extra[1 + 1][i] = (b1 = otherInits.extra[1 + 1][i])
0235:                                | (a1 = this .extra[1 + 1][i])
0236:                                & ((a3 = this .extra[3 + 1][i])
0237:                                        & (a4 = this .extra[4 + 1][i])
0238:                                        & (nb2 = ~(b2 = otherInits.extra[2 + 1][i]))
0239:                                        & (nb4 = ~(b4 = otherInits.extra[4 + 1][i])) | ((na4 = ~a4) | (na3 = ~a3))
0240:                                        & ((na2 = ~(a2 = this .extra[2 + 1][i]))
0241:                                                & nb2 | a2
0242:                                                & (nb3 = ~(b3 = otherInits.extra[3 + 1][i]))
0243:                                                & nb4));
0244:                        this .extra[2 + 1][i] = b2
0245:                                & (nb4 | nb3)
0246:                                | na3
0247:                                & na4
0248:                                & b2
0249:                                | a2
0250:                                & (nb3 & nb4 | (nb1 = ~b1)
0251:                                        & (na3 | (na1 = ~a1)) | a1 & b2);
0252:                        this .extra[3 + 1][i] = b3
0253:                                & (nb1 & (b2 | a2 | na1) | b1
0254:                                        & (b4 | nb2 | a1 & a3) | na1 & na2
0255:                                        & na4) | a3 & nb2 & nb4 | nb1
0256:                                & ((na2 & a4 | na1) & a3 | a1 & na2 & na4 & b2);
0257:                        this .extra[4 + 1][i] = nb1
0258:                                & (a4 & (na3 & nb3 | (a3 | na2) & nb2) | a1
0259:                                        & (a3 & nb2 & b4 | a2 & b2
0260:                                                & (b4 | a3 & na4 & nb3)))
0261:                                | b1
0262:                                & (a3 & a4 & b4 | na2 & na4 & nb3 & b4 | a2
0263:                                        & ((b3 | a4) & b4 | na3 & a4 & b2 & b3) | na1
0264:                                        & (b4 | (a4 | a2) & b2 & b3))
0265:                                | (na1 & (na3 & nb3 | na2 & nb2) | a1
0266:                                        & (nb2 & nb3 | a2 & a3)) & b4;
0267:                        if (coverageTestFlag && coverageTestId == 7) {
0268:                            this .extra[5][i] = ~0;
0269:                        }
0270:                    }
0271:                    for (; i < copyLimit; i++) {
0272:                        for (int j = 2; j < extraLength; j++) {
0273:                            this .extra[j][i] = otherInits.extra[j][i];
0274:                        }
0275:                        if (coverageTestFlag && coverageTestId == 8) {
0276:                            this .extra[5][i] = ~0;
0277:                        }
0278:                    }
0279:                }
0280:                return this ;
0281:            }
0282:
0283:            public FlowInfo addPotentialInitializationsFrom(FlowInfo inits) {
0284:                if (this  == DEAD_END) {
0285:                    return this ;
0286:                }
0287:                if (inits == DEAD_END) {
0288:                    return this ;
0289:                }
0290:                UnconditionalFlowInfo otherInits = inits.unconditionalInits();
0291:                // union of potentially set ones
0292:                this .potentialInits |= otherInits.potentialInits;
0293:                // treating extra storage
0294:                if (this .extra != null) {
0295:                    if (otherInits.extra != null) {
0296:                        // both sides have extra storage
0297:                        int i = 0, length, otherLength;
0298:                        if ((length = this .extra[0].length) < (otherLength = otherInits.extra[0].length)) {
0299:                            // current storage is shorter -> grow current
0300:                            for (int j = 0; j < extraLength; j++) {
0301:                                System
0302:                                        .arraycopy(
0303:                                                this .extra[j],
0304:                                                0,
0305:                                                (this .extra[j] = new long[otherLength]),
0306:                                                0, length);
0307:                            }
0308:                            for (; i < length; i++) {
0309:                                this .extra[1][i] |= otherInits.extra[1][i];
0310:                            }
0311:                            for (; i < otherLength; i++) {
0312:                                this .extra[1][i] = otherInits.extra[1][i];
0313:                            }
0314:                        } else {
0315:                            // current storage is longer
0316:                            for (; i < otherLength; i++) {
0317:                                this .extra[1][i] |= otherInits.extra[1][i];
0318:                            }
0319:                        }
0320:                    }
0321:                } else if (otherInits.extra != null) {
0322:                    // no storage here, but other has extra storage.
0323:                    int otherLength = otherInits.extra[0].length;
0324:                    this .extra = new long[extraLength][];
0325:                    for (int j = 0; j < extraLength; j++) {
0326:                        this .extra[j] = new long[otherLength];
0327:                    }
0328:                    System.arraycopy(otherInits.extra[1], 0, this .extra[1], 0,
0329:                            otherLength);
0330:                }
0331:                this .addPotentialNullInfoFrom(otherInits);
0332:                return this ;
0333:            }
0334:
0335:            /**
0336:             * Compose other inits over this flow info, then return this. The operation
0337:             * semantics are to wave into this flow info the consequences upon null 
0338:             * information of a possible path into the operations that resulted into 
0339:             * otherInits. The fact that this path may be left unexecuted under peculiar 
0340:             * conditions results into less specific results than 
0341:             * {@link #addInitializationsFrom(FlowInfo) addInitializationsFrom}; moreover,
0342:             * only the null information is affected.
0343:             * @param otherInits other null inits to compose over this
0344:             * @return this, modified according to otherInits information
0345:             */
0346:            public UnconditionalFlowInfo addPotentialNullInfoFrom(
0347:                    UnconditionalFlowInfo otherInits) {
0348:                if ((this .tagBits & UNREACHABLE) != 0
0349:                        || (otherInits.tagBits & UNREACHABLE) != 0
0350:                        || (otherInits.tagBits & NULL_FLAG_MASK) == 0) {
0351:                    return this ;
0352:                }
0353:                // if we get here, otherInits has some null info
0354:                boolean this HadNulls = (this .tagBits & NULL_FLAG_MASK) != 0, this HasNulls = false;
0355:                long a1, a2, a3, a4, na1, na2, na3, na4, b1, b2, b3, b4, nb1, nb2, nb3, nb4;
0356:                if (this HadNulls) {
0357:                    this .nullBit1 = (a1 = this .nullBit1)
0358:                            & ((a3 = this .nullBit3)
0359:                                    & (a4 = this .nullBit4)
0360:                                    & ((nb2 = ~(b2 = otherInits.nullBit2))
0361:                                            & (nb4 = ~(b4 = otherInits.nullBit4)) | (b1 = otherInits.nullBit1)
0362:                                            & (b3 = otherInits.nullBit3))
0363:                                    | (na2 = ~(a2 = this .nullBit2))
0364:                                    & (b1 & b3 | ((na4 = ~a4) | (na3 = ~a3))
0365:                                            & nb2) | a2
0366:                                    & ((na4 | na3) & ((nb3 = ~b3) & nb4 | b1
0367:                                            & b2)));
0368:                    this .nullBit2 = b2 & (nb3 | (nb1 = ~b1)) | a2
0369:                            & (nb3 & nb4 | b2 | na3 | (na1 = ~a1));
0370:                    this .nullBit3 = b3
0371:                            & (nb1 & b2 | a2 & (nb2 | a3) | na1 & nb2 | a1
0372:                                    & na2 & na4 & b1) | a3
0373:                            & (nb2 & nb4 | na2 & a4 | na1) | a1 & na2 & na4
0374:                            & b2;
0375:                    this .nullBit4 = na3
0376:                            & (nb1 & nb3 & b4 | a4 & (nb3 | b1 & b2))
0377:                            | nb2
0378:                            & (na3 & b1 & nb3 | na2
0379:                                    & (nb1 & b4 | b1 & nb3 | a4))
0380:                            | a3
0381:                            & (a4 & (nb2 | b1 & b3) | a1 & a2
0382:                                    & (nb1 & b4 | na4 & (b2 | b1) & nb3));
0383:                    if (coverageTestFlag && coverageTestId == 9) {
0384:                        this .nullBit4 = ~0;
0385:                    }
0386:                    if ((this .nullBit2 | this .nullBit3 | this .nullBit4) != 0) { //  bit1 is redundant
0387:                        this HasNulls = true;
0388:                    }
0389:                } else {
0390:                    this .nullBit1 = 0;
0391:                    this .nullBit2 = (b2 = otherInits.nullBit2)
0392:                            & ((nb3 = ~(b3 = otherInits.nullBit3)) | (nb1 = ~(b1 = otherInits.nullBit1)));
0393:                    this .nullBit3 = b3 & (nb1 | (nb2 = ~b2));
0394:                    this .nullBit4 = ~b1 & ~b3 & (b4 = otherInits.nullBit4)
0395:                            | ~b2 & (b1 & ~b3 | ~b1 & b4);
0396:                    if (coverageTestFlag && coverageTestId == 10) {
0397:                        this .nullBit4 = ~0;
0398:                    }
0399:                    if ((this .nullBit2 | this .nullBit3 | this .nullBit4) != 0) { //  bit1 is redundant
0400:                        this HasNulls = true;
0401:                    }
0402:                }
0403:                // extra storage management
0404:                if (otherInits.extra != null) {
0405:                    int mergeLimit = 0, copyLimit = otherInits.extra[0].length;
0406:                    if (this .extra == null) {
0407:                        this .extra = new long[extraLength][];
0408:                        for (int j = 0; j < extraLength; j++) {
0409:                            this .extra[j] = new long[copyLimit];
0410:                        }
0411:                        if (coverageTestFlag && coverageTestId == 11) {
0412:                            throw new AssertionFailedException("COVERAGE 11"); //$NON-NLS-1$
0413:                        }
0414:                    } else {
0415:                        mergeLimit = copyLimit;
0416:                        if (mergeLimit > this .extra[0].length) {
0417:                            mergeLimit = this .extra[0].length;
0418:                            for (int j = 0; j < extraLength; j++) {
0419:                                System.arraycopy(this .extra[j], 0,
0420:                                        this .extra[j] = new long[copyLimit], 0,
0421:                                        mergeLimit);
0422:                            }
0423:                            if (!this HadNulls) {
0424:                                mergeLimit = 0;
0425:                                // will do with a copy -- caveat: only valid because definite assignment bits copied above
0426:                                if (coverageTestFlag && coverageTestId == 12) {
0427:                                    throw new AssertionFailedException(
0428:                                            "COVERAGE 12"); //$NON-NLS-1$
0429:                                }
0430:                            }
0431:                        }
0432:                    }
0433:                    // PREMATURE skip operations for fields
0434:                    int i;
0435:                    for (i = 0; i < mergeLimit; i++) {
0436:                        this .extra[1 + 1][i] = (a1 = this .extra[1 + 1][i])
0437:                                & ((a3 = this .extra[3 + 1][i])
0438:                                        & (a4 = this .extra[4 + 1][i])
0439:                                        & ((nb2 = ~(b2 = otherInits.extra[2 + 1][i]))
0440:                                                & (nb4 = ~(b4 = otherInits.extra[4 + 1][i])) | (b1 = otherInits.extra[1 + 1][i])
0441:                                                & (b3 = otherInits.extra[3 + 1][i]))
0442:                                        | (na2 = ~(a2 = this .extra[2 + 1][i]))
0443:                                        & (b1 & b3 | ((na4 = ~a4) | (na3 = ~a3))
0444:                                                & nb2) | a2
0445:                                        & ((na4 | na3) & ((nb3 = ~b3) & nb4 | b1
0446:                                                & b2)));
0447:                        this .extra[2 + 1][i] = b2 & (nb3 | (nb1 = ~b1)) | a2
0448:                                & (nb3 & nb4 | b2 | na3 | (na1 = ~a1));
0449:                        this .extra[3 + 1][i] = b3
0450:                                & (nb1 & b2 | a2 & (nb2 | a3) | na1 & nb2 | a1
0451:                                        & na2 & na4 & b1) | a3
0452:                                & (nb2 & nb4 | na2 & a4 | na1) | a1 & na2 & na4
0453:                                & b2;
0454:                        this .extra[4 + 1][i] = na3
0455:                                & (nb1 & nb3 & b4 | a4 & (nb3 | b1 & b2))
0456:                                | nb2
0457:                                & (na3 & b1 & nb3 | na2
0458:                                        & (nb1 & b4 | b1 & nb3 | a4))
0459:                                | a3
0460:                                & (a4 & (nb2 | b1 & b3) | a1 & a2
0461:                                        & (nb1 & b4 | na4 & (b2 | b1) & nb3));
0462:                        if ((this .extra[2 + 1][i] | this .extra[3 + 1][i] | this .extra[4 + 1][i]) != 0) { //  bit1 is redundant
0463:                            this HasNulls = true;
0464:                        }
0465:                        if (coverageTestFlag && coverageTestId == 13) {
0466:                            this .nullBit4 = ~0;
0467:                        }
0468:                    }
0469:                    for (; i < copyLimit; i++) {
0470:                        this .extra[1 + 1][i] = 0;
0471:                        this .extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i])
0472:                                & ((nb3 = ~(b3 = otherInits.extra[3 + 1][i])) | (nb1 = ~(b1 = otherInits.extra[1 + 1][i])));
0473:                        this .extra[3 + 1][i] = b3 & (nb1 | (nb2 = ~b2));
0474:                        this .extra[4 + 1][i] = ~b1 & ~b3
0475:                                & (b4 = otherInits.extra[4 + 1][i]) | ~b2
0476:                                & (b1 & ~b3 | ~b1 & b4);
0477:                        if ((this .extra[2 + 1][i] | this .extra[3 + 1][i] | this .extra[4 + 1][i]) != 0) { //  bit1 is redundant
0478:                            this HasNulls = true;
0479:                        }
0480:                        if (coverageTestFlag && coverageTestId == 14) {
0481:                            this .extra[5][i] = ~0;
0482:                        }
0483:                    }
0484:                }
0485:                if (this HasNulls) {
0486:                    this .tagBits |= NULL_FLAG_MASK;
0487:                } else {
0488:                    this .tagBits &= NULL_FLAG_MASK;
0489:                }
0490:                return this ;
0491:            }
0492:
0493:            final public boolean cannotBeDefinitelyNullOrNonNull(
0494:                    LocalVariableBinding local) {
0495:                if ((this .tagBits & NULL_FLAG_MASK) == 0
0496:                        || (local.type.tagBits & TagBits.IsBaseType) != 0) {
0497:                    return false;
0498:                }
0499:                int position;
0500:                if ((position = local.id + this .maxFieldCount) < BitCacheSize) {
0501:                    // use bits
0502:                    return ((~this .nullBit1
0503:                            & (this .nullBit2 & this .nullBit3 | this .nullBit4) | ~this .nullBit2
0504:                            & ~this .nullBit3 & this .nullBit4) & (1L << position)) != 0;
0505:                }
0506:                // use extra vector
0507:                if (this .extra == null) {
0508:                    return false; // if vector not yet allocated, then not initialized
0509:                }
0510:                int vectorIndex;
0511:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0512:                    return false; // if not enough room in vector, then not initialized
0513:                }
0514:                long a2, a3, a4;
0515:                return ((~this .extra[2][vectorIndex]
0516:                        & ((a2 = this .extra[3][vectorIndex])
0517:                                & (a3 = this .extra[4][vectorIndex]) | (a4 = this .extra[5][vectorIndex])) | ~a2
0518:                        & ~a3 & a4) & (1L << (position % BitCacheSize))) != 0;
0519:            }
0520:
0521:            final public boolean cannotBeNull(LocalVariableBinding local) {
0522:                if ((this .tagBits & NULL_FLAG_MASK) == 0
0523:                        || (local.type.tagBits & TagBits.IsBaseType) != 0) {
0524:                    return false;
0525:                }
0526:                int position;
0527:                if ((position = local.id + this .maxFieldCount) < BitCacheSize) {
0528:                    // use bits
0529:                    return (this .nullBit1
0530:                            & this .nullBit3
0531:                            & ((this .nullBit2 & this .nullBit4) | ~this .nullBit2) & (1L << position)) != 0;
0532:                }
0533:                // use extra vector
0534:                if (this .extra == null) {
0535:                    return false; // if vector not yet allocated, then not initialized
0536:                }
0537:                int vectorIndex;
0538:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0539:                    return false; // if not enough room in vector, then not initialized
0540:                }
0541:                return (this .extra[2][vectorIndex]
0542:                        & this .extra[4][vectorIndex]
0543:                        & ((this .extra[3][vectorIndex] & this .extra[5][vectorIndex]) | ~this .extra[3][vectorIndex]) & (1L << (position % BitCacheSize))) != 0;
0544:            }
0545:
0546:            final public boolean canOnlyBeNull(LocalVariableBinding local) {
0547:                if ((this .tagBits & NULL_FLAG_MASK) == 0
0548:                        || (local.type.tagBits & TagBits.IsBaseType) != 0) {
0549:                    return false;
0550:                }
0551:                int position;
0552:                if ((position = local.id + this .maxFieldCount) < BitCacheSize) {
0553:                    // use bits
0554:                    return (this .nullBit1 & this .nullBit2
0555:                            & (~this .nullBit3 | ~this .nullBit4) & (1L << position)) != 0;
0556:                }
0557:                // use extra vector
0558:                if (this .extra == null) {
0559:                    return false; // if vector not yet allocated, then not initialized
0560:                }
0561:                int vectorIndex;
0562:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0563:                    return false; // if not enough room in vector, then not initialized
0564:                }
0565:                return (this .extra[2][vectorIndex]
0566:                        & this .extra[3][vectorIndex]
0567:                        & (~this .extra[4][vectorIndex] | ~this .extra[5][vectorIndex]) & (1L << (position % BitCacheSize))) != 0;
0568:            }
0569:
0570:            public FlowInfo copy() {
0571:                // do not clone the DeadEnd
0572:                if (this  == DEAD_END) {
0573:                    return this ;
0574:                }
0575:                UnconditionalFlowInfo copy = new UnconditionalFlowInfo();
0576:                // copy slots
0577:                copy.definiteInits = this .definiteInits;
0578:                copy.potentialInits = this .potentialInits;
0579:                boolean hasNullInfo = (this .tagBits & NULL_FLAG_MASK) != 0;
0580:                if (hasNullInfo) {
0581:                    copy.nullBit1 = this .nullBit1;
0582:                    copy.nullBit2 = this .nullBit2;
0583:                    copy.nullBit3 = this .nullBit3;
0584:                    copy.nullBit4 = this .nullBit4;
0585:                }
0586:                copy.tagBits = this .tagBits;
0587:                copy.maxFieldCount = this .maxFieldCount;
0588:                if (this .extra != null) {
0589:                    int length;
0590:                    copy.extra = new long[extraLength][];
0591:                    System
0592:                            .arraycopy(
0593:                                    this .extra[0],
0594:                                    0,
0595:                                    (copy.extra[0] = new long[length = this .extra[0].length]),
0596:                                    0, length);
0597:                    System.arraycopy(this .extra[1], 0,
0598:                            (copy.extra[1] = new long[length]), 0, length);
0599:                    if (hasNullInfo) {
0600:                        for (int j = 2; j < extraLength; j++) {
0601:                            System.arraycopy(this .extra[j], 0,
0602:                                    (copy.extra[j] = new long[length]), 0,
0603:                                    length);
0604:                        }
0605:                    } else {
0606:                        for (int j = 2; j < extraLength; j++) {
0607:                            copy.extra[j] = new long[length];
0608:                        }
0609:                    }
0610:                }
0611:                return copy;
0612:            }
0613:
0614:            /**
0615:             * Discard definite inits and potential inits from this, then return this.
0616:             * The returned flow info only holds null related information. 
0617:             * @return this flow info, minus definite inits and potential inits
0618:             */
0619:            public UnconditionalFlowInfo discardInitializationInfo() {
0620:                if (this  == DEAD_END) {
0621:                    return this ;
0622:                }
0623:                this .definiteInits = this .potentialInits = 0;
0624:                if (this .extra != null) {
0625:                    for (int i = 0, length = this .extra[0].length; i < length; i++) {
0626:                        this .extra[0][i] = this .extra[1][i] = 0;
0627:                    }
0628:                }
0629:                return this ;
0630:            }
0631:
0632:            /**
0633:             * Remove local variables information from this flow info and return this.
0634:             * @return this, deprived from any local variable information
0635:             */
0636:            public UnconditionalFlowInfo discardNonFieldInitializations() {
0637:                int limit = this .maxFieldCount;
0638:                if (limit < BitCacheSize) {
0639:                    long mask = (1L << limit) - 1;
0640:                    this .definiteInits &= mask;
0641:                    this .potentialInits &= mask;
0642:                    this .nullBit1 &= mask;
0643:                    this .nullBit2 &= mask;
0644:                    this .nullBit3 &= mask;
0645:                    this .nullBit4 &= mask;
0646:                }
0647:                // use extra vector
0648:                if (this .extra == null) {
0649:                    return this ; // if vector not yet allocated, then not initialized
0650:                }
0651:                int vectorIndex, length = this .extra[0].length;
0652:                if ((vectorIndex = (limit / BitCacheSize) - 1) >= length) {
0653:                    return this ; // not enough room yet
0654:                }
0655:                if (vectorIndex >= 0) {
0656:                    // else we only have complete non field array items left
0657:                    long mask = (1L << (limit % BitCacheSize)) - 1;
0658:                    for (int j = 0; j < extraLength; j++) {
0659:                        this .extra[j][vectorIndex] &= mask;
0660:                    }
0661:                }
0662:                for (int i = vectorIndex + 1; i < length; i++) {
0663:                    for (int j = 0; j < extraLength; j++) {
0664:                        this .extra[j][i] = 0;
0665:                    }
0666:                }
0667:                return this ;
0668:            }
0669:
0670:            public FlowInfo initsWhenFalse() {
0671:                return this ;
0672:            }
0673:
0674:            public FlowInfo initsWhenTrue() {
0675:                return this ;
0676:            }
0677:
0678:            /**
0679:             * Check status of definite assignment at a given position.
0680:             * It deals with the dual representation of the InitializationInfo2:
0681:             * bits for the first 64 entries, then an array of booleans.
0682:             */
0683:            final private boolean isDefinitelyAssigned(int position) {
0684:                if (position < BitCacheSize) {
0685:                    // use bits
0686:                    return (this .definiteInits & (1L << position)) != 0;
0687:                }
0688:                // use extra vector
0689:                if (this .extra == null)
0690:                    return false; // if vector not yet allocated, then not initialized
0691:                int vectorIndex;
0692:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0693:                    return false; // if not enough room in vector, then not initialized
0694:                }
0695:                return ((this .extra[0][vectorIndex]) & (1L << (position % BitCacheSize))) != 0;
0696:            }
0697:
0698:            final public boolean isDefinitelyAssigned(FieldBinding field) {
0699:                // Mirrored in CodeStream.isDefinitelyAssigned(..) 
0700:                // do not want to complain in unreachable code
0701:                if ((this .tagBits & UNREACHABLE) != 0) {
0702:                    return true;
0703:                }
0704:                return isDefinitelyAssigned(field.id);
0705:            }
0706:
0707:            final public boolean isDefinitelyAssigned(LocalVariableBinding local) {
0708:                // do not want to complain in unreachable code if local declared in reachable code
0709:                if ((this .tagBits & UNREACHABLE) != 0
0710:                        && (local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0) {
0711:                    return true;
0712:                }
0713:                return isDefinitelyAssigned(local.id + this .maxFieldCount);
0714:            }
0715:
0716:            final public boolean isDefinitelyNonNull(LocalVariableBinding local) {
0717:                // do not want to complain in unreachable code
0718:                if ((this .tagBits & UNREACHABLE) != 0
0719:                        || (this .tagBits & NULL_FLAG_MASK) == 0) {
0720:                    return false;
0721:                }
0722:                if ((local.type.tagBits & TagBits.IsBaseType) != 0
0723:                        || local.constant() != Constant.NotAConstant) { // String instances
0724:                    return true;
0725:                }
0726:                int position = local.id + this .maxFieldCount;
0727:                if (position < BitCacheSize) { // use bits
0728:                    return ((this .nullBit1 & this .nullBit3 & (~this .nullBit2 | this .nullBit4)) & (1L << position)) != 0;
0729:                }
0730:                // use extra vector
0731:                if (this .extra == null) {
0732:                    return false; // if vector not yet allocated, then not initialized
0733:                }
0734:                int vectorIndex;
0735:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0736:                    return false; // if not enough room in vector, then not initialized
0737:                }
0738:                return ((this .extra[2][vectorIndex]
0739:                        & this .extra[4][vectorIndex] & (~this .extra[3][vectorIndex] | this .extra[5][vectorIndex])) & (1L << (position % BitCacheSize))) != 0;
0740:            }
0741:
0742:            final public boolean isDefinitelyNull(LocalVariableBinding local) {
0743:                // do not want to complain in unreachable code
0744:                if ((this .tagBits & UNREACHABLE) != 0
0745:                        || (this .tagBits & NULL_FLAG_MASK) == 0
0746:                        || (local.type.tagBits & TagBits.IsBaseType) != 0) {
0747:                    return false;
0748:                }
0749:                int position = local.id + this .maxFieldCount;
0750:                if (position < BitCacheSize) { // use bits
0751:                    return ((this .nullBit1 & this .nullBit2 & (~this .nullBit3 | ~this .nullBit4)) & (1L << position)) != 0;
0752:                }
0753:                // use extra vector
0754:                if (this .extra == null) {
0755:                    return false; // if vector not yet allocated, then not initialized
0756:                }
0757:                int vectorIndex;
0758:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0759:                    return false; // if not enough room in vector, then not initialized
0760:                }
0761:                return ((this .extra[2][vectorIndex]
0762:                        & this .extra[3][vectorIndex] & (~this .extra[4][vectorIndex] | ~this .extra[5][vectorIndex])) & (1L << (position % BitCacheSize))) != 0;
0763:            }
0764:
0765:            final public boolean isDefinitelyUnknown(LocalVariableBinding local) {
0766:                // do not want to complain in unreachable code
0767:                if ((this .tagBits & UNREACHABLE) != 0
0768:                        || (this .tagBits & NULL_FLAG_MASK) == 0) {
0769:                    return false;
0770:                }
0771:                int position = local.id + this .maxFieldCount;
0772:                if (position < BitCacheSize) { // use bits
0773:                    return ((this .nullBit1 & this .nullBit4 & ~this .nullBit2 & ~this .nullBit3) & (1L << position)) != 0;
0774:                }
0775:                // use extra vector
0776:                if (this .extra == null) {
0777:                    return false; // if vector not yet allocated, then not initialized
0778:                }
0779:                int vectorIndex;
0780:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0781:                    return false; // if not enough room in vector, then not initialized
0782:                }
0783:                return ((this .extra[2][vectorIndex]
0784:                        & this .extra[5][vectorIndex]
0785:                        & ~this .extra[3][vectorIndex] & ~this .extra[4][vectorIndex]) & (1L << (position % BitCacheSize))) != 0;
0786:            }
0787:
0788:            /**
0789:             * Check status of potential assignment at a given position.
0790:             */
0791:            final private boolean isPotentiallyAssigned(int position) {
0792:                // id is zero-based
0793:                if (position < BitCacheSize) {
0794:                    // use bits
0795:                    return (this .potentialInits & (1L << position)) != 0;
0796:                }
0797:                // use extra vector
0798:                if (this .extra == null) {
0799:                    return false; // if vector not yet allocated, then not initialized
0800:                }
0801:                int vectorIndex;
0802:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0803:                    return false; // if not enough room in vector, then not initialized
0804:                }
0805:                return ((this .extra[1][vectorIndex]) & (1L << (position % BitCacheSize))) != 0;
0806:            }
0807:
0808:            final public boolean isPotentiallyAssigned(FieldBinding field) {
0809:                return isPotentiallyAssigned(field.id);
0810:            }
0811:
0812:            final public boolean isPotentiallyAssigned(
0813:                    LocalVariableBinding local) {
0814:                // final constants are inlined, and thus considered as always initialized
0815:                if (local.constant() != Constant.NotAConstant) {
0816:                    return true;
0817:                }
0818:                return isPotentiallyAssigned(local.id + this .maxFieldCount);
0819:            }
0820:
0821:            final public boolean isPotentiallyNonNull(LocalVariableBinding local) {
0822:                if ((this .tagBits & NULL_FLAG_MASK) == 0
0823:                        || (local.type.tagBits & TagBits.IsBaseType) != 0) {
0824:                    return false;
0825:                }
0826:                int position;
0827:                if ((position = local.id + this .maxFieldCount) < BitCacheSize) {
0828:                    // use bits
0829:                    return ((this .nullBit3 & (~this .nullBit1 | ~this .nullBit2)) & (1L << position)) != 0;
0830:                }
0831:                // use extra vector
0832:                if (this .extra == null) {
0833:                    return false; // if vector not yet allocated, then not initialized
0834:                }
0835:                int vectorIndex;
0836:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0837:                    return false; // if not enough room in vector, then not initialized
0838:                }
0839:                return ((this .extra[4][vectorIndex] & (~this .extra[2][vectorIndex] | ~this .extra[3][vectorIndex])) & (1L << (position % BitCacheSize))) != 0;
0840:            }
0841:
0842:            final public boolean isPotentiallyNull(LocalVariableBinding local) {
0843:                if ((this .tagBits & NULL_FLAG_MASK) == 0
0844:                        || (local.type.tagBits & TagBits.IsBaseType) != 0) {
0845:                    return false;
0846:                }
0847:                int position;
0848:                if ((position = local.id + this .maxFieldCount) < BitCacheSize) {
0849:                    // use bits
0850:                    return ((this .nullBit2 & (~this .nullBit1 | ~this .nullBit3)) & (1L << position)) != 0;
0851:                }
0852:                // use extra vector
0853:                if (this .extra == null) {
0854:                    return false; // if vector not yet allocated, then not initialized
0855:                }
0856:                int vectorIndex;
0857:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0858:                    return false; // if not enough room in vector, then not initialized
0859:                }
0860:                return ((this .extra[3][vectorIndex] & (~this .extra[2][vectorIndex] | ~this .extra[4][vectorIndex])) & (1L << (position % BitCacheSize))) != 0;
0861:            }
0862:
0863:            final public boolean isPotentiallyUnknown(LocalVariableBinding local) {
0864:                // do not want to complain in unreachable code
0865:                if ((this .tagBits & UNREACHABLE) != 0
0866:                        || (this .tagBits & NULL_FLAG_MASK) == 0) {
0867:                    return false;
0868:                }
0869:                int position = local.id + this .maxFieldCount;
0870:                if (position < BitCacheSize) { // use bits
0871:                    return (this .nullBit4
0872:                            & (~this .nullBit1 | ~this .nullBit2 & ~this .nullBit3) & (1L << position)) != 0;
0873:                }
0874:                // use extra vector
0875:                if (this .extra == null) {
0876:                    return false; // if vector not yet allocated, then not initialized
0877:                }
0878:                int vectorIndex;
0879:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0880:                    return false; // if not enough room in vector, then not initialized
0881:                }
0882:                return (this .extra[5][vectorIndex]
0883:                        & (~this .extra[2][vectorIndex] | ~this .extra[3][vectorIndex]
0884:                                & ~this .extra[4][vectorIndex]) & (1L << (position % BitCacheSize))) != 0;
0885:            }
0886:
0887:            final public boolean isProtectedNonNull(LocalVariableBinding local) {
0888:                if ((this .tagBits & NULL_FLAG_MASK) == 0
0889:                        || (local.type.tagBits & TagBits.IsBaseType) != 0) {
0890:                    return false;
0891:                }
0892:                int position;
0893:                if ((position = local.id + this .maxFieldCount) < BitCacheSize) {
0894:                    // use bits
0895:                    return (this .nullBit1 & this .nullBit3 & this .nullBit4 & (1L << position)) != 0;
0896:                }
0897:                // use extra vector
0898:                if (this .extra == null) {
0899:                    return false; // if vector not yet allocated, then not initialized
0900:                }
0901:                int vectorIndex;
0902:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0903:                    return false; // if not enough room in vector, then not initialized
0904:                }
0905:                return (this .extra[2][vectorIndex] & this .extra[4][vectorIndex]
0906:                        & this .extra[5][vectorIndex] & (1L << (position % BitCacheSize))) != 0;
0907:            }
0908:
0909:            final public boolean isProtectedNull(LocalVariableBinding local) {
0910:                if ((this .tagBits & NULL_FLAG_MASK) == 0
0911:                        || (local.type.tagBits & TagBits.IsBaseType) != 0) {
0912:                    return false;
0913:                }
0914:                int position;
0915:                if ((position = local.id + this .maxFieldCount) < BitCacheSize) {
0916:                    // use bits
0917:                    return (this .nullBit1 & this .nullBit2
0918:                            & (this .nullBit3 ^ this .nullBit4) & (1L << position)) != 0;
0919:                }
0920:                // use extra vector
0921:                if (this .extra == null) {
0922:                    return false; // if vector not yet allocated, then not initialized
0923:                }
0924:                int vectorIndex;
0925:                if ((vectorIndex = (position / BitCacheSize) - 1) >= this .extra[0].length) {
0926:                    return false; // if not enough room in vector, then not initialized
0927:                }
0928:                return (this .extra[2][vectorIndex]
0929:                        & this .extra[3][vectorIndex]
0930:                        & (this .extra[4][vectorIndex] ^ this .extra[5][vectorIndex]) & (1L << (position % BitCacheSize))) != 0;
0931:            }
0932:
0933:            public void markAsComparedEqualToNonNull(LocalVariableBinding local) {
0934:                // protected from non-object locals in calling methods
0935:                if (this  != DEAD_END) {
0936:                    this .tagBits |= NULL_FLAG_MASK;
0937:                    int position;
0938:                    long mask;
0939:                    long a1, a2, a3, a4, na2;
0940:                    // position is zero-based
0941:                    if ((position = local.id + this .maxFieldCount) < BitCacheSize) {
0942:                        // use bits
0943:                        if (((mask = 1L << position) & (a1 = this .nullBit1)
0944:                                & (na2 = ~(a2 = this .nullBit2))
0945:                                & ~(a3 = this .nullBit3) & (a4 = this .nullBit4)) != 0) {
0946:                            this .nullBit4 &= ~mask;
0947:                        } else if ((mask & a1 & na2 & a3) == 0) {
0948:                            this .nullBit4 |= mask;
0949:                            if ((mask & a1) == 0) {
0950:                                if ((mask & a2 & (a3 ^ a4)) != 0) {
0951:                                    this .nullBit2 &= ~mask;
0952:                                } else if ((mask & (a2 | a3 | a4)) == 0) {
0953:                                    this .nullBit2 |= mask;
0954:                                }
0955:                            }
0956:                        }
0957:                        this .nullBit1 |= mask;
0958:                        this .nullBit3 |= mask;
0959:                        if (coverageTestFlag && coverageTestId == 15) {
0960:                            this .nullBit4 = ~0;
0961:                        }
0962:                    } else {
0963:                        // use extra vector
0964:                        int vectorIndex = (position / BitCacheSize) - 1;
0965:                        if (this .extra == null) {
0966:                            int length = vectorIndex + 1;
0967:                            this .extra = new long[extraLength][];
0968:                            for (int j = 0; j < extraLength; j++) {
0969:                                this .extra[j] = new long[length];
0970:                            }
0971:                            if (coverageTestFlag && coverageTestId == 16) {
0972:                                throw new AssertionFailedException(
0973:                                        "COVERAGE 16"); //$NON-NLS-1$
0974:                            }
0975:                        } else {
0976:                            int oldLength;
0977:                            if (vectorIndex >= (oldLength = this .extra[0].length)) {
0978:                                int newLength = vectorIndex + 1;
0979:                                for (int j = 0; j < extraLength; j++) {
0980:                                    System
0981:                                            .arraycopy(
0982:                                                    this .extra[j],
0983:                                                    0,
0984:                                                    (this .extra[j] = new long[newLength]),
0985:                                                    0, oldLength);
0986:                                }
0987:                                if (coverageTestFlag && coverageTestId == 17) {
0988:                                    throw new AssertionFailedException(
0989:                                            "COVERAGE 17"); //$NON-NLS-1$
0990:                                }
0991:                            }
0992:                        }
0993:                        // MACRO :'b,'es/nullBit\(.\)/extra[\1 + 1][vectorIndex]/gc
0994:                        if (((mask = 1L << (position % BitCacheSize))
0995:                                & (a1 = this .extra[1 + 1][vectorIndex])
0996:                                & (na2 = ~(a2 = this .extra[2 + 1][vectorIndex]))
0997:                                & ~(a3 = this .extra[3 + 1][vectorIndex]) & (a4 = this .extra[4 + 1][vectorIndex])) != 0) {
0998:                            this .extra[4 + 1][vectorIndex] &= ~mask;
0999:                        } else if ((mask & a1 & na2 & a3) == 0) {
1000:                            this .extra[4 + 1][vectorIndex] |= mask;
1001:                            if ((mask & a1) == 0) {
1002:                                if ((mask & a2 & (a3 ^ a4)) != 0) {
1003:                                    this .extra[2 + 1][vectorIndex] &= ~mask;
1004:                                } else if ((mask & (a2 | a3 | a4)) == 0) {
1005:                                    this .extra[2 + 1][vectorIndex] |= mask;
1006:                                }
1007:                            }
1008:                        }
1009:                        this .extra[1 + 1][vectorIndex] |= mask;
1010:                        this .extra[3 + 1][vectorIndex] |= mask;
1011:                        if (coverageTestFlag && coverageTestId == 18) {
1012:                            this .extra[5][vectorIndex] = ~0;
1013:                        }
1014:                    }
1015:                }
1016:            }
1017:
1018:            public void markAsComparedEqualToNull(LocalVariableBinding local) {
1019:                // protected from non-object locals in calling methods
1020:                if (this  != DEAD_END) {
1021:                    this .tagBits |= NULL_FLAG_MASK;
1022:                    int position;
1023:                    long mask;
1024:                    // position is zero-based
1025:                    if ((position = local.id + this .maxFieldCount) < BitCacheSize) {
1026:                        // use bits
1027:                        if (((mask = 1L << position) & this .nullBit1) != 0) {
1028:                            if ((mask & (~this .nullBit2 | this .nullBit3 | ~this .nullBit4)) != 0) {
1029:                                this .nullBit4 &= ~mask;
1030:                            }
1031:                        } else if ((mask & this .nullBit4) != 0) {
1032:                            this .nullBit3 &= ~mask;
1033:                        } else {
1034:                            if ((mask & this .nullBit2) != 0) {
1035:                                this .nullBit3 &= ~mask;
1036:                                this .nullBit4 |= mask;
1037:                            } else {
1038:                                this .nullBit3 |= mask;
1039:                            }
1040:                        }
1041:                        this .nullBit1 |= mask;
1042:                        this .nullBit2 |= mask;
1043:                        if (coverageTestFlag && coverageTestId == 19) {
1044:                            this .nullBit4 = ~0;
1045:                        }
1046:                    } else {
1047:                        // use extra vector
1048:                        int vectorIndex = (position / BitCacheSize) - 1;
1049:                        mask = 1L << (position % BitCacheSize);
1050:                        if (this .extra == null) {
1051:                            int length = vectorIndex + 1;
1052:                            this .extra = new long[extraLength][];
1053:                            for (int j = 0; j < extraLength; j++) {
1054:                                this .extra[j] = new long[length];
1055:                            }
1056:                            if (coverageTestFlag && coverageTestId == 20) {
1057:                                throw new AssertionFailedException(
1058:                                        "COVERAGE 20"); //$NON-NLS-1$
1059:                            }
1060:                        } else {
1061:                            int oldLength;
1062:                            if (vectorIndex >= (oldLength = this .extra[0].length)) {
1063:                                int newLength = vectorIndex + 1;
1064:                                for (int j = 0; j < extraLength; j++) {
1065:                                    System
1066:                                            .arraycopy(
1067:                                                    this .extra[j],
1068:                                                    0,
1069:                                                    (this .extra[j] = new long[newLength]),
1070:                                                    0, oldLength);
1071:                                }
1072:                                if (coverageTestFlag && coverageTestId == 21) {
1073:                                    throw new AssertionFailedException(
1074:                                            "COVERAGE 21"); //$NON-NLS-1$
1075:                                }
1076:                            }
1077:                        }
1078:                        if ((mask & this .extra[1 + 1][vectorIndex]) != 0) {
1079:                            if ((mask & (~this .extra[2 + 1][vectorIndex]
1080:                                    | this .extra[3 + 1][vectorIndex] | ~this .extra[4 + 1][vectorIndex])) != 0) {
1081:                                this .extra[4 + 1][vectorIndex] &= ~mask;
1082:                            }
1083:                        } else if ((mask & this .extra[4 + 1][vectorIndex]) != 0) {
1084:                            this .extra[3 + 1][vectorIndex] &= ~mask;
1085:                        } else {
1086:                            if ((mask & this .extra[2 + 1][vectorIndex]) != 0) {
1087:                                this .extra[3 + 1][vectorIndex] &= ~mask;
1088:                                this .extra[4 + 1][vectorIndex] |= mask;
1089:                            } else {
1090:                                this .extra[3 + 1][vectorIndex] |= mask;
1091:                            }
1092:                        }
1093:                        this .extra[1 + 1][vectorIndex] |= mask;
1094:                        this .extra[2 + 1][vectorIndex] |= mask;
1095:                    }
1096:                }
1097:            }
1098:
1099:            /**
1100:             * Record a definite assignment at a given position.
1101:             */
1102:            final private void markAsDefinitelyAssigned(int position) {
1103:
1104:                if (this  != DEAD_END) {
1105:                    // position is zero-based
1106:                    if (position < BitCacheSize) {
1107:                        // use bits
1108:                        long mask;
1109:                        this .definiteInits |= (mask = 1L << position);
1110:                        this .potentialInits |= mask;
1111:                    } else {
1112:                        // use extra vector
1113:                        int vectorIndex = (position / BitCacheSize) - 1;
1114:                        if (this .extra == null) {
1115:                            int length = vectorIndex + 1;
1116:                            this .extra = new long[extraLength][];
1117:                            for (int j = 0; j < extraLength; j++) {
1118:                                this .extra[j] = new long[length];
1119:                            }
1120:                        } else {
1121:                            int oldLength; // might need to grow the arrays
1122:                            if (vectorIndex >= (oldLength = this .extra[0].length)) {
1123:                                for (int j = 0; j < extraLength; j++) {
1124:                                    System
1125:                                            .arraycopy(
1126:                                                    this .extra[j],
1127:                                                    0,
1128:                                                    (this .extra[j] = new long[vectorIndex + 1]),
1129:                                                    0, oldLength);
1130:                                }
1131:                            }
1132:                        }
1133:                        long mask;
1134:                        this .extra[0][vectorIndex] |= (mask = 1L << (position % BitCacheSize));
1135:                        this .extra[1][vectorIndex] |= mask;
1136:                    }
1137:                }
1138:            }
1139:
1140:            public void markAsDefinitelyAssigned(FieldBinding field) {
1141:                if (this  != DEAD_END)
1142:                    markAsDefinitelyAssigned(field.id);
1143:            }
1144:
1145:            public void markAsDefinitelyAssigned(LocalVariableBinding local) {
1146:                if (this  != DEAD_END)
1147:                    markAsDefinitelyAssigned(local.id + this .maxFieldCount);
1148:            }
1149:
1150:            public void markAsDefinitelyNonNull(LocalVariableBinding local) {
1151:                // protected from non-object locals in calling methods
1152:                if (this  != DEAD_END) {
1153:                    this .tagBits |= NULL_FLAG_MASK;
1154:                    long mask;
1155:                    int position;
1156:                    // position is zero-based
1157:                    if ((position = local.id + this .maxFieldCount) < BitCacheSize) { // use bits
1158:                        // set assigned non null
1159:                        this .nullBit1 |= (mask = 1L << position);
1160:                        this .nullBit3 |= mask;
1161:                        // clear others
1162:                        this .nullBit2 &= (mask = ~mask);
1163:                        this .nullBit4 &= mask;
1164:                        if (coverageTestFlag && coverageTestId == 22) {
1165:                            this .nullBit1 = 0;
1166:                        }
1167:                    } else {
1168:                        // use extra vector
1169:                        int vectorIndex;
1170:                        this .extra[2][vectorIndex = (position / BitCacheSize) - 1] |= (mask = 1L << (position % BitCacheSize));
1171:                        this .extra[4][vectorIndex] |= mask;
1172:                        this .extra[3][vectorIndex] &= (mask = ~mask);
1173:                        this .extra[5][vectorIndex] &= mask;
1174:                        if (coverageTestFlag && coverageTestId == 23) {
1175:                            this .extra[2][vectorIndex] = 0;
1176:                        }
1177:                    }
1178:                }
1179:            }
1180:
1181:            public void markAsDefinitelyNull(LocalVariableBinding local) {
1182:                // protected from non-object locals in calling methods
1183:                if (this  != DEAD_END) {
1184:                    this .tagBits |= NULL_FLAG_MASK;
1185:                    long mask;
1186:                    int position;
1187:                    // position is zero-based
1188:                    if ((position = local.id + this .maxFieldCount) < BitCacheSize) { // use bits
1189:                        // mark assigned null
1190:                        this .nullBit1 |= (mask = 1L << position);
1191:                        this .nullBit2 |= mask;
1192:                        // clear others
1193:                        this .nullBit3 &= (mask = ~mask);
1194:                        this .nullBit4 &= mask;
1195:                        if (coverageTestFlag && coverageTestId == 24) {
1196:                            this .nullBit4 = ~0;
1197:                        }
1198:                    } else {
1199:                        // use extra vector
1200:                        int vectorIndex;
1201:                        this .extra[2][vectorIndex = (position / BitCacheSize) - 1] |= (mask = 1L << (position % BitCacheSize));
1202:                        this .extra[3][vectorIndex] |= mask;
1203:                        this .extra[4][vectorIndex] &= (mask = ~mask);
1204:                        this .extra[5][vectorIndex] &= mask;
1205:                        if (coverageTestFlag && coverageTestId == 25) {
1206:                            this .extra[5][vectorIndex] = ~0;
1207:                        }
1208:                    }
1209:                }
1210:            }
1211:
1212:            /**
1213:             * Mark a local as having been assigned to an unknown value.
1214:             * @param local the local to mark
1215:             */
1216:            // PREMATURE may try to get closer to markAsDefinitelyAssigned, but not
1217:            //			 obvious
1218:            public void markAsDefinitelyUnknown(LocalVariableBinding local) {
1219:                // protected from non-object locals in calling methods
1220:                if (this  != DEAD_END) {
1221:                    this .tagBits |= NULL_FLAG_MASK;
1222:                    long mask;
1223:                    int position;
1224:                    // position is zero-based
1225:                    if ((position = local.id + this .maxFieldCount) < BitCacheSize) {
1226:                        // use bits
1227:                        // mark assigned null
1228:                        this .nullBit1 |= (mask = 1L << position);
1229:                        this .nullBit4 |= mask;
1230:                        // clear others
1231:                        this .nullBit2 &= (mask = ~mask);
1232:                        this .nullBit3 &= mask;
1233:                        if (coverageTestFlag && coverageTestId == 26) {
1234:                            this .nullBit4 = 0;
1235:                        }
1236:                    } else {
1237:                        // use extra vector
1238:                        int vectorIndex;
1239:                        this .extra[2][vectorIndex = (position / BitCacheSize) - 1] |= (mask = 1L << (position % BitCacheSize));
1240:                        this .extra[5][vectorIndex] |= mask;
1241:                        this .extra[3][vectorIndex] &= (mask = ~mask);
1242:                        this .extra[4][vectorIndex] &= mask;
1243:                        if (coverageTestFlag && coverageTestId == 27) {
1244:                            this .extra[5][vectorIndex] = 0;
1245:                        }
1246:                    }
1247:                }
1248:            }
1249:
1250:            public UnconditionalFlowInfo mergedWith(
1251:                    UnconditionalFlowInfo otherInits) {
1252:                if ((otherInits.tagBits & UNREACHABLE) != 0 && this  != DEAD_END) {
1253:                    if (coverageTestFlag && coverageTestId == 28) {
1254:                        throw new AssertionFailedException("COVERAGE 28"); //$NON-NLS-1$
1255:                    }
1256:                    return this ;
1257:                }
1258:                if ((this .tagBits & UNREACHABLE) != 0) {
1259:                    if (coverageTestFlag && coverageTestId == 29) {
1260:                        throw new AssertionFailedException("COVERAGE 29"); //$NON-NLS-1$
1261:                    }
1262:                    return (UnconditionalFlowInfo) otherInits.copy(); // make sure otherInits won't be affected
1263:                }
1264:
1265:                // intersection of definitely assigned variables, 
1266:                this .definiteInits &= otherInits.definiteInits;
1267:                // union of potentially set ones
1268:                this .potentialInits |= otherInits.potentialInits;
1269:
1270:                // null combinations
1271:                boolean this HasNulls = (this .tagBits & NULL_FLAG_MASK) != 0, otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0, this HadNulls = this HasNulls;
1272:                long a1, a2, a3, a4, na1, na2, na3, na4, nb1, nb2, nb3, nb4, b1, b2, b3, b4;
1273:                if (this HadNulls) {
1274:                    if (otherHasNulls) {
1275:                        this .nullBit1 = (a2 = this .nullBit2)
1276:                                & (a3 = this .nullBit3)
1277:                                & (a4 = this .nullBit4)
1278:                                & (b1 = otherInits.nullBit1)
1279:                                & (nb2 = ~(b2 = otherInits.nullBit2))
1280:                                | (a1 = this .nullBit1)
1281:                                & (b1
1282:                                        & (a3
1283:                                                & a4
1284:                                                & (b3 = otherInits.nullBit3)
1285:                                                & (b4 = otherInits.nullBit4)
1286:                                                | (na2 = ~a2)
1287:                                                & nb2
1288:                                                & ((nb4 = ~b4) | (na4 = ~a4) | (na3 = ~a3)
1289:                                                        & (nb3 = ~b3)) | a2
1290:                                                & b2
1291:                                                & ((na4 | na3) & (nb4 | nb3))) | na2
1292:                                        & b2 & b3 & b4);
1293:                        this .nullBit2 = b2
1294:                                & (nb3 | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1))
1295:                                        & nb4) | a2
1296:                                & (b2 | na4 & b3 & (b4 | nb1) | na3 | na1);
1297:                        this .nullBit3 = b3
1298:                                & (nb2 & b4 | nb1 | a3 & (na4 & nb4 | a4 & b4))
1299:                                | a3 & (na2 & a4 | na1) | (a2 | na1) & b1 & nb2
1300:                                & nb4 | a1 & na2 & na4 & (b2 | nb1);
1301:                        this .nullBit4 = na3
1302:                                & (nb1 & nb3 & b4 | b1
1303:                                        & (nb2 & nb3 | a4 & b2 & nb4) | na1
1304:                                        & a4 & (nb3 | b1 & b2))
1305:                                | a3
1306:                                & a4
1307:                                & (b3 & b4 | b1 & nb2)
1308:                                | na2
1309:                                & (nb1 & b4 | b1 & nb3 | na1 & a4)
1310:                                & nb2
1311:                                | a1
1312:                                & (na3
1313:                                        & (nb3 & b4 | b1 & b2 & b3 & nb4 | na2
1314:                                                & (nb3 | nb2)) | na2 & b3 & b4 | a2
1315:                                        & (nb1 & b4 | a3 & na4 & b1) & nb3);
1316:                        if (coverageTestFlag && coverageTestId == 30) {
1317:                            this .nullBit4 = ~0;
1318:                        }
1319:                    } else { // other has no null info 
1320:                        a1 = this .nullBit1;
1321:                        this .nullBit1 = 0;
1322:                        this .nullBit2 = (a2 = this .nullBit2)
1323:                                & (na3 = ~(a3 = this .nullBit3) | (na1 = ~a1));
1324:                        this .nullBit3 = a3
1325:                                & ((na2 = ~a2) & (a4 = this .nullBit4) | na1)
1326:                                | a1 & na2 & ~a4;
1327:                        this .nullBit4 = (na3 | na2) & na1 & a4 | a1 & na3 & na2;
1328:                        if (coverageTestFlag && coverageTestId == 31) {
1329:                            this .nullBit4 = ~0;
1330:                        }
1331:                    }
1332:                } else if (otherHasNulls) { // only other had nulls
1333:                    this .nullBit1 = 0;
1334:                    this .nullBit2 = (b2 = otherInits.nullBit2)
1335:                            & (nb3 = ~(b3 = otherInits.nullBit3)
1336:                                    | (nb1 = ~(b1 = otherInits.nullBit1)));
1337:                    this .nullBit3 = b3
1338:                            & ((nb2 = ~b2) & (b4 = otherInits.nullBit4) | nb1)
1339:                            | b1 & nb2 & ~b4;
1340:                    this .nullBit4 = (nb3 | nb2) & nb1 & b4 | b1 & nb3 & nb2;
1341:                    if (coverageTestFlag && coverageTestId == 32) {
1342:                        this .nullBit4 = ~0;
1343:                    }
1344:                    this HasNulls =
1345:                    // redundant with the three following ones
1346:                    this .nullBit2 != 0 || this .nullBit3 != 0
1347:                            || this .nullBit4 != 0;
1348:                }
1349:
1350:                // treating extra storage
1351:                if (this .extra != null || otherInits.extra != null) {
1352:                    int mergeLimit = 0, copyLimit = 0, resetLimit = 0;
1353:                    int i;
1354:                    if (this .extra != null) {
1355:                        if (otherInits.extra != null) {
1356:                            // both sides have extra storage
1357:                            int length, otherLength;
1358:                            if ((length = this .extra[0].length) < (otherLength = otherInits.extra[0].length)) {
1359:                                // current storage is shorter -> grow current 
1360:                                for (int j = 0; j < extraLength; j++) {
1361:                                    System
1362:                                            .arraycopy(
1363:                                                    this .extra[j],
1364:                                                    0,
1365:                                                    (this .extra[j] = new long[otherLength]),
1366:                                                    0, length);
1367:                                }
1368:                                mergeLimit = length;
1369:                                copyLimit = otherLength;
1370:                                if (coverageTestFlag && coverageTestId == 33) {
1371:                                    throw new AssertionFailedException(
1372:                                            "COVERAGE 33"); //$NON-NLS-1$
1373:                                }
1374:                            } else {
1375:                                // current storage is longer
1376:                                mergeLimit = otherLength;
1377:                                resetLimit = length;
1378:                                if (coverageTestFlag && coverageTestId == 34) {
1379:                                    throw new AssertionFailedException(
1380:                                            "COVERAGE 34"); //$NON-NLS-1$
1381:                                }
1382:                            }
1383:                        } else {
1384:                            resetLimit = this .extra[0].length;
1385:                            if (coverageTestFlag && coverageTestId == 35) {
1386:                                throw new AssertionFailedException(
1387:                                        "COVERAGE 35"); //$NON-NLS-1$
1388:                            }
1389:                        }
1390:                    } else if (otherInits.extra != null) {
1391:                        // no storage here, but other has extra storage.
1392:                        int otherLength = otherInits.extra[0].length;
1393:                        this .extra = new long[extraLength][];
1394:                        for (int j = 0; j < extraLength; j++) {
1395:                            this .extra[j] = new long[otherLength];
1396:                        }
1397:                        System.arraycopy(otherInits.extra[1], 0, this .extra[1],
1398:                                0, otherLength);
1399:                        copyLimit = otherLength;
1400:                        if (coverageTestFlag && coverageTestId == 36) {
1401:                            throw new AssertionFailedException("COVERAGE 36"); //$NON-NLS-1$
1402:                        }
1403:                    }
1404:                    // MACRO :'b,'es/nullBit\(.\)/extra[\1 + 1][i]/g
1405:                    // manage definite assignment
1406:                    for (i = 0; i < mergeLimit; i++) {
1407:                        this .extra[0][i] &= otherInits.extra[0][i];
1408:                        this .extra[1][i] |= otherInits.extra[1][i];
1409:                    }
1410:                    for (; i < copyLimit; i++) {
1411:                        this .extra[1][i] = otherInits.extra[1][i];
1412:                    }
1413:                    for (; i < resetLimit; i++) {
1414:                        this .extra[0][i] = 0;
1415:                    }
1416:                    // refine null bits requirements
1417:                    if (!otherHasNulls) {
1418:                        if (resetLimit < mergeLimit) {
1419:                            resetLimit = mergeLimit;
1420:                        }
1421:                        copyLimit = 0; // no need to carry inexisting nulls
1422:                        mergeLimit = 0;
1423:                    }
1424:                    if (!this HadNulls) {
1425:                        resetLimit = 0; // no need to reset anything
1426:                    }
1427:                    // compose nulls
1428:                    for (i = 0; i < mergeLimit; i++) {
1429:                        this .extra[1 + 1][i] = (a2 = this .extra[2 + 1][i])
1430:                                & (a3 = this .extra[3 + 1][i])
1431:                                & (a4 = this .extra[4 + 1][i])
1432:                                & (b1 = otherInits.extra[1 + 1][i])
1433:                                & (nb2 = ~(b2 = otherInits.extra[2 + 1][i]))
1434:                                | (a1 = this .extra[1 + 1][i])
1435:                                & (b1
1436:                                        & (a3
1437:                                                & a4
1438:                                                & (b3 = otherInits.extra[3 + 1][i])
1439:                                                & (b4 = otherInits.extra[4 + 1][i])
1440:                                                | (na2 = ~a2)
1441:                                                & nb2
1442:                                                & ((nb4 = ~b4) | (na4 = ~a4) | (na3 = ~a3)
1443:                                                        & (nb3 = ~b3)) | a2
1444:                                                & b2
1445:                                                & ((na4 | na3) & (nb4 | nb3))) | na2
1446:                                        & b2 & b3 & b4);
1447:                        this .extra[2 + 1][i] = b2
1448:                                & (nb3 | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1))
1449:                                        & nb4) | a2
1450:                                & (b2 | na4 & b3 & (b4 | nb1) | na3 | na1);
1451:                        this .extra[3 + 1][i] = b3
1452:                                & (nb2 & b4 | nb1 | a3 & (na4 & nb4 | a4 & b4))
1453:                                | a3 & (na2 & a4 | na1) | (a2 | na1) & b1 & nb2
1454:                                & nb4 | a1 & na2 & na4 & (b2 | nb1);
1455:                        this .extra[4 + 1][i] = na3
1456:                                & (nb1 & nb3 & b4 | b1
1457:                                        & (nb2 & nb3 | a4 & b2 & nb4) | na1
1458:                                        & a4 & (nb3 | b1 & b2))
1459:                                | a3
1460:                                & a4
1461:                                & (b3 & b4 | b1 & nb2)
1462:                                | na2
1463:                                & (nb1 & b4 | b1 & nb3 | na1 & a4)
1464:                                & nb2
1465:                                | a1
1466:                                & (na3
1467:                                        & (nb3 & b4 | b1 & b2 & b3 & nb4 | na2
1468:                                                & (nb3 | nb2)) | na2 & b3 & b4 | a2
1469:                                        & (nb1 & b4 | a3 & na4 & b1) & nb3);
1470:                        this HasNulls = this HasNulls || this .extra[3][i] != 0
1471:                                || this .extra[4][i] != 0
1472:                                || this .extra[5][i] != 0;
1473:                        if (coverageTestFlag && coverageTestId == 37) {
1474:                            this .extra[5][i] = ~0;
1475:                        }
1476:                    }
1477:                    for (; i < copyLimit; i++) {
1478:                        this .extra[1 + 1][i] = 0;
1479:                        this .extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i])
1480:                                & (nb3 = ~(b3 = otherInits.extra[3 + 1][i])
1481:                                        | (nb1 = ~(b1 = otherInits.extra[1 + 1][i])));
1482:                        this .extra[3 + 1][i] = b3
1483:                                & ((nb2 = ~b2)
1484:                                        & (b4 = otherInits.extra[4 + 1][i]) | nb1)
1485:                                | b1 & nb2 & ~b4;
1486:                        this .extra[4 + 1][i] = (nb3 | nb2) & nb1 & b4 | b1
1487:                                & nb3 & nb2;
1488:                        this HasNulls = this HasNulls || this .extra[3][i] != 0
1489:                                || this .extra[4][i] != 0
1490:                                || this .extra[5][i] != 0;
1491:                        if (coverageTestFlag && coverageTestId == 38) {
1492:                            this .extra[5][i] = ~0;
1493:                        }
1494:                    }
1495:                    for (; i < resetLimit; i++) {
1496:                        a1 = this .extra[1 + 1][i];
1497:                        this .extra[1 + 1][i] = 0;
1498:                        this .extra[2 + 1][i] = (a2 = this .extra[2 + 1][i])
1499:                                & (na3 = ~(a3 = this .extra[3 + 1][i])
1500:                                        | (na1 = ~a1));
1501:                        this .extra[3 + 1][i] = a3
1502:                                & ((na2 = ~a2) & (a4 = this .extra[4 + 1][i]) | na1)
1503:                                | a1 & na2 & ~a4;
1504:                        this .extra[4 + 1][i] = (na3 | na2) & na1 & a4 | a1
1505:                                & na3 & na2;
1506:                        this HasNulls = this HasNulls || this .extra[3][i] != 0
1507:                                || this .extra[4][i] != 0
1508:                                || this .extra[5][i] != 0;
1509:                        if (coverageTestFlag && coverageTestId == 39) {
1510:                            this .extra[5][i] = ~0;
1511:                        }
1512:                    }
1513:                }
1514:                if (this HasNulls) {
1515:                    this .tagBits |= NULL_FLAG_MASK;
1516:                } else {
1517:                    this .tagBits &= ~NULL_FLAG_MASK;
1518:                }
1519:                return this ;
1520:            }
1521:
1522:            /*
1523:             * Answer the total number of fields in enclosing types of a given type
1524:             */
1525:            static int numberOfEnclosingFields(ReferenceBinding type) {
1526:                int count = 0;
1527:                type = type.enclosingType();
1528:                while (type != null) {
1529:                    count += type.fieldCount();
1530:                    type = type.enclosingType();
1531:                }
1532:                return count;
1533:            }
1534:
1535:            public UnconditionalFlowInfo nullInfoLessUnconditionalCopy() {
1536:                if (this  == DEAD_END) {
1537:                    return this ;
1538:                }
1539:                UnconditionalFlowInfo copy = new UnconditionalFlowInfo();
1540:                copy.definiteInits = this .definiteInits;
1541:                copy.potentialInits = this .potentialInits;
1542:                copy.tagBits = this .tagBits & ~NULL_FLAG_MASK;
1543:                copy.maxFieldCount = this .maxFieldCount;
1544:                if (this .extra != null) {
1545:                    int length;
1546:                    copy.extra = new long[extraLength][];
1547:                    System
1548:                            .arraycopy(
1549:                                    this .extra[0],
1550:                                    0,
1551:                                    (copy.extra[0] = new long[length = this .extra[0].length]),
1552:                                    0, length);
1553:                    System.arraycopy(this .extra[1], 0,
1554:                            (copy.extra[1] = new long[length]), 0, length);
1555:                    for (int j = 2; j < extraLength; j++) {
1556:                        copy.extra[j] = new long[length];
1557:                    }
1558:                }
1559:                return copy;
1560:            }
1561:
1562:            public FlowInfo safeInitsWhenTrue() {
1563:                return copy();
1564:            }
1565:
1566:            public FlowInfo setReachMode(int reachMode) {
1567:                if (reachMode == REACHABLE && this  != DEAD_END) { // cannot modify DEAD_END
1568:                    this .tagBits &= ~UNREACHABLE;
1569:                } else {
1570:                    if ((this .tagBits & UNREACHABLE) == 0) {
1571:                        // reset optional inits when becoming unreachable
1572:                        // see InitializationTest#test090 (and others)
1573:                        this .potentialInits = 0;
1574:                        if (this .extra != null) {
1575:                            for (int i = 0, length = this .extra[0].length; i < length; i++) {
1576:                                this .extra[1][i] = 0;
1577:                            }
1578:                        }
1579:                    }
1580:                    this .tagBits |= UNREACHABLE;
1581:                }
1582:                return this ;
1583:            }
1584:
1585:            public String toString() {
1586:                // PREMATURE consider printing bit fields as 0001 0001 1000 0001...
1587:                if (this  == DEAD_END) {
1588:                    return "FlowInfo.DEAD_END"; //$NON-NLS-1$
1589:                }
1590:                if ((this .tagBits & NULL_FLAG_MASK) != 0) {
1591:                    if (this .extra == null) {
1592:                        return "FlowInfo<def: " + this .definiteInits //$NON-NLS-1$
1593:                                + ", pot: " + this .potentialInits //$NON-NLS-1$
1594:                                + ", reachable:" + ((this .tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
1595:                                + ", null: " + this .nullBit1 //$NON-NLS-1$
1596:                                + this .nullBit2 + this .nullBit3 + this .nullBit4
1597:                                + ">"; //$NON-NLS-1$
1598:                    } else {
1599:                        String def = "FlowInfo<def:[" + this .definiteInits, //$NON-NLS-1$
1600:                        pot = "], pot:[" + this .potentialInits, //$NON-NLS-1$
1601:                        nullS = ", null:[" + this .nullBit1 //$NON-NLS-1$
1602:                                + this .nullBit2 + this .nullBit3 + this .nullBit4;
1603:                        int i, ceil;
1604:                        for (i = 0, ceil = this .extra[0].length > 3 ? 3
1605:                                : this .extra[0].length; i < ceil; i++) {
1606:                            def += "," + this .extra[0][i]; //$NON-NLS-1$
1607:                            pot += "," + this .extra[1][i]; //$NON-NLS-1$
1608:                            nullS += "," + this .extra[2][i] //$NON-NLS-1$
1609:                                    + this .extra[3][i] + this .extra[4][i]
1610:                                    + this .extra[5][i];
1611:                        }
1612:                        if (ceil < this .extra[0].length) {
1613:                            def += ",..."; //$NON-NLS-1$
1614:                            pot += ",..."; //$NON-NLS-1$
1615:                            nullS += ",..."; //$NON-NLS-1$
1616:                        }
1617:                        return def
1618:                                + pot
1619:                                + "], reachable:" + ((this .tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
1620:                                + nullS + "]>"; //$NON-NLS-1$
1621:                    }
1622:                } else {
1623:                    if (this .extra == null) {
1624:                        return "FlowInfo<def: " + this .definiteInits //$NON-NLS-1$
1625:                                + ", pot: " + this .potentialInits //$NON-NLS-1$
1626:                                + ", reachable:" + ((this .tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
1627:                                + ", no null info>"; //$NON-NLS-1$
1628:                    } else {
1629:                        String def = "FlowInfo<def:[" + this .definiteInits, //$NON-NLS-1$
1630:                        pot = "], pot:[" + this .potentialInits; //$NON-NLS-1$
1631:                        int i, ceil;
1632:                        for (i = 0, ceil = this .extra[0].length > 3 ? 3
1633:                                : this .extra[0].length; i < ceil; i++) {
1634:                            def += "," + this .extra[0][i]; //$NON-NLS-1$
1635:                            pot += "," + this .extra[1][i]; //$NON-NLS-1$
1636:                        }
1637:                        if (ceil < this .extra[0].length) {
1638:                            def += ",..."; //$NON-NLS-1$
1639:                            pot += ",..."; //$NON-NLS-1$
1640:                        }
1641:                        return def
1642:                                + pot
1643:                                + "], reachable:" + ((this .tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
1644:                                + ", no null info>"; //$NON-NLS-1$
1645:                    }
1646:                }
1647:            }
1648:
1649:            public UnconditionalFlowInfo unconditionalCopy() {
1650:                return (UnconditionalFlowInfo) copy();
1651:            }
1652:
1653:            public UnconditionalFlowInfo unconditionalFieldLessCopy() {
1654:                // TODO (maxime) may consider leveraging null contribution verification as it is done in copy
1655:                UnconditionalFlowInfo copy = new UnconditionalFlowInfo();
1656:                copy.tagBits = this .tagBits;
1657:                copy.maxFieldCount = this .maxFieldCount;
1658:                int limit = this .maxFieldCount;
1659:                if (limit < BitCacheSize) {
1660:                    long mask;
1661:                    copy.definiteInits = this .definiteInits
1662:                            & (mask = ~((1L << limit) - 1));
1663:                    copy.potentialInits = this .potentialInits & mask;
1664:                    copy.nullBit1 = this .nullBit1 & mask;
1665:                    copy.nullBit2 = this .nullBit2 & mask;
1666:                    copy.nullBit3 = this .nullBit3 & mask;
1667:                    copy.nullBit4 = this .nullBit4 & mask;
1668:                }
1669:                // use extra vector
1670:                if (this .extra == null) {
1671:                    return copy; // if vector not yet allocated, then not initialized
1672:                }
1673:                int vectorIndex, length, copyStart;
1674:                if ((vectorIndex = (limit / BitCacheSize) - 1) >= (length = this .extra[0].length)) {
1675:                    return copy; // not enough room yet
1676:                }
1677:                long mask;
1678:                copy.extra = new long[extraLength][];
1679:                if ((copyStart = vectorIndex + 1) < length) {
1680:                    int copyLength = length - copyStart;
1681:                    for (int j = 0; j < extraLength; j++) {
1682:                        System.arraycopy(this .extra[j], copyStart,
1683:                                (copy.extra[j] = new long[length]), copyStart,
1684:                                copyLength);
1685:                    }
1686:                } else if (vectorIndex >= 0) {
1687:                    for (int j = 0; j < extraLength; j++) {
1688:                        copy.extra[j] = new long[length];
1689:                    }
1690:                }
1691:                if (vectorIndex >= 0) {
1692:                    mask = ~((1L << (limit % BitCacheSize)) - 1);
1693:                    for (int j = 0; j < extraLength; j++) {
1694:                        copy.extra[j][vectorIndex] = this .extra[j][vectorIndex]
1695:                                & mask;
1696:                    }
1697:                }
1698:                return copy;
1699:            }
1700:
1701:            public UnconditionalFlowInfo unconditionalInits() {
1702:                // also see conditional inits, where it requests them to merge
1703:                return this ;
1704:            }
1705:
1706:            public UnconditionalFlowInfo unconditionalInitsWithoutSideEffect() {
1707:                return this;
1708:            }
1709:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.