812 long len = file.getFileLength();
813 file_size_lo.putInt((int)len);
814 if (haveSizeHi)
815 file_size_hi.putInt((int)(len >>> 32));
816 if (haveModtime)
817 file_modtime.putInt(file.modtime - pkg.default_modtime);
818 if (haveOptions)
819 file_options.putInt(file.options);
820 file.writeTo(file_bits.collectorStream());
821 if (verbose > 1)
822 Utils.log.fine("Wrote "+len+" bytes of "+file.name.stringValue());
823 }
824 if (verbose > 0)
825 Utils.log.info("Wrote "+numFiles+" resource files");
826 }
827
828 void collectAttributeLayouts() {
829 maxFlags = new int[ATTR_CONTEXT_LIMIT];
830 allLayouts = new FixedList<>(ATTR_CONTEXT_LIMIT);
831 for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
832 allLayouts.set(i, new HashMap<Attribute.Layout, int[]>());
833 }
834 // Collect maxFlags and allLayouts.
835 for (Class cls : pkg.classes) {
836 visitAttributeLayoutsIn(ATTR_CONTEXT_CLASS, cls);
837 for (Class.Field f : cls.getFields()) {
838 visitAttributeLayoutsIn(ATTR_CONTEXT_FIELD, f);
839 }
840 for (Class.Method m : cls.getMethods()) {
841 visitAttributeLayoutsIn(ATTR_CONTEXT_METHOD, m);
842 if (m.code != null) {
843 visitAttributeLayoutsIn(ATTR_CONTEXT_CODE, m.code);
844 }
845 }
846 }
847 // If there are many species of attributes, use 63-bit flags.
848 for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
849 int nl = allLayouts.get(i).size();
850 boolean haveLongFlags = haveFlagsHi(i);
851 final int TOO_MANY_ATTRS = 32 /*int flag size*/
852 - 12 /*typical flag bits in use*/
875 backCountTable = new HashMap<>();
876 attrCounts = new int[ATTR_CONTEXT_LIMIT][];
877 for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
878 // Now the remaining defs in allLayouts[i] need attr. indexes.
879 // Fill up unused flag bits with new defs.
880 // Unused bits are those which are not used by predefined attrs,
881 // and which are always clear in the classfiles.
882 long avHiBits = ~(maxFlags[i] | attrFlagMask[i]);
883 assert(attrIndexLimit[i] > 0);
884 assert(attrIndexLimit[i] < 64); // all bits fit into a Java long
885 avHiBits &= (1L<<attrIndexLimit[i])-1;
886 int nextLoBit = 0;
887 Map<Attribute.Layout, int[]> defMap = allLayouts.get(i);
888 @SuppressWarnings({"unchecked", "rawtypes"})
889 Map.Entry<Attribute.Layout, int[]>[] layoutsAndCounts =
890 new Map.Entry[defMap.size()];
891 defMap.entrySet().toArray(layoutsAndCounts);
892 // Sort by count, most frequent first.
893 // Predefs. participate in this sort, though it does not matter.
894 Arrays.sort(layoutsAndCounts,
895 new Comparator<Map.Entry<Attribute.Layout, int[]>>() {
896 public int compare(Map.Entry<Attribute.Layout, int[]> e0,
897 Map.Entry<Attribute.Layout, int[]> e1) {
898 // Primary sort key is count, reversed.
899 int r = -(e0.getValue()[0] - e1.getValue()[0]);
900 if (r != 0) return r;
901 return e0.getKey().compareTo(e1.getKey());
902 }
903 });
904 attrCounts[i] = new int[attrIndexLimit[i]+layoutsAndCounts.length];
905 for (int j = 0; j < layoutsAndCounts.length; j++) {
906 Map.Entry<Attribute.Layout, int[]> e = layoutsAndCounts[j];
907 Attribute.Layout def = e.getKey();
908 int count = e.getValue()[0];
909 int index;
910 Integer predefIndex = attrIndexTable.get(def);
911 if (predefIndex != null) {
912 // The index is already set.
913 index = predefIndex.intValue();
914 } else if (avHiBits != 0) {
915 while ((avHiBits & 1) == 0) {
993 for (int j = 0; j < limit; j++) {
994 int header = i; // ctype
995 if (j < attrIndexLimit[i]) {
996 header |= ((j + ADH_BIT_IS_LSB) << ADH_BIT_SHIFT);
997 assert(header < 0x100); // must fit into a byte
998 // (...else header is simply ctype, with zero high bits.)
999 if (!testBit(attrDefSeen[i], 1L<<j)) {
1000 // either undefined or predefined; nothing to write
1001 continue;
1002 }
1003 }
1004 Attribute.Layout def = attrDefs.get(i).get(j);
1005 defList.add(new Object[]{ Integer.valueOf(header), def });
1006 assert(Integer.valueOf(j).equals(attrIndexTable.get(def)));
1007 }
1008 }
1009 // Sort the new attr defs into some "natural" order.
1010 int numAttrDefs = defList.size();
1011 Object[][] defs = new Object[numAttrDefs][];
1012 defList.toArray(defs);
1013 Arrays.sort(defs, new Comparator<Object[]>() {
1014 public int compare(Object[] a0, Object[] a1) {
1015 // Primary sort key is attr def header.
1016 @SuppressWarnings("unchecked")
1017 int r = ((Comparable)a0[0]).compareTo(a1[0]);
1018 if (r != 0) return r;
1019 Integer ind0 = attrIndexTable.get(a0[1]);
1020 Integer ind1 = attrIndexTable.get(a1[1]);
1021 // Secondary sort key is attribute index.
1022 // (This must be so, in order to keep overflow attr order.)
1023 assert(ind0 != null);
1024 assert(ind1 != null);
1025 return ind0.compareTo(ind1);
1026 }
1027 });
1028 attrDefsWritten = new Attribute.Layout[numAttrDefs];
1029 try (PrintStream dump = !optDumpBands ? null
1030 : new PrintStream(getDumpStream(attr_definition_headers, ".def")))
1031 {
1032 int[] indexForDebug = Arrays.copyOf(attrIndexLimit, ATTR_CONTEXT_LIMIT);
1033 for (int i = 0; i < defs.length; i++) {
|
812 long len = file.getFileLength();
813 file_size_lo.putInt((int)len);
814 if (haveSizeHi)
815 file_size_hi.putInt((int)(len >>> 32));
816 if (haveModtime)
817 file_modtime.putInt(file.modtime - pkg.default_modtime);
818 if (haveOptions)
819 file_options.putInt(file.options);
820 file.writeTo(file_bits.collectorStream());
821 if (verbose > 1)
822 Utils.log.fine("Wrote "+len+" bytes of "+file.name.stringValue());
823 }
824 if (verbose > 0)
825 Utils.log.info("Wrote "+numFiles+" resource files");
826 }
827
828 void collectAttributeLayouts() {
829 maxFlags = new int[ATTR_CONTEXT_LIMIT];
830 allLayouts = new FixedList<>(ATTR_CONTEXT_LIMIT);
831 for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
832 allLayouts.set(i, new HashMap<>());
833 }
834 // Collect maxFlags and allLayouts.
835 for (Class cls : pkg.classes) {
836 visitAttributeLayoutsIn(ATTR_CONTEXT_CLASS, cls);
837 for (Class.Field f : cls.getFields()) {
838 visitAttributeLayoutsIn(ATTR_CONTEXT_FIELD, f);
839 }
840 for (Class.Method m : cls.getMethods()) {
841 visitAttributeLayoutsIn(ATTR_CONTEXT_METHOD, m);
842 if (m.code != null) {
843 visitAttributeLayoutsIn(ATTR_CONTEXT_CODE, m.code);
844 }
845 }
846 }
847 // If there are many species of attributes, use 63-bit flags.
848 for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
849 int nl = allLayouts.get(i).size();
850 boolean haveLongFlags = haveFlagsHi(i);
851 final int TOO_MANY_ATTRS = 32 /*int flag size*/
852 - 12 /*typical flag bits in use*/
875 backCountTable = new HashMap<>();
876 attrCounts = new int[ATTR_CONTEXT_LIMIT][];
877 for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
878 // Now the remaining defs in allLayouts[i] need attr. indexes.
879 // Fill up unused flag bits with new defs.
880 // Unused bits are those which are not used by predefined attrs,
881 // and which are always clear in the classfiles.
882 long avHiBits = ~(maxFlags[i] | attrFlagMask[i]);
883 assert(attrIndexLimit[i] > 0);
884 assert(attrIndexLimit[i] < 64); // all bits fit into a Java long
885 avHiBits &= (1L<<attrIndexLimit[i])-1;
886 int nextLoBit = 0;
887 Map<Attribute.Layout, int[]> defMap = allLayouts.get(i);
888 @SuppressWarnings({"unchecked", "rawtypes"})
889 Map.Entry<Attribute.Layout, int[]>[] layoutsAndCounts =
890 new Map.Entry[defMap.size()];
891 defMap.entrySet().toArray(layoutsAndCounts);
892 // Sort by count, most frequent first.
893 // Predefs. participate in this sort, though it does not matter.
894 Arrays.sort(layoutsAndCounts,
895 new Comparator<>() {
896 public int compare(Map.Entry<Attribute.Layout, int[]> e0,
897 Map.Entry<Attribute.Layout, int[]> e1) {
898 // Primary sort key is count, reversed.
899 int r = -(e0.getValue()[0] - e1.getValue()[0]);
900 if (r != 0) return r;
901 return e0.getKey().compareTo(e1.getKey());
902 }
903 });
904 attrCounts[i] = new int[attrIndexLimit[i]+layoutsAndCounts.length];
905 for (int j = 0; j < layoutsAndCounts.length; j++) {
906 Map.Entry<Attribute.Layout, int[]> e = layoutsAndCounts[j];
907 Attribute.Layout def = e.getKey();
908 int count = e.getValue()[0];
909 int index;
910 Integer predefIndex = attrIndexTable.get(def);
911 if (predefIndex != null) {
912 // The index is already set.
913 index = predefIndex.intValue();
914 } else if (avHiBits != 0) {
915 while ((avHiBits & 1) == 0) {
993 for (int j = 0; j < limit; j++) {
994 int header = i; // ctype
995 if (j < attrIndexLimit[i]) {
996 header |= ((j + ADH_BIT_IS_LSB) << ADH_BIT_SHIFT);
997 assert(header < 0x100); // must fit into a byte
998 // (...else header is simply ctype, with zero high bits.)
999 if (!testBit(attrDefSeen[i], 1L<<j)) {
1000 // either undefined or predefined; nothing to write
1001 continue;
1002 }
1003 }
1004 Attribute.Layout def = attrDefs.get(i).get(j);
1005 defList.add(new Object[]{ Integer.valueOf(header), def });
1006 assert(Integer.valueOf(j).equals(attrIndexTable.get(def)));
1007 }
1008 }
1009 // Sort the new attr defs into some "natural" order.
1010 int numAttrDefs = defList.size();
1011 Object[][] defs = new Object[numAttrDefs][];
1012 defList.toArray(defs);
1013 Arrays.sort(defs, new Comparator<>() {
1014 public int compare(Object[] a0, Object[] a1) {
1015 // Primary sort key is attr def header.
1016 @SuppressWarnings("unchecked")
1017 int r = ((Comparable)a0[0]).compareTo(a1[0]);
1018 if (r != 0) return r;
1019 Integer ind0 = attrIndexTable.get(a0[1]);
1020 Integer ind1 = attrIndexTable.get(a1[1]);
1021 // Secondary sort key is attribute index.
1022 // (This must be so, in order to keep overflow attr order.)
1023 assert(ind0 != null);
1024 assert(ind1 != null);
1025 return ind0.compareTo(ind1);
1026 }
1027 });
1028 attrDefsWritten = new Attribute.Layout[numAttrDefs];
1029 try (PrintStream dump = !optDumpBands ? null
1030 : new PrintStream(getDumpStream(attr_definition_headers, ".def")))
1031 {
1032 int[] indexForDebug = Arrays.copyOf(attrIndexLimit, ATTR_CONTEXT_LIMIT);
1033 for (int i = 0; i < defs.length; i++) {
|