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                 try (PrintStream ps = new PrintStream(getDumpStream(index, ".idx"))) {
 544                     printArrayTo(ps, index.cpMap, 0, index.cpMap.length);
 545                 }
 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         try (PrintStream dump = !optDumpBands ? null
 832                  : new PrintStream(getDumpStream(attr_definition_headers, ".def")))
 833         {
 834             for (int i = 0; i < numAttrDefs; i++) {
 835                 int       header = attr_definition_headers.getByte();
 836                 Utf8Entry name   = (Utf8Entry) attr_definition_name.getRef();
 837                 Utf8Entry layout = (Utf8Entry) attr_definition_layout.getRef();
 838                 int       ctype  = (header &  ADH_CONTEXT_MASK);
 839                 int       index  = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
 840                 Attribute.Layout def = new Attribute.Layout(ctype,
 841                                                             name.stringValue(),
 842                                                             layout.stringValue());
 843                 // Check layout string for Java 6 extensions.
 844                 String pvLayout = def.layoutForPackageMajver(getPackageMajver());
 845                 if (!pvLayout.equals(def.layout())) {
 846                     throw new IOException("Bad attribute layout in version 150 archive: "+def.layout());
 847                 }
 848                 this.setAttributeLayoutIndex(def, index);
 849                 if (dump != null)  dump.println(index+" "+def);
 850             }
 851         } // TODO TWR: this relies on new null treatment for TWR's close()
 852         attr_definition_headers.doneDisbursing();
 853         attr_definition_name.doneDisbursing();
 854         attr_definition_layout.doneDisbursing();
 855         // Attribute layouts define bands, one per layout element.
 856         // Create them now, all at once.
 857         makeNewAttributeBands();
 858         attr_definition_bands.doneDisbursing();
 859     }
 860 
 861     void readInnerClasses() throws IOException {
 862         //  ic_bands:
 863         //        *ic_this_class :UDELTA5  (cp_Class)
 864         //        *ic_flags :UNSIGNED5
 865         //        *ic_outer_class :DELTA5  (null or cp_Class)
 866         //        *ic_name :DELTA5  (null or cp_Utf8)
 867         ic_this_class.expectLength(numInnerClasses);
 868         ic_this_class.readFrom(in);
 869         ic_flags.expectLength(numInnerClasses);
 870         ic_flags.readFrom(in);
 871         int longICCount = 0;
 872         for (int i = 0; i < numInnerClasses; i++) {
 873             int flags = ic_flags.getInt();
 874             boolean longForm = (flags & ACC_IC_LONG_FORM) != 0;
 875             if (longForm) {
 876                 longICCount += 1;
 877             }
 878         }
 879         ic_outer_class.expectLength(longICCount);
 880         ic_outer_class.readFrom(in);
 881         ic_name.expectLength(longICCount);
 882         ic_name.readFrom(in);
 883         ic_flags.resetForSecondPass();
 884         List<InnerClass> icList = new ArrayList<>(numInnerClasses);
 885         for (int i = 0; i < numInnerClasses; i++) {
 886             int flags = ic_flags.getInt();
 887             boolean longForm = (flags & ACC_IC_LONG_FORM) != 0;
 888             flags &= ~ACC_IC_LONG_FORM;
 889             ClassEntry thisClass = (ClassEntry) ic_this_class.getRef();
 890             ClassEntry outerClass;
 891             Utf8Entry  thisName;
 892             if (longForm) {
 893                 outerClass = (ClassEntry) ic_outer_class.getRef();
 894                 thisName   = (Utf8Entry)  ic_name.getRef();
 895             } else {
 896                 String n = thisClass.stringValue();
 897                 String[] parse = Package.parseInnerClassName(n);
 898                 assert(parse != null);
 899                 String pkgOuter = parse[0];
 900                 //String number = parse[1];
 901                 String name     = parse[2];
 902                 if (pkgOuter == null)
 903                     outerClass = null;
 904                 else
 905                     outerClass = ConstantPool.getClassEntry(pkgOuter);
 906                 if (name == null)
 907                     thisName   = null;
 908                 else
 909                     thisName   = ConstantPool.getUtf8Entry(name);
 910             }
 911             InnerClass ic =
 912                 new InnerClass(thisClass, outerClass, thisName, flags);
 913             assert(longForm || ic.predictable);
 914             icList.add(ic);
 915         }
 916         ic_flags.doneDisbursing();
 917         ic_this_class.doneDisbursing();
 918         ic_outer_class.doneDisbursing();
 919         ic_name.doneDisbursing();
 920         pkg.setAllInnerClasses(icList);
 921         ic_bands.doneDisbursing();
 922     }
 923 
 924     void readLocalInnerClasses(Class cls) throws IOException {
 925         int nc = class_InnerClasses_N.getInt();
 926         List<InnerClass> localICs = new ArrayList<>(nc);
 927         for (int i = 0; i < nc; i++) {
 928             ClassEntry thisClass = (ClassEntry) class_InnerClasses_RC.getRef();
 929             int        flags     =              class_InnerClasses_F.getInt();
 930             if (flags == 0) {
 931                 // A zero flag means copy a global IC here.
 932                 InnerClass ic = pkg.getGlobalInnerClass(thisClass);
 933                 assert(ic != null);  // must be a valid global IC reference
 934                 localICs.add(ic);
 935             } else {
 936                 if (flags == ACC_IC_LONG_FORM)
 937                     flags = 0;  // clear the marker bit
 938                 ClassEntry outer = (ClassEntry) class_InnerClasses_outer_RCN.getRef();
 939                 Utf8Entry name   = (Utf8Entry)  class_InnerClasses_name_RUN.getRef();
 940                 localICs.add(new InnerClass(thisClass, outer, name, flags));
 941             }
 942         }
 943         cls.setInnerClasses(localICs);
 944         // cls.expandLocalICs may add more tuples to ics also,
 945         // or may even delete tuples.
 946         // We cannot do that now, because we do not know the
 947         // full contents of the local constant pool yet.
 948     }
 949 
 950     static final int NO_FLAGS_YET = 0;  // placeholder for later flag read-in
 951 
 952     Class[] readClasses() throws IOException {
 953         //  class_bands:
 954         //        *class_this :DELTA5  (cp_Class)
 955         //        *class_super :DELTA5  (cp_Class)
 956         //        *class_interface_count :DELTA5
 957         //        *class_interface :DELTA5  (cp_Class)
 958         //        ...(member bands)...
 959         //        class_attr_bands
 960         //        code_bands
 961         Class[] classes = new Class[numClasses];
 962         if (verbose > 0)
 963             Utils.log.info("  ...building "+classes.length+" classes...");
 964 
 965         class_this.expectLength(numClasses);
 966         class_super.expectLength(numClasses);
 967         class_interface_count.expectLength(numClasses);
 968 
 969         class_this.readFrom(in);
 970         class_super.readFrom(in);
 971         class_interface_count.readFrom(in);
 972         class_interface.expectLength(class_interface_count.getIntTotal());
 973         class_interface.readFrom(in);
 974         for (int i = 0; i < classes.length; i++) {
 975             ClassEntry   thisClass  = (ClassEntry) class_this.getRef();
 976             ClassEntry   superClass = (ClassEntry) class_super.getRef();
 977             ClassEntry[] interfaces = new ClassEntry[class_interface_count.getInt()];
 978             for (int j = 0; j < interfaces.length; j++) {
 979                 interfaces[j] = (ClassEntry) class_interface.getRef();
 980             }
 981             // Packer encoded rare case of null superClass as thisClass:
 982             if (superClass == thisClass)  superClass = null;
 983             Class cls = pkg.new Class(NO_FLAGS_YET,
 984                                       thisClass, superClass, interfaces);
 985             classes[i] = cls;
 986         }
 987         class_this.doneDisbursing();
 988         class_super.doneDisbursing();
 989         class_interface_count.doneDisbursing();
 990         class_interface.doneDisbursing();
 991         readMembers(classes);
 992         countAndReadAttrs(ATTR_CONTEXT_CLASS, Arrays.asList(classes));
 993         pkg.trimToSize();
 994         readCodeHeaders();
 995         //code_bands.doneDisbursing(); // still need to read code attrs
 996         //class_bands.doneDisbursing(); // still need to read code attrs
 997         return classes;
 998     }
 999 
