public void finaliseBands()

in modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java [279:463]


    public void finaliseBands() {
        int defaultMajorVersion = segmentHeader.getDefaultMajorVersion();
        for (int i = 0; i < class_flags.length; i++) {
            int major = major_versions[i];
            if (major != defaultMajorVersion) {
                class_flags[i] |= 1 << 24;
                classFileVersionMajor.add(major);
                classFileVersionMinor.add(0);
            }
        }
        // Calculate code headers
        codeHeaders = new int[codeHandlerCount.size()];
        int removed = 0;
        for (int i = 0; i < codeHeaders.length; i++) {
            int numHandlers = codeHandlerCount.get(i - removed);
            int maxLocals = codeMaxLocals.get(i - removed);
            int maxStack = codeMaxStack.get(i - removed);
            if (numHandlers == 0) {
                int header = maxLocals * 12 + maxStack + 1;
                if (header < 145 && maxStack < 12) {
                    codeHeaders[i] = header;
                }
            } else if (numHandlers == 1) {
                int header = maxLocals * 8 + maxStack + 145;
                if (header < 209 && maxStack < 8) {
                    codeHeaders[i] = header;
                }
            } else if (numHandlers == 2) {
                int header = maxLocals * 7 + maxStack + 209;
                if (header < 256 && maxStack < 7) {
                    codeHeaders[i] = header;
                }
            }
            if (codeHeaders[i] != 0) { // Remove the redundant values from
                                        // codeHandlerCount, codeMaxLocals and
                                        // codeMaxStack
                codeHandlerCount.remove(i - removed);
                codeMaxLocals.remove(i - removed);
                codeMaxStack.remove(i - removed);
                removed++;
            } else if (!segment.getSegmentHeader().have_all_code_flags()) {
                codeFlags.add(new Long(0));
            }
        }

        // Compute any required IcLocals
        IntList innerClassesN = new IntList();
        List icLocal = new ArrayList();
        for (int i = 0; i < class_this.length; i++) {
            CPClass cpClass = class_this[i];
            Set referencedInnerClasses = (Set) classReferencesInnerClass.get(cpClass);
            if(referencedInnerClasses != null) {
                int innerN = 0;
                List innerClasses = segment.getIcBands().getInnerClassesForOuter(cpClass.toString());
                if(innerClasses != null) {
                    for (Iterator iterator2 = innerClasses.iterator(); iterator2
                            .hasNext();) {
                        referencedInnerClasses.remove(((IcTuple)iterator2.next()).C);
                    }
                }
                for (Iterator iterator2 = referencedInnerClasses.iterator(); iterator2
                        .hasNext();) {
                    CPClass inner = (CPClass) iterator2.next();
                    IcTuple icTuple = segment.getIcBands().getIcTuple(inner);
                    if(icTuple != null && ! icTuple.isAnonymous()) {
                        // should transmit an icLocal entry
                        icLocal.add(icTuple);
                        innerN++;
                    }
                }
                if(innerN != 0) {
                    innerClassesN.add(innerN);
                    class_flags[i] |= (1 << 23);
                }
            }
        }
        class_InnerClasses_N = innerClassesN.toArray();
        class_InnerClasses_RC = new CPClass[icLocal.size()];
        class_InnerClasses_F = new int[icLocal.size()];
        classInnerClassesOuterRCN = new ArrayList();
        classInnerClassesNameRUN = new ArrayList();
        for (int i = 0; i < class_InnerClasses_RC.length; i++) {
            IcTuple icTuple = (IcTuple) icLocal.get(i);
            class_InnerClasses_RC[i] = (icTuple.C);
            if(icTuple.C2 == null && icTuple.N == null) {
                class_InnerClasses_F[i] = 0;
            } else {
                if (icTuple.F == 0) {
                    class_InnerClasses_F[i] = 0x00010000;
                } else {
                    class_InnerClasses_F[i] = icTuple.F;
                }
                classInnerClassesOuterRCN.add(icTuple.C2);
                classInnerClassesNameRUN.add(icTuple.N);
            }
        }
        // Calculate any backwards calls from metadata bands
        IntList classAttrCalls = new IntList();
        IntList fieldAttrCalls = new IntList();
        IntList methodAttrCalls = new IntList();
        IntList codeAttrCalls = new IntList();

        if(class_RVA_bands.hasContent()) {
            classAttrCalls.add(class_RVA_bands.numBackwardsCalls());
        }
        if(class_RIA_bands.hasContent()) {
            classAttrCalls.add(class_RIA_bands.numBackwardsCalls());
        }
        if(field_RVA_bands.hasContent()) {
            fieldAttrCalls.add(field_RVA_bands.numBackwardsCalls());
        }
        if(field_RIA_bands.hasContent()) {
            fieldAttrCalls.add(field_RIA_bands.numBackwardsCalls());
        }
        if(method_RVA_bands.hasContent()) {
            methodAttrCalls.add(method_RVA_bands.numBackwardsCalls());
        }
        if(method_RIA_bands.hasContent()) {
            methodAttrCalls.add(method_RIA_bands.numBackwardsCalls());
        }
        if(method_RVPA_bands.hasContent()) {
            methodAttrCalls.add(method_RVPA_bands.numBackwardsCalls());
        }
        if(method_RIPA_bands.hasContent()) {
            methodAttrCalls.add(method_RIPA_bands.numBackwardsCalls());
        }
        if(method_AD_bands.hasContent()) {
            methodAttrCalls.add(method_AD_bands.numBackwardsCalls());
        }

        // Sort non-predefined attribute bands
        Comparator comparator = new Comparator() {
            public int compare(Object arg0, Object arg1) {
                NewAttributeBands bands0 = (NewAttributeBands)arg0;
                NewAttributeBands bands1 = (NewAttributeBands)arg1;
                return bands0.getFlagIndex() - bands1.getFlagIndex();
            }
        };
        Collections.sort(classAttributeBands, comparator);
        Collections.sort(methodAttributeBands, comparator);
        Collections.sort(fieldAttributeBands, comparator);
        Collections.sort(codeAttributeBands, comparator);

        for (Iterator iterator = classAttributeBands.iterator(); iterator.hasNext();) {
            NewAttributeBands bands = (NewAttributeBands) iterator.next();
            if(bands.isUsedAtLeastOnce()) {
                int[] backwardsCallCounts = bands.numBackwardsCalls();
                for (int i = 0; i < backwardsCallCounts.length; i++) {
                    classAttrCalls.add(backwardsCallCounts[i]);
                }
            }
        }
        for (Iterator iterator = methodAttributeBands.iterator(); iterator.hasNext();) {
            NewAttributeBands bands = (NewAttributeBands) iterator.next();
            if(bands.isUsedAtLeastOnce()) {
                int[] backwardsCallCounts = bands.numBackwardsCalls();
                for (int i = 0; i < backwardsCallCounts.length; i++) {
                    methodAttrCalls.add(backwardsCallCounts[i]);
                }
            }
        }
        for (Iterator iterator = fieldAttributeBands.iterator(); iterator.hasNext();) {
            NewAttributeBands bands = (NewAttributeBands) iterator.next();
            if(bands.isUsedAtLeastOnce()) {
                int[] backwardsCallCounts = bands.numBackwardsCalls();
                for (int i = 0; i < backwardsCallCounts.length; i++) {
                    fieldAttrCalls.add(backwardsCallCounts[i]);
                }
            }
        }
        for (Iterator iterator = codeAttributeBands.iterator(); iterator.hasNext();) {
            NewAttributeBands bands = (NewAttributeBands) iterator.next();
            if(bands.isUsedAtLeastOnce()) {
                int[] backwardsCallCounts = bands.numBackwardsCalls();
                for (int i = 0; i < backwardsCallCounts.length; i++) {
                    codeAttrCalls.add(backwardsCallCounts[i]);
                }
            }
        }

        class_attr_calls = classAttrCalls.toArray();
        field_attr_calls = fieldAttrCalls.toArray();
        method_attr_calls = methodAttrCalls.toArray();
        code_attr_calls = codeAttrCalls.toArray();
    }