jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java
changeset 7795 98021fc612af
parent 7192 445c518364c4
child 7816 55a18147b4bf
equal deleted inserted replaced
7551:dc77388d186a 7795:98021fc612af
     1 /*
     1 /*
     2  * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    30 import com.sun.java.util.jar.pack.ConstantPool.Entry;
    30 import com.sun.java.util.jar.pack.ConstantPool.Entry;
    31 import com.sun.java.util.jar.pack.ConstantPool.Index;
    31 import com.sun.java.util.jar.pack.ConstantPool.Index;
    32 import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
    32 import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
    33 import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
    33 import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
    34 import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
    34 import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
    35 import java.io.*;
       
    36 import java.util.*;
       
    37 import com.sun.java.util.jar.pack.Package.Class;
    35 import com.sun.java.util.jar.pack.Package.Class;
    38 import com.sun.java.util.jar.pack.Package.File;
    36 import com.sun.java.util.jar.pack.Package.File;
    39 import com.sun.java.util.jar.pack.Package.InnerClass;
    37 import com.sun.java.util.jar.pack.Package.InnerClass;
       
    38 import java.io.ByteArrayOutputStream;
       
    39 import java.io.EOFException;
       
    40 import java.io.PrintStream;
       
    41 import java.io.FilterInputStream;
       
    42 import java.io.BufferedInputStream;
       
    43 import java.io.InputStream;
       
    44 import java.io.IOException;
       
    45 import java.util.ArrayList;
       
    46 import java.util.Map;
       
    47 import java.util.Arrays;
       
    48 import java.util.Collection;
       
    49 import java.util.Comparator;
       
    50 import java.util.HashSet;
       
    51 import java.util.HashMap;
       
    52 import java.util.Iterator;
       
    53 import java.util.List;
       
    54 import java.util.ListIterator;
       
    55 import java.util.Set;
       
    56 import static com.sun.java.util.jar.pack.Constants.*;
    40 
    57 
    41 /**
    58 /**
    42  * Reader for a package file.
    59  * Reader for a package file.
    43  *
    60  *
    44  * @see PackageWriter
    61  * @see PackageWriter
   416             case CONSTANT_Integer:
   433             case CONSTANT_Integer:
   417                 cp_Int.expectLength(cpMap.length);
   434                 cp_Int.expectLength(cpMap.length);
   418                 cp_Int.readFrom(in);
   435                 cp_Int.readFrom(in);
   419                 for (int i = 0; i < cpMap.length; i++) {
   436                 for (int i = 0; i < cpMap.length; i++) {
   420                     int x = cp_Int.getInt();  // coding handles signs OK
   437                     int x = cp_Int.getInt();  // coding handles signs OK
   421                     cpMap[i] = ConstantPool.getLiteralEntry(new Integer(x));
   438                     cpMap[i] = ConstantPool.getLiteralEntry(x);
   422                 }
   439                 }
   423                 cp_Int.doneDisbursing();
   440                 cp_Int.doneDisbursing();
   424                 break;
   441                 break;
   425             case CONSTANT_Float:
   442             case CONSTANT_Float:
   426                 cp_Float.expectLength(cpMap.length);
   443                 cp_Float.expectLength(cpMap.length);
   427                 cp_Float.readFrom(in);
   444                 cp_Float.readFrom(in);
   428                 for (int i = 0; i < cpMap.length; i++) {
   445                 for (int i = 0; i < cpMap.length; i++) {
   429                     int x = cp_Float.getInt();
   446                     int x = cp_Float.getInt();
   430                     float fx = Float.intBitsToFloat(x);
   447                     float fx = Float.intBitsToFloat(x);
   431                     cpMap[i] = ConstantPool.getLiteralEntry(new Float(fx));
   448                     cpMap[i] = ConstantPool.getLiteralEntry(fx);
   432                 }
   449                 }
   433                 cp_Float.doneDisbursing();
   450                 cp_Float.doneDisbursing();
   434                 break;
   451                 break;
   435             case CONSTANT_Long:
   452             case CONSTANT_Long:
   436                 //  cp_Long:
   453                 //  cp_Long:
   442                 cp_Long_lo.readFrom(in);
   459                 cp_Long_lo.readFrom(in);
   443                 for (int i = 0; i < cpMap.length; i++) {
   460                 for (int i = 0; i < cpMap.length; i++) {
   444                     long hi = cp_Long_hi.getInt();
   461                     long hi = cp_Long_hi.getInt();
   445                     long lo = cp_Long_lo.getInt();
   462                     long lo = cp_Long_lo.getInt();
   446                     long x = (hi << 32) + ((lo << 32) >>> 32);
   463                     long x = (hi << 32) + ((lo << 32) >>> 32);
   447                     cpMap[i] = ConstantPool.getLiteralEntry(new Long(x));
   464                     cpMap[i] = ConstantPool.getLiteralEntry(x);
   448                 }
   465                 }
   449                 cp_Long_hi.doneDisbursing();
   466                 cp_Long_hi.doneDisbursing();
   450                 cp_Long_lo.doneDisbursing();
   467                 cp_Long_lo.doneDisbursing();
   451                 break;
   468                 break;
   452             case CONSTANT_Double:
   469             case CONSTANT_Double:
   460                 for (int i = 0; i < cpMap.length; i++) {
   477                 for (int i = 0; i < cpMap.length; i++) {
   461                     long hi = cp_Double_hi.getInt();
   478                     long hi = cp_Double_hi.getInt();
   462                     long lo = cp_Double_lo.getInt();
   479                     long lo = cp_Double_lo.getInt();
   463                     long x = (hi << 32) + ((lo << 32) >>> 32);
   480                     long x = (hi << 32) + ((lo << 32) >>> 32);
   464                     double dx = Double.longBitsToDouble(x);
   481                     double dx = Double.longBitsToDouble(x);
   465                     cpMap[i] = ConstantPool.getLiteralEntry(new Double(dx));
   482                     cpMap[i] = ConstantPool.getLiteralEntry(dx);
   466                 }
   483                 }
   467                 cp_Double_hi.doneDisbursing();
   484                 cp_Double_hi.doneDisbursing();
   468                 cp_Double_lo.doneDisbursing();
   485                 cp_Double_lo.doneDisbursing();
   469                 break;
   486                 break;
   470             case CONSTANT_String:
   487             case CONSTANT_String:
   643         cp_Utf8_prefix.doneDisbursing();
   660         cp_Utf8_prefix.doneDisbursing();
   644         cp_Utf8_suffix.doneDisbursing();
   661         cp_Utf8_suffix.doneDisbursing();
   645         cp_Utf8_big_suffix.doneDisbursing();
   662         cp_Utf8_big_suffix.doneDisbursing();
   646     }
   663     }
   647 
   664 
   648     HashMap utf8Signatures;  // Utf8Entry->SignatureEntry
   665     Map<Utf8Entry, SignatureEntry> utf8Signatures;
   649 
   666 
   650     void readSignatureBands(Entry[] cpMap) throws IOException {
   667     void readSignatureBands(Entry[] cpMap) throws IOException {
   651         //  cp_Signature:
   668         //  cp_Signature:
   652         //        *cp_Signature_form :DELTA5  (cp_Utf8)
   669         //        *cp_Signature_form :DELTA5  (cp_Utf8)
   653         //        *cp_Signature_classes :UDELTA5  (cp_Class)
   670         //        *cp_Signature_classes :UDELTA5  (cp_Class)
   661         }
   678         }
   662         cp_Signature_form.resetForSecondPass();
   679         cp_Signature_form.resetForSecondPass();
   663         cp_Signature_classes.expectLength(getIntTotal(numSigClasses));
   680         cp_Signature_classes.expectLength(getIntTotal(numSigClasses));
   664         cp_Signature_classes.readFrom(in);
   681         cp_Signature_classes.readFrom(in);
   665         cp_Signature_classes.setIndex(getCPIndex(CONSTANT_Class));
   682         cp_Signature_classes.setIndex(getCPIndex(CONSTANT_Class));
   666         utf8Signatures = new HashMap();
   683         utf8Signatures = new HashMap<>();
   667         for (int i = 0; i < cpMap.length; i++) {
   684         for (int i = 0; i < cpMap.length; i++) {
   668             Utf8Entry formRef = (Utf8Entry) cp_Signature_form.getRef();
   685             Utf8Entry formRef = (Utf8Entry) cp_Signature_form.getRef();
   669             ClassEntry[] classRefs = new ClassEntry[numSigClasses[i]];
   686             ClassEntry[] classRefs = new ClassEntry[numSigClasses[i]];
   670             for (int j = 0; j < classRefs.length; j++) {
   687             for (int j = 0; j < classRefs.length; j++) {
   671                 classRefs[j] = (ClassEntry) cp_Signature_classes.getRef();
   688                 classRefs[j] = (ClassEntry) cp_Signature_classes.getRef();
   861         ic_outer_class.expectLength(longICCount);
   878         ic_outer_class.expectLength(longICCount);
   862         ic_outer_class.readFrom(in);
   879         ic_outer_class.readFrom(in);
   863         ic_name.expectLength(longICCount);
   880         ic_name.expectLength(longICCount);
   864         ic_name.readFrom(in);
   881         ic_name.readFrom(in);
   865         ic_flags.resetForSecondPass();
   882         ic_flags.resetForSecondPass();
   866         ArrayList icList = new ArrayList(numInnerClasses);
   883         List<InnerClass> icList = new ArrayList<>(numInnerClasses);
   867         for (int i = 0; i < numInnerClasses; i++) {
   884         for (int i = 0; i < numInnerClasses; i++) {
   868             int flags = ic_flags.getInt();
   885             int flags = ic_flags.getInt();
   869             boolean longForm = (flags & ACC_IC_LONG_FORM) != 0;
   886             boolean longForm = (flags & ACC_IC_LONG_FORM) != 0;
   870             flags &= ~ACC_IC_LONG_FORM;
   887             flags &= ~ACC_IC_LONG_FORM;
   871             ClassEntry thisClass = (ClassEntry) ic_this_class.getRef();
   888             ClassEntry thisClass = (ClassEntry) ic_this_class.getRef();
   874             if (longForm) {
   891             if (longForm) {
   875                 outerClass = (ClassEntry) ic_outer_class.getRef();
   892                 outerClass = (ClassEntry) ic_outer_class.getRef();
   876                 thisName   = (Utf8Entry)  ic_name.getRef();
   893                 thisName   = (Utf8Entry)  ic_name.getRef();
   877             } else {
   894             } else {
   878                 String n = thisClass.stringValue();
   895                 String n = thisClass.stringValue();
   879                 String[] parse = pkg.parseInnerClassName(n);
   896                 String[] parse = Package.parseInnerClassName(n);
   880                 assert(parse != null);
   897                 assert(parse != null);
   881                 String pkgOuter = parse[0];
   898                 String pkgOuter = parse[0];
   882                 //String number = parse[1];
   899                 //String number = parse[1];
   883                 String name     = parse[2];
   900                 String name     = parse[2];
   884                 if (pkgOuter == null)
   901                 if (pkgOuter == null)
   903         ic_bands.doneDisbursing();
   920         ic_bands.doneDisbursing();
   904     }
   921     }
   905 
   922 
   906     void readLocalInnerClasses(Class cls) throws IOException {
   923     void readLocalInnerClasses(Class cls) throws IOException {
   907         int nc = class_InnerClasses_N.getInt();
   924         int nc = class_InnerClasses_N.getInt();
   908         ArrayList localICs = new ArrayList(nc);
   925         List<InnerClass> localICs = new ArrayList<>(nc);
   909         for (int i = 0; i < nc; i++) {
   926         for (int i = 0; i < nc; i++) {
   910             ClassEntry thisClass = (ClassEntry) class_InnerClasses_RC.getRef();
   927             ClassEntry thisClass = (ClassEntry) class_InnerClasses_RC.getRef();
   911             int        flags     =              class_InnerClasses_F.getInt();
   928             int        flags     =              class_InnerClasses_F.getInt();
   912             if (flags == 0) {
   929             if (flags == 0) {
   913                 // A zero flag means copy a global IC here.
   930                 // A zero flag means copy a global IC here.
   992             return pkg.cp.untypedIndexOf(se);
  1009             return pkg.cp.untypedIndexOf(se);
   993         }
  1010         }
   994         return -1;
  1011         return -1;
   995     }
  1012     }
   996 
  1013 
   997     Comparator entryOutputOrder = new Comparator() {
  1014     Comparator<Entry> entryOutputOrder = new Comparator<>() {
   998         public int compare(Object o0, Object o1) {
  1015         public int compare(Entry  e0, Entry e1) {
   999             Entry e0 = (Entry) o0;
       
  1000             Entry e1 = (Entry) o1;
       
  1001             int k0 = getOutputIndex(e0);
  1016             int k0 = getOutputIndex(e0);
  1002             int k1 = getOutputIndex(e1);
  1017             int k1 = getOutputIndex(e1);
  1003             if (k0 >= 0 && k1 >= 0)
  1018             if (k0 >= 0 && k1 >= 0)
  1004                 // If both have keys, use the keys.
  1019                 // If both have keys, use the keys.
  1005                 return k0 - k1;
  1020                 return k0 - k1;
  1032         // record the local cp:
  1047         // record the local cp:
  1033         cls.setCPMap(reconstructLocalCPMap(cls));
  1048         cls.setCPMap(reconstructLocalCPMap(cls));
  1034     }
  1049     }
  1035 
  1050 
  1036     Entry[] reconstructLocalCPMap(Class cls) {
  1051     Entry[] reconstructLocalCPMap(Class cls) {
  1037         HashSet ldcRefs = (HashSet) ldcRefMap.get(cls);
  1052         Set<Entry> ldcRefs = ldcRefMap.get(cls);
  1038         HashSet cpRefs = new HashSet();
  1053         Set<Entry> cpRefs = new HashSet<>();
  1039         HashSet sigSet = new HashSet();
       
  1040 
  1054 
  1041         // look for constant pool entries:
  1055         // look for constant pool entries:
  1042         cls.visitRefs(VRM_CLASSIC, cpRefs);
  1056         cls.visitRefs(VRM_CLASSIC, cpRefs);
  1043 
  1057 
  1044         // flesh out the local constant pool
  1058         // flesh out the local constant pool
  1062             ConstantPool.completeReferencesIn(cpRefs, true);
  1076             ConstantPool.completeReferencesIn(cpRefs, true);
  1063         }
  1077         }
  1064 
  1078 
  1065         // construct a local constant pool
  1079         // construct a local constant pool
  1066         int numDoubles = 0;
  1080         int numDoubles = 0;
  1067         for (Iterator i = cpRefs.iterator(); i.hasNext(); ) {
  1081         for (Entry e : cpRefs) {
  1068             Entry e = (Entry) i.next();
       
  1069             if (e.isDoubleWord())  numDoubles++;
  1082             if (e.isDoubleWord())  numDoubles++;
  1070             assert(e.tag != CONSTANT_Signature) : (e);
  1083             assert(e.tag != CONSTANT_Signature) : (e);
  1071         }
  1084         }
  1072         Entry[] cpMap = new Entry[1+numDoubles+cpRefs.size()];
  1085         Entry[] cpMap = new Entry[1+numDoubles+cpRefs.size()];
  1073         int fillp = 1;
  1086         int fillp = 1;
  1074 
  1087 
  1075         // Add all ldc operands first.
  1088         // Add all ldc operands first.
  1076         if (ldcRefs != null) {
  1089         if (ldcRefs != null) {
  1077             assert(cpRefs.containsAll(ldcRefs));
  1090             assert(cpRefs.containsAll(ldcRefs));
  1078             for (Iterator i = ldcRefs.iterator(); i.hasNext(); ) {
  1091             for (Entry e : ldcRefs) {
  1079                 Entry e = (Entry) i.next();
       
  1080                 cpMap[fillp++] = e;
  1092                 cpMap[fillp++] = e;
  1081             }
  1093             }
  1082             assert(fillp == 1+ldcRefs.size());
  1094             assert(fillp == 1+ldcRefs.size());
  1083             cpRefs.removeAll(ldcRefs);
  1095             cpRefs.removeAll(ldcRefs);
  1084             ldcRefs = null;  // done with it
  1096             ldcRefs = null;  // done with it
  1085         }
  1097         }
  1086 
  1098 
  1087         // Next add all the two-byte references.
  1099         // Next add all the two-byte references.
  1088         HashSet wideRefs = cpRefs;
  1100         Set<Entry> wideRefs = cpRefs;
  1089         cpRefs = null;  // do not use!
  1101         cpRefs = null;  // do not use!
  1090         int narrowLimit = fillp;
  1102         int narrowLimit = fillp;
  1091         for (Iterator i = wideRefs.iterator(); i.hasNext(); ) {
  1103         for (Entry e : wideRefs) {
  1092             Entry e = (Entry) i.next();
       
  1093             cpMap[fillp++] = e;
  1104             cpMap[fillp++] = e;
  1094         }
  1105         }
  1095         assert(fillp == narrowLimit+wideRefs.size());
  1106         assert(fillp == narrowLimit+wideRefs.size());
  1096         Arrays.sort(cpMap, 1, narrowLimit, entryOutputOrder);
  1107         Arrays.sort(cpMap, 1, narrowLimit, entryOutputOrder);
  1097         Arrays.sort(cpMap, narrowLimit, fillp, entryOutputOrder);
  1108         Arrays.sort(cpMap, narrowLimit, fillp, entryOutputOrder);
  1142         int totalNM = class_method_count.getIntTotal();
  1153         int totalNM = class_method_count.getIntTotal();
  1143         field_descr.expectLength(totalNF);
  1154         field_descr.expectLength(totalNF);
  1144         method_descr.expectLength(totalNM);
  1155         method_descr.expectLength(totalNM);
  1145         if (verbose > 1)  Utils.log.fine("expecting #fields="+totalNF+" and #methods="+totalNM+" in #classes="+numClasses);
  1156         if (verbose > 1)  Utils.log.fine("expecting #fields="+totalNF+" and #methods="+totalNM+" in #classes="+numClasses);
  1146 
  1157 
  1147         ArrayList fields = new ArrayList(totalNF);
  1158         List<Class.Field> fields = new ArrayList<>(totalNF);
  1148         field_descr.readFrom(in);
  1159         field_descr.readFrom(in);
  1149         for (int i = 0; i < classes.length; i++) {
  1160         for (int i = 0; i < classes.length; i++) {
  1150             Class c = classes[i];
  1161             Class c = classes[i];
  1151             int nf = class_field_count.getInt();
  1162             int nf = class_field_count.getInt();
  1152             for (int j = 0; j < nf; j++) {
  1163             for (int j = 0; j < nf; j++) {
  1158         class_field_count.doneDisbursing();
  1169         class_field_count.doneDisbursing();
  1159         field_descr.doneDisbursing();
  1170         field_descr.doneDisbursing();
  1160         countAndReadAttrs(ATTR_CONTEXT_FIELD, fields);
  1171         countAndReadAttrs(ATTR_CONTEXT_FIELD, fields);
  1161         fields = null;  // release to GC
  1172         fields = null;  // release to GC
  1162 
  1173 
  1163         ArrayList methods = new ArrayList(totalNM);
  1174         List<Class.Method> methods = new ArrayList<>(totalNM);
  1164         method_descr.readFrom(in);
  1175         method_descr.readFrom(in);
  1165         for (int i = 0; i < classes.length; i++) {
  1176         for (int i = 0; i < classes.length; i++) {
  1166             Class c = classes[i];
  1177             Class c = classes[i];
  1167             int nm = class_method_count.getInt();
  1178             int nm = class_method_count.getInt();
  1168             for (int j = 0; j < nm; j++) {
  1179             for (int j = 0; j < nm; j++) {
  1180         // attributes stay in the method attribute lists, however.
  1191         // attributes stay in the method attribute lists, however.
  1181         allCodes = buildCodeAttrs(methods);
  1192         allCodes = buildCodeAttrs(methods);
  1182     }
  1193     }
  1183 
  1194 
  1184     Code[] allCodes;
  1195     Code[] allCodes;
  1185     List codesWithFlags;
  1196     List<Code> codesWithFlags;
  1186     HashMap ldcRefMap = new HashMap();  // HashMap<Class, HashSet<Entry>>
  1197     Map<Class, Set<Entry>> ldcRefMap = new HashMap<>();
  1187 
  1198 
  1188     Code[] buildCodeAttrs(List methods) {
  1199     Code[] buildCodeAttrs(List<Class.Method> methods) {
  1189         ArrayList codes = new ArrayList(methods.size());
  1200         List<Code> codes = new ArrayList<>(methods.size());
  1190         for (Iterator i = methods.iterator(); i.hasNext(); ) {
  1201         for (Class.Method m : methods) {
  1191             Class.Method m = (Class.Method) i.next();
       
  1192             if (m.getAttribute(attrCodeEmpty) != null) {
  1202             if (m.getAttribute(attrCodeEmpty) != null) {
  1193                 m.code = new Code(m);
  1203                 m.code = new Code(m);
  1194                 codes.add(m.code);
  1204                 codes.add(m.code);
  1195             }
  1205             }
  1196         }
  1206         }
  1209         //        ...
  1219         //        ...
  1210         //        code_attr_bands
  1220         //        code_attr_bands
  1211         boolean attrsOK = testBit(archiveOptions, AO_HAVE_ALL_CODE_FLAGS);
  1221         boolean attrsOK = testBit(archiveOptions, AO_HAVE_ALL_CODE_FLAGS);
  1212         code_headers.expectLength(allCodes.length);
  1222         code_headers.expectLength(allCodes.length);
  1213         code_headers.readFrom(in);
  1223         code_headers.readFrom(in);
  1214         ArrayList longCodes = new ArrayList(allCodes.length / 10);
  1224         List<Code> longCodes = new ArrayList<>(allCodes.length / 10);
  1215         for (int i = 0; i < allCodes.length; i++) {
  1225         for (int i = 0; i < allCodes.length; i++) {
  1216             Code c = allCodes[i];
  1226             Code c = allCodes[i];
  1217             int sc = code_headers.getByte();
  1227             int sc = code_headers.getByte();
  1218             assert(sc == (sc & 0xFF));
  1228             assert(sc == (sc & 0xFF));
  1219             if (verbose > 2)
  1229             if (verbose > 2)
  1236 
  1246 
  1237         // Do the long headers now.
  1247         // Do the long headers now.
  1238         code_max_stack.readFrom(in);
  1248         code_max_stack.readFrom(in);
  1239         code_max_na_locals.readFrom(in);
  1249         code_max_na_locals.readFrom(in);
  1240         code_handler_count.readFrom(in);
  1250         code_handler_count.readFrom(in);
  1241         for (Iterator i = longCodes.iterator(); i.hasNext(); ) {
  1251         for (Code c : longCodes) {
  1242             Code c = (Code) i.next();
       
  1243             c.setMaxStack(     code_max_stack.getInt() );
  1252             c.setMaxStack(     code_max_stack.getInt() );
  1244             c.setMaxNALocals(  code_max_na_locals.getInt() );
  1253             c.setMaxNALocals(  code_max_na_locals.getInt() );
  1245             c.setHandlerCount( code_handler_count.getInt() );
  1254             c.setHandlerCount( code_handler_count.getInt() );
  1246         }
  1255         }
  1247         code_max_stack.doneDisbursing();
  1256         code_max_stack.doneDisbursing();
  1384             Utils.log.fine("scanning flags and attrs for "+Attribute.contextName(ctype)+"["+holders.size()+"]");
  1393             Utils.log.fine("scanning flags and attrs for "+Attribute.contextName(ctype)+"["+holders.size()+"]");
  1385         }
  1394         }
  1386 
  1395 
  1387         // Fetch the attribute layout definitions which govern the bands
  1396         // Fetch the attribute layout definitions which govern the bands
  1388         // we are about to read.
  1397         // we are about to read.
  1389         Attribute.Layout[] defs = new Attribute.Layout[attrDefs[ctype].size()];
  1398         List<Attribute.Layout> defList = attrDefs.get(ctype);
  1390         attrDefs[ctype].toArray(defs);
  1399         Attribute.Layout[] defs = new Attribute.Layout[defList.size()];
       
  1400         defList.toArray(defs);
  1391         IntBand xxx_flags_hi = getAttrBand(xxx_attr_bands, AB_FLAGS_HI);
  1401         IntBand xxx_flags_hi = getAttrBand(xxx_attr_bands, AB_FLAGS_HI);
  1392         IntBand xxx_flags_lo = getAttrBand(xxx_attr_bands, AB_FLAGS_LO);
  1402         IntBand xxx_flags_lo = getAttrBand(xxx_attr_bands, AB_FLAGS_LO);
  1393         IntBand xxx_attr_count = getAttrBand(xxx_attr_bands, AB_ATTR_COUNT);
  1403         IntBand xxx_attr_count = getAttrBand(xxx_attr_bands, AB_ATTR_COUNT);
  1394         IntBand xxx_attr_indexes = getAttrBand(xxx_attr_bands, AB_ATTR_INDEXES);
  1404         IntBand xxx_attr_indexes = getAttrBand(xxx_attr_bands, AB_ATTR_INDEXES);
  1395         IntBand xxx_attr_calls = getAttrBand(xxx_attr_bands, AB_ATTR_CALLS);
  1405         IntBand xxx_attr_calls = getAttrBand(xxx_attr_bands, AB_ATTR_CALLS);
  1448             for (int ai = 0; bits != 0; ai++) {
  1458             for (int ai = 0; bits != 0; ai++) {
  1449                 if ((bits & (1L<<ai)) == 0)  continue;
  1459                 if ((bits & (1L<<ai)) == 0)  continue;
  1450                 bits -= (1L<<ai);
  1460                 bits -= (1L<<ai);
  1451                 nfa += 1;
  1461                 nfa += 1;
  1452             }
  1462             }
  1453             ArrayList ha = new ArrayList(nfa + noa);
  1463             List<Attribute> ha = new ArrayList<>(nfa + noa);
  1454             h.attributes = ha;
  1464             h.attributes = ha;
  1455             bits = attrBits;  // iterate again
  1465             bits = attrBits;  // iterate again
  1456             for (int ai = 0; bits != 0; ai++) {
  1466             for (int ai = 0; bits != 0; ai++) {
  1457                 if ((bits & (1L<<ai)) == 0)  continue;
  1467                 if ((bits & (1L<<ai)) == 0)  continue;
  1458                 bits -= (1L<<ai);
  1468                 bits -= (1L<<ai);
  1514                 Attribute.Layout def = defs[ai];
  1524                 Attribute.Layout def = defs[ai];
  1515                 if (def == null)  continue;  // unused index
  1525                 if (def == null)  continue;  // unused index
  1516                 if (predef != isPredefinedAttr(ctype, ai))
  1526                 if (predef != isPredefinedAttr(ctype, ai))
  1517                     continue;  // wrong pass
  1527                     continue;  // wrong pass
  1518                 int totalCount = totalCounts[ai];
  1528                 int totalCount = totalCounts[ai];
  1519                 Band[] ab = (Band[]) attrBandTable.get(def);
  1529                 Band[] ab = attrBandTable.get(def);
  1520                 if (def == attrInnerClassesEmpty) {
  1530                 if (def == attrInnerClassesEmpty) {
  1521                     // Special case.
  1531                     // Special case.
  1522                     // Size the bands as if using the following layout:
  1532                     // Size the bands as if using the following layout:
  1523                     //    [RCH TI[ (0)[] ()[RCNH RUNH] ]].
  1533                     //    [RCH TI[ (0)[] ()[RCNH RUNH] ]].
  1524                     class_InnerClasses_N.expectLength(totalCount);
  1534                     class_InnerClasses_N.expectLength(totalCount);
  1569     void badAttrIndex(int ai, int ctype) throws IOException {
  1579     void badAttrIndex(int ai, int ctype) throws IOException {
  1570         throw new IOException("Unknown attribute index "+ai+" for "+
  1580         throw new IOException("Unknown attribute index "+ai+" for "+
  1571                                    ATTR_CONTEXT_NAME[ctype]+" attribute");
  1581                                    ATTR_CONTEXT_NAME[ctype]+" attribute");
  1572     }
  1582     }
  1573 
  1583 
       
  1584     @SuppressWarnings("unchecked")
  1574     void readAttrs(int ctype, Collection holders) throws IOException {
  1585     void readAttrs(int ctype, Collection holders) throws IOException {
  1575         // Decode band values into attributes.
  1586         // Decode band values into attributes.
  1576         HashSet sawDefs = new HashSet();
  1587         Set<Attribute.Layout> sawDefs = new HashSet<>();
  1577         ByteArrayOutputStream buf = new ByteArrayOutputStream();
  1588         ByteArrayOutputStream buf = new ByteArrayOutputStream();
  1578         for (Iterator i = holders.iterator(); i.hasNext(); ) {
  1589         for (Iterator i = holders.iterator(); i.hasNext(); ) {
  1579             final Attribute.Holder h = (Attribute.Holder) i.next();
  1590             final Attribute.Holder h = (Attribute.Holder) i.next();
  1580             if (h.attributes == null)  continue;
  1591             if (h.attributes == null)  continue;
  1581             for (ListIterator j = h.attributes.listIterator(); j.hasNext(); ) {
  1592             for (ListIterator<Attribute> j = h.attributes.listIterator(); j.hasNext(); ) {
  1582                 Attribute a = (Attribute) j.next();
  1593                 Attribute a = j.next();
  1583                 Attribute.Layout def = a.layout();
  1594                 Attribute.Layout def = a.layout();
  1584                 if (def.bandCount == 0) {
  1595                 if (def.bandCount == 0) {
  1585                     if (def == attrInnerClassesEmpty) {
  1596                     if (def == attrInnerClassesEmpty) {
  1586                         // Special logic to read this attr.
  1597                         // Special logic to read this attr.
  1587                         readLocalInnerClasses((Class) h);
  1598                         readLocalInnerClasses((Class) h);
  1593                 sawDefs.add(def);
  1604                 sawDefs.add(def);
  1594                 boolean isCV = (ctype == ATTR_CONTEXT_FIELD && def == attrConstantValue);
  1605                 boolean isCV = (ctype == ATTR_CONTEXT_FIELD && def == attrConstantValue);
  1595                 if (isCV)  setConstantValueIndex((Class.Field)h);
  1606                 if (isCV)  setConstantValueIndex((Class.Field)h);
  1596                 if (verbose > 2)
  1607                 if (verbose > 2)
  1597                     Utils.log.fine("read "+a+" in "+h);
  1608                     Utils.log.fine("read "+a+" in "+h);
  1598                 final Band[] ab = (Band[]) attrBandTable.get(def);
  1609                 final Band[] ab = attrBandTable.get(def);
  1599                 // Read one attribute of type def from ab into a byte array.
  1610                 // Read one attribute of type def from ab into a byte array.
  1600                 buf.reset();
  1611                 buf.reset();
  1601                 Object fixups = a.unparse(new Attribute.ValueStream() {
  1612                 Object fixups = a.unparse(new Attribute.ValueStream() {
  1602                     public int getInt(int bandIndex) {
  1613                     public int getInt(int bandIndex) {
  1603                         return ((IntBand) ab[bandIndex]).getInt();
  1614                         return ((IntBand) ab[bandIndex]).getInt();
  1615                 if (isCV)  setConstantValueIndex(null);  // clean up
  1626                 if (isCV)  setConstantValueIndex(null);  // clean up
  1616             }
  1627             }
  1617         }
  1628         }
  1618 
  1629 
  1619         // Mark the bands we just used as done disbursing.
  1630         // Mark the bands we just used as done disbursing.
  1620         for (Iterator i = sawDefs.iterator(); i.hasNext(); ) {
  1631         for (Attribute.Layout def : sawDefs) {
  1621             Attribute.Layout def = (Attribute.Layout) i.next();
       
  1622             if (def == null)  continue;  // unused index
  1632             if (def == null)  continue;  // unused index
  1623             Band[] ab = (Band[]) attrBandTable.get(def);
  1633             Band[] ab = attrBandTable.get(def);
  1624             for (int j = 0; j < ab.length; j++) {
  1634             for (int j = 0; j < ab.length; j++) {
  1625                 ab[j].doneDisbursing();
  1635                 ab[j].doneDisbursing();
  1626             }
  1636             }
  1627         }
  1637         }
  1628 
  1638 
  1776 
  1786 
  1777     private void readByteCodeOps() throws IOException {
  1787     private void readByteCodeOps() throws IOException {
  1778         // scratch buffer for collecting code::
  1788         // scratch buffer for collecting code::
  1779         byte[] buf = new byte[1<<12];
  1789         byte[] buf = new byte[1<<12];
  1780         // record of all switch opcodes (these are variable-length)
  1790         // record of all switch opcodes (these are variable-length)
  1781         ArrayList allSwitchOps = new ArrayList();
  1791         List<Integer> allSwitchOps = new ArrayList<>();
  1782         for (int k = 0; k < allCodes.length; k++) {
  1792         for (int k = 0; k < allCodes.length; k++) {
  1783             Code c = allCodes[k];
  1793             Code c = allCodes[k];
  1784         scanOneMethod:
  1794         scanOneMethod:
  1785             for (int i = 0; ; i++) {
  1795             for (int i = 0; ; i++) {
  1786                 int bc = bc_codes.getByte();
  1796                 int bc = bc_codes.getByte();
  1796                 // Adjust expectations of various band sizes.
  1806                 // Adjust expectations of various band sizes.
  1797                 switch (bc) {
  1807                 switch (bc) {
  1798                 case _tableswitch:
  1808                 case _tableswitch:
  1799                 case _lookupswitch:
  1809                 case _lookupswitch:
  1800                     bc_case_count.expectMoreLength(1);
  1810                     bc_case_count.expectMoreLength(1);
  1801                     allSwitchOps.add(new Integer(bc));
  1811                     allSwitchOps.add(bc);
  1802                     break;
  1812                     break;
  1803                 case _iinc:
  1813                 case _iinc:
  1804                     bc_local.expectMoreLength(1);
  1814                     bc_local.expectMoreLength(1);
  1805                     if (isWide)
  1815                     if (isWide)
  1806                         bc_short.expectMoreLength(1);
  1816                         bc_short.expectMoreLength(1);
  1864             }
  1874             }
  1865         }
  1875         }
  1866 
  1876 
  1867         // To size instruction bands correctly, we need info on switches:
  1877         // To size instruction bands correctly, we need info on switches:
  1868         bc_case_count.readFrom(in);
  1878         bc_case_count.readFrom(in);
  1869         for (Iterator i = allSwitchOps.iterator(); i.hasNext(); ) {
  1879         for (Integer i : allSwitchOps) {
  1870             int bc = ((Integer)i.next()).intValue();
  1880             int bc = i.intValue();
  1871             int caseCount = bc_case_count.getInt();
  1881             int caseCount = bc_case_count.getInt();
  1872             bc_label.expectMoreLength(1+caseCount); // default label + cases
  1882             bc_label.expectMoreLength(1+caseCount); // default label + cases
  1873             bc_case_value.expectMoreLength(bc == _tableswitch ? 1 : caseCount);
  1883             bc_case_value.expectMoreLength(bc == _tableswitch ? 1 : caseCount);
  1874         }
  1884         }
  1875         bc_case_count.resetForSecondPass();
  1885         bc_case_count.resetForSecondPass();
  1890             byte[] codeOps = code.bytes;
  1900             byte[] codeOps = code.bytes;
  1891             code.bytes = null;  // just for now, while we accumulate bits
  1901             code.bytes = null;  // just for now, while we accumulate bits
  1892 
  1902 
  1893             Class curClass = code.thisClass();
  1903             Class curClass = code.thisClass();
  1894 
  1904 
  1895             HashSet ldcRefSet = (HashSet) ldcRefMap.get(curClass);
  1905             Set<Entry> ldcRefSet = ldcRefMap.get(curClass);
  1896             if (ldcRefSet == null)
  1906             if (ldcRefSet == null)
  1897                 ldcRefMap.put(curClass, ldcRefSet = new HashSet());
  1907                 ldcRefMap.put(curClass, ldcRefSet = new HashSet<>());
  1898 
  1908 
  1899             ClassEntry thisClass  = curClass.thisClass;
  1909             ClassEntry thisClass  = curClass.thisClass;
  1900             ClassEntry superClass = curClass.superClass;
  1910             ClassEntry superClass = curClass.superClass;
  1901             ClassEntry newClass   = null;  // class of last _new opcode
  1911             ClassEntry newClass   = null;  // class of last _new opcode
  1902 
  1912