1000     private int getOutputIndex(Entry e) {
1001         // Output CPs do not contain signatures.
1002         assert(e.tag != CONSTANT_Signature);
1003         int k = pkg.cp.untypedIndexOf(e);
1004         // In the output ordering, input signatures can serve
1005         // in place of Utf8s.
1006         if (k >= 0)
1007             return k;
1008         if (e.tag == CONSTANT_Utf8) {
1009             Entry se = (Entry) utf8Signatures.get(e);
1010             return pkg.cp.untypedIndexOf(se);
1011         }
1012         return -1;
1013     }
1014 
1015     Comparator<Entry> entryOutputOrder = new Comparator<>() {
1016         public int compare(Entry  e0, Entry e1) {
1017             int k0 = getOutputIndex(e0);
1018             int k1 = getOutputIndex(e1);
1019             if (k0 >= 0 && k1 >= 0)
1020                 // If both have keys, use the keys.
1021                 return k0 - k1;
1022             if (k0 == k1)
1023                 // If neither have keys, use their native tags & spellings.
1024                 return e0.compareTo(e1);
1025             // Otherwise, the guy with the key comes first.
1026             return (k0 >= 0)? 0-1: 1-0;
1027         }
1028     };
1029 
1030     void reconstructClass(Class cls) {
1031         if (verbose > 1)  Utils.log.fine("reconstruct "+cls);
1032 
1033         // check for local .ClassFile.version
1034         Attribute retroVersion = cls.getAttribute(attrClassFileVersion);
1035         if (retroVersion != null) {
1036             cls.removeAttribute(retroVersion);
1037             short[] minmajver = parseClassFileVersionAttr(retroVersion);
1038             cls.minver = minmajver[0];
1039             cls.majver = minmajver[1];
1040         } else {
1041             cls.minver = pkg.default_class_minver;
1042             cls.majver = pkg.default_class_majver;
1043         }
1044 
1045         // Replace null SourceFile by "obvious" string.
1046         cls.expandSourceFile();
1047 
1048         // record the local cp:
1049         cls.setCPMap(reconstructLocalCPMap(cls));
1050     }
1051 
1052     Entry[] reconstructLocalCPMap(Class cls) {
1053         Set<Entry> ldcRefs = ldcRefMap.get(cls);
1054         Set<Entry> cpRefs = new HashSet<>();
1055 
1056         // look for constant pool entries:
1057         cls.visitRefs(VRM_CLASSIC, cpRefs);
1058 
1059         // flesh out the local constant pool
1060         ConstantPool.completeReferencesIn(cpRefs, true);
1061 
1062         // Now that we know all our local class references,
1063         // compute the InnerClasses attribute.
1064         int changed = cls.expandLocalICs();
1065 
1066         if (changed != 0) {
1067             if (changed > 0) {
1068                 // Just visit the expanded InnerClasses attr.
1069                 cls.visitInnerClassRefs(VRM_CLASSIC, cpRefs);
1070             } else {
1071                 // Have to recompute from scratch, because of deletions.
1072                 cpRefs.clear();
1073                 cls.visitRefs(VRM_CLASSIC, cpRefs);
1074             }
1075 
1076             // flesh out the local constant pool, again
1077             ConstantPool.completeReferencesIn(cpRefs, true);
1078         }
1079 
1080         // construct a local constant pool
1081         int numDoubles = 0;
1082         for (Entry e : cpRefs) {
1083             if (e.isDoubleWord())  numDoubles++;
1084             assert(e.tag != CONSTANT_Signature) : (e);
1085         }
1086         Entry[] cpMap = new Entry[1+numDoubles+cpRefs.size()];
1087         int fillp = 1;
1088 
1089         // Add all ldc operands first.
1090         if (ldcRefs != null) {
1091             assert(cpRefs.containsAll(ldcRefs));
1092             for (Entry e : ldcRefs) {
1093                 cpMap[fillp++] = e;
1094             }
1095             assert(fillp == 1+ldcRefs.size());
1096             cpRefs.removeAll(ldcRefs);
1097             ldcRefs = null;  // done with it
1098         }
1099 
1100         // Next add all the two-byte references.
1101         Set<Entry> wideRefs = cpRefs;
1102         cpRefs = null;  // do not use!
1103         int narrowLimit = fillp;
1104         for (Entry e : wideRefs) {
1105             cpMap[fillp++] = e;
1106         }
1107         assert(fillp == narrowLimit+wideRefs.size());
1108         Arrays.sort(cpMap, 1, narrowLimit, entryOutputOrder);
1109         Arrays.sort(cpMap, narrowLimit, fillp, entryOutputOrder);
1110 
1111         if (verbose > 3) {
1112             Utils.log.fine("CP of "+this+" {");
1113             for (int i = 0; i < fillp; i++) {
1114                 Entry e = cpMap[i];
1115                 Utils.log.fine("  "+((e==null)?-1:getOutputIndex(e))
1116                                    +" : "+e);
1117             }
1118             Utils.log.fine("}");
1119         }
1120 
1121         // Now repack backwards, introducing null elements.
1122         int revp = cpMap.length;
1123         for (int i = fillp; --i >= 1; ) {
1124             Entry e = cpMap[i];
1125             if (e.isDoubleWord())
1126                 cpMap[--revp] = null;
1127             cpMap[--revp] = e;
1128         }
1129         assert(revp == 1);  // do not process the initial null
1130 
1131         return cpMap;
1132     }
1133 
1134     void readMembers(Class[] classes) throws IOException {
1135         //  class_bands:
1136         //        ...
1137         //        *class_field_count :DELTA5
1138         //        *class_method_count :DELTA5
1139         //
1140         //        *field_descr :DELTA5  (cp_Descr)
1141         //        field_attr_bands
1142         //
1143         //        *method_descr :MDELTA5  (cp_Descr)
1144         //        method_attr_bands
1145         //        ...
1146         assert(classes.length == numClasses);
1147         class_field_count.expectLength(numClasses);
1148         class_method_count.expectLength(numClasses);
1149         class_field_count.readFrom(in);
1150         class_method_count.readFrom(in);
1151 
1152         // Make a pre-pass over field and method counts to size the descrs:
1153         int totalNF = class_field_count.getIntTotal();
1154         int totalNM = class_method_count.getIntTotal();
1155         field_descr.expectLength(totalNF);
1156         method_descr.expectLength(totalNM);
1157         if (verbose > 1)  Utils.log.fine("expecting #fields="+totalNF+" and #methods="+totalNM+" in #classes="+numClasses);
1158 
1159         List<Class.Field> fields = new ArrayList<>(totalNF);
1160         field_descr.readFrom(in);
1161         for (int i = 0; i < classes.length; i++) {
1162             Class c = classes[i];
1163             int nf = class_field_count.getInt();
1164             for (int j = 0; j < nf; j++) {
1165                 Class.Field f = c.new Field(NO_FLAGS_YET, (DescriptorEntry)
1166                                             field_descr.getRef());
1167                 fields.add(f);
1168             }
1169         }
1170         class_field_count.doneDisbursing();
1171         field_descr.doneDisbursing();
1172         countAndReadAttrs(ATTR_CONTEXT_FIELD, fields);
1173         fields = null;  // release to GC
1174 
1175         List<Class.Method> methods = new ArrayList<>(totalNM);
1176         method_descr.readFrom(in);
1177         for (int i = 0; i < classes.length; i++) {
1178             Class c = classes[i];
1179             int nm = class_method_count.getInt();
1180             for (int j = 0; j < nm; j++) {
1181                 Class.Method m = c.new Method(NO_FLAGS_YET, (DescriptorEntry)
1182                                               method_descr.getRef());
1183                 methods.add(m);
1184             }
1185         }
1186         class_method_count.doneDisbursing();
1187         method_descr.doneDisbursing();
1188         countAndReadAttrs(ATTR_CONTEXT_METHOD, methods);
1189 
1190         // Up to this point, Code attributes look like empty attributes.
1191         // Now we start to special-case them.  The empty canonical Code
1192         // attributes stay in the method attribute lists, however.
1193         allCodes = buildCodeAttrs(methods);
1194     }
1195 
1196     Code[] allCodes;
1197     List<Code> codesWithFlags;
1198     Map<Class, Set<Entry>> ldcRefMap = new HashMap<>();
1199 
1200     Code[] buildCodeAttrs(List<Class.Method> methods) {
1201         List<Code> codes = new ArrayList<>(methods.size());
1202         for (Class.Method m : methods) {
1203             if (m.getAttribute(attrCodeEmpty) != null) {
1204                 m.code = new Code(m);
1205                 codes.add(m.code);
1206             }
1207         }
1208         Code[] a = new Code[codes.size()];
1209         codes.toArray(a);
1210         return a;
1211     }
1212 
1213     void readCodeHeaders() throws IOException {
1214         //  code_bands:
1215         //        *code_headers :BYTE1
1216         //
1217         //        *code_max_stack :UNSIGNED5
1218         //        *code_max_na_locals :UNSIGNED5
1219         //        *code_handler_count :UNSIGNED5
1220         //        ...
1221         //        code_attr_bands
1222         boolean attrsOK = testBit(archiveOptions, AO_HAVE_ALL_CODE_FLAGS);
1223         code_headers.expectLength(allCodes.length);
1224         code_headers.readFrom(in);
1225         List<Code> longCodes = new ArrayList<>(allCodes.length / 10);
1226         for (int i = 0; i < allCodes.length; i++) {
1227             Code c = allCodes[i];
1228             int sc = code_headers.getByte();
1229             assert(sc == (sc & 0xFF));
1230             if (verbose > 2)
1231                 Utils.log.fine("codeHeader "+c+" = "+sc);
1232             if (sc == LONG_CODE_HEADER) {
1233                 // We will read ms/ml/nh/flags from bands shortly.
1234                 longCodes.add(c);
1235                 continue;
1236             }
1237             // Short code header is the usual case:
1238             c.setMaxStack(     shortCodeHeader_max_stack(sc) );
1239             c.setMaxNALocals(  shortCodeHeader_max_na_locals(sc) );
1240             c.setHandlerCount( shortCodeHeader_handler_count(sc) );
1241             assert(shortCodeHeader(c) == sc);
1242         }
1243         code_headers.doneDisbursing();
1244         code_max_stack.expectLength(longCodes.size());
1245         code_max_na_locals.expectLength(longCodes.size());
1246         code_handler_count.expectLength(longCodes.size());
1247 
1248         // Do the long headers now.
1249         code_max_stack.readFrom(in);
1250         code_max_na_locals.readFrom(in);
1251         code_handler_count.readFrom(in);
1252         for (Code c : longCodes) {
1253             c.setMaxStack(     code_max_stack.getInt() );
1254             c.setMaxNALocals(  code_max_na_locals.getInt() );
1255             c.setHandlerCount( code_handler_count.getInt() );
1256         }
1257         code_max_stack.doneDisbursing();
1258         code_max_na_locals.doneDisbursing();
1259         code_handler_count.doneDisbursing();
1260 
1261         readCodeHandlers();
1262 
1263         if (attrsOK) {
1264             // Code attributes are common (debug info not stripped).
1265             codesWithFlags = Arrays.asList(allCodes);
1266         } else {
1267             // Code attributes are very sparse (debug info is stripped).
1268             codesWithFlags = longCodes;
1269         }
1270         countAttrs(ATTR_CONTEXT_CODE, codesWithFlags);
1271         // do readAttrs later, after BCs are scanned
1272     }
1273 
1274     void readCodeHandlers() throws IOException {
1275         //  code_bands:
1276         //        ...
1277         //        *code_handler_start_P :BCI5
1278         //        *code_handler_end_PO :BRANCH5
1279         //        *code_handler_catch_PO :BRANCH5
1280         //        *code_handler_class_RCN :UNSIGNED5  (null or cp_Class)
1281         //        ...
1282         int nh = 0;
1283         for (int i = 0; i < allCodes.length; i++) {
1284             Code c = allCodes[i];
1285             nh += c.getHandlerCount();
1286         }
1287 
1288         ValueBand[] code_handler_bands = {
1289             code_handler_start_P,
1290             code_handler_end_PO,
1291             code_handler_catch_PO,
1292             code_handler_class_RCN
1293         };
1294 
1295         for (int i = 0; i < code_handler_bands.length; i++) {
1296             code_handler_bands[i].expectLength(nh);
1297             code_handler_bands[i].readFrom(in);
1298         }
1299 
1300         for (int i = 0; i < allCodes.length; i++) {
1301             Code c = allCodes[i];
1302             for (int j = 0, jmax = c.getHandlerCount(); j < jmax; j++) {
1303                 c.handler_class[j] = code_handler_class_RCN.getRef();
1304                 // For now, just record the raw BCI codes.
1305                 // We must wait until we have instruction boundaries.
1306                 c.handler_start[j] = code_handler_start_P.getInt();
1307                 c.handler_end[j]   = code_handler_end_PO.getInt();
1308                 c.handler_catch[j] = code_handler_catch_PO.getInt();
1309             }
1310         }
1311         for (int i = 0; i < code_handler_bands.length; i++) {
1312             code_handler_bands[i].doneDisbursing();
1313         }
1314     }
1315 
1316     void fixupCodeHandlers() {
1317         // Actually decode (renumber) the BCIs now.
1318         for (int i = 0; i < allCodes.length; i++) {
1319             Code c = allCodes[i];
1320             for (int j = 0, jmax = c.getHandlerCount(); j < jmax; j++) {
1321                 int sum = c.handler_start[j];
1322                 c.handler_start[j] = c.decodeBCI(sum);
1323                 sum += c.handler_end[j];
1324                 c.handler_end[j]   = c.decodeBCI(sum);
1325                 sum += c.handler_catch[j];
1326                 c.handler_catch[j] = c.decodeBCI(sum);
1327             }
1328         }
1329     }
1330 
1331     // Generic routines for reading attributes of
1332     // classes, fields, methods, and codes.
1333     // The holders is a global list, already collected,
1334     // of attribute "customers".
1335     void countAndReadAttrs(int ctype, Collection holders) throws IOException {
1336         //  class_attr_bands:
1337         //        *class_flags :UNSIGNED5
1338         //        *class_attr_count :UNSIGNED5
1339         //        *class_attr_indexes :UNSIGNED5
1340         //        *class_attr_calls :UNSIGNED5
1341         //        *class_Signature_RS :UNSIGNED5 (cp_Signature)
1342         //        class_metadata_bands
1343         //        *class_SourceFile_RU :UNSIGNED5 (cp_Utf8)
1344         //        *class_EnclosingMethod_RM :UNSIGNED5 (cp_Method)
1345         //        ic_local_bands
1346         //        *class_ClassFile_version_minor_H :UNSIGNED5
1347         //        *class_ClassFile_version_major_H :UNSIGNED5
1348         //
1349         //  field_attr_bands:
1350         //        *field_flags :UNSIGNED5
1351         //        *field_attr_count :UNSIGNED5
1352         //        *field_attr_indexes :UNSIGNED5
1353         //        *field_attr_calls :UNSIGNED5
1354         //        *field_Signature_RS :UNSIGNED5 (cp_Signature)
1355         //        field_metadata_bands
1356         //        *field_ConstantValue_KQ :UNSIGNED5 (cp_Int, etc.; see note)
1357         //
1358         //  method_attr_bands:
1359         //        *method_flags :UNSIGNED5
1360         //        *method_attr_count :UNSIGNED5
1361         //        *method_attr_indexes :UNSIGNED5
1362         //        *method_attr_calls :UNSIGNED5
1363         //        *method_Signature_RS :UNSIGNED5 (cp_Signature)
1364         //        method_metadata_bands
1365         //        *method_Exceptions_N :UNSIGNED5
1366         //        *method_Exceptions_RC :UNSIGNED5  (cp_Class)
1367         //
1368         //  code_attr_bands:
1369         //        *code_flags :UNSIGNED5
1370         //        *code_attr_count :UNSIGNED5
1371         //        *code_attr_indexes :UNSIGNED5
1372         //        *code_attr_calls :UNSIGNED5
1373         //        *code_LineNumberTable_N :UNSIGNED5
1374         //        *code_LineNumberTable_bci_P :BCI5
1375         //        *code_LineNumberTable_line :UNSIGNED5
1376         //        *code_LocalVariableTable_N :UNSIGNED5
1377         //        *code_LocalVariableTable_bci_P :BCI5
1378         //        *code_LocalVariableTable_span_O :BRANCH5
1379         //        *code_LocalVariableTable_name_RU :UNSIGNED5 (cp_Utf8)
1380         //        *code_LocalVariableTable_type_RS :UNSIGNED5 (cp_Signature)
1381         //        *code_LocalVariableTable_slot :UNSIGNED5
1382 
1383         countAttrs(ctype, holders);
1384         readAttrs(ctype, holders);
1385     }
1386 
1387     // Read flags and count the attributes that are to be placed
1388     // on the given holders.
1389     void countAttrs(int ctype, Collection holders) throws IOException {
1390         // Here, xxx stands for one of class, field, method, code.
1391         MultiBand xxx_attr_bands = attrBands[ctype];
1392         long flagMask = attrFlagMask[ctype];
1393         if (verbose > 1) {
1394             Utils.log.fine("scanning flags and attrs for "+Attribute.contextName(ctype)+"["+holders.size()+"]");
1395         }
1396 
1397         // Fetch the attribute layout definitions which govern the bands
1398         // we are about to read.
1399         List<Attribute.Layout> defList = attrDefs.get(ctype);
1400         Attribute.Layout[] defs = new Attribute.Layout[defList.size()];
1401         defList.toArray(defs);
1402         IntBand xxx_flags_hi = getAttrBand(xxx_attr_bands, AB_FLAGS_HI);
1403         IntBand xxx_flags_lo = getAttrBand(xxx_attr_bands, AB_FLAGS_LO);
1404         IntBand xxx_attr_count = getAttrBand(xxx_attr_bands, AB_ATTR_COUNT);
1405         IntBand xxx_attr_indexes = getAttrBand(xxx_attr_bands, AB_ATTR_INDEXES);
1406         IntBand xxx_attr_calls = getAttrBand(xxx_attr_bands, AB_ATTR_CALLS);
1407 
1408         // Count up the number of holders which have overflow attrs.
1409         int overflowMask = attrOverflowMask[ctype];
1410         int overflowHolderCount = 0;
1411         boolean haveLongFlags = haveFlagsHi(ctype);
1412         xxx_flags_hi.expectLength(haveLongFlags? holders.size(): 0);
1413         xxx_flags_hi.readFrom(in);
1414         xxx_flags_lo.expectLength(holders.size());
1415         xxx_flags_lo.readFrom(in);
1416         assert((flagMask & overflowMask) == overflowMask);
1417         for (Iterator i = holders.iterator(); i.hasNext(); ) {
1418             Attribute.Holder h = (Attribute.Holder) i.next();
1419             int flags = xxx_flags_lo.getInt();
1420             h.flags = flags;
1421             if ((flags & overflowMask) != 0)
1422                 overflowHolderCount += 1;
1423         }
1424 
1425         // For each holder with overflow attrs, read a count.
1426         xxx_attr_count.expectLength(overflowHolderCount);
1427         xxx_attr_count.readFrom(in);
1428         xxx_attr_indexes.expectLength(xxx_attr_count.getIntTotal());
1429         xxx_attr_indexes.readFrom(in);
1430 
1431         // Now it's time to check flag bits that indicate attributes.
1432         // We accumulate (a) a list of attribute types for each holder
1433         // (class/field/method/code), and also we accumulate (b) a total
1434         // count for each attribute type.
1435         int[] totalCounts = new int[defs.length];
1436         for (Iterator i = holders.iterator(); i.hasNext(); ) {
1437             Attribute.Holder h = (Attribute.Holder) i.next();
1438             assert(h.attributes == null);
1439             // System.out.println("flags="+h.flags+" using fm="+flagMask);
1440             long attrBits = ((h.flags & flagMask) << 32) >>> 32;
1441             // Clean up the flags now.
1442             h.flags -= (int)attrBits;   // strip attr bits
1443             assert(h.flags == (char)h.flags);  // 16 bits only now
1444             assert((ctype != ATTR_CONTEXT_CODE) || h.flags == 0);
1445             if (haveLongFlags)
1446                 attrBits += (long)xxx_flags_hi.getInt() << 32;
1447             if (attrBits == 0)  continue;  // no attrs on this guy
1448 
1449             int noa = 0;  // number of overflow attrs
1450             long overflowBit = (attrBits & overflowMask);
1451             assert(overflowBit >= 0);
1452             attrBits -= overflowBit;
1453             if (overflowBit != 0) {
1454                 noa = xxx_attr_count.getInt();
1455             }
1456 
1457             int nfa = 0;  // number of flag attrs
1458             long bits = attrBits;
1459             for (int ai = 0; bits != 0; ai++) {
1460                 if ((bits & (1L<<ai)) == 0)  continue;
1461                 bits -= (1L<<ai);
1462                 nfa += 1;
1463             }
1464             List<Attribute> ha = new ArrayList<>(nfa + noa);
1465             h.attributes = ha;
1466             bits = attrBits;  // iterate again
1467             for (int ai = 0; bits != 0; ai++) {
1468                 if ((bits & (1L<<ai)) == 0)  continue;
1469                 bits -= (1L<<ai);
1470                 totalCounts[ai] += 1;
1471                 // This definition index is live in this holder.
1472                 if (defs[ai] == null)  badAttrIndex(ai, ctype);
1473                 Attribute canonical = defs[ai].canonicalInstance();
1474                 ha.add(canonical);
1475                 nfa -= 1;
1476             }
1477             assert(nfa == 0);
1478             for (; noa > 0; noa--) {
1479                 int ai = xxx_attr_indexes.getInt();
1480                 totalCounts[ai] += 1;
1481                 // This definition index is live in this holder.
1482                 if (defs[ai] == null)  badAttrIndex(ai, ctype);
1483                 Attribute canonical = defs[ai].canonicalInstance();
1484                 ha.add(canonical);
1485             }
1486         }
1487 
1488         xxx_flags_hi.doneDisbursing();
1489         xxx_flags_lo.doneDisbursing();
1490         xxx_attr_count.doneDisbursing();
1491         xxx_attr_indexes.doneDisbursing();
1492 
1493         // Now each holder has a list of canonical attribute instances.
1494         // For layouts with no elements, we are done.  However, for
1495         // layouts with bands, we must replace each canonical (empty)
1496         // instance with a value-bearing one, initialized from the
1497         // appropriate bands.
1498 
1499         // Make a small pass to detect and read backward call counts.
1500         int callCounts = 0;
1501         for (boolean predef = true; ; predef = false) {
1502             for (int ai = 0; ai < defs.length; ai++) {
1503                 Attribute.Layout def = defs[ai];
1504                 if (def == null)  continue;  // unused index
1505                 if (predef != isPredefinedAttr(ctype, ai))
1506                     continue;  // wrong pass
1507                 int totalCount = totalCounts[ai];
1508                 if (totalCount == 0)
1509                     continue;  // irrelevant
1510                 Attribute.Layout.Element[] cbles = def.getCallables();
1511                 for (int j = 0; j < cbles.length; j++) {
1512                     assert(cbles[j].kind == Attribute.EK_CBLE);
1513                     if (cbles[j].flagTest(Attribute.EF_BACK))
1514                         callCounts += 1;
1515                 }
1516             }
1517             if (!predef)  break;
1518         }
1519         xxx_attr_calls.expectLength(callCounts);
1520         xxx_attr_calls.readFrom(in);
1521 
1522         // Finally, size all the attribute bands.
1523         for (boolean predef = true; ; predef = false) {
1524             for (int ai = 0; ai < defs.length; ai++) {
1525                 Attribute.Layout def = defs[ai];
1526                 if (def == null)  continue;  // unused index
1527                 if (predef != isPredefinedAttr(ctype, ai))
1528                     continue;  // wrong pass
1529                 int totalCount = totalCounts[ai];
1530                 Band[] ab = attrBandTable.get(def);
1531                 if (def == attrInnerClassesEmpty) {
1532                     // Special case.
1533                     // Size the bands as if using the following layout:
1534                     //    [RCH TI[ (0)[] ()[RCNH RUNH] ]].
1535                     class_InnerClasses_N.expectLength(totalCount);
1536                     class_InnerClasses_N.readFrom(in);
1537                     int tupleCount = class_InnerClasses_N.getIntTotal();
1538                     class_InnerClasses_RC.expectLength(tupleCount);
1539                     class_InnerClasses_RC.readFrom(in);
1540                     class_InnerClasses_F.expectLength(tupleCount);
1541                     class_InnerClasses_F.readFrom(in);
1542                     // Drop remaining columns wherever flags are zero:
1543                     tupleCount -= class_InnerClasses_F.getIntCount(0);
1544                     class_InnerClasses_outer_RCN.expectLength(tupleCount);
1545                     class_InnerClasses_outer_RCN.readFrom(in);
1546                     class_InnerClasses_name_RUN.expectLength(tupleCount);
1547                     class_InnerClasses_name_RUN.readFrom(in);
1548                 } else if (totalCount == 0) {
1549                     // Expect no elements at all.  Skip quickly.
1550                     for (int j = 0; j < ab.length; j++) {
1551                         ab[j].doneWithUnusedBand();
1552                     }
1553                 } else {
1554                     // Read these bands in sequence.
1555                     boolean hasCallables = def.hasCallables();
1556                     if (!hasCallables) {
1557                         readAttrBands(def.elems, totalCount, new int[0], ab);
1558                     } else {
1559                         Attribute.Layout.Element[] cbles = def.getCallables();
1560                         // At first, record initial calls.
1561                         // Later, forward calls may also accumulate here:
1562                         int[] forwardCounts = new int[cbles.length];
1563                         forwardCounts[0] = totalCount;
1564                         for (int j = 0; j < cbles.length; j++) {
1565                             assert(cbles[j].kind == Attribute.EK_CBLE);
1566                             int entryCount = forwardCounts[j];
1567                             forwardCounts[j] = -1;  // No more, please!
1568                             if (cbles[j].flagTest(Attribute.EF_BACK))
1569                                 entryCount += xxx_attr_calls.getInt();
1570                             readAttrBands(cbles[j].body, entryCount, forwardCounts, ab);
1571                         }
1572                     }
1573                 }
1574             }
1575             if (!predef)  break;
1576         }
1577         xxx_attr_calls.doneDisbursing();
1578     }
1579 
1580     void badAttrIndex(int ai, int ctype) throws IOException {
1581         throw new IOException("Unknown attribute index "+ai+" for "+
1582                                    ATTR_CONTEXT_NAME[ctype]+" attribute");
1583     }
1584 
1585     @SuppressWarnings("unchecked")
1586     void readAttrs(int ctype, Collection holders) throws IOException {
1587         // Decode band values into attributes.
1588         Set<Attribute.Layout> sawDefs = new HashSet<>();
1589         ByteArrayOutputStream buf = new ByteArrayOutputStream();
1590         for (Iterator i = holders.iterator(); i.hasNext(); ) {
1591             final Attribute.Holder h = (Attribute.Holder) i.next();
1592             if (h.attributes == null)  continue;
1593             for (ListIterator<Attribute> j = h.attributes.listIterator(); j.hasNext(); ) {
1594                 Attribute a = j.next();
1595                 Attribute.Layout def = a.layout();
1596                 if (def.bandCount == 0) {
1597                     if (def == attrInnerClassesEmpty) {
1598                         // Special logic to read this attr.
1599                         readLocalInnerClasses((Class) h);
1600                         continue;
1601                     }
1602                     // Canonical empty attr works fine (e.g., Synthetic).
1603                     continue;
1604                 }
1605                 sawDefs.add(def);
1606                 boolean isCV = (ctype == ATTR_CONTEXT_FIELD && def == attrConstantValue);
1607                 if (isCV)  setConstantValueIndex((Class.Field)h);
1608                 if (verbose > 2)
1609                     Utils.log.fine("read "+a+" in "+h);
1610                 final Band[] ab = attrBandTable.get(def);
1611                 // Read one attribute of type def from ab into a byte array.
1612                 buf.reset();
1613                 Object fixups = a.unparse(new Attribute.ValueStream() {
1614                     public int getInt(int bandIndex) {
1615                         return ((IntBand) ab[bandIndex]).getInt();
1616                     }
1617                     public Entry getRef(int bandIndex) {
1618                         return ((CPRefBand) ab[bandIndex]).getRef();
1619                     }
1620                     public int decodeBCI(int bciCode) {
1621                         Code code = (Code) h;
1622                         return code.decodeBCI(bciCode);
1623                     }
1624                 }, buf);
1625                 // Replace the canonical attr with the one just read.
1626                 j.set(a.addContent(buf.toByteArray(), fixups));
1627                 if (isCV)  setConstantValueIndex(null);  // clean up
1628             }
1629         }
1630 
1631         // Mark the bands we just used as done disbursing.
1632         for (Attribute.Layout def : sawDefs) {
1633             if (def == null)  continue;  // unused index
1634             Band[] ab = attrBandTable.get(def);
1635             for (int j = 0; j < ab.length; j++) {
1636                 ab[j].doneDisbursing();
1637             }
1638         }
1639 
1640         if (ctype == ATTR_CONTEXT_CLASS) {
1641             class_InnerClasses_N.doneDisbursing();
1642             class_InnerClasses_RC.doneDisbursing();
1643             class_InnerClasses_F.doneDisbursing();
1644             class_InnerClasses_outer_RCN.doneDisbursing();
1645             class_InnerClasses_name_RUN.doneDisbursing();
1646         }
1647 
1648         MultiBand xxx_attr_bands = attrBands[ctype];
1649         for (int i = 0; i < xxx_attr_bands.size(); i++) {
1650             Band b = xxx_attr_bands.get(i);
1651             if (b instanceof MultiBand)
1652                 b.doneDisbursing();
1653         }
1654         xxx_attr_bands.doneDisbursing();
1655     }
1656 
1657     private
1658     void readAttrBands(Attribute.Layout.Element[] elems,
1659                        int count, int[] forwardCounts,
1660                        Band[] ab)
1661             throws IOException {
1662         for (int i = 0; i < elems.length; i++) {
1663             Attribute.Layout.Element e = elems[i];
1664             Band eBand = null;
1665             if (e.hasBand()) {
1666                 eBand = ab[e.bandIndex];
1667                 eBand.expectLength(count);
1668                 eBand.readFrom(in);
1669             }
1670             switch (e.kind) {
1671             case Attribute.EK_REPL:
1672                 // Recursive call.
1673                 int repCount = ((IntBand)eBand).getIntTotal();
1674                 // Note:  getIntTotal makes an extra pass over this band.
1675                 readAttrBands(e.body, repCount, forwardCounts, ab);
1676                 break;
1677             case Attribute.EK_UN:
1678                 int remainingCount = count;
1679                 for (int j = 0; j < e.body.length; j++) {
1680                     int caseCount;
1681                     if (j == e.body.length-1) {
1682                         caseCount = remainingCount;
1683                     } else {
1684                         caseCount = 0;
1685                         for (int j0 = j;
1686                              (j == j0)
1687                              || (j < e.body.length
1688                                  && e.body[j].flagTest(Attribute.EF_BACK));
1689                              j++) {
1690                             caseCount += ((IntBand)eBand).getIntCount(e.body[j].value);
1691                         }
1692                         --j;  // back up to last occurrence of this body
1693                     }
1694                     remainingCount -= caseCount;
1695                     readAttrBands(e.body[j].body, caseCount, forwardCounts, ab);
1696                 }
1697                 assert(remainingCount == 0);
1698                 break;
1699             case Attribute.EK_CALL:
1700                 assert(e.body.length == 1);
1701                 assert(e.body[0].kind == Attribute.EK_CBLE);
1702                 if (!e.flagTest(Attribute.EF_BACK)) {
1703                     // Backward calls are pre-counted, but forwards are not.
1704                     // Push the present count forward.
1705                     assert(forwardCounts[e.value] >= 0);
1706                     forwardCounts[e.value] += count;
1707                 }
1708                 break;
1709             case Attribute.EK_CBLE:
1710                 assert(false);
1711                 break;
1712             }
1713         }
1714     }
1715 
1716     void readByteCodes() throws IOException {
1717         //  bc_bands:
1718         //        *bc_codes :BYTE1
1719         //        *bc_case_count :UNSIGNED5
1720         //        *bc_case_value :DELTA5
1721         //        *bc_byte :BYTE1
1722         //        *bc_short :DELTA5
1723         //        *bc_local :UNSIGNED5
1724         //        *bc_label :BRANCH5
1725         //        *bc_intref :DELTA5  (cp_Int)
1726         //        *bc_floatref :DELTA5  (cp_Float)
1727         //        *bc_longref :DELTA5  (cp_Long)
1728         //        *bc_doubleref :DELTA5  (cp_Double)
1729         //        *bc_stringref :DELTA5  (cp_String)
1730         //        *bc_classref :UNSIGNED5  (current class or cp_Class)
1731         //        *bc_fieldref :DELTA5  (cp_Field)
1732         //        *bc_methodref :UNSIGNED5  (cp_Method)
1733         //        *bc_imethodref :DELTA5  (cp_Imethod)
1734         //        *bc_thisfield :UNSIGNED5 (cp_Field, only for current class)
1735         //        *bc_superfield :UNSIGNED5 (cp_Field, only for current super)
1736         //        *bc_thismethod :UNSIGNED5 (cp_Method, only for current class)
1737         //        *bc_supermethod :UNSIGNED5 (cp_Method, only for current super)
1738         //        *bc_initref :UNSIGNED5 (cp_Field, only for most recent new)
1739         //        *bc_escref :UNSIGNED5 (cp_All)
1740         //        *bc_escrefsize :UNSIGNED5
1741         //        *bc_escsize :UNSIGNED5
1742         //        *bc_escbyte :BYTE1
1743         bc_codes.elementCountForDebug = allCodes.length;
1744         bc_codes.setInputStreamFrom(in);
1745         readByteCodeOps();  // reads from bc_codes and bc_case_count
1746         bc_codes.doneDisbursing();
1747 
1748         // All the operand bands have now been sized.  Read them all in turn.
1749         Band[] operand_bands = {
1750             bc_case_value,
1751             bc_byte, bc_short,
1752             bc_local, bc_label,
1753             bc_intref, bc_floatref,
1754             bc_longref, bc_doubleref, bc_stringref,
1755             bc_classref, bc_fieldref,
1756             bc_methodref, bc_imethodref,
1757             bc_thisfield, bc_superfield,
1758             bc_thismethod, bc_supermethod,
1759             bc_initref,
1760             bc_escref, bc_escrefsize, bc_escsize
1761         };
1762         for (int i = 0; i < operand_bands.length; i++) {
1763             operand_bands[i].readFrom(in);
1764         }
1765         bc_escbyte.expectLength(bc_escsize.getIntTotal());
1766         bc_escbyte.readFrom(in);
1767 
1768         expandByteCodeOps();
1769 
1770         // Done fetching values from operand bands:
1771         bc_case_count.doneDisbursing();
1772         for (int i = 0; i < operand_bands.length; i++) {
1773             operand_bands[i].doneDisbursing();
1774         }
1775         bc_escbyte.doneDisbursing();
1776         bc_bands.doneDisbursing();
1777 
1778         // We must delay the parsing of Code attributes until we
1779         // have a complete model of bytecodes, for BCI encodings.
1780         readAttrs(ATTR_CONTEXT_CODE, codesWithFlags);
1781         // Ditto for exception handlers in codes.
1782         fixupCodeHandlers();
1783         // Now we can finish with class_bands; cf. readClasses().
1784         code_bands.doneDisbursing();
1785         class_bands.doneDisbursing();
1786     }
1787 
1788     private void readByteCodeOps() throws IOException {
1789         // scratch buffer for collecting code::
1790         byte[] buf = new byte[1<<12];
1791         // record of all switch opcodes (these are variable-length)
1792         List<Integer> allSwitchOps = new ArrayList<>();
1793         for (int k = 0; k < allCodes.length; k++) {
1794             Code c = allCodes[k];
1795         scanOneMethod:
1796             for (int i = 0; ; i++) {
1797                 int bc = bc_codes.getByte();
1798                 if (i + 10 > buf.length)  buf = realloc(buf);
1799                 buf[i] = (byte)bc;
1800                 boolean isWide = false;
1801                 if (bc == _wide) {
1802                     bc = bc_codes.getByte();
1803                     buf[++i] = (byte)bc;
1804                     isWide = true;
1805                 }
1806                 assert(bc == (0xFF & bc));
1807                 // Adjust expectations of various band sizes.
1808                 switch (bc) {
1809                 case _tableswitch:
1810                 case _lookupswitch:
1811                     bc_case_count.expectMoreLength(1);
1812                     allSwitchOps.add(bc);
1813                     break;
1814                 case _iinc:
1815                     bc_local.expectMoreLength(1);
1816                     if (isWide)
1817                         bc_short.expectMoreLength(1);
1818                     else
1819                         bc_byte.expectMoreLength(1);
1820                     break;
1821                 case _sipush:
1822                     bc_short.expectMoreLength(1);
1823                     break;
1824                 case _bipush:
1825                     bc_byte.expectMoreLength(1);
1826                     break;
1827                 case _newarray:
1828                     bc_byte.expectMoreLength(1);
1829                     break;
1830                 case _multianewarray:
1831                     assert(getCPRefOpBand(bc) == bc_classref);
1832                     bc_classref.expectMoreLength(1);
1833                     bc_byte.expectMoreLength(1);
1834                     break;
1835                 case _ref_escape:
1836                     bc_escrefsize.expectMoreLength(1);
1837                     bc_escref.expectMoreLength(1);
1838                     break;
1839                 case _byte_escape:
1840                     bc_escsize.expectMoreLength(1);
1841                     // bc_escbyte will have to be counted too
1842                     break;
1843                 default:
1844                     if (Instruction.isInvokeInitOp(bc)) {
1845                         bc_initref.expectMoreLength(1);
1846                         break;
1847                     }
1848                     if (Instruction.isSelfLinkerOp(bc)) {
1849                         CPRefBand bc_which = selfOpRefBand(bc);
1850                         bc_which.expectMoreLength(1);
1851                         break;
1852                     }
1853                     if (Instruction.isBranchOp(bc)) {
1854                         bc_label.expectMoreLength(1);
1855                         break;
1856                     }
1857                     if (Instruction.isCPRefOp(bc)) {
1858                         CPRefBand bc_which = getCPRefOpBand(bc);
1859                         bc_which.expectMoreLength(1);
1860                         assert(bc != _multianewarray);  // handled elsewhere
1861                         break;
1862                     }
1863                     if (Instruction.isLocalSlotOp(bc)) {
1864                         bc_local.expectMoreLength(1);
1865                         break;
1866                     }
1867                     break;
1868                 case _end_marker:
1869                     {
1870                         // Transfer from buf to a more permanent place:
1871                         c.bytes = realloc(buf, i);
1872                         break scanOneMethod;
1873                     }
1874                 }
1875             }
1876         }
1877 
1878         // To size instruction bands correctly, we need info on switches:
1879         bc_case_count.readFrom(in);
1880         for (Integer i : allSwitchOps) {
1881             int bc = i.intValue();
1882             int caseCount = bc_case_count.getInt();
1883             bc_label.expectMoreLength(1+caseCount); // default label + cases
1884             bc_case_value.expectMoreLength(bc == _tableswitch ? 1 : caseCount);
1885         }
1886         bc_case_count.resetForSecondPass();
1887     }
1888 
1889     private void expandByteCodeOps() throws IOException {
1890         // scratch buffer for collecting code:
1891         byte[] buf = new byte[1<<12];
1892         // scratch buffer for collecting instruction boundaries:
1893         int[] insnMap = new int[1<<12];
1894         // list of label carriers, for label decoding post-pass:
1895         int[] labels = new int[1<<10];
1896         // scratch buffer for registering CP refs:
1897         Fixups fixupBuf = new Fixups();
1898 
1899         for (int k = 0; k < allCodes.length; k++) {
1900             Code code = allCodes[k];
1901             byte[] codeOps = code.bytes;
1902             code.bytes = null;  // just for now, while we accumulate bits
1903 
1904             Class curClass = code.thisClass();
1905 
1906             Set<Entry> ldcRefSet = ldcRefMap.get(curClass);
1907             if (ldcRefSet == null)
1908                 ldcRefMap.put(curClass, ldcRefSet = new HashSet<>());
1909 
1910             ClassEntry thisClass  = curClass.thisClass;
1911             ClassEntry superClass = curClass.superClass;
1912             ClassEntry newClass   = null;  // class of last _new opcode
1913 
1914             int pc = 0;  // fill pointer in buf; actual bytecode PC
1915             int numInsns = 0;
1916             int numLabels = 0;
1917             boolean hasEscs = false;
1918             fixupBuf.clear();
1919             for (int i = 0; i < codeOps.length; i++) {
1920                 int bc = Instruction.getByte(codeOps, i);
1921                 int curPC = pc;
1922                 insnMap[numInsns++] = curPC;
1923                 if (pc + 10 > buf.length)  buf = realloc(buf);
1924                 if (numInsns+10 > insnMap.length)  insnMap = realloc(insnMap);
1925                 if (numLabels+10 > labels.length)  labels = realloc(labels);
1926                 boolean isWide = false;
1927                 if (bc == _wide) {
1928                     buf[pc++] = (byte) bc;
1929                     bc = Instruction.getByte(codeOps, ++i);
1930                     isWide = true;
1931                 }
1932                 switch (bc) {
1933                 case _tableswitch: // apc:  (df, lo, hi, (hi-lo+1)*(label))
1934                 case _lookupswitch: // apc:  (df, nc, nc*(case, label))
1935                     {
1936                         int caseCount = bc_case_count.getInt();
1937                         while ((pc + 30 + caseCount*8) > buf.length)
1938                             buf = realloc(buf);
1939                         buf[pc++] = (byte) bc;
1940                         //initialize apc, df, lo, hi bytes to reasonable bits:
1941                         Arrays.fill(buf, pc, pc+30, (byte)0);
1942                         Instruction.Switch isw = (Instruction.Switch)
1943                             Instruction.at(buf, curPC);
1944                         //isw.setDefaultLabel(getLabel(bc_label, code, curPC));
1945                         isw.setCaseCount(caseCount);
1946                         if (bc == _tableswitch) {
1947                             isw.setCaseValue(0, bc_case_value.getInt());
1948                         } else {
1949                             for (int j = 0; j < caseCount; j++) {
1950                                 isw.setCaseValue(j, bc_case_value.getInt());
1951                             }
1952                         }
1953                         // Make our getLabel calls later.
1954                         labels[numLabels++] = curPC;
1955                         pc = isw.getNextPC();
1956                         continue;
1957                     }
1958                 case _iinc:
1959                     {
1960                         buf[pc++] = (byte) bc;
1961                         int local = bc_local.getInt();
1962                         int delta;
1963                         if (isWide) {
1964                             delta = bc_short.getInt();
1965                             Instruction.setShort(buf, pc, local); pc += 2;
1966                             Instruction.setShort(buf, pc, delta); pc += 2;
1967                         } else {
1968                             delta = (byte) bc_byte.getByte();
1969                             buf[pc++] = (byte)local;
1970                             buf[pc++] = (byte)delta;
1971                         }
1972                         continue;
1973                     }
1974                 case _sipush:
1975                     {
1976                         int val = bc_short.getInt();
1977                         buf[pc++] = (byte) bc;
1978                         Instruction.setShort(buf, pc, val); pc += 2;
1979                         continue;
1980                     }
1981                 case _bipush:
1982                 case _newarray:
1983                     {
1984                         int val = bc_byte.getByte();
1985                         buf[pc++] = (byte) bc;
1986                         buf[pc++] = (byte) val;
1987                         continue;
1988                     }
1989                 case _ref_escape:
1990                     {
1991                         // Note that insnMap has one entry for this.
1992                         hasEscs = true;
1993                         int size = bc_escrefsize.getInt();
1994                         Entry ref = bc_escref.getRef();
1995                         if (size == 1)  ldcRefSet.add(ref);
1996                         int fmt;
1997                         switch (size) {
1998                         case 1: fmt = Fixups.U1_FORMAT; break;
1999                         case 2: fmt = Fixups.U2_FORMAT; break;
2000                         default: assert(false); fmt = 0;
2001                         }
2002                         fixupBuf.add(pc, fmt, ref);
2003                         buf[pc+0] = buf[pc+1] = 0;
2004                         pc += size;
2005                     }
2006                     continue;
2007                 case _byte_escape:
2008                     {
2009                         // Note that insnMap has one entry for all these bytes.
2010                         hasEscs = true;
2011                         int size = bc_escsize.getInt();
2012                         while ((pc + size) > buf.length)
2013                             buf = realloc(buf);
2014                         while (size-- > 0) {
2015                             buf[pc++] = (byte) bc_escbyte.getByte();
2016                         }
2017                     }
2018                     continue;
2019                 default:
2020                     if (Instruction.isInvokeInitOp(bc)) {
2021                         int idx = (bc - _invokeinit_op);
2022                         int origBC = _invokespecial;
2023                         ClassEntry classRef;
2024                         switch (idx) {
2025                         case _invokeinit_self_option:
2026                             classRef = thisClass; break;
2027                         case _invokeinit_super_option:
2028                             classRef = superClass; break;
2029                         default:
2030                             assert(idx == _invokeinit_new_option);
2031                             classRef = newClass; break;
2032                         }
2033                         buf[pc++] = (byte) origBC;
2034                         int coding = bc_initref.getInt();
2035                         // Find the nth overloading of <init> in classRef.
2036                         MemberEntry ref = pkg.cp.getOverloadingForIndex(CONSTANT_Methodref, classRef, "<init>", coding);
2037                         fixupBuf.add(pc, Fixups.U2_FORMAT, ref);
2038                         buf[pc+0] = buf[pc+1] = 0;
2039                         pc += 2;
2040                         assert(Instruction.opLength(origBC) == (pc - curPC));
2041                         continue;
2042                     }
2043                     if (Instruction.isSelfLinkerOp(bc)) {
2044                         int idx = (bc - _self_linker_op);
2045                         boolean isSuper = (idx >= _self_linker_super_flag);
2046                         if (isSuper)  idx -= _self_linker_super_flag;
2047                         boolean isAload = (idx >= _self_linker_aload_flag);
2048                         if (isAload)  idx -= _self_linker_aload_flag;
2049                         int origBC = _first_linker_op + idx;
2050                         boolean isField = Instruction.isFieldOp(origBC);
2051                         CPRefBand bc_which;
2052                         ClassEntry which_cls  = isSuper ? superClass : thisClass;
2053                         Index which_ix;
2054                         if (isField) {
2055                             bc_which = isSuper ? bc_superfield  : bc_thisfield;
2056                             which_ix = pkg.cp.getMemberIndex(CONSTANT_Fieldref, which_cls);
2057                         } else {
2058                             bc_which = isSuper ? bc_supermethod : bc_thismethod;
2059                             which_ix = pkg.cp.getMemberIndex(CONSTANT_Methodref, which_cls);
2060                         }
2061                         assert(bc_which == selfOpRefBand(bc));
2062                         MemberEntry ref = (MemberEntry) bc_which.getRef(which_ix);
2063                         if (isAload) {
2064                             buf[pc++] = (byte) _aload_0;
2065                             curPC = pc;
2066                             // Note: insnMap keeps the _aload_0 separate.
2067                             insnMap[numInsns++] = curPC;
2068                         }
2069                         buf[pc++] = (byte) origBC;
2070                         fixupBuf.add(pc, Fixups.U2_FORMAT, ref);
2071                         buf[pc+0] = buf[pc+1] = 0;
2072                         pc += 2;
2073                         assert(Instruction.opLength(origBC) == (pc - curPC));
2074                         continue;
2075                     }
2076                     if (Instruction.isBranchOp(bc)) {
2077                         buf[pc++] = (byte) bc;
2078                         assert(!isWide);  // no wide prefix for branches
2079                         int nextPC = curPC + Instruction.opLength(bc);
2080                         // Make our getLabel calls later.
2081                         labels[numLabels++] = curPC;
2082                         //Instruction.at(buf, curPC).setBranchLabel(getLabel(bc_label, code, curPC));
2083                         while (pc < nextPC)  buf[pc++] = 0;
2084                         continue;
2085                     }
2086                     if (Instruction.isCPRefOp(bc)) {
2087                         CPRefBand bc_which = getCPRefOpBand(bc);
2088                         Entry ref = bc_which.getRef();
2089                         if (ref == null) {
2090                             if (bc_which == bc_classref) {
2091                                 // Shorthand for class self-references.
2092                                 ref = thisClass;
2093                             } else {
2094                                 assert(false);
2095                             }
2096                         }
2097                         int origBC = bc;
2098                         int size = 2;
2099                         switch (bc) {
2100                         case _ildc:
2101                         case _cldc:
2102                         case _fldc:
2103                         case _aldc:
2104                             origBC = _ldc;
2105                             size = 1;
2106                             ldcRefSet.add(ref);
2107                             break;
2108                         case _ildc_w:
2109                         case _cldc_w:
2110                         case _fldc_w:
2111                         case _aldc_w:
2112                             origBC = _ldc_w;
2113                             break;
2114                         case _lldc2_w:
2115                         case _dldc2_w:
2116                             origBC = _ldc2_w;
2117                             break;
2118                         case _new:
2119                             newClass = (ClassEntry) ref;
2120                             break;
2121                         }
2122                         buf[pc++] = (byte) origBC;
2123                         int fmt;
2124                         switch (size) {
2125                         case 1: fmt = Fixups.U1_FORMAT; break;
2126                         case 2: fmt = Fixups.U2_FORMAT; break;
2127                         default: assert(false); fmt = 0;
2128                         }
2129                         fixupBuf.add(pc, fmt, ref);
2130                         buf[pc+0] = buf[pc+1] = 0;
2131                         pc += size;
2132                         if (origBC == _multianewarray) {
2133                             // Copy the trailing byte also.
2134                             int val = bc_byte.getByte();
2135                             buf[pc++] = (byte) val;
2136                         } else if (origBC == _invokeinterface) {
2137                             int argSize = ((MemberEntry)ref).descRef.typeRef.computeSize(true);
2138                             buf[pc++] = (byte)( 1 + argSize );
2139                             buf[pc++] = 0;
2140                         }
2141                         assert(Instruction.opLength(origBC) == (pc - curPC));
2142                         continue;
2143                     }
2144                     if (Instruction.isLocalSlotOp(bc)) {
2145                         buf[pc++] = (byte) bc;
2146                         int local = bc_local.getInt();
2147                         if (isWide) {
2148                             Instruction.setShort(buf, pc, local);
2149                             pc += 2;
2150                             if (bc == _iinc) {
2151                                 int iVal = bc_short.getInt();
2152                                 Instruction.setShort(buf, pc, iVal);
2153                                 pc += 2;
2154                             }
2155                         } else {
2156                             Instruction.setByte(buf, pc, local);
2157                             pc += 1;
2158                             if (bc == _iinc) {
2159                                 int iVal = bc_byte.getByte();
2160                                 Instruction.setByte(buf, pc, iVal);
2161                                 pc += 1;
2162                             }
2163                         }
2164                         assert(Instruction.opLength(bc) == (pc - curPC));
2165                         continue;
2166                     }
2167                     // Random bytecode.  Just copy it.
2168                     if (bc >= _bytecode_limit)
2169                         Utils.log.warning("unrecognized bytescode "+bc
2170                                             +" "+Instruction.byteName(bc));
2171                     assert(bc < _bytecode_limit);
2172                     buf[pc++] = (byte) bc;
2173                     assert(Instruction.opLength(bc) == (pc - curPC));
2174                     continue;
2175                 }
2176             }
2177             // now make a permanent copy of the bytecodes
2178             code.setBytes(realloc(buf, pc));
2179             code.setInstructionMap(insnMap, numInsns);
2180             // fix up labels, now that code has its insnMap
2181             Instruction ibr = null;  // temporary branch instruction
2182             for (int i = 0; i < numLabels; i++) {
2183                 int curPC = labels[i];
2184                 // (Note:  Passing ibr in allows reuse, a speed hack.)
2185                 ibr = Instruction.at(code.bytes, curPC, ibr);
2186                 if (ibr instanceof Instruction.Switch) {
2187                     Instruction.Switch isw = (Instruction.Switch) ibr;
2188                     isw.setDefaultLabel(getLabel(bc_label, code, curPC));
2189                     int caseCount = isw.getCaseCount();
2190                     for (int j = 0; j < caseCount; j++) {
2191                         isw.setCaseLabel(j, getLabel(bc_label, code, curPC));
2192                     }
2193                 } else {
2194                     ibr.setBranchLabel(getLabel(bc_label, code, curPC));
2195                 }
2196             }
2197             if (fixupBuf.size() > 0) {
2198                 if (verbose > 2)
2199                     Utils.log.fine("Fixups in code: "+fixupBuf);
2200                 code.addFixups(fixupBuf);
2201             }
2202         }
2203     }
2204 }