1 /*
   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.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.java.util.jar.pack;
  27 
  28 import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
  29 import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
  30 import com.sun.java.util.jar.pack.ConstantPool.Entry;
  31 import com.sun.java.util.jar.pack.ConstantPool.Index;
  32 import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
  33 import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
  34 import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
  35 import com.sun.java.util.jar.pack.Package.Class;
  36 import com.sun.java.util.jar.pack.Package.File;
  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.*;
  57 
  58 /**
  59  * Reader for a package file.
  60  *
  61  * @see PackageWriter
  62  * @author John Rose
  63  */
  64 class PackageReader extends BandStructure {
  65     Package pkg;
  66     byte[] bytes;
  67     LimitedBuffer in;
  68 
  69     PackageReader(Package pkg, InputStream in) throws IOException {
  70         this.pkg = pkg;
  71         this.in = new LimitedBuffer(in);
  72     }
  73 
  74     /** A buffered input stream which is careful not to
  75      *  read its underlying stream ahead of a given mark,
  76      *  called the 'readLimit'.  This property declares
  77      *  the maximum number of characters that future reads
  78      *  can consume from the underlying stream.
  79      */
  80     static
  81     class LimitedBuffer extends BufferedInputStream {
  82         long served;     // total number of charburgers served
  83         int  servedPos;  // ...as of this value of super.pos
  84         long limit;      // current declared limit
  85         long buffered;
  86         public boolean atLimit() {
  87             boolean z = (getBytesServed() == limit);
  88             assert(!z || limit == buffered);
  89             return z;
  90         }
  91         public long getBytesServed() {
  92             return served + (pos - servedPos);
  93         }
  94         public void setReadLimit(long newLimit) {
  95             if (newLimit == -1)
  96                 limit = -1;
  97             else
  98                 limit = getBytesServed() + newLimit;
  99         }
 100         public long getReadLimit() {
 101             if (limit == -1)
 102                 return limit;
 103             else
 104                 return limit - getBytesServed();
 105         }
 106         public int read() throws IOException {
 107             if (pos < count) {
 108                 // fast path
 109                 return buf[pos++] & 0xFF;
 110             }
 111             served += (pos - servedPos);
 112             int ch = super.read();
 113             servedPos = pos;
 114             if (ch >= 0)  served += 1;
 115             assert(served <= limit || limit == -1);
 116             return ch;
 117         }
 118         public int read(byte b[], int off, int len) throws IOException {
 119             served += (pos - servedPos);
 120             int nr = super.read(b, off, len);
 121             servedPos = pos;
 122             if (nr >= 0)  served += nr;
 123             assert(served <= limit || limit == -1);
 124             return nr;
 125         }
 126         public long skip(long n) throws IOException {
 127             throw new RuntimeException("no skipping");
 128         }
 129         LimitedBuffer(InputStream originalIn) {
 130             super(null, 1<<14);
 131             servedPos = pos;
 132             super.in = new FilterInputStream(originalIn) {
 133                 public int read() throws IOException {
 134                     if (buffered == limit)
 135                         return -1;
 136                     ++buffered;
 137                     return super.read();
 138                 }
 139                 public int read(byte b[], int off, int len) throws IOException {
 140                     if (buffered == limit)
 141                         return -1;
 142                     if (limit != -1) {
 143                         long remaining = limit - buffered;
 144                         if (len > remaining)
 145                             len = (int)remaining;
 146                     }
 147                     int nr = super.read(b, off, len);
 148                     if (nr >= 0)  buffered += nr;
 149                     return nr;
 150                 }
 151             };
 152         }
 153     }
 154 
 155     void read() throws IOException {
 156         boolean ok = false;
 157         try {
 158             //  pack200_archive:
 159             //        file_header
 160             //        *band_headers :BYTE1
 161             //        cp_bands
 162             //        attr_definition_bands
 163             //        ic_bands
 164             //        class_bands
 165             //        bc_bands
 166             //        file_bands
 167             readFileHeader();
 168             readBandHeaders();
 169             readConstantPool();  // cp_bands
 170             readAttrDefs();
 171             readInnerClasses();
 172             Class[] classes = readClasses();
 173             readByteCodes();
 174             readFiles();     // file_bands
 175             assert(archiveSize1 == 0 || in.atLimit());
 176             assert(archiveSize1 == 0 ||
 177                    in.getBytesServed() == archiveSize0+archiveSize1);
 178             all_bands.doneDisbursing();
 179 
 180             // As a post-pass, build constant pools and inner classes.
 181             for (int i = 0; i < classes.length; i++) {
 182                 reconstructClass(classes[i]);
 183             }
 184 
 185             ok = true;
 186         } catch (Exception ee) {
 187             Utils.log.warning("Error on input: "+ee, ee);
 188             if (verbose > 0)
 189                 Utils.log.info("Stream offsets:"+
 190                                  " served="+in.getBytesServed()+
 191                                  " buffered="+in.buffered+
 192                                  " limit="+in.limit);
 193             //if (verbose > 0)  ee.printStackTrace();
 194             if (ee instanceof IOException)  throw (IOException)ee;
 195             if (ee instanceof RuntimeException)  throw (RuntimeException)ee;
 196             throw new Error("error unpacking", ee);
 197         }
 198     }
 199 
 200     // Temporary count values, until band decoding gets rolling.
 201     int[] tagCount = new int[CONSTANT_Limit];
 202     int numFiles;
 203     int numAttrDefs;
 204     int numInnerClasses;
 205     int numClasses;
 206 
 207     void readFileHeader() throws IOException {
 208         //  file_header:
 209         //        archive_magic archive_header
 210         readArchiveMagic();
 211         readArchiveHeader();
 212     }
 213 
 214     // Local routine used to parse fixed-format scalars
 215     // in the file_header:
 216     private int getMagicInt32() throws IOException {
 217         int res = 0;
 218         for (int i = 0; i < 4; i++) {
 219             res <<= 8;
 220             res |= (archive_magic.getByte() & 0xFF);
 221         }
 222         return res;
 223     }
 224 
 225     final static int MAGIC_BYTES = 4;
 226 
 227     void readArchiveMagic() throws IOException {
 228 
 229         // Read a minimum of bytes in the first gulp.
 230         in.setReadLimit(MAGIC_BYTES + AH_LENGTH_MIN);
 231 
 232         //  archive_magic:
 233         //        #archive_magic_word :BYTE1[4]
 234         archive_magic.expectLength(MAGIC_BYTES);
 235         archive_magic.readFrom(in);
 236 
 237         // read and check magic numbers:
 238         pkg.magic = getMagicInt32();
 239         archive_magic.doneDisbursing();
 240     }
 241 
 242     void readArchiveHeader() throws IOException {
 243         //  archive_header:
 244         //        #archive_minver :UNSIGNED5[1]
 245         //        #archive_majver :UNSIGNED5[1]
 246         //        #archive_options :UNSIGNED5[1]
 247         //        (archive_file_counts) ** (#have_file_headers)
 248         //        (archive_special_counts) ** (#have_special_formats)
 249         //        cp_counts
 250         //        class_counts
 251         //
 252         //  archive_file_counts:
 253         //        #archive_size_hi :UNSIGNED5[1]
 254         //        #archive_size_lo :UNSIGNED5[1]
 255         //        #archive_next_count :UNSIGNED5[1]
 256         //        #archive_modtime :UNSIGNED5[1]
 257         //        #file_count :UNSIGNED5[1]
 258         //
 259         //  class_counts:
 260         //        #ic_count :UNSIGNED5[1]
 261         //        #default_class_minver :UNSIGNED5[1]
 262         //        #default_class_majver :UNSIGNED5[1]
 263         //        #class_count :UNSIGNED5[1]
 264         //
 265         //  archive_special_counts:
 266         //        #band_headers_size :UNSIGNED5[1]
 267         //        #attr_definition_count :UNSIGNED5[1]
 268         //
 269         assert(AH_LENGTH == 8+(ConstantPool.TAGS_IN_ORDER.length)+6);
 270         archive_header_0.expectLength(AH_LENGTH_0);
 271         archive_header_0.readFrom(in);
 272 
 273         pkg.package_minver = archive_header_0.getInt();
 274         pkg.package_majver = archive_header_0.getInt();
 275         pkg.checkVersion();
 276         this.initPackageMajver(pkg.package_majver);
 277 
 278         archiveOptions = archive_header_0.getInt();
 279         archive_header_0.doneDisbursing();
 280 
 281         // detect archive optional fields in archive header
 282         boolean haveSpecial = testBit(archiveOptions, AO_HAVE_SPECIAL_FORMATS);
 283         boolean haveFiles   = testBit(archiveOptions, AO_HAVE_FILE_HEADERS);
 284         boolean haveNumbers = testBit(archiveOptions, AO_HAVE_CP_NUMBERS);
 285         initAttrIndexLimit();
 286 
 287         // now we are ready to use the data:
 288         archive_header_S.expectLength(haveFiles? AH_LENGTH_S: 0);
 289         archive_header_S.readFrom(in);
 290         if (haveFiles) {
 291             long sizeHi = archive_header_S.getInt();
 292             long sizeLo = archive_header_S.getInt();
 293             archiveSize1 = (sizeHi << 32) + ((sizeLo << 32) >>> 32);
 294             // Set the limit, now, up to the file_bits.
 295             in.setReadLimit(archiveSize1);  // for debug only
 296         } else {
 297             archiveSize1 = 0;
 298             in.setReadLimit(-1);  // remove limitation
 299         }
 300         archive_header_S.doneDisbursing();
 301         archiveSize0 = in.getBytesServed();
 302 
 303         int remainingHeaders = AH_LENGTH - AH_LENGTH_0 - AH_LENGTH_S;
 304         if (!haveFiles)    remainingHeaders -= AH_FILE_HEADER_LEN-AH_LENGTH_S;
 305         if (!haveSpecial)  remainingHeaders -= AH_SPECIAL_FORMAT_LEN;
 306         if (!haveNumbers)  remainingHeaders -= AH_CP_NUMBER_LEN;
 307         assert(remainingHeaders >= AH_LENGTH_MIN - AH_LENGTH_0);
 308         archive_header_1.expectLength(remainingHeaders);
 309         archive_header_1.readFrom(in);
 310 
 311         if (haveFiles) {
 312             archiveNextCount = archive_header_1.getInt();
 313             pkg.default_modtime = archive_header_1.getInt();
 314             numFiles = archive_header_1.getInt();
 315         } else {
 316             archiveNextCount = 0;
 317             numFiles = 0;
 318         }
 319 
 320         if (haveSpecial) {
 321             band_headers.expectLength(archive_header_1.getInt());
 322             numAttrDefs = archive_header_1.getInt();
 323         } else {
 324             band_headers.expectLength(0);
 325             numAttrDefs = 0;
 326         }
 327 
 328         readConstantPoolCounts(haveNumbers);
 329 
 330         numInnerClasses = archive_header_1.getInt();
 331 
 332         pkg.default_class_minver = (short) archive_header_1.getInt();
 333         pkg.default_class_majver = (short) archive_header_1.getInt();
 334         numClasses = archive_header_1.getInt();
 335 
 336         archive_header_1.doneDisbursing();
 337 
 338         // set some derived archive bits
 339         if (testBit(archiveOptions, AO_DEFLATE_HINT)) {
 340             pkg.default_options |= FO_DEFLATE_HINT;
 341         }
 342     }
 343 
 344     void readBandHeaders() throws IOException {
 345         band_headers.readFrom(in);
 346         bandHeaderBytePos = 1;  // Leave room to pushback the initial XB byte.
 347         bandHeaderBytes = new byte[bandHeaderBytePos + band_headers.length()];
 348         for (int i = bandHeaderBytePos; i < bandHeaderBytes.length; i++) {
 349             bandHeaderBytes[i] = (byte) band_headers.getByte();
 350         }
 351         band_headers.doneDisbursing();
 352     }
 353 
 354     void readConstantPoolCounts(boolean haveNumbers) throws IOException {
 355         // size the constant pools:
 356         for (int k = 0; k < ConstantPool.TAGS_IN_ORDER.length; k++) {
 357             //  cp_counts:
 358             //        #cp_Utf8_count :UNSIGNED5[1]
 359             //        (cp_number_counts) ** (#have_cp_numbers)
 360             //        #cp_String_count :UNSIGNED5[1]
 361             //        #cp_Class_count :UNSIGNED5[1]
 362             //        #cp_Signature_count :UNSIGNED5[1]
 363             //        #cp_Descr_count :UNSIGNED5[1]
 364             //        #cp_Field_count :UNSIGNED5[1]
 365             //        #cp_Method_count :UNSIGNED5[1]
 366             //        #cp_Imethod_count :UNSIGNED5[1]
 367             //
 368             //  cp_number_counts:
 369             //        #cp_Int_count :UNSIGNED5[1]
 370             //        #cp_Float_count :UNSIGNED5[1]
 371             //        #cp_Long_count :UNSIGNED5[1]
 372             //        #cp_Double_count :UNSIGNED5[1]
 373             //
 374             byte tag = ConstantPool.TAGS_IN_ORDER[k];
 375             if (!haveNumbers) {
 376                 // These four counts are optional.
 377                 switch (tag) {
 378                 case CONSTANT_Integer:
 379                 case CONSTANT_Float:
 380                 case CONSTANT_Long:
 381                 case CONSTANT_Double:
 382                     continue;
 383                 }
 384             }
 385             tagCount[tag] = archive_header_1.getInt();
 386         }
 387     }
 388 
 389     protected Index getCPIndex(byte tag) {
 390         return pkg.cp.getIndexByTag(tag);
 391     }
 392     Index initCPIndex(byte tag, Entry[] cpMap) {
 393         if (verbose > 3) {
 394             for (int i = 0; i < cpMap.length; i++) {
 395                 Utils.log.fine("cp.add "+cpMap[i]);
 396             }
 397         }
 398         Index index = ConstantPool.makeIndex(ConstantPool.tagName(tag), cpMap);
 399         if (verbose > 1)  Utils.log.fine("Read "+index);
 400         pkg.cp.initIndexByTag(tag, index);
 401         return index;
 402     }
 403 
 404     void readConstantPool() throws IOException {
 405         //  cp_bands:
 406         //        cp_Utf8
 407         //        *cp_Int :UDELTA5
 408         //        *cp_Float :UDELTA5
 409         //        cp_Long
 410         //        cp_Double
 411         //        *cp_String :UDELTA5  (cp_Utf8)
 412         //        *cp_Class :UDELTA5  (cp_Utf8)
 413         //        cp_Signature
 414         //        cp_Descr
 415         //        cp_Field
 416         //        cp_Method
 417         //        cp_Imethod
 418 
 419         if (verbose > 0)  Utils.log.info("Reading CP");
 420 
 421         for (int k = 0; k < ConstantPool.TAGS_IN_ORDER.length; k++) {
 422             byte tag = ConstantPool.TAGS_IN_ORDER[k];
 423             int  len = tagCount[tag];
 424 
 425             Entry[] cpMap = new Entry[len];
 426             if (verbose > 0)
 427                 Utils.log.info("Reading "+cpMap.length+" "+ConstantPool.tagName(tag)+" entries...");
 428 
 429             switch (tag) {
 430             case CONSTANT_Utf8:
 431                 readUtf8Bands(cpMap);
 432                 break;
 433             case CONSTANT_Integer:
 434                 cp_Int.expectLength(cpMap.length);
 435                 cp_Int.readFrom(in);
 436                 for (int i = 0; i < cpMap.length; i++) {
 437                     int x = cp_Int.getInt();  // coding handles signs OK
 438                     cpMap[i] = ConstantPool.getLiteralEntry(x);
 439                 }
 440                 cp_Int.doneDisbursing();
 441                 break;
 442             case CONSTANT_Float:
 443                 cp_Float.expectLength(cpMap.length);
 444                 cp_Float.readFrom(in);
 445                 for (int i = 0; i < cpMap.length; i++) {
 446                     int x = cp_Float.getInt();
 447                     float fx = Float.intBitsToFloat(x);
 448                     cpMap[i] = ConstantPool.getLiteralEntry(fx);
 449                 }
 450                 cp_Float.doneDisbursing();
 451                 break;
 452             case CONSTANT_Long:
 453                 //  cp_Long:
 454                 //        *cp_Long_hi :UDELTA5
 455                 //        *cp_Long_lo :DELTA5
 456                 cp_Long_hi.expectLength(cpMap.length);
 457                 cp_Long_hi.readFrom(in);
 458                 cp_Long_lo.expectLength(cpMap.length);
 459                 cp_Long_lo.readFrom(in);
 460                 for (int i = 0; i < cpMap.length; i++) {
 461                     long hi = cp_Long_hi.getInt();
 462                     long lo = cp_Long_lo.getInt();
 463                     long x = (hi << 32) + ((lo << 32) >>> 32);
 464                     cpMap[i] = ConstantPool.getLiteralEntry(x);
 465                 }
 466                 cp_Long_hi.doneDisbursing();
 467                 cp_Long_lo.doneDisbursing();
 468                 break;
 469             case CONSTANT_Double:
 470                 //  cp_Double:
 471                 //        *cp_Double_hi :UDELTA5
 472                 //        *cp_Double_lo :DELTA5
 473                 cp_Double_hi.expectLength(cpMap.length);
 474                 cp_Double_hi.readFrom(in);
 475                 cp_Double_lo.expectLength(cpMap.length);
 476                 cp_Double_lo.readFrom(in);
 477                 for (int i = 0; i < cpMap.length; i++) {
 478                     long hi = cp_Double_hi.getInt();
 479                     long lo = cp_Double_lo.getInt();
 480                     long x = (hi << 32) + ((lo << 32) >>> 32);
 481                     double dx = Double.longBitsToDouble(x);
 482                     cpMap[i] = ConstantPool.getLiteralEntry(dx);
 483                 }
 484                 cp_Double_hi.doneDisbursing();
 485                 cp_Double_lo.doneDisbursing();
 486                 break;
 487             case CONSTANT_String:
 488                 cp_String.expectLength(cpMap.length);
 489                 cp_String.readFrom(in);
 490                 cp_String.setIndex(getCPIndex(CONSTANT_Utf8));
 491                 for (int i = 0; i < cpMap.length; i++) {
 492                     cpMap[i] = ConstantPool.getLiteralEntry(cp_String.getRef().stringValue());
 493                 }
 494                 cp_String.doneDisbursing();
 495                 break;
 496             case CONSTANT_Class:
 497                 cp_Class.expectLength(cpMap.length);
 498                 cp_Class.readFrom(in);
 499                 cp_Class.setIndex(getCPIndex(CONSTANT_Utf8));
 500                 for (int i = 0; i < cpMap.length; i++) {
 501                     cpMap[i] = ConstantPool.getClassEntry(cp_Class.getRef().stringValue());
 502                 }
 503                 cp_Class.doneDisbursing();
 504                 break;
 505             case CONSTANT_Signature:
 506                 readSignatureBands(cpMap);
 507                 break;
 508             case CONSTANT_NameandType:
 509                 //  cp_Descr:
 510                 //        *cp_Descr_type :DELTA5  (cp_Signature)
 511                 //        *cp_Descr_name :UDELTA5  (cp_Utf8)
 512                 cp_Descr_name.expectLength(cpMap.length);
 513                 cp_Descr_name.readFrom(in);
 514                 cp_Descr_name.setIndex(getCPIndex(CONSTANT_Utf8));
 515                 cp_Descr_type.expectLength(cpMap.length);
 516                 cp_Descr_type.readFrom(in);
 517                 cp_Descr_type.setIndex(getCPIndex(CONSTANT_Signature));
 518                 for (int i = 0; i < cpMap.length; i++) {
 519                     Entry ref  = cp_Descr_name.getRef();
 520                     Entry ref2 = cp_Descr_type.getRef();
 521                     cpMap[i] = ConstantPool.getDescriptorEntry((Utf8Entry)ref,
 522                                                         (SignatureEntry)ref2);
 523                 }
 524                 cp_Descr_name.doneDisbursing();
 525                 cp_Descr_type.doneDisbursing();
 526                 break;
 527             case CONSTANT_Fieldref:
 528                 readMemberRefs(tag, cpMap, cp_Field_class, cp_Field_desc);
 529                 break;
 530             case CONSTANT_Methodref:
 531                 readMemberRefs(tag, cpMap, cp_Method_class, cp_Method_desc);
 532                 break;
 533             case CONSTANT_InterfaceMethodref:
 534                 readMemberRefs(tag, cpMap, cp_Imethod_class, cp_Imethod_desc);
 535                 break;
 536             default:
 537                 assert(false);
 538             }
 539 
 540             Index index = initCPIndex(tag, cpMap);
 541 
 542             if (optDumpBands) {
 543                 PrintStream ps = new PrintStream(getDumpStream(index, ".idx"));
 544                 printArrayTo(ps, index.cpMap, 0, index.cpMap.length);
 545                 ps.close();
 546             }
 547         }
 548 
 549         cp_bands.doneDisbursing();
 550 
 551         setBandIndexes();
 552     }
 553 
 554     void readUtf8Bands(Entry[] cpMap) throws IOException {
 555         //  cp_Utf8:
 556         //        *cp_Utf8_prefix :DELTA5
 557         //        *cp_Utf8_suffix :UNSIGNED5
 558         //        *cp_Utf8_chars :CHAR3
 559         //        *cp_Utf8_big_suffix :DELTA5
 560         //        (*cp_Utf8_big_chars :DELTA5)
 561         //          ** length(cp_Utf8_big_suffix)
 562         int len = cpMap.length;
 563         if (len == 0)
 564             return;  // nothing to read
 565 
 566         // Bands have implicit leading zeroes, for the empty string:
 567         final int SUFFIX_SKIP_1 = 1;
 568         final int PREFIX_SKIP_2 = 2;
 569 
 570         // First band:  Read lengths of shared prefixes.
 571         cp_Utf8_prefix.expectLength(Math.max(0, len - PREFIX_SKIP_2));
 572         cp_Utf8_prefix.readFrom(in);
 573 
 574         // Second band:  Read lengths of unshared suffixes:
 575         cp_Utf8_suffix.expectLength(Math.max(0, len - SUFFIX_SKIP_1));
 576         cp_Utf8_suffix.readFrom(in);
 577 
 578         char[][] suffixChars = new char[len][];
 579         int bigSuffixCount = 0;
 580 
 581         // Third band:  Read the char values in the unshared suffixes:
 582         cp_Utf8_chars.expectLength(cp_Utf8_suffix.getIntTotal());
 583         cp_Utf8_chars.readFrom(in);
 584         for (int i = 0; i < len; i++) {
 585             int suffix = (i < SUFFIX_SKIP_1)? 0: cp_Utf8_suffix.getInt();
 586             if (suffix == 0 && i >= SUFFIX_SKIP_1) {
 587                 // chars are packed in cp_Utf8_big_chars
 588                 bigSuffixCount += 1;
 589                 continue;
 590             }
 591             suffixChars[i] = new char[suffix];
 592             for (int j = 0; j < suffix; j++) {
 593                 int ch = cp_Utf8_chars.getInt();
 594                 assert(ch == (char)ch);
 595                 suffixChars[i][j] = (char)ch;
 596             }
 597         }
 598         cp_Utf8_chars.doneDisbursing();
 599 
 600         // Fourth band:  Go back and size the specially packed strings.
 601         int maxChars = 0;
 602         cp_Utf8_big_suffix.expectLength(bigSuffixCount);
 603         cp_Utf8_big_suffix.readFrom(in);
 604         cp_Utf8_suffix.resetForSecondPass();
 605         for (int i = 0; i < len; i++) {
 606             int suffix = (i < SUFFIX_SKIP_1)? 0: cp_Utf8_suffix.getInt();
 607             int prefix = (i < PREFIX_SKIP_2)? 0: cp_Utf8_prefix.getInt();
 608             if (suffix == 0 && i >= SUFFIX_SKIP_1) {
 609                 assert(suffixChars[i] == null);
 610                 suffix = cp_Utf8_big_suffix.getInt();
 611             } else {
 612                 assert(suffixChars[i] != null);
 613             }
 614             if (maxChars < prefix + suffix)
 615                 maxChars = prefix + suffix;
 616         }
 617         char[] buf = new char[maxChars];
 618 
 619         // Fifth band(s):  Get the specially packed characters.
 620         cp_Utf8_suffix.resetForSecondPass();
 621         cp_Utf8_big_suffix.resetForSecondPass();
 622         for (int i = 0; i < len; i++) {
 623             if (i < SUFFIX_SKIP_1)  continue;
 624             int suffix = cp_Utf8_suffix.getInt();
 625             if (suffix != 0)  continue;  // already input
 626             suffix = cp_Utf8_big_suffix.getInt();
 627             suffixChars[i] = new char[suffix];
 628             if (suffix == 0) {
 629                 // Do not bother to add an empty "(Utf8_big_0)" band.
 630                 continue;
 631             }
 632             IntBand packed = cp_Utf8_big_chars.newIntBand("(Utf8_big_"+i+")");
 633             packed.expectLength(suffix);
 634             packed.readFrom(in);
 635             for (int j = 0; j < suffix; j++) {
 636                 int ch = packed.getInt();
 637                 assert(ch == (char)ch);
 638                 suffixChars[i][j] = (char)ch;
 639             }
 640             packed.doneDisbursing();
 641         }
 642         cp_Utf8_big_chars.doneDisbursing();
 643 
 644         // Finally, sew together all the prefixes and suffixes.
 645         cp_Utf8_prefix.resetForSecondPass();
 646         cp_Utf8_suffix.resetForSecondPass();
 647         cp_Utf8_big_suffix.resetForSecondPass();
 648         for (int i = 0; i < len; i++) {
 649             int prefix = (i < PREFIX_SKIP_2)? 0: cp_Utf8_prefix.getInt();
 650             int suffix = (i < SUFFIX_SKIP_1)? 0: cp_Utf8_suffix.getInt();
 651             if (suffix == 0 && i >= SUFFIX_SKIP_1)
 652                 suffix = cp_Utf8_big_suffix.getInt();
 653 
 654             // by induction, the buffer is already filled with the prefix
 655             System.arraycopy(suffixChars[i], 0, buf, prefix, suffix);
 656 
 657             cpMap[i] = ConstantPool.getUtf8Entry(new String(buf, 0, prefix+suffix));
 658         }
 659 
 660         cp_Utf8_prefix.doneDisbursing();
 661         cp_Utf8_suffix.doneDisbursing();
 662         cp_Utf8_big_suffix.doneDisbursing();
 663     }
 664 
 665     Map<Utf8Entry, SignatureEntry> utf8Signatures;
 666 
 667     void readSignatureBands(Entry[] cpMap) throws IOException {
 668         //  cp_Signature:
 669         //        *cp_Signature_form :DELTA5  (cp_Utf8)
 670         //        *cp_Signature_classes :UDELTA5  (cp_Class)
 671         cp_Signature_form.expectLength(cpMap.length);
 672         cp_Signature_form.readFrom(in);
 673         cp_Signature_form.setIndex(getCPIndex(CONSTANT_Utf8));
 674         int[] numSigClasses = new int[cpMap.length];
 675         for (int i = 0; i < cpMap.length; i++) {
 676             Utf8Entry formRef = (Utf8Entry) cp_Signature_form.getRef();
 677             numSigClasses[i] = ConstantPool.countClassParts(formRef);
 678         }
 679         cp_Signature_form.resetForSecondPass();
 680         cp_Signature_classes.expectLength(getIntTotal(numSigClasses));
 681         cp_Signature_classes.readFrom(in);
 682         cp_Signature_classes.setIndex(getCPIndex(CONSTANT_Class));
 683         utf8Signatures = new HashMap<>();
 684         for (int i = 0; i < cpMap.length; i++) {
 685             Utf8Entry formRef = (Utf8Entry) cp_Signature_form.getRef();
 686             ClassEntry[] classRefs = new ClassEntry[numSigClasses[i]];
 687             for (int j = 0; j < classRefs.length; j++) {
 688                 classRefs[j] = (ClassEntry) cp_Signature_classes.getRef();
 689             }
 690             SignatureEntry se = ConstantPool.getSignatureEntry(formRef, classRefs);
 691             cpMap[i] = se;
 692             utf8Signatures.put(se.asUtf8Entry(), se);
 693         }
 694         cp_Signature_form.doneDisbursing();
 695         cp_Signature_classes.doneDisbursing();
 696     }
 697 
 698     void readMemberRefs(byte tag, Entry[] cpMap, CPRefBand cp_class, CPRefBand cp_desc) throws IOException {
 699         //  cp_Field:
 700         //        *cp_Field_class :DELTA5  (cp_Class)
 701         //        *cp_Field_desc :UDELTA5  (cp_Descr)
 702         //  cp_Method:
 703         //        *cp_Method_class :DELTA5  (cp_Class)
 704         //        *cp_Method_desc :UDELTA5  (cp_Descr)
 705         //  cp_Imethod:
 706         //        *cp_Imethod_class :DELTA5  (cp_Class)
 707         //        *cp_Imethod_desc :UDELTA5  (cp_Descr)
 708         cp_class.expectLength(cpMap.length);
 709         cp_class.readFrom(in);
 710         cp_class.setIndex(getCPIndex(CONSTANT_Class));
 711         cp_desc.expectLength(cpMap.length);
 712         cp_desc.readFrom(in);
 713         cp_desc.setIndex(getCPIndex(CONSTANT_NameandType));
 714         for (int i = 0; i < cpMap.length; i++) {
 715             ClassEntry      mclass = (ClassEntry     ) cp_class.getRef();
 716             DescriptorEntry mdescr = (DescriptorEntry) cp_desc.getRef();
 717             cpMap[i] = ConstantPool.getMemberEntry(tag, mclass, mdescr);
 718         }
 719         cp_class.doneDisbursing();
 720         cp_desc.doneDisbursing();
 721     }
 722 
 723     void readFiles() throws IOException {
 724         //  file_bands:
 725         //        *file_name :UNSIGNED5  (cp_Utf8)
 726         //        *file_size_hi :UNSIGNED5
 727         //        *file_size_lo :UNSIGNED5
 728         //        *file_modtime :DELTA5
 729         //        *file_options :UNSIGNED5
 730         //        *file_bits :BYTE1
 731         if (verbose > 0)
 732             Utils.log.info("  ...building "+numFiles+" files...");
 733         file_name.expectLength(numFiles);
 734         file_size_lo.expectLength(numFiles);
 735         int options = archiveOptions;
 736         boolean haveSizeHi  = testBit(options, AO_HAVE_FILE_SIZE_HI);
 737         boolean haveModtime = testBit(options, AO_HAVE_FILE_MODTIME);
 738         boolean haveOptions = testBit(options, AO_HAVE_FILE_OPTIONS);
 739         if (haveSizeHi)
 740             file_size_hi.expectLength(numFiles);
 741         if (haveModtime)
 742             file_modtime.expectLength(numFiles);
 743         if (haveOptions)
 744             file_options.expectLength(numFiles);
 745 
 746         file_name.readFrom(in);
 747         file_size_hi.readFrom(in);
 748         file_size_lo.readFrom(in);
 749         file_modtime.readFrom(in);
 750         file_options.readFrom(in);
 751         file_bits.setInputStreamFrom(in);
 752 
 753         Iterator nextClass = pkg.getClasses().iterator();
 754 
 755         // Compute file lengths before reading any file bits.
 756         long totalFileLength = 0;
 757         long[] fileLengths = new long[numFiles];
 758         for (int i = 0; i < numFiles; i++) {
 759             long size = ((long)file_size_lo.getInt() << 32) >>> 32;
 760             if (haveSizeHi)
 761                 size += (long)file_size_hi.getInt() << 32;
 762             fileLengths[i] = size;
 763             totalFileLength += size;
 764         }
 765         assert(in.getReadLimit() == -1 || in.getReadLimit() == totalFileLength);
 766 
 767         byte[] buf = new byte[1<<16];
 768         for (int i = 0; i < numFiles; i++) {
 769             // %%% Use a big temp file for file bits?
 770             Utf8Entry name = (Utf8Entry) file_name.getRef();
 771             long size = fileLengths[i];
 772             File file = pkg.new File(name);
 773             file.modtime = pkg.default_modtime;
 774             file.options = pkg.default_options;
 775             if (haveModtime)
 776                 file.modtime += file_modtime.getInt();
 777             if (haveOptions)
 778                 file.options |= file_options.getInt();
 779             if (verbose > 1)
 780                 Utils.log.fine("Reading "+size+" bytes of "+name.stringValue());
 781             long toRead = size;
 782             while (toRead > 0) {
 783                 int nr = buf.length;
 784                 if (nr > toRead)  nr = (int) toRead;
 785                 nr = file_bits.getInputStream().read(buf, 0, nr);
 786                 if (nr < 0)  throw new EOFException();
 787                 file.addBytes(buf, 0, nr);
 788                 toRead -= nr;
 789             }
 790             pkg.addFile(file);
 791             if (file.isClassStub()) {
 792                 assert(file.getFileLength() == 0);
 793                 Class cls = (Class) nextClass.next();
 794                 cls.initFile(file);
 795             }
 796         }
 797 
 798         // Do the rest of the classes.
 799         while (nextClass.hasNext()) {
 800             Class cls = (Class) nextClass.next();
 801             cls.initFile(null);  // implicitly initialize to a trivial one
 802             cls.file.modtime = pkg.default_modtime;
 803         }
 804 
 805         file_name.doneDisbursing();
 806         file_size_hi.doneDisbursing();
 807         file_size_lo.doneDisbursing();
 808         file_modtime.doneDisbursing();
 809         file_options.doneDisbursing();
 810         file_bits.doneDisbursing();
 811         file_bands.doneDisbursing();
 812 
 813         if (archiveSize1 != 0 && !in.atLimit()) {
 814             throw new RuntimeException("Predicted archive_size "+
 815                                        archiveSize1+" != "+
 816                                        (in.getBytesServed()-archiveSize0));
 817         }
 818     }
 819 
 820     void readAttrDefs() throws IOException {
 821         //  attr_definition_bands:
 822         //        *attr_definition_headers :BYTE1
 823         //        *attr_definition_name :UNSIGNED5  (cp_Utf8)
 824         //        *attr_definition_layout :UNSIGNED5  (cp_Utf8)
 825         attr_definition_headers.expectLength(numAttrDefs);
 826         attr_definition_name.expectLength(numAttrDefs);
 827         attr_definition_layout.expectLength(numAttrDefs);
 828         attr_definition_headers.readFrom(in);
 829         attr_definition_name.readFrom(in);
 830         attr_definition_layout.readFrom(in);
 831         PrintStream dump = !optDumpBands ? null
 832             : new PrintStream(getDumpStream(attr_definition_headers, ".def"));
 833         for (int i = 0; i < numAttrDefs; i++) {
 834             int       header = attr_definition_headers.getByte();
 835             Utf8Entry name   = (Utf8Entry) attr_definition_name.getRef();
 836             Utf8Entry layout = (Utf8Entry) attr_definition_layout.getRef();
 837             int       ctype  = (header &  ADH_CONTEXT_MASK);
 838             int       index  = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
 839             Attribute.Layout def = new Attribute.Layout(ctype,
 840                                                         name.stringValue(),
 841                                                         layout.stringValue());
 842             // Check layout string for Java 6 extensions.
 843             String pvLayout = def.layoutForPackageMajver(getPackageMajver());
 844             if (!pvLayout.equals(def.layout())) {
 845                 throw new IOException("Bad attribute layout in version 150 archive: "+def.layout());
 846             }
 847             this.setAttributeLayoutIndex(def, index);
 848             if (dump != null)  dump.println(index+" "+def);
 849         }
 850         if (dump != null)  dump.close();
 851         attr_definition_headers.doneDisbursing();
 852         attr_definition_name.doneDisbursing();
 853         attr_definition_layout.doneDisbursing();
 854         // Attribute layouts define bands, one per layout element.
 855         // Create them now, all at once.
 856         makeNewAttributeBands();
 857         attr_definition_bands.doneDisbursing();
 858     }
 859 
 860     void readInnerClasses() throws IOException {
 861         //  ic_bands:
 862         //        *ic_this_class :UDELTA5  (cp_Class)
 863         //        *ic_flags :UNSIGNED5
 864         //        *ic_outer_class :DELTA5  (null or cp_Class)
 865         //        *ic_name :DELTA5  (null or cp_Utf8)
 866         ic_this_class.expectLength(numInnerClasses);
 867         ic_this_class.readFrom(in);
 868         ic_flags.expectLength(numInnerClasses);
 869         ic_flags.readFrom(in);
 870         int longICCount = 0;
 871         for (int i = 0; i < numInnerClasses; i++) {
 872             int flags = ic_flags.getInt();
 873             boolean longForm = (flags & ACC_IC_LONG_FORM) != 0;
 874             if (longForm) {
 875                 longICCount += 1;
 876             }
 877         }
 878         ic_outer_class.expectLength(longICCount);
 879         ic_outer_class.readFrom(in);
 880         ic_name.expectLength(longICCount);
 881         ic_name.readFrom(in);
 882         ic_flags.resetForSecondPass();
 883         List<InnerClass> icList = new ArrayList<>(numInnerClasses);
 884         for (int i = 0; i < numInnerClasses; i++) {
 885             int flags = ic_flags.getInt();
 886             boolean longForm = (flags & ACC_IC_LONG_FORM) != 0;
 887             flags &= ~ACC_IC_LONG_FORM;
 888             ClassEntry thisClass = (ClassEntry) ic_this_class.getRef();
 889             ClassEntry outerClass;
 890             Utf8Entry  thisName;
 891             if (longForm) {
 892                 outerClass = (ClassEntry) ic_outer_class.getRef();
 893                 thisName   = (Utf8Entry)  ic_name.getRef();
 894             } else {
 895                 String n = thisClass.stringValue();
 896                 String[] parse = Package.parseInnerClassName(n);
 897                 assert(parse != null);
 898                 String pkgOuter = parse[0];
 899                 //String number = parse[1];
 900                 String name     = parse[2];
 901                 if (pkgOuter == null)
 902                     outerClass = null;
 903                 else
 904                     outerClass = ConstantPool.getClassEntry(pkgOuter);
 905                 if (name == null)
 906                     thisName   = null;
 907                 else
 908                     thisName   = ConstantPool.getUtf8Entry(name);
 909             }
 910             InnerClass ic =
 911                 new InnerClass(thisClass, outerClass, thisName, flags);
 912             assert(longForm || ic.predictable);
 913             icList.add(ic);
 914         }
 915         ic_flags.doneDisbursing();
 916         ic_this_class.doneDisbursing();
 917         ic_outer_class.doneDisbursing();
 918         ic_name.doneDisbursing();
 919         pkg.setAllInnerClasses(icList);
 920         ic_bands.doneDisbursing();
 921     }
 922 
 923     void readLocalInnerClasses(Class cls) throws IOException {
 924         int nc = class_InnerClasses_N.getInt();
 925         List<InnerClass> localICs = new ArrayList<>(nc);
 926         for (int i = 0; i < nc; i++) {
 927             ClassEntry thisClass = (ClassEntry) class_InnerClasses_RC.getRef();
 928             int        flags     =              class_InnerClasses_F.getInt();
 929             if (flags == 0) {
 930                 // A zero flag means copy a global IC here.
 931                 InnerClass ic = pkg.getGlobalInnerClass(thisClass);
 932                 assert(ic != null);  // must be a valid global IC reference
 933                 localICs.add(ic);
 934             } else {
 935                 if (flags == ACC_IC_LONG_FORM)
 936                     flags = 0;  // clear the marker bit
 937                 ClassEntry outer = (ClassEntry) class_InnerClasses_outer_RCN.getRef();
 938                 Utf8Entry name   = (Utf8Entry)  class_InnerClasses_name_RUN.getRef();
 939                 localICs.add(new InnerClass(thisClass, outer, name, flags));
 940             }
 941         }
 942         cls.setInnerClasses(localICs);
 943         // cls.expandLocalICs may add more tuples to ics also,
 944         // or may even delete tuples.
 945         // We cannot do that now, because we do not know the
 946         // full contents of the local constant pool yet.
 947     }
 948 
 949     static final int NO_FLAGS_YET = 0;  // placeholder for later flag read-in
 950 
 951     Class[] readClasses() throws IOException {
 952         //  class_bands:
 953         //        *class_this :DELTA5  (cp_Class)
 954         //        *class_super :DELTA5  (cp_Class)
 955         //        *class_interface_count :DELTA5
 956         //        *class_interface :DELTA5  (cp_Class)
 957         //        ...(member bands)...
 958         //        class_attr_bands
 959         //        code_bands
 960         Class[] classes = new Class[numClasses];
 961         if (verbose > 0)
 962             Utils.log.info("  ...building "+classes.length+" classes...");
 963 
 964         class_this.expectLength(numClasses);
 965         class_super.expectLength(numClasses);
 966         class_interface_count.expectLength(numClasses);
 967 
 968         class_this.readFrom(in);
 969         class_super.readFrom(in);
 970         class_interface_count.readFrom(in);
 971         class_interface.expectLength(class_interface_count.getIntTotal());
 972         class_interface.readFrom(in);
 973         for (int i = 0; i < classes.length; i++) {
 974             ClassEntry   thisClass  = (ClassEntry) class_this.getRef();
 975             ClassEntry   superClass = (ClassEntry) class_super.getRef();
 976             ClassEntry[] interfaces = new ClassEntry[class_interface_count.getInt()];
 977             for (int j = 0; j < interfaces.length; j++) {
 978                 interfaces[j] = (ClassEntry) class_interface.getRef();
 979             }
 980             // Packer encoded rare case of null superClass as thisClass:
 981             if (superClass == thisClass)  superClass = null;
 982             Class cls = pkg.new Class(NO_FLAGS_YET,
 983                                       thisClass, superClass, interfaces);
 984             classes[i] = cls;
 985         }
 986         class_this.doneDisbursing();
 987         class_super.doneDisbursing();
 988         class_interface_count.doneDisbursing();
 989         class_interface.doneDisbursing();
 990         readMembers(classes);
 991         countAndReadAttrs(ATTR_CONTEXT_CLASS, Arrays.asList(classes));
 992         pkg.trimToSize();
 993         readCodeHeaders();
 994         //code_bands.doneDisbursing(); // still need to read code attrs
 995         //class_bands.doneDisbursing(); // still need to read code attrs
 996         return classes;
 997     }
 998 
 999     private int getOutputIndex(Entry e) {
1000         // Output CPs do not contain signatures.
1001         assert(e.tag != CONSTANT_Signature);
1002         int k = pkg.cp.untypedIndexOf(e);
1003         // In the output ordering, input signatures can serve
1004         // in place of Utf8s.
1005         if (k >= 0)
1006             return k;
1007         if (e.tag == CONSTANT_Utf8) {
1008             Entry se = (Entry) utf8Signatures.get(e);
1009             return pkg.cp.untypedIndexOf(se);
1010         }
1011         return -1;
1012     }
1013 
1014     Comparator<Entry> entryOutputOrder = new Comparator<>() {
1015         public int compare(Entry  e0, Entry e1) {
1016             int k0 = getOutputIndex(e0);
1017             int k1 = getOutputIndex(e1);
1018             if (k0 >= 0 && k1 >= 0)
1019                 // If both have keys, use the keys.
1020                 return k0 - k1;
1021             if (k0 == k1)
1022                 // If neither have keys, use their native tags & spellings.
1023                 return e0.compareTo(e1);
1024             // Otherwise, the guy with the key comes first.
1025             return (k0 >= 0)? 0-1: 1-0;
1026         }
1027     };
1028 
1029     void reconstructClass(Class cls) {
1030         if (verbose > 1)  Utils.log.fine("reconstruct "+cls);
1031 
1032         // check for local .ClassFile.version
1033         Attribute retroVersion = cls.getAttribute(attrClassFileVersion);
1034         if (retroVersion != null) {
1035             cls.removeAttribute(retroVersion);
1036             short[] minmajver = parseClassFileVersionAttr(retroVersion);
1037             cls.minver = minmajver[0];
1038             cls.majver = minmajver[1];
1039         } else {
1040             cls.minver = pkg.default_class_minver;
1041             cls.majver = pkg.default_class_majver;
1042         }
1043 
1044         // Replace null SourceFile by "obvious" string.
1045         cls.expandSourceFile();
1046 
1047         // record the local cp:
1048         cls.setCPMap(reconstructLocalCPMap(cls));
1049     }
1050 
1051     Entry[] reconstructLocalCPMap(Class cls) {
1052         Set<Entry> ldcRefs = ldcRefMap.get(cls);
1053         Set<Entry> cpRefs = new HashSet<>();
1054 
1055         // look for constant pool entries:
1056         cls.visitRefs(VRM_CLASSIC, cpRefs);
1057 
1058         // flesh out the local constant pool
1059         ConstantPool.completeReferencesIn(cpRefs, true);
1060 
1061         // Now that we know all our local class references,
1062         // compute the InnerClasses attribute.
1063         int changed = cls.expandLocalICs();
1064 
1065         if (changed != 0) {
1066             if (changed > 0) {
1067                 // Just visit the expanded InnerClasses attr.
1068                 cls.visitInnerClassRefs(VRM_CLASSIC, cpRefs);
1069             } else {
1070                 // Have to recompute from scratch, because of deletions.
1071                 cpRefs.clear();
1072                 cls.visitRefs(VRM_CLASSIC, cpRefs);
1073             }
1074 
1075             // flesh out the local constant pool, again
1076             ConstantPool.completeReferencesIn(cpRefs, true);
1077         }
1078 
1079         // construct a local constant pool
1080         int numDoubles = 0;
1081         for (Entry e : cpRefs) {
1082             if (e.isDoubleWord())  numDoubles++;
1083             assert(e.tag != CONSTANT_Signature) : (e);
1084         }
1085         Entry[] cpMap = new Entry[1+numDoubles+cpRefs.size()];
1086         int fillp = 1;
1087 
1088         // Add all ldc operands first.
1089         if (ldcRefs != null) {
1090             assert(cpRefs.containsAll(ldcRefs));
1091             for (Entry e : ldcRefs) {
1092                 cpMap[fillp++] = e;
1093             }
1094             assert(fillp == 1+ldcRefs.size());
1095             cpRefs.removeAll(ldcRefs);
1096             ldcRefs = null;  // done with it
1097         }
1098 
1099         // Next add all the two-byte references.
1100         Set<Entry> wideRefs = cpRefs;
1101         cpRefs = null;  // do not use!
1102         int narrowLimit = fillp;
1103         for (Entry e : wideRefs) {
1104             cpMap[fillp++] = e;
1105         }
1106         assert(fillp == narrowLimit+wideRefs.size());
1107         Arrays.sort(cpMap, 1, narrowLimit, entryOutputOrder);
1108         Arrays.sort(cpMap, narrowLimit, fillp, entryOutputOrder);
1109 
1110         if (verbose > 3) {
1111             Utils.log.fine("CP of "+this+" {");
1112             for (int i = 0; i < fillp; i++) {
1113                 Entry e = cpMap[i];
1114                 Utils.log.fine("  "+((e==null)?-1:getOutputIndex(e))
1115                                    +" : "+e);
1116             }
1117             Utils.log.fine("}");
1118         }
1119 
1120         // Now repack backwards, introducing null elements.
1121         int revp = cpMap.length;
1122         for (int i = fillp; --i >= 1; ) {
1123             Entry e = cpMap[i];
1124             if (e.isDoubleWord())
1125                 cpMap[--revp] = null;
1126             cpMap[--revp] = e;
1127         }
1128         assert(revp == 1);  // do not process the initial null
1129 
1130         return cpMap;
1131     }
1132 
1133     void readMembers(Class[] classes) throws IOException {
1134         //  class_bands:
1135         //        ...
1136         //        *class_field_count :DELTA5
1137         //        *class_method_count :DELTA5
1138         //
1139         //        *field_descr :DELTA5  (cp_Descr)
1140         //        field_attr_bands
1141         //
1142         //        *method_descr :MDELTA5  (cp_Descr)
1143         //        method_attr_bands
1144         //        ...
1145         assert(classes.length == numClasses);
1146         class_field_count.expectLength(numClasses);
1147         class_method_count.expectLength(numClasses);
1148         class_field_count.readFrom(in);
1149         class_method_count.readFrom(in);
1150 
1151         // Make a pre-pass over field and method counts to size the descrs:
1152         int totalNF = class_field_count.getIntTotal();
1153         int totalNM = class_method_count.getIntTotal();
1154         field_descr.expectLength(totalNF);
1155         method_descr.expectLength(totalNM);
1156         if (verbose > 1)  Utils.log.fine("expecting #fields="+totalNF+" and #methods="+totalNM+" in #classes="+numClasses);
1157 
1158         List<Class.Field> fields = new ArrayList<>(totalNF);
1159         field_descr.readFrom(in);
1160         for (int i = 0; i < classes.length; i++) {
1161             Class c = classes[i];
1162             int nf = class_field_count.getInt();
1163             for (int j = 0; j < nf; j++) {
1164                 Class.Field f = c.new Field(NO_FLAGS_YET, (DescriptorEntry)
1165                                             field_descr.getRef());
1166                 fields.add(f);
1167             }
1168         }
1169         class_field_count.doneDisbursing();
1170         field_descr.doneDisbursing();
1171         countAndReadAttrs(ATTR_CONTEXT_FIELD, fields);
1172         fields = null;  // release to GC
1173 
1174         List<Class.Method> methods = new ArrayList<>(totalNM);
1175         method_descr.readFrom(in);
1176         for (int i = 0; i < classes.length; i++) {
1177             Class c = classes[i];
1178             int nm = class_method_count.getInt();
1179             for (int j = 0; j < nm; j++) {
1180                 Class.Method m = c.new Method(NO_FLAGS_YET, (DescriptorEntry)
1181                                               method_descr.getRef());
1182                 methods.add(m);
1183             }
1184         }
1185         class_method_count.doneDisbursing();
1186         method_descr.doneDisbursing();
1187         countAndReadAttrs(ATTR_CONTEXT_METHOD, methods);
1188 
1189         // Up to this point, Code attributes look like empty attributes.
1190         // Now we start to special-case them.  The empty canonical Code
1191         // attributes stay in the method attribute lists, however.
1192         allCodes = buildCodeAttrs(methods);
1193     }
1194 
1195     Code[] allCodes;
1196     List<Code> codesWithFlags;
1197     Map<Class, Set<Entry>> ldcRefMap = new HashMap<>();
1198 
1199     Code[] buildCodeAttrs(List<Class.Method> methods) {
1200         List<Code> codes = new ArrayList<>(methods.size());
1201         for (Class.Method m : methods) {
1202             if (m.getAttribute(attrCodeEmpty) != null) {
1203                 m.code = new Code(m);
1204                 codes.add(m.code);
1205             }
1206         }
1207         Code[] a = new Code[codes.size()];
1208         codes.toArray(a);
1209         return a;
1210     }
1211 
1212     void readCodeHeaders() throws IOException {
1213         //  code_bands:
1214         //        *code_headers :BYTE1
1215         //
1216         //        *code_max_stack :UNSIGNED5
1217         //        *code_max_na_locals :UNSIGNED5
1218         //        *code_handler_count :UNSIGNED5
1219         //        ...
1220         //        code_attr_bands
1221         boolean attrsOK = testBit(archiveOptions, AO_HAVE_ALL_CODE_FLAGS);
1222         code_headers.expectLength(allCodes.length);
1223         code_headers.readFrom(in);
1224         List<Code> longCodes = new ArrayList<>(allCodes.length / 10);
1225         for (int i = 0; i < allCodes.length; i++) {
1226             Code c = allCodes[i];
1227             int sc = code_headers.getByte();
1228             assert(sc == (sc & 0xFF));
1229             if (verbose > 2)
1230                 Utils.log.fine("codeHeader "+c+" = "+sc);
1231             if (sc == LONG_CODE_HEADER) {
1232                 // We will read ms/ml/nh/flags from bands shortly.
1233                 longCodes.add(c);
1234                 continue;
1235             }
1236             // Short code header is the usual case:
1237             c.setMaxStack(     shortCodeHeader_max_stack(sc) );
1238             c.setMaxNALocals(  shortCodeHeader_max_na_locals(sc) );
1239             c.setHandlerCount( shortCodeHeader_handler_count(sc) );
1240             assert(shortCodeHeader(c) == sc);
1241         }
1242         code_headers.doneDisbursing();
1243         code_max_stack.expectLength(longCodes.size());
1244         code_max_na_locals.expectLength(longCodes.size());
1245         code_handler_count.expectLength(longCodes.size());
1246 
1247         // Do the long headers now.
1248         code_max_stack.readFrom(in);
1249         code_max_na_locals.readFrom(in);
1250         code_handler_count.readFrom(in);
1251         for (Code c : longCodes) {
1252             c.setMaxStack(     code_max_stack.getInt() );
1253             c.setMaxNALocals(  code_max_na_locals.getInt() );
1254             c.setHandlerCount( code_handler_count.getInt() );
1255         }
1256         code_max_stack.doneDisbursing();
1257         code_max_na_locals.doneDisbursing();
1258         code_handler_count.doneDisbursing();
1259 
1260         readCodeHandlers();
1261 
1262         if (attrsOK) {
1263             // Code attributes are common (debug info not stripped).
1264             codesWithFlags = Arrays.asList(allCodes);
1265         } else {
1266             // Code attributes are very sparse (debug info is stripped).
1267             codesWithFlags = longCodes;
1268         }
1269         countAttrs(ATTR_CONTEXT_CODE, codesWithFlags);
1270         // do readAttrs later, after BCs are scanned
1271     }
1272 
1273     void readCodeHandlers() throws IOException {
1274         //  code_bands:
1275         //        ...
1276         //        *code_handler_start_P :BCI5
1277         //        *code_handler_end_PO :BRANCH5
1278         //        *code_handler_catch_PO :BRANCH5
1279         //        *code_handler_class_RCN :UNSIGNED5  (null or cp_Class)
1280         //        ...
1281         int nh = 0;
1282         for (int i = 0; i < allCodes.length; i++) {
1283             Code c = allCodes[i];
1284             nh += c.getHandlerCount();
1285         }
1286 
1287         ValueBand[] code_handler_bands = {
1288             code_handler_start_P,
1289             code_handler_end_PO,
1290             code_handler_catch_PO,
1291             code_handler_class_RCN
1292         };
1293 
1294         for (int i = 0; i < code_handler_bands.length; i++) {
1295             code_handler_bands[i].expectLength(nh);
1296             code_handler_bands[i].readFrom(in);
1297         }
1298 
1299         for (int i = 0; i < allCodes.length; i++) {
1300             Code c = allCodes[i];
1301             for (int j = 0, jmax = c.getHandlerCount(); j < jmax; j++) {
1302                 c.handler_class[j] = code_handler_class_RCN.getRef();
1303                 // For now, just record the raw BCI codes.
1304                 // We must wait until we have instruction boundaries.
1305                 c.handler_start[j] = code_handler_start_P.getInt();
1306                 c.handler_end[j]   = code_handler_end_PO.getInt();
1307                 c.handler_catch[j] = code_handler_catch_PO.getInt();
1308             }
1309         }
1310         for (int i = 0; i < code_handler_bands.length; i++) {
1311             code_handler_bands[i].doneDisbursing();
1312         }
1313     }
1314 
1315     void fixupCodeHandlers() {
1316         // Actually decode (renumber) the BCIs now.
1317         for (int i = 0; i < allCodes.length; i++) {
1318             Code c = allCodes[i];
1319             for (int j = 0, jmax = c.getHandlerCount(); j < jmax; j++) {
1320                 int sum = c.handler_start[j];
1321                 c.handler_start[j] = c.decodeBCI(sum);
1322                 sum += c.handler_end[j];
1323                 c.handler_end[j]   = c.decodeBCI(sum);
1324                 sum += c.handler_catch[j];
1325                 c.handler_catch[j] = c.decodeBCI(sum);
1326             }
1327         }
1328     }
1329 
1330     // Generic routines for reading attributes of
1331     // classes, fields, methods, and codes.
1332     // The holders is a global list, already collected,
1333     // of attribute "customers".
1334     void countAndReadAttrs(int ctype, Collection holders) throws IOException {
1335         //  class_attr_bands:
1336         //        *class_flags :UNSIGNED5
1337         //        *class_attr_count :UNSIGNED5
1338         //        *class_attr_indexes :UNSIGNED5
1339         //        *class_attr_calls :UNSIGNED5
1340         //        *class_Signature_RS :UNSIGNED5 (cp_Signature)
1341         //        class_metadata_bands
1342         //        *class_SourceFile_RU :UNSIGNED5 (cp_Utf8)
1343         //        *class_EnclosingMethod_RM :UNSIGNED5 (cp_Method)
1344         //        ic_local_bands
1345         //        *class_ClassFile_version_minor_H :UNSIGNED5
1346         //        *class_ClassFile_version_major_H :UNSIGNED5
1347         //
1348         //  field_attr_bands:
1349         //        *field_flags :UNSIGNED5
1350         //        *field_attr_count :UNSIGNED5
1351         //        *field_attr_indexes :UNSIGNED5
1352         //        *field_attr_calls :UNSIGNED5
1353         //        *field_Signature_RS :UNSIGNED5 (cp_Signature)
1354         //        field_metadata_bands
1355         //        *field_ConstantValue_KQ :UNSIGNED5 (cp_Int, etc.; see note)
1356         //
1357         //  method_attr_bands:
1358         //        *method_flags :UNSIGNED5
1359         //        *method_attr_count :UNSIGNED5
1360         //        *method_attr_indexes :UNSIGNED5
1361         //        *method_attr_calls :UNSIGNED5
1362         //        *method_Signature_RS :UNSIGNED5 (cp_Signature)
1363         //        method_metadata_bands
1364         //        *method_Exceptions_N :UNSIGNED5
1365         //        *method_Exceptions_RC :UNSIGNED5  (cp_Class)
1366         //
1367         //  code_attr_bands:
1368         //        *code_flags :UNSIGNED5
1369         //        *code_attr_count :UNSIGNED5
1370         //        *code_attr_indexes :UNSIGNED5
1371         //        *code_attr_calls :UNSIGNED5
1372         //        *code_LineNumberTable_N :UNSIGNED5
1373         //        *code_LineNumberTable_bci_P :BCI5
1374         //        *code_LineNumberTable_line :UNSIGNED5
1375         //        *code_LocalVariableTable_N :UNSIGNED5
1376         //        *code_LocalVariableTable_bci_P :BCI5
1377         //        *code_LocalVariableTable_span_O :BRANCH5
1378         //        *code_LocalVariableTable_name_RU :UNSIGNED5 (cp_Utf8)
1379         //        *code_LocalVariableTable_type_RS :UNSIGNED5 (cp_Signature)
1380         //        *code_LocalVariableTable_slot :UNSIGNED5
1381 
1382         countAttrs(ctype, holders);
1383         readAttrs(ctype, holders);
1384     }
1385 
1386     // Read flags and count the attributes that are to be placed
1387     // on the given holders.
1388     void countAttrs(int ctype, Collection holders) throws IOException {
1389         // Here, xxx stands for one of class, field, method, code.
1390         MultiBand xxx_attr_bands = attrBands[ctype];
1391         long flagMask = attrFlagMask[ctype];
1392         if (verbose > 1) {
1393             Utils.log.fine("scanning flags and attrs for "+Attribute.contextName(ctype)+"["+holders.size()+"]");
1394         }
1395 
1396         // Fetch the attribute layout definitions which govern the bands
1397         // we are about to read.
1398         List<Attribute.Layout> defList = attrDefs.get(ctype);
1399         Attribute.Layout[] defs = new Attribute.Layout[defList.size()];
1400         defList.toArray(defs);
1401         IntBand xxx_flags_hi = getAttrBand(xxx_attr_bands, AB_FLAGS_HI);
1402         IntBand xxx_flags_lo = getAttrBand(xxx_attr_bands, AB_FLAGS_LO);
1403         IntBand xxx_attr_count = getAttrBand(xxx_attr_bands, AB_ATTR_COUNT);
1404         IntBand xxx_attr_indexes = getAttrBand(xxx_attr_bands, AB_ATTR_INDEXES);
1405         IntBand xxx_attr_calls = getAttrBand(xxx_attr_bands, AB_ATTR_CALLS);
1406 
1407         // Count up the number of holders which have overflow attrs.
1408         int overflowMask = attrOverflowMask[ctype];
1409         int overflowHolderCount = 0;
1410         boolean haveLongFlags = haveFlagsHi(ctype);
1411         xxx_flags_hi.expectLength(haveLongFlags? holders.size(): 0);
1412         xxx_flags_hi.readFrom(in);
1413         xxx_flags_lo.expectLength(holders.size());
1414         xxx_flags_lo.readFrom(in);
1415         assert((flagMask & overflowMask) == overflowMask);
1416         for (Iterator i = holders.iterator(); i.hasNext(); ) {
1417             Attribute.Holder h = (Attribute.Holder) i.next();
1418             int flags = xxx_flags_lo.getInt();
1419             h.flags = flags;
1420             if ((flags & overflowMask) != 0)
1421                 overflowHolderCount += 1;
1422         }
1423 
1424         // For each holder with overflow attrs, read a count.
1425         xxx_attr_count.expectLength(overflowHolderCount);
1426         xxx_attr_count.readFrom(in);
1427         xxx_attr_indexes.expectLength(xxx_attr_count.getIntTotal());
1428         xxx_attr_indexes.readFrom(in);
1429 
1430         // Now it's time to check flag bits that indicate attributes.
1431         // We accumulate (a) a list of attribute types for each holder
1432         // (class/field/method/code), and also we accumulate (b) a total
1433         // count for each attribute type.
1434         int[] totalCounts = new int[defs.length];
1435         for (Iterator i = holders.iterator(); i.hasNext(); ) {
1436             Attribute.Holder h = (Attribute.Holder) i.next();
1437             assert(h.attributes == null);
1438             // System.out.println("flags="+h.flags+" using fm="+flagMask);
1439             long attrBits = ((h.flags & flagMask) << 32) >>> 32;
1440             // Clean up the flags now.
1441             h.flags -= (int)attrBits;   // strip attr bits
1442             assert(h.flags == (char)h.flags);  // 16 bits only now
1443             assert((ctype != ATTR_CONTEXT_CODE) || h.flags == 0);
1444             if (haveLongFlags)
1445                 attrBits += (long)xxx_flags_hi.getInt() << 32;
1446             if (attrBits == 0)  continue;  // no attrs on this guy
1447 
1448             int noa = 0;  // number of overflow attrs
1449             long overflowBit = (attrBits & overflowMask);
1450             assert(overflowBit >= 0);
1451             attrBits -= overflowBit;
1452             if (overflowBit != 0) {
1453                 noa = xxx_attr_count.getInt();
1454             }
1455 
1456             int nfa = 0;  // number of flag attrs
1457             long bits = attrBits;
1458             for (int ai = 0; bits != 0; ai++) {
1459                 if ((bits & (1L<<ai)) == 0)  continue;
1460                 bits -= (1L<<ai);
1461                 nfa += 1;
1462             }
1463             List<Attribute> ha = new ArrayList<>(nfa + noa);
1464             h.attributes = ha;
1465             bits = attrBits;  // iterate again
1466             for (int ai = 0; bits != 0; ai++) {
1467                 if ((bits & (1L<<ai)) == 0)  continue;
1468                 bits -= (1L<<ai);
1469                 totalCounts[ai] += 1;
1470                 // This definition index is live in this holder.
1471                 if (defs[ai] == null)  badAttrIndex(ai, ctype);
1472                 Attribute canonical = defs[ai].canonicalInstance();
1473                 ha.add(canonical);
1474                 nfa -= 1;
1475             }
1476             assert(nfa == 0);
1477             for (; noa > 0; noa--) {
1478                 int ai = xxx_attr_indexes.getInt();
1479                 totalCounts[ai] += 1;
1480                 // This definition index is live in this holder.
1481                 if (defs[ai] == null)  badAttrIndex(ai, ctype);
1482                 Attribute canonical = defs[ai].canonicalInstance();
1483                 ha.add(canonical);
1484             }
1485         }
1486 
1487         xxx_flags_hi.doneDisbursing();
1488         xxx_flags_lo.doneDisbursing();
1489         xxx_attr_count.doneDisbursing();
1490         xxx_attr_indexes.doneDisbursing();
1491 
1492         // Now each holder has a list of canonical attribute instances.
1493         // For layouts with no elements, we are done.  However, for
1494         // layouts with bands, we must replace each canonical (empty)
1495         // instance with a value-bearing one, initialized from the
1496         // appropriate bands.
1497 
1498         // Make a small pass to detect and read backward call counts.
1499         int callCounts = 0;
1500         for (boolean predef = true; ; predef = false) {
1501             for (int ai = 0; ai < defs.length; ai++) {
1502                 Attribute.Layout def = defs[ai];
1503                 if (def == null)  continue;  // unused index
1504                 if (predef != isPredefinedAttr(ctype, ai))
1505                     continue;  // wrong pass
1506                 int totalCount = totalCounts[ai];
1507                 if (totalCount == 0)
1508                     continue;  // irrelevant
1509                 Attribute.Layout.Element[] cbles = def.getCallables();
1510                 for (int j = 0; j < cbles.length; j++) {
1511                     assert(cbles[j].kind == Attribute.EK_CBLE);
1512                     if (cbles[j].flagTest(Attribute.EF_BACK))
1513                         callCounts += 1;
1514                 }
1515             }
1516             if (!predef)  break;
1517         }
1518         xxx_attr_calls.expectLength(callCounts);
1519         xxx_attr_calls.readFrom(in);
1520 
1521         // Finally, size all the attribute bands.
1522         for (boolean predef = true; ; predef = false) {
1523             for (int ai = 0; ai < defs.length; ai++) {
1524                 Attribute.Layout def = defs[ai];
1525                 if (def == null)  continue;  // unused index
1526                 if (predef != isPredefinedAttr(ctype, ai))
1527                     continue;  // wrong pass
1528                 int totalCount = totalCounts[ai];
1529                 Band[] ab = attrBandTable.get(def);
1530                 if (def == attrInnerClassesEmpty) {
1531                     // Special case.
1532                     // Size the bands as if using the following layout:
1533                     //    [RCH TI[ (0)[] ()[RCNH RUNH] ]].
1534                     class_InnerClasses_N.expectLength(totalCount);
1535                     class_InnerClasses_N.readFrom(in);
1536                     int tupleCount = class_InnerClasses_N.getIntTotal();
1537                     class_InnerClasses_RC.expectLength(tupleCount);
1538                     class_InnerClasses_RC.readFrom(in);
1539                     class_InnerClasses_F.expectLength(tupleCount);
1540                     class_InnerClasses_F.readFrom(in);
1541                     // Drop remaining columns wherever flags are zero:
1542                     tupleCount -= class_InnerClasses_F.getIntCount(0);
1543                     class_InnerClasses_outer_RCN.expectLength(tupleCount);
1544                     class_InnerClasses_outer_RCN.readFrom(in);
1545                     class_InnerClasses_name_RUN.expectLength(tupleCount);
1546                     class_InnerClasses_name_RUN.readFrom(in);
1547                 } else if (totalCount == 0) {
1548                     // Expect no elements at all.  Skip quickly.
1549                     for (int j = 0; j < ab.length; j++) {
1550                         ab[j].doneWithUnusedBand();
1551                     }
1552                 } else {
1553                     // Read these bands in sequence.
1554                     boolean hasCallables = def.hasCallables();
1555                     if (!hasCallables) {
1556                         readAttrBands(def.elems, totalCount, new int[0], ab);
1557                     } else {
1558                         Attribute.Layout.Element[] cbles = def.getCallables();
1559                         // At first, record initial calls.
1560                         // Later, forward calls may also accumulate here:
1561                         int[] forwardCounts = new int[cbles.length];
1562                         forwardCounts[0] = totalCount;
1563                         for (int j = 0; j < cbles.length; j++) {
1564                             assert(cbles[j].kind == Attribute.EK_CBLE);
1565                             int entryCount = forwardCounts[j];
1566                             forwardCounts[j] = -1;  // No more, please!
1567                             if (cbles[j].flagTest(Attribute.EF_BACK))
1568                                 entryCount += xxx_attr_calls.getInt();
1569                             readAttrBands(cbles[j].body, entryCount, forwardCounts, ab);
1570                         }
1571                     }
1572                 }
1573             }
1574             if (!predef)  break;
1575         }
1576         xxx_attr_calls.doneDisbursing();
1577     }
1578 
1579     void badAttrIndex(int ai, int ctype) throws IOException {
1580         throw new IOException("Unknown attribute index "+ai+" for "+
1581                                    ATTR_CONTEXT_NAME[ctype]+" attribute");
1582     }
1583 
1584     @SuppressWarnings("unchecked")
1585     void readAttrs(int ctype, Collection holders) throws IOException {
1586         // Decode band values into attributes.
1587         Set<Attribute.Layout> sawDefs = new HashSet<>();
1588         ByteArrayOutputStream buf = new ByteArrayOutputStream();
1589         for (Iterator i = holders.iterator(); i.hasNext(); ) {
1590             final Attribute.Holder h = (Attribute.Holder) i.next();
1591             if (h.attributes == null)  continue;
1592             for (ListIterator<Attribute> j = h.attributes.listIterator(); j.hasNext(); ) {
1593                 Attribute a = j.next();
1594                 Attribute.Layout def = a.layout();
1595                 if (def.bandCount == 0) {
1596                     if (def == attrInnerClassesEmpty) {
1597                         // Special logic to read this attr.
1598                         readLocalInnerClasses((Class) h);
1599                         continue;
1600                     }
1601                     // Canonical empty attr works fine (e.g., Synthetic).
1602                     continue;
1603                 }
1604                 sawDefs.add(def);
1605                 boolean isCV = (ctype == ATTR_CONTEXT_FIELD && def == attrConstantValue);
1606                 if (isCV)  setConstantValueIndex((Class.Field)h);
1607                 if (verbose > 2)
1608                     Utils.log.fine("read "+a+" in "+h);
1609                 final Band[] ab = attrBandTable.get(def);
1610                 // Read one attribute of type def from ab into a byte array.
1611                 buf.reset();
1612                 Object fixups = a.unparse(new Attribute.ValueStream() {
1613                     public int getInt(int bandIndex) {
1614                         return ((IntBand) ab[bandIndex]).getInt();
1615                     }
1616                     public Entry getRef(int bandIndex) {
1617                         return ((CPRefBand) ab[bandIndex]).getRef();
1618                     }
1619                     public int decodeBCI(int bciCode) {
1620                         Code code = (Code) h;
1621                         return code.decodeBCI(bciCode);
1622                     }
1623                 }, buf);
1624                 // Replace the canonical attr with the one just read.
1625                 j.set(a.addContent(buf.toByteArray(), fixups));
1626                 if (isCV)  setConstantValueIndex(null);  // clean up
1627             }
1628         }
1629 
1630         // Mark the bands we just used as done disbursing.
1631         for (Attribute.Layout def : sawDefs) {
1632             if (def == null)  continue;  // unused index
1633             Band[] ab = attrBandTable.get(def);
1634             for (int j = 0; j < ab.length; j++) {
1635                 ab[j].doneDisbursing();
1636             }
1637         }
1638 
1639         if (ctype == ATTR_CONTEXT_CLASS) {
1640             class_InnerClasses_N.doneDisbursing();
1641             class_InnerClasses_RC.doneDisbursing();
1642             class_InnerClasses_F.doneDisbursing();
1643             class_InnerClasses_outer_RCN.doneDisbursing();
1644             class_InnerClasses_name_RUN.doneDisbursing();
1645         }
1646 
1647         MultiBand xxx_attr_bands = attrBands[ctype];
1648         for (int i = 0; i < xxx_attr_bands.size(); i++) {
1649             Band b = xxx_attr_bands.get(i);
1650             if (b instanceof MultiBand)
1651                 b.doneDisbursing();
1652         }
1653         xxx_attr_bands.doneDisbursing();
1654     }
1655 
1656     private
1657     void readAttrBands(Attribute.Layout.Element[] elems,
1658                        int count, int[] forwardCounts,
1659                        Band[] ab)
1660             throws IOException {
1661         for (int i = 0; i < elems.length; i++) {
1662             Attribute.Layout.Element e = elems[i];
1663             Band eBand = null;
1664             if (e.hasBand()) {
1665                 eBand = ab[e.bandIndex];
1666                 eBand.expectLength(count);
1667                 eBand.readFrom(in);
1668             }
1669             switch (e.kind) {
1670             case Attribute.EK_REPL:
1671                 // Recursive call.
1672                 int repCount = ((IntBand)eBand).getIntTotal();
1673                 // Note:  getIntTotal makes an extra pass over this band.
1674                 readAttrBands(e.body, repCount, forwardCounts, ab);
1675                 break;
1676             case Attribute.EK_UN:
1677                 int remainingCount = count;
1678                 for (int j = 0; j < e.body.length; j++) {
1679                     int caseCount;
1680                     if (j == e.body.length-1) {
1681                         caseCount = remainingCount;
1682                     } else {
1683                         caseCount = 0;
1684                         for (int j0 = j;
1685                              (j == j0)
1686                              || (j < e.body.length
1687                                  && e.body[j].flagTest(Attribute.EF_BACK));
1688                              j++) {
1689                             caseCount += ((IntBand)eBand).getIntCount(e.body[j].value);
1690                         }
1691                         --j;  // back up to last occurrence of this body
1692                     }
1693                     remainingCount -= caseCount;
1694                     readAttrBands(e.body[j].body, caseCount, forwardCounts, ab);
1695                 }
1696                 assert(remainingCount == 0);
1697                 break;
1698             case Attribute.EK_CALL:
1699                 assert(e.body.length == 1);
1700                 assert(e.body[0].kind == Attribute.EK_CBLE);
1701                 if (!e.flagTest(Attribute.EF_BACK)) {
1702                     // Backward calls are pre-counted, but forwards are not.
1703                     // Push the present count forward.
1704                     assert(forwardCounts[e.value] >= 0);
1705                     forwardCounts[e.value] += count;
1706                 }
1707                 break;
1708             case Attribute.EK_CBLE:
1709                 assert(false);
1710                 break;
1711             }
1712         }
1713     }
1714 
1715     void readByteCodes() throws IOException {
1716         //  bc_bands:
1717         //        *bc_codes :BYTE1
1718         //        *bc_case_count :UNSIGNED5
1719         //        *bc_case_value :DELTA5
1720         //        *bc_byte :BYTE1
1721         //        *bc_short :DELTA5
1722         //        *bc_local :UNSIGNED5
1723         //        *bc_label :BRANCH5
1724         //        *bc_intref :DELTA5  (cp_Int)
1725         //        *bc_floatref :DELTA5  (cp_Float)
1726         //        *bc_longref :DELTA5  (cp_Long)
1727         //        *bc_doubleref :DELTA5  (cp_Double)
1728         //        *bc_stringref :DELTA5  (cp_String)
1729         //        *bc_classref :UNSIGNED5  (current class or cp_Class)
1730         //        *bc_fieldref :DELTA5  (cp_Field)
1731         //        *bc_methodref :UNSIGNED5  (cp_Method)
1732         //        *bc_imethodref :DELTA5  (cp_Imethod)
1733         //        *bc_thisfield :UNSIGNED5 (cp_Field, only for current class)
1734         //        *bc_superfield :UNSIGNED5 (cp_Field, only for current super)
1735         //        *bc_thismethod :UNSIGNED5 (cp_Method, only for current class)
1736         //        *bc_supermethod :UNSIGNED5 (cp_Method, only for current super)
1737         //        *bc_initref :UNSIGNED5 (cp_Field, only for most recent new)
1738         //        *bc_escref :UNSIGNED5 (cp_All)
1739         //        *bc_escrefsize :UNSIGNED5
1740         //        *bc_escsize :UNSIGNED5
1741         //        *bc_escbyte :BYTE1
1742         bc_codes.elementCountForDebug = allCodes.length;
1743         bc_codes.setInputStreamFrom(in);
1744         readByteCodeOps();  // reads from bc_codes and bc_case_count
1745         bc_codes.doneDisbursing();
1746 
1747         // All the operand bands have now been sized.  Read them all in turn.
1748         Band[] operand_bands = {
1749             bc_case_value,
1750             bc_byte, bc_short,
1751             bc_local, bc_label,
1752             bc_intref, bc_floatref,
1753             bc_longref, bc_doubleref, bc_stringref,
1754             bc_classref, bc_fieldref,
1755             bc_methodref, bc_imethodref,
1756             bc_thisfield, bc_superfield,
1757             bc_thismethod, bc_supermethod,
1758             bc_initref,
1759             bc_escref, bc_escrefsize, bc_escsize
1760         };
1761         for (int i = 0; i < operand_bands.length; i++) {
1762             operand_bands[i].readFrom(in);
1763         }
1764         bc_escbyte.expectLength(bc_escsize.getIntTotal());
1765         bc_escbyte.readFrom(in);
1766 
1767         expandByteCodeOps();
1768 
1769         // Done fetching values from operand bands:
1770         bc_case_count.doneDisbursing();
1771         for (int i = 0; i < operand_bands.length; i++) {
1772             operand_bands[i].doneDisbursing();
1773         }
1774         bc_escbyte.doneDisbursing();
1775         bc_bands.doneDisbursing();
1776 
1777         // We must delay the parsing of Code attributes until we
1778         // have a complete model of bytecodes, for BCI encodings.
1779         readAttrs(ATTR_CONTEXT_CODE, codesWithFlags);
1780         // Ditto for exception handlers in codes.
1781         fixupCodeHandlers();
1782         // Now we can finish with class_bands; cf. readClasses().
1783         code_bands.doneDisbursing();
1784         class_bands.doneDisbursing();
1785     }
1786 
1787     private void readByteCodeOps() throws IOException {
1788         // scratch buffer for collecting code::
1789         byte[] buf = new byte[1<<12];
1790         // record of all switch opcodes (these are variable-length)
1791         List<Integer> allSwitchOps = new ArrayList<>();
1792         for (int k = 0; k < allCodes.length; k++) {
1793             Code c = allCodes[k];
1794         scanOneMethod:
1795             for (int i = 0; ; i++) {
1796                 int bc = bc_codes.getByte();
1797                 if (i + 10 > buf.length)  buf = realloc(buf);
1798                 buf[i] = (byte)bc;
1799                 boolean isWide = false;
1800                 if (bc == _wide) {
1801                     bc = bc_codes.getByte();
1802                     buf[++i] = (byte)bc;
1803                     isWide = true;
1804                 }
1805                 assert(bc == (0xFF & bc));
1806                 // Adjust expectations of various band sizes.
1807                 switch (bc) {
1808                 case _tableswitch:
1809                 case _lookupswitch:
1810                     bc_case_count.expectMoreLength(1);
1811                     allSwitchOps.add(bc);
1812                     break;
1813                 case _iinc:
1814                     bc_local.expectMoreLength(1);
1815                     if (isWide)
1816                         bc_short.expectMoreLength(1);
1817                     else
1818                         bc_byte.expectMoreLength(1);
1819                     break;
1820                 case _sipush:
1821                     bc_short.expectMoreLength(1);
1822                     break;
1823                 case _bipush:
1824                     bc_byte.expectMoreLength(1);
1825                     break;
1826                 case _newarray:
1827                     bc_byte.expectMoreLength(1);
1828                     break;
1829                 case _multianewarray:
1830                     assert(getCPRefOpBand(bc) == bc_classref);
1831                     bc_classref.expectMoreLength(1);
1832                     bc_byte.expectMoreLength(1);
1833                     break;
1834                 case _ref_escape:
1835                     bc_escrefsize.expectMoreLength(1);
1836                     bc_escref.expectMoreLength(1);
1837                     break;
1838                 case _byte_escape:
1839                     bc_escsize.expectMoreLength(1);
1840                     // bc_escbyte will have to be counted too
1841                     break;
1842                 default:
1843                     if (Instruction.isInvokeInitOp(bc)) {
1844                         bc_initref.expectMoreLength(1);
1845                         break;
1846                     }
1847                     if (Instruction.isSelfLinkerOp(bc)) {
1848                         CPRefBand bc_which = selfOpRefBand(bc);
1849                         bc_which.expectMoreLength(1);
1850                         break;
1851                     }
1852                     if (Instruction.isBranchOp(bc)) {
1853                         bc_label.expectMoreLength(1);
1854                         break;
1855                     }
1856                     if (Instruction.isCPRefOp(bc)) {
1857                         CPRefBand bc_which = getCPRefOpBand(bc);
1858                         bc_which.expectMoreLength(1);
1859                         assert(bc != _multianewarray);  // handled elsewhere
1860                         break;
1861                     }
1862                     if (Instruction.isLocalSlotOp(bc)) {
1863                         bc_local.expectMoreLength(1);
1864                         break;
1865                     }
1866                     break;
1867                 case _end_marker:
1868                     {
1869                         // Transfer from buf to a more permanent place:
1870                         c.bytes = realloc(buf, i);
1871                         break scanOneMethod;
1872                     }
1873                 }
1874             }
1875         }
1876 
1877         // To size instruction bands correctly, we need info on switches:
1878         bc_case_count.readFrom(in);
1879         for (Integer i : allSwitchOps) {
1880             int bc = i.intValue();
1881             int caseCount = bc_case_count.getInt();
1882             bc_label.expectMoreLength(1+caseCount); // default label + cases
1883             bc_case_value.expectMoreLength(bc == _tableswitch ? 1 : caseCount);
1884         }
1885         bc_case_count.resetForSecondPass();
1886     }
1887 
1888     private void expandByteCodeOps() throws IOException {
1889         // scratch buffer for collecting code:
1890         byte[] buf = new byte[1<<12];
1891         // scratch buffer for collecting instruction boundaries:
1892         int[] insnMap = new int[1<<12];
1893         // list of label carriers, for label decoding post-pass:
1894         int[] labels = new int[1<<10];
1895         // scratch buffer for registering CP refs:
1896         Fixups fixupBuf = new Fixups();
1897 
1898         for (int k = 0; k < allCodes.length; k++) {
1899             Code code = allCodes[k];
1900             byte[] codeOps = code.bytes;
1901             code.bytes = null;  // just for now, while we accumulate bits
1902 
1903             Class curClass = code.thisClass();
1904 
1905             Set<Entry> ldcRefSet = ldcRefMap.get(curClass);
1906             if (ldcRefSet == null)
1907                 ldcRefMap.put(curClass, ldcRefSet = new HashSet<>());
1908 
1909             ClassEntry thisClass  = curClass.thisClass;
1910             ClassEntry superClass = curClass.superClass;
1911             ClassEntry newClass   = null;  // class of last _new opcode
1912 
1913             int pc = 0;  // fill pointer in buf; actual bytecode PC
1914             int numInsns = 0;
1915             int numLabels = 0;
1916             boolean hasEscs = false;
1917             fixupBuf.clear();
1918             for (int i = 0; i < codeOps.length; i++) {
1919                 int bc = Instruction.getByte(codeOps, i);
1920                 int curPC = pc;
1921                 insnMap[numInsns++] = curPC;
1922                 if (pc + 10 > buf.length)  buf = realloc(buf);
1923                 if (numInsns+10 > insnMap.length)  insnMap = realloc(insnMap);
1924                 if (numLabels+10 > labels.length)  labels = realloc(labels);
1925                 boolean isWide = false;
1926                 if (bc == _wide) {
1927                     buf[pc++] = (byte) bc;
1928                     bc = Instruction.getByte(codeOps, ++i);
1929                     isWide = true;
1930                 }
1931                 switch (bc) {
1932                 case _tableswitch: // apc:  (df, lo, hi, (hi-lo+1)*(label))
1933                 case _lookupswitch: // apc:  (df, nc, nc*(case, label))
1934                     {
1935                         int caseCount = bc_case_count.getInt();
1936                         while ((pc + 30 + caseCount*8) > buf.length)
1937                             buf = realloc(buf);
1938                         buf[pc++] = (byte) bc;
1939                         //initialize apc, df, lo, hi bytes to reasonable bits:
1940                         Arrays.fill(buf, pc, pc+30, (byte)0);
1941                         Instruction.Switch isw = (Instruction.Switch)
1942                             Instruction.at(buf, curPC);
1943                         //isw.setDefaultLabel(getLabel(bc_label, code, curPC));
1944                         isw.setCaseCount(caseCount);
1945                         if (bc == _tableswitch) {
1946                             isw.setCaseValue(0, bc_case_value.getInt());
1947                         } else {
1948                             for (int j = 0; j < caseCount; j++) {
1949                                 isw.setCaseValue(j, bc_case_value.getInt());
1950                             }
1951                         }
1952                         // Make our getLabel calls later.
1953                         labels[numLabels++] = curPC;
1954                         pc = isw.getNextPC();
1955                         continue;
1956                     }
1957                 case _iinc:
1958                     {
1959                         buf[pc++] = (byte) bc;
1960                         int local = bc_local.getInt();
1961                         int delta;
1962                         if (isWide) {
1963                             delta = bc_short.getInt();
1964                             Instruction.setShort(buf, pc, local); pc += 2;
1965                             Instruction.setShort(buf, pc, delta); pc += 2;
1966                         } else {
1967                             delta = (byte) bc_byte.getByte();
1968                             buf[pc++] = (byte)local;
1969                             buf[pc++] = (byte)delta;
1970                         }
1971                         continue;
1972                     }
1973                 case _sipush:
1974                     {
1975                         int val = bc_short.getInt();
1976                         buf[pc++] = (byte) bc;
1977                         Instruction.setShort(buf, pc, val); pc += 2;
1978                         continue;
1979                     }
1980                 case _bipush:
1981                 case _newarray:
1982                     {
1983                         int val = bc_byte.getByte();
1984                         buf[pc++] = (byte) bc;
1985                         buf[pc++] = (byte) val;
1986                         continue;
1987                     }
1988                 case _ref_escape:
1989                     {
1990                         // Note that insnMap has one entry for this.
1991                         hasEscs = true;
1992                         int size = bc_escrefsize.getInt();
1993                         Entry ref = bc_escref.getRef();
1994                         if (size == 1)  ldcRefSet.add(ref);
1995                         int fmt;
1996                         switch (size) {
1997                         case 1: fmt = Fixups.U1_FORMAT; break;
1998                         case 2: fmt = Fixups.U2_FORMAT; break;
1999                         default: assert(false); fmt = 0;
2000                         }
2001                         fixupBuf.add(pc, fmt, ref);
2002                         buf[pc+0] = buf[pc+1] = 0;
2003                         pc += size;
2004                     }
2005                     continue;
2006                 case _byte_escape:
2007                     {
2008                         // Note that insnMap has one entry for all these bytes.
2009                         hasEscs = true;
2010                         int size = bc_escsize.getInt();
2011                         while ((pc + size) > buf.length)
2012                             buf = realloc(buf);
2013                         while (size-- > 0) {
2014                             buf[pc++] = (byte) bc_escbyte.getByte();
2015                         }
2016                     }
2017                     continue;
2018                 default:
2019                     if (Instruction.isInvokeInitOp(bc)) {
2020                         int idx = (bc - _invokeinit_op);
2021                         int origBC = _invokespecial;
2022                         ClassEntry classRef;
2023                         switch (idx) {
2024                         case _invokeinit_self_option:
2025                             classRef = thisClass; break;
2026                         case _invokeinit_super_option:
2027                             classRef = superClass; break;
2028                         default:
2029                             assert(idx == _invokeinit_new_option);
2030                             classRef = newClass; break;
2031                         }
2032                         buf[pc++] = (byte) origBC;
2033                         int coding = bc_initref.getInt();
2034                         // Find the nth overloading of <init> in classRef.
2035                         MemberEntry ref = pkg.cp.getOverloadingForIndex(CONSTANT_Methodref, classRef, "<init>", coding);
2036                         fixupBuf.add(pc, Fixups.U2_FORMAT, ref);
2037                         buf[pc+0] = buf[pc+1] = 0;
2038                         pc += 2;
2039                         assert(Instruction.opLength(origBC) == (pc - curPC));
2040                         continue;
2041                     }
2042                     if (Instruction.isSelfLinkerOp(bc)) {
2043                         int idx = (bc - _self_linker_op);
2044                         boolean isSuper = (idx >= _self_linker_super_flag);
2045                         if (isSuper)  idx -= _self_linker_super_flag;
2046                         boolean isAload = (idx >= _self_linker_aload_flag);
2047                         if (isAload)  idx -= _self_linker_aload_flag;
2048                         int origBC = _first_linker_op + idx;
2049                         boolean isField = Instruction.isFieldOp(origBC);
2050                         CPRefBand bc_which;
2051                         ClassEntry which_cls  = isSuper ? superClass : thisClass;
2052                         Index which_ix;
2053                         if (isField) {
2054                             bc_which = isSuper ? bc_superfield  : bc_thisfield;
2055                             which_ix = pkg.cp.getMemberIndex(CONSTANT_Fieldref, which_cls);
2056                         } else {
2057                             bc_which = isSuper ? bc_supermethod : bc_thismethod;
2058                             which_ix = pkg.cp.getMemberIndex(CONSTANT_Methodref, which_cls);
2059                         }
2060                         assert(bc_which == selfOpRefBand(bc));
2061                         MemberEntry ref = (MemberEntry) bc_which.getRef(which_ix);
2062                         if (isAload) {
2063                             buf[pc++] = (byte) _aload_0;
2064                             curPC = pc;
2065                             // Note: insnMap keeps the _aload_0 separate.
2066                             insnMap[numInsns++] = curPC;
2067                         }
2068                         buf[pc++] = (byte) origBC;
2069                         fixupBuf.add(pc, Fixups.U2_FORMAT, ref);
2070                         buf[pc+0] = buf[pc+1] = 0;
2071                         pc += 2;
2072                         assert(Instruction.opLength(origBC) == (pc - curPC));
2073                         continue;
2074                     }
2075                     if (Instruction.isBranchOp(bc)) {
2076                         buf[pc++] = (byte) bc;
2077                         assert(!isWide);  // no wide prefix for branches
2078                         int nextPC = curPC + Instruction.opLength(bc);
2079                         // Make our getLabel calls later.
2080                         labels[numLabels++] = curPC;
2081                         //Instruction.at(buf, curPC).setBranchLabel(getLabel(bc_label, code, curPC));
2082                         while (pc < nextPC)  buf[pc++] = 0;
2083                         continue;
2084                     }
2085                     if (Instruction.isCPRefOp(bc)) {
2086                         CPRefBand bc_which = getCPRefOpBand(bc);
2087                         Entry ref = bc_which.getRef();
2088                         if (ref == null) {
2089                             if (bc_which == bc_classref) {
2090                                 // Shorthand for class self-references.
2091                                 ref = thisClass;
2092                             } else {
2093                                 assert(false);
2094                             }
2095                         }
2096                         int origBC = bc;
2097                         int size = 2;
2098                         switch (bc) {
2099                         case _ildc:
2100                         case _cldc:
2101                         case _fldc:
2102                         case _aldc:
2103                             origBC = _ldc;
2104                             size = 1;
2105                             ldcRefSet.add(ref);
2106                             break;
2107                         case _ildc_w:
2108                         case _cldc_w:
2109                         case _fldc_w:
2110                         case _aldc_w:
2111                             origBC = _ldc_w;
2112                             break;
2113                         case _lldc2_w:
2114                         case _dldc2_w:
2115                             origBC = _ldc2_w;
2116                             break;
2117                         case _new:
2118                             newClass = (ClassEntry) ref;
2119                             break;
2120                         }
2121                         buf[pc++] = (byte) origBC;
2122                         int fmt;
2123                         switch (size) {
2124                         case 1: fmt = Fixups.U1_FORMAT; break;
2125                         case 2: fmt = Fixups.U2_FORMAT; break;
2126                         default: assert(false); fmt = 0;
2127                         }
2128                         fixupBuf.add(pc, fmt, ref);
2129                         buf[pc+0] = buf[pc+1] = 0;
2130                         pc += size;
2131                         if (origBC == _multianewarray) {
2132                             // Copy the trailing byte also.
2133                             int val = bc_byte.getByte();
2134                             buf[pc++] = (byte) val;
2135                         } else if (origBC == _invokeinterface) {
2136                             int argSize = ((MemberEntry)ref).descRef.typeRef.computeSize(true);
2137                             buf[pc++] = (byte)( 1 + argSize );
2138                             buf[pc++] = 0;
2139                         }
2140                         assert(Instruction.opLength(origBC) == (pc - curPC));
2141                         continue;
2142                     }
2143                     if (Instruction.isLocalSlotOp(bc)) {
2144                         buf[pc++] = (byte) bc;
2145                         int local = bc_local.getInt();
2146                         if (isWide) {
2147                             Instruction.setShort(buf, pc, local);
2148                             pc += 2;
2149                             if (bc == _iinc) {
2150                                 int iVal = bc_short.getInt();
2151                                 Instruction.setShort(buf, pc, iVal);
2152                                 pc += 2;
2153                             }
2154                         } else {
2155                             Instruction.setByte(buf, pc, local);
2156                             pc += 1;
2157                             if (bc == _iinc) {
2158                                 int iVal = bc_byte.getByte();
2159                                 Instruction.setByte(buf, pc, iVal);
2160                                 pc += 1;
2161                             }
2162                         }
2163                         assert(Instruction.opLength(bc) == (pc - curPC));
2164                         continue;
2165                     }
2166                     // Random bytecode.  Just copy it.
2167                     if (bc >= _bytecode_limit)
2168                         Utils.log.warning("unrecognized bytescode "+bc
2169                                             +" "+Instruction.byteName(bc));
2170                     assert(bc < _bytecode_limit);
2171                     buf[pc++] = (byte) bc;
2172                     assert(Instruction.opLength(bc) == (pc - curPC));
2173                     continue;
2174                 }
2175             }
2176             // now make a permanent copy of the bytecodes
2177             code.setBytes(realloc(buf, pc));
2178             code.setInstructionMap(insnMap, numInsns);
2179             // fix up labels, now that code has its insnMap
2180             Instruction ibr = null;  // temporary branch instruction
2181             for (int i = 0; i < numLabels; i++) {
2182                 int curPC = labels[i];
2183                 // (Note:  Passing ibr in allows reuse, a speed hack.)
2184                 ibr = Instruction.at(code.bytes, curPC, ibr);
2185                 if (ibr instanceof Instruction.Switch) {
2186                     Instruction.Switch isw = (Instruction.Switch) ibr;
2187                     isw.setDefaultLabel(getLabel(bc_label, code, curPC));
2188                     int caseCount = isw.getCaseCount();
2189                     for (int j = 0; j < caseCount; j++) {
2190                         isw.setCaseLabel(j, getLabel(bc_label, code, curPC));
2191                     }
2192                 } else {
2193                     ibr.setBranchLabel(getLabel(bc_label, code, curPC));
2194                 }
2195             }
2196             if (fixupBuf.size() > 0) {
2197                 if (verbose > 2)
2198                     Utils.log.fine("Fixups in code: "+fixupBuf);
2199                 code.addFixups(fixupBuf);
2200             }
2201         }
2202     }
2203 }