441 // Because a typical delta usees much less data than a byte, the savings after
442 // zipping is even better: A zipped delta-encoded package is 8% smaller than
443 // a zipped non-delta-encoded package. Thus, in the zipped file, a banded,
444 // delta-encoded constant pool saves over 11% (of the total file size) compared
445 // with a zipped unbanded file.
446
447 void writeConstantPool() throws IOException {
448 IndexGroup cp = pkg.cp;
449
450 if (verbose > 0) Utils.log.info("Writing CP");
451
452 for (int k = 0; k < ConstantPool.TAGS_IN_ORDER.length; k++) {
453 byte tag = ConstantPool.TAGS_IN_ORDER[k];
454 Index index = cp.getIndexByTag(tag);
455
456 Entry[] cpMap = index.cpMap;
457 if (verbose > 0)
458 Utils.log.info("Writing "+cpMap.length+" "+ConstantPool.tagName(tag)+" entries...");
459
460 if (optDumpBands) {
461 PrintStream ps = new PrintStream(getDumpStream(index, ".idx"));
462 printArrayTo(ps, cpMap, 0, cpMap.length);
463 ps.close();
464 }
465
466 switch (tag) {
467 case CONSTANT_Utf8:
468 writeUtf8Bands(cpMap);
469 break;
470 case CONSTANT_Integer:
471 for (int i = 0; i < cpMap.length; i++) {
472 NumberEntry e = (NumberEntry) cpMap[i];
473 int x = ((Integer)e.numberValue()).intValue();
474 cp_Int.putInt(x);
475 }
476 break;
477 case CONSTANT_Float:
478 for (int i = 0; i < cpMap.length; i++) {
479 NumberEntry e = (NumberEntry) cpMap[i];
480 float fx = ((Float)e.numberValue()).floatValue();
481 int x = Float.floatToIntBits(fx);
482 cp_Float.putInt(x);
483 }
906 int numAttrDefs = defList.size();
907 Object[][] defs = new Object[numAttrDefs][];
908 defList.toArray(defs);
909 Arrays.sort(defs, new Comparator() {
910 public int compare(Object o0, Object o1) {
911 Object[] a0 = (Object[]) o0;
912 Object[] a1 = (Object[]) o1;
913 // Primary sort key is attr def header.
914 int r = ((Comparable)a0[0]).compareTo(a1[0]);
915 if (r != 0) return r;
916 Object ind0 = attrIndexTable.get(a0[1]);
917 Object ind1 = attrIndexTable.get(a1[1]);
918 // Secondary sort key is attribute index.
919 // (This must be so, in order to keep overflow attr order.)
920 assert(ind0 != null);
921 assert(ind1 != null);
922 return ((Comparable)ind0).compareTo(ind1);
923 }
924 });
925 attrDefsWritten = new Attribute.Layout[numAttrDefs];
926 PrintStream dump = !optDumpBands ? null
927 : new PrintStream(getDumpStream(attr_definition_headers, ".def"));
928 int[] indexForDebug = Arrays.copyOf(attrIndexLimit, ATTR_CONTEXT_LIMIT);
929 for (int i = 0; i < defs.length; i++) {
930 int header = ((Integer)defs[i][0]).intValue();
931 Attribute.Layout def = (Attribute.Layout) defs[i][1];
932 attrDefsWritten[i] = def;
933 assert((header & ADH_CONTEXT_MASK) == def.ctype());
934 attr_definition_headers.putByte(header);
935 attr_definition_name.putRef(ConstantPool.getUtf8Entry(def.name()));
936 String layout = def.layoutForPackageMajver(getPackageMajver());
937 attr_definition_layout.putRef(ConstantPool.getUtf8Entry(layout));
938 // Check that we are transmitting that correct attribute index:
939 boolean debug = false;
940 assert(debug = true);
941 if (debug) {
942 int hdrIndex = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
943 if (hdrIndex < 0) hdrIndex = indexForDebug[def.ctype()]++;
944 int realIndex = (attrIndexTable.get(def)).intValue();
945 assert(hdrIndex == realIndex);
946 }
947 if (dump != null) {
948 int index = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
949 dump.println(index+" "+def);
950 }
951 }
952 if (dump != null) dump.close();
953 }
954
955 void writeAttrCounts() throws IOException {
956 // Write the four xxx_attr_calls bands.
957 for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
958 MultiBand xxx_attr_bands = attrBands[ctype];
959 IntBand xxx_attr_calls = getAttrBand(xxx_attr_bands, AB_ATTR_CALLS);
960 Attribute.Layout[] defs = new Attribute.Layout[attrDefs.get(ctype).size()];
961 attrDefs.get(ctype).toArray(defs);
962 for (boolean predef = true; ; predef = false) {
963 for (int ai = 0; ai < defs.length; ai++) {
964 Attribute.Layout def = defs[ai];
965 if (def == null) continue; // unused index
966 if (predef != isPredefinedAttr(ctype, ai))
967 continue; // wrong pass
968 int totalCount = attrCounts[ctype][ai];
969 if (totalCount == 0)
970 continue; // irrelevant
971 int[] bc = backCountTable.get(def);
972 for (int j = 0; j < bc.length; j++) {
|
441 // Because a typical delta usees much less data than a byte, the savings after
442 // zipping is even better: A zipped delta-encoded package is 8% smaller than
443 // a zipped non-delta-encoded package. Thus, in the zipped file, a banded,
444 // delta-encoded constant pool saves over 11% (of the total file size) compared
445 // with a zipped unbanded file.
446
447 void writeConstantPool() throws IOException {
448 IndexGroup cp = pkg.cp;
449
450 if (verbose > 0) Utils.log.info("Writing CP");
451
452 for (int k = 0; k < ConstantPool.TAGS_IN_ORDER.length; k++) {
453 byte tag = ConstantPool.TAGS_IN_ORDER[k];
454 Index index = cp.getIndexByTag(tag);
455
456 Entry[] cpMap = index.cpMap;
457 if (verbose > 0)
458 Utils.log.info("Writing "+cpMap.length+" "+ConstantPool.tagName(tag)+" entries...");
459
460 if (optDumpBands) {
461 try (PrintStream ps = new PrintStream(getDumpStream(index, ".idx"))) {
462 printArrayTo(ps, cpMap, 0, cpMap.length);
463 }
464 }
465
466 switch (tag) {
467 case CONSTANT_Utf8:
468 writeUtf8Bands(cpMap);
469 break;
470 case CONSTANT_Integer:
471 for (int i = 0; i < cpMap.length; i++) {
472 NumberEntry e = (NumberEntry) cpMap[i];
473 int x = ((Integer)e.numberValue()).intValue();
474 cp_Int.putInt(x);
475 }
476 break;
477 case CONSTANT_Float:
478 for (int i = 0; i < cpMap.length; i++) {
479 NumberEntry e = (NumberEntry) cpMap[i];
480 float fx = ((Float)e.numberValue()).floatValue();
481 int x = Float.floatToIntBits(fx);
482 cp_Float.putInt(x);
483 }
906 int numAttrDefs = defList.size();
907 Object[][] defs = new Object[numAttrDefs][];
908 defList.toArray(defs);
909 Arrays.sort(defs, new Comparator() {
910 public int compare(Object o0, Object o1) {
911 Object[] a0 = (Object[]) o0;
912 Object[] a1 = (Object[]) o1;
913 // Primary sort key is attr def header.
914 int r = ((Comparable)a0[0]).compareTo(a1[0]);
915 if (r != 0) return r;
916 Object ind0 = attrIndexTable.get(a0[1]);
917 Object ind1 = attrIndexTable.get(a1[1]);
918 // Secondary sort key is attribute index.
919 // (This must be so, in order to keep overflow attr order.)
920 assert(ind0 != null);
921 assert(ind1 != null);
922 return ((Comparable)ind0).compareTo(ind1);
923 }
924 });
925 attrDefsWritten = new Attribute.Layout[numAttrDefs];
926 try (PrintStream dump = !optDumpBands ? null
927 : new PrintStream(getDumpStream(attr_definition_headers, ".def")))
928 {
929 int[] indexForDebug = Arrays.copyOf(attrIndexLimit, ATTR_CONTEXT_LIMIT);
930 for (int i = 0; i < defs.length; i++) {
931 int header = ((Integer)defs[i][0]).intValue();
932 Attribute.Layout def = (Attribute.Layout) defs[i][1];
933 attrDefsWritten[i] = def;
934 assert((header & ADH_CONTEXT_MASK) == def.ctype());
935 attr_definition_headers.putByte(header);
936 attr_definition_name.putRef(ConstantPool.getUtf8Entry(def.name()));
937 String layout = def.layoutForPackageMajver(getPackageMajver());
938 attr_definition_layout.putRef(ConstantPool.getUtf8Entry(layout));
939 // Check that we are transmitting that correct attribute index:
940 boolean debug = false;
941 assert(debug = true);
942 if (debug) {
943 int hdrIndex = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
944 if (hdrIndex < 0) hdrIndex = indexForDebug[def.ctype()]++;
945 int realIndex = (attrIndexTable.get(def)).intValue();
946 assert(hdrIndex == realIndex);
947 }
948 if (dump != null) {
949 int index = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
950 dump.println(index+" "+def);
951 }
952 }
953 } // TODO TWR: relies on new null handling behavior of TWR close()
954 }
955
956 void writeAttrCounts() throws IOException {
957 // Write the four xxx_attr_calls bands.
958 for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
959 MultiBand xxx_attr_bands = attrBands[ctype];
960 IntBand xxx_attr_calls = getAttrBand(xxx_attr_bands, AB_ATTR_CALLS);
961 Attribute.Layout[] defs = new Attribute.Layout[attrDefs.get(ctype).size()];
962 attrDefs.get(ctype).toArray(defs);
963 for (boolean predef = true; ; predef = false) {
964 for (int ai = 0; ai < defs.length; ai++) {
965 Attribute.Layout def = defs[ai];
966 if (def == null) continue; // unused index
967 if (predef != isPredefinedAttr(ctype, ai))
968 continue; // wrong pass
969 int totalCount = attrCounts[ctype][ai];
970 if (totalCount == 0)
971 continue; // irrelevant
972 int[] bc = backCountTable.get(def);
973 for (int j = 0; j < bc.length; j++) {
|